Kernel
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- 48 participants
- 19104 discussions

14 May '25
Tianrui Zhao (3):
drm/amdgpu: Fix pcie order dislocation
drm/amdgpu: make duplicated EOP packet for GFX6 have real content
drm/amdgpu: Fix RX550 pcie order dislocation.
lvjianmin (2):
drm/radeon: repeat the same EOP packet for EOP workaround on CIK
drm/amdgpu: make duplicated EOP packet for GFX7/8 have real content
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 5 +
drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 161 ++++++++++++++++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 6 +
drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 4 +
drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h | 3 +
drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c | 19 +++
drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 6 +
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 6 +
drivers/gpu/drm/radeon/cik.c | 4 +
9 files changed, 214 insertions(+)
--
2.33.0
2
6
Liu Chuang (1):
trace: Fix kabi breakage in struct trace_iterator
Steven Rostedt (Google) (2):
tracing/ring-buffer: Fix wait_on_pipe() race
ring-buffer: Make wake once of ring_buffer_wait() more robust
include/linux/ring_buffer.h | 3 ++-
include/linux/trace_events.h | 6 ++++-
kernel/trace/ring_buffer.c | 39 ++++++++++++++++++++------------
kernel/trace/trace.c | 43 ++++++++++++++++++++++++++----------
4 files changed, 63 insertions(+), 28 deletions(-)
--
2.34.1
2
4
SeongJae Park (1):
[Backport] mm/damon/sysfs-schemes: avoid Wformat-security warning on
damon_sysfs_access_pattern_add_range_dir()
jiarui (2):
[Huawei] ocfs2: fix: release bh only if lock is held
[Huawei] ocfs2: fix: Control the log output rate when disk lock and
unlock
fs/ocfs2/acl.c | 3 ++-
fs/ocfs2/adl/adllock.c | 6 +++---
fs/ocfs2/adl/cdb.c | 2 +-
fs/ocfs2/adlglue.c | 2 +-
fs/ocfs2/cluster/masklog.h | 9 +++++++++
fs/ocfs2/inode.c | 2 +-
fs/ocfs2/lockglue.c | 6 +++---
mm/damon/sysfs-schemes.c | 2 +-
8 files changed, 21 insertions(+), 11 deletions(-)
--
2.34.1
1
0

[openeuler:openEuler-1.0-LTS] BUILD REGRESSION f4c1b3d5eab859c8748b3960a7a86dbb09bac2b7
by kernel test robot 14 May '25
by kernel test robot 14 May '25
14 May '25
tree/branch: https://gitee.com/openeuler/kernel.git openEuler-1.0-LTS
branch HEAD: f4c1b3d5eab859c8748b3960a7a86dbb09bac2b7 !16177 Fix CVE-2022-49850
Error/Warning (recently discovered and may have been fixed):
https://lore.kernel.org/oe-kbuild-all/202504160234.O5AhsCPF-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504180904.aJTbSHsO-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504250657.SBZLGq3K-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504250827.FCNrED1Z-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504250942.HWyvS6HD-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504251109.LNg7C0pb-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504251357.XH0GnYXx-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290542.wZ43d7od-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290604.Y62ysEZs-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290804.SFjtS4nf-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290808.iYcj1P8f-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504291102.S4UEqzyV-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504291551.FOwjwu8e-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505070314.0zdCBK7T-lkp@intel.com
arch/x86/kernel/apic/io_apic.o: warning: objtool: acpi_get_override_irq()+0xfe: can't find switch jump table
block/bio-integrity.c:41:6: warning: no previous prototype for '__bio_integrity_free' [-Wmissing-prototypes]
block/bio-integrity.c:41:6: warning: no previous prototype for function '__bio_integrity_free' [-Wmissing-prototypes]
block/blk-iolatency.c:308:14: warning: variable 'changed' set but not used [-Wunused-but-set-variable]
block/blk-iolatency.c:308:7: warning: variable 'changed' set but not used [-Wunused-but-set-variable]
block/blk-iolatency.c:800:24: warning: variable 'blkiolat' set but not used [-Wunused-but-set-variable]
block/blk-iolatency.c:800:31: warning: variable 'blkiolat' set but not used [-Wunused-but-set-variable]
block/blk-merge.c:696:16: warning: no previous prototype for 'blk_try_req_merge' [-Wmissing-prototypes]
block/blk-mq-sched.c:220:5: warning: no previous prototype for '__blk_mq_sched_dispatch_requests' [-Wmissing-prototypes]
block/blk-mq-sched.c:220:5: warning: no previous prototype for function '__blk_mq_sched_dispatch_requests' [-Wmissing-prototypes]
block/blk-wbt.c:674:6: warning: no previous prototype for 'wbt_issue' [-Wmissing-prototypes]
block/blk-wbt.c:674:6: warning: no previous prototype for function 'wbt_issue' [-Wmissing-prototypes]
block/blk-wbt.c:694:6: warning: no previous prototype for 'wbt_requeue' [-Wmissing-prototypes]
block/blk-wbt.c:694:6: warning: no previous prototype for function 'wbt_requeue' [-Wmissing-prototypes]
block/genhd.c:533: warning: Function parameter or member 'devt' not described in 'blk_invalidate_devt'
block/genhd.c:642:5: warning: no previous prototype for 'disk_scan_partitions' [-Wmissing-prototypes]
block/genhd.c:642:5: warning: no previous prototype for function 'disk_scan_partitions' [-Wmissing-prototypes]
crypto/sm4_generic.o: warning: objtool: missing symbol for section .text
include/linux/device.h:1509:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
include/linux/device.h:1513:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
include/linux/device.h:1515:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
include/linux/device.h:1526:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
include/linux/filter.h:787:10: warning: cast between incompatible function types from 'u64 (*)(u64, u64, u64, u64, u64)' {aka 'long long unsigned int (*)(long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int)'} to 'u64 (*)(u64, u64, u64, u64, u64, const struct bpf_insn *)' {aka 'long long unsigned int (*)(long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int, const struct bpf_insn *)'} [-Wcast-function-type]
include/linux/ktask.h:123:35: warning: cast between incompatible function types from 'int (*)(long unsigned int, long unsigned int, struct cgp_args *)' to 'int (*)(void *, void *, void *)' [-Wcast-function-type]
include/linux/ktask.h:123:35: warning: cast between incompatible function types from 'int (*)(long unsigned int, long unsigned int, struct deferred_args *)' to 'int (*)(void *, void *, void *)' [-Wcast-function-type]
include/linux/ktask.h:123:35: warning: cast between incompatible function types from 'int (*)(long unsigned int, long unsigned int, struct hf_args *)' to 'int (*)(void *, void *, void *)' [-Wcast-function-type]
include/linux/ktask.h:123:35: warning: cast between incompatible function types from 'int (*)(long unsigned int, long unsigned int, struct vfio_pin_args *)' to 'int (*)(void *, void *, void *)' [-Wcast-function-type]
include/linux/ktask.h:163:32: warning: cast between incompatible function types from 'void (*)(long unsigned int, long unsigned int, struct vfio_pin_args *)' to 'void (*)(void *, void *, void *)' [-Wcast-function-type]
include/linux/list.h:65:19: warning: storing the address of local variable 'tmp' in '((struct list_head *)lip)[5].prev' [-Wdangling-pointer=]
include/linux/mempolicy.h:329:13: warning: '__do_mbind' defined but not used [-Wunused-function]
include/linux/skbuff.h:3551:24: warning: this statement may fall through [-Wimplicit-fallthrough=]
include/linux/string.h:249:16: warning: '__builtin_strncpy' accessing 80 bytes at offsets 100 and 36 may overlap up to 0 bytes at offset [9223372036854775807, -9223372036854775808] [-Wrestrict]
include/linux/thread_info.h:59:17: warning: 'usercmd' may be used uninitialized [-Wmaybe-uninitialized]
include/trace/trace_events.h:26:23: warning: 'str__fs__trace_system_name' defined but not used [-Wunused-const-variable=]
mm/mmu_gather.o: warning: objtool: missing symbol for section .text
mm/slab_common.c:1452:37: warning: 'proc_slabinfo_operations' defined but not used [-Wunused-const-variable=]
mm/sparse.o: warning: objtool: missing symbol for section .init.text
sound/isa/gus/interwave.o: warning: objtool: missing symbol for section .init.text
Unverified Error/Warning (likely false positive, kindly check if interested):
crypto/jitterentropy.c:204: warning: Function parameter or member 'ec' not described in 'jent_fold_time'
crypto/jitterentropy.c:204: warning: Function parameter or member 'folded' not described in 'jent_fold_time'
crypto/jitterentropy.c:204: warning: Function parameter or member 'loop_cnt' not described in 'jent_fold_time'
crypto/jitterentropy.c:204: warning: Function parameter or member 'time' not described in 'jent_fold_time'
crypto/jitterentropy.c:390: warning: Function parameter or member 'entropy_collector' not described in 'jent_unbiased_bit'
crypto/jitterentropy.c:422: warning: Function parameter or member 'entropy_collector' not described in 'jent_stir_pool'
Error/Warning ids grouped by kconfigs:
recent_errors
|-- arm64-allmodconfig
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-__bio_integrity_free
| |-- block-blk-iolatency.c:warning:variable-blkiolat-set-but-not-used
| |-- block-blk-iolatency.c:warning:variable-changed-set-but-not-used
| |-- block-blk-merge.c:warning:no-previous-prototype-for-blk_try_req_merge
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-__blk_mq_sched_dispatch_requests
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-wbt_issue
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-wbt_requeue
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- include-asm-generic-bitops-non-atomic.h:warning:array-subscript-long-unsigned-int-is-partly-outside-array-bounds-of-u32-aka-unsigned-int
| |-- include-linux-device.h:warning:this-statement-may-fall-through
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-cgp_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-deferred_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-hf_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-vfio_pin_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-void-(-)(long-unsigned-int-long-unsigned-int-struct-vfio_pin_args-)-to-void-(-)(void-void-void-)
| |-- include-linux-skbuff.h:warning:this-statement-may-fall-through
| |-- include-linux-string.h:warning:__builtin_strncpy-accessing-bytes-at-offsets-and-may-overlap-up-to-bytes-at-offset
| |-- include-linux-thread_info.h:warning:b-may-be-used-uninitialized
| `-- include-trace-trace_events.h:warning:str__fs__trace_system_name-defined-but-not-used
|-- arm64-allnoconfig
| `-- include-linux-mempolicy.h:warning:__do_mbind-defined-but-not-used
|-- arm64-randconfig-001-20250513
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-__bio_integrity_free
| |-- block-blk-merge.c:warning:no-previous-prototype-for-blk_try_req_merge
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-__blk_mq_sched_dispatch_requests
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- include-linux-device.h:warning:this-statement-may-fall-through
| |-- include-linux-filter.h:warning:cast-between-incompatible-function-types-from-u64-(-)(u64-u64-u64-u64-u64)-aka-long-long-unsigned-int-(-)(long-long-unsigned-int-long-long-unsigned-int-long-long-unsigne
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-deferred_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-vfio_pin_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-void-(-)(long-unsigned-int-long-unsigned-int-struct-vfio_pin_args-)-to-void-(-)(void-void-void-)
| |-- include-linux-mempolicy.h:warning:__do_mbind-defined-but-not-used
| `-- include-linux-skbuff.h:warning:this-statement-may-fall-through
|-- arm64-randconfig-002-20250513
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-__bio_integrity_free
| |-- block-blk-merge.c:warning:no-previous-prototype-for-blk_try_req_merge
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-__blk_mq_sched_dispatch_requests
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- include-linux-device.h:warning:this-statement-may-fall-through
| |-- include-linux-filter.h:warning:cast-between-incompatible-function-types-from-u64-(-)(u64-u64-u64-u64-u64)-aka-long-long-unsigned-int-(-)(long-long-unsigned-int-long-long-unsigned-int-long-long-unsigne
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-deferred_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-vfio_pin_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-void-(-)(long-unsigned-int-long-unsigned-int-struct-vfio_pin_args-)-to-void-(-)(void-void-void-)
| |-- include-linux-list.h:warning:storing-the-address-of-local-variable-tmp-in-((struct-list_head-)lip)-.prev
| `-- include-trace-trace_events.h:warning:str__fs__trace_system_name-defined-but-not-used
|-- arm64-randconfig-004-20250513
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- include-linux-filter.h:warning:cast-between-incompatible-function-types-from-u64-(-)(u64-u64-u64-u64-u64)-aka-long-long-unsigned-int-(-)(long-long-unsigned-int-long-long-unsigned-int-long-long-unsigne
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-cgp_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-hf_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-vfio_pin_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-void-(-)(long-unsigned-int-long-unsigned-int-struct-vfio_pin_args-)-to-void-(-)(void-void-void-)
| |-- include-linux-mempolicy.h:warning:__do_mbind-defined-but-not-used
| |-- include-trace-trace_events.h:warning:str__fs__trace_system_name-defined-but-not-used
| `-- mm-slab_common.c:warning:proc_slabinfo_operations-defined-but-not-used
|-- arm64-randconfig-r061-20250514
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-__bio_integrity_free
| |-- block-blk-merge.c:warning:no-previous-prototype-for-blk_try_req_merge
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-__blk_mq_sched_dispatch_requests
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- include-linux-device.h:warning:this-statement-may-fall-through
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-cgp_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-hf_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-vfio_pin_args-)-to-int-(-)(void-void-void-)
| `-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-void-(-)(long-unsigned-int-long-unsigned-int-struct-vfio_pin_args-)-to-void-(-)(void-void-void-)
|-- x86_64-allnoconfig
| |-- mm-mmu_gather.o:warning:objtool:missing-symbol-for-section-.text
| `-- mm-vmscan.c:error:implicit-declaration-of-function-kernel_swap_enabled-Werror-Wimplicit-function-declaration
|-- x86_64-allyesconfig
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-function-__bio_integrity_free
| |-- block-blk-iolatency.c:warning:variable-blkiolat-set-but-not-used
| |-- block-blk-iolatency.c:warning:variable-changed-set-but-not-used
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-function-__blk_mq_sched_dispatch_requests
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-function-wbt_issue
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-function-wbt_requeue
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-function-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| `-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
|-- x86_64-buildonly-randconfig-001-20250513
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- include-linux-device.h:warning:this-statement-may-fall-through
| |-- include-linux-filter.h:warning:cast-between-incompatible-function-types-from-u64-(-)(u64-u64-u64-u64-u64)-aka-long-long-unsigned-int-(-)(long-long-unsigned-int-long-long-unsigned-int-long-long-unsigne
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-cgp_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-deferred_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-hf_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-mempolicy.h:warning:__do_mbind-defined-but-not-used
| `-- include-trace-trace_events.h:warning:str__fs__trace_system_name-defined-but-not-used
|-- x86_64-buildonly-randconfig-002-20250513
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-__bio_integrity_free
| |-- block-blk-merge.c:warning:no-previous-prototype-for-blk_try_req_merge
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-__blk_mq_sched_dispatch_requests
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-wbt_issue
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-wbt_requeue
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- crypto-sm4_generic.o:warning:objtool:missing-symbol-for-section-.text
| |-- include-linux-device.h:warning:this-statement-may-fall-through
| |-- include-linux-filter.h:warning:cast-between-incompatible-function-types-from-u64-(-)(u64-u64-u64-u64-u64)-aka-long-long-unsigned-int-(-)(long-long-unsigned-int-long-long-unsigned-int-long-long-unsigne
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-vfio_pin_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-void-(-)(long-unsigned-int-long-unsigned-int-struct-vfio_pin_args-)-to-void-(-)(void-void-void-)
| |-- include-linux-mempolicy.h:warning:__do_mbind-defined-but-not-used
| |-- include-linux-skbuff.h:warning:this-statement-may-fall-through
| `-- include-trace-trace_events.h:warning:str__fs__trace_system_name-defined-but-not-used
|-- x86_64-buildonly-randconfig-003-20250513
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-function-__bio_integrity_free
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-function-__blk_mq_sched_dispatch_requests
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-function-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| `-- mm-hugetlb.c:warning:no-previous-prototype-for-function-free_huge_page_to_dhugetlb_pool
|-- x86_64-buildonly-randconfig-004-20250513
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-__bio_integrity_free
| |-- block-blk-merge.c:warning:no-previous-prototype-for-blk_try_req_merge
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-__blk_mq_sched_dispatch_requests
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- include-linux-device.h:warning:this-statement-may-fall-through
| |-- include-linux-filter.h:warning:cast-between-incompatible-function-types-from-u64-(-)(u64-u64-u64-u64-u64)-aka-long-long-unsigned-int-(-)(long-long-unsigned-int-long-long-unsigned-int-long-long-unsigne
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-cgp_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-hf_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-mempolicy.h:warning:__do_mbind-defined-but-not-used
| `-- include-linux-thread_info.h:warning:usercmd-may-be-used-uninitialized
|-- x86_64-buildonly-randconfig-005-20250513
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-function-__bio_integrity_free
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-function-__blk_mq_sched_dispatch_requests
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-function-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| `-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
|-- x86_64-buildonly-randconfig-006-20250513
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-__bio_integrity_free
| |-- block-blk-merge.c:warning:no-previous-prototype-for-blk_try_req_merge
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-__blk_mq_sched_dispatch_requests
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- crypto-sm4_generic.o:warning:objtool:missing-symbol-for-section-.text
| |-- include-linux-device.h:warning:this-statement-may-fall-through
| |-- include-linux-filter.h:warning:cast-between-incompatible-function-types-from-u64-(-)(u64-u64-u64-u64-u64)-aka-long-long-unsigned-int-(-)(long-long-unsigned-int-long-long-unsigned-int-long-long-unsigne
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-cgp_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-hf_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-mempolicy.h:warning:__do_mbind-defined-but-not-used
| |-- mm-sparse.o:warning:objtool:missing-symbol-for-section-.init.text
| `-- sound-isa-gus-interwave.o:warning:objtool:missing-symbol-for-section-.init.text
|-- x86_64-defconfig
| |-- block-blk-merge.c:warning:no-previous-prototype-for-blk_try_req_merge
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-__blk_mq_sched_dispatch_requests
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- include-linux-filter.h:warning:cast-between-incompatible-function-types-from-u64-(-)(u64-u64-u64-u64-u64)-aka-long-long-unsigned-int-(-)(long-long-unsigned-int-long-long-unsigned-int-long-long-unsigne
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-cgp_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-hf_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-skbuff.h:warning:this-statement-may-fall-through
| `-- include-trace-trace_events.h:warning:str__fs__trace_system_name-defined-but-not-used
|-- x86_64-randconfig-161-20250514
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- include-linux-filter.h:warning:cast-between-incompatible-function-types-from-u64-(-)(u64-u64-u64-u64-u64)-aka-long-long-unsigned-int-(-)(long-long-unsigned-int-long-long-unsigned-int-long-long-unsigne
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-cgp_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-mempolicy.h:warning:__do_mbind-defined-but-not-used
| |-- include-linux-skbuff.h:warning:this-statement-may-fall-through
| `-- include-trace-trace_events.h:warning:str__fs__trace_system_name-defined-but-not-used
`-- x86_64-rhel-9.4-rust
|-- arch-x86-kernel-apic-io_apic.o:warning:objtool:acpi_get_override_irq:can-t-find-switch-jump-table
|-- block-bio-integrity.c:warning:no-previous-prototype-for-function-__bio_integrity_free
|-- block-blk-iolatency.c:warning:variable-blkiolat-set-but-not-used
|-- block-blk-iolatency.c:warning:variable-changed-set-but-not-used
|-- block-blk-mq-sched.c:warning:no-previous-prototype-for-function-__blk_mq_sched_dispatch_requests
|-- block-blk-wbt.c:warning:no-previous-prototype-for-function-wbt_issue
|-- block-blk-wbt.c:warning:no-previous-prototype-for-function-wbt_requeue
|-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
|-- block-genhd.c:warning:no-previous-prototype-for-function-disk_scan_partitions
|-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
|-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
|-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
|-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
|-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
|-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
`-- mm-hugetlb.c:warning:no-previous-prototype-for-function-free_huge_page_to_dhugetlb_pool
elapsed time: 730m
configs tested: 16
configs skipped: 118
tested configs:
arm64 allmodconfig gcc-14.2.0
arm64 allnoconfig gcc-14.2.0
arm64 randconfig-001-20250513 gcc-14.2.0
arm64 randconfig-002-20250513 gcc-14.2.0
arm64 randconfig-003-20250513 gcc-6.5.0
arm64 randconfig-004-20250513 gcc-14.2.0
x86_64 allnoconfig clang-20
x86_64 allyesconfig clang-20
x86_64 buildonly-randconfig-001-20250513 gcc-12
x86_64 buildonly-randconfig-002-20250513 gcc-12
x86_64 buildonly-randconfig-003-20250513 clang-20
x86_64 buildonly-randconfig-004-20250513 gcc-12
x86_64 buildonly-randconfig-005-20250513 clang-20
x86_64 buildonly-randconfig-006-20250513 gcc-12
x86_64 defconfig gcc-11
x86_64 rhel-9.4-rust clang-18
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[PATCH openEuler-1.0-LTS] kvm: x86: fix infinite loop in kvm_guest_time_update when tsc is 0
by Yuntao Liu 14 May '25
by Yuntao Liu 14 May '25
14 May '25
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IC7KK7
CVE: NA
--------------------------------
Fixes: 35181e86df97 ("KVM: x86: Add a common TSC scaling function")
Syzkaller testing detected a soft lockup.
watchdog: BUG: soft lockup - CPU#3 stuck for 127s! [syz.1.2088:9817]
Modules linked in:
CPU: 3 PID: 9817 Comm: syz.1.2088 Tainted: G S 6.6.0+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
RIP: 0010:__sanitizer_cov_trace_const_cmp4+0x8/0x20 kernel/kcov.c:313
Code: bf 03 00 00 00 e9 48 fe ff ff 0f 1f 84 00 00 00 00 00 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 48 8b 0c 24 <89> f2 89
fe bf 05 00 00 00 e9 1a fe ff ff 66 2e 0f 1f 84 00 00 00
RSP: 0018:ffff888016d8fad8 EFLAGS: 00000206
RAX: 0000000000080000 RBX: ffff88810e242540 RCX: ffffffff901150d6
RDX: 0000000000080000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffff888016d8fb50 R08: 0000000000000001 R09: ffffed1021c484af
R10: 0000000000000000 R11: 0000000000000277 R12: 0000000000000000
R13: fffffed357281918 R14: 0000000000000000 R15: 0000000000000001
FS: 00007f2a8f6ea6c0(0000) GS:ffff888119780000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000012c56c0 CR3: 000000000dce8001 CR4: 0000000000772ee0
DR0: 0000000000000000 DR1: 0000000000d3eb1c DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
PKRU: 80000000
Call Trace:
<TASK>
kvm_get_time_scale arch/x86/kvm/x86.c:2458 [inline]
kvm_guest_time_update+0x926/0xb00 arch/x86/kvm/x86.c:3268
vcpu_enter_guest.constprop.0+0x1e70/0x3cf0 arch/x86/kvm/x86.c:10678
vcpu_run+0x129/0x8d0 arch/x86/kvm/x86.c:11126
kvm_arch_vcpu_ioctl_run+0x37a/0x13d0 arch/x86/kvm/x86.c:11352
kvm_vcpu_ioctl+0x56b/0xe60 virt/kvm/kvm_main.c:4188
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:871 [inline]
__se_sys_ioctl+0x12d/0x190 fs/ioctl.c:857
do_syscall_x64 arch/x86/entry/common.c:51 [inline]
do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81
entry_SYSCALL_64_after_hwframe+0x78/0xe2
ioctl$KVM_SET_TSC_KHZ(r2, 0xaea2, 0x1)
user_tsc_khz = 0x1
|
kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz)
|
ioctl$KVM_RUN(r2, 0xae80, 0x0)
|
...
kvm_guest_time_update(struct kvm_vcpu *v)
|
if (kvm_caps.has_tsc_control)
tgt_tsc_khz = kvm_scale_tsc(tgt_tsc_khz,
v->arch.l1_tsc_scaling_ratio);
|
kvm_scale_tsc(u64 tsc, u64 ratio)
|
__scale_tsc(u64 ratio, u64 tsc)
ratio=122380531, tsc=2299998, N=48
ratio*tsc >> N = 0.999... -> 0
|
kvm_get_time_scale
In function __scale_tsc, it uses fixed point number to calculate
tsc, therefore, a certain degree of precision is lost, the actual tsc
value of 0.999... would be 0. In function kvm_get_time_scale
tps32=tps64=base_hz=0, would lead second while_loop infinite. when
CONFIG_PREEMPT is n, it causes a soft lockup issue.
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
arch/x86/kvm/x86.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 6afffdcc656e..83d215d43eb3 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1673,10 +1673,14 @@ static void update_ia32_tsc_adjust_msr(struct kvm_vcpu *vcpu, s64 offset)
* point number (mult + frac * 2^(-N)).
*
* N equals to kvm_tsc_scaling_ratio_frac_bits.
+ *
+ * return 1 if _tsc is 0.
*/
static inline u64 __scale_tsc(u64 ratio, u64 tsc)
{
- return mul_u64_u64_shr(tsc, ratio, kvm_tsc_scaling_ratio_frac_bits);
+ u64 _tsc = mul_u64_u64_shr(tsc, ratio, kvm_tsc_scaling_ratio_frac_bits);
+
+ return !_tsc ? 1 : _tsc;
}
u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc)
--
2.34.1
2
1

[PATCH OLK-5.10] kvm: x86: fix infinite loop in kvm_guest_time_update when tsc is 0
by Yuntao Liu 14 May '25
by Yuntao Liu 14 May '25
14 May '25
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IC7KK7
CVE: NA
--------------------------------
Fixes: 35181e86df97 ("KVM: x86: Add a common TSC scaling function")
Syzkaller testing detected a soft lockup.
watchdog: BUG: soft lockup - CPU#3 stuck for 127s! [syz.1.2088:9817]
Modules linked in:
CPU: 3 PID: 9817 Comm: syz.1.2088 Tainted: G S 6.6.0+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
RIP: 0010:__sanitizer_cov_trace_const_cmp4+0x8/0x20 kernel/kcov.c:313
Code: bf 03 00 00 00 e9 48 fe ff ff 0f 1f 84 00 00 00 00 00 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 48 8b 0c 24 <89> f2 89
fe bf 05 00 00 00 e9 1a fe ff ff 66 2e 0f 1f 84 00 00 00
RSP: 0018:ffff888016d8fad8 EFLAGS: 00000206
RAX: 0000000000080000 RBX: ffff88810e242540 RCX: ffffffff901150d6
RDX: 0000000000080000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffff888016d8fb50 R08: 0000000000000001 R09: ffffed1021c484af
R10: 0000000000000000 R11: 0000000000000277 R12: 0000000000000000
R13: fffffed357281918 R14: 0000000000000000 R15: 0000000000000001
FS: 00007f2a8f6ea6c0(0000) GS:ffff888119780000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000012c56c0 CR3: 000000000dce8001 CR4: 0000000000772ee0
DR0: 0000000000000000 DR1: 0000000000d3eb1c DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
PKRU: 80000000
Call Trace:
<TASK>
kvm_get_time_scale arch/x86/kvm/x86.c:2458 [inline]
kvm_guest_time_update+0x926/0xb00 arch/x86/kvm/x86.c:3268
vcpu_enter_guest.constprop.0+0x1e70/0x3cf0 arch/x86/kvm/x86.c:10678
vcpu_run+0x129/0x8d0 arch/x86/kvm/x86.c:11126
kvm_arch_vcpu_ioctl_run+0x37a/0x13d0 arch/x86/kvm/x86.c:11352
kvm_vcpu_ioctl+0x56b/0xe60 virt/kvm/kvm_main.c:4188
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:871 [inline]
__se_sys_ioctl+0x12d/0x190 fs/ioctl.c:857
do_syscall_x64 arch/x86/entry/common.c:51 [inline]
do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81
entry_SYSCALL_64_after_hwframe+0x78/0xe2
ioctl$KVM_SET_TSC_KHZ(r2, 0xaea2, 0x1)
user_tsc_khz = 0x1
|
kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz)
|
ioctl$KVM_RUN(r2, 0xae80, 0x0)
|
...
kvm_guest_time_update(struct kvm_vcpu *v)
|
if (kvm_caps.has_tsc_control)
tgt_tsc_khz = kvm_scale_tsc(tgt_tsc_khz,
v->arch.l1_tsc_scaling_ratio);
|
kvm_scale_tsc(u64 tsc, u64 ratio)
|
__scale_tsc(u64 ratio, u64 tsc)
ratio=122380531, tsc=2299998, N=48
ratio*tsc >> N = 0.999... -> 0
|
kvm_get_time_scale
In function __scale_tsc, it uses fixed point number to calculate
tsc, therefore, a certain degree of precision is lost, the actual tsc
value of 0.999... would be 0. In function kvm_get_time_scale
tps32=tps64=base_hz=0, would lead second while_loop infinite. when
CONFIG_PREEMPT is n, it causes a soft lockup issue.
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
arch/x86/kvm/x86.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index d2d206ff6462..dec2d3baf202 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2428,10 +2428,14 @@ static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
* point number (mult + frac * 2^(-N)).
*
* N equals to kvm_tsc_scaling_ratio_frac_bits.
+ *
+ * return 1 if _tsc is 0.
*/
static inline u64 __scale_tsc(u64 ratio, u64 tsc)
{
- return mul_u64_u64_shr(tsc, ratio, kvm_tsc_scaling_ratio_frac_bits);
+ u64 _tsc = mul_u64_u64_shr(tsc, ratio, kvm_tsc_scaling_ratio_frac_bits);
+
+ return !_tsc ? 1 : _tsc;
}
u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc)
--
2.34.1
2
1

[openeuler:OLK-6.6 2220/2220] drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
by kernel test robot 14 May '25
by kernel test robot 14 May '25
14 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: 855c2a6945da5d74f3e50d601537000d0989d5a3
commit: 663a9a1c191fd26f1d8cb44edb6e0e50dd0536b2 [2220/2220] !14287 [OLK-6.6] SCSI: Support Linkdata HBA/RAID Controllers
config: x86_64-randconfig-123-20250513 (https://download.01.org/0day-ci/archive/20250514/202505140714.hwzBwdOl-lkp@…)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
rustc: rustc 1.73.0 (cc66ad468 2023-10-03)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250514/202505140714.hwzBwdOl-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505140714.hwzBwdOl-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.c: note: in included file:
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
--
>> drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:107:17: sparse: sparse: cast removes address space '__iomem' of expression
>> drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:107:17: sparse: sparse: incorrect type in argument 3 (different address spaces) @@ expected void [noderef] __iomem *reg @@ got unsigned char * @@
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:107:17: sparse: expected void [noderef] __iomem *reg
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:107:17: sparse: got unsigned char *
>> drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:127:25: sparse: sparse: incorrect type in argument 3 (different address spaces) @@ expected void [noderef] __iomem *reg @@ got unsigned char *reset_key_vir_addr @@
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:127:25: sparse: expected void [noderef] __iomem *reg
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:127:25: sparse: got unsigned char *reset_key_vir_addr
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:151:17: sparse: sparse: cast removes address space '__iomem' of expression
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:151:17: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void [noderef] __iomem *reg @@ got unsigned char * @@
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:151:17: sparse: expected void [noderef] __iomem *reg
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:151:17: sparse: got unsigned char *
>> drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:188:35: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void [noderef] __iomem *reg @@ got unsigned char *reset_key_state_vir_addr @@
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:188:35: sparse: expected void [noderef] __iomem *reg
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:188:35: sparse: got unsigned char *reset_key_state_vir_addr
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:261:9: sparse: sparse: cast removes address space '__iomem' of expression
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:261:9: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void [noderef] __iomem *reg @@ got unsigned char * @@
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:261:9: sparse: expected void [noderef] __iomem *reg
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:261:9: sparse: got unsigned char *
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:280:17: sparse: sparse: cast removes address space '__iomem' of expression
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:280:17: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void [noderef] __iomem *reg @@ got unsigned char * @@
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:280:17: sparse: expected void [noderef] __iomem *reg
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:280:17: sparse: got unsigned char *
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:549:9: sparse: sparse: cast removes address space '__iomem' of expression
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:549:9: sparse: sparse: incorrect type in argument 3 (different address spaces) @@ expected void [noderef] __iomem *reg @@ got unsigned char * @@
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:549:9: sparse: expected void [noderef] __iomem *reg
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:549:9: sparse: got unsigned char *
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:584:37: sparse: sparse: cast removes address space '__iomem' of expression
>> drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:661:37: sparse: sparse: incorrect type in argument 3 (different address spaces) @@ expected void [noderef] __iomem *reg @@ got unsigned char *[assigned] reset_addr @@
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:661:37: sparse: expected void [noderef] __iomem *reg
drivers/scsi/linkdata/ps3stor/ps3_ioc_state.c:661:37: sparse: got unsigned char *[assigned] reset_addr
--
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:720:17: sparse: sparse: cast to restricted __le32
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c: note: in included file:
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned long long addr @@ got restricted __le64 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: expected unsigned long long addr
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: got restricted __le64 [usertype]
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int length @@ got restricted __le32 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: expected unsigned int length
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: got restricted __le32 [usertype]
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned long long addr @@ got restricted __le64 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: expected unsigned long long addr
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: got restricted __le64 [usertype]
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int length @@ got restricted __le32 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: expected unsigned int length
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: got restricted __le32 [usertype]
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned long long addr @@ got restricted __le64 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: expected unsigned long long addr
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: got restricted __le64 [usertype]
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int length @@ got restricted __le32 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: expected unsigned int length
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: got restricted __le32 [usertype]
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned long long addr @@ got restricted __le64 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: expected unsigned long long addr
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: got restricted __le64 [usertype]
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int length @@ got restricted __le32 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: expected unsigned int length
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: got restricted __le32 [usertype]
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned long long addr @@ got restricted __le64 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: expected unsigned long long addr
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: got restricted __le64 [usertype]
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int length @@ got restricted __le32 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: expected unsigned int length
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: got restricted __le32 [usertype]
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned long long addr @@ got restricted __le64 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: expected unsigned long long addr
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: got restricted __le64 [usertype]
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int length @@ got restricted __le32 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: expected unsigned int length
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: got restricted __le32 [usertype]
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned long long addr @@ got restricted __le64 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: expected unsigned long long addr
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: got restricted __le64 [usertype]
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int length @@ got restricted __le32 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: expected unsigned int length
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: got restricted __le32 [usertype]
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned long long addr @@ got restricted __le64 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: expected unsigned long long addr
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:317:21: sparse: got restricted __le64 [usertype]
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int length @@ got restricted __le32 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: expected unsigned int length
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:318:23: sparse: got restricted __le32 [usertype]
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:1572:31: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int length @@ got restricted __le32 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:1572:31: sparse: expected unsigned int length
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:1572:31: sparse: got restricted __le32 [usertype]
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:1573:29: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned long long addr @@ got restricted __le64 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:1573:29: sparse: expected unsigned long long addr
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:1573:29: sparse: got restricted __le64 [usertype]
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:1578:46: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned long long sasAddr @@ got restricted __le64 [usertype] @@
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:1578:46: sparse: expected unsigned long long sasAddr
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd.c:1578:46: sparse: got restricted __le64 [usertype]
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
--
drivers/scsi/linkdata/ps3stor/ps3_mgr_cmd_err.c: note: in included file:
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
>> drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h:30:16: sparse: sparse: cast to restricted __le32
--
>> drivers/scsi/linkdata/ps3stor/ps3_event.c:23:16: sparse: sparse: symbol 'ps3_event_code_pd_count' was not declared. Should it be static?
>> drivers/scsi/linkdata/ps3stor/ps3_event.c:39:16: sparse: sparse: symbol 'ps3_event_code_pd_attr' was not declared. Should it be static?
>> drivers/scsi/linkdata/ps3stor/ps3_event.c:54:16: sparse: sparse: symbol 'ps3_event_code_vd_attr' was not declared. Should it be static?
--
>> drivers/scsi/linkdata/ps3stor/ps3_instance_manager.c:24:22: sparse: sparse: symbol 'g_ps3_host_info' was not declared. Should it be static?
--
>> drivers/scsi/linkdata/ps3stor/ps3_pci.c:436:21: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void volatile [noderef] __iomem *addr @@ got void *reg @@
drivers/scsi/linkdata/ps3stor/ps3_pci.c:436:21: sparse: expected void volatile [noderef] __iomem *addr
drivers/scsi/linkdata/ps3stor/ps3_pci.c:436:21: sparse: got void *reg
>> drivers/scsi/linkdata/ps3stor/ps3_pci.c:456:23: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void const volatile [noderef] __iomem *addr @@ got void *reg @@
drivers/scsi/linkdata/ps3stor/ps3_pci.c:456:23: sparse: expected void const volatile [noderef] __iomem *addr
drivers/scsi/linkdata/ps3stor/ps3_pci.c:456:23: sparse: got void *reg
vim +30 drivers/scsi/linkdata/ps3stor/ps3_mgr_channel.h
97a2bb6ece556f liujie_answer 2024-12-24 23
97a2bb6ece556f liujie_answer 2024-12-24 24 static inline union PS3RespFrame *ps3_cmd_resp_frame_get(struct ps3_cmd *cmd)
97a2bb6ece556f liujie_answer 2024-12-24 25 {
97a2bb6ece556f liujie_answer 2024-12-24 26 return cmd->resp_frame;
97a2bb6ece556f liujie_answer 2024-12-24 27 }
97a2bb6ece556f liujie_answer 2024-12-24 28 static inline unsigned int ps3_cmd_resp_status(struct ps3_cmd *cmd)
97a2bb6ece556f liujie_answer 2024-12-24 29 {
97a2bb6ece556f liujie_answer 2024-12-24 @30 return le32_to_cpu(cmd->resp_frame->normalRespFrame.respStatus);
97a2bb6ece556f liujie_answer 2024-12-24 31 };
97a2bb6ece556f liujie_answer 2024-12-24 32
:::::: The code at line 30 was first introduced by commit
:::::: 97a2bb6ece556f3882263ee8df2b77f10c511311 SCSI: Linkdata: Supports Linkdata HBA/RAID Controllers
:::::: TO: liujie_answer <liujie5(a)linkdatatechnology.com>
:::::: CC: liujie_answer <liujie5(a)linkdatatechnology.com>
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-5.10] BUILD REGRESSION 731227d05f54b13300b28332fabd3f3aaf0950eb
by kernel test robot 14 May '25
by kernel test robot 14 May '25
14 May '25
tree/branch: https://gitee.com/openeuler/kernel.git OLK-5.10
branch HEAD: 731227d05f54b13300b28332fabd3f3aaf0950eb !16242 fuse: support fastpath
Error/Warning (recently discovered and may have been fixed):
https://lore.kernel.org/oe-kbuild-all/202504290538.Gt6tWC7N-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290659.kdYkNrXR-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290828.J8Cynzh6-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504300111.nH5Pw0yV-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504302232.oeU1VyOU-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505021040.redoLH7C-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505021153.ilI6N3GY-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505062356.u2rMcCQF-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505091231.o5lexadJ-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505100150.DG1QGwH3-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505140440.zitmKJqg-lkp@intel.com
./drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c: 682: need linux/version.h
./drivers/net/ethernet/linkdata/sxe/base/compat/sxe_compat.h: 16 linux/version.h not needed.
./drivers/net/ethernet/linkdata/sxevf/base/compat/sxe_compat.h: 16 linux/version.h not needed.
drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c:158:5: warning: no previous prototype for function 'cqm3_lb_send_cmd_box_async' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c:689:5: warning: variable 'cos_num' set but not used [-Wunused-but-set-variable]
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c:342:5: warning: no previous prototype for function 'hinic3_rx_queue_stat_pack' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c:357:5: warning: no previous prototype for function 'hinic3_tx_queue_stat_pack' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c:1678:5: warning: no previous prototype for function 'set_fecparam' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c:1706:5: warning: no previous prototype for function 'get_fecparam' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c:623:6: warning: no previous prototype for function 'print_port_info' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c:802:6: warning: no previous prototype for function 'hinic3_notify_vf_bond_status' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c:832:6: warning: no previous prototype for function 'hinic3_notify_all_vfs_bond_changed' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hinic3_main.c:1211:6: warning: no previous prototype for function 'hinic3_need_proc_link_event' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hinic3_main.c:1258:6: warning: no previous prototype for function 'hinic3_need_proc_bond_event' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c:59:6: warning: variable 'size' set but not used [-Wunused-but-set-variable]
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c:618:6: warning: no previous prototype for function 'hinic3_write_oshr_info' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c:95: warning: Function parameter or member 'instance' not described in 'hinic3_sm_ctr_rd16_clear'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c:1671:6: warning: no previous prototype for function 'hinic3_is_optical_module_mode' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:865:5: warning: no previous prototype for function 'hinic3_global_func_id_hw' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:1796:6: warning: no previous prototype for function 'hinic3_set_func_state' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:1822:6: warning: no previous prototype for function 'slave_host_mgmt_work' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:525:5: warning: no previous prototype for function 'hinic3_pdev_is_virtfn' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:785:5: warning: no previous prototype for function '__set_vroce_func_state' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:826:6: warning: no previous prototype for function 'slave_host_mgmt_vroce_work' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:834:7: warning: no previous prototype for function 'hinic3_get_roce_uld_by_pdev' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c:176:5: warning: no previous prototype for function 'hinic3_pci_sriov_check' [-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:24: warning: Excess function parameter 'author' description in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:24: warning: Excess function parameter 'date' description in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:24: warning: Excess function parameter 'file' description in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:24: warning: Function parameter or member 'buf_len' not described in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:24: warning: Function parameter or member 'buff' not described in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxe/base/trace/sxe_trace.c:21: warning: Excess function parameter 'author' description in 'SXE_FILE_NAME_LEN'
drivers/net/ethernet/linkdata/sxe/base/trace/sxe_trace.c:21: warning: Excess function parameter 'date' description in 'SXE_FILE_NAME_LEN'
drivers/net/ethernet/linkdata/sxe/base/trace/sxe_trace.c:21: warning: Excess function parameter 'file' description in 'SXE_FILE_NAME_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:23: warning: Excess function parameter 'author' description in 'sxe_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:23: warning: Excess function parameter 'date' description in 'sxe_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:23: warning: Excess function parameter 'file' description in 'sxe_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:23: warning: Function parameter or member 'protocol' not described in 'sxe_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:23: warning: Function parameter or member 'skb' not described in 'sxe_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb.c:16: warning: Excess function parameter 'author' description in 'SXE_TC_BWG_PERCENT_PER_CHAN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb.c:16: warning: Excess function parameter 'date' description in 'SXE_TC_BWG_PERCENT_PER_CHAN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb.c:16: warning: Excess function parameter 'file' description in 'SXE_TC_BWG_PERCENT_PER_CHAN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb_nl.c:20: warning: Excess function parameter 'author' description in 'BIT_PFC'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb_nl.c:20: warning: Excess function parameter 'date' description in 'BIT_PFC'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb_nl.c:20: warning: Excess function parameter 'file' description in 'BIT_PFC'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debug.c:18: warning: Excess function parameter 'author' description in 'SKB_DESCRIPTION_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debug.c:18: warning: Excess function parameter 'date' description in 'SKB_DESCRIPTION_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debug.c:18: warning: Excess function parameter 'file' description in 'SKB_DESCRIPTION_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:432:6: error: no previous prototype for 'sxe_debugfs_entries_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:459:6: error: no previous prototype for 'sxe_debugfs_entries_exit' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:465:6: error: no previous prototype for 'sxe_debugfs_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:470:6: error: no previous prototype for 'sxe_debugfs_exit' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c:2022:5: error: no previous prototype for 'sxe_reg_test' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c:2644:5: error: no previous prototype for 'sxe_phys_id_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c:2736:47: error: suggest braces around empty body in an 'if' statement [-Werror=empty-body]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_filter.c:24: warning: cannot understand function prototype: 'struct workqueue_struct *sxe_fnav_workqueue; '
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_cli.c:18: warning: cannot understand function prototype: 'dev_t sxe_cdev_major; '
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_hdc.c:27: warning: cannot understand function prototype: 'atomic_t hdc_available = ATOMIC_INIT(1); '
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1014:6: error: no previous prototype for 'sxe_hw_link_speed_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1033:6: error: no previous prototype for 'sxe_hw_is_link_state_up' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1055:6: error: no previous prototype for 'sxe_hw_mac_pad_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1064:5: error: no previous prototype for 'sxe_hw_fc_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1135:6: error: no previous prototype for 'sxe_fc_autoneg_localcap_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1164:5: error: no previous prototype for 'sxe_hw_pfc_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1256:6: error: no previous prototype for 'sxe_hw_crc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1264:6: error: no previous prototype for 'sxe_hw_loopback_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1276:6: error: no previous prototype for 'sxe_hw_mac_txrx_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1285:6: error: no previous prototype for 'sxe_hw_mac_max_frame_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1298:5: error: no previous prototype for 'sxe_hw_mac_max_frame_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1330:6: error: no previous prototype for 'sxe_hw_fc_tc_high_water_mark_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1335:6: error: no previous prototype for 'sxe_hw_fc_tc_low_water_mark_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1340:6: error: no previous prototype for 'sxe_hw_is_fc_autoneg_disabled' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1345:6: error: no previous prototype for 'sxe_hw_fc_autoneg_disable_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1360:6: error: no previous prototype for 'sxe_hw_fc_requested_mode_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1388:5: error: no previous prototype for 'sxe_hw_rx_mode_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1393:5: error: no previous prototype for 'sxe_hw_pool_rx_mode_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1398:6: error: no previous prototype for 'sxe_hw_rx_mode_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1403:6: error: no previous prototype for 'sxe_hw_pool_rx_mode_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1408:6: error: no previous prototype for 'sxe_hw_rx_lro_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1420:6: error: no previous prototype for 'sxe_hw_rx_nfs_filter_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1428:6: error: no previous prototype for 'sxe_hw_rx_udp_frag_checksum_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1437:6: error: no previous prototype for 'sxe_hw_fc_mac_addr_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1449:5: error: no previous prototype for 'sxe_hw_uc_addr_add' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1484:5: error: no previous prototype for 'sxe_hw_uc_addr_del' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1510:6: error: no previous prototype for 'sxe_hw_mta_hash_table_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1515:6: error: no previous prototype for 'sxe_hw_mta_hash_table_update' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1525:5: error: no previous prototype for 'sxe_hw_mc_filter_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1530:6: error: no previous prototype for 'sxe_hw_mc_filter_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1554:6: error: no previous prototype for 'sxe_hw_uc_addr_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1587:6: error: no previous prototype for 'sxe_hw_vt_ctrl_cfg' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1601:6: error: no previous prototype for 'sxe_hw_vt_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1675:5: error: no previous prototype for 'sxe_hw_vlan_pool_filter_read' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1697:6: error: no previous prototype for 'sxe_hw_vlan_filter_array_write' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1702:5: error: no previous prototype for 'sxe_hw_vlan_filter_array_read' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1707:6: error: no previous prototype for 'sxe_hw_vlan_filter_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1735:5: error: no previous prototype for 'sxe_hw_vlvf_slot_find' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1769:5: error: no previous prototype for 'sxe_hw_vlan_filter_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1836:6: error: no previous prototype for 'sxe_hw_vlan_filter_array_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1910:5: error: no previous prototype for 'sxe_hw_rx_pkt_buf_size_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1915:6: error: no previous prototype for 'sxe_hw_rx_multi_ring_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1996:6: error: no previous prototype for 'sxe_hw_rss_key_set_all' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2004:6: error: no previous prototype for 'sxe_hw_rss_redir_tbl_reg_write' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2009:6: error: no previous prototype for 'sxe_hw_rss_redir_tbl_set_all' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2024:6: error: no previous prototype for 'sxe_hw_rx_cap_switch_on' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2041:6: error: no previous prototype for 'sxe_hw_rx_cap_switch_off' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2070:6: error: no previous prototype for 'sxe_hw_tx_pkt_buf_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2086:6: error: no previous prototype for 'sxe_hw_tx_pkt_buf_size_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2101:6: error: no previous prototype for 'sxe_hw_rx_lro_ack_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2147:6: error: no previous prototype for 'sxe_hw_fnav_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2204:5: error: no previous prototype for 'sxe_hw_fnav_port_mask_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:230:6: error: no previous prototype for 'sxe_hw_no_snoop_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2310:5: error: no previous prototype for 'sxe_hw_fnav_specific_rule_mask_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2445:5: error: no previous prototype for 'sxe_hw_fnav_specific_rule_add' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2469:5: error: no previous prototype for 'sxe_hw_fnav_specific_rule_del' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2500:6: error: no previous prototype for 'sxe_hw_fnav_sample_rule_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2587:5: error: no previous prototype for 'sxe_hw_fnav_sample_rules_table_reinit' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:262:6: error: no previous prototype for 'sxe_hw_uc_addr_pool_del' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2651:5: error: no previous prototype for 'sxe_hw_ptp_systime_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2667:6: error: no previous prototype for 'sxe_hw_ptp_systime_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2676:6: error: no previous prototype for 'sxe_hw_ptp_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2692:6: error: no previous prototype for 'sxe_hw_ptp_rx_timestamp_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2697:6: error: no previous prototype for 'sxe_hw_ptp_tx_timestamp_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2729:5: error: no previous prototype for 'sxe_hw_ptp_rx_timestamp_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2746:6: error: no previous prototype for 'sxe_hw_ptp_is_rx_timestamp_valid' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2758:6: error: no previous prototype for 'sxe_hw_ptp_timestamp_mode_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2782:6: error: no previous prototype for 'sxe_hw_ptp_timestamp_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:283:5: error: no previous prototype for 'sxe_hw_uc_addr_pool_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2922:6: error: no previous prototype for 'sxe_hw_rx_dma_ctrl_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2930:6: error: no previous prototype for 'sxe_hw_rx_dma_lro_ctrl_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2938:6: error: no previous prototype for 'sxe_hw_rx_desc_thresh_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2949:6: error: no previous prototype for 'sxe_hw_rx_ring_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2983:6: error: no previous prototype for 'sxe_hw_rx_ring_switch_not_polling' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2999:6: error: no previous prototype for 'sxe_hw_rx_queue_desc_reg_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3016:6: error: no previous prototype for 'sxe_hw_rx_ring_desc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3030:6: error: no previous prototype for 'sxe_hw_rx_rcv_ctl_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3043:6: error: no previous prototype for 'sxe_hw_rx_lro_ctl_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3111:6: error: no previous prototype for 'sxe_hw_tx_ring_head_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3116:6: error: no previous prototype for 'sxe_hw_tx_ring_tail_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3121:6: error: no previous prototype for 'sxe_hw_tx_ring_desc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3136:6: error: no previous prototype for 'sxe_hw_tx_desc_thresh_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3147:6: error: no previous prototype for 'sxe_hw_all_ring_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3165:6: error: no previous prototype for 'sxe_hw_tx_ring_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3195:6: error: no previous prototype for 'sxe_hw_tx_ring_switch_not_polling' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3209:6: error: no previous prototype for 'sxe_hw_tx_pkt_buf_thresh_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3230:6: error: no previous prototype for 'sxe_hw_tx_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3257:6: error: no previous prototype for 'sxe_hw_vlan_tag_strip_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3279:6: error: no previous prototype for 'sxe_hw_tx_vlan_tag_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3284:5: error: no previous prototype for 'sxe_hw_tx_vlan_insert_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3289:6: error: no previous prototype for 'sxe_hw_tx_ring_info_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3295:6: error: no previous prototype for 'sxe_hw_dcb_rx_bw_alloc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3330:6: error: no previous prototype for 'sxe_hw_dcb_tx_desc_bw_alloc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3360:6: error: no previous prototype for 'sxe_hw_dcb_tx_data_bw_alloc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:337:5: error: no previous prototype for 'sxe_hw_nic_reset' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3397:6: error: no previous prototype for 'sxe_hw_dcb_pfc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3515:6: error: no previous prototype for 'sxe_hw_vt_pool_loopback_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3523:6: error: no previous prototype for 'sxe_hw_pool_rx_ring_drop_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3545:5: error: no previous prototype for 'sxe_hw_rx_pool_bitmap_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3550:6: error: no previous prototype for 'sxe_hw_rx_pool_bitmap_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3555:5: error: no previous prototype for 'sxe_hw_tx_pool_bitmap_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3560:6: error: no previous prototype for 'sxe_hw_tx_pool_bitmap_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3565:6: error: no previous prototype for 'sxe_hw_dcb_max_mem_window_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3570:6: error: no previous prototype for 'sxe_hw_dcb_tx_ring_rate_factor_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3577:6: error: no previous prototype for 'sxe_hw_spoof_count_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3586:6: error: no previous prototype for 'sxe_hw_pool_mac_anti_spoof_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3613:6: error: no previous prototype for 'sxe_hw_rx_drop_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3674:6: error: no previous prototype for 'sxe_hw_dcb_rate_limiter_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:367:6: error: no previous prototype for 'sxe_hw_pf_rst_done_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3990:6: error: no previous prototype for 'sxe_hw_stats_regs_clean' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4099:6: error: no previous prototype for 'sxe_hw_stats_seq_clean' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4115:50: error: suggest braces around empty body in an 'if' statement [-Werror=empty-body]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4125:6: error: no previous prototype for 'sxe_hw_stats_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4301:6: error: no previous prototype for 'sxe_hw_mbx_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4326:6: error: no previous prototype for 'sxe_hw_vf_rst_check' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4342:6: error: no previous prototype for 'sxe_hw_vf_req_check' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4355:6: error: no previous prototype for 'sxe_hw_vf_ack_check' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4389:5: error: no previous prototype for 'sxe_hw_rcv_msg_from_vf' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4419:5: error: no previous prototype for 'sxe_hw_send_msg_to_vf' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4462:6: error: no previous prototype for 'sxe_hw_mbx_mem_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4488:6: error: no previous prototype for 'sxe_hw_pcie_vt_mode_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4497:5: error: no previous prototype for 'sxe_hw_hdc_lock_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4536:6: error: no previous prototype for 'sxe_hw_hdc_lock_release' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4552:6: error: no previous prototype for 'sxe_hw_hdc_fw_ov_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4557:6: error: no previous prototype for 'sxe_hw_hdc_is_fw_over_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4567:6: error: no previous prototype for 'sxe_hw_hdc_packet_send_done' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4573:6: error: no previous prototype for 'sxe_hw_hdc_packet_header_send' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4578:6: error: no previous prototype for 'sxe_hw_hdc_packet_data_dword_send' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4584:5: error: no previous prototype for 'sxe_hw_hdc_fw_ack_header_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4589:5: error: no previous prototype for 'sxe_hw_hdc_packet_data_dword_rcv' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4594:5: error: no previous prototype for 'sxe_hw_hdc_fw_status_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4604:6: error: no previous prototype for 'sxe_hw_hdc_drv_status_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4609:5: error: no previous prototype for 'sxe_hw_hdc_channel_state_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:735:5: error: no previous prototype for 'sxe_hw_pending_irq_read_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:740:6: error: no previous prototype for 'sxe_hw_pending_irq_write_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:745:5: error: no previous prototype for 'sxe_hw_irq_cause_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:765:6: error: no previous prototype for 'sxe_hw_ring_irq_auto_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:775:6: error: no previous prototype for 'sxe_hw_irq_general_reg_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:780:5: error: no previous prototype for 'sxe_hw_irq_general_reg_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:790:6: error: no previous prototype for 'sxe_hw_event_irq_map' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:806:6: error: no previous prototype for 'sxe_hw_ring_irq_map' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:823:6: error: no previous prototype for 'sxe_hw_ring_irq_interval_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:838:6: error: no previous prototype for 'sxe_hw_event_irq_auto_clear_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:843:6: error: no previous prototype for 'sxe_hw_specific_irq_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:848:6: error: no previous prototype for 'sxe_hw_specific_irq_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:876:6: error: no previous prototype for 'sxe_hw_all_irq_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:994:5: error: no previous prototype for 'sxe_hw_link_speed_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ipsec.c:23: warning: cannot understand function prototype: 'const char ipsec_aes_name[] = "rfc4106(gcm(aes))"; '
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:136:5: error: no previous prototype for 'sxe_msi_irq_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:182:6: error: no previous prototype for 'sxe_disable_dcb' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:212:6: error: no previous prototype for 'sxe_disable_rss' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:729:6: error: no previous prototype for 'sxe_lsc_irq_handler' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:745:6: error: no previous prototype for 'sxe_mailbox_irq_handler' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c: linux/moduleparam.h is included more than once.
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c:70:6: error: no previous prototype for 'sxe_allow_inval_mac' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_monitor.c:24: warning: cannot understand function prototype: 'struct workqueue_struct *sxe_fnav_workqueue; '
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c: sxe_netdev.h is included more than once.
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c:40: warning: Excess function parameter 'author' description in 'SXE_HW_REINIT_SRIOV_DELAY'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c:40: warning: Excess function parameter 'date' description in 'SXE_HW_REINIT_SRIOV_DELAY'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c:40: warning: Excess function parameter 'file' description in 'SXE_HW_REINIT_SRIOV_DELAY'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:16: warning: Excess function parameter 'author' description in 'sxe_check_cfg_fault'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:16: warning: Excess function parameter 'date' description in 'sxe_check_cfg_fault'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:16: warning: Excess function parameter 'file' description in 'sxe_check_cfg_fault'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:16: warning: Function parameter or member 'dev' not described in 'sxe_check_cfg_fault'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:16: warning: Function parameter or member 'hw' not described in 'sxe_check_cfg_fault'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_phy.c:733:5: error: no previous prototype for 'sxe_multispeed_sfp_link_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ptp.c:18: warning: Excess function parameter 'author' description in 'sxe_ptp_read'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ptp.c:18: warning: Excess function parameter 'date' description in 'sxe_ptp_read'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ptp.c:18: warning: Excess function parameter 'file' description in 'sxe_ptp_read'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ptp.c:18: warning: Function parameter or member 'cc' not described in 'sxe_ptp_read'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ring.c:18: warning: Excess function parameter 'author' description in 'sxe_rss_num_get'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ring.c:18: warning: Excess function parameter 'date' description in 'sxe_rss_num_get'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ring.c:18: warning: Excess function parameter 'file' description in 'sxe_rss_num_get'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ring.c:18: warning: Function parameter or member 'adapter' not described in 'sxe_rss_num_get'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c:1431:6: error: no previous prototype for 'sxe_headers_cleanup' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c:1569:6: error: no previous prototype for 'sxe_rx_buffer_page_offset_update' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c: sxe_ipsec.h is included more than once.
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c:1552:6: error: no previous prototype for 'sxe_set_vf_link_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c:766:13: error: variable 'ret' set but not used [-Werror=unused-but-set-variable]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:41: warning: Excess function parameter 'author' description in 'SXE_SKB_MIN_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:41: warning: Excess function parameter 'date' description in 'SXE_SKB_MIN_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:41: warning: Excess function parameter 'file' description in 'SXE_SKB_MIN_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_xdp.c:403:6: error: no previous prototype for 'sxe_txrx_ring_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:24: warning: Excess function parameter 'author' description in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:24: warning: Excess function parameter 'date' description in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:24: warning: Excess function parameter 'file' description in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:24: warning: Function parameter or member 'buf_len' not described in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:24: warning: Function parameter or member 'buff' not described in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxevf/base/trace/sxe_trace.c:21: warning: Excess function parameter 'author' description in 'SXE_FILE_NAME_LEN'
drivers/net/ethernet/linkdata/sxevf/base/trace/sxe_trace.c:21: warning: Excess function parameter 'date' description in 'SXE_FILE_NAME_LEN'
drivers/net/ethernet/linkdata/sxevf/base/trace/sxe_trace.c:21: warning: Excess function parameter 'file' description in 'SXE_FILE_NAME_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf.h: sxe_errno.h is included more than once.
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:23: warning: Excess function parameter 'author' description in 'sxevf_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:23: warning: Excess function parameter 'date' description in 'sxevf_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:23: warning: Excess function parameter 'file' description in 'sxevf_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:23: warning: Function parameter or member 'protocol' not described in 'sxevf_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:23: warning: Function parameter or member 'skb' not described in 'sxevf_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_debug.c:18: warning: Excess function parameter 'author' description in 'SKB_DESCRIPTION_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_debug.c:18: warning: Excess function parameter 'date' description in 'SKB_DESCRIPTION_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_debug.c:18: warning: Excess function parameter 'file' description in 'SKB_DESCRIPTION_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ethtool.c:22: warning: Excess function parameter 'author' description in 'SXEVF_DIAG_REGS_TEST'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ethtool.c:22: warning: Excess function parameter 'date' description in 'SXEVF_DIAG_REGS_TEST'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ethtool.c:22: warning: Excess function parameter 'file' description in 'SXEVF_DIAG_REGS_TEST'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c: sxevf.h is included more than once.
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c: sxevf_hw.h is included more than once.
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:160:6: error: no previous prototype for 'sxevf_hw_stop' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:187:6: error: no previous prototype for 'sxevf_msg_write' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:196:5: error: no previous prototype for 'sxevf_msg_read' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:206:5: error: no previous prototype for 'sxevf_mailbox_read' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:211:6: error: no previous prototype for 'sxevf_mailbox_write' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:216:6: error: no previous prototype for 'sxevf_pf_req_irq_trigger' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:221:6: error: no previous prototype for 'sxevf_pf_ack_irq_trigger' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:226:6: error: no previous prototype for 'sxevf_event_irq_map' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:240:6: error: no previous prototype for 'sxevf_specific_irq_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:245:6: error: no previous prototype for 'sxevf_irq_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:251:6: error: no previous prototype for 'sxevf_irq_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:259:6: error: no previous prototype for 'sxevf_hw_ring_irq_map' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:276:6: error: no previous prototype for 'sxevf_ring_irq_interval_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:313:6: error: no previous prototype for 'sxevf_hw_reset' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:324:5: error: no previous prototype for 'sxevf_link_state_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:539:6: error: no previous prototype for 'sxevf_tx_ring_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:594:6: error: no previous prototype for 'sxevf_rx_ring_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:626:6: error: no previous prototype for 'sxevf_rx_ring_desc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:640:6: error: no previous prototype for 'sxevf_rx_rcv_ctl_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:697:6: error: no previous prototype for 'sxevf_32bit_counter_update' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:710:6: error: no previous prototype for 'sxevf_36bit_counter_update' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:726:6: error: no previous prototype for 'sxevf_packet_stats_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:740:6: error: no previous prototype for 'sxevf_stats_init_value_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ipsec.c:21: warning: cannot understand function prototype: 'const char ipsec_aes_name[] = "rfc4106(gcm(aes))"; '
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Excess function parameter 'author' description in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Excess function parameter 'date' description in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Excess function parameter 'file' description in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Function parameter or member 'dev' not described in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Function parameter or member 'napi' not described in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Function parameter or member 'poll' not described in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Function parameter or member 'weight' not described in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:28: warning: Excess function parameter 'author' description in 'SXEVF_MSG_LEVEL_DEFAULT'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:28: warning: Excess function parameter 'date' description in 'SXEVF_MSG_LEVEL_DEFAULT'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:28: warning: Excess function parameter 'file' description in 'SXEVF_MSG_LEVEL_DEFAULT'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_monitor.c:19: warning: Excess function parameter 'author' description in 'SXEVF_CHECK_LINK_TIMER_PERIOD'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_monitor.c:19: warning: Excess function parameter 'date' description in 'SXEVF_CHECK_LINK_TIMER_PERIOD'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_monitor.c:19: warning: Excess function parameter 'file' description in 'SXEVF_CHECK_LINK_TIMER_PERIOD'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_msg.c:20: warning: Excess function parameter 'author' description in 'SXEVF_PFMSG_MASK'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_msg.c:20: warning: Excess function parameter 'date' description in 'SXEVF_PFMSG_MASK'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_msg.c:20: warning: Excess function parameter 'file' description in 'SXEVF_PFMSG_MASK'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c: sxevf_hw.h is included more than once.
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c:32: warning: Excess function parameter 'author' description in 'SXEVF_MAX_MAC_HDR_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c:32: warning: Excess function parameter 'date' description in 'SXEVF_MAX_MAC_HDR_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c:32: warning: Excess function parameter 'file' description in 'SXEVF_MAX_MAC_HDR_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ring.c:19: warning: Excess function parameter 'author' description in 'sxevf_ring_feature_init'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ring.c:19: warning: Excess function parameter 'date' description in 'sxevf_ring_feature_init'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ring.c:19: warning: Excess function parameter 'file' description in 'sxevf_ring_feature_init'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ring.c:19: warning: Function parameter or member 'adapter' not described in 'sxevf_ring_feature_init'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_rx_proc.c:362:6: error: no previous prototype for 'sxevf_rx_ring_buffers_alloc' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:127:5: error: no previous prototype for 'sxevf_tx_ring_alloc' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:703:66: error: suggest braces around empty body in an 'if' statement [-Werror=empty-body]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:838:71: error: suggest braces around empty body in an 'else' statement [-Werror=empty-body]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:88:6: error: no previous prototype for 'sxevf_tx_ring_free' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:23: warning: Excess function parameter 'author' description in 'bpf_warn_invalid_xdp_action_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:23: warning: Excess function parameter 'date' description in 'bpf_warn_invalid_xdp_action_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:23: warning: Excess function parameter 'file' description in 'bpf_warn_invalid_xdp_action_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:23: warning: Function parameter or member 'act' not described in 'bpf_warn_invalid_xdp_action_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:23: warning: Function parameter or member 'dev' not described in 'bpf_warn_invalid_xdp_action_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:23: warning: Function parameter or member 'prog' not described in 'bpf_warn_invalid_xdp_action_compat'
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.o: warning: objtool: mlxsw_sp_neigh_entry_update()+0x26f: unreachable instruction
include/linux/backing-dev.h:430:49: warning: 'struct cgroup_subsys' declared inside parameter list will not be visible outside of this definition or declaration
include/linux/backing-dev.h:430:49: warning: declaration of 'struct cgroup_subsys' will not be visible outside of this function [-Wvisibility]
include/linux/blk_types.h: linux/kabi.h is included more than once.
include/linux/cred.h: linux/kabi.h is included more than once.
include/linux/device.h: linux/kabi.h is included more than once.
include/linux/device/class.h: linux/kabi.h is included more than once.
include/linux/ioport.h: linux/kabi.h is included more than once.
include/linux/minmax.h:20:35: warning: comparison of distinct pointer types lacks a cast
include/linux/mm.h: linux/kabi.h is included more than once.
include/linux/swap.h: linux/kabi.h is included more than once.
llvm-objcopy: error: 'arch/x86/entry/vdso/vdso64.so.dbg': No such file or directory
llvm-objdump: error: 'arch/x86/entry/vdso/vdso64.so.dbg': No such file or directory
samples/bpf/hbm.c: bpf/bpf.h is included more than once.
Unverified Error/Warning (likely false positive, kindly check if interested):
drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h: net/devlink.h is included more than once.
drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.o: warning: objtool: mlx5_chains_put_table()+0x38f: unreachable instruction
Error/Warning ids grouped by kconfigs:
recent_errors
|-- arm64-allnoconfig
| `-- include-linux-backing-dev.h:warning:struct-cgroup_subsys-declared-inside-parameter-list-will-not-be-visible-outside-of-this-definition-or-declaration
|-- x86_64-allnoconfig
| |-- drivers-net-ethernet-huawei-hinic3-cqm-cqm_memsec.c::need-linux-version.h
| |-- drivers-net-ethernet-huawei-hinic3-ossl_knl_linux.h:net-devlink.h-is-included-more-than-once.
| |-- drivers-net-ethernet-linkdata-sxe-base-compat-sxe_compat.h:linux-version.h-not-needed.
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:linux-moduleparam.h-is-included-more-than-once.
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:sxe_netdev.h-is-included-more-than-once.
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:sxe_ipsec.h-is-included-more-than-once.
| |-- drivers-net-ethernet-linkdata-sxevf-base-compat-sxe_compat.h:linux-version.h-not-needed.
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf.h:sxe_errno.h-is-included-more-than-once.
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:sxevf.h-is-included-more-than-once.
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:sxevf_hw.h-is-included-more-than-once.
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:sxevf_hw.h-is-included-more-than-once.
| |-- include-linux-backing-dev.h:warning:declaration-of-struct-cgroup_subsys-will-not-be-visible-outside-of-this-function
| |-- include-linux-blk_types.h:linux-kabi.h-is-included-more-than-once.
| |-- include-linux-cred.h:linux-kabi.h-is-included-more-than-once.
| |-- include-linux-device-class.h:linux-kabi.h-is-included-more-than-once.
| |-- include-linux-device.h:linux-kabi.h-is-included-more-than-once.
| |-- include-linux-ioport.h:linux-kabi.h-is-included-more-than-once.
| |-- include-linux-mm.h:linux-kabi.h-is-included-more-than-once.
| |-- include-linux-swap.h:linux-kabi.h-is-included-more-than-once.
| `-- samples-bpf-hbm.c:bpf-bpf.h-is-included-more-than-once.
|-- x86_64-allyesconfig
| |-- drivers-net-ethernet-huawei-hinic3-cqm-cqm_cmd.c:warning:no-previous-prototype-for-function-cqm3_lb_send_cmd_box_async
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_dbg.c:warning:variable-cos_num-set-but-not-used
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_ethtool_stats.c:warning:no-previous-prototype-for-function-hinic3_rx_queue_stat_pack
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_ethtool_stats.c:warning:no-previous-prototype-for-function-hinic3_tx_queue_stat_pack
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_mag_cfg.c:warning:no-previous-prototype-for-function-get_fecparam
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_mag_cfg.c:warning:no-previous-prototype-for-function-hinic3_notify_all_vfs_bond_changed
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_mag_cfg.c:warning:no-previous-prototype-for-function-hinic3_notify_vf_bond_status
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_mag_cfg.c:warning:no-previous-prototype-for-function-print_port_info
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_mag_cfg.c:warning:no-previous-prototype-for-function-set_fecparam
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_main.c:warning:no-previous-prototype-for-function-hinic3_need_proc_bond_event
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_main.c:warning:no-previous-prototype-for-function-hinic3_need_proc_link_event
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_netdev_ops.c:warning:variable-size-set-but-not-used
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_dev_mgmt.c:warning:no-previous-prototype-for-function-hinic3_write_oshr_info
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_hw_api.c:warning:Function-parameter-or-member-instance-not-described-in-hinic3_sm_ctr_rd16_clear
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_hw_comm.c:warning:no-previous-prototype-for-function-hinic3_is_optical_module_mode
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_hwif.c:warning:no-previous-prototype-for-function-hinic3_global_func_id_hw
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_lld.c:warning:no-previous-prototype-for-function-__set_vroce_func_state
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_lld.c:warning:no-previous-prototype-for-function-hinic3_get_roce_uld_by_pdev
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_lld.c:warning:no-previous-prototype-for-function-hinic3_pdev_is_virtfn
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_lld.c:warning:no-previous-prototype-for-function-hinic3_set_func_state
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_lld.c:warning:no-previous-prototype-for-function-slave_host_mgmt_vroce_work
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_lld.c:warning:no-previous-prototype-for-function-slave_host_mgmt_work
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_sriov.c:warning:no-previous-prototype-for-function-hinic3_pci_sriov_check
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-author-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-date-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-file-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-author-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-date-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-file-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-author-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-date-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-file-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:cannot-understand-function-prototype:dev_t-sxe_cdev_major
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:cannot-understand-function-prototype:atomic_t-hdc_available-ATOMIC_INIT()
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-author-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-date-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-file-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-author-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-date-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-file-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-dev-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-hw-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-author-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-date-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-file-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Function-parameter-or-member-cc-not-described-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-author-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-date-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-file-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-author-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-date-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-file-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-author-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-date-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-file-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-author-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-date-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-file-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-author-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-date-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-file-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-dev-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-napi-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-poll-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-weight-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-author-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-date-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-file-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-author-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-date-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-file-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-author-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-date-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-file-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-author-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-date-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-file-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-author-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-date-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-file-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-author-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-date-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-file-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-act-not-described-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-dev-not-described-in-bpf_warn_invalid_xdp_action_compat
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-prog-not-described-in-bpf_warn_invalid_xdp_action_compat
|-- x86_64-buildonly-randconfig-002-20250513
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-author-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-date-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-file-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-author-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-date-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-file-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-author-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-date-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-file-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_entries_exit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_entries_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_exit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-sxe_phys_id_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-sxe_reg_test
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:cannot-understand-function-prototype:dev_t-sxe_cdev_major
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:cannot-understand-function-prototype:atomic_t-hdc_available-ATOMIC_INIT()
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_fc_autoneg_localcap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_all_irq_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_all_ring_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_crc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_max_mem_window_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_pfc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_rate_limiter_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_rx_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_data_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_desc_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_ring_rate_factor_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_event_irq_auto_clear_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_event_irq_map
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_autoneg_disable_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_mac_addr_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_requested_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_tc_high_water_mark_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_tc_low_water_mark_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_port_mask_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_sample_rule_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_sample_rules_table_reinit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_add
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_mask_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_channel_state_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_drv_status_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_ack_header_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_ov_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_status_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_is_fw_over_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_lock_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_lock_release
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_data_dword_rcv
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_data_dword_send
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_header_send
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_send_done
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_cause_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_general_reg_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_general_reg_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_is_fc_autoneg_disabled
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_is_link_state_up
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_link_speed_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_link_speed_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_loopback_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_max_frame_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_max_frame_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_pad_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_txrx_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mbx_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mbx_mem_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mc_filter_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mc_filter_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mta_hash_table_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mta_hash_table_update
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_nic_reset
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_no_snoop_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pcie_vt_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pending_irq_read_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pending_irq_write_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pf_rst_done_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pfc_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_mac_anti_spoof_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_mode_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_ring_drop_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_is_rx_timestamp_valid
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_rx_timestamp_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_rx_timestamp_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_systime_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_systime_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_timestamp_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_timestamp_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_tx_timestamp_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rcv_msg_from_vf
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_auto_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_interval_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_map
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_key_set_all
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_redir_tbl_reg_write
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_redir_tbl_set_all
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_cap_switch_off
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_cap_switch_on
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_desc_thresh_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_dma_ctrl_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_dma_lro_ctrl_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_drop_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_ack_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_mode_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_multi_ring_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_nfs_filter_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pkt_buf_size_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pool_bitmap_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pool_bitmap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_queue_desc_reg_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_rcv_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_switch_not_polling
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_udp_frag_checksum_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_send_msg_to_vf
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_specific_irq_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_specific_irq_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_spoof_count_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_regs_clean
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_seq_clean
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_desc_thresh_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_size_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_thresh_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pool_bitmap_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pool_bitmap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_head_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_info_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_switch_not_polling
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_tail_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_vlan_insert_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_vlan_tag_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_add
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_pool_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_pool_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_ack_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_req_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_rst_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_write
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_pool_filter_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_tag_strip_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlvf_slot_find
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_ctrl_cfg
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_pool_loopback_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_disable_dcb
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_disable_rss
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_lsc_irq_handler
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_mailbox_irq_handler
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_msi_irq_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-sxe_allow_inval_mac
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-author-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-date-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-file-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-author-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-date-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-file-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-dev-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-hw-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-sxe_multispeed_sfp_link_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-author-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-date-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-file-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Function-parameter-or-member-cc-not-described-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-author-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-date-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-file-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-sxe_headers_cleanup
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-sxe_rx_buffer_page_offset_update
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-sxe_set_vf_link_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-author-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-date-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-file-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-sxe_txrx_ring_enable
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-author-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-date-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-file-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-author-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-date-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-file-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_32bit_counter_update
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_36bit_counter_update
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_event_irq_map
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_reset
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_ring_irq_map
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_stop
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_irq_disable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_irq_enable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_link_state_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_mailbox_read
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_mailbox_write
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_msg_read
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_msg_write
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_packet_stats_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_pf_ack_irq_trigger
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_pf_req_irq_trigger
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_ring_irq_interval_set
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_rcv_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_specific_irq_enable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_stats_init_value_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_tx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-author-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-date-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-file-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-dev-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-napi-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-poll-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-weight-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-author-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-date-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-file-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-author-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-date-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-file-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-author-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-date-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-file-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-author-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-date-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-file-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-author-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-date-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-file-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-sxevf_rx_ring_buffers_alloc
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-sxevf_tx_ring_alloc
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-sxevf_tx_ring_free
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:suggest-braces-around-empty-body-in-an-else-statement
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-author-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-date-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-file-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-act-not-described-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-dev-not-described-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-prog-not-described-in-bpf_warn_invalid_xdp_action_compat
| `-- include-linux-backing-dev.h:warning:struct-cgroup_subsys-declared-inside-parameter-list-will-not-be-visible-outside-of-this-definition-or-declaration
|-- x86_64-buildonly-randconfig-003-20250513
| |-- include-linux-backing-dev.h:warning:declaration-of-struct-cgroup_subsys-will-not-be-visible-outside-of-this-function
| |-- llvm-objcopy:error:arch-x86-entry-vdso-vdso64.so.dbg:No-such-file-or-directory
| `-- llvm-objdump:error:arch-x86-entry-vdso-vdso64.so.dbg:No-such-file-or-directory
|-- x86_64-buildonly-randconfig-006-20250513
| `-- include-linux-minmax.h:warning:comparison-of-distinct-pointer-types-lacks-a-cast
|-- x86_64-defconfig
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-author-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-date-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-file-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-author-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-date-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-file-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-author-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-date-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-file-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_entries_exit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_entries_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_exit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-sxe_phys_id_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-sxe_reg_test
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:cannot-understand-function-prototype:dev_t-sxe_cdev_major
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:cannot-understand-function-prototype:atomic_t-hdc_available-ATOMIC_INIT()
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_fc_autoneg_localcap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_all_irq_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_all_ring_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_crc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_max_mem_window_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_pfc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_rate_limiter_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_rx_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_data_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_desc_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_ring_rate_factor_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_event_irq_auto_clear_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_event_irq_map
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_autoneg_disable_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_mac_addr_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_requested_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_tc_high_water_mark_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_tc_low_water_mark_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_port_mask_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_sample_rule_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_sample_rules_table_reinit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_add
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_mask_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_channel_state_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_drv_status_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_ack_header_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_ov_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_status_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_is_fw_over_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_lock_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_lock_release
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_data_dword_rcv
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_data_dword_send
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_header_send
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_send_done
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_cause_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_general_reg_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_general_reg_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_is_fc_autoneg_disabled
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_is_link_state_up
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_link_speed_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_link_speed_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_loopback_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_max_frame_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_max_frame_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_pad_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_txrx_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mbx_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mbx_mem_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mc_filter_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mc_filter_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mta_hash_table_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mta_hash_table_update
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_nic_reset
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_no_snoop_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pcie_vt_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pending_irq_read_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pending_irq_write_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pf_rst_done_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pfc_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_mac_anti_spoof_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_mode_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_ring_drop_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_is_rx_timestamp_valid
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_rx_timestamp_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_rx_timestamp_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_systime_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_systime_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_timestamp_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_timestamp_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_tx_timestamp_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rcv_msg_from_vf
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_auto_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_interval_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_map
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_key_set_all
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_redir_tbl_reg_write
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_redir_tbl_set_all
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_cap_switch_off
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_cap_switch_on
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_desc_thresh_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_dma_ctrl_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_dma_lro_ctrl_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_drop_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_ack_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_mode_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_multi_ring_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_nfs_filter_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pkt_buf_size_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pool_bitmap_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pool_bitmap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_queue_desc_reg_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_rcv_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_switch_not_polling
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_udp_frag_checksum_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_send_msg_to_vf
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_specific_irq_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_specific_irq_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_spoof_count_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_regs_clean
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_seq_clean
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_desc_thresh_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_size_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_thresh_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pool_bitmap_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pool_bitmap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_head_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_info_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_switch_not_polling
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_tail_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_vlan_insert_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_vlan_tag_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_add
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_pool_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_pool_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_ack_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_req_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_rst_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_write
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_pool_filter_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_tag_strip_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlvf_slot_find
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_ctrl_cfg
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_pool_loopback_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_disable_dcb
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_disable_rss
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_lsc_irq_handler
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_mailbox_irq_handler
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_msi_irq_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-sxe_allow_inval_mac
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-author-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-date-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-file-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-author-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-date-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-file-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-dev-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-hw-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-sxe_multispeed_sfp_link_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-author-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-date-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-file-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Function-parameter-or-member-cc-not-described-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-author-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-date-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-file-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-sxe_headers_cleanup
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-sxe_rx_buffer_page_offset_update
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-sxe_set_vf_link_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-author-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-date-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-file-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-sxe_txrx_ring_enable
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-author-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-date-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-file-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-author-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-date-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-file-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_32bit_counter_update
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_36bit_counter_update
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_event_irq_map
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_reset
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_ring_irq_map
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_stop
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_irq_disable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_irq_enable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_link_state_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_mailbox_read
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_mailbox_write
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_msg_read
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_msg_write
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_packet_stats_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_pf_ack_irq_trigger
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_pf_req_irq_trigger
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_ring_irq_interval_set
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_rcv_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_specific_irq_enable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_stats_init_value_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_tx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-author-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-date-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-file-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-dev-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-napi-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-poll-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-weight-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-author-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-date-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-file-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-author-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-date-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-file-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-author-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-date-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-file-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-author-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-date-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-file-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-author-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-date-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-file-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-sxevf_rx_ring_buffers_alloc
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-sxevf_tx_ring_alloc
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-sxevf_tx_ring_free
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:suggest-braces-around-empty-body-in-an-else-statement
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-author-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-date-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-file-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-act-not-described-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-dev-not-described-in-bpf_warn_invalid_xdp_action_compat
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-prog-not-described-in-bpf_warn_invalid_xdp_action_compat
|-- x86_64-randconfig-161-20250514
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-author-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-date-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-file-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-author-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-date-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-file-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-author-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-date-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-file-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_entries_exit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_entries_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_exit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-sxe_phys_id_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-sxe_reg_test
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:cannot-understand-function-prototype:dev_t-sxe_cdev_major
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:cannot-understand-function-prototype:atomic_t-hdc_available-ATOMIC_INIT()
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_fc_autoneg_localcap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_all_irq_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_all_ring_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_crc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_max_mem_window_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_pfc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_rate_limiter_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_rx_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_data_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_desc_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_ring_rate_factor_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_event_irq_auto_clear_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_event_irq_map
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_autoneg_disable_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_mac_addr_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_requested_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_tc_high_water_mark_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_tc_low_water_mark_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_port_mask_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_sample_rule_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_sample_rules_table_reinit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_add
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_mask_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_channel_state_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_drv_status_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_ack_header_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_ov_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_status_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_is_fw_over_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_lock_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_lock_release
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_data_dword_rcv
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_data_dword_send
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_header_send
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_send_done
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_cause_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_general_reg_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_general_reg_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_is_fc_autoneg_disabled
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_is_link_state_up
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_link_speed_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_link_speed_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_loopback_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_max_frame_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_max_frame_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_pad_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_txrx_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mbx_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mbx_mem_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mc_filter_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mc_filter_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mta_hash_table_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mta_hash_table_update
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_nic_reset
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_no_snoop_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pcie_vt_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pending_irq_read_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pending_irq_write_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pf_rst_done_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pfc_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_mac_anti_spoof_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_mode_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_ring_drop_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_is_rx_timestamp_valid
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_rx_timestamp_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_rx_timestamp_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_systime_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_systime_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_timestamp_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_timestamp_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_tx_timestamp_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rcv_msg_from_vf
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_auto_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_interval_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_map
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_key_set_all
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_redir_tbl_reg_write
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_redir_tbl_set_all
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_cap_switch_off
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_cap_switch_on
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_desc_thresh_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_dma_ctrl_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_dma_lro_ctrl_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_drop_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_ack_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_mode_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_multi_ring_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_nfs_filter_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pkt_buf_size_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pool_bitmap_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pool_bitmap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_queue_desc_reg_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_rcv_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_switch_not_polling
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_udp_frag_checksum_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_send_msg_to_vf
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_specific_irq_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_specific_irq_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_spoof_count_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_regs_clean
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_seq_clean
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_desc_thresh_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_size_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_thresh_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pool_bitmap_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pool_bitmap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_head_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_info_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_switch_not_polling
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_tail_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_vlan_insert_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_vlan_tag_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_add
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_pool_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_pool_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_ack_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_req_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_rst_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_write
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_pool_filter_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_tag_strip_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlvf_slot_find
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_ctrl_cfg
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_pool_loopback_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_disable_dcb
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_disable_rss
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_lsc_irq_handler
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_mailbox_irq_handler
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_msi_irq_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-sxe_allow_inval_mac
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-author-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-date-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-file-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-author-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-date-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-file-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-dev-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-hw-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-sxe_multispeed_sfp_link_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-author-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-date-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-file-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Function-parameter-or-member-cc-not-described-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-author-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-date-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-file-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-sxe_headers_cleanup
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-sxe_rx_buffer_page_offset_update
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-sxe_set_vf_link_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-author-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-date-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-file-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-sxe_txrx_ring_enable
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-author-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-date-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-file-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-author-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-date-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-file-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_32bit_counter_update
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_36bit_counter_update
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_event_irq_map
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_reset
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_ring_irq_map
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_stop
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_irq_disable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_irq_enable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_link_state_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_mailbox_read
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_mailbox_write
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_msg_read
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_msg_write
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_packet_stats_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_pf_ack_irq_trigger
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_pf_req_irq_trigger
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_ring_irq_interval_set
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_rcv_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_specific_irq_enable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_stats_init_value_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_tx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-author-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-date-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-file-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-dev-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-napi-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-poll-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-weight-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-author-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-date-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-file-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-author-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-date-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-file-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-author-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-date-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-file-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-author-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-date-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-file-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-author-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-date-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-file-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-sxevf_rx_ring_buffers_alloc
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-sxevf_tx_ring_alloc
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-sxevf_tx_ring_free
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:suggest-braces-around-empty-body-in-an-else-statement
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-author-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-date-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-file-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-act-not-described-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-dev-not-described-in-bpf_warn_invalid_xdp_action_compat
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-prog-not-described-in-bpf_warn_invalid_xdp_action_compat
|-- x86_64-randconfig-r121-20250514
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-author-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-date-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-file-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-author-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-date-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-file-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-author-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-date-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-file-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_entries_exit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_entries_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_exit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-sxe_phys_id_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-sxe_reg_test
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:sparse:sparse:symbol-sxe_cdev_fops-was-not-declared.-Should-it-be-static
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:cannot-understand-function-prototype:dev_t-sxe_cdev_major
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:sparse:sparse:symbol-g_hdc_sema-was-not-declared.-Should-it-be-static
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:cannot-understand-function-prototype:atomic_t-hdc_available-ATOMIC_INIT()
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_fc_autoneg_localcap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_all_irq_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_all_ring_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_crc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_max_mem_window_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_pfc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_rate_limiter_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_rx_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_data_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_desc_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_ring_rate_factor_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_event_irq_auto_clear_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_event_irq_map
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_autoneg_disable_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_mac_addr_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_requested_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_tc_high_water_mark_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_tc_low_water_mark_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_port_mask_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_sample_rule_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_sample_rules_table_reinit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_add
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_mask_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_channel_state_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_drv_status_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_ack_header_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_ov_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_status_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_is_fw_over_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_lock_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_lock_release
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_data_dword_rcv
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_data_dword_send
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_header_send
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_send_done
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_cause_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_general_reg_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_general_reg_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_is_fc_autoneg_disabled
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_is_link_state_up
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_link_speed_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_link_speed_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_loopback_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_max_frame_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_max_frame_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_pad_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_txrx_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mbx_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mbx_mem_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mc_filter_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mc_filter_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mta_hash_table_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mta_hash_table_update
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_nic_reset
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_no_snoop_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pcie_vt_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pending_irq_read_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pending_irq_write_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pf_rst_done_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pfc_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_mac_anti_spoof_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_mode_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_ring_drop_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_is_rx_timestamp_valid
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_rx_timestamp_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_rx_timestamp_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_systime_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_systime_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_timestamp_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_timestamp_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_tx_timestamp_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rcv_msg_from_vf
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_auto_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_interval_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_map
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_key_set_all
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_redir_tbl_reg_write
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_redir_tbl_set_all
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_cap_switch_off
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_cap_switch_on
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_desc_thresh_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_dma_ctrl_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_dma_lro_ctrl_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_drop_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_ack_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_mode_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_multi_ring_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_nfs_filter_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pkt_buf_size_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pool_bitmap_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pool_bitmap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_queue_desc_reg_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_rcv_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_switch_not_polling
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_udp_frag_checksum_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_send_msg_to_vf
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_specific_irq_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_specific_irq_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_spoof_count_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_regs_clean
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_seq_clean
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_desc_thresh_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_size_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_thresh_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pool_bitmap_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pool_bitmap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_head_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_info_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_switch_not_polling
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_tail_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_vlan_insert_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_vlan_tag_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_add
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_pool_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_pool_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_ack_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_req_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_rst_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_write
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_pool_filter_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_tag_strip_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlvf_slot_find
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_ctrl_cfg
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_pool_loopback_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_disable_dcb
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_disable_rss
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_lsc_irq_handler
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_mailbox_irq_handler
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_msi_irq_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-sxe_allow_inval_mac
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-author-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-date-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-file-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-author-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-date-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-file-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-dev-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-hw-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-sxe_multispeed_sfp_link_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-author-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-date-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-file-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Function-parameter-or-member-cc-not-described-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-author-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-date-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-file-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-sxe_headers_cleanup
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-sxe_rx_buffer_page_offset_update
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-sxe_set_vf_link_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:sparse:sparse:cast-from-restricted-__le32
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:sparse:sparse:invalid-assignment:
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-author-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-date-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-file-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.h:sparse:sparse:incorrect-type-in-assignment-(different-base-types)-expected-restricted-__le32-usertype-mss_l4len_idx-got-unsigned-int-usertype-mss_
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.h:sparse:sparse:invalid-assignment:
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-sxe_txrx_ring_enable
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-author-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-date-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-file-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-author-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-date-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-file-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_32bit_counter_update
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_36bit_counter_update
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_event_irq_map
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_reset
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_ring_irq_map
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_stop
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_irq_disable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_irq_enable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_link_state_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_mailbox_read
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_mailbox_write
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_msg_read
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_msg_write
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_packet_stats_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_pf_ack_irq_trigger
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_pf_req_irq_trigger
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_ring_irq_interval_set
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_rcv_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_specific_irq_enable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_stats_init_value_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_tx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-author-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-date-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-file-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-dev-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-napi-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-poll-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-weight-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-const-volatile-noderef-__iomem-addr-got-void-const-reg
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:sparse:sparse:incorrect-type-in-argument-(different-address-spaces)-expected-void-volatile-noderef-__iomem-addr-got-void-reg
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:sparse:sparse:symbol-g_netdev-was-not-declared.-Should-it-be-static
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-author-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-date-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-file-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-author-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-date-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-file-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-author-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-date-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-file-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-author-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-date-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-file-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-author-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-date-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-file-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-sxevf_rx_ring_buffers_alloc
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-sxevf_tx_ring_alloc
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-sxevf_tx_ring_free
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:suggest-braces-around-empty-body-in-an-else-statement
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.h:sparse:sparse:invalid-assignment:
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-author-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-date-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-file-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-act-not-described-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-dev-not-described-in-bpf_warn_invalid_xdp_action_compat
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-prog-not-described-in-bpf_warn_invalid_xdp_action_compat
|-- x86_64-randconfig-r133-20250514
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-author-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-date-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-file-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-author-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-date-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-file-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-author-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-date-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-file-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:cannot-understand-function-prototype:dev_t-sxe_cdev_major
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:cannot-understand-function-prototype:atomic_t-hdc_available-ATOMIC_INIT()
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-author-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-date-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-file-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-author-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-date-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-file-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-dev-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-hw-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-author-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-date-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-file-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Function-parameter-or-member-cc-not-described-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-author-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-date-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-file-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-author-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-date-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-file-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-author-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-date-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-file-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-author-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-date-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-file-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-author-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-date-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-file-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-dev-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-napi-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-poll-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-weight-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-author-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-date-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-file-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-author-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-date-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-file-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-author-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-date-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-file-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-author-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-date-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-file-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-author-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-date-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-file-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-author-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-date-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-file-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-act-not-described-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-dev-not-described-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-prog-not-described-in-bpf_warn_invalid_xdp_action_compat
| |-- llvm-objcopy:error:arch-x86-entry-vdso-vdso64.so.dbg:No-such-file-or-directory
| `-- llvm-objdump:error:arch-x86-entry-vdso-vdso64.so.dbg:No-such-file-or-directory
`-- x86_64-rhel-9.4-rust
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
|-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
|-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-author-description-in-sxe_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-date-description-in-sxe_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-file-description-in-sxe_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxe_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxe_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-author-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-date-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-file-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-author-description-in-BIT_PFC
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-date-description-in-BIT_PFC
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-file-description-in-BIT_PFC
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:cannot-understand-function-prototype:dev_t-sxe_cdev_major
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:cannot-understand-function-prototype:atomic_t-hdc_available-ATOMIC_INIT()
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-author-description-in-SXE_HW_REINIT_SRIOV_DELAY
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-date-description-in-SXE_HW_REINIT_SRIOV_DELAY
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-file-description-in-SXE_HW_REINIT_SRIOV_DELAY
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-author-description-in-sxe_check_cfg_fault
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-date-description-in-sxe_check_cfg_fault
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-file-description-in-sxe_check_cfg_fault
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-dev-not-described-in-sxe_check_cfg_fault
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-hw-not-described-in-sxe_check_cfg_fault
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-author-description-in-sxe_ptp_read
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-date-description-in-sxe_ptp_read
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-file-description-in-sxe_ptp_read
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Function-parameter-or-member-cc-not-described-in-sxe_ptp_read
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-author-description-in-sxe_rss_num_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-date-description-in-sxe_rss_num_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-file-description-in-sxe_rss_num_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxe_rss_num_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-author-description-in-SXE_SKB_MIN_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-date-description-in-SXE_SKB_MIN_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-file-description-in-SXE_SKB_MIN_LEN
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
|-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
|-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-author-description-in-sxevf_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-date-description-in-sxevf_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-file-description-in-sxevf_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxevf_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxevf_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-author-description-in-SXEVF_DIAG_REGS_TEST
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-date-description-in-SXEVF_DIAG_REGS_TEST
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-file-description-in-SXEVF_DIAG_REGS_TEST
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-author-description-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-date-description-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-file-description-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-dev-not-described-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-napi-not-described-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-poll-not-described-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-weight-not-described-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-author-description-in-SXEVF_MSG_LEVEL_DEFAULT
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-date-description-in-SXEVF_MSG_LEVEL_DEFAULT
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-file-description-in-SXEVF_MSG_LEVEL_DEFAULT
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-author-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-date-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-file-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-author-description-in-SXEVF_PFMSG_MASK
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-date-description-in-SXEVF_PFMSG_MASK
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-file-description-in-SXEVF_PFMSG_MASK
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-author-description-in-SXEVF_MAX_MAC_HDR_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-date-description-in-SXEVF_MAX_MAC_HDR_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-file-description-in-SXEVF_MAX_MAC_HDR_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-author-description-in-sxevf_ring_feature_init
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-date-description-in-sxevf_ring_feature_init
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-file-description-in-sxevf_ring_feature_init
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxevf_ring_feature_init
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-author-description-in-bpf_warn_invalid_xdp_action_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-date-description-in-bpf_warn_invalid_xdp_action_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-file-description-in-bpf_warn_invalid_xdp_action_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-act-not-described-in-bpf_warn_invalid_xdp_action_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-dev-not-described-in-bpf_warn_invalid_xdp_action_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-prog-not-described-in-bpf_warn_invalid_xdp_action_compat
|-- drivers-net-ethernet-mellanox-mlx5-core-lib-fs_chains.o:warning:objtool:mlx5_chains_put_table:unreachable-instruction
`-- drivers-net-ethernet-mellanox-mlxsw-spectrum_router.o:warning:objtool:mlxsw_sp_neigh_entry_update:unreachable-instruction
elapsed time: 731m
configs tested: 16
configs skipped: 128
tested configs:
arm64 allmodconfig clang-19
arm64 allnoconfig gcc-14.2.0
arm64 randconfig-001-20250513 clang-21
arm64 randconfig-002-20250513 clang-21
arm64 randconfig-003-20250513 gcc-6.5.0
arm64 randconfig-004-20250513 clang-21
x86_64 allnoconfig clang-20
x86_64 allyesconfig clang-20
x86_64 buildonly-randconfig-001-20250513 gcc-12
x86_64 buildonly-randconfig-002-20250513 gcc-12
x86_64 buildonly-randconfig-003-20250513 clang-20
x86_64 buildonly-randconfig-004-20250513 gcc-12
x86_64 buildonly-randconfig-005-20250513 clang-20
x86_64 buildonly-randconfig-006-20250513 gcc-12
x86_64 defconfig gcc-11
x86_64 rhel-9.4-rust clang-18
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-5.10 2893/2893] llvm-objdump: error: 'arch/x86/entry/vdso/vdso64.so.dbg': No such file or directory
by kernel test robot 14 May '25
by kernel test robot 14 May '25
14 May '25
Hi Sean,
FYI, the error/warning still remains.
tree: https://gitee.com/openeuler/kernel.git OLK-5.10
head: 731227d05f54b13300b28332fabd3f3aaf0950eb
commit: 5476cb89ef2297bd36f8b38e27b54617b6f63236 [2893/2893] x86/vdso: Implement a vDSO for Intel SGX enclave call
config: x86_64-buildonly-randconfig-003-20250513 (https://download.01.org/0day-ci/archive/20250514/202505140440.zitmKJqg-lkp@…)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250514/202505140440.zitmKJqg-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505140440.zitmKJqg-lkp@intel.com/
All errors (new ones prefixed by >>):
ld.lld: error: version script assignment of 'LINUX_2.6' to symbol '__vdso_sgx_enter_enclave' failed: symbol not defined
>> llvm-objdump: error: 'arch/x86/entry/vdso/vdso64.so.dbg': No such file or directory
--
>> llvm-objcopy: error: 'arch/x86/entry/vdso/vdso64.so.dbg': No such file or directory
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-6.6 2195/2195] Documentation/devicetree/bindings/gpu/phytium,dc.yaml:40:8: [warning] wrong indentation: expected 2 but found 7 (indentation)
by kernel test robot 13 May '25
by kernel test robot 13 May '25
13 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: 855c2a6945da5d74f3e50d601537000d0989d5a3
commit: ab9ff1e38569313e41ba5a036591f93cb55e5d87 [2195/2195] DRM: Phytium display DRM doc
config: arm64-randconfig-2053-20250504 (https://download.01.org/0day-ci/archive/20250513/202505132302.zMQCF7g7-lkp@…)
compiler: aarch64-linux-gcc (GCC) 9.5.0
dtschema version: 2025.3.dev21+ge6ea659
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250513/202505132302.zMQCF7g7-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505132302.zMQCF7g7-lkp@intel.com/
dtcheck warnings: (new ones prefixed by >>)
>> Documentation/devicetree/bindings/gpu/phytium,dc.yaml:40:8: [warning] wrong indentation: expected 2 but found 7 (indentation)
Documentation/devicetree/bindings/arm/arm,mpam-msc.yaml:76:15: [error] string value is redundantly quoted with any quotes (quoted-strings)
Documentation/devicetree/bindings/arm/arm,mpam-msc.yaml:82:15: [error] string value is redundantly quoted with any quotes (quoted-strings)
--
>> Documentation/devicetree/bindings/gpu/phytium,dc.yaml: ignoring, error in schema: properties: clocks: items
/usr/local/lib/python3.11/dist-packages/dtschema/schemas/reserved-memory/memory-region.yaml: warning: ignoring duplicate '$id' value 'http://devicetree.org/schemas/reserved-memory/memory-region.yaml#'
/usr/local/lib/python3.11/dist-packages/dtschema/schemas/reserved-memory/framebuffer.yaml: warning: ignoring duplicate '$id' value 'http://devicetree.org/schemas/reserved-memory/framebuffer.yaml#'
/usr/local/lib/python3.11/dist-packages/dtschema/schemas/reserved-memory/shared-dma-pool.yaml: warning: ignoring duplicate '$id' value 'http://devicetree.org/schemas/reserved-memory/shared-dma-pool.yaml#'
/usr/local/lib/python3.11/dist-packages/dtschema/schemas/reserved-memory/reserved-memory.yaml: warning: ignoring duplicate '$id' value 'http://devicetree.org/schemas/reserved-memory/reserved-memory.yaml#'
Documentation/devicetree/bindings/sound/audio-graph-port.yaml: convert-sample-format: missing type definition
Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml: i2c-alias: missing type definition
Documentation/devicetree/bindings/display/panel/advantech,idk-2121wr.yaml: dual-lvds-odd-pixels: missing type definition
Documentation/devicetree/bindings/display/panel/advantech,idk-2121wr.yaml: dual-lvds-even-pixels: missing type definition
Documentation/devicetree/bindings/input/touchscreen/ti,tsc2005.yaml: ti,x-plate-ohms: missing type definition
Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml: input-debounce: multiple incompatible types: uint32-array
vim +40 Documentation/devicetree/bindings/gpu/phytium,dc.yaml
33
34 required:
35 - compatible
36 - reg
37 - interrupts
38
39 Example:
> 40 /memreserve/ 0xf4000000 0x4000000; // (optional)
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0
Compared with the previous IPIV, the IPIV-BUGFIX has the following changes:
1. Use Kconfig to Control whether to enable IPIV.
2. Users use ioctl to control whether to enable IPIV.
3. Use the SMCCC interface for Guest OS to control whether to enable IPIV.
4. make sure vcpu_id == vcpu_idx.
5. the MPIDR cannot be changed When IPIV is enabled.
6. fix bug that ipiv enable is displayed on the host when "kvm-arm.vgic_v4_enable=0
kvm-arm.ipiv_enabled=1" is configured.
7. Add Exception Printing
Patch#1 arm64/config: add config to control whether enable IPIV feature
Patch#2 KVM: arm64: Introduce ipiv enable ioctl
Patch#3 KVM: arm64: Document PV-sgi interface
Patch#4 KVM: arm64: Implement PV_SGI related calls
Patch#5 irqchip/gic: Add HiSilicon PV SGI support
Patch#6 kvm: hisi: make sure vcpu_id and vcpu_idx have same value in IPIv
Patch#7 kvm: hisi: Don't allow to change mpidr in IPIv
Patch#8 KVM: arm64: using kvm_vgic_global_state for ipiv
Patch#9 kvm: hisi: print error for IPIV
Patch#10 arm64/kabi: use KABI_EXTEND to skip KABI check
Jinqian Yang (4):
arm64/config: add config to control whether enable IPIV feature
KVM: arm64: using kvm_vgic_global_state for ipiv
kvm: hisi: print error for IPIV
arm64/kabi: use KABI_EXTEND to skip KABI check
Zhou Wang (6):
KVM: arm64: Introduce ipiv enable ioctl
KVM: arm64: Document PV-sgi interface
KVM: arm64: Implement PV_SGI related calls
irqchip/gic: Add HiSilicon PV SGI support
kvm: hisi: make sure vcpu_id and vcpu_idx have same value in IPIv
kvm: hisi: Don't allow to change mpidr in IPIv
Documentation/virt/kvm/arm/pvsgi.rst | 33 ++++++++++++++++
arch/arm64/Kconfig | 13 ++++++
arch/arm64/configs/openeuler_defconfig | 1 +
arch/arm64/include/asm/kvm_host.h | 3 ++
arch/arm64/kvm/arm.c | 34 ++++++++++++----
arch/arm64/kvm/hisilicon/hisi_virt.c | 25 +++++++++++-
arch/arm64/kvm/hisilicon/hisi_virt.h | 20 ++++++++--
arch/arm64/kvm/hypercalls.c | 24 +++++++++++
arch/arm64/kvm/sys_regs.c | 34 +++++++++++-----
arch/arm64/kvm/vgic/vgic-init.c | 42 +++++++++++++++++---
arch/arm64/kvm/vgic/vgic-mmio-v3.c | 2 +
drivers/irqchip/irq-gic-v3-its.c | 50 ++++++++++++++++-------
drivers/irqchip/irq-gic-v3.c | 55 ++++++++++++++++++++------
include/linux/arm-smccc.h | 15 +++++++
include/linux/irqchip/arm-gic-v3.h | 10 +++++
include/linux/irqchip/arm-gic-v4.h | 4 ++
16 files changed, 311 insertions(+), 54 deletions(-)
create mode 100644 Documentation/virt/kvm/arm/pvsgi.rst
--
2.33.0
2
12

[openeuler:OLK-6.6 2220/2220] kernel/sched/fair.c:7080:6: sparse: sparse: symbol 'free_affinity_domains' was not declared. Should it be static?
by kernel test robot 13 May '25
by kernel test robot 13 May '25
13 May '25
Hi Wang,
First bad commit (maybe != root cause):
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: 196f295c5eeefa026912137e7fc120f3c8565d2e
commit: 1a553561230ab6bdc36f9e28e268c75b96dbe67e [2220/2220] sched: smart grid: init sched_grid_qos structure on QOS purpose
config: x86_64-randconfig-123-20250513 (https://download.01.org/0day-ci/archive/20250513/202505132224.plUhY3K3-lkp@…)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250513/202505132224.plUhY3K3-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505132224.plUhY3K3-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
kernel/sched/fair.c:151:14: sparse: sparse: symbol 'sysctl_overload_detect_period' was not declared. Should it be static?
kernel/sched/fair.c:152:14: sparse: sparse: symbol 'sysctl_offline_wait_interval' was not declared. Should it be static?
kernel/sched/fair.c:164:14: sparse: sparse: symbol 'sysctl_sched_prio_load_balance_enabled' was not declared. Should it be static?
kernel/sched/fair.c:209:5: sparse: sparse: symbol 'sysctl_sched_util_low_pct' was not declared. Should it be static?
kernel/sched/fair.c:1310:34: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_entity const *se @@ got struct sched_entity [noderef] __rcu * @@
kernel/sched/fair.c:1310:34: sparse: expected struct sched_entity const *se
kernel/sched/fair.c:1310:34: sparse: got struct sched_entity [noderef] __rcu *
kernel/sched/fair.c:13907:9: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/fair.c:13907:9: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/fair.c:13907:9: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/fair.c:6071:22: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/fair.c:6071:22: sparse: struct task_struct [noderef] __rcu *
kernel/sched/fair.c:6071:22: sparse: struct task_struct *
>> kernel/sched/fair.c:7080:6: sparse: sparse: symbol 'free_affinity_domains' was not declared. Should it be static?
kernel/sched/fair.c:7132:9: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] tmp @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/fair.c:7132:9: sparse: expected struct sched_domain *[assigned] tmp
kernel/sched/fair.c:7132:9: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/fair.c:7146:9: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] tmp @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/fair.c:7146:9: sparse: expected struct sched_domain *[assigned] tmp
kernel/sched/fair.c:7146:9: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/fair.c:7275:38: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct task_struct *curr @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/fair.c:7275:38: sparse: expected struct task_struct *curr
kernel/sched/fair.c:7275:38: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/fair.c:8658:20: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/fair.c:8658:20: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/fair.c:8658:20: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/fair.c:9010:9: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] tmp @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/fair.c:9010:9: sparse: expected struct sched_domain *[assigned] tmp
kernel/sched/fair.c:9010:9: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/fair.c:9122:38: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct task_struct *curr @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/fair.c:9122:38: sparse: expected struct task_struct *curr
kernel/sched/fair.c:9122:38: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/fair.c:9468:22: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/fair.c:9468:22: sparse: struct task_struct [noderef] __rcu *
kernel/sched/fair.c:9468:22: sparse: struct task_struct *
kernel/sched/fair.c:9553:1: sparse: sparse: symbol 'qos_smt_expell_switch' was not declared. Should it be static?
kernel/sched/fair.c:9687:51: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct task_struct *sibling_p @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/fair.c:9687:51: sparse: expected struct task_struct *sibling_p
kernel/sched/fair.c:9687:51: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/fair.c:9692:30: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/fair.c:9692:30: sparse: struct task_struct [noderef] __rcu *
kernel/sched/fair.c:9692:30: sparse: struct task_struct *
kernel/sched/fair.c:9770:48: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct task_struct *p @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/fair.c:10019:38: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct task_struct *curr @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/fair.c:11107:40: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct sched_domain *child @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/fair.c:11744:22: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/fair.c:11744:22: sparse: struct task_struct [noderef] __rcu *
kernel/sched/fair.c:11744:22: sparse: struct task_struct *
kernel/sched/fair.c:13185:9: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/fair.c:13185:9: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/fair.c:13185:9: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/fair.c:12842:44: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct sched_domain *sd_parent @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/fair.c:12842:44: sparse: expected struct sched_domain *sd_parent
kernel/sched/fair.c:12842:44: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/fair.c:13281:9: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/fair.c:13281:9: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/fair.c:13281:9: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/fair.c: note: in included file:
kernel/sched/sched.h:2244:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2244:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2244:25: sparse: struct task_struct *
kernel/sched/sched.h:2408:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2408:9: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2408:9: sparse: struct task_struct *
kernel/sched/sched.h:2408:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2408:9: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2408:9: sparse: struct task_struct *
kernel/sched/sched.h:2244:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2244:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2244:25: sparse: struct task_struct *
kernel/sched/sched.h:2244:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2244:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2244:25: sparse: struct task_struct *
vim +/free_affinity_domains +7080 kernel/sched/fair.c
6eb07f9925a906 Hui Tang 2024-01-17 7079
6eb07f9925a906 Hui Tang 2024-01-17 @7080 void free_affinity_domains(struct affinity_domain *ad)
6eb07f9925a906 Hui Tang 2024-01-17 7081 {
6eb07f9925a906 Hui Tang 2024-01-17 7082 int i;
6eb07f9925a906 Hui Tang 2024-01-17 7083
6eb07f9925a906 Hui Tang 2024-01-17 7084 for (i = 0; i < AD_LEVEL_MAX; i++) {
6eb07f9925a906 Hui Tang 2024-01-17 7085 kfree(ad->domains[i]);
6eb07f9925a906 Hui Tang 2024-01-17 7086 kfree(ad->domains_orig[i]);
6eb07f9925a906 Hui Tang 2024-01-17 7087 ad->domains[i] = NULL;
6eb07f9925a906 Hui Tang 2024-01-17 7088 ad->domains_orig[i] = NULL;
6eb07f9925a906 Hui Tang 2024-01-17 7089 }
6eb07f9925a906 Hui Tang 2024-01-17 7090 ad->dcount = 0;
6eb07f9925a906 Hui Tang 2024-01-17 7091 }
6eb07f9925a906 Hui Tang 2024-01-17 7092
:::::: The code at line 7080 was first introduced by commit
:::::: 6eb07f9925a906d81f328c808ba25f7800888dce sched: Introduce smart grid scheduling strategy for cfs
:::::: TO: Hui Tang <tanghui20(a)huawei.com>
:::::: CC: yanhaitao <yanhaitao2(a)huawei.com>
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[PATCH OLK-6.6] kvm: x86: fix infinite loop in kvm_guest_time_update when tsc is 0
by Yuntao Liu 13 May '25
by Yuntao Liu 13 May '25
13 May '25
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IC7KK7
CVE: NA
--------------------------------
Fixes: 35181e86df97 ("KVM: x86: Add a common TSC scaling function")
Syzkaller testing detected a soft lockup.
watchdog: BUG: soft lockup - CPU#3 stuck for 127s! [syz.1.2088:9817]
Modules linked in:
CPU: 3 PID: 9817 Comm: syz.1.2088 Tainted: G S 6.6.0+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
RIP: 0010:__sanitizer_cov_trace_const_cmp4+0x8/0x20 kernel/kcov.c:313
Code: bf 03 00 00 00 e9 48 fe ff ff 0f 1f 84 00 00 00 00 00 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 48 8b 0c 24 <89> f2 89
fe bf 05 00 00 00 e9 1a fe ff ff 66 2e 0f 1f 84 00 00 00
RSP: 0018:ffff888016d8fad8 EFLAGS: 00000206
RAX: 0000000000080000 RBX: ffff88810e242540 RCX: ffffffff901150d6
RDX: 0000000000080000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffff888016d8fb50 R08: 0000000000000001 R09: ffffed1021c484af
R10: 0000000000000000 R11: 0000000000000277 R12: 0000000000000000
R13: fffffed357281918 R14: 0000000000000000 R15: 0000000000000001
FS: 00007f2a8f6ea6c0(0000) GS:ffff888119780000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000012c56c0 CR3: 000000000dce8001 CR4: 0000000000772ee0
DR0: 0000000000000000 DR1: 0000000000d3eb1c DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
PKRU: 80000000
Call Trace:
<TASK>
kvm_get_time_scale arch/x86/kvm/x86.c:2458 [inline]
kvm_guest_time_update+0x926/0xb00 arch/x86/kvm/x86.c:3268
vcpu_enter_guest.constprop.0+0x1e70/0x3cf0 arch/x86/kvm/x86.c:10678
vcpu_run+0x129/0x8d0 arch/x86/kvm/x86.c:11126
kvm_arch_vcpu_ioctl_run+0x37a/0x13d0 arch/x86/kvm/x86.c:11352
kvm_vcpu_ioctl+0x56b/0xe60 virt/kvm/kvm_main.c:4188
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:871 [inline]
__se_sys_ioctl+0x12d/0x190 fs/ioctl.c:857
do_syscall_x64 arch/x86/entry/common.c:51 [inline]
do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81
entry_SYSCALL_64_after_hwframe+0x78/0xe2
ioctl$KVM_SET_TSC_KHZ(r2, 0xaea2, 0x1)
user_tsc_khz = 0x1
|
kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz)
|
ioctl$KVM_RUN(r2, 0xae80, 0x0)
|
...
kvm_guest_time_update(struct kvm_vcpu *v)
|
if (kvm_caps.has_tsc_control)
tgt_tsc_khz = kvm_scale_tsc(tgt_tsc_khz,
v->arch.l1_tsc_scaling_ratio);
|
kvm_scale_tsc(u64 tsc, u64 ratio)
|
__scale_tsc(u64 ratio, u64 tsc)
ratio=122380531, tsc=2299998, N=48
ratio*tsc >> N = 0.999... -> 0
|
kvm_get_time_scale
In function __scale_tsc, it uses fixed point number to calculate
tsc, therefore, a certain degree of precision is lost, the actual tsc
value of 0.999... would be 0. In function kvm_get_time_scale
tps32=tps64=base_hz=0, would lead second while_loop infinite. when
CONFIG_PREEMPT is n, it causes a soft lockup issue.
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
arch/x86/kvm/x86.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1fa5d89f8d27..3e9d6f368eed 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2605,10 +2605,14 @@ static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
* point number (mult + frac * 2^(-N)).
*
* N equals to kvm_caps.tsc_scaling_ratio_frac_bits.
+ *
+ * return 1 if _tsc is 0.
*/
static inline u64 __scale_tsc(u64 ratio, u64 tsc)
{
- return mul_u64_u64_shr(tsc, ratio, kvm_caps.tsc_scaling_ratio_frac_bits);
+ u64 _tsc = mul_u64_u64_shr(tsc, ratio, kvm_caps.tsc_scaling_ratio_frac_bits);
+
+ return !_tsc ? 1 : _tsc;
}
u64 kvm_scale_tsc(u64 tsc, u64 ratio)
--
2.34.1
2
1
From: Hongye Lin <linhongye(a)h-partners.com>
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IC76OZ
----------------------------------------------------------------------
Armv8.7 introduces single-copy atomic 64-byte loads and stores
instructions and its variants named under FEAT_{LS64, LS64_V}.
These features are identified by ID_AA64ISAR1_EL1.LS64 and the
use of such instructions in userspace (EL0) can be trapped. In
order to support the use of corresponding instructions in userspace:
Make ID_AA64ISAR1_EL1.LS64 visbile to userspace
Add identifying and enabling in the cpufeature list
Expose these support of these features to userspace through HWCAP3
and cpuinfo
Mark Brown (2):
arm64: Support AT_HWCAP3
binfmt_elf: Wire up AT_HWCAP3 at AT_HWCAP4
Peter Bergner (1):
uapi/auxvec: Define AT_HWCAP3 and AT_HWCAP4 aux vector, entries
Yicong Yang (4):
arm64: Provide basic EL2 setup for FEAT_{LS64, LS64_V} usage at EL0/1
arm64: Add support for FEAT_{LS64, LS64_V}
Workaround the issue when compile with CONFIG_FUNCTION_ALIGNMENT_64B
KVM: arm64: Enable FEAT_{LS64, LS64_V} in the supported guest
Documentation/arch/arm64/booting.rst | 12 +++++
Documentation/arch/arm64/elf_hwcaps.rst | 12 +++--
arch/arm64/Kconfig | 4 ++
arch/arm64/include/asm/cpufeature.h | 3 +-
arch/arm64/include/asm/el2_setup.h | 13 ++++++
arch/arm64/include/asm/hwcap.h | 7 ++-
arch/arm64/include/uapi/asm/hwcap.h | 6 +++
arch/arm64/kernel/cpufeature.c | 61 +++++++++++++++++++++++++
arch/arm64/kernel/cpuinfo.c | 2 +
arch/arm64/kvm/hyp/include/hyp/switch.h | 6 +++
arch/arm64/tools/cpucaps | 4 +-
fs/binfmt_elf.c | 6 +++
fs/binfmt_elf_fdpic.c | 6 +++
fs/compat_binfmt_elf.c | 10 ++++
include/uapi/linux/auxvec.h | 2 +
15 files changed, 147 insertions(+), 7 deletions(-)
--
2.33.0
2
8

[PATCH openEuler-1.0-LTS] kvm: x86: fix infinite loop in kvm_guest_time_update when tsc is 0
by Yuntao Liu 13 May '25
by Yuntao Liu 13 May '25
13 May '25
hulk inclusion
category: bugfix
bugzilla: 190614
CVE: NA
--------------------------------
Fixes: 35181e86df97 ("KVM: x86: Add a common TSC scaling function")
Syzkaller testing detected a soft lockup.
watchdog: BUG: soft lockup - CPU#3 stuck for 127s! [syz.1.2088:9817]
Modules linked in:
CPU: 3 PID: 9817 Comm: syz.1.2088 Tainted: G S 6.6.0+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
RIP: 0010:__sanitizer_cov_trace_const_cmp4+0x8/0x20 kernel/kcov.c:313
Code: bf 03 00 00 00 e9 48 fe ff ff 0f 1f 84 00 00 00 00 00 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 48 8b 0c 24 <89> f2 89
fe bf 05 00 00 00 e9 1a fe ff ff 66 2e 0f 1f 84 00 00 00
RSP: 0018:ffff888016d8fad8 EFLAGS: 00000206
RAX: 0000000000080000 RBX: ffff88810e242540 RCX: ffffffff901150d6
RDX: 0000000000080000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffff888016d8fb50 R08: 0000000000000001 R09: ffffed1021c484af
R10: 0000000000000000 R11: 0000000000000277 R12: 0000000000000000
R13: fffffed357281918 R14: 0000000000000000 R15: 0000000000000001
FS: 00007f2a8f6ea6c0(0000) GS:ffff888119780000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000012c56c0 CR3: 000000000dce8001 CR4: 0000000000772ee0
DR0: 0000000000000000 DR1: 0000000000d3eb1c DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
PKRU: 80000000
Call Trace:
<TASK>
kvm_get_time_scale arch/x86/kvm/x86.c:2458 [inline]
kvm_guest_time_update+0x926/0xb00 arch/x86/kvm/x86.c:3268
vcpu_enter_guest.constprop.0+0x1e70/0x3cf0 arch/x86/kvm/x86.c:10678
vcpu_run+0x129/0x8d0 arch/x86/kvm/x86.c:11126
kvm_arch_vcpu_ioctl_run+0x37a/0x13d0 arch/x86/kvm/x86.c:11352
kvm_vcpu_ioctl+0x56b/0xe60 virt/kvm/kvm_main.c:4188
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:871 [inline]
__se_sys_ioctl+0x12d/0x190 fs/ioctl.c:857
do_syscall_x64 arch/x86/entry/common.c:51 [inline]
do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81
entry_SYSCALL_64_after_hwframe+0x78/0xe2
ioctl$KVM_SET_TSC_KHZ(r2, 0xaea2, 0x1)
user_tsc_khz = 0x1
|
kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz)
|
ioctl$KVM_RUN(r2, 0xae80, 0x0)
|
...
kvm_guest_time_update(struct kvm_vcpu *v)
|
if (kvm_caps.has_tsc_control)
tgt_tsc_khz = kvm_scale_tsc(tgt_tsc_khz,
v->arch.l1_tsc_scaling_ratio);
|
kvm_scale_tsc(u64 tsc, u64 ratio)
|
__scale_tsc(u64 ratio, u64 tsc)
ratio=122380531, tsc=2299998, N=48
ratio*tsc >> N = 0.999... -> 0
|
kvm_get_time_scale
In function __scale_tsc, it uses fixed point number to calculate
tsc, therefore, a certain degree of precision is lost, the actual tsc
value of 0.999... would be 0. In function kvm_get_time_scale
tps32=tps64=base_hz=0, would lead second while_loop infinite. when
CONFIG_PREEMPT is n, it causes a soft lockup issue.
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
arch/x86/kvm/x86.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 6afffdcc656e..83d215d43eb3 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1673,10 +1673,14 @@ static void update_ia32_tsc_adjust_msr(struct kvm_vcpu *vcpu, s64 offset)
* point number (mult + frac * 2^(-N)).
*
* N equals to kvm_tsc_scaling_ratio_frac_bits.
+ *
+ * return 1 if _tsc is 0.
*/
static inline u64 __scale_tsc(u64 ratio, u64 tsc)
{
- return mul_u64_u64_shr(tsc, ratio, kvm_tsc_scaling_ratio_frac_bits);
+ u64 _tsc = mul_u64_u64_shr(tsc, ratio, kvm_tsc_scaling_ratio_frac_bits);
+
+ return !_tsc ? 1 : _tsc;
}
u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc)
--
2.34.1
2
1

[PATCH OLK-5.10] kvm: x86: fix infinite loop in kvm_guest_time_update when tsc is 0
by Yuntao Liu 13 May '25
by Yuntao Liu 13 May '25
13 May '25
hulk inclusion
category: bugfix
bugzilla: 190614
CVE: NA
--------------------------------
Fixes: 35181e86df97 ("KVM: x86: Add a common TSC scaling function")
Syzkaller testing detected a soft lockup.
watchdog: BUG: soft lockup - CPU#3 stuck for 127s! [syz.1.2088:9817]
Modules linked in:
CPU: 3 PID: 9817 Comm: syz.1.2088 Tainted: G S 6.6.0+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
RIP: 0010:__sanitizer_cov_trace_const_cmp4+0x8/0x20 kernel/kcov.c:313
Code: bf 03 00 00 00 e9 48 fe ff ff 0f 1f 84 00 00 00 00 00 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 48 8b 0c 24 <89> f2 89
fe bf 05 00 00 00 e9 1a fe ff ff 66 2e 0f 1f 84 00 00 00
RSP: 0018:ffff888016d8fad8 EFLAGS: 00000206
RAX: 0000000000080000 RBX: ffff88810e242540 RCX: ffffffff901150d6
RDX: 0000000000080000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffff888016d8fb50 R08: 0000000000000001 R09: ffffed1021c484af
R10: 0000000000000000 R11: 0000000000000277 R12: 0000000000000000
R13: fffffed357281918 R14: 0000000000000000 R15: 0000000000000001
FS: 00007f2a8f6ea6c0(0000) GS:ffff888119780000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000012c56c0 CR3: 000000000dce8001 CR4: 0000000000772ee0
DR0: 0000000000000000 DR1: 0000000000d3eb1c DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
PKRU: 80000000
Call Trace:
<TASK>
kvm_get_time_scale arch/x86/kvm/x86.c:2458 [inline]
kvm_guest_time_update+0x926/0xb00 arch/x86/kvm/x86.c:3268
vcpu_enter_guest.constprop.0+0x1e70/0x3cf0 arch/x86/kvm/x86.c:10678
vcpu_run+0x129/0x8d0 arch/x86/kvm/x86.c:11126
kvm_arch_vcpu_ioctl_run+0x37a/0x13d0 arch/x86/kvm/x86.c:11352
kvm_vcpu_ioctl+0x56b/0xe60 virt/kvm/kvm_main.c:4188
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:871 [inline]
__se_sys_ioctl+0x12d/0x190 fs/ioctl.c:857
do_syscall_x64 arch/x86/entry/common.c:51 [inline]
do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81
entry_SYSCALL_64_after_hwframe+0x78/0xe2
ioctl$KVM_SET_TSC_KHZ(r2, 0xaea2, 0x1)
user_tsc_khz = 0x1
|
kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz)
|
ioctl$KVM_RUN(r2, 0xae80, 0x0)
|
...
kvm_guest_time_update(struct kvm_vcpu *v)
|
if (kvm_caps.has_tsc_control)
tgt_tsc_khz = kvm_scale_tsc(tgt_tsc_khz,
v->arch.l1_tsc_scaling_ratio);
|
kvm_scale_tsc(u64 tsc, u64 ratio)
|
__scale_tsc(u64 ratio, u64 tsc)
ratio=122380531, tsc=2299998, N=48
ratio*tsc >> N = 0.999... -> 0
|
kvm_get_time_scale
In function __scale_tsc, it uses fixed point number to calculate
tsc, therefore, a certain degree of precision is lost, the actual tsc
value of 0.999... would be 0. In function kvm_get_time_scale
tps32=tps64=base_hz=0, would lead second while_loop infinite. when
CONFIG_PREEMPT is n, it causes a soft lockup issue.
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
arch/x86/kvm/x86.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index d2d206ff6462..dec2d3baf202 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2428,10 +2428,14 @@ static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
* point number (mult + frac * 2^(-N)).
*
* N equals to kvm_tsc_scaling_ratio_frac_bits.
+ *
+ * return 1 if _tsc is 0.
*/
static inline u64 __scale_tsc(u64 ratio, u64 tsc)
{
- return mul_u64_u64_shr(tsc, ratio, kvm_tsc_scaling_ratio_frac_bits);
+ u64 _tsc = mul_u64_u64_shr(tsc, ratio, kvm_tsc_scaling_ratio_frac_bits);
+
+ return !_tsc ? 1 : _tsc;
}
u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc)
--
2.34.1
2
1

[PATCH OLK-6.6] kvm: x86: fix infinite loop in kvm_guest_time_update when tsc is 0
by Yuntao Liu 13 May '25
by Yuntao Liu 13 May '25
13 May '25
hulk inclusion
category: bugfix
bugzilla: 190614
CVE: NA
--------------------------------
Fixes: 35181e86df97 ("KVM: x86: Add a common TSC scaling function")
Syzkaller testing detected a soft lockup.
watchdog: BUG: soft lockup - CPU#3 stuck for 127s! [syz.1.2088:9817]
Modules linked in:
CPU: 3 PID: 9817 Comm: syz.1.2088 Tainted: G S 6.6.0+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
RIP: 0010:__sanitizer_cov_trace_const_cmp4+0x8/0x20 kernel/kcov.c:313
Code: bf 03 00 00 00 e9 48 fe ff ff 0f 1f 84 00 00 00 00 00 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 48 8b 0c 24 <89> f2 89
fe bf 05 00 00 00 e9 1a fe ff ff 66 2e 0f 1f 84 00 00 00
RSP: 0018:ffff888016d8fad8 EFLAGS: 00000206
RAX: 0000000000080000 RBX: ffff88810e242540 RCX: ffffffff901150d6
RDX: 0000000000080000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffff888016d8fb50 R08: 0000000000000001 R09: ffffed1021c484af
R10: 0000000000000000 R11: 0000000000000277 R12: 0000000000000000
R13: fffffed357281918 R14: 0000000000000000 R15: 0000000000000001
FS: 00007f2a8f6ea6c0(0000) GS:ffff888119780000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000012c56c0 CR3: 000000000dce8001 CR4: 0000000000772ee0
DR0: 0000000000000000 DR1: 0000000000d3eb1c DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
PKRU: 80000000
Call Trace:
<TASK>
kvm_get_time_scale arch/x86/kvm/x86.c:2458 [inline]
kvm_guest_time_update+0x926/0xb00 arch/x86/kvm/x86.c:3268
vcpu_enter_guest.constprop.0+0x1e70/0x3cf0 arch/x86/kvm/x86.c:10678
vcpu_run+0x129/0x8d0 arch/x86/kvm/x86.c:11126
kvm_arch_vcpu_ioctl_run+0x37a/0x13d0 arch/x86/kvm/x86.c:11352
kvm_vcpu_ioctl+0x56b/0xe60 virt/kvm/kvm_main.c:4188
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:871 [inline]
__se_sys_ioctl+0x12d/0x190 fs/ioctl.c:857
do_syscall_x64 arch/x86/entry/common.c:51 [inline]
do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81
entry_SYSCALL_64_after_hwframe+0x78/0xe2
ioctl$KVM_SET_TSC_KHZ(r2, 0xaea2, 0x1)
user_tsc_khz = 0x1
|
kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz)
|
ioctl$KVM_RUN(r2, 0xae80, 0x0)
|
...
kvm_guest_time_update(struct kvm_vcpu *v)
|
if (kvm_caps.has_tsc_control)
tgt_tsc_khz = kvm_scale_tsc(tgt_tsc_khz,
v->arch.l1_tsc_scaling_ratio);
|
kvm_scale_tsc(u64 tsc, u64 ratio)
|
__scale_tsc(u64 ratio, u64 tsc)
ratio=122380531, tsc=2299998, N=48
ratio*tsc >> N = 0.999... -> 0
|
kvm_get_time_scale
In function __scale_tsc, it uses fixed point number to calculate
tsc, therefore, a certain degree of precision is lost, the actual tsc
value of 0.999... would be 0. In function kvm_get_time_scale
tps32=tps64=base_hz=0, would lead second while_loop infinite. when
CONFIG_PREEMPT is n, it causes a soft lockup issue.
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
arch/x86/kvm/x86.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1fa5d89f8d27..3e9d6f368eed 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2605,10 +2605,14 @@ static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
* point number (mult + frac * 2^(-N)).
*
* N equals to kvm_caps.tsc_scaling_ratio_frac_bits.
+ *
+ * return 1 if _tsc is 0.
*/
static inline u64 __scale_tsc(u64 ratio, u64 tsc)
{
- return mul_u64_u64_shr(tsc, ratio, kvm_caps.tsc_scaling_ratio_frac_bits);
+ u64 _tsc = mul_u64_u64_shr(tsc, ratio, kvm_caps.tsc_scaling_ratio_frac_bits);
+
+ return !_tsc ? 1 : _tsc;
}
u64 kvm_scale_tsc(u64 tsc, u64 ratio)
--
2.34.1
2
1

[PATCH OLK-6.6] kvm: x86: fix infinite loop in kvm_guest_time_update when tsc is 0
by Yuntao Liu 13 May '25
by Yuntao Liu 13 May '25
13 May '25
Offering: HULK
hulk inclusion
category: bugfix
bugzilla: 190614
CVE: NA
--------------------------------
Fixes: 35181e86df97 ("KVM: x86: Add a common TSC scaling function")
Syzkaller testing detected a soft lockup.
watchdog: BUG: soft lockup - CPU#3 stuck for 127s! [syz.1.2088:9817]
Modules linked in:
CPU: 3 PID: 9817 Comm: syz.1.2088 Tainted: G S 6.6.0+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
RIP: 0010:__sanitizer_cov_trace_const_cmp4+0x8/0x20 kernel/kcov.c:313
Code: bf 03 00 00 00 e9 48 fe ff ff 0f 1f 84 00 00 00 00 00 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 48 8b 0c 24 <89> f2 89
fe bf 05 00 00 00 e9 1a fe ff ff 66 2e 0f 1f 84 00 00 00
RSP: 0018:ffff888016d8fad8 EFLAGS: 00000206
RAX: 0000000000080000 RBX: ffff88810e242540 RCX: ffffffff901150d6
RDX: 0000000000080000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffff888016d8fb50 R08: 0000000000000001 R09: ffffed1021c484af
R10: 0000000000000000 R11: 0000000000000277 R12: 0000000000000000
R13: fffffed357281918 R14: 0000000000000000 R15: 0000000000000001
FS: 00007f2a8f6ea6c0(0000) GS:ffff888119780000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000012c56c0 CR3: 000000000dce8001 CR4: 0000000000772ee0
DR0: 0000000000000000 DR1: 0000000000d3eb1c DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
PKRU: 80000000
Call Trace:
<TASK>
kvm_get_time_scale arch/x86/kvm/x86.c:2458 [inline]
kvm_guest_time_update+0x926/0xb00 arch/x86/kvm/x86.c:3268
vcpu_enter_guest.constprop.0+0x1e70/0x3cf0 arch/x86/kvm/x86.c:10678
vcpu_run+0x129/0x8d0 arch/x86/kvm/x86.c:11126
kvm_arch_vcpu_ioctl_run+0x37a/0x13d0 arch/x86/kvm/x86.c:11352
kvm_vcpu_ioctl+0x56b/0xe60 virt/kvm/kvm_main.c:4188
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:871 [inline]
__se_sys_ioctl+0x12d/0x190 fs/ioctl.c:857
do_syscall_x64 arch/x86/entry/common.c:51 [inline]
do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81
entry_SYSCALL_64_after_hwframe+0x78/0xe2
ioctl$KVM_SET_TSC_KHZ(r2, 0xaea2, 0x1)
user_tsc_khz = 0x1
|
kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz)
|
ioctl$KVM_RUN(r2, 0xae80, 0x0)
|
...
kvm_guest_time_update(struct kvm_vcpu *v)
|
if (kvm_caps.has_tsc_control)
tgt_tsc_khz = kvm_scale_tsc(tgt_tsc_khz,
v->arch.l1_tsc_scaling_ratio);
|
kvm_scale_tsc(u64 tsc, u64 ratio)
|
__scale_tsc(u64 ratio, u64 tsc)
ratio=122380531, tsc=2299998, N=48
ratio*tsc >> N = 0.999... -> 0
|
kvm_get_time_scale
In function __scale_tsc, it uses fixed point number to calculate
tsc, therefore, a certain degree of precision is lost, the actual tsc
value of 0.999... would be 0. In function kvm_get_time_scale
tps32=tps64=base_hz=0, would lead second while_loop infinite. when
CONFIG_PREEMPT is n, it causes a soft lockup issue.
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
arch/x86/kvm/x86.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1fa5d89f8d27..3e9d6f368eed 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2605,10 +2605,14 @@ static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
* point number (mult + frac * 2^(-N)).
*
* N equals to kvm_caps.tsc_scaling_ratio_frac_bits.
+ *
+ * return 1 if _tsc is 0.
*/
static inline u64 __scale_tsc(u64 ratio, u64 tsc)
{
- return mul_u64_u64_shr(tsc, ratio, kvm_caps.tsc_scaling_ratio_frac_bits);
+ u64 _tsc = mul_u64_u64_shr(tsc, ratio, kvm_caps.tsc_scaling_ratio_frac_bits);
+
+ return !_tsc ? 1 : _tsc;
}
u64 kvm_scale_tsc(u64 tsc, u64 ratio)
--
2.34.1
2
1

[PATCH OLK-6.6] kvm: x86: fix infinite loop in kvm_guest_time_update when tsc is 0
by Yuntao Liu 13 May '25
by Yuntao Liu 13 May '25
13 May '25
Offering: HULK
hulk inclusion
category: bugfix
bugzilla: 190614
CVE: NA
--------------------------------
Fixes: 35181e86df97 ("KVM: x86: Add a common TSC scaling function")
Syzkaller testing detected a soft lockup.
watchdog: BUG: soft lockup - CPU#3 stuck for 127s! [syz.1.2088:9817]
Modules linked in:
CPU: 3 PID: 9817 Comm: syz.1.2088 Tainted: G S 6.6.0+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
RIP: 0010:__sanitizer_cov_trace_const_cmp4+0x8/0x20 kernel/kcov.c:313
Code: bf 03 00 00 00 e9 48 fe ff ff 0f 1f 84 00 00 00 00 00 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 48 8b 0c 24 <89> f2 89
fe bf 05 00 00 00 e9 1a fe ff ff 66 2e 0f 1f 84 00 00 00
RSP: 0018:ffff888016d8fad8 EFLAGS: 00000206
RAX: 0000000000080000 RBX: ffff88810e242540 RCX: ffffffff901150d6
RDX: 0000000000080000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffff888016d8fb50 R08: 0000000000000001 R09: ffffed1021c484af
R10: 0000000000000000 R11: 0000000000000277 R12: 0000000000000000
R13: fffffed357281918 R14: 0000000000000000 R15: 0000000000000001
FS: 00007f2a8f6ea6c0(0000) GS:ffff888119780000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000012c56c0 CR3: 000000000dce8001 CR4: 0000000000772ee0
DR0: 0000000000000000 DR1: 0000000000d3eb1c DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
PKRU: 80000000
Call Trace:
<TASK>
kvm_get_time_scale arch/x86/kvm/x86.c:2458 [inline]
kvm_guest_time_update+0x926/0xb00 arch/x86/kvm/x86.c:3268
vcpu_enter_guest.constprop.0+0x1e70/0x3cf0 arch/x86/kvm/x86.c:10678
vcpu_run+0x129/0x8d0 arch/x86/kvm/x86.c:11126
kvm_arch_vcpu_ioctl_run+0x37a/0x13d0 arch/x86/kvm/x86.c:11352
kvm_vcpu_ioctl+0x56b/0xe60 virt/kvm/kvm_main.c:4188
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:871 [inline]
__se_sys_ioctl+0x12d/0x190 fs/ioctl.c:857
do_syscall_x64 arch/x86/entry/common.c:51 [inline]
do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81
entry_SYSCALL_64_after_hwframe+0x78/0xe2
ioctl$KVM_SET_TSC_KHZ(r2, 0xaea2, 0x1)
user_tsc_khz = 0x1
|
kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz)
|
ioctl$KVM_RUN(r2, 0xae80, 0x0)
|
...
kvm_guest_time_update(struct kvm_vcpu *v)
|
if (kvm_caps.has_tsc_control)
tgt_tsc_khz = kvm_scale_tsc(tgt_tsc_khz,
v->arch.l1_tsc_scaling_ratio);
|
kvm_scale_tsc(u64 tsc, u64 ratio)
|
__scale_tsc(u64 ratio, u64 tsc)
ratio=122380531, tsc=2299998, N=48
ratio*tsc >> N = 0.999... -> 0
|
kvm_get_time_scale
In function __scale_tsc, it uses fixed point number to calculate
tsc, therefore, a certain degree of precision is lost, the actual tsc
value of 0.999... would be 0. In function kvm_get_time_scale
tps32=tps64=base_hz=0, would lead second while_loop infinite. when
CONFIG_PREEMPT is n, it causes a soft lockup issue.
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
arch/x86/kvm/x86.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1fa5d89f8d27..57a12f2a4642 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2605,10 +2605,14 @@ static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
* point number (mult + frac * 2^(-N)).
*
* N equals to kvm_caps.tsc_scaling_ratio_frac_bits.
+ *
+ * return 1 if _tsc is 0.
*/
static inline u64 __scale_tsc(u64 ratio, u64 tsc)
{
- return mul_u64_u64_shr(tsc, ratio, kvm_caps.tsc_scaling_ratio_frac_bits);
+ u64 _tsc = mul_u64_u64_shr(tsc, ratio, kvm_caps.tsc_scaling_ratio_frac_bits);
+
+ return !_tsc ? 1 : _tsc;
}
u64 kvm_scale_tsc(u64 tsc, u64 ratio)
--
2.34.1
2
1

[PATCH OLK-5.10] kvm: x86: fix infinite loop in kvm_guest_time_update when tsc is 0
by Yuntao Liu 13 May '25
by Yuntao Liu 13 May '25
13 May '25
Offering: HULK
hulk inclusion
category: bugfix
bugzilla: 190614
CVE: NA
--------------------------------
Fixes: 35181e86df97 ("KVM: x86: Add a common TSC scaling function")
Syzkaller testing detected a soft lockup.
watchdog: BUG: soft lockup - CPU#3 stuck for 127s! [syz.1.2088:9817]
Modules linked in:
CPU: 3 PID: 9817 Comm: syz.1.2088 Tainted: G S 6.6.0+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
RIP: 0010:__sanitizer_cov_trace_const_cmp4+0x8/0x20 kernel/kcov.c:313
Code: bf 03 00 00 00 e9 48 fe ff ff 0f 1f 84 00 00 00 00 00 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 48 8b 0c 24 <89> f2 89
fe bf 05 00 00 00 e9 1a fe ff ff 66 2e 0f 1f 84 00 00 00
RSP: 0018:ffff888016d8fad8 EFLAGS: 00000206
RAX: 0000000000080000 RBX: ffff88810e242540 RCX: ffffffff901150d6
RDX: 0000000000080000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffff888016d8fb50 R08: 0000000000000001 R09: ffffed1021c484af
R10: 0000000000000000 R11: 0000000000000277 R12: 0000000000000000
R13: fffffed357281918 R14: 0000000000000000 R15: 0000000000000001
FS: 00007f2a8f6ea6c0(0000) GS:ffff888119780000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000012c56c0 CR3: 000000000dce8001 CR4: 0000000000772ee0
DR0: 0000000000000000 DR1: 0000000000d3eb1c DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
PKRU: 80000000
Call Trace:
<TASK>
kvm_get_time_scale arch/x86/kvm/x86.c:2458 [inline]
kvm_guest_time_update+0x926/0xb00 arch/x86/kvm/x86.c:3268
vcpu_enter_guest.constprop.0+0x1e70/0x3cf0 arch/x86/kvm/x86.c:10678
vcpu_run+0x129/0x8d0 arch/x86/kvm/x86.c:11126
kvm_arch_vcpu_ioctl_run+0x37a/0x13d0 arch/x86/kvm/x86.c:11352
kvm_vcpu_ioctl+0x56b/0xe60 virt/kvm/kvm_main.c:4188
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:871 [inline]
__se_sys_ioctl+0x12d/0x190 fs/ioctl.c:857
do_syscall_x64 arch/x86/entry/common.c:51 [inline]
do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81
entry_SYSCALL_64_after_hwframe+0x78/0xe2
ioctl$KVM_SET_TSC_KHZ(r2, 0xaea2, 0x1)
user_tsc_khz = 0x1
|
kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz)
|
ioctl$KVM_RUN(r2, 0xae80, 0x0)
|
...
kvm_guest_time_update(struct kvm_vcpu *v)
|
if (kvm_caps.has_tsc_control)
tgt_tsc_khz = kvm_scale_tsc(tgt_tsc_khz,
v->arch.l1_tsc_scaling_ratio);
|
kvm_scale_tsc(u64 tsc, u64 ratio)
|
__scale_tsc(u64 ratio, u64 tsc)
ratio=122380531, tsc=2299998, N=48
ratio*tsc >> N = 0.999... -> 0
|
kvm_get_time_scale
In function __scale_tsc, it uses fixed point number to calculate
tsc, therefore, a certain degree of precision is lost, the actual tsc
value of 0.999... would be 0. In function kvm_get_time_scale
tps32=tps64=base_hz=0, would lead second while_loop infinite. when
CONFIG_PREEMPT is n, it causes a soft lockup issue.
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
arch/x86/kvm/x86.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index d2d206ff6462..dec2d3baf202 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2428,10 +2428,14 @@ static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
* point number (mult + frac * 2^(-N)).
*
* N equals to kvm_tsc_scaling_ratio_frac_bits.
+ *
+ * return 1 if _tsc is 0.
*/
static inline u64 __scale_tsc(u64 ratio, u64 tsc)
{
- return mul_u64_u64_shr(tsc, ratio, kvm_tsc_scaling_ratio_frac_bits);
+ u64 _tsc = mul_u64_u64_shr(tsc, ratio, kvm_tsc_scaling_ratio_frac_bits);
+
+ return !_tsc ? 1 : _tsc;
}
u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc)
--
2.34.1
2
1

[PATCH openEuler-1.0-LTS] kvm: x86: fix infinite loop in kvm_guest_time_update when tsc is 0
by Yuntao Liu 13 May '25
by Yuntao Liu 13 May '25
13 May '25
Offering: HULK
hulk inclusion
category: bugfix
bugzilla: 190614
CVE: NA
--------------------------------
Fixes: 35181e86df97 ("KVM: x86: Add a common TSC scaling function")
Syzkaller testing detected a soft lockup.
watchdog: BUG: soft lockup - CPU#3 stuck for 127s! [syz.1.2088:9817]
Modules linked in:
CPU: 3 PID: 9817 Comm: syz.1.2088 Tainted: G S 6.6.0+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
RIP: 0010:__sanitizer_cov_trace_const_cmp4+0x8/0x20 kernel/kcov.c:313
Code: bf 03 00 00 00 e9 48 fe ff ff 0f 1f 84 00 00 00 00 00 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 48 8b 0c 24 <89> f2 89
fe bf 05 00 00 00 e9 1a fe ff ff 66 2e 0f 1f 84 00 00 00
RSP: 0018:ffff888016d8fad8 EFLAGS: 00000206
RAX: 0000000000080000 RBX: ffff88810e242540 RCX: ffffffff901150d6
RDX: 0000000000080000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffff888016d8fb50 R08: 0000000000000001 R09: ffffed1021c484af
R10: 0000000000000000 R11: 0000000000000277 R12: 0000000000000000
R13: fffffed357281918 R14: 0000000000000000 R15: 0000000000000001
FS: 00007f2a8f6ea6c0(0000) GS:ffff888119780000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000012c56c0 CR3: 000000000dce8001 CR4: 0000000000772ee0
DR0: 0000000000000000 DR1: 0000000000d3eb1c DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
PKRU: 80000000
Call Trace:
<TASK>
kvm_get_time_scale arch/x86/kvm/x86.c:2458 [inline]
kvm_guest_time_update+0x926/0xb00 arch/x86/kvm/x86.c:3268
vcpu_enter_guest.constprop.0+0x1e70/0x3cf0 arch/x86/kvm/x86.c:10678
vcpu_run+0x129/0x8d0 arch/x86/kvm/x86.c:11126
kvm_arch_vcpu_ioctl_run+0x37a/0x13d0 arch/x86/kvm/x86.c:11352
kvm_vcpu_ioctl+0x56b/0xe60 virt/kvm/kvm_main.c:4188
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:871 [inline]
__se_sys_ioctl+0x12d/0x190 fs/ioctl.c:857
do_syscall_x64 arch/x86/entry/common.c:51 [inline]
do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81
entry_SYSCALL_64_after_hwframe+0x78/0xe2
ioctl$KVM_SET_TSC_KHZ(r2, 0xaea2, 0x1)
user_tsc_khz = 0x1
|
kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz)
|
ioctl$KVM_RUN(r2, 0xae80, 0x0)
|
...
kvm_guest_time_update(struct kvm_vcpu *v)
|
if (kvm_caps.has_tsc_control)
tgt_tsc_khz = kvm_scale_tsc(tgt_tsc_khz,
v->arch.l1_tsc_scaling_ratio);
|
kvm_scale_tsc(u64 tsc, u64 ratio)
|
__scale_tsc(u64 ratio, u64 tsc)
ratio=122380531, tsc=2299998, N=48
ratio*tsc >> N = 0.999... -> 0
|
kvm_get_time_scale
In function __scale_tsc, it uses fixed point number to calculate
tsc, therefore, a certain degree of precision is lost, the actual tsc
value of 0.999... would be 0. In function kvm_get_time_scale
tps32=tps64=base_hz=0, would lead second while_loop infinite. when
CONFIG_PREEMPT is n, it causes a soft lockup issue.
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
arch/x86/kvm/x86.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 6afffdcc656e..83d215d43eb3 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1673,10 +1673,14 @@ static void update_ia32_tsc_adjust_msr(struct kvm_vcpu *vcpu, s64 offset)
* point number (mult + frac * 2^(-N)).
*
* N equals to kvm_tsc_scaling_ratio_frac_bits.
+ *
+ * return 1 if _tsc is 0.
*/
static inline u64 __scale_tsc(u64 ratio, u64 tsc)
{
- return mul_u64_u64_shr(tsc, ratio, kvm_tsc_scaling_ratio_frac_bits);
+ u64 _tsc = mul_u64_u64_shr(tsc, ratio, kvm_tsc_scaling_ratio_frac_bits);
+
+ return !_tsc ? 1 : _tsc;
}
u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc)
--
2.34.1
2
1

[PATCH OLK-6.6 0/2] Update the watchdog period according to real CPU frequency
by Qinxin Xia 13 May '25
by Qinxin Xia 13 May '25
13 May '25
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IC7CQP
----------------------------------------------------------------------
watchdog perf needs architecture to provide method for converting the watchdog
thresh to counter period. For arm64 we're using the max CPU frequency for
doing the conversion which is from cpufreq driver. But some cpufreq driver
are registered lately, for example cppc_cpufreq will be registered at late
initcall which is after the initialization of watchdog perf (initialized in
armv8_pmuv3 of device initcall). In such case the period of watchdog will not
be accurate enough. Fix this by registering a cpufreq notifier and update the
watchdog period once the cpufreq driver is initialized.
Yicong Yang (2):
watchdog/perf: Provide function for adjusting the event period
arm64/watchdog_hld: Add a cpufreq notifier for update watchdog thresh
arch/arm64/kernel/watchdog_hld.c | 58 ++++++++++++++++++++++++++++++++
include/linux/nmi.h | 2 ++
kernel/watchdog_perf.c | 23 +++++++++++++
3 files changed, 83 insertions(+)
--
2.33.0
2
3
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IC76OZ
----------------------------------------------------------------------
Armv8.7 introduces single-copy atomic 64-byte loads and stores
instructions and its variants named under FEAT_{LS64, LS64_V}.
These features are identified by ID_AA64ISAR1_EL1.LS64 and the
use of such instructions in userspace (EL0) can be trapped. In
order to support the use of corresponding instructions in userspace:
Make ID_AA64ISAR1_EL1.LS64 visbile to userspace
Add identifying and enabling in the cpufeature list
Expose these support of these features to userspace through HWCAP3
and cpuinfo
Mark Brown (2):
arm64: Support AT_HWCAP3
binfmt_elf: Wire up AT_HWCAP3 at AT_HWCAP4
Peter Bergner (1):
uapi/auxvec: Define AT_HWCAP3 and AT_HWCAP4 aux vector, entries
Yicong Yang (4):
arm64: Provide basic EL2 setup for FEAT_{LS64, LS64_V} usage at EL0/1
arm64: Add support for FEAT_{LS64, LS64_V}
Workaround the issue when compile with CONFIG_FUNCTION_ALIGNMENT_64B
KVM: arm64: Enable FEAT_{LS64, LS64_V} in the supported guest
Documentation/arch/arm64/booting.rst | 12 +++++
Documentation/arch/arm64/elf_hwcaps.rst | 12 +++--
arch/arm64/Kconfig | 4 ++
arch/arm64/include/asm/cpufeature.h | 3 +-
arch/arm64/include/asm/el2_setup.h | 13 ++++++
arch/arm64/include/asm/hwcap.h | 7 ++-
arch/arm64/include/uapi/asm/hwcap.h | 6 +++
arch/arm64/kernel/cpufeature.c | 61 +++++++++++++++++++++++++
arch/arm64/kernel/cpuinfo.c | 2 +
arch/arm64/kvm/hyp/include/hyp/switch.h | 6 +++
arch/arm64/tools/cpucaps | 4 +-
fs/binfmt_elf.c | 6 +++
fs/binfmt_elf_fdpic.c | 6 +++
fs/compat_binfmt_elf.c | 10 ++++
include/uapi/linux/auxvec.h | 2 +
15 files changed, 147 insertions(+), 7 deletions(-)
--
2.33.0
2
8
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IC76OZ
----------------------------------------------------------------------
Armv8.7 introduces single-copy atomic 64-byte loads and stores
instructions and its variants named under FEAT_{LS64, LS64_V}.
These features are identified by ID_AA64ISAR1_EL1.LS64 and the
use of such instructions in userspace (EL0) can be trapped. In
order to support the use of corresponding instructions in userspace:
Make ID_AA64ISAR1_EL1.LS64 visbile to userspace
Add identifying and enabling in the cpufeature list
Expose these support of these features to userspace through HWCAP3
and cpuinfo
Mark Brown (2):
arm64: Support AT_HWCAP3
binfmt_elf: Wire up AT_HWCAP3 at AT_HWCAP4
Peter Bergner (1):
uapi/auxvec: Define AT_HWCAP3 and AT_HWCAP4 aux vector, entries
Yicong Yang (4):
arm64: Provide basic EL2 setup for FEAT_{LS64, LS64_V} usage at EL0/1
arm64: Add support for FEAT_{LS64, LS64_V}
Workaround the issue when compile with CONFIG_FUNCTION_ALIGNMENT_64B
KVM: arm64: Enable FEAT_{LS64, LS64_V} in the supported guest
Documentation/arch/arm64/booting.rst | 12 +++++
Documentation/arch/arm64/elf_hwcaps.rst | 12 +++--
arch/arm64/Kconfig | 4 ++
arch/arm64/include/asm/cpufeature.h | 3 +-
arch/arm64/include/asm/el2_setup.h | 13 ++++++
arch/arm64/include/asm/hwcap.h | 7 ++-
arch/arm64/include/uapi/asm/hwcap.h | 6 +++
arch/arm64/kernel/cpufeature.c | 61 +++++++++++++++++++++++++
arch/arm64/kernel/cpuinfo.c | 2 +
arch/arm64/kvm/hyp/include/hyp/switch.h | 6 +++
arch/arm64/tools/cpucaps | 4 +-
fs/binfmt_elf.c | 6 +++
fs/binfmt_elf_fdpic.c | 6 +++
fs/compat_binfmt_elf.c | 10 ++++
include/uapi/linux/auxvec.h | 2 +
15 files changed, 147 insertions(+), 7 deletions(-)
--
2.33.0
2
8

[PATCH OLK-6.6 0/2] Update the watchdog period according to real CPU frequency
by Qinxin Xia 13 May '25
by Qinxin Xia 13 May '25
13 May '25
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IC7CQP
----------------------------------------------------------------------
watchdog perf needs architecture to provide method for converting the watchdog
thresh to counter period. For arm64 we're using the max CPU frequency for
doing the conversion which is from cpufreq driver. But some cpufreq driver
are registered lately, for example cppc_cpufreq will be registered at late
initcall which is after the initialization of watchdog perf (initialized in
armv8_pmuv3 of device initcall). In such case the period of watchdog will not
be accurate enough. Fix this by registering a cpufreq notifier and update the
watchdog period once the cpufreq driver is initialized.
Yicong Yang (2):
watchdog/perf: Provide function for adjusting the event period
arm64/watchdog_hld: Add a cpufreq notifier for update watchdog thresh
arch/arm64/kernel/watchdog_hld.c | 58 ++++++++++++++++++++++++++++++++
include/linux/nmi.h | 2 ++
kernel/watchdog_perf.c | 23 +++++++++++++
3 files changed, 83 insertions(+)
--
2.33.0
2
3

[openeuler:OLK-6.6 2195/2195] Documentation/devicetree/bindings/arm/arm,mpam-msc.yaml:76:15: [error] string value is redundantly quoted with any quotes (quoted-strings)
by kernel test robot 13 May '25
by kernel test robot 13 May '25
13 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: 8c683c781fbd8981b1fabf54cf6eec18190cebdf
commit: c21dc717760f8594e1fccae49eb86eb05e9a5f12 [2195/2195] dt-bindings: arm: Add MPAM MSC binding
config: arm64-randconfig-2053-20250504 (https://download.01.org/0day-ci/archive/20250513/202505131911.EBxgIjad-lkp@…)
compiler: aarch64-linux-gcc (GCC) 9.5.0
dtschema version: 2025.3.dev21+ge6ea659
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250513/202505131911.EBxgIjad-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505131911.EBxgIjad-lkp@intel.com/
dtcheck warnings: (new ones prefixed by >>)
>> Documentation/devicetree/bindings/arm/arm,mpam-msc.yaml:76:15: [error] string value is redundantly quoted with any quotes (quoted-strings)
Documentation/devicetree/bindings/arm/arm,mpam-msc.yaml:82:15: [error] string value is redundantly quoted with any quotes (quoted-strings)
vim +76 Documentation/devicetree/bindings/arm/arm,mpam-msc.yaml
8
9 description: |
10 The Arm MPAM specification can be found here:
11
12 https://developer.arm.com/documentation/ddi0598/latest
13
14 maintainers:
15 - Rob Herring <robh(a)kernel.org>
16
17 properties:
18 compatible:
19 items:
20 - const: arm,mpam-msc # Further details are discoverable
21 - const: arm,mpam-memory-controller-msc
22
23 reg:
24 maxItems: 1
25 description: A memory region containing registers as defined in the MPAM
26 specification.
27
28 interrupts:
29 minItems: 1
30 items:
31 - description: error (optional)
32 - description: overflow (optional, only for monitoring)
33
34 interrupt-names:
35 oneOf:
36 - items:
37 - enum: [ error, overflow ]
38 - items:
39 - const: error
40 - const: overflow
41
42 arm,not-ready-us:
43 description: The maximum time in microseconds for monitoring data to be
44 accurate after a settings change. For more information, see the
45 Not-Ready (NRDY) bit description in the MPAM specification.
46
47 numa-node-id: true # see NUMA binding
48
49 '#address-cells':
50 const: 1
51
52 '#size-cells':
53 const: 0
54
55 patternProperties:
56 '^ris@[0-9a-f]$':
57 type: object
58 additionalProperties: false
59 description: |
60 RIS nodes for each RIS in an MSC. These nodes are required for each RIS
61 implementing known MPAM controls
62
63 properties:
64 compatible:
65 enum:
66 # Bulk storage for cache
67 - arm,mpam-cache
68 # Memory bandwidth
69 - arm,mpam-memory
70
71 reg:
72 minimum: 0
73 maximum: 0xf
74
75 cpus:
> 76 $ref: '/schemas/types.yaml#/definitions/phandle-array'
77 description:
78 Phandle(s) to the CPU node(s) this RIS belongs to. By default, the parent
79 device's affinity is used.
80
81 arm,mpam-device:
82 $ref: '/schemas/types.yaml#/definitions/phandle'
83 description:
84 By default, the MPAM enabled device associated with a RIS is the MSC's
85 parent node. It is possible for each RIS to be associated with different
86 devices in which case 'arm,mpam-device' should be used.
87
88 required:
89 - compatible
90 - reg
91
92 required:
93 - compatible
94 - reg
95
96 dependencies:
97 interrupts: [ interrupt-names ]
98
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IBFE17
CVE: NA
--------------------------------
1. Add Motorcomm yt6801 PCIe Gigabit ethernet driver.
2. Add myself as the maintainer for the motorcomm ethernet driver.
3. Add yt6801 and MOTORCOMM_PHY in openeuler_defconfig
Signed-off-by: Frank_Sae <Frank.Sae(a)motor-comm.com>
---
MAINTAINERS | 7 +
arch/arm64/configs/openeuler_defconfig | 4 +-
arch/loongarch/configs/loongson3_defconfig | 3 +
arch/powerpc/configs/openeuler_defconfig | 4 +-
arch/riscv/configs/openeuler_defconfig | 4 +-
arch/x86/configs/openeuler_defconfig | 4 +-
drivers/net/ethernet/Kconfig | 1 +
drivers/net/ethernet/Makefile | 1 +
drivers/net/ethernet/motorcomm/Kconfig | 27 +
drivers/net/ethernet/motorcomm/Makefile | 6 +
.../net/ethernet/motorcomm/yt6801/Makefile | 8 +
.../ethernet/motorcomm/yt6801/yt6801_desc.c | 565 +++
.../ethernet/motorcomm/yt6801/yt6801_desc.h | 35 +
.../ethernet/motorcomm/yt6801/yt6801_main.c | 3020 +++++++++++++++++
.../ethernet/motorcomm/yt6801/yt6801_type.h | 961 ++++++
drivers/net/phy/motorcomm.c | 6 +
16 files changed, 4652 insertions(+), 4 deletions(-)
create mode 100644 drivers/net/ethernet/motorcomm/Kconfig
create mode 100644 drivers/net/ethernet/motorcomm/Makefile
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/Makefile
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.c
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.h
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_main.c
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_type.h
diff --git a/MAINTAINERS b/MAINTAINERS
index c6a3ac619..30cfe2988 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14553,6 +14553,13 @@ F: drivers/most/
F: drivers/staging/most/
F: include/linux/most.h
+MOTORCOMM ETHERNET DRIVER
+M: Frank <Frank.Sae(a)motor-comm.com>
+L: netdev(a)vger.kernel.org
+S: Maintained
+W: https://www.motor-comm.com/
+F: drivers/net/ethernet/motorcomm/*
+
MOTORCOMM PHY DRIVER
M: Peter Geis <pgwipeout(a)gmail.com>
M: Frank <Frank.Sae(a)motor-comm.com>
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig
index 7481b1293..563ef3bf4 100644
--- a/arch/arm64/configs/openeuler_defconfig
+++ b/arch/arm64/configs/openeuler_defconfig
@@ -3036,6 +3036,8 @@ CONFIG_MLXFW=m
CONFIG_NET_VENDOR_MICROSEMI=y
# CONFIG_MSCC_OCELOT_SWITCH is not set
CONFIG_NET_VENDOR_MICROSOFT=y
+CONFIG_NET_VENDOR_MOTORCOMM=y
+CONFIG_YT6801=m
CONFIG_NET_VENDOR_MYRI=y
# CONFIG_MYRI10GE is not set
# CONFIG_FEALNX is not set
@@ -3165,7 +3167,7 @@ CONFIG_MICREL_PHY=m
CONFIG_MICROCHIP_PHY=m
# CONFIG_MICROCHIP_T1_PHY is not set
# CONFIG_MICROSEMI_PHY is not set
-# CONFIG_MOTORCOMM_PHY is not set
+CONFIG_MOTORCOMM_PHY=m
CONFIG_NATIONAL_PHY=m
# CONFIG_NXP_CBTX_PHY is not set
# CONFIG_NXP_C45_TJA11XX_PHY is not set
diff --git a/arch/loongarch/configs/loongson3_defconfig b/arch/loongarch/configs/loongson3_defconfig
index 106b20292..0ec1d967c 100644
--- a/arch/loongarch/configs/loongson3_defconfig
+++ b/arch/loongarch/configs/loongson3_defconfig
@@ -858,6 +858,8 @@ CONFIG_MLXSW_CORE=m
# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_MICROCHIP is not set
# CONFIG_NET_VENDOR_MICROSEMI is not set
+CONFIG_NET_VENDOR_MOTORCOMM=y
+CONFIG_YT6801=m
# CONFIG_NET_VENDOR_MYRI is not set
# CONFIG_NET_VENDOR_NI is not set
# CONFIG_NET_VENDOR_NATSEMI is not set
@@ -913,6 +915,7 @@ CONFIG_MARVELL_10G_PHY=y
CONFIG_MICREL_PHY=m
CONFIG_MICROCHIP_T1_PHY=m
CONFIG_MICROSEMI_PHY=m
+CONFIG_MOTORCOMM_PHY=m
CONFIG_NATIONAL_PHY=m
CONFIG_QSEMI_PHY=m
CONFIG_RENESAS_PHY=m
diff --git a/arch/powerpc/configs/openeuler_defconfig b/arch/powerpc/configs/openeuler_defconfig
index 0c143a279..69286cb35 100644
--- a/arch/powerpc/configs/openeuler_defconfig
+++ b/arch/powerpc/configs/openeuler_defconfig
@@ -2557,6 +2557,8 @@ CONFIG_NET_VENDOR_MICROCHIP=y
CONFIG_NET_VENDOR_MICROSEMI=y
# CONFIG_MSCC_OCELOT_SWITCH is not set
CONFIG_NET_VENDOR_MICROSOFT=y
+CONFIG_NET_VENDOR_MOTORCOMM=y
+CONFIG_YT6801=m
CONFIG_NET_VENDOR_MYRI=y
CONFIG_MYRI10GE=m
# CONFIG_FEALNX is not set
@@ -2681,7 +2683,7 @@ CONFIG_MICREL_PHY=m
# CONFIG_MICROCHIP_PHY is not set
# CONFIG_MICROCHIP_T1_PHY is not set
# CONFIG_MICROSEMI_PHY is not set
-# CONFIG_MOTORCOMM_PHY is not set
+CONFIG_MOTORCOMM_PHY=m
CONFIG_NATIONAL_PHY=m
# CONFIG_NXP_C45_TJA11XX_PHY is not set
# CONFIG_NXP_TJA11XX_PHY is not set
diff --git a/arch/riscv/configs/openeuler_defconfig b/arch/riscv/configs/openeuler_defconfig
index 61f2b2f12..ca72545c1 100644
--- a/arch/riscv/configs/openeuler_defconfig
+++ b/arch/riscv/configs/openeuler_defconfig
@@ -2506,6 +2506,8 @@ CONFIG_MLXFW=m
CONFIG_NET_VENDOR_MICROSEMI=y
# CONFIG_MSCC_OCELOT_SWITCH is not set
CONFIG_NET_VENDOR_MICROSOFT=y
+CONFIG_NET_VENDOR_MOTORCOMM=y
+CONFIG_YT6801=m
CONFIG_NET_VENDOR_MYRI=y
# CONFIG_MYRI10GE is not set
# CONFIG_FEALNX is not set
@@ -2627,7 +2629,7 @@ CONFIG_MICREL_PHY=m
CONFIG_MICROCHIP_PHY=m
# CONFIG_MICROCHIP_T1_PHY is not set
CONFIG_MICROSEMI_PHY=m
-# CONFIG_MOTORCOMM_PHY is not set
+CONFIG_MOTORCOMM_PHY=m
CONFIG_NATIONAL_PHY=m
# CONFIG_NXP_CBTX_PHY is not set
# CONFIG_NXP_C45_TJA11XX_PHY is not set
diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig
index 84d771bec..9d86489a5 100644
--- a/arch/x86/configs/openeuler_defconfig
+++ b/arch/x86/configs/openeuler_defconfig
@@ -3026,6 +3026,8 @@ CONFIG_MLXFW=m
# CONFIG_NET_VENDOR_MICROSEMI is not set
CONFIG_NET_VENDOR_MICROSOFT=y
# CONFIG_MICROSOFT_MANA is not set
+CONFIG_NET_VENDOR_MOTORCOMM=y
+CONFIG_YT6801=m
CONFIG_NET_VENDOR_MYRI=y
CONFIG_MYRI10GE=m
CONFIG_MYRI10GE_DCA=y
@@ -3153,7 +3155,7 @@ CONFIG_MICREL_PHY=m
CONFIG_MICROCHIP_PHY=m
CONFIG_MICROCHIP_T1_PHY=m
CONFIG_MICROSEMI_PHY=m
-# CONFIG_MOTORCOMM_PHY is not set
+CONFIG_MOTORCOMM_PHY=m
CONFIG_NATIONAL_PHY=m
# CONFIG_NXP_CBTX_PHY is not set
# CONFIG_NXP_C45_TJA11XX_PHY is not set
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index 9cf6f1c67..f18cd4a57 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -133,6 +133,7 @@ source "drivers/net/ethernet/micrel/Kconfig"
source "drivers/net/ethernet/microchip/Kconfig"
source "drivers/net/ethernet/mscc/Kconfig"
source "drivers/net/ethernet/microsoft/Kconfig"
+source "drivers/net/ethernet/motorcomm/Kconfig"
source "drivers/net/ethernet/moxa/Kconfig"
source "drivers/net/ethernet/myricom/Kconfig"
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
index 328f6c44e..e3d013997 100644
--- a/drivers/net/ethernet/Makefile
+++ b/drivers/net/ethernet/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_NET_VENDOR_MELLANOX) += mellanox/
obj-$(CONFIG_NET_VENDOR_MICREL) += micrel/
obj-$(CONFIG_NET_VENDOR_MICROCHIP) += microchip/
obj-$(CONFIG_NET_VENDOR_MICROSEMI) += mscc/
+obj-$(CONFIG_NET_VENDOR_MOTORCOMM) += motorcomm/
obj-$(CONFIG_NET_VENDOR_MOXART) += moxa/
obj-$(CONFIG_NET_VENDOR_MYRI) += myricom/
obj-$(CONFIG_FEALNX) += fealnx.o
diff --git a/drivers/net/ethernet/motorcomm/Kconfig b/drivers/net/ethernet/motorcomm/Kconfig
new file mode 100644
index 000000000..abcc6cbcc
--- /dev/null
+++ b/drivers/net/ethernet/motorcomm/Kconfig
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Motorcomm network device configuration
+#
+
+config NET_VENDOR_MOTORCOMM
+ bool "Motorcomm devices"
+ default y
+ help
+ If you have a network (Ethernet) device belonging to this class,
+ say Y.
+
+ Note that the answer to this question doesn't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the questions about Motorcomm devices. If you say Y, you will be
+ asked for your specific device in the following questions.
+
+if NET_VENDOR_MOTORCOMM
+
+config YT6801
+ tristate "Motorcomm(R) 6801 PCI-Express Gigabit Ethernet support"
+ depends on PCI && NET
+ help
+ This driver supports Motorcomm(R) 6801 gigabit ethernet family of
+ adapters.
+
+endif # NET_VENDOR_MOTORCOMM
diff --git a/drivers/net/ethernet/motorcomm/Makefile b/drivers/net/ethernet/motorcomm/Makefile
new file mode 100644
index 000000000..511940680
--- /dev/null
+++ b/drivers/net/ethernet/motorcomm/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the Motorcomm network device drivers.
+#
+
+obj-$(CONFIG_YT6801) += yt6801/
diff --git a/drivers/net/ethernet/motorcomm/yt6801/Makefile b/drivers/net/ethernet/motorcomm/yt6801/Makefile
new file mode 100644
index 000000000..727866237
--- /dev/null
+++ b/drivers/net/ethernet/motorcomm/yt6801/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2021 Motor-comm Corporation.
+#
+# Makefile for the Motorcomm(R) 6801 PCI-Express ethernet driver
+#
+
+obj-$(CONFIG_YT6801) += yt6801.o
+yt6801-objs := yt6801_desc.o yt6801_main.o
diff --git a/drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.c b/drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.c
new file mode 100644
index 000000000..42aa7d694
--- /dev/null
+++ b/drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.c
@@ -0,0 +1,565 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Copyright (c) 2022 - 2024 Motorcomm Electronic Technology Co.,Ltd. */
+
+#include "yt6801_type.h"
+#include "yt6801_desc.h"
+
+void fxgmac_desc_data_unmap(struct fxgmac_pdata *priv,
+ struct fxgmac_desc_data *desc_data)
+{
+ if (desc_data->skb_dma) {
+ if (desc_data->mapped_as_page) {
+ dma_unmap_page(priv->dev, desc_data->skb_dma,
+ desc_data->skb_dma_len, DMA_TO_DEVICE);
+ } else {
+ dma_unmap_single(priv->dev, desc_data->skb_dma,
+ desc_data->skb_dma_len, DMA_TO_DEVICE);
+ }
+ desc_data->skb_dma = 0;
+ desc_data->skb_dma_len = 0;
+ }
+
+ if (desc_data->skb) {
+ dev_kfree_skb_any(desc_data->skb);
+ desc_data->skb = NULL;
+ }
+
+ if (desc_data->rx.hdr.pa.pages)
+ put_page(desc_data->rx.hdr.pa.pages);
+
+ if (desc_data->rx.hdr.pa_unmap.pages) {
+ dma_unmap_page(priv->dev, desc_data->rx.hdr.pa_unmap.pages_dma,
+ desc_data->rx.hdr.pa_unmap.pages_len,
+ DMA_FROM_DEVICE);
+ put_page(desc_data->rx.hdr.pa_unmap.pages);
+ }
+
+ if (desc_data->rx.buf.pa.pages)
+ put_page(desc_data->rx.buf.pa.pages);
+
+ if (desc_data->rx.buf.pa_unmap.pages) {
+ dma_unmap_page(priv->dev, desc_data->rx.buf.pa_unmap.pages_dma,
+ desc_data->rx.buf.pa_unmap.pages_len,
+ DMA_FROM_DEVICE);
+ put_page(desc_data->rx.buf.pa_unmap.pages);
+ }
+ memset(&desc_data->tx, 0, sizeof(desc_data->tx));
+ memset(&desc_data->rx, 0, sizeof(desc_data->rx));
+
+ desc_data->mapped_as_page = 0;
+}
+
+static int fxgmac_ring_init(struct fxgmac_pdata *priv, struct fxgmac_ring *ring,
+ unsigned int dma_desc_count)
+{
+ /* Descriptors */
+ ring->dma_desc_count = dma_desc_count;
+ ring->dma_desc_head =
+ dma_alloc_coherent(priv->dev, (sizeof(struct fxgmac_dma_desc) *
+ dma_desc_count),
+ &ring->dma_desc_head_addr, GFP_KERNEL);
+ if (!ring->dma_desc_head)
+ return -ENOMEM;
+
+ /* Array of descriptor data */
+ ring->desc_data_head = kcalloc(dma_desc_count,
+ sizeof(struct fxgmac_desc_data),
+ GFP_KERNEL);
+ if (!ring->desc_data_head)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void fxgmac_ring_free(struct fxgmac_pdata *priv,
+ struct fxgmac_ring *ring)
+{
+ if (!ring)
+ return;
+
+ if (ring->desc_data_head) {
+ for (u32 i = 0; i < ring->dma_desc_count; i++)
+ fxgmac_desc_data_unmap(priv,
+ FXGMAC_GET_DESC_DATA(ring, i));
+
+ kfree(ring->desc_data_head);
+ ring->desc_data_head = NULL;
+ }
+
+ if (ring->rx_hdr_pa.pages) {
+ dma_unmap_page(priv->dev, ring->rx_hdr_pa.pages_dma,
+ ring->rx_hdr_pa.pages_len, DMA_FROM_DEVICE);
+ put_page(ring->rx_hdr_pa.pages);
+
+ ring->rx_hdr_pa.pages = NULL;
+ ring->rx_hdr_pa.pages_len = 0;
+ ring->rx_hdr_pa.pages_offset = 0;
+ ring->rx_hdr_pa.pages_dma = 0;
+ }
+
+ if (ring->rx_buf_pa.pages) {
+ dma_unmap_page(priv->dev, ring->rx_buf_pa.pages_dma,
+ ring->rx_buf_pa.pages_len, DMA_FROM_DEVICE);
+ put_page(ring->rx_buf_pa.pages);
+
+ ring->rx_buf_pa.pages = NULL;
+ ring->rx_buf_pa.pages_len = 0;
+ ring->rx_buf_pa.pages_offset = 0;
+ ring->rx_buf_pa.pages_dma = 0;
+ }
+ if (ring->dma_desc_head) {
+ dma_free_coherent(priv->dev, (sizeof(struct fxgmac_dma_desc) *
+ ring->dma_desc_count), ring->dma_desc_head,
+ ring->dma_desc_head_addr);
+ ring->dma_desc_head = NULL;
+ }
+}
+
+static void fxgmac_rings_free(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ fxgmac_ring_free(priv, channel->tx_ring);
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ fxgmac_ring_free(priv, channel->rx_ring);
+}
+
+static int fxgmac_rings_alloc(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ int ret;
+
+ ret = fxgmac_ring_init(priv, channel->tx_ring, priv->tx_desc_count);
+ if (ret < 0) {
+ dev_err(priv->dev, "Initializing Tx ring failed");
+ goto err_init_ring;
+ }
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++) {
+ ret = fxgmac_ring_init(priv, channel->rx_ring,
+ priv->rx_desc_count);
+ if (ret < 0) {
+ dev_err(priv->dev, "Initializing Rx ring failed\n");
+ goto err_init_ring;
+ }
+ }
+ return 0;
+
+err_init_ring:
+ fxgmac_rings_free(priv);
+ return ret;
+}
+
+static void fxgmac_channels_free(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ kfree(channel->tx_ring);
+ channel->tx_ring = NULL;
+
+ kfree(channel->rx_ring);
+ channel->rx_ring = NULL;
+
+ kfree(channel);
+ priv->channel_head = NULL;
+}
+
+void fxgmac_channels_rings_free(struct fxgmac_pdata *priv)
+{
+ fxgmac_rings_free(priv);
+ fxgmac_channels_free(priv);
+}
+
+static void fxgmac_set_msix_tx_irq(struct fxgmac_pdata *priv,
+ struct fxgmac_channel *channel)
+{
+ priv->channel_irq[FXGMAC_MAX_DMA_RX_CHANNELS] =
+ priv->msix_entries[FXGMAC_MAX_DMA_RX_CHANNELS].vector;
+ channel->dma_irq_tx = priv->channel_irq[FXGMAC_MAX_DMA_RX_CHANNELS];
+}
+
+static int fxgmac_channels_alloc(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel_head, *channel;
+ struct fxgmac_ring *tx_ring, *rx_ring;
+ int ret = -ENOMEM;
+
+ channel_head = kcalloc(priv->channel_count,
+ sizeof(struct fxgmac_channel), GFP_KERNEL);
+
+ if (!channel_head)
+ return ret;
+
+ tx_ring = kcalloc(FXGMAC_TX_1_RING, sizeof(struct fxgmac_ring),
+ GFP_KERNEL);
+ if (!tx_ring)
+ goto err_tx_ring;
+
+ rx_ring = kcalloc(priv->rx_ring_count, sizeof(struct fxgmac_ring),
+ GFP_KERNEL);
+ if (!rx_ring)
+ goto err_rx_ring;
+
+ channel = channel_head;
+ for (u32 i = 0; i < priv->channel_count; i++, channel++) {
+ snprintf(channel->name, sizeof(channel->name), "channel-%u", i);
+ channel->priv = priv;
+ channel->queue_index = i;
+ channel->dma_regs = (priv)->hw_addr + DMA_CH_BASE +
+ (DMA_CH_INC * i);
+
+ if (priv->per_channel_irq) {
+ priv->channel_irq[i] = priv->msix_entries[i].vector;
+
+ if (IS_ENABLED(CONFIG_PCI_MSI) && i < FXGMAC_TX_1_RING)
+ fxgmac_set_msix_tx_irq(priv, channel);
+
+ /* Get the per DMA rx interrupt */
+ ret = priv->channel_irq[i];
+ if (ret < 0) {
+ dev_err(priv->dev, "channel irq[%u] failed\n",
+ i + 1);
+ goto err_irq;
+ }
+
+ channel->dma_irq_rx = ret;
+ }
+
+ if (i < FXGMAC_TX_1_RING)
+ channel->tx_ring = tx_ring++;
+
+ if (i < priv->rx_ring_count)
+ channel->rx_ring = rx_ring++;
+ }
+
+ priv->channel_head = channel_head;
+ return 0;
+
+err_irq:
+ kfree(rx_ring);
+
+err_rx_ring:
+ kfree(tx_ring);
+
+err_tx_ring:
+ kfree(channel_head);
+
+ dev_err(priv->dev, "%s failed:%d\n", __func__, ret);
+ return ret;
+}
+
+int fxgmac_channels_rings_alloc(struct fxgmac_pdata *priv)
+{
+ int ret;
+
+ ret = fxgmac_channels_alloc(priv);
+ if (ret < 0)
+ goto err_alloc;
+
+ ret = fxgmac_rings_alloc(priv);
+ if (ret < 0)
+ goto err_alloc;
+
+ return 0;
+
+err_alloc:
+ fxgmac_channels_rings_free(priv);
+ return ret;
+}
+
+static void fxgmac_set_buffer_data(struct fxgmac_buffer_data *bd,
+ struct fxgmac_page_alloc *pa,
+ unsigned int len)
+{
+ get_page(pa->pages);
+ bd->pa = *pa;
+
+ bd->dma_base = pa->pages_dma;
+ bd->dma_off = pa->pages_offset;
+ bd->dma_len = len;
+
+ pa->pages_offset += len;
+ if ((pa->pages_offset + len) > pa->pages_len) {
+ /* This data descriptor is responsible for unmapping page(s) */
+ bd->pa_unmap = *pa;
+
+ /* Get a new allocation next time */
+ pa->pages = NULL;
+ pa->pages_len = 0;
+ pa->pages_offset = 0;
+ pa->pages_dma = 0;
+ }
+}
+
+static int fxgmac_alloc_pages(struct fxgmac_pdata *priv,
+ struct fxgmac_page_alloc *pa, gfp_t gfp,
+ int order)
+{
+ struct page *pages = NULL;
+ dma_addr_t pages_dma;
+
+ /* Try to obtain pages, decreasing order if necessary */
+ gfp |= __GFP_COMP | __GFP_NOWARN;
+ while (order >= 0) {
+ pages = alloc_pages(gfp, order);
+ if (pages)
+ break;
+
+ order--;
+ }
+
+ if (!pages)
+ return -ENOMEM;
+
+ /* Map the pages */
+ pages_dma = dma_map_page(priv->dev, pages, 0, PAGE_SIZE << order,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(priv->dev, pages_dma)) {
+ put_page(pages);
+ return -ENOMEM;
+ }
+
+ pa->pages = pages;
+ pa->pages_len = PAGE_SIZE << order;
+ pa->pages_offset = 0;
+ pa->pages_dma = pages_dma;
+
+ return 0;
+}
+
+#define FXGMAC_SKB_ALLOC_SIZE 512
+
+int fxgmac_rx_buffe_map(struct fxgmac_pdata *priv, struct fxgmac_ring *ring,
+ struct fxgmac_desc_data *desc_data)
+{
+ int ret;
+
+ if (!ring->rx_hdr_pa.pages) {
+ ret = fxgmac_alloc_pages(priv, &ring->rx_hdr_pa, GFP_ATOMIC, 0);
+ if (ret)
+ return ret;
+ }
+ /* Set up the header page info */
+ fxgmac_set_buffer_data(&desc_data->rx.hdr, &ring->rx_hdr_pa,
+ priv->rx_buf_size);
+
+ return 0;
+}
+
+void fxgmac_desc_tx_reset(struct fxgmac_desc_data *desc_data)
+{
+ struct fxgmac_dma_desc *dma_desc = desc_data->dma_desc;
+
+ /* Reset the Tx descriptor
+ * Set buffer 1 (lo) address to zero
+ * Set buffer 1 (hi) address to zero
+ * Reset all other control bits (IC, TTSE, B2L & B1L)
+ * Reset all other control bits (OWN, CTXT, FD, LD, CPC, CIC, etc)
+ */
+ dma_desc->desc0 = 0;
+ dma_desc->desc1 = 0;
+ dma_desc->desc2 = 0;
+ dma_desc->desc3 = 0;
+
+ /* Make sure ownership is written to the descriptor */
+ dma_wmb();
+}
+
+void fxgmac_desc_rx_reset(struct fxgmac_desc_data *desc_data)
+{
+ struct fxgmac_dma_desc *dma_desc = desc_data->dma_desc;
+ dma_addr_t hdr_dma;
+
+ /* Reset the Rx descriptor
+ * Set buffer 1 (lo) address to header dma address (lo)
+ * Set buffer 1 (hi) address to header dma address (hi)
+ * set control bits OWN and INTE
+ */
+ hdr_dma = desc_data->rx.hdr.dma_base + desc_data->rx.hdr.dma_off;
+ dma_desc->desc0 = cpu_to_le32(lower_32_bits(hdr_dma));
+ dma_desc->desc1 = cpu_to_le32(upper_32_bits(hdr_dma));
+ dma_desc->desc2 = 0;
+ dma_desc->desc3 = 0;
+ fxgmac_desc_wr_bits(&dma_desc->desc3, RX_DESC3_INTE, 1);
+ fxgmac_desc_wr_bits(&dma_desc->desc3, RX_DESC3_BUF2V, 0);
+ fxgmac_desc_wr_bits(&dma_desc->desc3, RX_DESC3_BUF1V, 1);
+
+ /* Since the Rx DMA engine is likely running, make sure everything
+ * is written to the descriptor(s) before setting the OWN bit
+ * for the descriptor
+ */
+ dma_wmb();
+
+ fxgmac_desc_wr_bits(&dma_desc->desc3, RX_DESC3_OWN, 1);
+
+ /* Make sure ownership is written to the descriptor */
+ dma_wmb();
+}
+
+int fxgmac_tx_skb_map(struct fxgmac_channel *channel, struct sk_buff *skb)
+{
+ struct fxgmac_pdata *priv = channel->priv;
+ struct fxgmac_ring *ring = channel->tx_ring;
+ unsigned int start_index, cur_index;
+ struct fxgmac_desc_data *desc_data;
+ unsigned int offset, datalen, len;
+ struct fxgmac_pkt_info *pkt_info;
+ unsigned int tso, vlan;
+ dma_addr_t skb_dma;
+ skb_frag_t *frag;
+
+ offset = 0;
+ start_index = ring->cur;
+ cur_index = ring->cur;
+ pkt_info = &ring->pkt_info;
+ pkt_info->desc_count = 0;
+ pkt_info->length = 0;
+
+ tso = field_get(ATTR_TX_TSO_ENABLE, pkt_info->attr);
+ vlan = field_get(ATTR_TX_VLAN_CTAG, pkt_info->attr);
+
+ /* Save space for a context descriptor if needed */
+ if ((tso && pkt_info->mss != ring->tx.cur_mss) ||
+ (vlan && pkt_info->vlan_ctag != ring->tx.cur_vlan_ctag))
+ cur_index = FXGMAC_GET_ENTRY(cur_index, ring->dma_desc_count);
+
+ desc_data = FXGMAC_GET_DESC_DATA(ring, cur_index);
+
+ if (tso) {
+ /* Map the TSO header */
+ skb_dma = dma_map_single(priv->dev, skb->data,
+ pkt_info->header_len, DMA_TO_DEVICE);
+ if (dma_mapping_error(priv->dev, skb_dma)) {
+ dev_err(priv->dev, "dma map single failed\n");
+ goto err_out;
+ }
+ desc_data->skb_dma = skb_dma;
+ desc_data->skb_dma_len = pkt_info->header_len;
+
+ offset = pkt_info->header_len;
+ pkt_info->length += pkt_info->header_len;
+
+ cur_index = FXGMAC_GET_ENTRY(cur_index, ring->dma_desc_count);
+ desc_data = FXGMAC_GET_DESC_DATA(ring, cur_index);
+ }
+
+ /* Map the (remainder of the) packet */
+ for (datalen = skb_headlen(skb) - offset; datalen;) {
+ len = min_t(unsigned int, datalen, FXGMAC_TX_MAX_BUF_SIZE);
+ skb_dma = dma_map_single(priv->dev, skb->data + offset, len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(priv->dev, skb_dma)) {
+ dev_err(priv->dev, "dma map single failed\n");
+ goto err_out;
+ }
+ desc_data->skb_dma = skb_dma;
+ desc_data->skb_dma_len = len;
+
+ datalen -= len;
+ offset += len;
+ pkt_info->length += len;
+
+ cur_index = FXGMAC_GET_ENTRY(cur_index, ring->dma_desc_count);
+ desc_data = FXGMAC_GET_DESC_DATA(ring, cur_index);
+ }
+
+ for (u32 i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ frag = &skb_shinfo(skb)->frags[i];
+ offset = 0;
+
+ for (datalen = skb_frag_size(frag); datalen;) {
+ len = min_t(unsigned int, datalen,
+ FXGMAC_TX_MAX_BUF_SIZE);
+ skb_dma = skb_frag_dma_map(priv->dev, frag, offset, len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(priv->dev, skb_dma)) {
+ dev_err(priv->dev, "skb frag dma map failed\n");
+ goto err_out;
+ }
+ desc_data->skb_dma = skb_dma;
+ desc_data->skb_dma_len = len;
+ desc_data->mapped_as_page = 1;
+
+ datalen -= len;
+ offset += len;
+ pkt_info->length += len;
+
+ cur_index = FXGMAC_GET_ENTRY(cur_index,
+ ring->dma_desc_count);
+ desc_data = FXGMAC_GET_DESC_DATA(ring, cur_index);
+ }
+ }
+
+ /* Save the skb address in the last entry. We always have some data
+ * that has been mapped so desc_data is always advanced past the last
+ * piece of mapped data - use the entry pointed to by cur_index - 1.
+ */
+ desc_data = FXGMAC_GET_DESC_DATA(ring, (cur_index - 1) &
+ (ring->dma_desc_count - 1));
+ desc_data->skb = skb;
+
+ /* Save the number of descriptor entries used */
+ if (start_index <= cur_index)
+ pkt_info->desc_count = cur_index - start_index;
+ else
+ pkt_info->desc_count =
+ ring->dma_desc_count - start_index + cur_index;
+
+ return pkt_info->desc_count;
+
+err_out:
+ while (start_index < cur_index) {
+ desc_data = FXGMAC_GET_DESC_DATA(ring, start_index);
+ start_index =
+ FXGMAC_GET_ENTRY(start_index, ring->dma_desc_count);
+ fxgmac_desc_data_unmap(priv, desc_data);
+ }
+
+ return 0;
+}
+
+void fxgmac_dump_rx_desc(struct fxgmac_pdata *priv, struct fxgmac_ring *ring,
+ unsigned int idx)
+{
+ struct fxgmac_desc_data *desc_data;
+ struct fxgmac_dma_desc *dma_desc;
+
+ desc_data = FXGMAC_GET_DESC_DATA(ring, idx);
+ dma_desc = desc_data->dma_desc;
+ dev_dbg(priv->dev, "RX: dma_desc=%p, dma_desc_addr=%pad, RX_DESC[%d RX BY DEVICE] = %08x:%08x:%08x:%08x\n\n",
+ dma_desc, &desc_data->dma_desc_addr, idx,
+ le32_to_cpu(dma_desc->desc0), le32_to_cpu(dma_desc->desc1),
+ le32_to_cpu(dma_desc->desc2), le32_to_cpu(dma_desc->desc3));
+}
+
+void fxgmac_dump_tx_desc(struct fxgmac_pdata *priv, struct fxgmac_ring *ring,
+ unsigned int idx, unsigned int count,
+ unsigned int flag)
+{
+ struct fxgmac_desc_data *desc_data;
+
+ while (count--) {
+ desc_data = FXGMAC_GET_DESC_DATA(ring, idx);
+ dev_dbg(priv->dev, "TX: dma_desc=%p, dma_desc_addr=%pad, TX_DESC[%d %s] = %08x:%08x:%08x:%08x\n",
+ desc_data->dma_desc, &desc_data->dma_desc_addr, idx,
+ (flag == 1) ? "QUEUED FOR TX" : "TX BY DEVICE",
+ le32_to_cpu(desc_data->dma_desc->desc0),
+ le32_to_cpu(desc_data->dma_desc->desc1),
+ le32_to_cpu(desc_data->dma_desc->desc2),
+ le32_to_cpu(desc_data->dma_desc->desc3));
+
+ idx++;
+ }
+}
+
+int fxgmac_is_tx_complete(struct fxgmac_dma_desc *dma_desc)
+{
+ return !fxgmac_desc_rd_bits(dma_desc->desc3, TX_DESC3_OWN);
+}
+
+int fxgmac_is_last_desc(struct fxgmac_dma_desc *dma_desc)
+{
+ /* Rx and Tx share LD bit, so check TDES3.LD bit */
+ return fxgmac_desc_rd_bits(dma_desc->desc3, TX_DESC3_LD);
+}
diff --git a/drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.h b/drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.h
new file mode 100644
index 000000000..b238f20be
--- /dev/null
+++ b/drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* Copyright (c) 2022 - 2024 Motorcomm Electronic Technology Co.,Ltd. */
+
+#ifndef YT6801_DESC_H
+#define YT6801_DESC_H
+
+#define FXGMAC_TX_DESC_CNT 256
+#define FXGMAC_TX_DESC_MIN_FREE (FXGMAC_TX_DESC_CNT >> 3)
+#define FXGMAC_TX_DESC_MAX_PROC (FXGMAC_TX_DESC_CNT >> 1)
+#define FXGMAC_RX_DESC_CNT 1024
+#define FXGMAC_RX_DESC_MAX_DIRTY (FXGMAC_RX_DESC_CNT >> 3)
+
+#define FXGMAC_GET_DESC_DATA(ring, idx) ((ring)->desc_data_head + (idx))
+#define FXGMAC_GET_ENTRY(x, size) (((x) + 1) & ((size) - 1))
+
+void fxgmac_desc_tx_reset(struct fxgmac_desc_data *desc_data);
+void fxgmac_desc_rx_reset(struct fxgmac_desc_data *desc_data);
+void fxgmac_desc_data_unmap(struct fxgmac_pdata *priv,
+ struct fxgmac_desc_data *desc_data);
+
+int fxgmac_channels_rings_alloc(struct fxgmac_pdata *priv);
+void fxgmac_channels_rings_free(struct fxgmac_pdata *priv);
+int fxgmac_tx_skb_map(struct fxgmac_channel *channel, struct sk_buff *skb);
+int fxgmac_rx_buffe_map(struct fxgmac_pdata *priv, struct fxgmac_ring *ring,
+ struct fxgmac_desc_data *desc_data);
+void fxgmac_dump_tx_desc(struct fxgmac_pdata *priv, struct fxgmac_ring *ring,
+ unsigned int idx, unsigned int count,
+ unsigned int flag);
+void fxgmac_dump_rx_desc(struct fxgmac_pdata *priv, struct fxgmac_ring *ring,
+ unsigned int idx);
+
+int fxgmac_is_tx_complete(struct fxgmac_dma_desc *dma_desc);
+int fxgmac_is_last_desc(struct fxgmac_dma_desc *dma_desc);
+
+#endif /* YT6801_DESC_H */
diff --git a/drivers/net/ethernet/motorcomm/yt6801/yt6801_main.c b/drivers/net/ethernet/motorcomm/yt6801/yt6801_main.c
new file mode 100644
index 000000000..1bbfd8431
--- /dev/null
+++ b/drivers/net/ethernet/motorcomm/yt6801/yt6801_main.c
@@ -0,0 +1,3020 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Copyright (c) 2022 - 2024 Motorcomm Electronic Technology Co.,Ltd.
+ *
+ * Below is a simplified block diagram of YT6801 chip and its relevant
+ * interfaces.
+ * ||
+ * ********************++**********************
+ * * | PCIE Endpoint | *
+ * * +---------------+ *
+ * * | GMAC | *
+ * * +--++--+ *
+ * * |**| *
+ * * GMII --> |**| <-- MDIO *
+ * * +-++--+ *
+ * * | Integrated PHY | YT8531S *
+ * * +-++-+ *
+ * ********************||******************* **
+ */
+
+#include <linux/if_vlan.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+#include <linux/tcp.h>
+
+#include "yt6801_type.h"
+#include "yt6801_desc.h"
+
+const struct net_device_ops *fxgmac_get_netdev_ops(void);
+static void fxgmac_napi_enable(struct fxgmac_pdata *priv);
+
+#define PHY_WR_CONFIG(reg_offset) (0x8000205 + ((reg_offset) * 0x10000))
+static int fxgmac_phy_write_reg(struct fxgmac_pdata *priv, u32 reg_id, u32 data)
+{
+ u32 val;
+ int ret;
+
+ fxgmac_io_wr(priv, MAC_MDIO_DATA, data);
+ fxgmac_io_wr(priv, MAC_MDIO_ADDR, PHY_WR_CONFIG(reg_id));
+ ret = read_poll_timeout_atomic(fxgmac_io_rd, val,
+ !field_get(MAC_MDIO_ADDR_BUSY, val),
+ 10, 250, false, priv, MAC_MDIO_ADDR);
+ if (ret == -ETIMEDOUT)
+ dev_err(priv->dev, "%s, id:%x ctrl:0x%08x, data:0x%08x\n",
+ __func__, reg_id, PHY_WR_CONFIG(reg_id), data);
+
+ return ret;
+}
+
+#define PHY_RD_CONFIG(reg_offset) (0x800020d + ((reg_offset) * 0x10000))
+static int fxgmac_phy_read_reg(struct fxgmac_pdata *priv, u32 reg_id)
+{
+ u32 val;
+ int ret;
+
+ fxgmac_io_wr(priv, MAC_MDIO_ADDR, PHY_RD_CONFIG(reg_id));
+ ret = read_poll_timeout_atomic(fxgmac_io_rd, val,
+ !field_get(MAC_MDIO_ADDR_BUSY, val),
+ 10, 250, false, priv, MAC_MDIO_ADDR);
+ if (ret == -ETIMEDOUT) {
+ dev_err(priv->dev, "%s, id:%x, ctrl:0x%08x, val:0x%08x.\n",
+ __func__, reg_id, PHY_RD_CONFIG(reg_id), val);
+ return ret;
+ }
+
+ return fxgmac_io_rd(priv, MAC_MDIO_DATA); /* Read data */
+}
+
+static int fxgmac_mdio_write_reg(struct mii_bus *mii_bus, int phyaddr,
+ int phyreg, u16 val)
+{
+ if (phyaddr > 0)
+ return -ENODEV;
+
+ return fxgmac_phy_write_reg(mii_bus->priv, phyreg, val);
+}
+
+static int fxgmac_mdio_read_reg(struct mii_bus *mii_bus, int phyaddr,
+ int phyreg)
+{
+ if (phyaddr > 0)
+ return -ENODEV;
+
+ return fxgmac_phy_read_reg(mii_bus->priv, phyreg);
+}
+
+static int fxgmac_mdio_register(struct fxgmac_pdata *priv)
+{
+ struct pci_dev *pdev = to_pci_dev(priv->dev);
+ struct phy_device *phydev;
+ struct mii_bus *new_bus;
+ int ret;
+
+ new_bus = devm_mdiobus_alloc(&pdev->dev);
+ if (!new_bus)
+ return -ENOMEM;
+
+ new_bus->name = "yt6801";
+ new_bus->priv = priv;
+ new_bus->parent = &pdev->dev;
+ new_bus->read = fxgmac_mdio_read_reg;
+ new_bus->write = fxgmac_mdio_write_reg;
+ snprintf(new_bus->id, MII_BUS_ID_SIZE, "yt6801-%x-%x",
+ pci_domain_nr(pdev->bus), pci_dev_id(pdev));
+
+ ret = devm_mdiobus_register(&pdev->dev, new_bus);
+ if (ret < 0)
+ return ret;
+
+ phydev = mdiobus_get_phy(new_bus, 0);
+ if (!phydev)
+ return -ENODEV;
+
+ priv->phydev = phydev;
+ return 0;
+}
+
+static void fxgmac_tx_start_xmit(struct fxgmac_channel *channel,
+ struct fxgmac_ring *ring)
+{
+ struct fxgmac_desc_data *desc_data;
+
+ wmb(); /* Make sure everything is written before the register write */
+
+ /* Issue a poll command to Tx DMA by writing address
+ * of next immediate free descriptor
+ */
+ desc_data = FXGMAC_GET_DESC_DATA(ring, ring->cur);
+ fxgmac_dma_io_wr(channel, DMA_CH_TDTR_LO,
+ lower_32_bits(desc_data->dma_desc_addr));
+
+ ring->tx.xmit_more = 0;
+}
+
+static unsigned int fxgmac_desc_tx_avail(struct fxgmac_ring *ring)
+{
+ if (ring->dirty > ring->cur)
+ return ring->dirty - ring->cur;
+ else
+ return ring->dma_desc_count - ring->cur + ring->dirty;
+}
+
+static netdev_tx_t fxgmac_maybe_stop_tx_queue(struct fxgmac_channel *channel,
+ struct fxgmac_ring *ring,
+ unsigned int count)
+{
+ struct fxgmac_pdata *priv = channel->priv;
+
+ if (count > fxgmac_desc_tx_avail(ring)) {
+ netdev_err(priv->ndev, "Tx queue stopped, not enough descriptors available\n");
+ netif_stop_subqueue(priv->ndev, channel->queue_index);
+ ring->tx.queue_stopped = 1;
+
+ /* If we haven't notified the hardware because of xmit_more
+ * support, tell it now
+ */
+ if (ring->tx.xmit_more)
+ fxgmac_tx_start_xmit(channel, ring);
+
+ return NETDEV_TX_BUSY;
+ }
+
+ return NETDEV_TX_OK;
+}
+
+static void fxgmac_enable_msix_one_irq(struct fxgmac_pdata *priv, u32 int_id)
+{
+ fxgmac_io_wr(priv, MSIX_TBL_MASK + int_id * 16, 0);
+}
+
+static void fxgmac_disable_msix_one_irq(struct fxgmac_pdata *priv, u32 intid)
+{
+ fxgmac_io_wr(priv, MSIX_TBL_MASK + intid * 16, 1);
+}
+
+static void fxgmac_disable_mgm_irq(struct fxgmac_pdata *priv)
+{
+ fxgmac_io_wr_bits(priv, MGMT_INT_CTRL0, MGMT_INT_CTRL0_INT_MASK,
+ MGMT_INT_CTRL0_INT_MASK_MASK);
+}
+
+static irqreturn_t fxgmac_isr(int irq, void *data)
+{
+ struct fxgmac_pdata *priv = data;
+ u32 val;
+
+ val = fxgmac_io_rd(priv, MGMT_INT_CTRL0);
+ if (!(val & MGMT_INT_CTRL0_INT_STATUS_RXTX))
+ return IRQ_NONE;
+
+ /* Restart the device on a Fatal Bus Error */
+ for (u32 i = 0; i < priv->channel_count; i++) {
+ val = fxgmac_dma_io_rd(priv->channel_head + i, DMA_CH_SR);
+ if (field_get(DMA_CH_SR_FBE, val))
+ schedule_work(&priv->restart_work);
+ /* Clear all the interrupts which are set */
+ fxgmac_dma_io_wr(priv->channel_head + i, DMA_CH_SR, val);
+ }
+
+ fxgmac_disable_mgm_irq(priv);
+ napi_schedule_irqoff(&priv->napi); /* Turn on polling */
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t fxgmac_dma_isr(int irq, void *data)
+{
+ struct fxgmac_channel *channel = data;
+
+ if (irq == channel->dma_irq_tx) {
+ fxgmac_disable_msix_one_irq(channel->priv, MSI_ID_TXQ0);
+ /* Clear Tx signal */
+ fxgmac_dma_io_wr(channel, DMA_CH_SR, DMA_CH_SR_TI);
+ napi_schedule_irqoff(&channel->napi_tx);
+ return IRQ_HANDLED;
+ }
+
+ fxgmac_disable_msix_one_irq(channel->priv, channel->queue_index);
+ /* Clear Rx signal */
+ fxgmac_dma_io_wr(channel, DMA_CH_SR, DMA_CH_SR_RI);
+ napi_schedule_irqoff(&channel->napi_rx);
+ return IRQ_HANDLED;
+}
+
+static void napi_disable_del(struct fxgmac_pdata *priv, struct napi_struct *n,
+ u32 flag)
+{
+ napi_disable(n);
+ netif_napi_del(n);
+ priv->int_flag &= ~flag;
+}
+
+static void fxgmac_napi_disable(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ u32 rx_napi[] = {INT_FLAG_RX0_NAPI, INT_FLAG_RX1_NAPI,
+ INT_FLAG_RX2_NAPI, INT_FLAG_RX3_NAPI};
+
+ if (!priv->per_channel_irq) {
+ if (!field_get(INT_FLAG_LEGACY_NAPI, priv->int_flag))
+ return;
+
+ napi_disable_del(priv, &priv->napi,
+ INT_FLAG_LEGACY_NAPI);
+ return;
+ }
+
+ if (field_get(INT_FLAG_TX_NAPI, priv->int_flag))
+ napi_disable_del(priv, &channel->napi_tx, INT_FLAG_TX_NAPI);
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ if (priv->int_flag & rx_napi[i])
+ napi_disable_del(priv, &channel->napi_rx, rx_napi[i]);
+}
+
+static void fxgmac_free_irqs(struct fxgmac_pdata *priv)
+{
+ u32 rx_irq[] = {INT_FLAG_RX0_IRQ, INT_FLAG_RX1_IRQ,
+ INT_FLAG_RX2_IRQ, INT_FLAG_RX3_IRQ};
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ if (!field_get(INT_FLAG_MSIX, priv->int_flag) &&
+ field_get(INT_FLAG_LEGACY_IRQ, priv->int_flag)) {
+ devm_free_irq(priv->dev, priv->dev_irq, priv);
+ priv->int_flag &= ~INT_FLAG_LEGACY_IRQ;
+ }
+
+ if (!priv->per_channel_irq)
+ return;
+
+ if (field_get(INT_FLAG_TX_IRQ, priv->int_flag)) {
+ priv->int_flag &= ~INT_FLAG_TX_IRQ;
+ devm_free_irq(priv->dev, channel->dma_irq_tx, channel);
+ }
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ if (priv->int_flag & rx_irq[i]) {
+ priv->int_flag &= ~rx_irq[i];
+ devm_free_irq(priv->dev, channel->dma_irq_rx, channel);
+ }
+}
+
+static int fxgmac_request_irqs(struct fxgmac_pdata *priv)
+{
+ u32 rx_irq[] = {INT_FLAG_RX0_IRQ, INT_FLAG_RX1_IRQ,
+ INT_FLAG_RX2_IRQ, INT_FLAG_RX3_IRQ};
+ u32 i = 0, msi = field_get(INT_FLAG_MSI, priv->int_flag);
+ struct fxgmac_channel *channel = priv->channel_head;
+ struct net_device *ndev = priv->ndev;
+ int ret;
+
+ if (!field_get(INT_FLAG_MSIX, priv->int_flag) &&
+ !field_get(INT_FLAG_LEGACY_IRQ, priv->int_flag)) {
+ priv->int_flag |= INT_FLAG_LEGACY_IRQ;
+ ret = devm_request_irq(priv->dev, priv->dev_irq, fxgmac_isr,
+ msi ? 0 : IRQF_SHARED, ndev->name,
+ priv);
+ if (ret) {
+ dev_err(priv->dev, "Requesting irq:%d, failed:%d\n",
+ priv->dev_irq, ret);
+ return ret;
+ }
+ }
+
+ if (!priv->per_channel_irq)
+ return 0;
+
+ if (!field_get(INT_FLAG_TX_IRQ, priv->int_flag)) {
+ snprintf(channel->dma_irq_tx_name,
+ sizeof(channel->dma_irq_tx_name) - 1,
+ "%s-ch%d-Tx-%u", netdev_name(ndev), 0,
+ channel->queue_index);
+ priv->int_flag |= INT_FLAG_TX_IRQ;
+ ret = devm_request_irq(priv->dev, channel->dma_irq_tx,
+ fxgmac_dma_isr, 0,
+ channel->dma_irq_tx_name, channel);
+ if (ret) {
+ dev_err(priv->dev, "dev:%p, channel:%p\n",
+ priv->dev, channel);
+
+ dev_err(priv->dev, "Requesting tx irq:%d, failed:%d\n",
+ channel->dma_irq_tx, ret);
+ goto err_irq;
+ }
+ }
+
+ for (i = 0; i < priv->channel_count; i++, channel++) {
+ snprintf(channel->dma_irq_rx_name,
+ sizeof(channel->dma_irq_rx_name) - 1, "%s-ch%d-Rx-%u",
+ netdev_name(ndev), i, channel->queue_index);
+
+ if ((priv->int_flag & rx_irq[i]) != rx_irq[i]) {
+ priv->int_flag |= rx_irq[i];
+ ret = devm_request_irq(priv->dev, channel->dma_irq_rx,
+ fxgmac_dma_isr, 0,
+ channel->dma_irq_rx_name,
+ channel);
+ if (ret) {
+ dev_err(priv->dev, "Requesting rx irq:%d, failed:%d\n",
+ channel->dma_irq_rx, ret);
+ goto err_irq;
+ }
+ }
+ }
+
+ return 0;
+
+err_irq:
+ fxgmac_free_irqs(priv);
+ return ret;
+}
+
+static void fxgmac_free_tx_data(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ struct fxgmac_ring *ring;
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++) {
+ ring = channel->tx_ring;
+ if (!ring)
+ break;
+
+ for (u32 j = 0; j < ring->dma_desc_count; j++)
+ fxgmac_desc_data_unmap(priv,
+ FXGMAC_GET_DESC_DATA(ring, j));
+ }
+}
+
+static void fxgmac_free_rx_data(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ struct fxgmac_ring *ring;
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++) {
+ ring = channel->rx_ring;
+ if (!ring)
+ break;
+
+ for (u32 j = 0; j < ring->dma_desc_count; j++)
+ fxgmac_desc_data_unmap(priv,
+ FXGMAC_GET_DESC_DATA(ring, j));
+ }
+}
+
+static void fxgmac_enable_tx(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ /* Enable Tx DMA channel */
+ fxgmac_dma_wr_bits(channel, DMA_CH_TCR, DMA_CH_TCR_ST, 1);
+
+ /* Enable Tx queue */
+ fxgmac_mtl_wr_bits(priv, 0, MTL_Q_TQOMR, MTL_Q_TQOMR_TXQEN,
+ MTL_Q_ENABLED);
+ /* Enable MAC Tx */
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_TE, 1);
+}
+
+static void fxgmac_prepare_tx_stop(struct fxgmac_pdata *priv,
+ struct fxgmac_channel *channel)
+{
+ unsigned long tx_timeout;
+ unsigned int tx_status;
+
+ /* The Tx engine cannot be stopped if it is actively processing
+ * descriptors. Wait for the Tx engine to enter the stopped or
+ * suspended state.
+ */
+ tx_timeout = jiffies + (FXGMAC_DMA_STOP_TIMEOUT * HZ);
+
+ while (time_before(jiffies, tx_timeout)) {
+ tx_status = fxgmac_io_rd(priv, DMA_DSR0);
+ tx_status = field_get(DMA_DSR0_TPS, tx_status);
+ if (tx_status == DMA_TPS_STOPPED ||
+ tx_status == DMA_TPS_SUSPENDED)
+ break;
+
+ fsleep(500);
+ }
+
+ if (!time_before(jiffies, tx_timeout))
+ dev_err(priv->dev, "timed out waiting for Tx DMA channel stop\n");
+}
+
+static void fxgmac_disable_tx(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ /* Prepare for Tx DMA channel stop */
+ fxgmac_prepare_tx_stop(priv, channel);
+
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_TE, 0); /* Disable MAC Tx */
+
+ /* Disable Tx queue */
+ fxgmac_mtl_wr_bits(priv, 0, MTL_Q_TQOMR, MTL_Q_TQOMR_TXQEN,
+ MTL_Q_DISABLED);
+
+ /* Disable Tx DMA channel */
+ fxgmac_dma_wr_bits(channel, DMA_CH_TCR, DMA_CH_TCR_ST, 0);
+}
+
+static void fxgmac_enable_rx(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ u32 val = 0, i;
+
+ /* Enable each Rx DMA channel */
+ for (i = 0; i < priv->channel_count; i++, channel++)
+ fxgmac_dma_wr_bits(channel, DMA_CH_RCR, DMA_CH_RCR_SR, 1);
+
+ /* Enable each Rx queue */
+ for (i = 0; i < priv->rx_q_count; i++)
+ val |= (0x02 << (i << 1));
+
+ fxgmac_io_wr(priv, MAC_RQC0R, val);
+
+ /* Enable MAC Rx */
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_CST, 1);
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_ACS, 1);
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_RE, 1);
+}
+
+static void fxgmac_prepare_rx_stop(struct fxgmac_pdata *priv,
+ unsigned int queue)
+{
+ unsigned int rx_status, rx_q, rx_q_sts;
+ unsigned long rx_timeout;
+
+ /* The Rx engine cannot be stopped if it is actively processing
+ * packets. Wait for the Rx queue to empty the Rx fifo.
+ */
+ rx_timeout = jiffies + (FXGMAC_DMA_STOP_TIMEOUT * HZ);
+
+ while (time_before(jiffies, rx_timeout)) {
+ rx_status = fxgmac_mtl_io_rd(priv, queue, MTL_Q_RQDR);
+ rx_q = field_get(MTL_Q_RQDR_PRXQ, rx_status);
+ rx_q_sts = field_get(MTL_Q_RQDR_RXQSTS, rx_status);
+ if (rx_q == 0 && rx_q_sts == 0)
+ break;
+
+ fsleep(500);
+ }
+
+ if (!time_before(jiffies, rx_timeout))
+ dev_err(priv->dev, "timed out waiting for Rx queue %u to empty\n",
+ queue);
+}
+
+static void fxgmac_disable_rx(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ u32 i;
+
+ /* Disable MAC Rx */
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_CST, 0);
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_ACS, 0);
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_RE, 0);
+
+ /* Prepare for Rx DMA channel stop */
+ for (i = 0; i < priv->rx_q_count; i++)
+ fxgmac_prepare_rx_stop(priv, i);
+
+ fxgmac_io_wr(priv, MAC_RQC0R, 0); /* Disable each Rx queue */
+
+ /* Disable each Rx DMA channel */
+ for (i = 0; i < priv->channel_count; i++, channel++)
+ fxgmac_dma_wr_bits(channel, DMA_CH_RCR, DMA_CH_RCR_SR, 0);
+}
+
+static void fxgmac_default_speed_duplex_config(struct fxgmac_pdata *priv)
+{
+ priv->mac_duplex = DUPLEX_FULL;
+ priv->mac_speed = SPEED_1000;
+}
+
+static void fxgmac_config_mac_speed(struct fxgmac_pdata *priv)
+{
+ if (priv->mac_duplex == DUPLEX_UNKNOWN &&
+ priv->mac_speed == SPEED_UNKNOWN)
+ fxgmac_default_speed_duplex_config(priv);
+
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_DM, priv->mac_duplex);
+
+ switch (priv->mac_speed) {
+ case SPEED_1000:
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_PS, 0);
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_FES, 0);
+ break;
+ case SPEED_100:
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_PS, 1);
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_FES, 1);
+ break;
+ case SPEED_10:
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_PS, 1);
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_FES, 0);
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+}
+
+static void fxgmac_phylink_handler(struct net_device *ndev)
+{
+ struct fxgmac_pdata *priv = netdev_priv(ndev);
+
+ priv->mac_speed = priv->phydev->speed;
+ priv->mac_duplex = priv->phydev->duplex;
+
+ if (priv->phydev->link) {
+ fxgmac_config_mac_speed(priv);
+ fxgmac_enable_rx(priv);
+ fxgmac_enable_tx(priv);
+ if (netif_running(priv->ndev))
+ netif_tx_wake_all_queues(priv->ndev);
+ } else {
+ netif_tx_stop_all_queues(priv->ndev);
+ fxgmac_disable_rx(priv);
+ fxgmac_disable_tx(priv);
+ }
+
+ phy_print_status(priv->phydev);
+}
+
+static int fxgmac_phy_connect(struct fxgmac_pdata *priv)
+{
+ struct phy_device *phydev = priv->phydev;
+ int ret;
+
+ priv->phydev->irq = PHY_POLL;
+ ret = phy_connect_direct(priv->ndev, phydev, fxgmac_phylink_handler,
+ PHY_INTERFACE_MODE_INTERNAL);
+ if (ret)
+ return ret;
+
+ phy_support_asym_pause(phydev);
+ priv->phydev->mac_managed_pm = 1;
+ phy_attached_info(phydev);
+
+ return 0;
+}
+
+static void fxgmac_enable_msix_irqs(struct fxgmac_pdata *priv)
+{
+ for (u32 intid = 0; intid < MSIX_TBL_MAX_NUM; intid++)
+ fxgmac_enable_msix_one_irq(priv, intid);
+}
+
+static void __fxgmac_set_mac_address(struct fxgmac_pdata *priv, u8 *addr)
+{
+ u32 mac_hi, mac_lo;
+
+ mac_lo = (u32)addr[0] | ((u32)addr[1] << 8) | ((u32)addr[2] << 16) |
+ ((u32)addr[3] << 24);
+
+ mac_hi = (u32)addr[4] | ((u32)addr[5] << 8);
+
+ fxgmac_io_wr(priv, MAC_MACA0LR, mac_lo);
+ fxgmac_io_wr(priv, MAC_MACA0HR, mac_hi);
+}
+
+static void fxgmac_config_mac_address(struct fxgmac_pdata *priv)
+{
+ __fxgmac_set_mac_address(priv, priv->mac_addr);
+ fxgmac_io_wr_bits(priv, MAC_PFR, MAC_PFR_HPF, 1);
+ fxgmac_io_wr_bits(priv, MAC_PFR, MAC_PFR_HUC, 1);
+ fxgmac_io_wr_bits(priv, MAC_PFR, MAC_PFR_HMC, 1);
+}
+
+static void fxgmac_config_crc_check_en(struct fxgmac_pdata *priv)
+{
+ fxgmac_io_wr_bits(priv, MAC_ECR, MAC_ECR_DCRCC, 1);
+}
+
+static void fxgmac_config_checksum_offload(struct fxgmac_pdata *priv)
+{
+ if (priv->ndev->features & NETIF_F_RXCSUM)
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_IPC, 1);
+ else
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_IPC, 0);
+}
+
+static void fxgmac_set_promiscuous_mode(struct fxgmac_pdata *priv,
+ unsigned int enable)
+{
+ fxgmac_io_wr_bits(priv, MAC_PFR, MAC_PFR_PR, enable);
+}
+
+static void fxgmac_enable_rx_broadcast(struct fxgmac_pdata *priv,
+ unsigned int enable)
+{
+ fxgmac_io_wr_bits(priv, MAC_PFR, MAC_PFR_DBF, enable);
+}
+
+static void fxgmac_set_all_multicast_mode(struct fxgmac_pdata *priv,
+ unsigned int enable)
+{
+ fxgmac_io_wr_bits(priv, MAC_PFR, MAC_PFR_PM, enable);
+}
+
+static void fxgmac_config_rx_mode(struct fxgmac_pdata *priv)
+{
+ u32 pr_mode, am_mode, bd_mode;
+
+ pr_mode = ((priv->ndev->flags & IFF_PROMISC) != 0);
+ am_mode = ((priv->ndev->flags & IFF_ALLMULTI) != 0);
+ bd_mode = ((priv->ndev->flags & IFF_BROADCAST) != 0);
+
+ fxgmac_enable_rx_broadcast(priv, bd_mode);
+ fxgmac_set_promiscuous_mode(priv, pr_mode);
+ fxgmac_set_all_multicast_mode(priv, am_mode);
+}
+
+static void fxgmac_config_tx_flow_control(struct fxgmac_pdata *priv)
+{
+ /* Set MTL flow control */
+ for (u32 i = 0; i < priv->rx_q_count; i++)
+ fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_EHFC,
+ priv->tx_pause);
+
+ /* Set MAC flow control */
+ fxgmac_io_wr_bits(priv, MAC_Q0TFCR, MAC_Q0TFCR_TFE, priv->tx_pause);
+
+ if (priv->tx_pause == 1) /* Set pause time */
+ fxgmac_io_wr_bits(priv, MAC_Q0TFCR, MAC_Q0TFCR_PT, 0xffff);
+}
+
+static void fxgmac_config_rx_flow_control(struct fxgmac_pdata *priv)
+{
+ fxgmac_io_wr_bits(priv, MAC_RFCR, MAC_RFCR_RFE, priv->rx_pause);
+}
+
+static void fxgmac_config_rx_coalesce(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++) {
+ if (!channel->rx_ring)
+ break;
+ fxgmac_dma_wr_bits(channel, DMA_CH_RIWT, DMA_CH_RIWT_RWT,
+ priv->rx_riwt);
+ }
+}
+
+static void fxgmac_config_rx_fep_disable(struct fxgmac_pdata *priv)
+{
+ /* Enable the rx queue forward packet with error status
+ * (crc error,gmii_er, watch dog timeout.or overflow)
+ */
+ for (u32 i = 0; i < priv->rx_q_count; i++)
+ fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_FEP, 1);
+}
+
+static void fxgmac_config_rx_fup_enable(struct fxgmac_pdata *priv)
+{
+ for (u32 i = 0; i < priv->rx_q_count; i++)
+ fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_FUP, 1);
+}
+
+static void fxgmac_config_rx_buffer_size(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ fxgmac_dma_wr_bits(channel, DMA_CH_RCR, DMA_CH_RCR_RBSZ,
+ priv->rx_buf_size);
+}
+
+static void fxgmac_config_tso_mode(struct fxgmac_pdata *priv)
+{
+ fxgmac_dma_wr_bits(priv->channel_head, DMA_CH_TCR, DMA_CH_TCR_TSE,
+ priv->hw_feat.tso);
+}
+
+static void fxgmac_config_sph_mode(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ fxgmac_dma_wr_bits(channel, DMA_CH_CR, DMA_CH_CR_SPH, 0);
+
+ fxgmac_io_wr_bits(priv, MAC_ECR, MAC_ECR_HDSMS, MAC_ECR_HDSMS_512B);
+}
+
+static void fxgmac_config_rx_threshold(struct fxgmac_pdata *priv,
+ unsigned int set_val)
+{
+ for (u32 i = 0; i < priv->rx_q_count; i++)
+ fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_RTC,
+ set_val);
+}
+
+static void fxgmac_config_mtl_mode(struct fxgmac_pdata *priv)
+{
+ /* Set Tx to weighted round robin scheduling algorithm */
+ fxgmac_io_wr_bits(priv, MTL_OMR, MTL_OMR_ETSALG, MTL_ETSALG_WRR);
+
+ /* Set Tx traffic classes to use WRR algorithm with equal weights */
+ fxgmac_mtl_wr_bits(priv, 0, MTL_TC_QWR, MTL_TC_QWR_QW, 1);
+
+ /* Set Rx to strict priority algorithm */
+ fxgmac_io_wr_bits(priv, MTL_OMR, MTL_OMR_RAA, MTL_RAA_SP);
+}
+
+static void fxgmac_config_queue_mapping(struct fxgmac_pdata *priv)
+{
+ unsigned int ppq, ppq_extra, prio_queues;
+ unsigned int __maybe_unused prio;
+ unsigned int reg, val, mask;
+
+ /* Map the 8 VLAN priority values to available MTL Rx queues */
+ prio_queues =
+ min_t(unsigned int, IEEE_8021QAZ_MAX_TCS, priv->rx_q_count);
+ ppq = IEEE_8021QAZ_MAX_TCS / prio_queues;
+ ppq_extra = IEEE_8021QAZ_MAX_TCS % prio_queues;
+
+ reg = MAC_RQC2R;
+ for (u32 i = 0, prio = 0; i < prio_queues;) {
+ val = 0;
+ mask = 0;
+ for (u32 j = 0; j < ppq; j++) {
+ mask |= (1 << prio);
+ prio++;
+ }
+
+ if (i < ppq_extra) {
+ mask |= (1 << prio);
+ prio++;
+ }
+
+ val |= (mask << ((i++ % MAC_RQC2_Q_PER_REG) << 3));
+
+ if ((i % MAC_RQC2_Q_PER_REG) && i != prio_queues)
+ continue;
+
+ fxgmac_io_wr(priv, reg, val);
+ reg += MAC_RQC2_INC;
+ }
+
+ /* Configure one to one, MTL Rx queue to DMA Rx channel mapping
+ * ie Q0 <--> CH0, Q1 <--> CH1 ... Q7 <--> CH7
+ */
+ val = fxgmac_io_rd(priv, MTL_RQDCM0R);
+ val |= (MTL_RQDCM0R_Q0MDMACH | MTL_RQDCM0R_Q1MDMACH |
+ MTL_RQDCM0R_Q2MDMACH | MTL_RQDCM0R_Q3MDMACH);
+ fxgmac_io_wr(priv, MTL_RQDCM0R, val);
+
+ val = fxgmac_io_rd(priv, MTL_RQDCM0R + MTL_RQDCM_INC);
+ val |= (MTL_RQDCM1R_Q4MDMACH | MTL_RQDCM1R_Q5MDMACH |
+ MTL_RQDCM1R_Q6MDMACH | MTL_RQDCM1R_Q7MDMACH);
+ fxgmac_io_wr(priv, MTL_RQDCM0R + MTL_RQDCM_INC, val);
+}
+
+static unsigned int fxgmac_calculate_per_queue_fifo(unsigned int fifo_size,
+ unsigned int queue_count)
+{
+ u32 q_fifo_size, p_fifo;
+
+ /* Calculate the configured fifo size */
+ q_fifo_size = 1 << (fifo_size + 7);
+
+#define FXGMAC_MAX_FIFO 81920
+ /* The configured value may not be the actual amount of fifo RAM */
+ q_fifo_size = min_t(unsigned int, FXGMAC_MAX_FIFO, q_fifo_size);
+ q_fifo_size = q_fifo_size / queue_count;
+
+ /* Each increment in the queue fifo size represents 256 bytes of
+ * fifo, with 0 representing 256 bytes. Distribute the fifo equally
+ * between the queues.
+ */
+ p_fifo = q_fifo_size / 256;
+ if (p_fifo)
+ p_fifo--;
+
+ return p_fifo;
+}
+
+static void fxgmac_config_tx_fifo_size(struct fxgmac_pdata *priv)
+{
+ u32 fifo_size;
+
+ fifo_size = fxgmac_calculate_per_queue_fifo(priv->hw_feat.tx_fifo_size,
+ FXGMAC_TX_1_Q);
+ fxgmac_mtl_wr_bits(priv, 0, MTL_Q_TQOMR, MTL_Q_TQOMR_TQS, fifo_size);
+}
+
+static void fxgmac_config_rx_fifo_size(struct fxgmac_pdata *priv)
+{
+ u32 fifo_size;
+
+ fifo_size = fxgmac_calculate_per_queue_fifo(priv->hw_feat.rx_fifo_size,
+ priv->rx_q_count);
+
+ for (u32 i = 0; i < priv->rx_q_count; i++)
+ fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_RQS,
+ fifo_size);
+}
+
+static void fxgmac_config_flow_control_threshold(struct fxgmac_pdata *priv)
+{
+ for (u32 i = 0; i < priv->rx_q_count; i++) {
+ /* Activate flow control when less than 4k left in fifo */
+ fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_RFA, 6);
+ /* De-activate flow control when more than 6k left in fifo */
+ fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_RFD, 10);
+ }
+}
+
+static void fxgmac_config_tx_threshold(struct fxgmac_pdata *priv,
+ unsigned int set_val)
+{
+ fxgmac_mtl_wr_bits(priv, 0, MTL_Q_TQOMR, MTL_Q_TQOMR_TTC, set_val);
+}
+
+static void fxgmac_config_rsf_mode(struct fxgmac_pdata *priv,
+ unsigned int set_val)
+{
+ for (u32 i = 0; i < priv->rx_q_count; i++)
+ fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_RSF,
+ set_val);
+}
+
+static void fxgmac_config_tsf_mode(struct fxgmac_pdata *priv,
+ unsigned int set_val)
+{
+ fxgmac_mtl_wr_bits(priv, 0, MTL_Q_TQOMR, MTL_Q_TQOMR_TSF, set_val);
+}
+
+static void fxgmac_config_osp_mode(struct fxgmac_pdata *priv)
+{
+ fxgmac_dma_wr_bits(priv->channel_head, DMA_CH_TCR, DMA_CH_TCR_OSP,
+ priv->tx_osp_mode);
+}
+
+static void fxgmac_config_pblx8(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ fxgmac_dma_wr_bits(channel, DMA_CH_CR, DMA_CH_CR_PBLX8,
+ priv->pblx8);
+}
+
+static void fxgmac_config_tx_pbl_val(struct fxgmac_pdata *priv)
+{
+ fxgmac_dma_wr_bits(priv->channel_head, DMA_CH_TCR, DMA_CH_TCR_PBL,
+ priv->tx_pbl);
+}
+
+static void fxgmac_config_rx_pbl_val(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ fxgmac_dma_wr_bits(channel, DMA_CH_RCR, DMA_CH_RCR_PBL,
+ priv->rx_pbl);
+}
+
+static void fxgmac_config_mmc(struct fxgmac_pdata *priv)
+{
+ /* Set counters to reset on read, Reset the counters */
+ fxgmac_io_wr_bits(priv, MMC_CR, MMC_CR_ROR, 1);
+ fxgmac_io_wr_bits(priv, MMC_CR, MMC_CR_CR, 1);
+
+ fxgmac_io_wr(priv, MMC_IPC_RXINT_MASK, 0xffffffff);
+}
+
+static void fxgmac_enable_dma_interrupts(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ u32 ch_sr;
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++) {
+ /* Clear all the interrupts which are set */
+ ch_sr = fxgmac_dma_io_rd(channel, DMA_CH_SR);
+ fxgmac_dma_io_wr(channel, DMA_CH_SR, ch_sr);
+
+ ch_sr = 0;
+ /* Enable Normal Interrupt Summary Enable and Fatal Bus Error
+ * Enable interrupts.
+ */
+ ch_sr |= (DMA_CH_IER_NIE | DMA_CH_IER_FBEE);
+
+ /* only one tx, enable Transmit Interrupt Enable interrupts */
+ if (i == 0 && channel->tx_ring)
+ ch_sr |= DMA_CH_IER_TIE;
+
+ /* Enable Receive Buffer Unavailable Enable and Receive
+ * Interrupt Enable interrupts.
+ */
+ if (channel->rx_ring)
+ ch_sr |= (DMA_CH_IER_RBUE | DMA_CH_IER_RIE);
+
+ fxgmac_dma_io_wr(channel, DMA_CH_IER, ch_sr);
+ }
+}
+
+static void fxgmac_enable_mtl_interrupts(struct fxgmac_pdata *priv)
+{
+ unsigned int mtl_q_isr;
+
+ for (u32 i = 0; i < priv->hw_feat.rx_q_cnt; i++) {
+ /* Clear all the interrupts which are set */
+ mtl_q_isr = fxgmac_mtl_io_rd(priv, i, MTL_Q_IR);
+ fxgmac_mtl_io_wr(priv, i, MTL_Q_IR, mtl_q_isr);
+
+ /* No MTL interrupts to be enabled */
+ fxgmac_mtl_io_wr(priv, i, MTL_Q_IR, 0);
+ }
+}
+
+static void fxgmac_enable_mac_interrupts(struct fxgmac_pdata *priv)
+{
+ /* Disable Timestamp interrupt */
+ fxgmac_io_wr_bits(priv, MAC_IER, MAC_IER_TSIE, 0);
+
+ fxgmac_io_wr_bits(priv, MMC_RIER, MMC_RIER_ALL_INTERRUPTS, 0);
+ fxgmac_io_wr_bits(priv, MMC_TIER, MMC_TIER_ALL_INTERRUPTS, 0);
+}
+
+static int fxgmac_flush_tx_queues(struct fxgmac_pdata *priv)
+{
+ u32 val, count = 2000;
+
+ fxgmac_mtl_wr_bits(priv, 0, MTL_Q_TQOMR, MTL_Q_TQOMR_FTQ, 1);
+ do {
+ fsleep(20);
+ val = fxgmac_mtl_io_rd(priv, 0, MTL_Q_TQOMR);
+ val = field_get(MTL_Q_TQOMR_FTQ, val);
+
+ } while (--count && val);
+
+ if (val)
+ return -EBUSY;
+
+ return 0;
+}
+
+static void fxgmac_config_dma_bus(struct fxgmac_pdata *priv)
+{
+ u32 val = fxgmac_io_rd(priv, DMA_SBMR);
+
+ val &= ~(DMA_SBMR_EAME | DMA_SBMR_RD_OSR_LMT |
+ DMA_SBMR_WR_OSR_LMT | DMA_SBMR_FB);
+
+ /* Set enhanced addressing mode */
+ val |= DMA_SBMR_EAME;
+
+ /* Out standing read/write requests */
+ val |= field_prep(DMA_SBMR_RD_OSR_LMT, 0x7);
+ val |= field_prep(DMA_SBMR_WR_OSR_LMT, 0x7);
+
+ /* Set the System Bus mode */
+ val |= (DMA_SBMR_BLEN_4 | DMA_SBMR_BLEN_8 |
+ DMA_SBMR_BLEN_16 | DMA_SBMR_BLEN_32);
+
+ fxgmac_io_wr(priv, DMA_SBMR, val);
+}
+
+static void fxgmac_desc_rx_channel_init(struct fxgmac_channel *channel)
+{
+ struct fxgmac_ring *ring = channel->rx_ring;
+ unsigned int start_index = ring->cur;
+ struct fxgmac_desc_data *desc_data;
+
+ /* Initialize all descriptors */
+ for (u32 i = 0; i < ring->dma_desc_count; i++) {
+ desc_data = FXGMAC_GET_DESC_DATA(ring, i);
+ fxgmac_desc_rx_reset(desc_data); /* Initialize Rx descriptor */
+ }
+
+ /* Update the total number of Rx descriptors */
+ fxgmac_dma_io_wr(channel, DMA_CH_RDRLR, ring->dma_desc_count - 1);
+
+ /* Update the starting address of descriptor ring */
+ desc_data = FXGMAC_GET_DESC_DATA(ring, start_index);
+
+ fxgmac_dma_io_wr(channel, DMA_CH_RDLR_HI,
+ upper_32_bits(desc_data->dma_desc_addr));
+ fxgmac_dma_io_wr(channel, DMA_CH_RDLR_LO,
+ lower_32_bits(desc_data->dma_desc_addr));
+
+ /* Update the Rx Descriptor Tail Pointer */
+ desc_data = FXGMAC_GET_DESC_DATA(ring, start_index +
+ ring->dma_desc_count - 1);
+ fxgmac_dma_io_wr(channel, DMA_CH_RDTR_LO,
+ lower_32_bits(desc_data->dma_desc_addr));
+}
+
+static void fxgmac_desc_rx_init(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ struct fxgmac_desc_data *desc_data;
+ struct fxgmac_dma_desc *dma_desc;
+ dma_addr_t dma_desc_addr;
+ struct fxgmac_ring *ring;
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++) {
+ ring = channel->rx_ring;
+ dma_desc = ring->dma_desc_head;
+ dma_desc_addr = ring->dma_desc_head_addr;
+
+ for (u32 j = 0; j < ring->dma_desc_count; j++) {
+ desc_data = FXGMAC_GET_DESC_DATA(ring, j);
+ desc_data->dma_desc = dma_desc;
+ desc_data->dma_desc_addr = dma_desc_addr;
+ if (fxgmac_rx_buffe_map(priv, ring, desc_data))
+ break;
+
+ dma_desc++;
+ dma_desc_addr += sizeof(struct fxgmac_dma_desc);
+ }
+
+ ring->cur = 0;
+ ring->dirty = 0;
+
+ fxgmac_desc_rx_channel_init(channel);
+ }
+}
+
+static void fxgmac_desc_tx_channel_init(struct fxgmac_channel *channel)
+{
+ struct fxgmac_ring *ring = channel->tx_ring;
+ struct fxgmac_desc_data *desc_data;
+ int start_index = ring->cur;
+
+ /* Initialize all descriptors */
+ for (u32 i = 0; i < ring->dma_desc_count; i++) {
+ desc_data = FXGMAC_GET_DESC_DATA(ring, i);
+ fxgmac_desc_tx_reset(desc_data); /* Initialize Tx descriptor */
+ }
+
+ /* Update the total number of Tx descriptors */
+ fxgmac_dma_io_wr(channel, DMA_CH_TDRLR,
+ channel->priv->tx_desc_count - 1);
+
+ /* Update the starting address of descriptor ring */
+ desc_data = FXGMAC_GET_DESC_DATA(ring, start_index);
+
+ fxgmac_dma_io_wr(channel, DMA_CH_TDLR_HI,
+ upper_32_bits(desc_data->dma_desc_addr));
+ fxgmac_dma_io_wr(channel, DMA_CH_TDLR_LO,
+ lower_32_bits(desc_data->dma_desc_addr));
+}
+
+static void fxgmac_desc_tx_init(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ struct fxgmac_ring *ring = channel->tx_ring;
+ struct fxgmac_desc_data *desc_data;
+ struct fxgmac_dma_desc *dma_desc;
+ dma_addr_t dma_desc_addr;
+
+ dma_desc = ring->dma_desc_head;
+ dma_desc_addr = ring->dma_desc_head_addr;
+
+ for (u32 j = 0; j < ring->dma_desc_count; j++) {
+ desc_data = FXGMAC_GET_DESC_DATA(ring, j);
+ desc_data->dma_desc = dma_desc;
+ desc_data->dma_desc_addr = dma_desc_addr;
+
+ dma_desc++;
+ dma_desc_addr += sizeof(struct fxgmac_dma_desc);
+ }
+
+ ring->cur = 0;
+ ring->dirty = 0;
+ memset(&ring->tx, 0, sizeof(ring->tx));
+ fxgmac_desc_tx_channel_init(priv->channel_head);
+}
+
+static int fxgmac_hw_init(struct fxgmac_pdata *priv)
+{
+ int ret;
+
+ ret = fxgmac_flush_tx_queues(priv); /* Flush Tx queues */
+ if (ret < 0) {
+ dev_err(priv->dev, "%s, flush tx queue failed:%d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ /* Initialize DMA related features */
+ fxgmac_config_dma_bus(priv);
+ fxgmac_config_osp_mode(priv);
+ fxgmac_config_pblx8(priv);
+ fxgmac_config_tx_pbl_val(priv);
+ fxgmac_config_rx_pbl_val(priv);
+ fxgmac_config_rx_coalesce(priv);
+ fxgmac_config_rx_buffer_size(priv);
+ fxgmac_config_tso_mode(priv);
+ fxgmac_config_sph_mode(priv);
+ fxgmac_desc_tx_init(priv);
+ fxgmac_desc_rx_init(priv);
+ fxgmac_enable_dma_interrupts(priv);
+
+ /* Initialize MTL related features */
+ fxgmac_config_mtl_mode(priv);
+ fxgmac_config_queue_mapping(priv);
+ fxgmac_config_tsf_mode(priv, priv->tx_sf_mode);
+ fxgmac_config_rsf_mode(priv, priv->rx_sf_mode);
+ fxgmac_config_tx_threshold(priv, priv->tx_threshold);
+ fxgmac_config_rx_threshold(priv, priv->rx_threshold);
+ fxgmac_config_tx_fifo_size(priv);
+ fxgmac_config_rx_fifo_size(priv);
+ fxgmac_config_flow_control_threshold(priv);
+ fxgmac_config_rx_fep_disable(priv);
+ fxgmac_config_rx_fup_enable(priv);
+ fxgmac_enable_mtl_interrupts(priv);
+
+ /* Initialize MAC related features */
+ fxgmac_config_mac_address(priv);
+ fxgmac_config_crc_check_en(priv);
+ fxgmac_config_rx_mode(priv);
+ fxgmac_config_tx_flow_control(priv);
+ fxgmac_config_rx_flow_control(priv);
+ fxgmac_config_mac_speed(priv);
+ fxgmac_config_checksum_offload(priv);
+ fxgmac_config_mmc(priv);
+ fxgmac_enable_mac_interrupts(priv);
+
+ return 0;
+}
+
+static void fxgmac_dismiss_all_int(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ u32 i;
+
+ /* Clear all the interrupts which are set */
+ for (i = 0; i < priv->channel_count; i++, channel++)
+ fxgmac_dma_io_wr(channel, DMA_CH_SR,
+ fxgmac_dma_io_rd(channel, DMA_CH_SR));
+
+ for (i = 0; i < priv->hw_feat.rx_q_cnt; i++)
+ fxgmac_mtl_io_wr(priv, i, MTL_Q_IR,
+ fxgmac_mtl_io_rd(priv, i, MTL_Q_IR));
+
+ fxgmac_io_rd(priv, MAC_ISR); /* Clear all MAC interrupts */
+ fxgmac_io_rd(priv, MAC_TX_RX_STA);/* Clear tx/rx error interrupts */
+ fxgmac_io_rd(priv, MAC_PMT_STA);
+ fxgmac_io_rd(priv, MAC_LPI_STA);
+
+ fxgmac_io_wr(priv, MAC_DBG_STA, fxgmac_io_rd(priv, MAC_DBG_STA));
+}
+
+static void fxgmac_set_interrupt_moderation(struct fxgmac_pdata *priv)
+{
+ fxgmac_io_wr_bits(priv, INT_MOD, INT_MOD_TX, priv->tx_usecs);
+ fxgmac_io_wr_bits(priv, INT_MOD, INT_MOD_RX, priv->rx_usecs);
+}
+
+static void fxgmac_enable_mgm_irq(struct fxgmac_pdata *priv)
+{
+ fxgmac_io_wr_bits(priv, MGMT_INT_CTRL0, MGMT_INT_CTRL0_INT_STATUS, 0);
+ fxgmac_io_wr_bits(priv, MGMT_INT_CTRL0, MGMT_INT_CTRL0_INT_MASK,
+ MGMT_INT_CTRL0_INT_MASK_MISC);
+}
+
+/**
+ * fxgmac_set_oob_wol - disable or enable oob wol crtl function
+ * @priv: driver private struct
+ * @en: 1 or 0
+ *
+ * Description: After enable OOB_WOL from efuse, mac will loopcheck phy status,
+ * and lead to panic sometimes. So we should disable it from powerup,
+ * enable it from power down.
+ */
+static void fxgmac_set_oob_wol(struct fxgmac_pdata *priv, unsigned int en)
+{
+ /* en = 1 is disable */
+ fxgmac_io_wr_bits(priv, OOB_WOL_CTRL, OOB_WOL_CTRL_DIS, !en);
+}
+
+static void fxgmac_config_powerup(struct fxgmac_pdata *priv)
+{
+ fxgmac_set_oob_wol(priv, 0);
+ /* GAMC power up */
+ fxgmac_io_wr_bits(priv, MAC_PMT_STA, MAC_PMT_STA_PWRDWN, 0);
+}
+
+static void fxgmac_pre_powerdown(struct fxgmac_pdata *priv)
+{
+ fxgmac_set_oob_wol(priv, 1);
+ fsleep(2000);
+}
+
+static void fxgmac_restore_nonstick_reg(struct fxgmac_pdata *priv)
+{
+ for (u32 i = GLOBAL_CTRL0; i < MSI_PBA; i += 4)
+ fxgmac_io_wr(priv, i,
+ priv->reg_nonstick[(i - GLOBAL_CTRL0) >> 2]);
+}
+
+static void fxgmac_phy_release(struct fxgmac_pdata *priv)
+{
+ fxgmac_io_wr_bits(priv, EPHY_CTRL, EPHY_CTRL_RESET, 1);
+ fsleep(100);
+}
+
+static void fxgmac_hw_exit(struct fxgmac_pdata *priv)
+{
+ /* Reset CHIP, it will reset trigger circuit and reload efuse patch */
+ fxgmac_io_wr_bits(priv, SYS_RESET, SYS_RESET_RESET, 1);
+ fsleep(9000);
+
+ fxgmac_phy_release(priv);
+
+ /* Reset will clear nonstick registers. */
+ fxgmac_restore_nonstick_reg(priv);
+}
+
+static void fxgmac_pcie_init(struct fxgmac_pdata *priv)
+{
+ /* snoopy + non-snoopy */
+ fxgmac_io_wr_bits(priv, LTR_IDLE_ENTER, LTR_IDLE_ENTER_REQUIRE, 1);
+ fxgmac_io_wr_bits(priv, LTR_IDLE_ENTER, LTR_IDLE_ENTER_SCALE,
+ LTR_IDLE_ENTER_SCALE_1024_NS);
+ fxgmac_io_wr_bits(priv, LTR_IDLE_ENTER, LTR_IDLE_ENTER_ENTER,
+ LTR_IDLE_ENTER_900_US);
+
+ /* snoopy + non-snoopy */
+ fxgmac_io_wr_bits(priv, LTR_IDLE_EXIT, LTR_IDLE_EXIT_REQUIRE, 1);
+ fxgmac_io_wr_bits(priv, LTR_IDLE_EXIT, LTR_IDLE_EXIT_SCALE, 2);
+ fxgmac_io_wr_bits(priv, LTR_IDLE_EXIT, LTR_IDLE_EXIT_EXIT,
+ LTR_IDLE_EXIT_171_US);
+
+ fxgmac_io_wr_bits(priv, PCIE_SERDES_PLL, PCIE_SERDES_PLL_AUTOOFF, 1);
+}
+
+static void fxgmac_phy_reset(struct fxgmac_pdata *priv)
+{
+ fxgmac_io_wr_bits(priv, EPHY_CTRL, EPHY_CTRL_RESET, 0);
+ fsleep(1500);
+}
+
+static int fxgmac_start(struct fxgmac_pdata *priv)
+{
+ int ret;
+
+ if (priv->dev_state != FXGMAC_DEV_OPEN &&
+ priv->dev_state != FXGMAC_DEV_STOP &&
+ priv->dev_state != FXGMAC_DEV_RESUME) {
+ return 0;
+ }
+
+ if (priv->dev_state != FXGMAC_DEV_STOP) {
+ fxgmac_phy_reset(priv);
+ fxgmac_phy_release(priv);
+ }
+
+ if (priv->dev_state == FXGMAC_DEV_OPEN) {
+ ret = fxgmac_phy_connect(priv);
+ if (ret < 0)
+ return ret;
+ }
+
+ fxgmac_pcie_init(priv);
+ if (test_bit(FXGMAC_POWER_STATE_DOWN, &priv->power_state)) {
+ dev_err(priv->dev, "fxgmac powerstate is %lu when config power up.\n",
+ priv->power_state);
+ }
+
+ fxgmac_config_powerup(priv);
+ fxgmac_dismiss_all_int(priv);
+ ret = fxgmac_hw_init(priv);
+ if (ret < 0) {
+ dev_err(priv->dev, "fxgmac hw init failed.\n");
+ return ret;
+ }
+
+ fxgmac_napi_enable(priv);
+ ret = fxgmac_request_irqs(priv);
+ if (ret < 0)
+ return ret;
+
+ /* Config interrupt to level signal */
+ fxgmac_io_wr_bits(priv, DMA_MR, DMA_MR_INTM, 2);
+ fxgmac_io_wr_bits(priv, DMA_MR, DMA_MR_QUREAD, 1);
+
+ fxgmac_enable_mgm_irq(priv);
+ fxgmac_set_interrupt_moderation(priv);
+
+ if (priv->per_channel_irq)
+ fxgmac_enable_msix_irqs(priv);
+
+ fxgmac_enable_dma_interrupts(priv);
+ priv->dev_state = FXGMAC_DEV_START;
+ phy_start(priv->phydev);
+
+ return 0;
+}
+
+static void fxgmac_disable_msix_irqs(struct fxgmac_pdata *priv)
+{
+ for (u32 intid = 0; intid < MSIX_TBL_MAX_NUM; intid++)
+ fxgmac_disable_msix_one_irq(priv, intid);
+}
+
+static void fxgmac_stop(struct fxgmac_pdata *priv)
+{
+ struct net_device *ndev = priv->ndev;
+ struct netdev_queue *txq;
+
+ if (priv->dev_state != FXGMAC_DEV_START)
+ return;
+
+ priv->dev_state = FXGMAC_DEV_STOP;
+
+ if (priv->per_channel_irq)
+ fxgmac_disable_msix_irqs(priv);
+ else
+ fxgmac_disable_mgm_irq(priv);
+
+ netif_carrier_off(ndev);
+ netif_tx_stop_all_queues(ndev);
+ fxgmac_disable_tx(priv);
+ fxgmac_disable_rx(priv);
+ fxgmac_free_irqs(priv);
+ fxgmac_napi_disable(priv);
+ phy_stop(priv->phydev);
+
+ txq = netdev_get_tx_queue(ndev, priv->channel_head->queue_index);
+ netdev_tx_reset_queue(txq);
+}
+
+static void fxgmac_restart(struct fxgmac_pdata *priv)
+{
+ int ret;
+
+ /* If not running, "restart" will happen on open */
+ if (!netif_running(priv->ndev) && priv->dev_state != FXGMAC_DEV_START)
+ return;
+
+ fxgmac_stop(priv);
+ fxgmac_free_tx_data(priv);
+ fxgmac_free_rx_data(priv);
+ ret = fxgmac_start(priv);
+ if (ret < 0)
+ dev_err(priv->dev, "fxgmac start failed:%d.\n", ret);
+}
+
+static void fxgmac_restart_work(struct work_struct *work)
+{
+ rtnl_lock();
+ fxgmac_restart(container_of(work, struct fxgmac_pdata, restart_work));
+ rtnl_unlock();
+}
+
+static int fxgmac_net_powerup(struct fxgmac_pdata *priv)
+{
+ int ret;
+
+ priv->power_state = 0;/* clear all bits as normal now */
+ ret = fxgmac_start(priv);
+ if (ret < 0) {
+ dev_err(priv->dev, "fxgmac start failed:%d.\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void fxgmac_config_powerdown(struct fxgmac_pdata *priv)
+{
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_RE, 1); /* Enable MAC Rx */
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_TE, 1); /* Enable MAC TX */
+
+ /* Set GAMC power down */
+ fxgmac_io_wr_bits(priv, MAC_PMT_STA, MAC_PMT_STA_PWRDWN, 1);
+}
+
+static int fxgmac_net_powerdown(struct fxgmac_pdata *priv)
+{
+ struct net_device *ndev = priv->ndev;
+
+ /* Signal that we are down to the interrupt handler */
+ if (__test_and_set_bit(FXGMAC_POWER_STATE_DOWN, &priv->power_state))
+ return 0; /* do nothing if already down */
+
+ __clear_bit(FXGMAC_POWER_STATE_UP, &priv->power_state);
+ netif_tx_stop_all_queues(ndev); /* Shut off incoming Tx traffic */
+
+ /* Call carrier off first to avoid false dev_watchdog timeouts */
+ netif_carrier_off(ndev);
+ netif_tx_disable(ndev);
+ fxgmac_disable_rx(priv);
+
+ /* Synchronize_rcu() needed for pending XDP buffers to drain */
+ synchronize_rcu();
+
+ fxgmac_stop(priv);
+ fxgmac_pre_powerdown(priv);
+
+ if (!test_bit(FXGMAC_POWER_STATE_DOWN, &priv->power_state))
+ dev_err(priv->dev, "fxgmac powerstate is %lu when config powe down.\n",
+ priv->power_state);
+
+ /* Set mac to lowpower mode */
+ fxgmac_config_powerdown(priv);
+ fxgmac_free_tx_data(priv);
+ fxgmac_free_rx_data(priv);
+
+ return 0;
+}
+
+static int fxgmac_calc_rx_buf_size(struct fxgmac_pdata *priv, unsigned int mtu)
+{
+ u32 rx_buf_size, max_mtu = FXGMAC_JUMBO_PACKET_MTU - ETH_HLEN;
+
+ if (mtu > max_mtu) {
+ dev_err(priv->dev, "MTU exceeds maximum supported value\n");
+ return -EINVAL;
+ }
+
+ rx_buf_size = mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
+ rx_buf_size =
+ clamp_val(rx_buf_size, FXGMAC_RX_MIN_BUF_SIZE, PAGE_SIZE * 4);
+
+ rx_buf_size = (rx_buf_size + FXGMAC_RX_BUF_ALIGN - 1) &
+ ~(FXGMAC_RX_BUF_ALIGN - 1);
+
+ return rx_buf_size;
+}
+
+static int fxgmac_open(struct net_device *ndev)
+{
+ struct fxgmac_pdata *priv = netdev_priv(ndev);
+ int ret;
+
+ priv->dev_state = FXGMAC_DEV_OPEN;
+
+ /* Calculate the Rx buffer size before allocating rings */
+ ret = fxgmac_calc_rx_buf_size(priv, ndev->mtu);
+ if (ret < 0)
+ goto unlock;
+
+ priv->rx_buf_size = ret;
+ ret = fxgmac_channels_rings_alloc(priv);
+ if (ret < 0)
+ goto unlock;
+
+ INIT_WORK(&priv->restart_work, fxgmac_restart_work);
+ ret = fxgmac_start(priv);
+ if (ret < 0)
+ goto err_channels_and_rings;
+
+ return 0;
+
+err_channels_and_rings:
+ fxgmac_channels_rings_free(priv);
+ dev_err(priv->dev, "%s, channel alloc failed\n", __func__);
+unlock:
+ rtnl_unlock();
+ return ret;
+}
+
+static int fxgmac_close(struct net_device *ndev)
+{
+ struct fxgmac_pdata *priv = netdev_priv(ndev);
+
+ fxgmac_stop(priv); /* Stop the device */
+ priv->dev_state = FXGMAC_DEV_CLOSE;
+ fxgmac_channels_rings_free(priv); /* Free the channels and rings */
+ fxgmac_phy_reset(priv);
+ phy_disconnect(priv->phydev);
+
+ return 0;
+}
+
+static void fxgmac_dump_state(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ struct fxgmac_ring *ring = &channel->tx_ring[0];
+ struct device *pdev = priv->dev;
+
+ dev_err(pdev, "Tx descriptor info:\n");
+ dev_err(pdev, " cur = 0x%x\n", ring->cur);
+ dev_err(pdev, " dirty = 0x%x\n", ring->dirty);
+ dev_err(pdev, " dma_desc_head = %pad\n", &ring->dma_desc_head);
+ dev_err(pdev, " desc_data_head = %pad\n", &ring->desc_data_head);
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++) {
+ ring = &channel->rx_ring[0];
+ dev_err(pdev, "Rx[%d] descriptor info:\n", i);
+ dev_err(pdev, " cur = 0x%x\n", ring->cur);
+ dev_err(pdev, " dirty = 0x%x\n", ring->dirty);
+ dev_err(pdev, " dma_desc_head = %pad\n", &ring->dma_desc_head);
+ dev_err(pdev, " desc_data_head = %pad\n",
+ &ring->desc_data_head);
+ }
+
+ dev_err(pdev, "Device Registers:\n");
+ dev_err(pdev, "MAC_ISR = %08x\n", fxgmac_io_rd(priv, MAC_ISR));
+ dev_err(pdev, "MAC_IER = %08x\n", fxgmac_io_rd(priv, MAC_IER));
+ dev_err(pdev, "MMC_RISR = %08x\n", fxgmac_io_rd(priv, MMC_RISR));
+ dev_err(pdev, "MMC_RIER = %08x\n", fxgmac_io_rd(priv, MMC_RIER));
+ dev_err(pdev, "MMC_TISR = %08x\n", fxgmac_io_rd(priv, MMC_TISR));
+ dev_err(pdev, "MMC_TIER = %08x\n", fxgmac_io_rd(priv, MMC_TIER));
+
+ dev_err(pdev, "EPHY_CTRL = %04x\n", fxgmac_io_rd(priv, EPHY_CTRL));
+ dev_err(pdev, "MGMT_INT_CTRL0 = %04x\n",
+ fxgmac_io_rd(priv, MGMT_INT_CTRL0));
+ dev_err(pdev, "MSIX_TBL_MASK = %04x\n",
+ fxgmac_io_rd(priv, MSIX_TBL_MASK));
+
+ dev_err(pdev, "Dump nonstick regs:\n");
+ for (u32 i = GLOBAL_CTRL0; i < MSI_PBA; i += 4)
+ dev_err(pdev, "[%d] = %04x\n", i / 4, fxgmac_io_rd(priv, i));
+}
+
+static void fxgmac_tx_timeout(struct net_device *ndev, unsigned int unused)
+{
+ struct fxgmac_pdata *priv = netdev_priv(ndev);
+
+ fxgmac_dump_state(priv);
+ schedule_work(&priv->restart_work);
+}
+
+#define EFUSE_FISRT_UPDATE_ADDR 255
+#define EFUSE_SECOND_UPDATE_ADDR 209
+#define EFUSE_MAX_ENTRY 39
+#define EFUSE_PATCH_ADDR_START 0
+#define EFUSE_PATCH_DATA_START 2
+#define EFUSE_PATCH_SIZE 6
+#define EFUSE_REGION_A_B_LENGTH 18
+
+static bool fxgmac_efuse_read_data(struct fxgmac_pdata *priv, u32 offset,
+ u8 *value)
+{
+ u32 val = 0, wait = 1000;
+ bool ret = false;
+
+ val |= field_prep(EFUSE_OP_ADDR, offset);
+ val |= EFUSE_OP_START;
+ val |= field_prep(EFUSE_OP_MODE, EFUSE_OP_MODE_ROW_READ);
+ fxgmac_io_wr(priv, EFUSE_OP_CTRL_0, val);
+
+ while (wait--) {
+ fsleep(20);
+ val = fxgmac_io_rd(priv, EFUSE_OP_CTRL_1);
+ if (field_get(EFUSE_OP_DONE, val)) {
+ ret = true;
+ break;
+ }
+ }
+
+ if (!ret) {
+ dev_err(priv->dev, "Reading efuse Byte:%d failed\n", offset);
+ return ret;
+ }
+
+ if (value)
+ *value = field_get(EFUSE_OP_RD_DATA, val) & 0xff;
+
+ return ret;
+}
+
+static bool fxgmac_efuse_read_index_patch(struct fxgmac_pdata *priv, u8 index,
+ u32 *offset, u32 *value)
+{
+ u8 tmp[EFUSE_PATCH_SIZE - EFUSE_PATCH_DATA_START];
+ u32 addr, i;
+ bool ret;
+
+ if (index >= EFUSE_MAX_ENTRY) {
+ dev_err(priv->dev, "Reading efuse out of range, index %d\n",
+ index);
+ return false;
+ }
+
+ for (i = EFUSE_PATCH_ADDR_START; i < EFUSE_PATCH_DATA_START; i++) {
+ addr = EFUSE_REGION_A_B_LENGTH + index * EFUSE_PATCH_SIZE + i;
+ ret = fxgmac_efuse_read_data(priv, addr,
+ tmp + i - EFUSE_PATCH_ADDR_START);
+ if (!ret) {
+ dev_err(priv->dev, "Reading efuse Byte:%d failed\n",
+ addr);
+ return ret;
+ }
+ }
+ /* tmp[0] is low 8bit date, tmp[1] is high 8bit date */
+ if (offset)
+ *offset = tmp[0] | (tmp[1] << 8);
+
+ for (i = EFUSE_PATCH_DATA_START; i < EFUSE_PATCH_SIZE; i++) {
+ addr = EFUSE_REGION_A_B_LENGTH + index * EFUSE_PATCH_SIZE + i;
+ ret = fxgmac_efuse_read_data(priv, addr,
+ tmp + i - EFUSE_PATCH_DATA_START);
+ if (!ret) {
+ dev_err(priv->dev, "Reading efuse Byte:%d failed\n",
+ addr);
+ return ret;
+ }
+ }
+ /* tmp[0] is low 8bit date, tmp[1] is low 8bit date
+ * ... tmp[3] is highest 8bit date
+ */
+ if (value)
+ *value = tmp[0] | (tmp[1] << 8) | (tmp[2] << 16) |
+ (tmp[3] << 24);
+
+ return ret;
+}
+
+static bool fxgmac_efuse_read_mac_subsys(struct fxgmac_pdata *priv,
+ u8 *mac_addr, u32 *subsys, u32 *revid)
+{
+ u32 machr = 0, maclr = 0, offset = 0, val = 0;
+
+ for (u8 index = 0; index < EFUSE_MAX_ENTRY; index++) {
+ if (!fxgmac_efuse_read_index_patch(priv, index, &offset, &val))
+ return false;
+
+ if (offset == 0x00)
+ break; /* Reach the blank. */
+ if (offset == MACA0LR_FROM_EFUSE)
+ maclr = val;
+ if (offset == MACA0HR_FROM_EFUSE)
+ machr = val;
+ if (offset == PCI_REVISION_ID && revid)
+ *revid = val;
+ if (offset == PCI_SUBSYSTEM_VENDOR_ID && subsys)
+ *subsys = val;
+ }
+
+ if (mac_addr) {
+ mac_addr[5] = (u8)(maclr & 0xFF);
+ mac_addr[4] = (u8)((maclr >> 8) & 0xFF);
+ mac_addr[3] = (u8)((maclr >> 16) & 0xFF);
+ mac_addr[2] = (u8)((maclr >> 24) & 0xFF);
+ mac_addr[1] = (u8)(machr & 0xFF);
+ mac_addr[0] = (u8)((machr >> 8) & 0xFF);
+ }
+
+ return true;
+}
+
+static int fxgmac_read_mac_addr(struct fxgmac_pdata *priv)
+{
+ u8 default_addr[ETH_ALEN] = { 0, 0x55, 0x7b, 0xb5, 0x7d, 0xf7 };
+ struct net_device *ndev = priv->ndev;
+ int ret;
+
+ /* If efuse have mac addr, use it. if not, use static mac address. */
+ ret = fxgmac_efuse_read_mac_subsys(priv, priv->mac_addr, NULL, NULL);
+ if (!ret)
+ return -1;
+
+ if (is_zero_ether_addr(priv->mac_addr))
+ /* Use a static mac address for test */
+ memcpy(priv->mac_addr, default_addr, ndev->addr_len);
+
+ return 0;
+}
+
+static void fxgmac_default_config(struct fxgmac_pdata *priv)
+{
+ priv->sysclk_rate = 125000000; /* System clock is 125 MHz */
+ priv->tx_threshold = MTL_Q_TQOMR_TTC_THRESHOLD_128;
+ priv->rx_threshold = MTL_Q_RQOMR_RTC_THRESHOLD_128;
+ priv->tx_osp_mode = 1; /* Enable DMA OSP */
+ priv->tx_sf_mode = 1; /* Enable MTL TSF */
+ priv->rx_sf_mode = 1; /* Enable MTL RSF */
+ priv->pblx8 = 1; /* Enable DMA PBL X8 */
+ priv->tx_pause = 1; /* Enable tx pause */
+ priv->rx_pause = 1; /* Enable rx pause */
+ priv->tx_pbl = DMA_CH_PBL_16;
+ priv->rx_pbl = DMA_CH_PBL_4;
+
+ fxgmac_default_speed_duplex_config(priv);
+}
+
+static void fxgmac_get_all_hw_features(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_hw_features *hw_feat = &priv->hw_feat;
+ unsigned int mac_hfr0, mac_hfr1, mac_hfr2, mac_hfr3;
+
+ mac_hfr0 = fxgmac_io_rd(priv, MAC_HWF0R);
+ mac_hfr1 = fxgmac_io_rd(priv, MAC_HWF1R);
+ mac_hfr2 = fxgmac_io_rd(priv, MAC_HWF2R);
+ mac_hfr3 = fxgmac_io_rd(priv, MAC_HWF3R);
+ memset(hw_feat, 0, sizeof(*hw_feat));
+ hw_feat->version = fxgmac_io_rd(priv, MAC_VR);
+
+ /* Hardware feature register 0 */
+ hw_feat->phyifsel = field_get(MAC_HWF0R_ACTPHYIFSEL, mac_hfr0);
+ hw_feat->vlhash = field_get(MAC_HWF0R_VLHASH, mac_hfr0);
+ hw_feat->sma = field_get(MAC_HWF0R_SMASEL, mac_hfr0);
+ hw_feat->rwk = field_get(MAC_HWF0R_RWKSEL, mac_hfr0);
+ hw_feat->mgk = field_get(MAC_HWF0R_MGKSEL, mac_hfr0);
+ hw_feat->mmc = field_get(MAC_HWF0R_MMCSEL, mac_hfr0);
+ hw_feat->aoe = field_get(MAC_HWF0R_ARPOFFSEL, mac_hfr0);
+ hw_feat->ts = field_get(MAC_HWF0R_TSSEL, mac_hfr0);
+ hw_feat->eee = field_get(MAC_HWF0R_EEESEL, mac_hfr0);
+ hw_feat->tx_coe = field_get(MAC_HWF0R_TXCOESEL, mac_hfr0);
+ hw_feat->rx_coe = field_get(MAC_HWF0R_RXCOESEL, mac_hfr0);
+ hw_feat->addn_mac = field_get(MAC_HWF0R_ADDMACADRSEL, mac_hfr0);
+ hw_feat->ts_src = field_get(MAC_HWF0R_TSSTSSEL, mac_hfr0);
+ hw_feat->sa_vlan_ins = field_get(MAC_HWF0R_SAVLANINS, mac_hfr0);
+
+ /* Hardware feature register 1 */
+ hw_feat->rx_fifo_size = field_get(MAC_HWF1R_RXFIFOSIZE, mac_hfr1);
+ hw_feat->tx_fifo_size = field_get(MAC_HWF1R_TXFIFOSIZE, mac_hfr1);
+ hw_feat->adv_ts_hi = field_get(MAC_HWF1R_ADVTHWORD, mac_hfr1);
+ hw_feat->dma_width = field_get(MAC_HWF1R_ADDR64, mac_hfr1);
+ hw_feat->dcb = field_get(MAC_HWF1R_DCBEN, mac_hfr1);
+ hw_feat->sph = field_get(MAC_HWF1R_SPHEN, mac_hfr1);
+ hw_feat->tso = field_get(MAC_HWF1R_TSOEN, mac_hfr1);
+ hw_feat->dma_debug = field_get(MAC_HWF1R_DBGMEMA, mac_hfr1);
+ hw_feat->avsel = field_get(MAC_HWF1R_AVSEL, mac_hfr1);
+ hw_feat->ravsel = field_get(MAC_HWF1R_RAVSEL, mac_hfr1);
+ hw_feat->hash_table_size = field_get(MAC_HWF1R_HASHTBLSZ, mac_hfr1);
+ hw_feat->l3l4_filter_num = field_get(MAC_HWF1R_L3L4FNUM, mac_hfr1);
+ hw_feat->tx_q_cnt = field_get(MAC_HWF2R_TXQCNT, mac_hfr1);
+ hw_feat->rx_ch_cnt = field_get(MAC_HWF2R_RXCHCNT, mac_hfr1);
+ hw_feat->tx_ch_cnt = field_get(MAC_HWF2R_TXCHCNT, mac_hfr1);
+ hw_feat->pps_out_num = field_get(MAC_HWF2R_PPSOUTNUM, mac_hfr1);
+ hw_feat->aux_snap_num = field_get(MAC_HWF2R_AUXSNAPNUM, mac_hfr1);
+
+ /* Translate the Hash Table size into actual number */
+ switch (hw_feat->hash_table_size) {
+ case 0:
+ break;
+ case 1:
+ hw_feat->hash_table_size = 64;
+ break;
+ case 2:
+ hw_feat->hash_table_size = 128;
+ break;
+ case 3:
+ hw_feat->hash_table_size = 256;
+ break;
+ }
+
+ /* Translate the address width setting into actual number */
+ switch (hw_feat->dma_width) {
+ case 0:
+ hw_feat->dma_width = 32;
+ break;
+ case 1:
+ hw_feat->dma_width = 40;
+ break;
+ case 2:
+ hw_feat->dma_width = 48;
+ break;
+ default:
+ hw_feat->dma_width = 32;
+ }
+
+ /* The Queue, Channel are zero based so increment them
+ * to get the actual number
+ */
+ hw_feat->tx_q_cnt++;
+ hw_feat->rx_ch_cnt++;
+ hw_feat->tx_ch_cnt++;
+
+ /* HW implement 1 rx fifo, 4 dma channel. but from software
+ * we see 4 logical queues. hardcode to 4 queues.
+ */
+ hw_feat->rx_q_cnt = 4;
+ hw_feat->hwfr3 = mac_hfr3;
+}
+
+static unsigned int fxgmac_usec_to_riwt(struct fxgmac_pdata *priv,
+ unsigned int usec)
+{
+ /* Convert the input usec value to the watchdog timer value. Each
+ * watchdog timer value is equivalent to 256 clock cycles.
+ * Calculate the required value as:
+ * ( usec * ( system_clock_mhz / 10^6) / 256
+ */
+ return (usec * (priv->sysclk_rate / 1000000)) / 256;
+}
+
+static void fxgmac_save_nonstick_reg(struct fxgmac_pdata *priv)
+{
+ for (u32 i = GLOBAL_CTRL0; i < MSI_PBA; i += 4) {
+ priv->reg_nonstick[(i - GLOBAL_CTRL0) >> 2] =
+ fxgmac_io_rd(priv, i);
+ }
+}
+
+static int fxgmac_init(struct fxgmac_pdata *priv, bool save_private_reg)
+{
+ struct net_device *ndev = priv->ndev;
+ int ret;
+
+ fxgmac_default_config(priv); /* Set default configuration data */
+ ndev->irq = priv->dev_irq;
+ ndev->base_addr = (unsigned long)priv->hw_addr;
+
+ ret = fxgmac_read_mac_addr(priv);
+ if (ret) {
+ dev_err(priv->dev, "Read mac addr failed:%d\n", ret);
+ return ret;
+ }
+ eth_hw_addr_set(ndev, priv->mac_addr);
+
+ if (save_private_reg)
+ fxgmac_save_nonstick_reg(priv);
+
+ fxgmac_hw_exit(priv); /* Reset here to get hw features correctly */
+ fxgmac_get_all_hw_features(priv);
+
+ /* Set the DMA mask */
+ ret = dma_set_mask_and_coherent(priv->dev,
+ DMA_BIT_MASK(priv->hw_feat.dma_width));
+ if (ret) {
+ ret = dma_set_mask_and_coherent(priv->dev, DMA_BIT_MASK(32));
+ if (ret) {
+ dev_err(priv->dev, "No usable DMA configuration, aborting\n");
+ return ret;
+ }
+ }
+
+ if (field_get(INT_FLAG_LEGACY, priv->int_flag)) {
+ /* We should disable msi and msix here when we use legacy
+ * interrupt,for two reasons:
+ * 1. Exit will restore msi and msix config regisiter,
+ * that may enable them.
+ * 2. When the driver that uses the msix interrupt by default
+ * is compiled into the OS, uninstall the driver through rmmod,
+ * and then install the driver that uses the legacy interrupt,
+ * at which time the msix enable will be turned on again by
+ * default after waking up from S4 on some
+ * platform. such as UOS platform.
+ */
+ pci_disable_msi(to_pci_dev(priv->dev));
+ pci_disable_msix(to_pci_dev(priv->dev));
+ }
+
+ BUILD_BUG_ON_NOT_POWER_OF_2(FXGMAC_TX_DESC_CNT);
+ priv->tx_desc_count = FXGMAC_TX_DESC_CNT;
+ BUILD_BUG_ON_NOT_POWER_OF_2(FXGMAC_RX_DESC_CNT);
+ priv->rx_desc_count = FXGMAC_RX_DESC_CNT;
+
+ ret = netif_set_real_num_tx_queues(ndev, FXGMAC_TX_1_Q);
+ if (ret) {
+ dev_err(priv->dev, "Setting real tx queue count failed\n");
+ return ret;
+ }
+
+ priv->rx_ring_count = min_t(unsigned int,
+ netif_get_num_default_rss_queues(),
+ priv->hw_feat.rx_ch_cnt);
+ priv->rx_ring_count = min_t(unsigned int, priv->rx_ring_count,
+ priv->hw_feat.rx_q_cnt);
+ priv->rx_q_count = priv->rx_ring_count;
+ ret = netif_set_real_num_rx_queues(ndev, priv->rx_q_count);
+ if (ret) {
+ dev_err(priv->dev, "Setting real rx queue count failed\n");
+ return ret;
+ }
+
+ priv->channel_count =
+ max_t(unsigned int, FXGMAC_TX_1_RING, priv->rx_ring_count);
+
+ ndev->min_mtu = ETH_MIN_MTU;
+ ndev->max_mtu =
+ FXGMAC_JUMBO_PACKET_MTU + (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN);
+
+ ndev->netdev_ops = fxgmac_get_netdev_ops();/* Set device operations */
+
+ /* Set device features */
+ if (priv->hw_feat.tso) {
+ ndev->hw_features = NETIF_F_TSO;
+ ndev->hw_features |= NETIF_F_TSO6;
+ ndev->hw_features |= NETIF_F_SG;
+ ndev->hw_features |= NETIF_F_IP_CSUM;
+ ndev->hw_features |= NETIF_F_IPV6_CSUM;
+ } else if (priv->hw_feat.tx_coe) {
+ ndev->hw_features = NETIF_F_IP_CSUM;
+ ndev->hw_features |= NETIF_F_IPV6_CSUM;
+ }
+
+ if (priv->hw_feat.rx_coe) {
+ ndev->hw_features |= NETIF_F_RXCSUM;
+ ndev->hw_features |= NETIF_F_GRO;
+ }
+
+ ndev->hw_features |= NETIF_F_RXHASH;
+ ndev->vlan_features |= ndev->hw_features;
+ ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
+
+ if (priv->hw_feat.sa_vlan_ins)
+ ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX;
+
+ ndev->features |= ndev->hw_features;
+
+ ndev->priv_flags |= IFF_UNICAST_FLT;
+ ndev->watchdog_timeo = msecs_to_jiffies(5000);
+
+#define NIC_MAX_TCP_OFFLOAD_SIZE 7300
+ netif_set_tso_max_size(ndev, NIC_MAX_TCP_OFFLOAD_SIZE);
+
+/* Default coalescing parameters */
+#define FXGMAC_INIT_DMA_TX_USECS INT_MOD_200_US
+#define FXGMAC_INIT_DMA_TX_FRAMES 25
+#define FXGMAC_INIT_DMA_RX_USECS INT_MOD_200_US
+#define FXGMAC_INIT_DMA_RX_FRAMES 25
+
+ /* Tx coalesce parameters initialization */
+ priv->tx_usecs = FXGMAC_INIT_DMA_TX_USECS;
+ priv->tx_frames = FXGMAC_INIT_DMA_TX_FRAMES;
+
+ /* Rx coalesce parameters initialization */
+ priv->rx_riwt = fxgmac_usec_to_riwt(priv, FXGMAC_INIT_DMA_RX_USECS);
+ priv->rx_usecs = FXGMAC_INIT_DMA_RX_USECS;
+ priv->rx_frames = FXGMAC_INIT_DMA_RX_FRAMES;
+
+ return 0;
+}
+
+static void fxgmac_init_interrupt_scheme(struct fxgmac_pdata *priv)
+{
+ struct pci_dev *pdev = to_pci_dev(priv->dev);
+ int req_vectors = FXGMAC_MAX_DMA_CHANNELS;
+
+ /* Since we have FXGMAC_MAX_DMA_CHANNELS channels, we must ensure the
+ * number of cpu core is ok. otherwise, just roll back to legacy.
+ */
+ if (num_online_cpus() < FXGMAC_MAX_DMA_CHANNELS - 1)
+ goto enable_msi_interrupt;
+
+ priv->msix_entries =
+ kcalloc(req_vectors, sizeof(struct msix_entry), GFP_KERNEL);
+ if (!priv->msix_entries)
+ goto enable_msi_interrupt;
+
+ for (u32 i = 0; i < req_vectors; i++)
+ priv->msix_entries[i].entry = i;
+
+ if (pci_enable_msix_exact(pdev, priv->msix_entries, req_vectors) < 0) {
+ /* Roll back to msi */
+ kfree(priv->msix_entries);
+ priv->msix_entries = NULL;
+ dev_err(priv->dev, "Enable MSIx failed, clear msix entries.\n");
+ goto enable_msi_interrupt;
+ }
+
+ priv->int_flag &= ~INT_FLAG_INTERRUPT;
+ priv->int_flag |= INT_FLAG_MSIX;
+ priv->per_channel_irq = 1;
+ return;
+
+enable_msi_interrupt:
+ priv->int_flag &= ~INT_FLAG_INTERRUPT;
+ if (pci_enable_msi(pdev) < 0) {
+ priv->int_flag |= INT_FLAG_LEGACY;
+ dev_err(priv->dev, "rollback to LEGACY.\n");
+ } else {
+ priv->int_flag |= INT_FLAG_MSI;
+ dev_err(priv->dev, "rollback to MSI.\n");
+ priv->dev_irq = pdev->irq;
+ }
+}
+
+static int fxgmac_drv_probe(struct device *dev, struct fxgmac_resources *res)
+{
+ struct fxgmac_pdata *priv;
+ struct net_device *ndev;
+ int ret;
+
+ ndev = alloc_etherdev_mq(sizeof(struct fxgmac_pdata),
+ FXGMAC_MAX_DMA_RX_CHANNELS);
+ if (!ndev)
+ return -ENOMEM;
+
+ SET_NETDEV_DEV(ndev, dev);
+ priv = netdev_priv(ndev);
+
+ priv->dev = dev;
+ priv->ndev = ndev;
+ priv->dev_irq = res->irq;
+ priv->hw_addr = res->addr;
+ priv->msg_enable = NETIF_MSG_DRV;
+ priv->dev_state = FXGMAC_DEV_PROBE;
+
+ /* Default to legacy interrupt */
+ priv->int_flag &= ~INT_FLAG_INTERRUPT;
+ priv->int_flag |= INT_FLAG_LEGACY;
+
+ pci_set_drvdata(to_pci_dev(priv->dev), priv);
+
+ if (IS_ENABLED(CONFIG_PCI_MSI))
+ fxgmac_init_interrupt_scheme(priv);
+
+ ret = fxgmac_init(priv, true);
+ if (ret < 0) {
+ dev_err(dev, "fxgmac init failed:%d\n", ret);
+ goto err_free_netdev;
+ }
+
+ fxgmac_phy_reset(priv);
+ fxgmac_phy_release(priv);
+ ret = fxgmac_mdio_register(priv);
+ if (ret < 0) {
+ dev_err(dev, "Register fxgmac mdio failed:%d\n", ret);
+ goto err_free_netdev;
+ }
+
+ netif_carrier_off(ndev);
+ ret = register_netdev(ndev);
+ if (ret) {
+ dev_err(dev, "Register ndev failed:%d\n", ret);
+ goto err_free_netdev;
+ }
+
+ return 0;
+
+err_free_netdev:
+ free_netdev(ndev);
+ return ret;
+}
+
+static void fxgmac_dbg_pkt(struct fxgmac_pdata *priv, struct sk_buff *skb,
+ bool tx_rx)
+{
+ struct ethhdr *eth = (struct ethhdr *)skb->data;
+ unsigned char buffer[128];
+
+ dev_dbg(priv->dev, "\n************** SKB dump ****************\n");
+ dev_dbg(priv->dev, "%s, packet of %d bytes\n", (tx_rx ? "TX" : "RX"),
+ skb->len);
+ dev_dbg(priv->dev, "Dst MAC addr: %pM\n", eth->h_dest);
+ dev_dbg(priv->dev, "Src MAC addr: %pM\n", eth->h_source);
+ dev_dbg(priv->dev, "Protocol: %#06x\n", ntohs(eth->h_proto));
+
+ for (u32 i = 0; i < skb->len; i += 32) {
+ unsigned int len = min(skb->len - i, 32U);
+
+ hex_dump_to_buffer(&skb->data[i], len, 32, 1, buffer,
+ sizeof(buffer), false);
+ dev_dbg(priv->dev, " %#06x: %s\n", i, buffer);
+ }
+
+ dev_dbg(priv->dev, "\n************** SKB dump ****************\n");
+}
+
+static void fxgmac_dev_xmit(struct fxgmac_channel *channel)
+{
+ struct fxgmac_pdata *priv = channel->priv;
+ struct fxgmac_ring *ring = channel->tx_ring;
+ unsigned int tso_context, vlan_context;
+ struct fxgmac_desc_data *desc_data;
+ struct fxgmac_dma_desc *dma_desc;
+ struct fxgmac_pkt_info *pkt_info;
+ unsigned int csum, tso, vlan;
+ int i, start_index = ring->cur;
+ int cur_index = ring->cur;
+
+ pkt_info = &ring->pkt_info;
+ csum = field_get(ATTR_TX_CSUM_ENABLE, pkt_info->attr);
+ tso = field_get(ATTR_TX_TSO_ENABLE, pkt_info->attr);
+ vlan = field_get(ATTR_TX_VLAN_CTAG, pkt_info->attr);
+
+ if (tso && pkt_info->mss != ring->tx.cur_mss)
+ tso_context = 1;
+ else
+ tso_context = 0;
+
+ if (vlan && pkt_info->vlan_ctag != ring->tx.cur_vlan_ctag)
+ vlan_context = 1;
+ else
+ vlan_context = 0;
+
+ desc_data = FXGMAC_GET_DESC_DATA(ring, cur_index);
+ dma_desc = desc_data->dma_desc;
+
+ /* Create a context descriptor if this is a TSO pkt_info */
+ if (tso_context) {
+ /* Set the MSS size */
+ fxgmac_desc_wr_bits(&dma_desc->desc2, TX_CONTEXT_DESC2_MSS,
+ pkt_info->mss);
+
+ /* Mark it as a CONTEXT descriptor */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_CONTEXT_DESC3_CTXT, 1);
+
+ /* Indicate this descriptor contains the MSS */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_CONTEXT_DESC3_TCMSSV,
+ 1);
+
+ ring->tx.cur_mss = pkt_info->mss;
+ }
+
+ if (vlan_context) {
+ /* Mark it as a CONTEXT descriptor */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_CONTEXT_DESC3_CTXT, 1);
+
+ /* Set the VLAN tag */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_CONTEXT_DESC3_VT,
+ pkt_info->vlan_ctag);
+
+ /* Indicate this descriptor contains the VLAN tag */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_CONTEXT_DESC3_VLTV, 1);
+
+ ring->tx.cur_vlan_ctag = pkt_info->vlan_ctag;
+ }
+ if (tso_context || vlan_context) {
+ cur_index = FXGMAC_GET_ENTRY(cur_index, ring->dma_desc_count);
+ desc_data = FXGMAC_GET_DESC_DATA(ring, cur_index);
+ dma_desc = desc_data->dma_desc;
+ }
+
+ /* Update buffer address (for TSO this is the header) */
+ dma_desc->desc0 = cpu_to_le32(lower_32_bits(desc_data->skb_dma));
+ dma_desc->desc1 = cpu_to_le32(upper_32_bits(desc_data->skb_dma));
+
+ /* Update the buffer length */
+ fxgmac_desc_wr_bits(&dma_desc->desc2, TX_DESC2_HL_B1L,
+ desc_data->skb_dma_len);
+
+ /* VLAN tag insertion check */
+ if (vlan)
+ fxgmac_desc_wr_bits(&dma_desc->desc2, TX_DESC2_VTIR, 2);
+
+ /* Timestamp enablement check */
+ if (field_get(ATTR_TX_PTP, pkt_info->attr))
+ fxgmac_desc_wr_bits(&dma_desc->desc2, TX_DESC2_TTSE, 1);
+
+ /* Mark it as First Descriptor */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_FD, 1);
+
+ /* Mark it as a NORMAL descriptor */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_CTXT, 0);
+
+ /* Set OWN bit if not the first descriptor */
+ if (cur_index != start_index)
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_OWN, 1);
+
+ if (tso) {
+ /* Enable TSO */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_TSE, 1);
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_TCPPL,
+ pkt_info->tcp_payload_len);
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_TCPHDRLEN,
+ pkt_info->tcp_header_len / 4);
+ } else {
+ /* Enable CRC and Pad Insertion */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_CPC, 0);
+
+ /* Enable HW CSUM */
+ if (csum)
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_CIC,
+ 0x3);
+
+ /* Set the total length to be transmitted */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_FL,
+ pkt_info->length);
+ }
+
+ if (start_index <= cur_index)
+ i = cur_index - start_index + 1;
+ else
+ i = ring->dma_desc_count - start_index + cur_index;
+
+ for (; i < pkt_info->desc_count; i++) {
+ cur_index = FXGMAC_GET_ENTRY(cur_index, ring->dma_desc_count);
+ desc_data = FXGMAC_GET_DESC_DATA(ring, cur_index);
+ dma_desc = desc_data->dma_desc;
+
+ /* Update buffer address */
+ dma_desc->desc0 =
+ cpu_to_le32(lower_32_bits(desc_data->skb_dma));
+ dma_desc->desc1 =
+ cpu_to_le32(upper_32_bits(desc_data->skb_dma));
+
+ /* Update the buffer length */
+ fxgmac_desc_wr_bits(&dma_desc->desc2, TX_DESC2_HL_B1L,
+ desc_data->skb_dma_len);
+
+ /* Set OWN bit */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_OWN, 1);
+
+ /* Mark it as NORMAL descriptor */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_CTXT, 0);
+
+ /* Enable HW CSUM */
+ if (csum)
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_CIC,
+ 0x3);
+ }
+
+ /* Set LAST bit for the last descriptor */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_LD, 1);
+
+ fxgmac_desc_wr_bits(&dma_desc->desc2, TX_DESC2_IC, 1);
+
+ /* Save the Tx info to report back during cleanup */
+ desc_data->tx.packets = pkt_info->tx_packets;
+ desc_data->tx.bytes = pkt_info->tx_bytes;
+
+ /* In case the Tx DMA engine is running, make sure everything
+ * is written to the descriptor(s) before setting the OWN bit
+ * for the first descriptor
+ */
+ dma_wmb();
+
+ /* Set OWN bit for the first descriptor */
+ desc_data = FXGMAC_GET_DESC_DATA(ring, start_index);
+ dma_desc = desc_data->dma_desc;
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_OWN, 1);
+
+ if (netif_msg_tx_queued(priv))
+ fxgmac_dump_tx_desc(priv, ring, start_index,
+ pkt_info->desc_count, 1);
+
+ smp_wmb(); /* Make sure ownership is written to the descriptor */
+
+ ring->cur = FXGMAC_GET_ENTRY(cur_index, ring->dma_desc_count);
+ fxgmac_tx_start_xmit(channel, ring);
+}
+
+static void fxgmac_prep_vlan(struct sk_buff *skb,
+ struct fxgmac_pkt_info *pkt_info)
+{
+ if (skb_vlan_tag_present(skb))
+ pkt_info->vlan_ctag = skb_vlan_tag_get(skb);
+}
+
+static int fxgmac_prep_tso(struct fxgmac_pdata *priv, struct sk_buff *skb,
+ struct fxgmac_pkt_info *pkt_info)
+{
+ int ret;
+
+ if (!field_get(ATTR_TX_TSO_ENABLE, pkt_info->attr))
+ return 0;
+
+ ret = skb_cow_head(skb, 0);
+ if (ret)
+ return ret;
+
+ pkt_info->header_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ pkt_info->tcp_header_len = tcp_hdrlen(skb);
+ pkt_info->tcp_payload_len = skb->len - pkt_info->header_len;
+ pkt_info->mss = skb_shinfo(skb)->gso_size;
+
+ /* Update the number of packets that will ultimately be transmitted
+ * along with the extra bytes for each extra packet
+ */
+ pkt_info->tx_packets = skb_shinfo(skb)->gso_segs;
+ pkt_info->tx_bytes += (pkt_info->tx_packets - 1) * pkt_info->header_len;
+
+ return 0;
+}
+
+static int fxgmac_is_tso(struct sk_buff *skb)
+{
+ if (skb->ip_summed != CHECKSUM_PARTIAL)
+ return 0;
+
+ if (!skb_is_gso(skb))
+ return 0;
+
+ return 1;
+}
+
+static void fxgmac_prep_tx_pkt(struct fxgmac_pdata *priv,
+ struct fxgmac_ring *ring, struct sk_buff *skb,
+ struct fxgmac_pkt_info *pkt_info)
+{
+ u32 len, context_desc = 0;
+
+ pkt_info->skb = skb;
+ pkt_info->desc_count = 0;
+ pkt_info->tx_packets = 1;
+ pkt_info->tx_bytes = skb->len;
+
+ if (fxgmac_is_tso(skb)) {
+ /* TSO requires an extra descriptor if mss is different */
+ if (skb_shinfo(skb)->gso_size != ring->tx.cur_mss) {
+ context_desc = 1;
+ pkt_info->desc_count++;
+ }
+
+ /* TSO requires an extra descriptor for TSO header */
+ pkt_info->desc_count++;
+ pkt_info->attr |= (ATTR_TX_TSO_ENABLE | ATTR_TX_CSUM_ENABLE);
+ } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ pkt_info->attr |= ATTR_TX_CSUM_ENABLE;
+ }
+
+ if (skb_vlan_tag_present(skb)) {
+ /* VLAN requires an extra descriptor if tag is different */
+ if (skb_vlan_tag_get(skb) != ring->tx.cur_vlan_ctag)
+ /* We can share with the TSO context descriptor */
+ if (!context_desc)
+ pkt_info->desc_count++;
+
+ pkt_info->attr |= ATTR_TX_VLAN_CTAG;
+ }
+
+ for (len = skb_headlen(skb); len;) {
+ pkt_info->desc_count++;
+ len -= min_t(unsigned int, len, FXGMAC_TX_MAX_BUF_SIZE);
+ }
+
+ for (u32 i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+ for (len = skb_frag_size(&skb_shinfo(skb)->frags[i]); len;) {
+ pkt_info->desc_count++;
+ len -= min_t(unsigned int, len, FXGMAC_TX_MAX_BUF_SIZE);
+ }
+}
+
+static netdev_tx_t fxgmac_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ struct fxgmac_pdata *priv = netdev_priv(ndev);
+ struct fxgmac_pkt_info *tx_pkt_info;
+ struct fxgmac_channel *channel;
+ struct netdev_queue *txq;
+ struct fxgmac_ring *ring;
+ int ret;
+
+ channel = priv->channel_head + skb->queue_mapping;
+ txq = netdev_get_tx_queue(ndev, channel->queue_index);
+ ring = channel->tx_ring;
+ tx_pkt_info = &ring->pkt_info;
+
+ if (skb->len == 0) {
+ netdev_err(priv->ndev, "empty skb received from stack\n");
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+ /* Prepare preliminary packet info for TX */
+ memset(tx_pkt_info, 0, sizeof(*tx_pkt_info));
+ fxgmac_prep_tx_pkt(priv, ring, skb, tx_pkt_info);
+
+ /* Check that there are enough descriptors available */
+ ret = fxgmac_maybe_stop_tx_queue(channel, ring,
+ tx_pkt_info->desc_count);
+ if (ret == NETDEV_TX_BUSY)
+ return ret;
+
+ ret = fxgmac_prep_tso(priv, skb, tx_pkt_info);
+ if (ret < 0) {
+ netdev_err(priv->ndev, "processing TSO packet failed\n");
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+ fxgmac_prep_vlan(skb, tx_pkt_info);
+
+ if (!fxgmac_tx_skb_map(channel, skb)) {
+ dev_kfree_skb_any(skb);
+ netdev_err(priv->ndev, "xmit, map tx skb failed\n");
+ return NETDEV_TX_OK;
+ }
+
+ /* Report on the actual number of bytes (to be) sent */
+ netdev_tx_sent_queue(txq, tx_pkt_info->tx_bytes);
+
+ /* Configure required descriptor fields for transmission */
+ fxgmac_dev_xmit(channel);
+
+ if (netif_msg_pktdata(priv))
+ fxgmac_dbg_pkt(priv, skb, true);
+
+ /* Stop the queue in advance if there may not be enough descriptors */
+ fxgmac_maybe_stop_tx_queue(channel, ring, FXGMAC_TX_MAX_DESC_NR);
+
+ return NETDEV_TX_OK;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void fxgmac_poll_controller(struct net_device *ndev)
+{
+ struct fxgmac_pdata *priv = netdev_priv(ndev);
+ struct fxgmac_channel *channel;
+
+ if (priv->per_channel_irq) {
+ channel = priv->channel_head;
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ fxgmac_dma_isr(channel->dma_irq_rx, channel);
+ } else {
+ disable_irq(priv->dev_irq);
+ fxgmac_isr(priv->dev_irq, priv);
+ enable_irq(priv->dev_irq);
+ }
+}
+#endif /* CONFIG_NET_POLL_CONTROLLER */
+
+static const struct net_device_ops fxgmac_netdev_ops = {
+ .ndo_open = fxgmac_open,
+ .ndo_stop = fxgmac_close,
+ .ndo_start_xmit = fxgmac_xmit,
+ .ndo_tx_timeout = fxgmac_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = fxgmac_poll_controller,
+#endif
+};
+
+const struct net_device_ops *fxgmac_get_netdev_ops(void)
+{
+ return &fxgmac_netdev_ops;
+}
+
+static void fxgmac_rx_refresh(struct fxgmac_channel *channel)
+{
+ struct fxgmac_ring *ring = channel->rx_ring;
+ struct fxgmac_pdata *priv = channel->priv;
+ struct fxgmac_desc_data *desc_data;
+
+ while (ring->dirty != ring->cur) {
+ desc_data = FXGMAC_GET_DESC_DATA(ring, ring->dirty);
+
+ /* Reset desc_data values */
+ fxgmac_desc_data_unmap(priv, desc_data);
+
+ if (fxgmac_rx_buffe_map(priv, ring, desc_data))
+ break;
+
+ fxgmac_desc_rx_reset(desc_data);
+ ring->dirty =
+ FXGMAC_GET_ENTRY(ring->dirty, ring->dma_desc_count);
+ }
+
+ /* Make sure everything is written before the register write */
+ wmb();
+
+ /* Update the Rx Tail Pointer Register with address of
+ * the last cleaned entry
+ */
+ desc_data = FXGMAC_GET_DESC_DATA(ring, (ring->dirty - 1) &
+ (ring->dma_desc_count - 1));
+ fxgmac_dma_io_wr(channel, DMA_CH_RDTR_LO,
+ lower_32_bits(desc_data->dma_desc_addr));
+}
+
+static struct sk_buff *fxgmac_create_skb(struct fxgmac_pdata *priv,
+ struct napi_struct *napi,
+ struct fxgmac_desc_data *desc_data,
+ unsigned int len)
+{
+ unsigned int copy_len;
+ struct sk_buff *skb;
+ u8 *packet;
+
+ skb = napi_alloc_skb(napi, desc_data->rx.hdr.dma_len);
+ if (!skb)
+ return NULL;
+
+ /* Start with the header buffer which may contain just the header
+ * or the header plus data
+ */
+ dma_sync_single_range_for_cpu(priv->dev, desc_data->rx.hdr.dma_base,
+ desc_data->rx.hdr.dma_off,
+ desc_data->rx.hdr.dma_len,
+ DMA_FROM_DEVICE);
+
+ packet = page_address(desc_data->rx.hdr.pa.pages) +
+ desc_data->rx.hdr.pa.pages_offset;
+ copy_len = min(desc_data->rx.hdr.dma_len, len);
+ skb_copy_to_linear_data(skb, packet, copy_len);
+ skb_put(skb, copy_len);
+
+ return skb;
+}
+
+static int fxgmac_tx_poll(struct fxgmac_channel *channel)
+{
+ struct fxgmac_pdata *priv = channel->priv;
+ unsigned int cur, tx_packets = 0, tx_bytes = 0;
+ struct fxgmac_ring *ring = channel->tx_ring;
+ struct net_device *ndev = priv->ndev;
+ struct fxgmac_desc_data *desc_data;
+ struct fxgmac_dma_desc *dma_desc;
+ struct netdev_queue *txq;
+ int processed = 0;
+
+ /* Nothing to do if there isn't a Tx ring for this channel */
+ if (!ring)
+ return 0;
+
+ if (ring->cur != ring->dirty && (netif_msg_tx_done(priv)))
+ netdev_dbg(priv->ndev, "%s, ring_cur=%d,ring_dirty=%d,qIdx=%d\n",
+ __func__, ring->cur, ring->dirty,
+ channel->queue_index);
+
+ cur = ring->cur;
+
+ /* Be sure we get ring->cur before accessing descriptor data */
+ smp_rmb();
+
+ txq = netdev_get_tx_queue(ndev, channel->queue_index);
+ while (ring->dirty != cur) {
+ desc_data = FXGMAC_GET_DESC_DATA(ring, ring->dirty);
+ dma_desc = desc_data->dma_desc;
+
+ if (!fxgmac_is_tx_complete(dma_desc))
+ break;
+
+ /* Make sure descriptor fields are read after reading
+ * the OWN bit
+ */
+ dma_rmb();
+
+ if (netif_msg_tx_done(priv))
+ fxgmac_dump_tx_desc(priv, ring, ring->dirty, 1, 0);
+
+ if (fxgmac_is_last_desc(dma_desc)) {
+ tx_packets += desc_data->tx.packets;
+ tx_bytes += desc_data->tx.bytes;
+ }
+
+ /* Free the SKB and reset the descriptor for re-use */
+ fxgmac_desc_data_unmap(priv, desc_data);
+ fxgmac_desc_tx_reset(desc_data);
+
+ processed++;
+ ring->dirty =
+ FXGMAC_GET_ENTRY(ring->dirty, ring->dma_desc_count);
+ }
+
+ if (!processed)
+ return 0;
+
+ netdev_tx_completed_queue(txq, tx_packets, tx_bytes);
+
+ /* Make sure ownership is written to the descriptor */
+ smp_wmb();
+ if (ring->tx.queue_stopped == 1 &&
+ (fxgmac_desc_tx_avail(ring) > FXGMAC_TX_DESC_MIN_FREE)) {
+ ring->tx.queue_stopped = 0;
+ netif_tx_wake_queue(txq);
+ }
+
+ return processed;
+}
+
+static int fxgmac_one_poll_tx(struct napi_struct *napi, int budget)
+{
+ struct fxgmac_channel *channel =
+ container_of(napi, struct fxgmac_channel, napi_tx);
+ struct fxgmac_pdata *priv = channel->priv;
+ int ret;
+
+ ret = fxgmac_tx_poll(channel);
+ if (napi_complete_done(napi, 0))
+ fxgmac_enable_msix_one_irq(priv, MSI_ID_TXQ0);
+
+ return ret;
+}
+
+static int fxgmac_dev_read(struct fxgmac_channel *channel)
+{
+ struct fxgmac_pdata *priv = channel->priv;
+ struct fxgmac_ring *ring = channel->rx_ring;
+ struct net_device *ndev = priv->ndev;
+ static unsigned int cnt_incomplete;
+ struct fxgmac_desc_data *desc_data;
+ struct fxgmac_dma_desc *dma_desc;
+ struct fxgmac_pkt_info *pkt_info;
+ u32 ipce, iphe, rxparser;
+ unsigned int err, etlt;
+
+ desc_data = FXGMAC_GET_DESC_DATA(ring, ring->cur);
+ dma_desc = desc_data->dma_desc;
+ pkt_info = &ring->pkt_info;
+
+ /* Check for data availability */
+ if (fxgmac_desc_rd_bits(dma_desc->desc3, RX_DESC3_OWN))
+ return 1;
+
+ /* Make sure descriptor fields are read after reading the OWN bit */
+ dma_rmb();
+
+ if (netif_msg_rx_status(priv))
+ fxgmac_dump_rx_desc(priv, ring, ring->cur);
+
+ /* Normal Descriptor, be sure Context Descriptor bit is off */
+ pkt_info->attr &= ~ATTR_RX_CONTEXT;
+
+ /* Indicate if a Context Descriptor is next */
+ /* Get the header length */
+ if (fxgmac_desc_rd_bits(dma_desc->desc3, RX_DESC3_FD)) {
+ desc_data->rx.hdr_len = fxgmac_desc_rd_bits(dma_desc->desc2,
+ RX_DESC2_HL);
+ }
+
+ /* Get the pkt_info length */
+ desc_data->rx.len =
+ fxgmac_desc_rd_bits(dma_desc->desc3, RX_DESC3_PL);
+
+ if (!fxgmac_desc_rd_bits(dma_desc->desc3, RX_DESC3_LD)) {
+ /* Not all the data has been transferred for this pkt_info */
+ pkt_info->attr |= ATTR_RX_INCOMPLETE;
+ cnt_incomplete++;
+ return 0;
+ }
+
+ if ((cnt_incomplete) && netif_msg_rx_status(priv))
+ netdev_dbg(priv->ndev, "%s, rx back to normal and incomplete cnt=%u\n",
+ __func__, cnt_incomplete);
+ cnt_incomplete = 0;
+
+ /* This is the last of the data for this pkt_info */
+ pkt_info->attr &= ~ATTR_RX_INCOMPLETE;
+
+ /* Set checksum done indicator as appropriate */
+ if (ndev->features & NETIF_F_RXCSUM) {
+ ipce = fxgmac_desc_rd_bits(dma_desc->desc1, RX_DESC1_WB_IPCE);
+ iphe = fxgmac_desc_rd_bits(dma_desc->desc1, RX_DESC1_WB_IPHE);
+ if (!ipce && !iphe)
+ pkt_info->attr |= ATTR_RX_CSUM_DONE;
+ else
+ return 0;
+ }
+
+ /* Check for errors (only valid in last descriptor) */
+ err = fxgmac_desc_rd_bits(dma_desc->desc3, RX_DESC3_ES);
+ rxparser = fxgmac_desc_rd_bits(dma_desc->desc2, RX_DESC2_WB_RAPARSER);
+ /* Error or incomplete parsing due to ECC error */
+ if (err || rxparser == 0x7) {
+ pkt_info->errors |= ERRORS_RX_FRAME;
+ return 0;
+ }
+
+ etlt = fxgmac_desc_rd_bits(dma_desc->desc3, RX_DESC3_ETLT);
+ if (etlt == 0x4 && (ndev->features & NETIF_F_HW_VLAN_CTAG_RX)) {
+ pkt_info->attr |= ATTR_RX_VLAN_CTAG;
+ pkt_info->vlan_ctag = fxgmac_desc_rd_bits(dma_desc->desc0,
+ RX_DESC0_OVT);
+ }
+
+ return 0;
+}
+
+static unsigned int fxgmac_desc_rx_dirty(struct fxgmac_ring *ring)
+{
+ unsigned int dirty;
+
+ if (ring->dirty <= ring->cur)
+ dirty = ring->cur - ring->dirty;
+ else
+ dirty = ring->dma_desc_count - ring->dirty + ring->cur;
+
+ return dirty;
+}
+
+static int fxgmac_rx_poll(struct fxgmac_channel *channel, int budget)
+{
+ struct fxgmac_pdata *priv = channel->priv;
+ struct fxgmac_ring *ring = channel->rx_ring;
+ struct net_device *ndev = priv->ndev;
+ u32 context_next, context, incomplete;
+ struct fxgmac_desc_data *desc_data;
+ struct fxgmac_pkt_info *pkt_info;
+ struct napi_struct *napi;
+ u32 len, max_len;
+ int packet_count = 0;
+
+ struct sk_buff *skb;
+
+ /* Nothing to do if there isn't a Rx ring for this channel */
+ if (!ring)
+ return 0;
+
+ napi = (priv->per_channel_irq) ? &channel->napi_rx : &priv->napi;
+ pkt_info = &ring->pkt_info;
+
+ while (packet_count < budget) {
+ memset(pkt_info, 0, sizeof(*pkt_info));
+ skb = NULL;
+ len = 0;
+
+read_again:
+ desc_data = FXGMAC_GET_DESC_DATA(ring, ring->cur);
+
+ if (fxgmac_desc_rx_dirty(ring) > FXGMAC_RX_DESC_MAX_DIRTY)
+ fxgmac_rx_refresh(channel);
+
+ if (fxgmac_dev_read(channel))
+ break;
+
+ ring->cur = FXGMAC_GET_ENTRY(ring->cur, ring->dma_desc_count);
+ incomplete = field_get(ATTR_RX_INCOMPLETE, pkt_info->attr);
+ context_next = field_get(ATTR_RX_CONTEXT_NEXT, pkt_info->attr);
+ context = field_get(ATTR_RX_CONTEXT, pkt_info->attr);
+
+ if (incomplete || context_next)
+ goto read_again;
+
+ if (pkt_info->errors) {
+ dev_kfree_skb(skb);
+ priv->ndev->stats.rx_dropped++;
+ netdev_err(priv->ndev, "Received packet failed\n");
+ goto next_packet;
+ }
+
+ if (!context) {
+ len = desc_data->rx.len;
+ if (len == 0) {
+ if (net_ratelimit())
+ netdev_err(priv->ndev, "A packet of length 0 was received\n");
+ priv->ndev->stats.rx_length_errors++;
+ priv->ndev->stats.rx_dropped++;
+ goto next_packet;
+ }
+
+ if (len && !skb) {
+ skb = fxgmac_create_skb(priv, napi, desc_data,
+ len);
+ if (unlikely(!skb)) {
+ if (net_ratelimit())
+ netdev_err(priv->ndev, "create skb failed\n");
+ priv->ndev->stats.rx_dropped++;
+ goto next_packet;
+ }
+ }
+ max_len = ndev->mtu + ETH_HLEN;
+ if (!(ndev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
+ skb->protocol == htons(ETH_P_8021Q))
+ max_len += VLAN_HLEN;
+
+ if (len > max_len) {
+ if (net_ratelimit())
+ netdev_err(priv->ndev, "len %d larger than max size %d\n",
+ len, max_len);
+ priv->ndev->stats.rx_length_errors++;
+ priv->ndev->stats.rx_dropped++;
+ dev_kfree_skb(skb);
+ goto next_packet;
+ }
+ }
+
+ if (!skb) {
+ priv->ndev->stats.rx_dropped++;
+ goto next_packet;
+ }
+
+ if (netif_msg_pktdata(priv))
+ fxgmac_dbg_pkt(priv, skb, false);
+
+ skb_checksum_none_assert(skb);
+ if (ndev->features & NETIF_F_RXCSUM)
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ if (field_get(ATTR_RX_VLAN_CTAG, pkt_info->attr))
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+ pkt_info->vlan_ctag);
+
+ if (field_get(ATTR_RX_RSS_HASH, pkt_info->attr))
+ skb_set_hash(skb, pkt_info->rss_hash,
+ pkt_info->rss_hash_type);
+
+ skb->dev = ndev;
+ skb->protocol = eth_type_trans(skb, ndev);
+ skb_record_rx_queue(skb, channel->queue_index);
+ napi_gro_receive(napi, skb);
+
+next_packet:
+ packet_count++;
+ priv->ndev->stats.rx_packets++;
+ priv->ndev->stats.rx_bytes += len;
+ }
+
+ return packet_count;
+}
+
+static int fxgmac_one_poll_rx(struct napi_struct *napi, int budget)
+{
+ struct fxgmac_channel *channel =
+ container_of(napi, struct fxgmac_channel, napi_rx);
+ int processed = fxgmac_rx_poll(channel, budget);
+
+ if (processed < budget && (napi_complete_done(napi, processed)))
+ fxgmac_enable_msix_one_irq(channel->priv, channel->queue_index);
+
+ return processed;
+}
+
+static int fxgmac_all_poll(struct napi_struct *napi, int budget)
+{
+ struct fxgmac_channel *channel;
+ struct fxgmac_pdata *priv;
+ int processed = 0;
+
+ priv = container_of(napi, struct fxgmac_pdata, napi);
+ do {
+ channel = priv->channel_head;
+ /* Only support 1 tx channel, poll ch 0. */
+ fxgmac_tx_poll(priv->channel_head + 0);
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ processed += fxgmac_rx_poll(channel, budget);
+ } while (false);
+
+ /* If we processed everything, we are done */
+ if (processed < budget) {
+ /* Turn off polling */
+ if (napi_complete_done(napi, processed))
+ fxgmac_enable_mgm_irq(priv);
+ }
+
+ if ((processed) && (netif_msg_rx_status(priv)))
+ netdev_dbg(priv->ndev, "%s,received:%d\n", __func__, processed);
+
+ return processed;
+}
+
+static void napi_add_enable(struct fxgmac_pdata *priv, struct napi_struct *napi,
+ int (*poll)(struct napi_struct *, int),
+ u32 flag)
+{
+ netif_napi_add(priv->ndev, napi, poll);
+ napi_enable(napi);
+ priv->int_flag |= flag;
+}
+
+static void fxgmac_napi_enable(struct fxgmac_pdata *priv)
+{
+ u32 rx_napi[] = {INT_FLAG_RX0_NAPI, INT_FLAG_RX1_NAPI,
+ INT_FLAG_RX2_NAPI, INT_FLAG_RX3_NAPI};
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ if (!priv->per_channel_irq) {
+ if (field_get(INT_FLAG_LEGACY_NAPI, priv->int_flag))
+ return;
+
+ napi_add_enable(priv, &priv->napi, fxgmac_all_poll,
+ INT_FLAG_LEGACY_NAPI);
+ return;
+ }
+
+ if (!field_get(INT_FLAG_TX_NAPI, priv->int_flag))
+ napi_add_enable(priv, &channel->napi_tx, fxgmac_one_poll_tx,
+ INT_FLAG_TX_NAPI);
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ if (!(priv->int_flag & rx_napi[i]))
+ napi_add_enable(priv, &channel->napi_rx,
+ fxgmac_one_poll_rx, rx_napi[i]);
+}
+
+static int fxgmac_probe(struct pci_dev *pcidev, const struct pci_device_id *id)
+{
+ struct device *dev = &pcidev->dev;
+ struct fxgmac_resources res;
+ int i, ret;
+
+ ret = pcim_enable_device(pcidev);
+ if (ret) {
+ dev_err(dev, "%s pcim_enable_device err:%d\n", __func__, ret);
+ return ret;
+ }
+
+ for (i = 0; i < PCI_STD_NUM_BARS; i++) {
+ if (pci_resource_len(pcidev, i) == 0)
+ continue;
+
+ ret = pcim_iomap_regions(pcidev, BIT(i), FXGMAC_DRV_NAME);
+ if (ret) {
+ dev_err(dev, "%s, pcim_iomap_regions err:%d\n",
+ __func__, ret);
+ return ret;
+ }
+ break;
+ }
+
+ pci_set_master(pcidev);
+
+ memset(&res, 0, sizeof(res));
+ res.irq = pcidev->irq;
+ res.addr = pcim_iomap_table(pcidev)[i];
+
+ return fxgmac_drv_probe(&pcidev->dev, &res);
+}
+
+static void fxgmac_remove(struct pci_dev *pcidev)
+{
+ struct fxgmac_pdata *priv = dev_get_drvdata(&pcidev->dev);
+ struct net_device *ndev = priv->ndev;
+
+ unregister_netdev(ndev);
+ fxgmac_phy_reset(priv);
+ free_netdev(ndev);
+
+ if (IS_ENABLED(CONFIG_PCI_MSI) &&
+ FIELD_GET(INT_FLAG_MSIX, priv->int_flag)) {
+ pci_disable_msix(pcidev);
+ kfree(priv->msix_entries);
+ priv->msix_entries = NULL;
+ }
+}
+
+static void __fxgmac_shutdown(struct pci_dev *pcidev)
+{
+ struct fxgmac_pdata *priv = dev_get_drvdata(&pcidev->dev);
+ struct net_device *ndev = priv->ndev;
+
+ fxgmac_net_powerdown(priv);
+ netif_device_detach(ndev);
+}
+
+static void fxgmac_shutdown(struct pci_dev *pcidev)
+{
+ rtnl_lock();
+ __fxgmac_shutdown(pcidev);
+ if (system_state == SYSTEM_POWER_OFF) {
+ pci_wake_from_d3(pcidev, false);
+ pci_set_power_state(pcidev, PCI_D3hot);
+ }
+ rtnl_unlock();
+}
+
+static int fxgmac_suspend(struct device *device)
+{
+ struct fxgmac_pdata *priv = dev_get_drvdata(device);
+ struct net_device *ndev = priv->ndev;
+
+ rtnl_lock();
+ if (priv->dev_state != FXGMAC_DEV_START)
+ goto unlock;
+
+ if (netif_running(ndev))
+ __fxgmac_shutdown(to_pci_dev(device));
+
+ priv->dev_state = FXGMAC_DEV_SUSPEND;
+unlock:
+ rtnl_unlock();
+
+ return 0;
+}
+
+static int fxgmac_resume(struct device *device)
+{
+ struct fxgmac_pdata *priv = dev_get_drvdata(device);
+ struct net_device *ndev = priv->ndev;
+ int ret = 0;
+
+ rtnl_lock();
+ if (priv->dev_state != FXGMAC_DEV_SUSPEND)
+ goto unlock;
+
+ priv->dev_state = FXGMAC_DEV_RESUME;
+ __clear_bit(FXGMAC_POWER_STATE_DOWN, &priv->power_state);
+ rtnl_lock();
+ if (netif_running(ndev)) {
+ ret = fxgmac_net_powerup(priv);
+ if (ret < 0) {
+ netdev_err(priv->ndev, "%s, fxgmac net powerup failed:%d\n",
+ __func__, ret);
+ goto unlock;
+ }
+ }
+
+ netif_device_attach(ndev);
+unlock:
+ rtnl_unlock();
+
+ return ret;
+}
+
+#define MOTORCOMM_PCI_ID 0x1f0a
+#define YT6801_PCI_DEVICE_ID 0x6801
+
+static const struct pci_device_id fxgmac_pci_tbl[] = {
+ { PCI_DEVICE(MOTORCOMM_PCI_ID, YT6801_PCI_DEVICE_ID) },
+ { 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, fxgmac_pci_tbl);
+
+static const struct dev_pm_ops fxgmac_pm_ops = {
+ SYSTEM_SLEEP_PM_OPS(fxgmac_suspend, fxgmac_resume)
+};
+
+static struct pci_driver fxgmac_pci_driver = {
+ .name = FXGMAC_DRV_NAME,
+ .id_table = fxgmac_pci_tbl,
+ .probe = fxgmac_probe,
+ .remove = fxgmac_remove,
+ .driver.pm = pm_ptr(&fxgmac_pm_ops),
+ .shutdown = fxgmac_shutdown,
+};
+
+module_pci_driver(fxgmac_pci_driver);
+
+MODULE_AUTHOR("Motorcomm Electronic Tech. Co., Ltd.");
+MODULE_DESCRIPTION(FXGMAC_DRV_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/motorcomm/yt6801/yt6801_type.h b/drivers/net/ethernet/motorcomm/yt6801/yt6801_type.h
new file mode 100644
index 000000000..b5a853d70
--- /dev/null
+++ b/drivers/net/ethernet/motorcomm/yt6801/yt6801_type.h
@@ -0,0 +1,961 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* Copyright (c) 2022 - 2024 Motorcomm Electronic Technology Co.,Ltd. */
+
+#ifndef YT6801_TYPE_H
+#define YT6801_TYPE_H
+
+#include <linux/netdevice.h>
+#include <linux/bitfield.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#define FXGMAC_DRV_NAME "yt6801"
+#define FXGMAC_DRV_DESC "Motorcomm Gigabit Ethernet Driver"
+
+#define FXGMAC_RX_BUF_ALIGN 64
+#define FXGMAC_TX_MAX_BUF_SIZE (0x3fff & ~(FXGMAC_RX_BUF_ALIGN - 1))
+#define FXGMAC_RX_MIN_BUF_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
+
+/* Descriptors required for maximum contiguous TSO/GSO packet */
+#define FXGMAC_TX_MAX_SPLIT ((GSO_MAX_SIZE / FXGMAC_TX_MAX_BUF_SIZE) + 1)
+
+/* Maximum possible descriptors needed for a SKB */
+#define FXGMAC_TX_MAX_DESC_NR (MAX_SKB_FRAGS + FXGMAC_TX_MAX_SPLIT + 2)
+
+#define FXGMAC_DMA_STOP_TIMEOUT 5
+#define FXGMAC_JUMBO_PACKET_MTU 9014
+#define FXGMAC_MAX_DMA_RX_CHANNELS 4
+#define FXGMAC_MAX_DMA_TX_CHANNELS 1
+#define FXGMAC_MAX_DMA_CHANNELS \
+ (FXGMAC_MAX_DMA_RX_CHANNELS + FXGMAC_MAX_DMA_TX_CHANNELS)
+
+/**************** Other configuration register. *********************/
+#define GLOBAL_CTRL0 0x1000
+
+#define EPHY_CTRL 0x1004
+#define EPHY_CTRL_RESET BIT(0)
+#define EPHY_CTRL_STA_LINKUP BIT(1)
+#define EPHY_CTRL_STA_DUPLEX BIT(2)
+#define EPHY_CTRL_STA_SPEED GENMASK(4, 3)
+
+#define OOB_WOL_CTRL 0x1010
+#define OOB_WOL_CTRL_DIS BIT(0)
+
+/* MAC management registers */
+#define MGMT_INT_CTRL0 0x1100
+#define MGMT_INT_CTRL0_INT_STATUS GENMASK(15, 0)
+#define MGMT_INT_CTRL0_INT_STATUS_RX 0x000f
+#define MGMT_INT_CTRL0_INT_STATUS_TX 0x0010
+#define MGMT_INT_CTRL0_INT_STATUS_MISC 0x0020
+#define MGMT_INT_CTRL0_INT_STATUS_RXTX 0x0030
+#define MGMT_INT_CTRL0_INT_MASK GENMASK(31, 16)
+#define MGMT_INT_CTRL0_INT_MASK_RXCH 0x000f
+#define MGMT_INT_CTRL0_INT_MASK_TXCH 0x0010
+#define MGMT_INT_CTRL0_INT_MASK_MISC 0x0020
+#define MGMT_INT_CTRL0_INT_MASK_EX_PMT 0xf7ff
+#define MGMT_INT_CTRL0_INT_MASK_DISABLE 0xf000
+#define MGMT_INT_CTRL0_INT_MASK_MASK 0xffff
+
+/* Interrupt Moderation */
+#define INT_MOD 0x1108
+#define INT_MOD_RX GENMASK(11, 0)
+#define INT_MOD_200_US 200
+#define INT_MOD_TX GENMASK(27, 16)
+
+/* LTR_CTRL3, LTR latency message, only for System IDLE Start. */
+#define LTR_IDLE_ENTER 0x113c
+#define LTR_IDLE_ENTER_ENTER GENMASK(9, 0)
+#define LTR_IDLE_ENTER_900_US 900
+#define LTR_IDLE_ENTER_SCALE GENMASK(14, 10)
+#define LTR_IDLE_ENTER_SCALE_1_NS 0
+#define LTR_IDLE_ENTER_SCALE_32_NS 1
+#define LTR_IDLE_ENTER_SCALE_1024_NS 2
+#define LTR_IDLE_ENTER_SCALE_32768_NS 3
+#define LTR_IDLE_ENTER_SCALE_1048576_NS 4
+#define LTR_IDLE_ENTER_SCALE_33554432_NS 5
+#define LTR_IDLE_ENTER_REQUIRE BIT(15)
+
+/* LTR_CTRL4, LTR latency message, only for System IDLE End. */
+#define LTR_IDLE_EXIT 0x1140
+#define LTR_IDLE_EXIT_EXIT GENMASK(9, 0)
+#define LTR_IDLE_EXIT_171_US 171
+#define LTR_IDLE_EXIT_SCALE GENMASK(14, 10)
+#define LTR_IDLE_EXIT_REQUIRE BIT(15)
+
+#define MSIX_TBL_MASK 0x120c
+
+/* msi table */
+#define MSI_ID_RXQ0 0
+#define MSI_ID_RXQ1 1
+#define MSI_ID_RXQ2 2
+#define MSI_ID_RXQ3 3
+#define MSI_ID_TXQ0 4
+#define MSIX_TBL_MAX_NUM 5
+
+#define MSI_PBA 0x1300
+
+#define EFUSE_OP_CTRL_0 0x1500
+#define EFUSE_OP_MODE GENMASK(1, 0)
+#define EFUSE_OP_MODE_ROW_WRITE 0x0
+#define EFUSE_OP_MODE_ROW_READ 0x1
+#define EFUSE_OP_MODE_AUTO_LOAD 0x2
+#define EFUSE_OP_MODE_READ_BLANK 0x3
+#define EFUSE_OP_START BIT(2)
+#define EFUSE_OP_ADDR GENMASK(15, 8)
+#define EFUSE_OP_WR_DATA GENMASK(23, 16)
+
+#define EFUSE_OP_CTRL_1 0x1504
+#define EFUSE_OP_DONE BIT(1)
+#define EFUSE_OP_PGM_PASS BIT(2)
+#define EFUSE_OP_BIST_ERR_CNT GENMASK(15, 8)
+#define EFUSE_OP_BIST_ERR_ADDR GENMASK(23, 16)
+#define EFUSE_OP_RD_DATA GENMASK(31, 24)
+
+/* MAC addr can be configured through effuse */
+#define MACA0LR_FROM_EFUSE 0x1520
+#define MACA0HR_FROM_EFUSE 0x1524
+
+#define SYS_RESET 0x152c
+#define SYS_RESET_RESET BIT(31)
+
+#define PCIE_SERDES_PLL 0x199c
+#define PCIE_SERDES_PLL_AUTOOFF BIT(0)
+
+/**************** GMAC register. *********************/
+#define MAC_CR 0x2000
+#define MAC_CR_RE BIT(0)
+#define MAC_CR_TE BIT(1)
+#define MAC_CR_LM BIT(12)
+#define MAC_CR_DM BIT(13)
+#define MAC_CR_FES BIT(14)
+#define MAC_CR_PS BIT(15)
+#define MAC_CR_JE BIT(16)
+#define MAC_CR_ACS BIT(20)
+#define MAC_CR_CST BIT(21)
+#define MAC_CR_IPC BIT(27)
+#define MAC_CR_ARPEN BIT(31)
+
+#define MAC_ECR 0x2004
+#define MAC_ECR_DCRCC BIT(16)
+#define MAC_ECR_HDSMS GENMASK(22, 20)
+#define MAC_ECR_HDSMS_64B 0
+#define MAC_ECR_HDSMS_128B 1
+#define MAC_ECR_HDSMS_256B 2
+#define MAC_ECR_HDSMS_512B 3
+#define MAC_ECR_HDSMS_1023B 4
+
+#define MAC_PFR 0x3008
+#define MAC_PFR_PR BIT(0) /* Promiscuous Mode. */
+#define MAC_PFR_HUC BIT(1) /* Hash Unicast Mode. */
+#define MAC_PFR_HMC BIT(2)
+#define MAC_PFR_PM BIT(4) /* Pass all Multicast. */
+#define MAC_PFR_DBF BIT(5) /* Disable Broadcast Packets. */
+#define MAC_PFR_HPF BIT(10)
+#define MAC_PFR_VTFE BIT(16)
+
+#define MAC_Q0TFCR 0x2070
+#define MAC_Q0TFCR_TFE BIT(1)
+#define MAC_Q0TFCR_PT GENMASK(31, 16)
+
+#define MAC_RFCR 0x2090
+#define MAC_RFCR_RFE BIT(0)
+#define MAC_RFCR_UP BIT(1)
+#define MAC_RFCR_PFCE BIT(8)
+
+#define MAC_RQC0R 0x20a0
+#define MAC_RQC1R 0x20a4
+#define MAC_RQC2R 0x20a8
+#define MAC_RQC2_INC 4
+#define MAC_RQC2_Q_PER_REG 4
+
+#define MAC_ISR 0x20b0
+#define MAC_ISR_PHYIF_STA BIT(0)
+#define MAC_ISR_AN_SR GENMASK(3, 1)
+#define MAC_ISR_PMT_STA BIT(4)
+#define MAC_ISR_LPI_STA BIT(5)
+#define MAC_ISR_MMC_STA BIT(8)
+#define MAC_ISR_RX_MMC_STA BIT(9)
+#define MAC_ISR_TX_MMC_STA BIT(10)
+#define MAC_ISR_IPC_RXINT BIT(11)
+#define MAC_ISR_TSIS BIT(12)
+#define MAC_ISR_TX_RX_STA GENMASK(14, 13)
+#define MAC_ISR_GPIO_SR GENMASK(25, 15)
+
+#define MAC_IER 0x20b4
+#define MAC_IER_TSIE BIT(12)
+
+#define MAC_TX_RX_STA 0x20b8
+
+#define MAC_PMT_STA 0x20c0
+#define MAC_PMT_STA_PWRDWN BIT(0)
+#define MAC_PMT_STA_MGKPKTEN BIT(1)
+#define MAC_PMT_STA_RWKPKTEN BIT(2)
+#define MAC_PMT_STA_MGKPRCVD BIT(5)
+#define MAC_PMT_STA_RWKPRCVD BIT(6)
+#define MAC_PMT_STA_GLBLUCAST BIT(9)
+#define MAC_PMT_STA_RWKPTR GENMASK(27, 24)
+#define MAC_PMT_STA_RWKFILTERST BIT(31)
+
+#define MAC_RWK_PAC 0x20c4
+#define MAC_LPI_STA 0x20d0
+#define MAC_LPI_CONTROL 0x20d4
+#define MAC_LPI_TIMER 0x20d8
+#define MAC_MS_TIC_COUNTER 0x20dc
+#define MAC_AN_CR 0x20e0
+#define MAC_AN_SR 0x20e4
+#define MAC_AN_ADV 0x20e8
+#define MAC_AN_LPA 0x20ec
+#define MAC_AN_EXP 0x20f0
+#define MAC_PHYIF_STA 0x20f8
+#define MAC_VR 0x2110
+#define MAC_DBG_STA 0x2114
+
+#define MAC_HWF0R 0x211c
+#define MAC_HWF0R_VLHASH BIT(4)
+#define MAC_HWF0R_SMASEL BIT(5)
+#define MAC_HWF0R_RWKSEL BIT(6)
+#define MAC_HWF0R_MGKSEL BIT(7)
+#define MAC_HWF0R_MMCSEL BIT(8)
+#define MAC_HWF0R_ARPOFFSEL BIT(9)
+#define MAC_HWF0R_TSSEL BIT(12)
+#define MAC_HWF0R_EEESEL BIT(13)
+#define MAC_HWF0R_TXCOESEL BIT(14)
+#define MAC_HWF0R_RXCOESEL BIT(16)
+#define MAC_HWF0R_ADDMACADRSEL GENMASK(22, 18)
+#define MAC_HWF0R_TSSTSSEL GENMASK(26, 25)
+#define MAC_HWF0R_SAVLANINS BIT(27)
+#define MAC_HWF0R_ACTPHYIFSEL GENMASK(30, 28)
+
+#define MAC_HWF1R 0x2120
+#define MAC_HWF1R_RXFIFOSIZE GENMASK(4, 0)
+#define MAC_HWF1R_TXFIFOSIZE GENMASK(10, 6)
+#define MAC_HWF1R_ADVTHWORD BIT(13)
+#define MAC_HWF1R_ADDR64 GENMASK(15, 14)
+#define MAC_HWF1R_DCBEN BIT(16)
+#define MAC_HWF1R_SPHEN BIT(17)
+#define MAC_HWF1R_TSOEN BIT(18)
+#define MAC_HWF1R_DBGMEMA BIT(19)
+#define MAC_HWF1R_AVSEL BIT(20)
+#define MAC_HWF1R_RAVSEL BIT(21)
+#define MAC_HWF1R_HASHTBLSZ GENMASK(25, 24)
+#define MAC_HWF1R_L3L4FNUM GENMASK(30, 27)
+
+#define MAC_HWF2R 0x2124
+#define MAC_HWF2R_RXQCNT GENMASK(3, 0)
+#define MAC_HWF2R_TXQCNT GENMASK(9, 6)
+#define MAC_HWF2R_RXCHCNT GENMASK(15, 12)
+#define MAC_HWF2R_TXCHCNT GENMASK(21, 18)
+#define MAC_HWF2R_PPSOUTNUM GENMASK(26, 24)
+#define MAC_HWF2R_AUXSNAPNUM GENMASK(30, 28)
+
+#define MAC_HWF3R 0x2128
+
+#define MAC_MDIO_ADDR 0x2200
+#define MAC_MDIO_ADDR_BUSY BIT(0)
+#define MAC_MDIO_ADDR_GOC GENMASK(3, 2)
+
+#define MAC_MDIO_DATA 0x2204
+#define MAC_MDIO_DATA_GD GENMASK(15, 0)
+#define MAC_MDIO_DATA_RA GENMASK(31, 16)
+
+#define MAC_GPIO_CR 0x2208
+#define MAC_GPIO_SR 0x220c
+#define MAC_ARP_PROTO_ADDR 0x2210
+#define MAC_CSR_SW_CTRL 0x2230
+#define MAC_MACA0HR 0x2300
+#define MAC_MACA0LR 0x2304
+#define MAC_MACA1HR 0x2308
+#define MAC_MACA1LR 0x230c
+
+/* MMC registers */
+#define MMC_CR 0x2700
+#define MMC_CR_CR BIT(0)
+#define MMC_CR_CSR BIT(1)
+#define MMC_CR_ROR BIT(2)
+#define MMC_CR_MCF BIT(3)
+
+#define MMC_RISR 0x2704
+#define MMC_TISR 0x2708
+
+#define MMC_RIER 0x270c
+#define MMC_RIER_ALL_INTERRUPTS GENMASK(27, 0)
+
+#define MMC_TIER 0x2710
+#define MMC_TIER_ALL_INTERRUPTS GENMASK(27, 0)
+
+#define MMC_IPC_RXINT_MASK 0x2800
+#define MMC_IPC_RXINT 0x2808
+
+/* MTL registers */
+#define MTL_OMR 0x2c00
+#define MTL_OMR_RAA BIT(2)
+#define MTL_OMR_ETSALG GENMASK(6, 5)
+
+#define MTL_FDCR 0x2c08
+#define MTL_FDSR 0x2c0c
+#define MTL_FDDR 0x2c10
+#define MTL_INT_SR 0x2c20
+
+#define MTL_RQDCM_INC 4
+#define MTL_RQDCM_Q_PER_REG 4
+
+#define MTL_RQDCM0R 0x2c30
+#define MTL_RQDCM0R_Q0MDMACH 0x0
+#define MTL_RQDCM0R_Q1MDMACH 0x00000100
+#define MTL_RQDCM0R_Q2MDMACH 0x00020000
+#define MTL_RQDCM0R_Q3MDMACH 0x03000000
+
+#define MTL_ECC_INT_SR 0x2ccc
+
+#define MTL_RQDCM1R_Q4MDMACH 0x00000004
+#define MTL_RQDCM1R_Q5MDMACH 0x00000500
+#define MTL_RQDCM1R_Q6MDMACH 0x00060000
+#define MTL_RQDCM1R_Q7MDMACH 0x07000000
+
+/* MTL queue registers */
+#define MTL_Q_BASE 0x2d00
+#define MTL_Q_INC 0x40
+
+#define MTL_Q_TQOMR 0x00
+#define MTL_Q_TQOMR_FTQ BIT(0)
+#define MTL_Q_TQOMR_TSF BIT(1)
+#define MTL_Q_TQOMR_TXQEN GENMASK(3, 2)
+#define MTL_Q_DISABLED 0x00
+#define MTL_Q_EN_IF_AV 0x01
+#define MTL_Q_ENABLED 0x02
+
+#define MTL_Q_TQOMR_TTC GENMASK(6, 4)
+#define MTL_Q_TQOMR_TTC_THRESHOLD_32 0x00
+#define MTL_Q_TQOMR_TTC_THRESHOLD_64 0x01
+#define MTL_Q_TQOMR_TTC_THRESHOLD_96 0x02
+#define MTL_Q_TQOMR_TTC_THRESHOLD_128 0x03
+#define MTL_Q_TQOMR_TTC_THRESHOLD_192 0x04
+#define MTL_Q_TQOMR_TTC_THRESHOLD_256 0x05
+#define MTL_Q_TQOMR_TTC_THRESHOLD_384 0x06
+#define MTL_Q_TQOMR_TTC_THRESHOLD_512 0x07
+
+#define MTL_Q_TQOMR_TQS GENMASK(22, 16)
+
+#define MTL_Q_TQUR 0x04
+#define MTL_Q_TXDEG 0x08 /* Transmit debug */
+#define MTL_Q_IR 0x2c /* Interrupt control status */
+
+#define MTL_Q_RQOMR 0x30
+#define MTL_Q_RQOMR_RTC GENMASK(1, 0)
+#define MTL_Q_RQOMR_RTC_THRESHOLD_64 0x00
+#define MTL_Q_RQOMR_RTC_THRESHOLD_32 0x01
+#define MTL_Q_RQOMR_RTC_THRESHOLD_96 0x02
+#define MTL_Q_RQOMR_RTC_THRESHOLD_128 0x03
+
+#define MTL_Q_RQOMR_FUP BIT(3)
+#define MTL_Q_RQOMR_FEP BIT(4)
+#define MTL_Q_RQOMR_RSF BIT(5)
+#define MTL_Q_RQOMR_EHFC BIT(7)
+#define MTL_Q_RQOMR_RFA GENMASK(13, 8)
+#define MTL_Q_RQOMR_RFD GENMASK(19, 14)
+#define MTL_Q_RQOMR_RQS GENMASK(28, 20)
+
+#define MTL_Q_RQMPOCR 0x34
+
+#define MTL_Q_RQDR 0x38
+#define MTL_Q_RQDR_RXQSTS GENMASK(5, 4)
+#define MTL_Q_RQDR_PRXQ GENMASK(29, 16)
+
+#define MTL_Q_RQCR 0x3c
+
+/* MTL queue registers */
+#define MTL_ETSALG_WRR 0x00
+#define MTL_ETSALG_WFQ 0x01
+#define MTL_ETSALG_DWRR 0x02
+#define MTL_ETSALG_SP 0x03
+
+#define MTL_RAA_SP 0x00
+#define MTL_RAA_WSP 0x01
+
+/* MTL traffic class registers */
+#define MTL_TC_BASE MTL_Q_BASE
+#define MTL_TC_INC MTL_Q_INC
+
+#define MTL_TC_TQDR 0x08
+#define MTL_TC_TQDR_TRCSTS GENMASK(2, 1)
+#define MTL_TC_TQDR_TXQSTS BIT(4)
+
+#define MTL_TC_ETSCR 0x10
+#define MTL_TC_ETSCR_TSA GENMASK(1, 0)
+
+#define MTL_TC_ETSSR 0x14
+#define MTL_TC_QWR 0x18
+#define MTL_TC_QWR_QW GENMASK(20, 0)
+
+/* DMA registers */
+#define DMA_MR 0x3000
+#define DMA_MR_SWR BIT(0)
+#define DMA_MR_TXPR BIT(11)
+#define DMA_MR_INTM GENMASK(17, 16)
+#define DMA_MR_QUREAD BIT(19)
+#define DMA_MR_TNDF GENMASK(21, 20)
+#define DMA_MR_RNDF GENMASK(23, 22)
+
+#define DMA_SBMR 0x3004
+#define DMA_SBMR_FB BIT(0)
+#define DMA_SBMR_BLEN_4 BIT(1)
+#define DMA_SBMR_BLEN_8 BIT(2)
+#define DMA_SBMR_BLEN_16 BIT(3)
+#define DMA_SBMR_BLEN_32 BIT(4)
+#define DMA_SBMR_BLEN_64 BIT(5)
+#define DMA_SBMR_BLEN_128 BIT(6)
+#define DMA_SBMR_BLEN_256 BIT(7)
+#define DMA_SBMR_AALE BIT(10)
+#define DMA_SBMR_EAME BIT(11)
+#define DMA_SBMR_AAL BIT(12)
+#define DMA_SBMR_RD_OSR_LMT GENMASK(23, 16)
+#define DMA_SBMR_WR_OSR_LMT GENMASK(29, 24)
+#define DMA_SBMR_LPI_XIT_PKT BIT(30)
+#define DMA_SBMR_EN_LPI BIT(31)
+
+#define DMA_ISR 0x3008
+#define DMA_ISR_MTLIS BIT(16)
+#define DMA_ISR_MACIS BIT(17)
+
+#define DMA_DSRX_INC 4
+#define DMA_DSR0 0x300c
+#define DMA_DSR0_TPS GENMASK(15, 12)
+#define DMA_TPS_STOPPED 0x00
+#define DMA_TPS_SUSPENDED 0x06
+
+#define DMA_DSR1 0x3010
+#define DMA_DSR2 0x3014
+#define DMA_AXIARCR 0x3020
+#define DMA_AXIAWCR 0x3024
+#define DMA_AXIAWRCR 0x3028
+#define DMA_SAFE_ISR 0x3080
+#define DMA_ECC_IE 0x3084
+#define DMA_ECC_INT_SR 0x3088
+
+/* DMA channel registers */
+#define DMA_CH_BASE 0x3100
+#define DMA_CH_INC 0x80
+
+#define DMA_CH_CR 0x00
+#define DMA_CH_CR_PBLX8 BIT(16)
+#define DMA_CH_CR_SPH BIT(24)
+
+#define DMA_CH_TCR 0x04
+#define DMA_CH_TCR_ST BIT(0)
+#define DMA_CH_TCR_OSP BIT(4)
+#define DMA_CH_TCR_TSE BIT(12)
+#define DMA_CH_TCR_PBL GENMASK(21, 16)
+#define DMA_CH_PBL_1 1
+#define DMA_CH_PBL_2 2
+#define DMA_CH_PBL_4 4
+#define DMA_CH_PBL_8 8
+#define DMA_CH_PBL_16 16
+#define DMA_CH_PBL_32 32
+#define DMA_CH_PBL_64 64
+#define DMA_CH_PBL_128 128
+#define DMA_CH_PBL_256 256
+
+#define DMA_CH_RCR 0x08
+#define DMA_CH_RCR_SR BIT(0)
+#define DMA_CH_RCR_RBSZ GENMASK(14, 1)
+#define DMA_CH_RCR_PBL GENMASK(21, 16)
+
+#define DMA_CH_TDLR_HI 0x10
+#define DMA_CH_TDLR_LO 0x14
+#define DMA_CH_RDLR_HI 0x18
+#define DMA_CH_RDLR_LO 0x1c
+#define DMA_CH_TDTR_LO 0x20
+#define DMA_CH_RDTR_LO 0x28
+#define DMA_CH_TDRLR 0x2c
+#define DMA_CH_RDRLR 0x30
+
+#define DMA_CH_IER 0x34
+#define DMA_CH_IER_TIE BIT(0)
+#define DMA_CH_IER_TXSE BIT(1)
+#define DMA_CH_IER_TBUE BIT(2)
+#define DMA_CH_IER_RIE BIT(6)
+#define DMA_CH_IER_RBUE BIT(7)
+#define DMA_CH_IER_RSE BIT(8)
+#define DMA_CH_IER_FBEE BIT(12)
+#define DMA_CH_IER_AIE BIT(14)
+#define DMA_CH_IER_NIE BIT(15)
+
+#define DMA_CH_RIWT 0x38
+#define DMA_CH_RIWT_RWT GENMASK(7, 0)
+
+#define DMA_CH_CATDR_LO 0x44
+#define DMA_CH_CARDR_LO 0x4c
+#define DMA_CH_CATBR_HI 0x50
+#define DMA_CH_CATBR_LO 0x54
+#define DMA_CH_CARBR_HI 0x58
+#define DMA_CH_CARBR_LO 0x5c
+
+#define DMA_CH_SR 0x60
+#define DMA_CH_SR_TI BIT(0)
+#define DMA_CH_SR_TPS BIT(1)
+#define DMA_CH_SR_TBU BIT(2)
+#define DMA_CH_SR_RI BIT(6)
+#define DMA_CH_SR_RBU BIT(7)
+#define DMA_CH_SR_RPS BIT(8)
+#define DMA_CH_SR_FBE BIT(12)
+
+/* Receive Normal Descriptor (Read Format) */
+#define RX_DESC0_OVT GENMASK(15, 0) /* Outer VLAN Tag */
+
+#define RX_DESC2_HL GENMASK(9, 0) /* L3/L4 Header Length */
+
+#define RX_DESC3_PL GENMASK(14, 0) /* Packet Length */
+#define RX_DESC3_ES BIT(15) /* Error Summary */
+#define RX_DESC3_ETLT GENMASK(18, 16) /* Length/Type Field */
+#define RX_DESC3_BUF1V BIT(24) /* Receive Status RDES1 Valid */
+#define RX_DESC3_BUF2V BIT(25) /* Receive Status RDES2 Valid */
+#define RX_DESC3_LD BIT(28) /* Last Descriptor */
+#define RX_DESC3_FD BIT(29) /* First Descriptor */
+#define RX_DESC3_INTE BIT(30)
+#define RX_DESC3_OWN BIT(31) /* Own Bit */
+
+/* Transmit Normal Descriptor (Read Format) */
+#define TX_DESC2_HL_B1L GENMASK(13, 0) /* Header Length or Buffer 1 Length */
+#define TX_DESC2_VTIR GENMASK(15, 14) /* VLAN Tag Insertion/Replacement */
+#define TX_DESC2_TTSE BIT(30) /* Transmit Timestamp Enable */
+#define TX_DESC2_IC BIT(31) /* Interrupt on Completion. */
+#define TX_DESC3_TCPPL GENMASK(17, 0) /* TCP Packet Length.*/
+#define TX_DESC3_FL GENMASK(14, 0) /* Frame Length */
+#define TX_DESC3_CIC GENMASK(17, 16) /* Checksum Insertion Control */
+#define TX_DESC3_TSE BIT(18) /* TCP Segmentation Enable */
+#define TX_DESC3_TCPHDRLEN GENMASK(22, 19) /* TCP/UDP Header Length. */
+#define TX_DESC3_CPC GENMASK(27, 26) /* CRC Pad Control */
+#define TX_DESC3_LD BIT(28) /* Last Descriptor */
+#define TX_DESC3_FD BIT(29) /* First Descriptor */
+#define TX_DESC3_CTXT BIT(30) /* Context Type */
+#define TX_DESC3_OWN BIT(31) /* Own Bit */
+
+/* Transmit Context Descriptor */
+#define TX_CONTEXT_DESC2_MSS GENMASK(13, 0) /* Maximum Segment Size */
+#define TX_CONTEXT_DESC2_IVLTV GENMASK(31, 16) /* Inner VLAN Tag. */
+
+#define TX_CONTEXT_DESC3_VT GENMASK(15, 0) /* VLAN Tag */
+#define TX_CONTEXT_DESC3_VLTV BIT(16) /* Inner VLAN Tag Valid */
+#define TX_CONTEXT_DESC3_IVLTV BIT(17) /* Inner VLAN TAG valid. */
+/* Inner VLAN Tag Insert/Replace */
+#define TX_CONTEXT_DESC3_IVTIR GENMASK(19, 18)
+#define TX_CONTEXT_DESC3_TCMSSV BIT(26) /* Timestamp correct or MSS Valid */
+#define TX_CONTEXT_DESC3_CTXT BIT(30) /* Context Type */
+
+/* Receive Normal Descriptor (Write-Back Format) */
+#define RX_DESC0_WB_OVT GENMASK(15, 0) /* Outer VLAN Tag. */
+#define RX_DESC0_WB_IVT GENMASK(31, 16) /* Inner VLAN Tag. */
+
+#define RX_DESC1_WB_PT GENMASK(2, 0) /* Payload Type */
+#define RX_DESC1_WB_IPHE BIT(3) /* IP Header Error. */
+#define RX_DESC1_WB_IPV4 BIT(4) /* IPV4 Header Present */
+#define RX_DESC1_WB_IPV6 BIT(5) /* IPV6 Header Present. */
+#define RX_DESC1_WB_IPCE BIT(7) /* IP Payload Error. */
+
+#define RX_DESC2_WB_RAPARSER GENMASK(13, 11) /* Parse error */
+#define RX_DESC2_WB_DAF BIT(17) /* DA Filter Fail */
+#define RX_DESC2_WB_HF BIT(18) /* Hash Filter Status. */
+
+struct fxgmac_ring_buf {
+ struct sk_buff *skb;
+ dma_addr_t skb_dma;
+ unsigned int skb_len;
+};
+
+/* Common Tx and Rx DMA hardware descriptor */
+struct fxgmac_dma_desc {
+ __le32 desc0;
+ __le32 desc1;
+ __le32 desc2;
+ __le32 desc3;
+};
+
+/* Page allocation related values */
+struct fxgmac_page_alloc {
+ struct page *pages;
+ unsigned int pages_len;
+ unsigned int pages_offset;
+ dma_addr_t pages_dma;
+};
+
+/* Ring entry buffer data */
+struct fxgmac_buffer_data {
+ struct fxgmac_page_alloc pa;
+ struct fxgmac_page_alloc pa_unmap;
+
+ dma_addr_t dma_base;
+ unsigned long dma_off;
+ unsigned int dma_len;
+};
+
+struct fxgmac_tx_desc_data {
+ unsigned int packets; /* BQL packet count */
+ unsigned int bytes; /* BQL byte count */
+};
+
+struct fxgmac_rx_desc_data {
+ struct fxgmac_buffer_data hdr; /* Header locations */
+ struct fxgmac_buffer_data buf; /* Payload locations */
+ unsigned short hdr_len; /* Length of received header */
+ unsigned short len; /* Length of received packet */
+};
+
+struct fxgmac_pkt_info {
+ struct sk_buff *skb;
+#define ATTR_TX_CSUM_ENABLE BIT(0)
+#define ATTR_TX_TSO_ENABLE BIT(1)
+#define ATTR_TX_VLAN_CTAG BIT(2)
+#define ATTR_TX_PTP BIT(3)
+
+#define ATTR_RX_CSUM_DONE BIT(0)
+#define ATTR_RX_VLAN_CTAG BIT(1)
+#define ATTR_RX_INCOMPLETE BIT(2)
+#define ATTR_RX_CONTEXT_NEXT BIT(3)
+#define ATTR_RX_CONTEXT BIT(4)
+#define ATTR_RX_RX_TSTAMP BIT(5)
+#define ATTR_RX_RSS_HASH BIT(6)
+ unsigned int attr;
+
+#define ERRORS_RX_LENGTH BIT(0)
+#define ERRORS_RX_OVERRUN BIT(1)
+#define ERRORS_RX_CRC BIT(2)
+#define ERRORS_RX_FRAME BIT(3)
+ unsigned int errors;
+ unsigned int desc_count; /* descriptors needed for this packet */
+ unsigned int length;
+ unsigned int tx_packets;
+ unsigned int tx_bytes;
+
+ unsigned int header_len;
+ unsigned int tcp_header_len;
+ unsigned int tcp_payload_len;
+ unsigned short mss;
+ unsigned short vlan_ctag;
+
+ u64 rx_tstamp;
+ u32 rss_hash;
+ enum pkt_hash_types rss_hash_type;
+};
+
+struct fxgmac_desc_data {
+ struct fxgmac_dma_desc *dma_desc; /* Virtual address of descriptor */
+ dma_addr_t dma_desc_addr; /* DMA address of descriptor */
+ struct sk_buff *skb; /* Virtual address of SKB */
+ dma_addr_t skb_dma; /* DMA address of SKB data */
+ unsigned int skb_dma_len; /* Length of SKB DMA area */
+
+ /* Tx/Rx -related data */
+ struct fxgmac_tx_desc_data tx;
+ struct fxgmac_rx_desc_data rx;
+
+ unsigned int mapped_as_page;
+};
+
+struct fxgmac_ring {
+ struct fxgmac_pkt_info pkt_info; /* packet related information */
+
+ /* Virtual/DMA addresses of DMA descriptor list */
+ struct fxgmac_dma_desc *dma_desc_head;
+ dma_addr_t dma_desc_head_addr;
+ unsigned int dma_desc_count;
+
+ /* Array of descriptor data corresponding the DMA descriptor
+ * (always use the FXGMAC_GET_DESC_DATA macro to access this data)
+ */
+ struct fxgmac_desc_data *desc_data_head;
+
+ /* Page allocation for RX buffers */
+ struct fxgmac_page_alloc rx_hdr_pa;
+ struct fxgmac_page_alloc rx_buf_pa;
+
+ /* Ring index values
+ * cur - Tx: index of descriptor to be used for current transfer
+ * Rx: index of descriptor to check for packet availability
+ * dirty - Tx: index of descriptor to check for transfer complete
+ * Rx: index of descriptor to check for buffer reallocation
+ */
+ unsigned int cur;
+ unsigned int dirty;
+
+ struct {
+ unsigned int xmit_more;
+ unsigned int queue_stopped;
+ unsigned short cur_mss;
+ unsigned short cur_vlan_ctag;
+ } tx;
+} ____cacheline_aligned;
+
+struct fxgmac_channel {
+ char name[16];
+
+ /* Address of private data area for device */
+ struct fxgmac_pdata *priv;
+
+ /* Queue index and base address of queue's DMA registers */
+ unsigned int queue_index;
+
+ /* Per channel interrupt irq number */
+ u32 dma_irq_rx;
+ char dma_irq_rx_name[IFNAMSIZ + 32];
+ u32 dma_irq_tx;
+ char dma_irq_tx_name[IFNAMSIZ + 32];
+
+ /* ndev related settings */
+ struct napi_struct napi_tx;
+ struct napi_struct napi_rx;
+
+ void __iomem *dma_regs;
+ struct fxgmac_ring *tx_ring;
+ struct fxgmac_ring *rx_ring;
+} ____cacheline_aligned;
+
+/* This structure contains flags that indicate what hardware features
+ * or configurations are present in the device.
+ */
+struct fxgmac_hw_features {
+ unsigned int version; /* HW Version */
+
+ /* HW Feature Register0 */
+ unsigned int phyifsel; /* PHY interface support */
+ unsigned int vlhash; /* VLAN Hash Filter */
+ unsigned int sma; /* SMA(MDIO) Interface */
+ unsigned int rwk; /* PMT remote wake-up packet */
+ unsigned int mgk; /* PMT magic packet */
+ unsigned int mmc; /* RMON module */
+ unsigned int aoe; /* ARP Offload */
+ unsigned int ts; /* IEEE 1588-2008 Advanced Timestamp */
+ unsigned int eee; /* Energy Efficient Ethernet */
+ unsigned int tx_coe; /* Tx Checksum Offload */
+ unsigned int rx_coe; /* Rx Checksum Offload */
+ unsigned int addn_mac; /* Additional MAC Addresses */
+ unsigned int ts_src; /* Timestamp Source */
+ unsigned int sa_vlan_ins; /* Source Address or VLAN Insertion */
+
+ /* HW Feature Register1 */
+ unsigned int rx_fifo_size; /* MTL Receive FIFO Size */
+ unsigned int tx_fifo_size; /* MTL Transmit FIFO Size */
+ unsigned int adv_ts_hi; /* Advance Timestamping High Word */
+ unsigned int dma_width; /* DMA width */
+ unsigned int dcb; /* DCB Feature */
+ unsigned int sph; /* Split Header Feature */
+ unsigned int tso; /* TCP Segmentation Offload */
+ unsigned int dma_debug; /* DMA Debug Registers */
+ unsigned int rss; /* Receive Side Scaling */
+ unsigned int tc_cnt; /* Number of Traffic Classes */
+ unsigned int avsel; /* AV Feature Enable */
+ unsigned int ravsel; /* Rx Side Only AV Feature Enable */
+ unsigned int hash_table_size; /* Hash Table Size */
+ unsigned int l3l4_filter_num; /* Number of L3-L4 Filters */
+
+ /* HW Feature Register2 */
+ unsigned int rx_q_cnt; /* Number of MTL Receive Queues */
+ unsigned int tx_q_cnt; /* Number of MTL Transmit Queues */
+ unsigned int rx_ch_cnt; /* Number of DMA Receive Channels */
+ unsigned int tx_ch_cnt; /* Number of DMA Transmit Channels */
+ unsigned int pps_out_num; /* Number of PPS outputs */
+ unsigned int aux_snap_num; /* Number of Aux snapshot inputs */
+
+ u32 hwfr3; /* HW Feature Register3 */
+};
+
+struct fxgmac_resources {
+ void __iomem *addr;
+ int irq;
+};
+
+enum fxgmac_dev_state {
+ FXGMAC_DEV_OPEN = 0x0,
+ FXGMAC_DEV_CLOSE = 0x1,
+ FXGMAC_DEV_STOP = 0x2,
+ FXGMAC_DEV_START = 0x3,
+ FXGMAC_DEV_SUSPEND = 0x4,
+ FXGMAC_DEV_RESUME = 0x5,
+ FXGMAC_DEV_PROBE = 0xFF,
+};
+
+struct fxgmac_pdata {
+ struct net_device *ndev;
+ struct device *dev;
+ struct phy_device *phydev;
+
+ struct fxgmac_hw_features hw_feat; /* Hardware features */
+ void __iomem *hw_addr; /* Registers base */
+
+ /* Rings for Tx/Rx on a DMA channel */
+ struct fxgmac_channel *channel_head;
+ unsigned int channel_count;
+ unsigned int rx_ring_count;
+ unsigned int rx_desc_count;
+ unsigned int rx_q_count;
+#define FXGMAC_TX_1_RING 1
+#define FXGMAC_TX_1_Q 1
+ unsigned int tx_desc_count;
+
+ unsigned long sysclk_rate; /* Device clocks */
+ unsigned int pblx8; /* Tx/Rx common settings */
+
+ /* Tx settings */
+ unsigned int tx_sf_mode;
+ unsigned int tx_threshold;
+ unsigned int tx_pbl;
+ unsigned int tx_osp_mode;
+
+ /* Rx settings */
+ unsigned int rx_sf_mode;
+ unsigned int rx_threshold;
+ unsigned int rx_pbl;
+
+ /* Tx coalescing settings */
+ unsigned int tx_usecs;
+ unsigned int tx_frames;
+
+ /* Rx coalescing settings */
+ unsigned int rx_riwt;
+ unsigned int rx_usecs;
+ unsigned int rx_frames;
+
+ /* Flow control settings */
+ unsigned int tx_pause;
+ unsigned int rx_pause;
+
+ unsigned int rx_buf_size; /* Current Rx buffer size */
+
+ /* Device interrupt */
+ int dev_irq;
+ unsigned int per_channel_irq;
+ u32 channel_irq[FXGMAC_MAX_DMA_CHANNELS];
+ struct msix_entry *msix_entries;
+#define INT_FLAG_INTERRUPT GENMASK(4, 0)
+#define INT_FLAG_MSI BIT(1)
+#define INT_FLAG_MSIX BIT(3)
+#define INT_FLAG_LEGACY BIT(4)
+#define INT_FLAG_RX0_NAPI BIT(18)
+#define INT_FLAG_RX1_NAPI BIT(19)
+#define INT_FLAG_RX2_NAPI BIT(20)
+#define INT_FLAG_RX3_NAPI BIT(21)
+#define INT_FLAG_RX0_IRQ BIT(22)
+#define INT_FLAG_RX1_IRQ BIT(23)
+#define INT_FLAG_RX2_IRQ BIT(24)
+#define INT_FLAG_RX3_IRQ BIT(25)
+#define INT_FLAG_TX_NAPI BIT(26)
+#define INT_FLAG_TX_IRQ BIT(27)
+#define INT_FLAG_LEGACY_NAPI BIT(30)
+#define INT_FLAG_LEGACY_IRQ BIT(31)
+ u32 int_flag; /* interrupt flag */
+
+ /* ndev related settings */
+ unsigned char mac_addr[ETH_ALEN];
+ struct napi_struct napi;
+
+ int mac_speed;
+ int mac_duplex;
+
+ u32 msg_enable;
+ u32 reg_nonstick[(MSI_PBA - GLOBAL_CTRL0) >> 2];
+
+ struct work_struct restart_work;
+ enum fxgmac_dev_state dev_state;
+#define FXGMAC_POWER_STATE_DOWN 0
+#define FXGMAC_POWER_STATE_UP 1
+ unsigned long power_state;
+};
+
+/* Non-constant mask variant of FIELD_GET() and FIELD_PREP() */
+#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
+#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask))
+
+static inline u32 fxgmac_io_rd(struct fxgmac_pdata *priv, u32 reg)
+{
+ return ioread32(priv->hw_addr + reg);
+}
+
+static inline u32
+fxgmac_io_rd_bits(struct fxgmac_pdata *priv, u32 reg, u32 mask)
+{
+ u32 cfg = fxgmac_io_rd(priv, reg);
+
+ return field_get(mask, cfg);
+}
+
+static inline void fxgmac_io_wr(struct fxgmac_pdata *priv, u32 reg, u32 set)
+{
+ iowrite32(set, priv->hw_addr + reg);
+}
+
+static inline void
+fxgmac_io_wr_bits(struct fxgmac_pdata *priv, u32 reg, u32 mask, u32 set)
+{
+ u32 cfg = fxgmac_io_rd(priv, reg);
+
+ cfg &= ~mask;
+ cfg |= field_prep(mask, set);
+ fxgmac_io_wr(priv, reg, cfg);
+}
+
+static inline u32 fxgmac_mtl_io_rd(struct fxgmac_pdata *priv, u8 n, u32 reg)
+{
+ return fxgmac_io_rd(priv, reg + n * MTL_Q_INC);
+}
+
+static inline u32
+fxgmac_mtl_rd_bits(struct fxgmac_pdata *priv, u8 n, u32 reg, u32 mask)
+{
+ return fxgmac_io_rd_bits(priv, reg + n * MTL_Q_INC, mask);
+}
+
+static inline void
+fxgmac_mtl_io_wr(struct fxgmac_pdata *priv, u8 n, u32 reg, u32 set)
+{
+ return fxgmac_io_wr(priv, reg + n * MTL_Q_INC, set);
+}
+
+static inline void
+fxgmac_mtl_wr_bits(struct fxgmac_pdata *priv, u8 n, u32 reg, u32 mask, u32 set)
+{
+ return fxgmac_io_wr_bits(priv, reg + n * MTL_Q_INC, mask, set);
+}
+
+static inline u32 fxgmac_dma_io_rd(struct fxgmac_channel *channel, u32 reg)
+{
+ return ioread32(channel->dma_regs + reg);
+}
+
+static inline u32
+fxgmac_dma_rd_bits(struct fxgmac_channel *channel, u32 reg, u32 mask)
+{
+ u32 cfg = fxgmac_dma_io_rd(channel, reg);
+
+ return field_get(mask, cfg);
+}
+
+static inline void
+fxgmac_dma_io_wr(struct fxgmac_channel *channel, u32 reg, u32 set)
+{
+ iowrite32(set, channel->dma_regs + reg);
+}
+
+static inline void
+fxgmac_dma_wr_bits(struct fxgmac_channel *channel, u32 reg, u32 mask, u32 set)
+{
+ u32 cfg = fxgmac_dma_io_rd(channel, reg);
+
+ cfg &= ~mask;
+ cfg |= field_prep(mask, set);
+ fxgmac_dma_io_wr(channel, reg, cfg);
+}
+
+static inline u32 fxgmac_desc_rd_bits(__le32 desc, u32 mask)
+{
+ return field_get(mask, le32_to_cpu(desc));
+}
+
+static inline void fxgmac_desc_wr_bits(__le32 *desc, u32 mask, u32 set)
+{
+ u32 cfg = le32_to_cpu(*desc);
+
+ cfg &= ~mask;
+ cfg |= field_prep(mask, set);
+ *desc = cpu_to_le32(cfg);
+}
+
+#endif /* YT6801_TYPE_H */
diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
index 7a11fdb68..7abd5dee8 100644
--- a/drivers/net/phy/motorcomm.c
+++ b/drivers/net/phy/motorcomm.c
@@ -819,6 +819,12 @@ static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev)
val |= FIELD_PREP(YT8521_RC1R_RX_DELAY_MASK, rx_reg) |
FIELD_PREP(YT8521_RC1R_GE_TX_DELAY_MASK, tx_reg);
break;
+ case PHY_INTERFACE_MODE_INTERNAL:
+ if (phydev->drv->phy_id != PHY_ID_YT8531S)
+ return -EOPNOTSUPP;
+
+ dev_info_once(&phydev->mdio.dev, "Integrated YT8531S phy of YT6801.\n");
+ return 0;
default: /* do not support other modes */
return -EOPNOTSUPP;
}
--
2.34.1
2
1

[openeuler:OLK-6.6 2220/2220] kernel/sched/core.c:11374:5: sparse: sparse: symbol 'tg_set_dynamic_affinity_mode' was not declared. Should it be static?
by kernel test robot 13 May '25
by kernel test robot 13 May '25
13 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: 8c683c781fbd8981b1fabf54cf6eec18190cebdf
commit: 6eb07f9925a906d81f328c808ba25f7800888dce [2220/2220] sched: Introduce smart grid scheduling strategy for cfs
config: x86_64-randconfig-123-20250513 (https://download.01.org/0day-ci/archive/20250513/202505131750.XmCe9Vhu-lkp@…)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250513/202505131750.XmCe9Vhu-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505131750.XmCe9Vhu-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
kernel/sched/core.c:797:48: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected struct task_struct *p @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:797:48: sparse: expected struct task_struct *p
kernel/sched/core.c:797:48: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:1044:38: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct task_struct *curr @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:1044:38: sparse: expected struct task_struct *curr
kernel/sched/core.c:1044:38: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:1103:9: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/core.c:1103:9: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/core.c:1103:9: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/core.c:2233:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct task_struct *p @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:2233:33: sparse: expected struct task_struct *p
kernel/sched/core.c:2233:33: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:2233:68: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct task_struct *tsk @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:2233:68: sparse: expected struct task_struct *tsk
kernel/sched/core.c:2233:68: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:3747:17: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/core.c:3747:17: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/core.c:3747:17: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/core.c:3955:36: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct task_struct const *p @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:3955:36: sparse: expected struct task_struct const *p
kernel/sched/core.c:3955:36: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:9512:43: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct task_struct *push_task @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:9512:43: sparse: expected struct task_struct *push_task
kernel/sched/core.c:9512:43: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:5683:38: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct task_struct *curr @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:5683:38: sparse: expected struct task_struct *curr
kernel/sched/core.c:5683:38: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:6628:14: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct task_struct *prev @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:6628:14: sparse: expected struct task_struct *prev
kernel/sched/core.c:6628:14: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:7153:17: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/core.c:7153:17: sparse: struct task_struct *
kernel/sched/core.c:7153:17: sparse: struct task_struct [noderef] __rcu *
kernel/sched/core.c:7369:22: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/core.c:7369:22: sparse: struct task_struct [noderef] __rcu *
kernel/sched/core.c:7369:22: sparse: struct task_struct *
>> kernel/sched/core.c:11374:5: sparse: sparse: symbol 'tg_set_dynamic_affinity_mode' was not declared. Should it be static?
>> kernel/sched/core.c:11415:5: sparse: sparse: symbol 'tg_set_affinity_period' was not declared. Should it be static?
>> kernel/sched/core.c:11429:5: sparse: sparse: symbol 'tg_get_affinity_period' was not declared. Should it be static?
kernel/sched/core.c:12118:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct task_struct *p @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/core.c:12118:25: sparse: expected struct task_struct *p
kernel/sched/core.c:12118:25: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:551:6: sparse: sparse: context imbalance in 'raw_spin_rq_lock_nested' - wrong count at exit
kernel/sched/core.c:584:23: sparse: sparse: context imbalance in 'raw_spin_rq_trylock' - wrong count at exit
kernel/sched/core.c:600:6: sparse: sparse: context imbalance in 'raw_spin_rq_unlock' - unexpected unlock
kernel/sched/core.c: note: in included file:
kernel/sched/sched.h:1717:9: sparse: sparse: context imbalance in '__task_rq_lock' - wrong count at exit
kernel/sched/sched.h:1717:9: sparse: sparse: context imbalance in 'task_rq_lock' - wrong count at exit
kernel/sched/core.c: note: in included file:
kernel/sched/pelt.h:97:13: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct task_struct const *p @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/pelt.h:97:13: sparse: expected struct task_struct const *p
kernel/sched/pelt.h:97:13: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/core.c:797:11: sparse: sparse: dereference of noderef expression
kernel/sched/core.c:1087:5: sparse: sparse: context imbalance in 'get_nohz_timer_target' - wrong count at exit
kernel/sched/core.c:1482:13: sparse: sparse: context imbalance in 'uclamp_update_util_min_rt_default' - wrong count at exit
kernel/sched/core.c:2224:33: sparse: sparse: dereference of noderef expression
kernel/sched/core.c:2225:19: sparse: sparse: dereference of noderef expression
kernel/sched/core.c:2226:18: sparse: sparse: dereference of noderef expression
kernel/sched/core.c:2286:15: sparse: sparse: context imbalance in 'wait_task_inactive' - different lock contexts for basic block
kernel/sched/core.c: note: in included file:
kernel/sched/sched.h:2244:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2244:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2244:25: sparse: struct task_struct *
kernel/sched/sched.h:2408:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2408:9: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2408:9: sparse: struct task_struct *
kernel/sched/core.c:2199:38: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/core.c:2199:38: sparse: struct task_struct [noderef] __rcu *
kernel/sched/core.c:2199:38: sparse: struct task_struct const *
kernel/sched/sched.h:2244:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2244:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2244:25: sparse: struct task_struct *
kernel/sched/sched.h:2408:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2408:9: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2408:9: sparse: struct task_struct *
kernel/sched/sched.h:2408:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2408:9: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2408:9: sparse: struct task_struct *
kernel/sched/sched.h:2244:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2244:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2244:25: sparse: struct task_struct *
kernel/sched/sched.h:2408:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2408:9: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2408:9: sparse: struct task_struct *
kernel/sched/sched.h:2244:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2244:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2244:25: sparse: struct task_struct *
kernel/sched/sched.h:2408:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2408:9: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2408:9: sparse: struct task_struct *
kernel/sched/sched.h:2244:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2244:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2244:25: sparse: struct task_struct *
kernel/sched/sched.h:2408:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2408:9: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2408:9: sparse: struct task_struct *
kernel/sched/sched.h:2244:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2244:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2244:25: sparse: struct task_struct *
kernel/sched/sched.h:2408:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2408:9: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2408:9: sparse: struct task_struct *
kernel/sched/sched.h:2244:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2244:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2244:25: sparse: struct task_struct *
kernel/sched/sched.h:2408:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2408:9: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2408:9: sparse: struct task_struct *
vim +/tg_set_dynamic_affinity_mode +11374 kernel/sched/core.c
11372
11373 #ifdef CONFIG_QOS_SCHED_SMART_GRID
11374 int tg_set_dynamic_affinity_mode(struct task_group *tg, u64 mode)
11375 {
11376 struct auto_affinity *auto_affi = tg->auto_affinity;
11377
11378 if (unlikely(!auto_affi))
11379 return -EPERM;
11380
11381 /* auto mode */
11382 if (mode == 1)
11383 start_auto_affinity(auto_affi);
11384 else if (mode == 0)
11385 stop_auto_affinity(auto_affi);
11386 else
11387 return -EINVAL;
11388
11389 return 0;
11390 }
11391
11392 static u64 cpu_affinity_mode_read_u64(struct cgroup_subsys_state *css,
11393 struct cftype *cft)
11394 {
11395 struct task_group *tg = css_tg(css);
11396
11397 if (!dynamic_affinity_enabled())
11398 return -EPERM;
11399
11400 if (unlikely(!tg->auto_affinity))
11401 return -EPERM;
11402
11403 return tg->auto_affinity->mode;
11404 }
11405
11406 static int cpu_affinity_mode_write_u64(struct cgroup_subsys_state *css,
11407 struct cftype *cftype, u64 mode)
11408 {
11409 if (!dynamic_affinity_enabled())
11410 return -EPERM;
11411
11412 return tg_set_dynamic_affinity_mode(css_tg(css), mode);
11413 }
11414
11415 int tg_set_affinity_period(struct task_group *tg, u64 period_ms)
11416 {
11417 if (unlikely(!tg->auto_affinity))
11418 return -EPERM;
11419
11420 if (!period_ms || period_ms > U64_MAX / NSEC_PER_MSEC)
11421 return -EINVAL;
11422
11423 raw_spin_lock_irq(&tg->auto_affinity->lock);
11424 tg->auto_affinity->period = ms_to_ktime(period_ms);
11425 raw_spin_unlock_irq(&tg->auto_affinity->lock);
11426 return 0;
11427 }
11428
11429 u64 tg_get_affinity_period(struct task_group *tg)
11430 {
11431 if (unlikely(!tg->auto_affinity))
11432 return -EPERM;
11433
11434 return ktime_to_ms(tg->auto_affinity->period);
11435 }
11436
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0
Haoyu Li (1):
drivers: virt: acrn: hsm: Use kzalloc to avoid info leak in
pmcmd_ioctl
drivers/virt/acrn/hsm.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--
2.25.1
2
2
Nikita Zhandarovich (1):
usb: atm: cxacru: fix a flaw in existing endpoint checks
drivers/usb/atm/cxacru.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
--
2.25.1
2
2

[PATCH OLK-5.10] kvm: x86: fix infinite loop in kvm_guest_time_update when tsc is 0
by Yuntao Liu 13 May '25
by Yuntao Liu 13 May '25
13 May '25
hulk inclusion
category: bugfix
bugzilla: 190614
--------------------------------
Syzkaller testing detected a soft lockup.
watchdog: BUG: soft lockup - CPU#3 stuck for 127s! [syz.1.2088:9817]
Modules linked in:
CPU: 3 PID: 9817 Comm: syz.1.2088 Tainted: G S 6.6.0+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
RIP: 0010:__sanitizer_cov_trace_const_cmp4+0x8/0x20 kernel/kcov.c:313
Code: bf 03 00 00 00 e9 48 fe ff ff 0f 1f 84 00 00 00 00 00 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 48 8b 0c 24 <89> f2 89
fe bf 05 00 00 00 e9 1a fe ff ff 66 2e 0f 1f 84 00 00 00
RSP: 0018:ffff888016d8fad8 EFLAGS: 00000206
RAX: 0000000000080000 RBX: ffff88810e242540 RCX: ffffffff901150d6
RDX: 0000000000080000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffff888016d8fb50 R08: 0000000000000001 R09: ffffed1021c484af
R10: 0000000000000000 R11: 0000000000000277 R12: 0000000000000000
R13: fffffed357281918 R14: 0000000000000000 R15: 0000000000000001
FS: 00007f2a8f6ea6c0(0000) GS:ffff888119780000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000012c56c0 CR3: 000000000dce8001 CR4: 0000000000772ee0
DR0: 0000000000000000 DR1: 0000000000d3eb1c DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
PKRU: 80000000
Call Trace:
<TASK>
kvm_get_time_scale arch/x86/kvm/x86.c:2458 [inline]
kvm_guest_time_update+0x926/0xb00 arch/x86/kvm/x86.c:3268
vcpu_enter_guest.constprop.0+0x1e70/0x3cf0 arch/x86/kvm/x86.c:10678
vcpu_run+0x129/0x8d0 arch/x86/kvm/x86.c:11126
kvm_arch_vcpu_ioctl_run+0x37a/0x13d0 arch/x86/kvm/x86.c:11352
kvm_vcpu_ioctl+0x56b/0xe60 virt/kvm/kvm_main.c:4188
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:871 [inline]
__se_sys_ioctl+0x12d/0x190 fs/ioctl.c:857
do_syscall_x64 arch/x86/entry/common.c:51 [inline]
do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81
entry_SYSCALL_64_after_hwframe+0x78/0xe2
test case:
18.689865147s ago: executing program 1 (id=2088):
r0 = openat$kvm(0xffffffffffffff9c, &(0x7f0000002080), 0x0, 0x0)
r1 = ioctl$KVM_CREATE_VM(r0, 0xae01, 0x0)
r2 = ioctl$KVM_CREATE_VCPU(r1, 0xae41, 0x0)
ioctl$KVM_RUN(r2, 0xae80, 0x0)
ioctl$KVM_SET_TSC_KHZ(r2, 0xaea2, 0x1)
socket$nl_route(0x10, 0x3, 0x0)
r3 = socket$igmp(0x2, 0x3, 0x2)
ioctl$sock_SIOCGIFINDEX(r3, 0x8933, &(0x7f00000001c0)={'netdevsim0\x00',
<r4=>0x0})
r5 = bpf$MAP_CREATE(0x0, &(0x7f0000000140)=@base={0x1, 0x4, 0x8000, 0x2,
0x0, 0xffffffffffffffff, 0x0, '\x00', r4, 0xffffffffffffffff, 0x0, 0x0,
0x0, 0x0, @void, @value, @void, @value}, 0x50)
bpf$MAP_UPDATE_CONST_STR(0x2, &(0x7f0000000100)={{r5},
&(0x7f0000000000), &(0x7f0000000040)='%ps \x00'}, 0x20)
bpf$MAP_DELETE_ELEM(0x3, &(0x7f00000000c0)={r5, &(0x7f0000001480)},
0x20)
ioctl$KVM_SET_USER_MEMORY_REGION(r1, 0x4020ae46,
&(0x7f0000000000)={0x1ff, 0x3, 0x3000, 0x1000,
&(0x7f0000fec000/0x1000)=nil})
syz_kvm_setup_cpu$x86(r1, 0xffffffffffffffff,
&(0x7f0000fe8000/0x18000)=nil, &(0x7f0000000100)=[@textreal={0x8, 0x0}],
0x1, 0x0, 0x0, 0x0)
ioctl$KVM_SET_USER_MEMORY_REGION(0xffffffffffffffff, 0x4020ae46, 0x0)
openat$ipvs(0xffffffffffffff9c, 0x0, 0x2, 0x0)
syz_kvm_setup_cpu$x86(0xffffffffffffffff, r2,
&(0x7f0000fe8000/0x18000)=nil, &(0x7f00000000c0)=[@text64={0x40,
&(0x7f0000000040)="26f2a70f3548b807000000000000000f23c00f21f835020008000f23f80fc73eb9330800000f326666470f3880be6cc468550f01cf360f01f80f30450f01c9",
0x3f}], 0x1, 0x0, 0x0, 0x0)
ioctl$KVM_RUN(r2, 0xae80, 0x0)
ioctl$KVM_SET_TSC_KHZ(r2, 0xaea2, 0x1)
user_tsc_khz = 0x1
|
kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz)
|
ioctl$KVM_RUN(r2, 0xae80, 0x0)
|
...
kvm_guest_time_update(struct kvm_vcpu *v)
|
if (kvm_caps.has_tsc_control)
tgt_tsc_khz = kvm_scale_tsc(tgt_tsc_khz,
v->arch.l1_tsc_scaling_ratio);
|
kvm_scale_tsc(u64 tsc, u64 ratio)
|
__scale_tsc(u64 ratio, u64 tsc)
ratio=122380531, tsc=2299998, N=48
ratio*tsc >> N = 0.999... -> 0
|
kvm_get_time_scale
In function __scale_tsc, it uses fixed point number to calculate
tsc, therefore, a certain degree of precision is lost, the actual tsc
value of 0.999... would be 0. In function kvm_get_time_scale
tps32=tps64=base_hz=0, would lead second while_loop infinite. when
CONFIG_PREEMPT is n, it causes a soft lockup issue.
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
arch/x86/kvm/x86.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index d2d206ff6462..e9266a91e84e 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2428,10 +2428,13 @@ static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
* point number (mult + frac * 2^(-N)).
*
* N equals to kvm_tsc_scaling_ratio_frac_bits.
+ *
+ * return 1 if _tsc is 0.
*/
static inline u64 __scale_tsc(u64 ratio, u64 tsc)
{
- return mul_u64_u64_shr(tsc, ratio, kvm_tsc_scaling_ratio_frac_bits);
+ u64 _tsc = mul_u64_u64_shr(tsc, ratio, kvm_tsc_scaling_ratio_frac_bits);
+ return !_tsc ? 1 : _tsc;
}
u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc)
--
2.34.1
2
1
motorcomm NIC team
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IBFE17
CVE: NA
--------------------------------
1. Add Motorcomm yt6801 PCIe Gigabit ethernet driver.
2. Add myself as the maintainer for the motorcomm ethernet driver.
3. Add yt6801 and MOTORCOMM_PHY in openeuler_defconfig
Signed-off-by: Frank_Sae <Frank.Sae(a)motor-comm.com>
---
MAINTAINERS | 7 +
arch/arm64/configs/openeuler_defconfig | 4 +-
arch/loongarch/configs/loongson3_defconfig | 3 +
arch/powerpc/configs/openeuler_defconfig | 4 +-
arch/riscv/configs/openeuler_defconfig | 4 +-
arch/x86/configs/openeuler_defconfig | 4 +-
drivers/net/ethernet/Kconfig | 1 +
drivers/net/ethernet/Makefile | 1 +
drivers/net/ethernet/motorcomm/Kconfig | 27 +
drivers/net/ethernet/motorcomm/Makefile | 6 +
.../net/ethernet/motorcomm/yt6801/Makefile | 8 +
.../ethernet/motorcomm/yt6801/yt6801_desc.c | 565 +++
.../ethernet/motorcomm/yt6801/yt6801_desc.h | 35 +
.../ethernet/motorcomm/yt6801/yt6801_main.c | 3020 +++++++++++++++++
.../ethernet/motorcomm/yt6801/yt6801_type.h | 961 ++++++
drivers/net/phy/motorcomm.c | 6 +
16 files changed, 4652 insertions(+), 4 deletions(-)
create mode 100644 drivers/net/ethernet/motorcomm/Kconfig
create mode 100644 drivers/net/ethernet/motorcomm/Makefile
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/Makefile
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.c
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.h
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_main.c
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_type.h
diff --git a/MAINTAINERS b/MAINTAINERS
index c6a3ac619..30cfe2988 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14553,6 +14553,13 @@ F: drivers/most/
F: drivers/staging/most/
F: include/linux/most.h
+MOTORCOMM ETHERNET DRIVER
+M: Frank <Frank.Sae(a)motor-comm.com>
+L: netdev(a)vger.kernel.org
+S: Maintained
+W: https://www.motor-comm.com/
+F: drivers/net/ethernet/motorcomm/*
+
MOTORCOMM PHY DRIVER
M: Peter Geis <pgwipeout(a)gmail.com>
M: Frank <Frank.Sae(a)motor-comm.com>
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig
index 7481b1293..563ef3bf4 100644
--- a/arch/arm64/configs/openeuler_defconfig
+++ b/arch/arm64/configs/openeuler_defconfig
@@ -3036,6 +3036,8 @@ CONFIG_MLXFW=m
CONFIG_NET_VENDOR_MICROSEMI=y
# CONFIG_MSCC_OCELOT_SWITCH is not set
CONFIG_NET_VENDOR_MICROSOFT=y
+CONFIG_NET_VENDOR_MOTORCOMM=y
+CONFIG_YT6801=m
CONFIG_NET_VENDOR_MYRI=y
# CONFIG_MYRI10GE is not set
# CONFIG_FEALNX is not set
@@ -3165,7 +3167,7 @@ CONFIG_MICREL_PHY=m
CONFIG_MICROCHIP_PHY=m
# CONFIG_MICROCHIP_T1_PHY is not set
# CONFIG_MICROSEMI_PHY is not set
-# CONFIG_MOTORCOMM_PHY is not set
+CONFIG_MOTORCOMM_PHY=m
CONFIG_NATIONAL_PHY=m
# CONFIG_NXP_CBTX_PHY is not set
# CONFIG_NXP_C45_TJA11XX_PHY is not set
diff --git a/arch/loongarch/configs/loongson3_defconfig b/arch/loongarch/configs/loongson3_defconfig
index 106b20292..0ec1d967c 100644
--- a/arch/loongarch/configs/loongson3_defconfig
+++ b/arch/loongarch/configs/loongson3_defconfig
@@ -858,6 +858,8 @@ CONFIG_MLXSW_CORE=m
# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_MICROCHIP is not set
# CONFIG_NET_VENDOR_MICROSEMI is not set
+CONFIG_NET_VENDOR_MOTORCOMM=y
+CONFIG_YT6801=m
# CONFIG_NET_VENDOR_MYRI is not set
# CONFIG_NET_VENDOR_NI is not set
# CONFIG_NET_VENDOR_NATSEMI is not set
@@ -913,6 +915,7 @@ CONFIG_MARVELL_10G_PHY=y
CONFIG_MICREL_PHY=m
CONFIG_MICROCHIP_T1_PHY=m
CONFIG_MICROSEMI_PHY=m
+CONFIG_MOTORCOMM_PHY=m
CONFIG_NATIONAL_PHY=m
CONFIG_QSEMI_PHY=m
CONFIG_RENESAS_PHY=m
diff --git a/arch/powerpc/configs/openeuler_defconfig b/arch/powerpc/configs/openeuler_defconfig
index 0c143a279..69286cb35 100644
--- a/arch/powerpc/configs/openeuler_defconfig
+++ b/arch/powerpc/configs/openeuler_defconfig
@@ -2557,6 +2557,8 @@ CONFIG_NET_VENDOR_MICROCHIP=y
CONFIG_NET_VENDOR_MICROSEMI=y
# CONFIG_MSCC_OCELOT_SWITCH is not set
CONFIG_NET_VENDOR_MICROSOFT=y
+CONFIG_NET_VENDOR_MOTORCOMM=y
+CONFIG_YT6801=m
CONFIG_NET_VENDOR_MYRI=y
CONFIG_MYRI10GE=m
# CONFIG_FEALNX is not set
@@ -2681,7 +2683,7 @@ CONFIG_MICREL_PHY=m
# CONFIG_MICROCHIP_PHY is not set
# CONFIG_MICROCHIP_T1_PHY is not set
# CONFIG_MICROSEMI_PHY is not set
-# CONFIG_MOTORCOMM_PHY is not set
+CONFIG_MOTORCOMM_PHY=m
CONFIG_NATIONAL_PHY=m
# CONFIG_NXP_C45_TJA11XX_PHY is not set
# CONFIG_NXP_TJA11XX_PHY is not set
diff --git a/arch/riscv/configs/openeuler_defconfig b/arch/riscv/configs/openeuler_defconfig
index 61f2b2f12..ca72545c1 100644
--- a/arch/riscv/configs/openeuler_defconfig
+++ b/arch/riscv/configs/openeuler_defconfig
@@ -2506,6 +2506,8 @@ CONFIG_MLXFW=m
CONFIG_NET_VENDOR_MICROSEMI=y
# CONFIG_MSCC_OCELOT_SWITCH is not set
CONFIG_NET_VENDOR_MICROSOFT=y
+CONFIG_NET_VENDOR_MOTORCOMM=y
+CONFIG_YT6801=m
CONFIG_NET_VENDOR_MYRI=y
# CONFIG_MYRI10GE is not set
# CONFIG_FEALNX is not set
@@ -2627,7 +2629,7 @@ CONFIG_MICREL_PHY=m
CONFIG_MICROCHIP_PHY=m
# CONFIG_MICROCHIP_T1_PHY is not set
CONFIG_MICROSEMI_PHY=m
-# CONFIG_MOTORCOMM_PHY is not set
+CONFIG_MOTORCOMM_PHY=m
CONFIG_NATIONAL_PHY=m
# CONFIG_NXP_CBTX_PHY is not set
# CONFIG_NXP_C45_TJA11XX_PHY is not set
diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig
index 84d771bec..9d86489a5 100644
--- a/arch/x86/configs/openeuler_defconfig
+++ b/arch/x86/configs/openeuler_defconfig
@@ -3026,6 +3026,8 @@ CONFIG_MLXFW=m
# CONFIG_NET_VENDOR_MICROSEMI is not set
CONFIG_NET_VENDOR_MICROSOFT=y
# CONFIG_MICROSOFT_MANA is not set
+CONFIG_NET_VENDOR_MOTORCOMM=y
+CONFIG_YT6801=m
CONFIG_NET_VENDOR_MYRI=y
CONFIG_MYRI10GE=m
CONFIG_MYRI10GE_DCA=y
@@ -3153,7 +3155,7 @@ CONFIG_MICREL_PHY=m
CONFIG_MICROCHIP_PHY=m
CONFIG_MICROCHIP_T1_PHY=m
CONFIG_MICROSEMI_PHY=m
-# CONFIG_MOTORCOMM_PHY is not set
+CONFIG_MOTORCOMM_PHY=m
CONFIG_NATIONAL_PHY=m
# CONFIG_NXP_CBTX_PHY is not set
# CONFIG_NXP_C45_TJA11XX_PHY is not set
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index 9cf6f1c67..f18cd4a57 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -133,6 +133,7 @@ source "drivers/net/ethernet/micrel/Kconfig"
source "drivers/net/ethernet/microchip/Kconfig"
source "drivers/net/ethernet/mscc/Kconfig"
source "drivers/net/ethernet/microsoft/Kconfig"
+source "drivers/net/ethernet/motorcomm/Kconfig"
source "drivers/net/ethernet/moxa/Kconfig"
source "drivers/net/ethernet/myricom/Kconfig"
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
index 328f6c44e..e3d013997 100644
--- a/drivers/net/ethernet/Makefile
+++ b/drivers/net/ethernet/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_NET_VENDOR_MELLANOX) += mellanox/
obj-$(CONFIG_NET_VENDOR_MICREL) += micrel/
obj-$(CONFIG_NET_VENDOR_MICROCHIP) += microchip/
obj-$(CONFIG_NET_VENDOR_MICROSEMI) += mscc/
+obj-$(CONFIG_NET_VENDOR_MOTORCOMM) += motorcomm/
obj-$(CONFIG_NET_VENDOR_MOXART) += moxa/
obj-$(CONFIG_NET_VENDOR_MYRI) += myricom/
obj-$(CONFIG_FEALNX) += fealnx.o
diff --git a/drivers/net/ethernet/motorcomm/Kconfig b/drivers/net/ethernet/motorcomm/Kconfig
new file mode 100644
index 000000000..abcc6cbcc
--- /dev/null
+++ b/drivers/net/ethernet/motorcomm/Kconfig
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Motorcomm network device configuration
+#
+
+config NET_VENDOR_MOTORCOMM
+ bool "Motorcomm devices"
+ default y
+ help
+ If you have a network (Ethernet) device belonging to this class,
+ say Y.
+
+ Note that the answer to this question doesn't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the questions about Motorcomm devices. If you say Y, you will be
+ asked for your specific device in the following questions.
+
+if NET_VENDOR_MOTORCOMM
+
+config YT6801
+ tristate "Motorcomm(R) 6801 PCI-Express Gigabit Ethernet support"
+ depends on PCI && NET
+ help
+ This driver supports Motorcomm(R) 6801 gigabit ethernet family of
+ adapters.
+
+endif # NET_VENDOR_MOTORCOMM
diff --git a/drivers/net/ethernet/motorcomm/Makefile b/drivers/net/ethernet/motorcomm/Makefile
new file mode 100644
index 000000000..511940680
--- /dev/null
+++ b/drivers/net/ethernet/motorcomm/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the Motorcomm network device drivers.
+#
+
+obj-$(CONFIG_YT6801) += yt6801/
diff --git a/drivers/net/ethernet/motorcomm/yt6801/Makefile b/drivers/net/ethernet/motorcomm/yt6801/Makefile
new file mode 100644
index 000000000..727866237
--- /dev/null
+++ b/drivers/net/ethernet/motorcomm/yt6801/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2021 Motor-comm Corporation.
+#
+# Makefile for the Motorcomm(R) 6801 PCI-Express ethernet driver
+#
+
+obj-$(CONFIG_YT6801) += yt6801.o
+yt6801-objs := yt6801_desc.o yt6801_main.o
diff --git a/drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.c b/drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.c
new file mode 100644
index 000000000..42aa7d694
--- /dev/null
+++ b/drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.c
@@ -0,0 +1,565 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Copyright (c) 2022 - 2024 Motorcomm Electronic Technology Co.,Ltd. */
+
+#include "yt6801_type.h"
+#include "yt6801_desc.h"
+
+void fxgmac_desc_data_unmap(struct fxgmac_pdata *priv,
+ struct fxgmac_desc_data *desc_data)
+{
+ if (desc_data->skb_dma) {
+ if (desc_data->mapped_as_page) {
+ dma_unmap_page(priv->dev, desc_data->skb_dma,
+ desc_data->skb_dma_len, DMA_TO_DEVICE);
+ } else {
+ dma_unmap_single(priv->dev, desc_data->skb_dma,
+ desc_data->skb_dma_len, DMA_TO_DEVICE);
+ }
+ desc_data->skb_dma = 0;
+ desc_data->skb_dma_len = 0;
+ }
+
+ if (desc_data->skb) {
+ dev_kfree_skb_any(desc_data->skb);
+ desc_data->skb = NULL;
+ }
+
+ if (desc_data->rx.hdr.pa.pages)
+ put_page(desc_data->rx.hdr.pa.pages);
+
+ if (desc_data->rx.hdr.pa_unmap.pages) {
+ dma_unmap_page(priv->dev, desc_data->rx.hdr.pa_unmap.pages_dma,
+ desc_data->rx.hdr.pa_unmap.pages_len,
+ DMA_FROM_DEVICE);
+ put_page(desc_data->rx.hdr.pa_unmap.pages);
+ }
+
+ if (desc_data->rx.buf.pa.pages)
+ put_page(desc_data->rx.buf.pa.pages);
+
+ if (desc_data->rx.buf.pa_unmap.pages) {
+ dma_unmap_page(priv->dev, desc_data->rx.buf.pa_unmap.pages_dma,
+ desc_data->rx.buf.pa_unmap.pages_len,
+ DMA_FROM_DEVICE);
+ put_page(desc_data->rx.buf.pa_unmap.pages);
+ }
+ memset(&desc_data->tx, 0, sizeof(desc_data->tx));
+ memset(&desc_data->rx, 0, sizeof(desc_data->rx));
+
+ desc_data->mapped_as_page = 0;
+}
+
+static int fxgmac_ring_init(struct fxgmac_pdata *priv, struct fxgmac_ring *ring,
+ unsigned int dma_desc_count)
+{
+ /* Descriptors */
+ ring->dma_desc_count = dma_desc_count;
+ ring->dma_desc_head =
+ dma_alloc_coherent(priv->dev, (sizeof(struct fxgmac_dma_desc) *
+ dma_desc_count),
+ &ring->dma_desc_head_addr, GFP_KERNEL);
+ if (!ring->dma_desc_head)
+ return -ENOMEM;
+
+ /* Array of descriptor data */
+ ring->desc_data_head = kcalloc(dma_desc_count,
+ sizeof(struct fxgmac_desc_data),
+ GFP_KERNEL);
+ if (!ring->desc_data_head)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void fxgmac_ring_free(struct fxgmac_pdata *priv,
+ struct fxgmac_ring *ring)
+{
+ if (!ring)
+ return;
+
+ if (ring->desc_data_head) {
+ for (u32 i = 0; i < ring->dma_desc_count; i++)
+ fxgmac_desc_data_unmap(priv,
+ FXGMAC_GET_DESC_DATA(ring, i));
+
+ kfree(ring->desc_data_head);
+ ring->desc_data_head = NULL;
+ }
+
+ if (ring->rx_hdr_pa.pages) {
+ dma_unmap_page(priv->dev, ring->rx_hdr_pa.pages_dma,
+ ring->rx_hdr_pa.pages_len, DMA_FROM_DEVICE);
+ put_page(ring->rx_hdr_pa.pages);
+
+ ring->rx_hdr_pa.pages = NULL;
+ ring->rx_hdr_pa.pages_len = 0;
+ ring->rx_hdr_pa.pages_offset = 0;
+ ring->rx_hdr_pa.pages_dma = 0;
+ }
+
+ if (ring->rx_buf_pa.pages) {
+ dma_unmap_page(priv->dev, ring->rx_buf_pa.pages_dma,
+ ring->rx_buf_pa.pages_len, DMA_FROM_DEVICE);
+ put_page(ring->rx_buf_pa.pages);
+
+ ring->rx_buf_pa.pages = NULL;
+ ring->rx_buf_pa.pages_len = 0;
+ ring->rx_buf_pa.pages_offset = 0;
+ ring->rx_buf_pa.pages_dma = 0;
+ }
+ if (ring->dma_desc_head) {
+ dma_free_coherent(priv->dev, (sizeof(struct fxgmac_dma_desc) *
+ ring->dma_desc_count), ring->dma_desc_head,
+ ring->dma_desc_head_addr);
+ ring->dma_desc_head = NULL;
+ }
+}
+
+static void fxgmac_rings_free(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ fxgmac_ring_free(priv, channel->tx_ring);
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ fxgmac_ring_free(priv, channel->rx_ring);
+}
+
+static int fxgmac_rings_alloc(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ int ret;
+
+ ret = fxgmac_ring_init(priv, channel->tx_ring, priv->tx_desc_count);
+ if (ret < 0) {
+ dev_err(priv->dev, "Initializing Tx ring failed");
+ goto err_init_ring;
+ }
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++) {
+ ret = fxgmac_ring_init(priv, channel->rx_ring,
+ priv->rx_desc_count);
+ if (ret < 0) {
+ dev_err(priv->dev, "Initializing Rx ring failed\n");
+ goto err_init_ring;
+ }
+ }
+ return 0;
+
+err_init_ring:
+ fxgmac_rings_free(priv);
+ return ret;
+}
+
+static void fxgmac_channels_free(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ kfree(channel->tx_ring);
+ channel->tx_ring = NULL;
+
+ kfree(channel->rx_ring);
+ channel->rx_ring = NULL;
+
+ kfree(channel);
+ priv->channel_head = NULL;
+}
+
+void fxgmac_channels_rings_free(struct fxgmac_pdata *priv)
+{
+ fxgmac_rings_free(priv);
+ fxgmac_channels_free(priv);
+}
+
+static void fxgmac_set_msix_tx_irq(struct fxgmac_pdata *priv,
+ struct fxgmac_channel *channel)
+{
+ priv->channel_irq[FXGMAC_MAX_DMA_RX_CHANNELS] =
+ priv->msix_entries[FXGMAC_MAX_DMA_RX_CHANNELS].vector;
+ channel->dma_irq_tx = priv->channel_irq[FXGMAC_MAX_DMA_RX_CHANNELS];
+}
+
+static int fxgmac_channels_alloc(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel_head, *channel;
+ struct fxgmac_ring *tx_ring, *rx_ring;
+ int ret = -ENOMEM;
+
+ channel_head = kcalloc(priv->channel_count,
+ sizeof(struct fxgmac_channel), GFP_KERNEL);
+
+ if (!channel_head)
+ return ret;
+
+ tx_ring = kcalloc(FXGMAC_TX_1_RING, sizeof(struct fxgmac_ring),
+ GFP_KERNEL);
+ if (!tx_ring)
+ goto err_tx_ring;
+
+ rx_ring = kcalloc(priv->rx_ring_count, sizeof(struct fxgmac_ring),
+ GFP_KERNEL);
+ if (!rx_ring)
+ goto err_rx_ring;
+
+ channel = channel_head;
+ for (u32 i = 0; i < priv->channel_count; i++, channel++) {
+ snprintf(channel->name, sizeof(channel->name), "channel-%u", i);
+ channel->priv = priv;
+ channel->queue_index = i;
+ channel->dma_regs = (priv)->hw_addr + DMA_CH_BASE +
+ (DMA_CH_INC * i);
+
+ if (priv->per_channel_irq) {
+ priv->channel_irq[i] = priv->msix_entries[i].vector;
+
+ if (IS_ENABLED(CONFIG_PCI_MSI) && i < FXGMAC_TX_1_RING)
+ fxgmac_set_msix_tx_irq(priv, channel);
+
+ /* Get the per DMA rx interrupt */
+ ret = priv->channel_irq[i];
+ if (ret < 0) {
+ dev_err(priv->dev, "channel irq[%u] failed\n",
+ i + 1);
+ goto err_irq;
+ }
+
+ channel->dma_irq_rx = ret;
+ }
+
+ if (i < FXGMAC_TX_1_RING)
+ channel->tx_ring = tx_ring++;
+
+ if (i < priv->rx_ring_count)
+ channel->rx_ring = rx_ring++;
+ }
+
+ priv->channel_head = channel_head;
+ return 0;
+
+err_irq:
+ kfree(rx_ring);
+
+err_rx_ring:
+ kfree(tx_ring);
+
+err_tx_ring:
+ kfree(channel_head);
+
+ dev_err(priv->dev, "%s failed:%d\n", __func__, ret);
+ return ret;
+}
+
+int fxgmac_channels_rings_alloc(struct fxgmac_pdata *priv)
+{
+ int ret;
+
+ ret = fxgmac_channels_alloc(priv);
+ if (ret < 0)
+ goto err_alloc;
+
+ ret = fxgmac_rings_alloc(priv);
+ if (ret < 0)
+ goto err_alloc;
+
+ return 0;
+
+err_alloc:
+ fxgmac_channels_rings_free(priv);
+ return ret;
+}
+
+static void fxgmac_set_buffer_data(struct fxgmac_buffer_data *bd,
+ struct fxgmac_page_alloc *pa,
+ unsigned int len)
+{
+ get_page(pa->pages);
+ bd->pa = *pa;
+
+ bd->dma_base = pa->pages_dma;
+ bd->dma_off = pa->pages_offset;
+ bd->dma_len = len;
+
+ pa->pages_offset += len;
+ if ((pa->pages_offset + len) > pa->pages_len) {
+ /* This data descriptor is responsible for unmapping page(s) */
+ bd->pa_unmap = *pa;
+
+ /* Get a new allocation next time */
+ pa->pages = NULL;
+ pa->pages_len = 0;
+ pa->pages_offset = 0;
+ pa->pages_dma = 0;
+ }
+}
+
+static int fxgmac_alloc_pages(struct fxgmac_pdata *priv,
+ struct fxgmac_page_alloc *pa, gfp_t gfp,
+ int order)
+{
+ struct page *pages = NULL;
+ dma_addr_t pages_dma;
+
+ /* Try to obtain pages, decreasing order if necessary */
+ gfp |= __GFP_COMP | __GFP_NOWARN;
+ while (order >= 0) {
+ pages = alloc_pages(gfp, order);
+ if (pages)
+ break;
+
+ order--;
+ }
+
+ if (!pages)
+ return -ENOMEM;
+
+ /* Map the pages */
+ pages_dma = dma_map_page(priv->dev, pages, 0, PAGE_SIZE << order,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(priv->dev, pages_dma)) {
+ put_page(pages);
+ return -ENOMEM;
+ }
+
+ pa->pages = pages;
+ pa->pages_len = PAGE_SIZE << order;
+ pa->pages_offset = 0;
+ pa->pages_dma = pages_dma;
+
+ return 0;
+}
+
+#define FXGMAC_SKB_ALLOC_SIZE 512
+
+int fxgmac_rx_buffe_map(struct fxgmac_pdata *priv, struct fxgmac_ring *ring,
+ struct fxgmac_desc_data *desc_data)
+{
+ int ret;
+
+ if (!ring->rx_hdr_pa.pages) {
+ ret = fxgmac_alloc_pages(priv, &ring->rx_hdr_pa, GFP_ATOMIC, 0);
+ if (ret)
+ return ret;
+ }
+ /* Set up the header page info */
+ fxgmac_set_buffer_data(&desc_data->rx.hdr, &ring->rx_hdr_pa,
+ priv->rx_buf_size);
+
+ return 0;
+}
+
+void fxgmac_desc_tx_reset(struct fxgmac_desc_data *desc_data)
+{
+ struct fxgmac_dma_desc *dma_desc = desc_data->dma_desc;
+
+ /* Reset the Tx descriptor
+ * Set buffer 1 (lo) address to zero
+ * Set buffer 1 (hi) address to zero
+ * Reset all other control bits (IC, TTSE, B2L & B1L)
+ * Reset all other control bits (OWN, CTXT, FD, LD, CPC, CIC, etc)
+ */
+ dma_desc->desc0 = 0;
+ dma_desc->desc1 = 0;
+ dma_desc->desc2 = 0;
+ dma_desc->desc3 = 0;
+
+ /* Make sure ownership is written to the descriptor */
+ dma_wmb();
+}
+
+void fxgmac_desc_rx_reset(struct fxgmac_desc_data *desc_data)
+{
+ struct fxgmac_dma_desc *dma_desc = desc_data->dma_desc;
+ dma_addr_t hdr_dma;
+
+ /* Reset the Rx descriptor
+ * Set buffer 1 (lo) address to header dma address (lo)
+ * Set buffer 1 (hi) address to header dma address (hi)
+ * set control bits OWN and INTE
+ */
+ hdr_dma = desc_data->rx.hdr.dma_base + desc_data->rx.hdr.dma_off;
+ dma_desc->desc0 = cpu_to_le32(lower_32_bits(hdr_dma));
+ dma_desc->desc1 = cpu_to_le32(upper_32_bits(hdr_dma));
+ dma_desc->desc2 = 0;
+ dma_desc->desc3 = 0;
+ fxgmac_desc_wr_bits(&dma_desc->desc3, RX_DESC3_INTE, 1);
+ fxgmac_desc_wr_bits(&dma_desc->desc3, RX_DESC3_BUF2V, 0);
+ fxgmac_desc_wr_bits(&dma_desc->desc3, RX_DESC3_BUF1V, 1);
+
+ /* Since the Rx DMA engine is likely running, make sure everything
+ * is written to the descriptor(s) before setting the OWN bit
+ * for the descriptor
+ */
+ dma_wmb();
+
+ fxgmac_desc_wr_bits(&dma_desc->desc3, RX_DESC3_OWN, 1);
+
+ /* Make sure ownership is written to the descriptor */
+ dma_wmb();
+}
+
+int fxgmac_tx_skb_map(struct fxgmac_channel *channel, struct sk_buff *skb)
+{
+ struct fxgmac_pdata *priv = channel->priv;
+ struct fxgmac_ring *ring = channel->tx_ring;
+ unsigned int start_index, cur_index;
+ struct fxgmac_desc_data *desc_data;
+ unsigned int offset, datalen, len;
+ struct fxgmac_pkt_info *pkt_info;
+ unsigned int tso, vlan;
+ dma_addr_t skb_dma;
+ skb_frag_t *frag;
+
+ offset = 0;
+ start_index = ring->cur;
+ cur_index = ring->cur;
+ pkt_info = &ring->pkt_info;
+ pkt_info->desc_count = 0;
+ pkt_info->length = 0;
+
+ tso = field_get(ATTR_TX_TSO_ENABLE, pkt_info->attr);
+ vlan = field_get(ATTR_TX_VLAN_CTAG, pkt_info->attr);
+
+ /* Save space for a context descriptor if needed */
+ if ((tso && pkt_info->mss != ring->tx.cur_mss) ||
+ (vlan && pkt_info->vlan_ctag != ring->tx.cur_vlan_ctag))
+ cur_index = FXGMAC_GET_ENTRY(cur_index, ring->dma_desc_count);
+
+ desc_data = FXGMAC_GET_DESC_DATA(ring, cur_index);
+
+ if (tso) {
+ /* Map the TSO header */
+ skb_dma = dma_map_single(priv->dev, skb->data,
+ pkt_info->header_len, DMA_TO_DEVICE);
+ if (dma_mapping_error(priv->dev, skb_dma)) {
+ dev_err(priv->dev, "dma map single failed\n");
+ goto err_out;
+ }
+ desc_data->skb_dma = skb_dma;
+ desc_data->skb_dma_len = pkt_info->header_len;
+
+ offset = pkt_info->header_len;
+ pkt_info->length += pkt_info->header_len;
+
+ cur_index = FXGMAC_GET_ENTRY(cur_index, ring->dma_desc_count);
+ desc_data = FXGMAC_GET_DESC_DATA(ring, cur_index);
+ }
+
+ /* Map the (remainder of the) packet */
+ for (datalen = skb_headlen(skb) - offset; datalen;) {
+ len = min_t(unsigned int, datalen, FXGMAC_TX_MAX_BUF_SIZE);
+ skb_dma = dma_map_single(priv->dev, skb->data + offset, len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(priv->dev, skb_dma)) {
+ dev_err(priv->dev, "dma map single failed\n");
+ goto err_out;
+ }
+ desc_data->skb_dma = skb_dma;
+ desc_data->skb_dma_len = len;
+
+ datalen -= len;
+ offset += len;
+ pkt_info->length += len;
+
+ cur_index = FXGMAC_GET_ENTRY(cur_index, ring->dma_desc_count);
+ desc_data = FXGMAC_GET_DESC_DATA(ring, cur_index);
+ }
+
+ for (u32 i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ frag = &skb_shinfo(skb)->frags[i];
+ offset = 0;
+
+ for (datalen = skb_frag_size(frag); datalen;) {
+ len = min_t(unsigned int, datalen,
+ FXGMAC_TX_MAX_BUF_SIZE);
+ skb_dma = skb_frag_dma_map(priv->dev, frag, offset, len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(priv->dev, skb_dma)) {
+ dev_err(priv->dev, "skb frag dma map failed\n");
+ goto err_out;
+ }
+ desc_data->skb_dma = skb_dma;
+ desc_data->skb_dma_len = len;
+ desc_data->mapped_as_page = 1;
+
+ datalen -= len;
+ offset += len;
+ pkt_info->length += len;
+
+ cur_index = FXGMAC_GET_ENTRY(cur_index,
+ ring->dma_desc_count);
+ desc_data = FXGMAC_GET_DESC_DATA(ring, cur_index);
+ }
+ }
+
+ /* Save the skb address in the last entry. We always have some data
+ * that has been mapped so desc_data is always advanced past the last
+ * piece of mapped data - use the entry pointed to by cur_index - 1.
+ */
+ desc_data = FXGMAC_GET_DESC_DATA(ring, (cur_index - 1) &
+ (ring->dma_desc_count - 1));
+ desc_data->skb = skb;
+
+ /* Save the number of descriptor entries used */
+ if (start_index <= cur_index)
+ pkt_info->desc_count = cur_index - start_index;
+ else
+ pkt_info->desc_count =
+ ring->dma_desc_count - start_index + cur_index;
+
+ return pkt_info->desc_count;
+
+err_out:
+ while (start_index < cur_index) {
+ desc_data = FXGMAC_GET_DESC_DATA(ring, start_index);
+ start_index =
+ FXGMAC_GET_ENTRY(start_index, ring->dma_desc_count);
+ fxgmac_desc_data_unmap(priv, desc_data);
+ }
+
+ return 0;
+}
+
+void fxgmac_dump_rx_desc(struct fxgmac_pdata *priv, struct fxgmac_ring *ring,
+ unsigned int idx)
+{
+ struct fxgmac_desc_data *desc_data;
+ struct fxgmac_dma_desc *dma_desc;
+
+ desc_data = FXGMAC_GET_DESC_DATA(ring, idx);
+ dma_desc = desc_data->dma_desc;
+ dev_dbg(priv->dev, "RX: dma_desc=%p, dma_desc_addr=%pad, RX_DESC[%d RX BY DEVICE] = %08x:%08x:%08x:%08x\n\n",
+ dma_desc, &desc_data->dma_desc_addr, idx,
+ le32_to_cpu(dma_desc->desc0), le32_to_cpu(dma_desc->desc1),
+ le32_to_cpu(dma_desc->desc2), le32_to_cpu(dma_desc->desc3));
+}
+
+void fxgmac_dump_tx_desc(struct fxgmac_pdata *priv, struct fxgmac_ring *ring,
+ unsigned int idx, unsigned int count,
+ unsigned int flag)
+{
+ struct fxgmac_desc_data *desc_data;
+
+ while (count--) {
+ desc_data = FXGMAC_GET_DESC_DATA(ring, idx);
+ dev_dbg(priv->dev, "TX: dma_desc=%p, dma_desc_addr=%pad, TX_DESC[%d %s] = %08x:%08x:%08x:%08x\n",
+ desc_data->dma_desc, &desc_data->dma_desc_addr, idx,
+ (flag == 1) ? "QUEUED FOR TX" : "TX BY DEVICE",
+ le32_to_cpu(desc_data->dma_desc->desc0),
+ le32_to_cpu(desc_data->dma_desc->desc1),
+ le32_to_cpu(desc_data->dma_desc->desc2),
+ le32_to_cpu(desc_data->dma_desc->desc3));
+
+ idx++;
+ }
+}
+
+int fxgmac_is_tx_complete(struct fxgmac_dma_desc *dma_desc)
+{
+ return !fxgmac_desc_rd_bits(dma_desc->desc3, TX_DESC3_OWN);
+}
+
+int fxgmac_is_last_desc(struct fxgmac_dma_desc *dma_desc)
+{
+ /* Rx and Tx share LD bit, so check TDES3.LD bit */
+ return fxgmac_desc_rd_bits(dma_desc->desc3, TX_DESC3_LD);
+}
diff --git a/drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.h b/drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.h
new file mode 100644
index 000000000..b238f20be
--- /dev/null
+++ b/drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* Copyright (c) 2022 - 2024 Motorcomm Electronic Technology Co.,Ltd. */
+
+#ifndef YT6801_DESC_H
+#define YT6801_DESC_H
+
+#define FXGMAC_TX_DESC_CNT 256
+#define FXGMAC_TX_DESC_MIN_FREE (FXGMAC_TX_DESC_CNT >> 3)
+#define FXGMAC_TX_DESC_MAX_PROC (FXGMAC_TX_DESC_CNT >> 1)
+#define FXGMAC_RX_DESC_CNT 1024
+#define FXGMAC_RX_DESC_MAX_DIRTY (FXGMAC_RX_DESC_CNT >> 3)
+
+#define FXGMAC_GET_DESC_DATA(ring, idx) ((ring)->desc_data_head + (idx))
+#define FXGMAC_GET_ENTRY(x, size) (((x) + 1) & ((size) - 1))
+
+void fxgmac_desc_tx_reset(struct fxgmac_desc_data *desc_data);
+void fxgmac_desc_rx_reset(struct fxgmac_desc_data *desc_data);
+void fxgmac_desc_data_unmap(struct fxgmac_pdata *priv,
+ struct fxgmac_desc_data *desc_data);
+
+int fxgmac_channels_rings_alloc(struct fxgmac_pdata *priv);
+void fxgmac_channels_rings_free(struct fxgmac_pdata *priv);
+int fxgmac_tx_skb_map(struct fxgmac_channel *channel, struct sk_buff *skb);
+int fxgmac_rx_buffe_map(struct fxgmac_pdata *priv, struct fxgmac_ring *ring,
+ struct fxgmac_desc_data *desc_data);
+void fxgmac_dump_tx_desc(struct fxgmac_pdata *priv, struct fxgmac_ring *ring,
+ unsigned int idx, unsigned int count,
+ unsigned int flag);
+void fxgmac_dump_rx_desc(struct fxgmac_pdata *priv, struct fxgmac_ring *ring,
+ unsigned int idx);
+
+int fxgmac_is_tx_complete(struct fxgmac_dma_desc *dma_desc);
+int fxgmac_is_last_desc(struct fxgmac_dma_desc *dma_desc);
+
+#endif /* YT6801_DESC_H */
diff --git a/drivers/net/ethernet/motorcomm/yt6801/yt6801_main.c b/drivers/net/ethernet/motorcomm/yt6801/yt6801_main.c
new file mode 100644
index 000000000..1bbfd8431
--- /dev/null
+++ b/drivers/net/ethernet/motorcomm/yt6801/yt6801_main.c
@@ -0,0 +1,3020 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Copyright (c) 2022 - 2024 Motorcomm Electronic Technology Co.,Ltd.
+ *
+ * Below is a simplified block diagram of YT6801 chip and its relevant
+ * interfaces.
+ * ||
+ * ********************++**********************
+ * * | PCIE Endpoint | *
+ * * +---------------+ *
+ * * | GMAC | *
+ * * +--++--+ *
+ * * |**| *
+ * * GMII --> |**| <-- MDIO *
+ * * +-++--+ *
+ * * | Integrated PHY | YT8531S *
+ * * +-++-+ *
+ * ********************||******************* **
+ */
+
+#include <linux/if_vlan.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+#include <linux/tcp.h>
+
+#include "yt6801_type.h"
+#include "yt6801_desc.h"
+
+const struct net_device_ops *fxgmac_get_netdev_ops(void);
+static void fxgmac_napi_enable(struct fxgmac_pdata *priv);
+
+#define PHY_WR_CONFIG(reg_offset) (0x8000205 + ((reg_offset) * 0x10000))
+static int fxgmac_phy_write_reg(struct fxgmac_pdata *priv, u32 reg_id, u32 data)
+{
+ u32 val;
+ int ret;
+
+ fxgmac_io_wr(priv, MAC_MDIO_DATA, data);
+ fxgmac_io_wr(priv, MAC_MDIO_ADDR, PHY_WR_CONFIG(reg_id));
+ ret = read_poll_timeout_atomic(fxgmac_io_rd, val,
+ !field_get(MAC_MDIO_ADDR_BUSY, val),
+ 10, 250, false, priv, MAC_MDIO_ADDR);
+ if (ret == -ETIMEDOUT)
+ dev_err(priv->dev, "%s, id:%x ctrl:0x%08x, data:0x%08x\n",
+ __func__, reg_id, PHY_WR_CONFIG(reg_id), data);
+
+ return ret;
+}
+
+#define PHY_RD_CONFIG(reg_offset) (0x800020d + ((reg_offset) * 0x10000))
+static int fxgmac_phy_read_reg(struct fxgmac_pdata *priv, u32 reg_id)
+{
+ u32 val;
+ int ret;
+
+ fxgmac_io_wr(priv, MAC_MDIO_ADDR, PHY_RD_CONFIG(reg_id));
+ ret = read_poll_timeout_atomic(fxgmac_io_rd, val,
+ !field_get(MAC_MDIO_ADDR_BUSY, val),
+ 10, 250, false, priv, MAC_MDIO_ADDR);
+ if (ret == -ETIMEDOUT) {
+ dev_err(priv->dev, "%s, id:%x, ctrl:0x%08x, val:0x%08x.\n",
+ __func__, reg_id, PHY_RD_CONFIG(reg_id), val);
+ return ret;
+ }
+
+ return fxgmac_io_rd(priv, MAC_MDIO_DATA); /* Read data */
+}
+
+static int fxgmac_mdio_write_reg(struct mii_bus *mii_bus, int phyaddr,
+ int phyreg, u16 val)
+{
+ if (phyaddr > 0)
+ return -ENODEV;
+
+ return fxgmac_phy_write_reg(mii_bus->priv, phyreg, val);
+}
+
+static int fxgmac_mdio_read_reg(struct mii_bus *mii_bus, int phyaddr,
+ int phyreg)
+{
+ if (phyaddr > 0)
+ return -ENODEV;
+
+ return fxgmac_phy_read_reg(mii_bus->priv, phyreg);
+}
+
+static int fxgmac_mdio_register(struct fxgmac_pdata *priv)
+{
+ struct pci_dev *pdev = to_pci_dev(priv->dev);
+ struct phy_device *phydev;
+ struct mii_bus *new_bus;
+ int ret;
+
+ new_bus = devm_mdiobus_alloc(&pdev->dev);
+ if (!new_bus)
+ return -ENOMEM;
+
+ new_bus->name = "yt6801";
+ new_bus->priv = priv;
+ new_bus->parent = &pdev->dev;
+ new_bus->read = fxgmac_mdio_read_reg;
+ new_bus->write = fxgmac_mdio_write_reg;
+ snprintf(new_bus->id, MII_BUS_ID_SIZE, "yt6801-%x-%x",
+ pci_domain_nr(pdev->bus), pci_dev_id(pdev));
+
+ ret = devm_mdiobus_register(&pdev->dev, new_bus);
+ if (ret < 0)
+ return ret;
+
+ phydev = mdiobus_get_phy(new_bus, 0);
+ if (!phydev)
+ return -ENODEV;
+
+ priv->phydev = phydev;
+ return 0;
+}
+
+static void fxgmac_tx_start_xmit(struct fxgmac_channel *channel,
+ struct fxgmac_ring *ring)
+{
+ struct fxgmac_desc_data *desc_data;
+
+ wmb(); /* Make sure everything is written before the register write */
+
+ /* Issue a poll command to Tx DMA by writing address
+ * of next immediate free descriptor
+ */
+ desc_data = FXGMAC_GET_DESC_DATA(ring, ring->cur);
+ fxgmac_dma_io_wr(channel, DMA_CH_TDTR_LO,
+ lower_32_bits(desc_data->dma_desc_addr));
+
+ ring->tx.xmit_more = 0;
+}
+
+static unsigned int fxgmac_desc_tx_avail(struct fxgmac_ring *ring)
+{
+ if (ring->dirty > ring->cur)
+ return ring->dirty - ring->cur;
+ else
+ return ring->dma_desc_count - ring->cur + ring->dirty;
+}
+
+static netdev_tx_t fxgmac_maybe_stop_tx_queue(struct fxgmac_channel *channel,
+ struct fxgmac_ring *ring,
+ unsigned int count)
+{
+ struct fxgmac_pdata *priv = channel->priv;
+
+ if (count > fxgmac_desc_tx_avail(ring)) {
+ netdev_err(priv->ndev, "Tx queue stopped, not enough descriptors available\n");
+ netif_stop_subqueue(priv->ndev, channel->queue_index);
+ ring->tx.queue_stopped = 1;
+
+ /* If we haven't notified the hardware because of xmit_more
+ * support, tell it now
+ */
+ if (ring->tx.xmit_more)
+ fxgmac_tx_start_xmit(channel, ring);
+
+ return NETDEV_TX_BUSY;
+ }
+
+ return NETDEV_TX_OK;
+}
+
+static void fxgmac_enable_msix_one_irq(struct fxgmac_pdata *priv, u32 int_id)
+{
+ fxgmac_io_wr(priv, MSIX_TBL_MASK + int_id * 16, 0);
+}
+
+static void fxgmac_disable_msix_one_irq(struct fxgmac_pdata *priv, u32 intid)
+{
+ fxgmac_io_wr(priv, MSIX_TBL_MASK + intid * 16, 1);
+}
+
+static void fxgmac_disable_mgm_irq(struct fxgmac_pdata *priv)
+{
+ fxgmac_io_wr_bits(priv, MGMT_INT_CTRL0, MGMT_INT_CTRL0_INT_MASK,
+ MGMT_INT_CTRL0_INT_MASK_MASK);
+}
+
+static irqreturn_t fxgmac_isr(int irq, void *data)
+{
+ struct fxgmac_pdata *priv = data;
+ u32 val;
+
+ val = fxgmac_io_rd(priv, MGMT_INT_CTRL0);
+ if (!(val & MGMT_INT_CTRL0_INT_STATUS_RXTX))
+ return IRQ_NONE;
+
+ /* Restart the device on a Fatal Bus Error */
+ for (u32 i = 0; i < priv->channel_count; i++) {
+ val = fxgmac_dma_io_rd(priv->channel_head + i, DMA_CH_SR);
+ if (field_get(DMA_CH_SR_FBE, val))
+ schedule_work(&priv->restart_work);
+ /* Clear all the interrupts which are set */
+ fxgmac_dma_io_wr(priv->channel_head + i, DMA_CH_SR, val);
+ }
+
+ fxgmac_disable_mgm_irq(priv);
+ napi_schedule_irqoff(&priv->napi); /* Turn on polling */
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t fxgmac_dma_isr(int irq, void *data)
+{
+ struct fxgmac_channel *channel = data;
+
+ if (irq == channel->dma_irq_tx) {
+ fxgmac_disable_msix_one_irq(channel->priv, MSI_ID_TXQ0);
+ /* Clear Tx signal */
+ fxgmac_dma_io_wr(channel, DMA_CH_SR, DMA_CH_SR_TI);
+ napi_schedule_irqoff(&channel->napi_tx);
+ return IRQ_HANDLED;
+ }
+
+ fxgmac_disable_msix_one_irq(channel->priv, channel->queue_index);
+ /* Clear Rx signal */
+ fxgmac_dma_io_wr(channel, DMA_CH_SR, DMA_CH_SR_RI);
+ napi_schedule_irqoff(&channel->napi_rx);
+ return IRQ_HANDLED;
+}
+
+static void napi_disable_del(struct fxgmac_pdata *priv, struct napi_struct *n,
+ u32 flag)
+{
+ napi_disable(n);
+ netif_napi_del(n);
+ priv->int_flag &= ~flag;
+}
+
+static void fxgmac_napi_disable(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ u32 rx_napi[] = {INT_FLAG_RX0_NAPI, INT_FLAG_RX1_NAPI,
+ INT_FLAG_RX2_NAPI, INT_FLAG_RX3_NAPI};
+
+ if (!priv->per_channel_irq) {
+ if (!field_get(INT_FLAG_LEGACY_NAPI, priv->int_flag))
+ return;
+
+ napi_disable_del(priv, &priv->napi,
+ INT_FLAG_LEGACY_NAPI);
+ return;
+ }
+
+ if (field_get(INT_FLAG_TX_NAPI, priv->int_flag))
+ napi_disable_del(priv, &channel->napi_tx, INT_FLAG_TX_NAPI);
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ if (priv->int_flag & rx_napi[i])
+ napi_disable_del(priv, &channel->napi_rx, rx_napi[i]);
+}
+
+static void fxgmac_free_irqs(struct fxgmac_pdata *priv)
+{
+ u32 rx_irq[] = {INT_FLAG_RX0_IRQ, INT_FLAG_RX1_IRQ,
+ INT_FLAG_RX2_IRQ, INT_FLAG_RX3_IRQ};
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ if (!field_get(INT_FLAG_MSIX, priv->int_flag) &&
+ field_get(INT_FLAG_LEGACY_IRQ, priv->int_flag)) {
+ devm_free_irq(priv->dev, priv->dev_irq, priv);
+ priv->int_flag &= ~INT_FLAG_LEGACY_IRQ;
+ }
+
+ if (!priv->per_channel_irq)
+ return;
+
+ if (field_get(INT_FLAG_TX_IRQ, priv->int_flag)) {
+ priv->int_flag &= ~INT_FLAG_TX_IRQ;
+ devm_free_irq(priv->dev, channel->dma_irq_tx, channel);
+ }
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ if (priv->int_flag & rx_irq[i]) {
+ priv->int_flag &= ~rx_irq[i];
+ devm_free_irq(priv->dev, channel->dma_irq_rx, channel);
+ }
+}
+
+static int fxgmac_request_irqs(struct fxgmac_pdata *priv)
+{
+ u32 rx_irq[] = {INT_FLAG_RX0_IRQ, INT_FLAG_RX1_IRQ,
+ INT_FLAG_RX2_IRQ, INT_FLAG_RX3_IRQ};
+ u32 i = 0, msi = field_get(INT_FLAG_MSI, priv->int_flag);
+ struct fxgmac_channel *channel = priv->channel_head;
+ struct net_device *ndev = priv->ndev;
+ int ret;
+
+ if (!field_get(INT_FLAG_MSIX, priv->int_flag) &&
+ !field_get(INT_FLAG_LEGACY_IRQ, priv->int_flag)) {
+ priv->int_flag |= INT_FLAG_LEGACY_IRQ;
+ ret = devm_request_irq(priv->dev, priv->dev_irq, fxgmac_isr,
+ msi ? 0 : IRQF_SHARED, ndev->name,
+ priv);
+ if (ret) {
+ dev_err(priv->dev, "Requesting irq:%d, failed:%d\n",
+ priv->dev_irq, ret);
+ return ret;
+ }
+ }
+
+ if (!priv->per_channel_irq)
+ return 0;
+
+ if (!field_get(INT_FLAG_TX_IRQ, priv->int_flag)) {
+ snprintf(channel->dma_irq_tx_name,
+ sizeof(channel->dma_irq_tx_name) - 1,
+ "%s-ch%d-Tx-%u", netdev_name(ndev), 0,
+ channel->queue_index);
+ priv->int_flag |= INT_FLAG_TX_IRQ;
+ ret = devm_request_irq(priv->dev, channel->dma_irq_tx,
+ fxgmac_dma_isr, 0,
+ channel->dma_irq_tx_name, channel);
+ if (ret) {
+ dev_err(priv->dev, "dev:%p, channel:%p\n",
+ priv->dev, channel);
+
+ dev_err(priv->dev, "Requesting tx irq:%d, failed:%d\n",
+ channel->dma_irq_tx, ret);
+ goto err_irq;
+ }
+ }
+
+ for (i = 0; i < priv->channel_count; i++, channel++) {
+ snprintf(channel->dma_irq_rx_name,
+ sizeof(channel->dma_irq_rx_name) - 1, "%s-ch%d-Rx-%u",
+ netdev_name(ndev), i, channel->queue_index);
+
+ if ((priv->int_flag & rx_irq[i]) != rx_irq[i]) {
+ priv->int_flag |= rx_irq[i];
+ ret = devm_request_irq(priv->dev, channel->dma_irq_rx,
+ fxgmac_dma_isr, 0,
+ channel->dma_irq_rx_name,
+ channel);
+ if (ret) {
+ dev_err(priv->dev, "Requesting rx irq:%d, failed:%d\n",
+ channel->dma_irq_rx, ret);
+ goto err_irq;
+ }
+ }
+ }
+
+ return 0;
+
+err_irq:
+ fxgmac_free_irqs(priv);
+ return ret;
+}
+
+static void fxgmac_free_tx_data(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ struct fxgmac_ring *ring;
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++) {
+ ring = channel->tx_ring;
+ if (!ring)
+ break;
+
+ for (u32 j = 0; j < ring->dma_desc_count; j++)
+ fxgmac_desc_data_unmap(priv,
+ FXGMAC_GET_DESC_DATA(ring, j));
+ }
+}
+
+static void fxgmac_free_rx_data(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ struct fxgmac_ring *ring;
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++) {
+ ring = channel->rx_ring;
+ if (!ring)
+ break;
+
+ for (u32 j = 0; j < ring->dma_desc_count; j++)
+ fxgmac_desc_data_unmap(priv,
+ FXGMAC_GET_DESC_DATA(ring, j));
+ }
+}
+
+static void fxgmac_enable_tx(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ /* Enable Tx DMA channel */
+ fxgmac_dma_wr_bits(channel, DMA_CH_TCR, DMA_CH_TCR_ST, 1);
+
+ /* Enable Tx queue */
+ fxgmac_mtl_wr_bits(priv, 0, MTL_Q_TQOMR, MTL_Q_TQOMR_TXQEN,
+ MTL_Q_ENABLED);
+ /* Enable MAC Tx */
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_TE, 1);
+}
+
+static void fxgmac_prepare_tx_stop(struct fxgmac_pdata *priv,
+ struct fxgmac_channel *channel)
+{
+ unsigned long tx_timeout;
+ unsigned int tx_status;
+
+ /* The Tx engine cannot be stopped if it is actively processing
+ * descriptors. Wait for the Tx engine to enter the stopped or
+ * suspended state.
+ */
+ tx_timeout = jiffies + (FXGMAC_DMA_STOP_TIMEOUT * HZ);
+
+ while (time_before(jiffies, tx_timeout)) {
+ tx_status = fxgmac_io_rd(priv, DMA_DSR0);
+ tx_status = field_get(DMA_DSR0_TPS, tx_status);
+ if (tx_status == DMA_TPS_STOPPED ||
+ tx_status == DMA_TPS_SUSPENDED)
+ break;
+
+ fsleep(500);
+ }
+
+ if (!time_before(jiffies, tx_timeout))
+ dev_err(priv->dev, "timed out waiting for Tx DMA channel stop\n");
+}
+
+static void fxgmac_disable_tx(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ /* Prepare for Tx DMA channel stop */
+ fxgmac_prepare_tx_stop(priv, channel);
+
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_TE, 0); /* Disable MAC Tx */
+
+ /* Disable Tx queue */
+ fxgmac_mtl_wr_bits(priv, 0, MTL_Q_TQOMR, MTL_Q_TQOMR_TXQEN,
+ MTL_Q_DISABLED);
+
+ /* Disable Tx DMA channel */
+ fxgmac_dma_wr_bits(channel, DMA_CH_TCR, DMA_CH_TCR_ST, 0);
+}
+
+static void fxgmac_enable_rx(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ u32 val = 0, i;
+
+ /* Enable each Rx DMA channel */
+ for (i = 0; i < priv->channel_count; i++, channel++)
+ fxgmac_dma_wr_bits(channel, DMA_CH_RCR, DMA_CH_RCR_SR, 1);
+
+ /* Enable each Rx queue */
+ for (i = 0; i < priv->rx_q_count; i++)
+ val |= (0x02 << (i << 1));
+
+ fxgmac_io_wr(priv, MAC_RQC0R, val);
+
+ /* Enable MAC Rx */
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_CST, 1);
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_ACS, 1);
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_RE, 1);
+}
+
+static void fxgmac_prepare_rx_stop(struct fxgmac_pdata *priv,
+ unsigned int queue)
+{
+ unsigned int rx_status, rx_q, rx_q_sts;
+ unsigned long rx_timeout;
+
+ /* The Rx engine cannot be stopped if it is actively processing
+ * packets. Wait for the Rx queue to empty the Rx fifo.
+ */
+ rx_timeout = jiffies + (FXGMAC_DMA_STOP_TIMEOUT * HZ);
+
+ while (time_before(jiffies, rx_timeout)) {
+ rx_status = fxgmac_mtl_io_rd(priv, queue, MTL_Q_RQDR);
+ rx_q = field_get(MTL_Q_RQDR_PRXQ, rx_status);
+ rx_q_sts = field_get(MTL_Q_RQDR_RXQSTS, rx_status);
+ if (rx_q == 0 && rx_q_sts == 0)
+ break;
+
+ fsleep(500);
+ }
+
+ if (!time_before(jiffies, rx_timeout))
+ dev_err(priv->dev, "timed out waiting for Rx queue %u to empty\n",
+ queue);
+}
+
+static void fxgmac_disable_rx(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ u32 i;
+
+ /* Disable MAC Rx */
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_CST, 0);
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_ACS, 0);
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_RE, 0);
+
+ /* Prepare for Rx DMA channel stop */
+ for (i = 0; i < priv->rx_q_count; i++)
+ fxgmac_prepare_rx_stop(priv, i);
+
+ fxgmac_io_wr(priv, MAC_RQC0R, 0); /* Disable each Rx queue */
+
+ /* Disable each Rx DMA channel */
+ for (i = 0; i < priv->channel_count; i++, channel++)
+ fxgmac_dma_wr_bits(channel, DMA_CH_RCR, DMA_CH_RCR_SR, 0);
+}
+
+static void fxgmac_default_speed_duplex_config(struct fxgmac_pdata *priv)
+{
+ priv->mac_duplex = DUPLEX_FULL;
+ priv->mac_speed = SPEED_1000;
+}
+
+static void fxgmac_config_mac_speed(struct fxgmac_pdata *priv)
+{
+ if (priv->mac_duplex == DUPLEX_UNKNOWN &&
+ priv->mac_speed == SPEED_UNKNOWN)
+ fxgmac_default_speed_duplex_config(priv);
+
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_DM, priv->mac_duplex);
+
+ switch (priv->mac_speed) {
+ case SPEED_1000:
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_PS, 0);
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_FES, 0);
+ break;
+ case SPEED_100:
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_PS, 1);
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_FES, 1);
+ break;
+ case SPEED_10:
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_PS, 1);
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_FES, 0);
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+}
+
+static void fxgmac_phylink_handler(struct net_device *ndev)
+{
+ struct fxgmac_pdata *priv = netdev_priv(ndev);
+
+ priv->mac_speed = priv->phydev->speed;
+ priv->mac_duplex = priv->phydev->duplex;
+
+ if (priv->phydev->link) {
+ fxgmac_config_mac_speed(priv);
+ fxgmac_enable_rx(priv);
+ fxgmac_enable_tx(priv);
+ if (netif_running(priv->ndev))
+ netif_tx_wake_all_queues(priv->ndev);
+ } else {
+ netif_tx_stop_all_queues(priv->ndev);
+ fxgmac_disable_rx(priv);
+ fxgmac_disable_tx(priv);
+ }
+
+ phy_print_status(priv->phydev);
+}
+
+static int fxgmac_phy_connect(struct fxgmac_pdata *priv)
+{
+ struct phy_device *phydev = priv->phydev;
+ int ret;
+
+ priv->phydev->irq = PHY_POLL;
+ ret = phy_connect_direct(priv->ndev, phydev, fxgmac_phylink_handler,
+ PHY_INTERFACE_MODE_INTERNAL);
+ if (ret)
+ return ret;
+
+ phy_support_asym_pause(phydev);
+ priv->phydev->mac_managed_pm = 1;
+ phy_attached_info(phydev);
+
+ return 0;
+}
+
+static void fxgmac_enable_msix_irqs(struct fxgmac_pdata *priv)
+{
+ for (u32 intid = 0; intid < MSIX_TBL_MAX_NUM; intid++)
+ fxgmac_enable_msix_one_irq(priv, intid);
+}
+
+static void __fxgmac_set_mac_address(struct fxgmac_pdata *priv, u8 *addr)
+{
+ u32 mac_hi, mac_lo;
+
+ mac_lo = (u32)addr[0] | ((u32)addr[1] << 8) | ((u32)addr[2] << 16) |
+ ((u32)addr[3] << 24);
+
+ mac_hi = (u32)addr[4] | ((u32)addr[5] << 8);
+
+ fxgmac_io_wr(priv, MAC_MACA0LR, mac_lo);
+ fxgmac_io_wr(priv, MAC_MACA0HR, mac_hi);
+}
+
+static void fxgmac_config_mac_address(struct fxgmac_pdata *priv)
+{
+ __fxgmac_set_mac_address(priv, priv->mac_addr);
+ fxgmac_io_wr_bits(priv, MAC_PFR, MAC_PFR_HPF, 1);
+ fxgmac_io_wr_bits(priv, MAC_PFR, MAC_PFR_HUC, 1);
+ fxgmac_io_wr_bits(priv, MAC_PFR, MAC_PFR_HMC, 1);
+}
+
+static void fxgmac_config_crc_check_en(struct fxgmac_pdata *priv)
+{
+ fxgmac_io_wr_bits(priv, MAC_ECR, MAC_ECR_DCRCC, 1);
+}
+
+static void fxgmac_config_checksum_offload(struct fxgmac_pdata *priv)
+{
+ if (priv->ndev->features & NETIF_F_RXCSUM)
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_IPC, 1);
+ else
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_IPC, 0);
+}
+
+static void fxgmac_set_promiscuous_mode(struct fxgmac_pdata *priv,
+ unsigned int enable)
+{
+ fxgmac_io_wr_bits(priv, MAC_PFR, MAC_PFR_PR, enable);
+}
+
+static void fxgmac_enable_rx_broadcast(struct fxgmac_pdata *priv,
+ unsigned int enable)
+{
+ fxgmac_io_wr_bits(priv, MAC_PFR, MAC_PFR_DBF, enable);
+}
+
+static void fxgmac_set_all_multicast_mode(struct fxgmac_pdata *priv,
+ unsigned int enable)
+{
+ fxgmac_io_wr_bits(priv, MAC_PFR, MAC_PFR_PM, enable);
+}
+
+static void fxgmac_config_rx_mode(struct fxgmac_pdata *priv)
+{
+ u32 pr_mode, am_mode, bd_mode;
+
+ pr_mode = ((priv->ndev->flags & IFF_PROMISC) != 0);
+ am_mode = ((priv->ndev->flags & IFF_ALLMULTI) != 0);
+ bd_mode = ((priv->ndev->flags & IFF_BROADCAST) != 0);
+
+ fxgmac_enable_rx_broadcast(priv, bd_mode);
+ fxgmac_set_promiscuous_mode(priv, pr_mode);
+ fxgmac_set_all_multicast_mode(priv, am_mode);
+}
+
+static void fxgmac_config_tx_flow_control(struct fxgmac_pdata *priv)
+{
+ /* Set MTL flow control */
+ for (u32 i = 0; i < priv->rx_q_count; i++)
+ fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_EHFC,
+ priv->tx_pause);
+
+ /* Set MAC flow control */
+ fxgmac_io_wr_bits(priv, MAC_Q0TFCR, MAC_Q0TFCR_TFE, priv->tx_pause);
+
+ if (priv->tx_pause == 1) /* Set pause time */
+ fxgmac_io_wr_bits(priv, MAC_Q0TFCR, MAC_Q0TFCR_PT, 0xffff);
+}
+
+static void fxgmac_config_rx_flow_control(struct fxgmac_pdata *priv)
+{
+ fxgmac_io_wr_bits(priv, MAC_RFCR, MAC_RFCR_RFE, priv->rx_pause);
+}
+
+static void fxgmac_config_rx_coalesce(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++) {
+ if (!channel->rx_ring)
+ break;
+ fxgmac_dma_wr_bits(channel, DMA_CH_RIWT, DMA_CH_RIWT_RWT,
+ priv->rx_riwt);
+ }
+}
+
+static void fxgmac_config_rx_fep_disable(struct fxgmac_pdata *priv)
+{
+ /* Enable the rx queue forward packet with error status
+ * (crc error,gmii_er, watch dog timeout.or overflow)
+ */
+ for (u32 i = 0; i < priv->rx_q_count; i++)
+ fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_FEP, 1);
+}
+
+static void fxgmac_config_rx_fup_enable(struct fxgmac_pdata *priv)
+{
+ for (u32 i = 0; i < priv->rx_q_count; i++)
+ fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_FUP, 1);
+}
+
+static void fxgmac_config_rx_buffer_size(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ fxgmac_dma_wr_bits(channel, DMA_CH_RCR, DMA_CH_RCR_RBSZ,
+ priv->rx_buf_size);
+}
+
+static void fxgmac_config_tso_mode(struct fxgmac_pdata *priv)
+{
+ fxgmac_dma_wr_bits(priv->channel_head, DMA_CH_TCR, DMA_CH_TCR_TSE,
+ priv->hw_feat.tso);
+}
+
+static void fxgmac_config_sph_mode(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ fxgmac_dma_wr_bits(channel, DMA_CH_CR, DMA_CH_CR_SPH, 0);
+
+ fxgmac_io_wr_bits(priv, MAC_ECR, MAC_ECR_HDSMS, MAC_ECR_HDSMS_512B);
+}
+
+static void fxgmac_config_rx_threshold(struct fxgmac_pdata *priv,
+ unsigned int set_val)
+{
+ for (u32 i = 0; i < priv->rx_q_count; i++)
+ fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_RTC,
+ set_val);
+}
+
+static void fxgmac_config_mtl_mode(struct fxgmac_pdata *priv)
+{
+ /* Set Tx to weighted round robin scheduling algorithm */
+ fxgmac_io_wr_bits(priv, MTL_OMR, MTL_OMR_ETSALG, MTL_ETSALG_WRR);
+
+ /* Set Tx traffic classes to use WRR algorithm with equal weights */
+ fxgmac_mtl_wr_bits(priv, 0, MTL_TC_QWR, MTL_TC_QWR_QW, 1);
+
+ /* Set Rx to strict priority algorithm */
+ fxgmac_io_wr_bits(priv, MTL_OMR, MTL_OMR_RAA, MTL_RAA_SP);
+}
+
+static void fxgmac_config_queue_mapping(struct fxgmac_pdata *priv)
+{
+ unsigned int ppq, ppq_extra, prio_queues;
+ unsigned int __maybe_unused prio;
+ unsigned int reg, val, mask;
+
+ /* Map the 8 VLAN priority values to available MTL Rx queues */
+ prio_queues =
+ min_t(unsigned int, IEEE_8021QAZ_MAX_TCS, priv->rx_q_count);
+ ppq = IEEE_8021QAZ_MAX_TCS / prio_queues;
+ ppq_extra = IEEE_8021QAZ_MAX_TCS % prio_queues;
+
+ reg = MAC_RQC2R;
+ for (u32 i = 0, prio = 0; i < prio_queues;) {
+ val = 0;
+ mask = 0;
+ for (u32 j = 0; j < ppq; j++) {
+ mask |= (1 << prio);
+ prio++;
+ }
+
+ if (i < ppq_extra) {
+ mask |= (1 << prio);
+ prio++;
+ }
+
+ val |= (mask << ((i++ % MAC_RQC2_Q_PER_REG) << 3));
+
+ if ((i % MAC_RQC2_Q_PER_REG) && i != prio_queues)
+ continue;
+
+ fxgmac_io_wr(priv, reg, val);
+ reg += MAC_RQC2_INC;
+ }
+
+ /* Configure one to one, MTL Rx queue to DMA Rx channel mapping
+ * ie Q0 <--> CH0, Q1 <--> CH1 ... Q7 <--> CH7
+ */
+ val = fxgmac_io_rd(priv, MTL_RQDCM0R);
+ val |= (MTL_RQDCM0R_Q0MDMACH | MTL_RQDCM0R_Q1MDMACH |
+ MTL_RQDCM0R_Q2MDMACH | MTL_RQDCM0R_Q3MDMACH);
+ fxgmac_io_wr(priv, MTL_RQDCM0R, val);
+
+ val = fxgmac_io_rd(priv, MTL_RQDCM0R + MTL_RQDCM_INC);
+ val |= (MTL_RQDCM1R_Q4MDMACH | MTL_RQDCM1R_Q5MDMACH |
+ MTL_RQDCM1R_Q6MDMACH | MTL_RQDCM1R_Q7MDMACH);
+ fxgmac_io_wr(priv, MTL_RQDCM0R + MTL_RQDCM_INC, val);
+}
+
+static unsigned int fxgmac_calculate_per_queue_fifo(unsigned int fifo_size,
+ unsigned int queue_count)
+{
+ u32 q_fifo_size, p_fifo;
+
+ /* Calculate the configured fifo size */
+ q_fifo_size = 1 << (fifo_size + 7);
+
+#define FXGMAC_MAX_FIFO 81920
+ /* The configured value may not be the actual amount of fifo RAM */
+ q_fifo_size = min_t(unsigned int, FXGMAC_MAX_FIFO, q_fifo_size);
+ q_fifo_size = q_fifo_size / queue_count;
+
+ /* Each increment in the queue fifo size represents 256 bytes of
+ * fifo, with 0 representing 256 bytes. Distribute the fifo equally
+ * between the queues.
+ */
+ p_fifo = q_fifo_size / 256;
+ if (p_fifo)
+ p_fifo--;
+
+ return p_fifo;
+}
+
+static void fxgmac_config_tx_fifo_size(struct fxgmac_pdata *priv)
+{
+ u32 fifo_size;
+
+ fifo_size = fxgmac_calculate_per_queue_fifo(priv->hw_feat.tx_fifo_size,
+ FXGMAC_TX_1_Q);
+ fxgmac_mtl_wr_bits(priv, 0, MTL_Q_TQOMR, MTL_Q_TQOMR_TQS, fifo_size);
+}
+
+static void fxgmac_config_rx_fifo_size(struct fxgmac_pdata *priv)
+{
+ u32 fifo_size;
+
+ fifo_size = fxgmac_calculate_per_queue_fifo(priv->hw_feat.rx_fifo_size,
+ priv->rx_q_count);
+
+ for (u32 i = 0; i < priv->rx_q_count; i++)
+ fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_RQS,
+ fifo_size);
+}
+
+static void fxgmac_config_flow_control_threshold(struct fxgmac_pdata *priv)
+{
+ for (u32 i = 0; i < priv->rx_q_count; i++) {
+ /* Activate flow control when less than 4k left in fifo */
+ fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_RFA, 6);
+ /* De-activate flow control when more than 6k left in fifo */
+ fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_RFD, 10);
+ }
+}
+
+static void fxgmac_config_tx_threshold(struct fxgmac_pdata *priv,
+ unsigned int set_val)
+{
+ fxgmac_mtl_wr_bits(priv, 0, MTL_Q_TQOMR, MTL_Q_TQOMR_TTC, set_val);
+}
+
+static void fxgmac_config_rsf_mode(struct fxgmac_pdata *priv,
+ unsigned int set_val)
+{
+ for (u32 i = 0; i < priv->rx_q_count; i++)
+ fxgmac_mtl_wr_bits(priv, i, MTL_Q_RQOMR, MTL_Q_RQOMR_RSF,
+ set_val);
+}
+
+static void fxgmac_config_tsf_mode(struct fxgmac_pdata *priv,
+ unsigned int set_val)
+{
+ fxgmac_mtl_wr_bits(priv, 0, MTL_Q_TQOMR, MTL_Q_TQOMR_TSF, set_val);
+}
+
+static void fxgmac_config_osp_mode(struct fxgmac_pdata *priv)
+{
+ fxgmac_dma_wr_bits(priv->channel_head, DMA_CH_TCR, DMA_CH_TCR_OSP,
+ priv->tx_osp_mode);
+}
+
+static void fxgmac_config_pblx8(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ fxgmac_dma_wr_bits(channel, DMA_CH_CR, DMA_CH_CR_PBLX8,
+ priv->pblx8);
+}
+
+static void fxgmac_config_tx_pbl_val(struct fxgmac_pdata *priv)
+{
+ fxgmac_dma_wr_bits(priv->channel_head, DMA_CH_TCR, DMA_CH_TCR_PBL,
+ priv->tx_pbl);
+}
+
+static void fxgmac_config_rx_pbl_val(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ fxgmac_dma_wr_bits(channel, DMA_CH_RCR, DMA_CH_RCR_PBL,
+ priv->rx_pbl);
+}
+
+static void fxgmac_config_mmc(struct fxgmac_pdata *priv)
+{
+ /* Set counters to reset on read, Reset the counters */
+ fxgmac_io_wr_bits(priv, MMC_CR, MMC_CR_ROR, 1);
+ fxgmac_io_wr_bits(priv, MMC_CR, MMC_CR_CR, 1);
+
+ fxgmac_io_wr(priv, MMC_IPC_RXINT_MASK, 0xffffffff);
+}
+
+static void fxgmac_enable_dma_interrupts(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ u32 ch_sr;
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++) {
+ /* Clear all the interrupts which are set */
+ ch_sr = fxgmac_dma_io_rd(channel, DMA_CH_SR);
+ fxgmac_dma_io_wr(channel, DMA_CH_SR, ch_sr);
+
+ ch_sr = 0;
+ /* Enable Normal Interrupt Summary Enable and Fatal Bus Error
+ * Enable interrupts.
+ */
+ ch_sr |= (DMA_CH_IER_NIE | DMA_CH_IER_FBEE);
+
+ /* only one tx, enable Transmit Interrupt Enable interrupts */
+ if (i == 0 && channel->tx_ring)
+ ch_sr |= DMA_CH_IER_TIE;
+
+ /* Enable Receive Buffer Unavailable Enable and Receive
+ * Interrupt Enable interrupts.
+ */
+ if (channel->rx_ring)
+ ch_sr |= (DMA_CH_IER_RBUE | DMA_CH_IER_RIE);
+
+ fxgmac_dma_io_wr(channel, DMA_CH_IER, ch_sr);
+ }
+}
+
+static void fxgmac_enable_mtl_interrupts(struct fxgmac_pdata *priv)
+{
+ unsigned int mtl_q_isr;
+
+ for (u32 i = 0; i < priv->hw_feat.rx_q_cnt; i++) {
+ /* Clear all the interrupts which are set */
+ mtl_q_isr = fxgmac_mtl_io_rd(priv, i, MTL_Q_IR);
+ fxgmac_mtl_io_wr(priv, i, MTL_Q_IR, mtl_q_isr);
+
+ /* No MTL interrupts to be enabled */
+ fxgmac_mtl_io_wr(priv, i, MTL_Q_IR, 0);
+ }
+}
+
+static void fxgmac_enable_mac_interrupts(struct fxgmac_pdata *priv)
+{
+ /* Disable Timestamp interrupt */
+ fxgmac_io_wr_bits(priv, MAC_IER, MAC_IER_TSIE, 0);
+
+ fxgmac_io_wr_bits(priv, MMC_RIER, MMC_RIER_ALL_INTERRUPTS, 0);
+ fxgmac_io_wr_bits(priv, MMC_TIER, MMC_TIER_ALL_INTERRUPTS, 0);
+}
+
+static int fxgmac_flush_tx_queues(struct fxgmac_pdata *priv)
+{
+ u32 val, count = 2000;
+
+ fxgmac_mtl_wr_bits(priv, 0, MTL_Q_TQOMR, MTL_Q_TQOMR_FTQ, 1);
+ do {
+ fsleep(20);
+ val = fxgmac_mtl_io_rd(priv, 0, MTL_Q_TQOMR);
+ val = field_get(MTL_Q_TQOMR_FTQ, val);
+
+ } while (--count && val);
+
+ if (val)
+ return -EBUSY;
+
+ return 0;
+}
+
+static void fxgmac_config_dma_bus(struct fxgmac_pdata *priv)
+{
+ u32 val = fxgmac_io_rd(priv, DMA_SBMR);
+
+ val &= ~(DMA_SBMR_EAME | DMA_SBMR_RD_OSR_LMT |
+ DMA_SBMR_WR_OSR_LMT | DMA_SBMR_FB);
+
+ /* Set enhanced addressing mode */
+ val |= DMA_SBMR_EAME;
+
+ /* Out standing read/write requests */
+ val |= field_prep(DMA_SBMR_RD_OSR_LMT, 0x7);
+ val |= field_prep(DMA_SBMR_WR_OSR_LMT, 0x7);
+
+ /* Set the System Bus mode */
+ val |= (DMA_SBMR_BLEN_4 | DMA_SBMR_BLEN_8 |
+ DMA_SBMR_BLEN_16 | DMA_SBMR_BLEN_32);
+
+ fxgmac_io_wr(priv, DMA_SBMR, val);
+}
+
+static void fxgmac_desc_rx_channel_init(struct fxgmac_channel *channel)
+{
+ struct fxgmac_ring *ring = channel->rx_ring;
+ unsigned int start_index = ring->cur;
+ struct fxgmac_desc_data *desc_data;
+
+ /* Initialize all descriptors */
+ for (u32 i = 0; i < ring->dma_desc_count; i++) {
+ desc_data = FXGMAC_GET_DESC_DATA(ring, i);
+ fxgmac_desc_rx_reset(desc_data); /* Initialize Rx descriptor */
+ }
+
+ /* Update the total number of Rx descriptors */
+ fxgmac_dma_io_wr(channel, DMA_CH_RDRLR, ring->dma_desc_count - 1);
+
+ /* Update the starting address of descriptor ring */
+ desc_data = FXGMAC_GET_DESC_DATA(ring, start_index);
+
+ fxgmac_dma_io_wr(channel, DMA_CH_RDLR_HI,
+ upper_32_bits(desc_data->dma_desc_addr));
+ fxgmac_dma_io_wr(channel, DMA_CH_RDLR_LO,
+ lower_32_bits(desc_data->dma_desc_addr));
+
+ /* Update the Rx Descriptor Tail Pointer */
+ desc_data = FXGMAC_GET_DESC_DATA(ring, start_index +
+ ring->dma_desc_count - 1);
+ fxgmac_dma_io_wr(channel, DMA_CH_RDTR_LO,
+ lower_32_bits(desc_data->dma_desc_addr));
+}
+
+static void fxgmac_desc_rx_init(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ struct fxgmac_desc_data *desc_data;
+ struct fxgmac_dma_desc *dma_desc;
+ dma_addr_t dma_desc_addr;
+ struct fxgmac_ring *ring;
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++) {
+ ring = channel->rx_ring;
+ dma_desc = ring->dma_desc_head;
+ dma_desc_addr = ring->dma_desc_head_addr;
+
+ for (u32 j = 0; j < ring->dma_desc_count; j++) {
+ desc_data = FXGMAC_GET_DESC_DATA(ring, j);
+ desc_data->dma_desc = dma_desc;
+ desc_data->dma_desc_addr = dma_desc_addr;
+ if (fxgmac_rx_buffe_map(priv, ring, desc_data))
+ break;
+
+ dma_desc++;
+ dma_desc_addr += sizeof(struct fxgmac_dma_desc);
+ }
+
+ ring->cur = 0;
+ ring->dirty = 0;
+
+ fxgmac_desc_rx_channel_init(channel);
+ }
+}
+
+static void fxgmac_desc_tx_channel_init(struct fxgmac_channel *channel)
+{
+ struct fxgmac_ring *ring = channel->tx_ring;
+ struct fxgmac_desc_data *desc_data;
+ int start_index = ring->cur;
+
+ /* Initialize all descriptors */
+ for (u32 i = 0; i < ring->dma_desc_count; i++) {
+ desc_data = FXGMAC_GET_DESC_DATA(ring, i);
+ fxgmac_desc_tx_reset(desc_data); /* Initialize Tx descriptor */
+ }
+
+ /* Update the total number of Tx descriptors */
+ fxgmac_dma_io_wr(channel, DMA_CH_TDRLR,
+ channel->priv->tx_desc_count - 1);
+
+ /* Update the starting address of descriptor ring */
+ desc_data = FXGMAC_GET_DESC_DATA(ring, start_index);
+
+ fxgmac_dma_io_wr(channel, DMA_CH_TDLR_HI,
+ upper_32_bits(desc_data->dma_desc_addr));
+ fxgmac_dma_io_wr(channel, DMA_CH_TDLR_LO,
+ lower_32_bits(desc_data->dma_desc_addr));
+}
+
+static void fxgmac_desc_tx_init(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ struct fxgmac_ring *ring = channel->tx_ring;
+ struct fxgmac_desc_data *desc_data;
+ struct fxgmac_dma_desc *dma_desc;
+ dma_addr_t dma_desc_addr;
+
+ dma_desc = ring->dma_desc_head;
+ dma_desc_addr = ring->dma_desc_head_addr;
+
+ for (u32 j = 0; j < ring->dma_desc_count; j++) {
+ desc_data = FXGMAC_GET_DESC_DATA(ring, j);
+ desc_data->dma_desc = dma_desc;
+ desc_data->dma_desc_addr = dma_desc_addr;
+
+ dma_desc++;
+ dma_desc_addr += sizeof(struct fxgmac_dma_desc);
+ }
+
+ ring->cur = 0;
+ ring->dirty = 0;
+ memset(&ring->tx, 0, sizeof(ring->tx));
+ fxgmac_desc_tx_channel_init(priv->channel_head);
+}
+
+static int fxgmac_hw_init(struct fxgmac_pdata *priv)
+{
+ int ret;
+
+ ret = fxgmac_flush_tx_queues(priv); /* Flush Tx queues */
+ if (ret < 0) {
+ dev_err(priv->dev, "%s, flush tx queue failed:%d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ /* Initialize DMA related features */
+ fxgmac_config_dma_bus(priv);
+ fxgmac_config_osp_mode(priv);
+ fxgmac_config_pblx8(priv);
+ fxgmac_config_tx_pbl_val(priv);
+ fxgmac_config_rx_pbl_val(priv);
+ fxgmac_config_rx_coalesce(priv);
+ fxgmac_config_rx_buffer_size(priv);
+ fxgmac_config_tso_mode(priv);
+ fxgmac_config_sph_mode(priv);
+ fxgmac_desc_tx_init(priv);
+ fxgmac_desc_rx_init(priv);
+ fxgmac_enable_dma_interrupts(priv);
+
+ /* Initialize MTL related features */
+ fxgmac_config_mtl_mode(priv);
+ fxgmac_config_queue_mapping(priv);
+ fxgmac_config_tsf_mode(priv, priv->tx_sf_mode);
+ fxgmac_config_rsf_mode(priv, priv->rx_sf_mode);
+ fxgmac_config_tx_threshold(priv, priv->tx_threshold);
+ fxgmac_config_rx_threshold(priv, priv->rx_threshold);
+ fxgmac_config_tx_fifo_size(priv);
+ fxgmac_config_rx_fifo_size(priv);
+ fxgmac_config_flow_control_threshold(priv);
+ fxgmac_config_rx_fep_disable(priv);
+ fxgmac_config_rx_fup_enable(priv);
+ fxgmac_enable_mtl_interrupts(priv);
+
+ /* Initialize MAC related features */
+ fxgmac_config_mac_address(priv);
+ fxgmac_config_crc_check_en(priv);
+ fxgmac_config_rx_mode(priv);
+ fxgmac_config_tx_flow_control(priv);
+ fxgmac_config_rx_flow_control(priv);
+ fxgmac_config_mac_speed(priv);
+ fxgmac_config_checksum_offload(priv);
+ fxgmac_config_mmc(priv);
+ fxgmac_enable_mac_interrupts(priv);
+
+ return 0;
+}
+
+static void fxgmac_dismiss_all_int(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ u32 i;
+
+ /* Clear all the interrupts which are set */
+ for (i = 0; i < priv->channel_count; i++, channel++)
+ fxgmac_dma_io_wr(channel, DMA_CH_SR,
+ fxgmac_dma_io_rd(channel, DMA_CH_SR));
+
+ for (i = 0; i < priv->hw_feat.rx_q_cnt; i++)
+ fxgmac_mtl_io_wr(priv, i, MTL_Q_IR,
+ fxgmac_mtl_io_rd(priv, i, MTL_Q_IR));
+
+ fxgmac_io_rd(priv, MAC_ISR); /* Clear all MAC interrupts */
+ fxgmac_io_rd(priv, MAC_TX_RX_STA);/* Clear tx/rx error interrupts */
+ fxgmac_io_rd(priv, MAC_PMT_STA);
+ fxgmac_io_rd(priv, MAC_LPI_STA);
+
+ fxgmac_io_wr(priv, MAC_DBG_STA, fxgmac_io_rd(priv, MAC_DBG_STA));
+}
+
+static void fxgmac_set_interrupt_moderation(struct fxgmac_pdata *priv)
+{
+ fxgmac_io_wr_bits(priv, INT_MOD, INT_MOD_TX, priv->tx_usecs);
+ fxgmac_io_wr_bits(priv, INT_MOD, INT_MOD_RX, priv->rx_usecs);
+}
+
+static void fxgmac_enable_mgm_irq(struct fxgmac_pdata *priv)
+{
+ fxgmac_io_wr_bits(priv, MGMT_INT_CTRL0, MGMT_INT_CTRL0_INT_STATUS, 0);
+ fxgmac_io_wr_bits(priv, MGMT_INT_CTRL0, MGMT_INT_CTRL0_INT_MASK,
+ MGMT_INT_CTRL0_INT_MASK_MISC);
+}
+
+/**
+ * fxgmac_set_oob_wol - disable or enable oob wol crtl function
+ * @priv: driver private struct
+ * @en: 1 or 0
+ *
+ * Description: After enable OOB_WOL from efuse, mac will loopcheck phy status,
+ * and lead to panic sometimes. So we should disable it from powerup,
+ * enable it from power down.
+ */
+static void fxgmac_set_oob_wol(struct fxgmac_pdata *priv, unsigned int en)
+{
+ /* en = 1 is disable */
+ fxgmac_io_wr_bits(priv, OOB_WOL_CTRL, OOB_WOL_CTRL_DIS, !en);
+}
+
+static void fxgmac_config_powerup(struct fxgmac_pdata *priv)
+{
+ fxgmac_set_oob_wol(priv, 0);
+ /* GAMC power up */
+ fxgmac_io_wr_bits(priv, MAC_PMT_STA, MAC_PMT_STA_PWRDWN, 0);
+}
+
+static void fxgmac_pre_powerdown(struct fxgmac_pdata *priv)
+{
+ fxgmac_set_oob_wol(priv, 1);
+ fsleep(2000);
+}
+
+static void fxgmac_restore_nonstick_reg(struct fxgmac_pdata *priv)
+{
+ for (u32 i = GLOBAL_CTRL0; i < MSI_PBA; i += 4)
+ fxgmac_io_wr(priv, i,
+ priv->reg_nonstick[(i - GLOBAL_CTRL0) >> 2]);
+}
+
+static void fxgmac_phy_release(struct fxgmac_pdata *priv)
+{
+ fxgmac_io_wr_bits(priv, EPHY_CTRL, EPHY_CTRL_RESET, 1);
+ fsleep(100);
+}
+
+static void fxgmac_hw_exit(struct fxgmac_pdata *priv)
+{
+ /* Reset CHIP, it will reset trigger circuit and reload efuse patch */
+ fxgmac_io_wr_bits(priv, SYS_RESET, SYS_RESET_RESET, 1);
+ fsleep(9000);
+
+ fxgmac_phy_release(priv);
+
+ /* Reset will clear nonstick registers. */
+ fxgmac_restore_nonstick_reg(priv);
+}
+
+static void fxgmac_pcie_init(struct fxgmac_pdata *priv)
+{
+ /* snoopy + non-snoopy */
+ fxgmac_io_wr_bits(priv, LTR_IDLE_ENTER, LTR_IDLE_ENTER_REQUIRE, 1);
+ fxgmac_io_wr_bits(priv, LTR_IDLE_ENTER, LTR_IDLE_ENTER_SCALE,
+ LTR_IDLE_ENTER_SCALE_1024_NS);
+ fxgmac_io_wr_bits(priv, LTR_IDLE_ENTER, LTR_IDLE_ENTER_ENTER,
+ LTR_IDLE_ENTER_900_US);
+
+ /* snoopy + non-snoopy */
+ fxgmac_io_wr_bits(priv, LTR_IDLE_EXIT, LTR_IDLE_EXIT_REQUIRE, 1);
+ fxgmac_io_wr_bits(priv, LTR_IDLE_EXIT, LTR_IDLE_EXIT_SCALE, 2);
+ fxgmac_io_wr_bits(priv, LTR_IDLE_EXIT, LTR_IDLE_EXIT_EXIT,
+ LTR_IDLE_EXIT_171_US);
+
+ fxgmac_io_wr_bits(priv, PCIE_SERDES_PLL, PCIE_SERDES_PLL_AUTOOFF, 1);
+}
+
+static void fxgmac_phy_reset(struct fxgmac_pdata *priv)
+{
+ fxgmac_io_wr_bits(priv, EPHY_CTRL, EPHY_CTRL_RESET, 0);
+ fsleep(1500);
+}
+
+static int fxgmac_start(struct fxgmac_pdata *priv)
+{
+ int ret;
+
+ if (priv->dev_state != FXGMAC_DEV_OPEN &&
+ priv->dev_state != FXGMAC_DEV_STOP &&
+ priv->dev_state != FXGMAC_DEV_RESUME) {
+ return 0;
+ }
+
+ if (priv->dev_state != FXGMAC_DEV_STOP) {
+ fxgmac_phy_reset(priv);
+ fxgmac_phy_release(priv);
+ }
+
+ if (priv->dev_state == FXGMAC_DEV_OPEN) {
+ ret = fxgmac_phy_connect(priv);
+ if (ret < 0)
+ return ret;
+ }
+
+ fxgmac_pcie_init(priv);
+ if (test_bit(FXGMAC_POWER_STATE_DOWN, &priv->power_state)) {
+ dev_err(priv->dev, "fxgmac powerstate is %lu when config power up.\n",
+ priv->power_state);
+ }
+
+ fxgmac_config_powerup(priv);
+ fxgmac_dismiss_all_int(priv);
+ ret = fxgmac_hw_init(priv);
+ if (ret < 0) {
+ dev_err(priv->dev, "fxgmac hw init failed.\n");
+ return ret;
+ }
+
+ fxgmac_napi_enable(priv);
+ ret = fxgmac_request_irqs(priv);
+ if (ret < 0)
+ return ret;
+
+ /* Config interrupt to level signal */
+ fxgmac_io_wr_bits(priv, DMA_MR, DMA_MR_INTM, 2);
+ fxgmac_io_wr_bits(priv, DMA_MR, DMA_MR_QUREAD, 1);
+
+ fxgmac_enable_mgm_irq(priv);
+ fxgmac_set_interrupt_moderation(priv);
+
+ if (priv->per_channel_irq)
+ fxgmac_enable_msix_irqs(priv);
+
+ fxgmac_enable_dma_interrupts(priv);
+ priv->dev_state = FXGMAC_DEV_START;
+ phy_start(priv->phydev);
+
+ return 0;
+}
+
+static void fxgmac_disable_msix_irqs(struct fxgmac_pdata *priv)
+{
+ for (u32 intid = 0; intid < MSIX_TBL_MAX_NUM; intid++)
+ fxgmac_disable_msix_one_irq(priv, intid);
+}
+
+static void fxgmac_stop(struct fxgmac_pdata *priv)
+{
+ struct net_device *ndev = priv->ndev;
+ struct netdev_queue *txq;
+
+ if (priv->dev_state != FXGMAC_DEV_START)
+ return;
+
+ priv->dev_state = FXGMAC_DEV_STOP;
+
+ if (priv->per_channel_irq)
+ fxgmac_disable_msix_irqs(priv);
+ else
+ fxgmac_disable_mgm_irq(priv);
+
+ netif_carrier_off(ndev);
+ netif_tx_stop_all_queues(ndev);
+ fxgmac_disable_tx(priv);
+ fxgmac_disable_rx(priv);
+ fxgmac_free_irqs(priv);
+ fxgmac_napi_disable(priv);
+ phy_stop(priv->phydev);
+
+ txq = netdev_get_tx_queue(ndev, priv->channel_head->queue_index);
+ netdev_tx_reset_queue(txq);
+}
+
+static void fxgmac_restart(struct fxgmac_pdata *priv)
+{
+ int ret;
+
+ /* If not running, "restart" will happen on open */
+ if (!netif_running(priv->ndev) && priv->dev_state != FXGMAC_DEV_START)
+ return;
+
+ fxgmac_stop(priv);
+ fxgmac_free_tx_data(priv);
+ fxgmac_free_rx_data(priv);
+ ret = fxgmac_start(priv);
+ if (ret < 0)
+ dev_err(priv->dev, "fxgmac start failed:%d.\n", ret);
+}
+
+static void fxgmac_restart_work(struct work_struct *work)
+{
+ rtnl_lock();
+ fxgmac_restart(container_of(work, struct fxgmac_pdata, restart_work));
+ rtnl_unlock();
+}
+
+static int fxgmac_net_powerup(struct fxgmac_pdata *priv)
+{
+ int ret;
+
+ priv->power_state = 0;/* clear all bits as normal now */
+ ret = fxgmac_start(priv);
+ if (ret < 0) {
+ dev_err(priv->dev, "fxgmac start failed:%d.\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void fxgmac_config_powerdown(struct fxgmac_pdata *priv)
+{
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_RE, 1); /* Enable MAC Rx */
+ fxgmac_io_wr_bits(priv, MAC_CR, MAC_CR_TE, 1); /* Enable MAC TX */
+
+ /* Set GAMC power down */
+ fxgmac_io_wr_bits(priv, MAC_PMT_STA, MAC_PMT_STA_PWRDWN, 1);
+}
+
+static int fxgmac_net_powerdown(struct fxgmac_pdata *priv)
+{
+ struct net_device *ndev = priv->ndev;
+
+ /* Signal that we are down to the interrupt handler */
+ if (__test_and_set_bit(FXGMAC_POWER_STATE_DOWN, &priv->power_state))
+ return 0; /* do nothing if already down */
+
+ __clear_bit(FXGMAC_POWER_STATE_UP, &priv->power_state);
+ netif_tx_stop_all_queues(ndev); /* Shut off incoming Tx traffic */
+
+ /* Call carrier off first to avoid false dev_watchdog timeouts */
+ netif_carrier_off(ndev);
+ netif_tx_disable(ndev);
+ fxgmac_disable_rx(priv);
+
+ /* Synchronize_rcu() needed for pending XDP buffers to drain */
+ synchronize_rcu();
+
+ fxgmac_stop(priv);
+ fxgmac_pre_powerdown(priv);
+
+ if (!test_bit(FXGMAC_POWER_STATE_DOWN, &priv->power_state))
+ dev_err(priv->dev, "fxgmac powerstate is %lu when config powe down.\n",
+ priv->power_state);
+
+ /* Set mac to lowpower mode */
+ fxgmac_config_powerdown(priv);
+ fxgmac_free_tx_data(priv);
+ fxgmac_free_rx_data(priv);
+
+ return 0;
+}
+
+static int fxgmac_calc_rx_buf_size(struct fxgmac_pdata *priv, unsigned int mtu)
+{
+ u32 rx_buf_size, max_mtu = FXGMAC_JUMBO_PACKET_MTU - ETH_HLEN;
+
+ if (mtu > max_mtu) {
+ dev_err(priv->dev, "MTU exceeds maximum supported value\n");
+ return -EINVAL;
+ }
+
+ rx_buf_size = mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
+ rx_buf_size =
+ clamp_val(rx_buf_size, FXGMAC_RX_MIN_BUF_SIZE, PAGE_SIZE * 4);
+
+ rx_buf_size = (rx_buf_size + FXGMAC_RX_BUF_ALIGN - 1) &
+ ~(FXGMAC_RX_BUF_ALIGN - 1);
+
+ return rx_buf_size;
+}
+
+static int fxgmac_open(struct net_device *ndev)
+{
+ struct fxgmac_pdata *priv = netdev_priv(ndev);
+ int ret;
+
+ priv->dev_state = FXGMAC_DEV_OPEN;
+
+ /* Calculate the Rx buffer size before allocating rings */
+ ret = fxgmac_calc_rx_buf_size(priv, ndev->mtu);
+ if (ret < 0)
+ goto unlock;
+
+ priv->rx_buf_size = ret;
+ ret = fxgmac_channels_rings_alloc(priv);
+ if (ret < 0)
+ goto unlock;
+
+ INIT_WORK(&priv->restart_work, fxgmac_restart_work);
+ ret = fxgmac_start(priv);
+ if (ret < 0)
+ goto err_channels_and_rings;
+
+ return 0;
+
+err_channels_and_rings:
+ fxgmac_channels_rings_free(priv);
+ dev_err(priv->dev, "%s, channel alloc failed\n", __func__);
+unlock:
+ rtnl_unlock();
+ return ret;
+}
+
+static int fxgmac_close(struct net_device *ndev)
+{
+ struct fxgmac_pdata *priv = netdev_priv(ndev);
+
+ fxgmac_stop(priv); /* Stop the device */
+ priv->dev_state = FXGMAC_DEV_CLOSE;
+ fxgmac_channels_rings_free(priv); /* Free the channels and rings */
+ fxgmac_phy_reset(priv);
+ phy_disconnect(priv->phydev);
+
+ return 0;
+}
+
+static void fxgmac_dump_state(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_channel *channel = priv->channel_head;
+ struct fxgmac_ring *ring = &channel->tx_ring[0];
+ struct device *pdev = priv->dev;
+
+ dev_err(pdev, "Tx descriptor info:\n");
+ dev_err(pdev, " cur = 0x%x\n", ring->cur);
+ dev_err(pdev, " dirty = 0x%x\n", ring->dirty);
+ dev_err(pdev, " dma_desc_head = %pad\n", &ring->dma_desc_head);
+ dev_err(pdev, " desc_data_head = %pad\n", &ring->desc_data_head);
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++) {
+ ring = &channel->rx_ring[0];
+ dev_err(pdev, "Rx[%d] descriptor info:\n", i);
+ dev_err(pdev, " cur = 0x%x\n", ring->cur);
+ dev_err(pdev, " dirty = 0x%x\n", ring->dirty);
+ dev_err(pdev, " dma_desc_head = %pad\n", &ring->dma_desc_head);
+ dev_err(pdev, " desc_data_head = %pad\n",
+ &ring->desc_data_head);
+ }
+
+ dev_err(pdev, "Device Registers:\n");
+ dev_err(pdev, "MAC_ISR = %08x\n", fxgmac_io_rd(priv, MAC_ISR));
+ dev_err(pdev, "MAC_IER = %08x\n", fxgmac_io_rd(priv, MAC_IER));
+ dev_err(pdev, "MMC_RISR = %08x\n", fxgmac_io_rd(priv, MMC_RISR));
+ dev_err(pdev, "MMC_RIER = %08x\n", fxgmac_io_rd(priv, MMC_RIER));
+ dev_err(pdev, "MMC_TISR = %08x\n", fxgmac_io_rd(priv, MMC_TISR));
+ dev_err(pdev, "MMC_TIER = %08x\n", fxgmac_io_rd(priv, MMC_TIER));
+
+ dev_err(pdev, "EPHY_CTRL = %04x\n", fxgmac_io_rd(priv, EPHY_CTRL));
+ dev_err(pdev, "MGMT_INT_CTRL0 = %04x\n",
+ fxgmac_io_rd(priv, MGMT_INT_CTRL0));
+ dev_err(pdev, "MSIX_TBL_MASK = %04x\n",
+ fxgmac_io_rd(priv, MSIX_TBL_MASK));
+
+ dev_err(pdev, "Dump nonstick regs:\n");
+ for (u32 i = GLOBAL_CTRL0; i < MSI_PBA; i += 4)
+ dev_err(pdev, "[%d] = %04x\n", i / 4, fxgmac_io_rd(priv, i));
+}
+
+static void fxgmac_tx_timeout(struct net_device *ndev, unsigned int unused)
+{
+ struct fxgmac_pdata *priv = netdev_priv(ndev);
+
+ fxgmac_dump_state(priv);
+ schedule_work(&priv->restart_work);
+}
+
+#define EFUSE_FISRT_UPDATE_ADDR 255
+#define EFUSE_SECOND_UPDATE_ADDR 209
+#define EFUSE_MAX_ENTRY 39
+#define EFUSE_PATCH_ADDR_START 0
+#define EFUSE_PATCH_DATA_START 2
+#define EFUSE_PATCH_SIZE 6
+#define EFUSE_REGION_A_B_LENGTH 18
+
+static bool fxgmac_efuse_read_data(struct fxgmac_pdata *priv, u32 offset,
+ u8 *value)
+{
+ u32 val = 0, wait = 1000;
+ bool ret = false;
+
+ val |= field_prep(EFUSE_OP_ADDR, offset);
+ val |= EFUSE_OP_START;
+ val |= field_prep(EFUSE_OP_MODE, EFUSE_OP_MODE_ROW_READ);
+ fxgmac_io_wr(priv, EFUSE_OP_CTRL_0, val);
+
+ while (wait--) {
+ fsleep(20);
+ val = fxgmac_io_rd(priv, EFUSE_OP_CTRL_1);
+ if (field_get(EFUSE_OP_DONE, val)) {
+ ret = true;
+ break;
+ }
+ }
+
+ if (!ret) {
+ dev_err(priv->dev, "Reading efuse Byte:%d failed\n", offset);
+ return ret;
+ }
+
+ if (value)
+ *value = field_get(EFUSE_OP_RD_DATA, val) & 0xff;
+
+ return ret;
+}
+
+static bool fxgmac_efuse_read_index_patch(struct fxgmac_pdata *priv, u8 index,
+ u32 *offset, u32 *value)
+{
+ u8 tmp[EFUSE_PATCH_SIZE - EFUSE_PATCH_DATA_START];
+ u32 addr, i;
+ bool ret;
+
+ if (index >= EFUSE_MAX_ENTRY) {
+ dev_err(priv->dev, "Reading efuse out of range, index %d\n",
+ index);
+ return false;
+ }
+
+ for (i = EFUSE_PATCH_ADDR_START; i < EFUSE_PATCH_DATA_START; i++) {
+ addr = EFUSE_REGION_A_B_LENGTH + index * EFUSE_PATCH_SIZE + i;
+ ret = fxgmac_efuse_read_data(priv, addr,
+ tmp + i - EFUSE_PATCH_ADDR_START);
+ if (!ret) {
+ dev_err(priv->dev, "Reading efuse Byte:%d failed\n",
+ addr);
+ return ret;
+ }
+ }
+ /* tmp[0] is low 8bit date, tmp[1] is high 8bit date */
+ if (offset)
+ *offset = tmp[0] | (tmp[1] << 8);
+
+ for (i = EFUSE_PATCH_DATA_START; i < EFUSE_PATCH_SIZE; i++) {
+ addr = EFUSE_REGION_A_B_LENGTH + index * EFUSE_PATCH_SIZE + i;
+ ret = fxgmac_efuse_read_data(priv, addr,
+ tmp + i - EFUSE_PATCH_DATA_START);
+ if (!ret) {
+ dev_err(priv->dev, "Reading efuse Byte:%d failed\n",
+ addr);
+ return ret;
+ }
+ }
+ /* tmp[0] is low 8bit date, tmp[1] is low 8bit date
+ * ... tmp[3] is highest 8bit date
+ */
+ if (value)
+ *value = tmp[0] | (tmp[1] << 8) | (tmp[2] << 16) |
+ (tmp[3] << 24);
+
+ return ret;
+}
+
+static bool fxgmac_efuse_read_mac_subsys(struct fxgmac_pdata *priv,
+ u8 *mac_addr, u32 *subsys, u32 *revid)
+{
+ u32 machr = 0, maclr = 0, offset = 0, val = 0;
+
+ for (u8 index = 0; index < EFUSE_MAX_ENTRY; index++) {
+ if (!fxgmac_efuse_read_index_patch(priv, index, &offset, &val))
+ return false;
+
+ if (offset == 0x00)
+ break; /* Reach the blank. */
+ if (offset == MACA0LR_FROM_EFUSE)
+ maclr = val;
+ if (offset == MACA0HR_FROM_EFUSE)
+ machr = val;
+ if (offset == PCI_REVISION_ID && revid)
+ *revid = val;
+ if (offset == PCI_SUBSYSTEM_VENDOR_ID && subsys)
+ *subsys = val;
+ }
+
+ if (mac_addr) {
+ mac_addr[5] = (u8)(maclr & 0xFF);
+ mac_addr[4] = (u8)((maclr >> 8) & 0xFF);
+ mac_addr[3] = (u8)((maclr >> 16) & 0xFF);
+ mac_addr[2] = (u8)((maclr >> 24) & 0xFF);
+ mac_addr[1] = (u8)(machr & 0xFF);
+ mac_addr[0] = (u8)((machr >> 8) & 0xFF);
+ }
+
+ return true;
+}
+
+static int fxgmac_read_mac_addr(struct fxgmac_pdata *priv)
+{
+ u8 default_addr[ETH_ALEN] = { 0, 0x55, 0x7b, 0xb5, 0x7d, 0xf7 };
+ struct net_device *ndev = priv->ndev;
+ int ret;
+
+ /* If efuse have mac addr, use it. if not, use static mac address. */
+ ret = fxgmac_efuse_read_mac_subsys(priv, priv->mac_addr, NULL, NULL);
+ if (!ret)
+ return -1;
+
+ if (is_zero_ether_addr(priv->mac_addr))
+ /* Use a static mac address for test */
+ memcpy(priv->mac_addr, default_addr, ndev->addr_len);
+
+ return 0;
+}
+
+static void fxgmac_default_config(struct fxgmac_pdata *priv)
+{
+ priv->sysclk_rate = 125000000; /* System clock is 125 MHz */
+ priv->tx_threshold = MTL_Q_TQOMR_TTC_THRESHOLD_128;
+ priv->rx_threshold = MTL_Q_RQOMR_RTC_THRESHOLD_128;
+ priv->tx_osp_mode = 1; /* Enable DMA OSP */
+ priv->tx_sf_mode = 1; /* Enable MTL TSF */
+ priv->rx_sf_mode = 1; /* Enable MTL RSF */
+ priv->pblx8 = 1; /* Enable DMA PBL X8 */
+ priv->tx_pause = 1; /* Enable tx pause */
+ priv->rx_pause = 1; /* Enable rx pause */
+ priv->tx_pbl = DMA_CH_PBL_16;
+ priv->rx_pbl = DMA_CH_PBL_4;
+
+ fxgmac_default_speed_duplex_config(priv);
+}
+
+static void fxgmac_get_all_hw_features(struct fxgmac_pdata *priv)
+{
+ struct fxgmac_hw_features *hw_feat = &priv->hw_feat;
+ unsigned int mac_hfr0, mac_hfr1, mac_hfr2, mac_hfr3;
+
+ mac_hfr0 = fxgmac_io_rd(priv, MAC_HWF0R);
+ mac_hfr1 = fxgmac_io_rd(priv, MAC_HWF1R);
+ mac_hfr2 = fxgmac_io_rd(priv, MAC_HWF2R);
+ mac_hfr3 = fxgmac_io_rd(priv, MAC_HWF3R);
+ memset(hw_feat, 0, sizeof(*hw_feat));
+ hw_feat->version = fxgmac_io_rd(priv, MAC_VR);
+
+ /* Hardware feature register 0 */
+ hw_feat->phyifsel = field_get(MAC_HWF0R_ACTPHYIFSEL, mac_hfr0);
+ hw_feat->vlhash = field_get(MAC_HWF0R_VLHASH, mac_hfr0);
+ hw_feat->sma = field_get(MAC_HWF0R_SMASEL, mac_hfr0);
+ hw_feat->rwk = field_get(MAC_HWF0R_RWKSEL, mac_hfr0);
+ hw_feat->mgk = field_get(MAC_HWF0R_MGKSEL, mac_hfr0);
+ hw_feat->mmc = field_get(MAC_HWF0R_MMCSEL, mac_hfr0);
+ hw_feat->aoe = field_get(MAC_HWF0R_ARPOFFSEL, mac_hfr0);
+ hw_feat->ts = field_get(MAC_HWF0R_TSSEL, mac_hfr0);
+ hw_feat->eee = field_get(MAC_HWF0R_EEESEL, mac_hfr0);
+ hw_feat->tx_coe = field_get(MAC_HWF0R_TXCOESEL, mac_hfr0);
+ hw_feat->rx_coe = field_get(MAC_HWF0R_RXCOESEL, mac_hfr0);
+ hw_feat->addn_mac = field_get(MAC_HWF0R_ADDMACADRSEL, mac_hfr0);
+ hw_feat->ts_src = field_get(MAC_HWF0R_TSSTSSEL, mac_hfr0);
+ hw_feat->sa_vlan_ins = field_get(MAC_HWF0R_SAVLANINS, mac_hfr0);
+
+ /* Hardware feature register 1 */
+ hw_feat->rx_fifo_size = field_get(MAC_HWF1R_RXFIFOSIZE, mac_hfr1);
+ hw_feat->tx_fifo_size = field_get(MAC_HWF1R_TXFIFOSIZE, mac_hfr1);
+ hw_feat->adv_ts_hi = field_get(MAC_HWF1R_ADVTHWORD, mac_hfr1);
+ hw_feat->dma_width = field_get(MAC_HWF1R_ADDR64, mac_hfr1);
+ hw_feat->dcb = field_get(MAC_HWF1R_DCBEN, mac_hfr1);
+ hw_feat->sph = field_get(MAC_HWF1R_SPHEN, mac_hfr1);
+ hw_feat->tso = field_get(MAC_HWF1R_TSOEN, mac_hfr1);
+ hw_feat->dma_debug = field_get(MAC_HWF1R_DBGMEMA, mac_hfr1);
+ hw_feat->avsel = field_get(MAC_HWF1R_AVSEL, mac_hfr1);
+ hw_feat->ravsel = field_get(MAC_HWF1R_RAVSEL, mac_hfr1);
+ hw_feat->hash_table_size = field_get(MAC_HWF1R_HASHTBLSZ, mac_hfr1);
+ hw_feat->l3l4_filter_num = field_get(MAC_HWF1R_L3L4FNUM, mac_hfr1);
+ hw_feat->tx_q_cnt = field_get(MAC_HWF2R_TXQCNT, mac_hfr1);
+ hw_feat->rx_ch_cnt = field_get(MAC_HWF2R_RXCHCNT, mac_hfr1);
+ hw_feat->tx_ch_cnt = field_get(MAC_HWF2R_TXCHCNT, mac_hfr1);
+ hw_feat->pps_out_num = field_get(MAC_HWF2R_PPSOUTNUM, mac_hfr1);
+ hw_feat->aux_snap_num = field_get(MAC_HWF2R_AUXSNAPNUM, mac_hfr1);
+
+ /* Translate the Hash Table size into actual number */
+ switch (hw_feat->hash_table_size) {
+ case 0:
+ break;
+ case 1:
+ hw_feat->hash_table_size = 64;
+ break;
+ case 2:
+ hw_feat->hash_table_size = 128;
+ break;
+ case 3:
+ hw_feat->hash_table_size = 256;
+ break;
+ }
+
+ /* Translate the address width setting into actual number */
+ switch (hw_feat->dma_width) {
+ case 0:
+ hw_feat->dma_width = 32;
+ break;
+ case 1:
+ hw_feat->dma_width = 40;
+ break;
+ case 2:
+ hw_feat->dma_width = 48;
+ break;
+ default:
+ hw_feat->dma_width = 32;
+ }
+
+ /* The Queue, Channel are zero based so increment them
+ * to get the actual number
+ */
+ hw_feat->tx_q_cnt++;
+ hw_feat->rx_ch_cnt++;
+ hw_feat->tx_ch_cnt++;
+
+ /* HW implement 1 rx fifo, 4 dma channel. but from software
+ * we see 4 logical queues. hardcode to 4 queues.
+ */
+ hw_feat->rx_q_cnt = 4;
+ hw_feat->hwfr3 = mac_hfr3;
+}
+
+static unsigned int fxgmac_usec_to_riwt(struct fxgmac_pdata *priv,
+ unsigned int usec)
+{
+ /* Convert the input usec value to the watchdog timer value. Each
+ * watchdog timer value is equivalent to 256 clock cycles.
+ * Calculate the required value as:
+ * ( usec * ( system_clock_mhz / 10^6) / 256
+ */
+ return (usec * (priv->sysclk_rate / 1000000)) / 256;
+}
+
+static void fxgmac_save_nonstick_reg(struct fxgmac_pdata *priv)
+{
+ for (u32 i = GLOBAL_CTRL0; i < MSI_PBA; i += 4) {
+ priv->reg_nonstick[(i - GLOBAL_CTRL0) >> 2] =
+ fxgmac_io_rd(priv, i);
+ }
+}
+
+static int fxgmac_init(struct fxgmac_pdata *priv, bool save_private_reg)
+{
+ struct net_device *ndev = priv->ndev;
+ int ret;
+
+ fxgmac_default_config(priv); /* Set default configuration data */
+ ndev->irq = priv->dev_irq;
+ ndev->base_addr = (unsigned long)priv->hw_addr;
+
+ ret = fxgmac_read_mac_addr(priv);
+ if (ret) {
+ dev_err(priv->dev, "Read mac addr failed:%d\n", ret);
+ return ret;
+ }
+ eth_hw_addr_set(ndev, priv->mac_addr);
+
+ if (save_private_reg)
+ fxgmac_save_nonstick_reg(priv);
+
+ fxgmac_hw_exit(priv); /* Reset here to get hw features correctly */
+ fxgmac_get_all_hw_features(priv);
+
+ /* Set the DMA mask */
+ ret = dma_set_mask_and_coherent(priv->dev,
+ DMA_BIT_MASK(priv->hw_feat.dma_width));
+ if (ret) {
+ ret = dma_set_mask_and_coherent(priv->dev, DMA_BIT_MASK(32));
+ if (ret) {
+ dev_err(priv->dev, "No usable DMA configuration, aborting\n");
+ return ret;
+ }
+ }
+
+ if (field_get(INT_FLAG_LEGACY, priv->int_flag)) {
+ /* We should disable msi and msix here when we use legacy
+ * interrupt,for two reasons:
+ * 1. Exit will restore msi and msix config regisiter,
+ * that may enable them.
+ * 2. When the driver that uses the msix interrupt by default
+ * is compiled into the OS, uninstall the driver through rmmod,
+ * and then install the driver that uses the legacy interrupt,
+ * at which time the msix enable will be turned on again by
+ * default after waking up from S4 on some
+ * platform. such as UOS platform.
+ */
+ pci_disable_msi(to_pci_dev(priv->dev));
+ pci_disable_msix(to_pci_dev(priv->dev));
+ }
+
+ BUILD_BUG_ON_NOT_POWER_OF_2(FXGMAC_TX_DESC_CNT);
+ priv->tx_desc_count = FXGMAC_TX_DESC_CNT;
+ BUILD_BUG_ON_NOT_POWER_OF_2(FXGMAC_RX_DESC_CNT);
+ priv->rx_desc_count = FXGMAC_RX_DESC_CNT;
+
+ ret = netif_set_real_num_tx_queues(ndev, FXGMAC_TX_1_Q);
+ if (ret) {
+ dev_err(priv->dev, "Setting real tx queue count failed\n");
+ return ret;
+ }
+
+ priv->rx_ring_count = min_t(unsigned int,
+ netif_get_num_default_rss_queues(),
+ priv->hw_feat.rx_ch_cnt);
+ priv->rx_ring_count = min_t(unsigned int, priv->rx_ring_count,
+ priv->hw_feat.rx_q_cnt);
+ priv->rx_q_count = priv->rx_ring_count;
+ ret = netif_set_real_num_rx_queues(ndev, priv->rx_q_count);
+ if (ret) {
+ dev_err(priv->dev, "Setting real rx queue count failed\n");
+ return ret;
+ }
+
+ priv->channel_count =
+ max_t(unsigned int, FXGMAC_TX_1_RING, priv->rx_ring_count);
+
+ ndev->min_mtu = ETH_MIN_MTU;
+ ndev->max_mtu =
+ FXGMAC_JUMBO_PACKET_MTU + (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN);
+
+ ndev->netdev_ops = fxgmac_get_netdev_ops();/* Set device operations */
+
+ /* Set device features */
+ if (priv->hw_feat.tso) {
+ ndev->hw_features = NETIF_F_TSO;
+ ndev->hw_features |= NETIF_F_TSO6;
+ ndev->hw_features |= NETIF_F_SG;
+ ndev->hw_features |= NETIF_F_IP_CSUM;
+ ndev->hw_features |= NETIF_F_IPV6_CSUM;
+ } else if (priv->hw_feat.tx_coe) {
+ ndev->hw_features = NETIF_F_IP_CSUM;
+ ndev->hw_features |= NETIF_F_IPV6_CSUM;
+ }
+
+ if (priv->hw_feat.rx_coe) {
+ ndev->hw_features |= NETIF_F_RXCSUM;
+ ndev->hw_features |= NETIF_F_GRO;
+ }
+
+ ndev->hw_features |= NETIF_F_RXHASH;
+ ndev->vlan_features |= ndev->hw_features;
+ ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
+
+ if (priv->hw_feat.sa_vlan_ins)
+ ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX;
+
+ ndev->features |= ndev->hw_features;
+
+ ndev->priv_flags |= IFF_UNICAST_FLT;
+ ndev->watchdog_timeo = msecs_to_jiffies(5000);
+
+#define NIC_MAX_TCP_OFFLOAD_SIZE 7300
+ netif_set_tso_max_size(ndev, NIC_MAX_TCP_OFFLOAD_SIZE);
+
+/* Default coalescing parameters */
+#define FXGMAC_INIT_DMA_TX_USECS INT_MOD_200_US
+#define FXGMAC_INIT_DMA_TX_FRAMES 25
+#define FXGMAC_INIT_DMA_RX_USECS INT_MOD_200_US
+#define FXGMAC_INIT_DMA_RX_FRAMES 25
+
+ /* Tx coalesce parameters initialization */
+ priv->tx_usecs = FXGMAC_INIT_DMA_TX_USECS;
+ priv->tx_frames = FXGMAC_INIT_DMA_TX_FRAMES;
+
+ /* Rx coalesce parameters initialization */
+ priv->rx_riwt = fxgmac_usec_to_riwt(priv, FXGMAC_INIT_DMA_RX_USECS);
+ priv->rx_usecs = FXGMAC_INIT_DMA_RX_USECS;
+ priv->rx_frames = FXGMAC_INIT_DMA_RX_FRAMES;
+
+ return 0;
+}
+
+static void fxgmac_init_interrupt_scheme(struct fxgmac_pdata *priv)
+{
+ struct pci_dev *pdev = to_pci_dev(priv->dev);
+ int req_vectors = FXGMAC_MAX_DMA_CHANNELS;
+
+ /* Since we have FXGMAC_MAX_DMA_CHANNELS channels, we must ensure the
+ * number of cpu core is ok. otherwise, just roll back to legacy.
+ */
+ if (num_online_cpus() < FXGMAC_MAX_DMA_CHANNELS - 1)
+ goto enable_msi_interrupt;
+
+ priv->msix_entries =
+ kcalloc(req_vectors, sizeof(struct msix_entry), GFP_KERNEL);
+ if (!priv->msix_entries)
+ goto enable_msi_interrupt;
+
+ for (u32 i = 0; i < req_vectors; i++)
+ priv->msix_entries[i].entry = i;
+
+ if (pci_enable_msix_exact(pdev, priv->msix_entries, req_vectors) < 0) {
+ /* Roll back to msi */
+ kfree(priv->msix_entries);
+ priv->msix_entries = NULL;
+ dev_err(priv->dev, "Enable MSIx failed, clear msix entries.\n");
+ goto enable_msi_interrupt;
+ }
+
+ priv->int_flag &= ~INT_FLAG_INTERRUPT;
+ priv->int_flag |= INT_FLAG_MSIX;
+ priv->per_channel_irq = 1;
+ return;
+
+enable_msi_interrupt:
+ priv->int_flag &= ~INT_FLAG_INTERRUPT;
+ if (pci_enable_msi(pdev) < 0) {
+ priv->int_flag |= INT_FLAG_LEGACY;
+ dev_err(priv->dev, "rollback to LEGACY.\n");
+ } else {
+ priv->int_flag |= INT_FLAG_MSI;
+ dev_err(priv->dev, "rollback to MSI.\n");
+ priv->dev_irq = pdev->irq;
+ }
+}
+
+static int fxgmac_drv_probe(struct device *dev, struct fxgmac_resources *res)
+{
+ struct fxgmac_pdata *priv;
+ struct net_device *ndev;
+ int ret;
+
+ ndev = alloc_etherdev_mq(sizeof(struct fxgmac_pdata),
+ FXGMAC_MAX_DMA_RX_CHANNELS);
+ if (!ndev)
+ return -ENOMEM;
+
+ SET_NETDEV_DEV(ndev, dev);
+ priv = netdev_priv(ndev);
+
+ priv->dev = dev;
+ priv->ndev = ndev;
+ priv->dev_irq = res->irq;
+ priv->hw_addr = res->addr;
+ priv->msg_enable = NETIF_MSG_DRV;
+ priv->dev_state = FXGMAC_DEV_PROBE;
+
+ /* Default to legacy interrupt */
+ priv->int_flag &= ~INT_FLAG_INTERRUPT;
+ priv->int_flag |= INT_FLAG_LEGACY;
+
+ pci_set_drvdata(to_pci_dev(priv->dev), priv);
+
+ if (IS_ENABLED(CONFIG_PCI_MSI))
+ fxgmac_init_interrupt_scheme(priv);
+
+ ret = fxgmac_init(priv, true);
+ if (ret < 0) {
+ dev_err(dev, "fxgmac init failed:%d\n", ret);
+ goto err_free_netdev;
+ }
+
+ fxgmac_phy_reset(priv);
+ fxgmac_phy_release(priv);
+ ret = fxgmac_mdio_register(priv);
+ if (ret < 0) {
+ dev_err(dev, "Register fxgmac mdio failed:%d\n", ret);
+ goto err_free_netdev;
+ }
+
+ netif_carrier_off(ndev);
+ ret = register_netdev(ndev);
+ if (ret) {
+ dev_err(dev, "Register ndev failed:%d\n", ret);
+ goto err_free_netdev;
+ }
+
+ return 0;
+
+err_free_netdev:
+ free_netdev(ndev);
+ return ret;
+}
+
+static void fxgmac_dbg_pkt(struct fxgmac_pdata *priv, struct sk_buff *skb,
+ bool tx_rx)
+{
+ struct ethhdr *eth = (struct ethhdr *)skb->data;
+ unsigned char buffer[128];
+
+ dev_dbg(priv->dev, "\n************** SKB dump ****************\n");
+ dev_dbg(priv->dev, "%s, packet of %d bytes\n", (tx_rx ? "TX" : "RX"),
+ skb->len);
+ dev_dbg(priv->dev, "Dst MAC addr: %pM\n", eth->h_dest);
+ dev_dbg(priv->dev, "Src MAC addr: %pM\n", eth->h_source);
+ dev_dbg(priv->dev, "Protocol: %#06x\n", ntohs(eth->h_proto));
+
+ for (u32 i = 0; i < skb->len; i += 32) {
+ unsigned int len = min(skb->len - i, 32U);
+
+ hex_dump_to_buffer(&skb->data[i], len, 32, 1, buffer,
+ sizeof(buffer), false);
+ dev_dbg(priv->dev, " %#06x: %s\n", i, buffer);
+ }
+
+ dev_dbg(priv->dev, "\n************** SKB dump ****************\n");
+}
+
+static void fxgmac_dev_xmit(struct fxgmac_channel *channel)
+{
+ struct fxgmac_pdata *priv = channel->priv;
+ struct fxgmac_ring *ring = channel->tx_ring;
+ unsigned int tso_context, vlan_context;
+ struct fxgmac_desc_data *desc_data;
+ struct fxgmac_dma_desc *dma_desc;
+ struct fxgmac_pkt_info *pkt_info;
+ unsigned int csum, tso, vlan;
+ int i, start_index = ring->cur;
+ int cur_index = ring->cur;
+
+ pkt_info = &ring->pkt_info;
+ csum = field_get(ATTR_TX_CSUM_ENABLE, pkt_info->attr);
+ tso = field_get(ATTR_TX_TSO_ENABLE, pkt_info->attr);
+ vlan = field_get(ATTR_TX_VLAN_CTAG, pkt_info->attr);
+
+ if (tso && pkt_info->mss != ring->tx.cur_mss)
+ tso_context = 1;
+ else
+ tso_context = 0;
+
+ if (vlan && pkt_info->vlan_ctag != ring->tx.cur_vlan_ctag)
+ vlan_context = 1;
+ else
+ vlan_context = 0;
+
+ desc_data = FXGMAC_GET_DESC_DATA(ring, cur_index);
+ dma_desc = desc_data->dma_desc;
+
+ /* Create a context descriptor if this is a TSO pkt_info */
+ if (tso_context) {
+ /* Set the MSS size */
+ fxgmac_desc_wr_bits(&dma_desc->desc2, TX_CONTEXT_DESC2_MSS,
+ pkt_info->mss);
+
+ /* Mark it as a CONTEXT descriptor */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_CONTEXT_DESC3_CTXT, 1);
+
+ /* Indicate this descriptor contains the MSS */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_CONTEXT_DESC3_TCMSSV,
+ 1);
+
+ ring->tx.cur_mss = pkt_info->mss;
+ }
+
+ if (vlan_context) {
+ /* Mark it as a CONTEXT descriptor */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_CONTEXT_DESC3_CTXT, 1);
+
+ /* Set the VLAN tag */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_CONTEXT_DESC3_VT,
+ pkt_info->vlan_ctag);
+
+ /* Indicate this descriptor contains the VLAN tag */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_CONTEXT_DESC3_VLTV, 1);
+
+ ring->tx.cur_vlan_ctag = pkt_info->vlan_ctag;
+ }
+ if (tso_context || vlan_context) {
+ cur_index = FXGMAC_GET_ENTRY(cur_index, ring->dma_desc_count);
+ desc_data = FXGMAC_GET_DESC_DATA(ring, cur_index);
+ dma_desc = desc_data->dma_desc;
+ }
+
+ /* Update buffer address (for TSO this is the header) */
+ dma_desc->desc0 = cpu_to_le32(lower_32_bits(desc_data->skb_dma));
+ dma_desc->desc1 = cpu_to_le32(upper_32_bits(desc_data->skb_dma));
+
+ /* Update the buffer length */
+ fxgmac_desc_wr_bits(&dma_desc->desc2, TX_DESC2_HL_B1L,
+ desc_data->skb_dma_len);
+
+ /* VLAN tag insertion check */
+ if (vlan)
+ fxgmac_desc_wr_bits(&dma_desc->desc2, TX_DESC2_VTIR, 2);
+
+ /* Timestamp enablement check */
+ if (field_get(ATTR_TX_PTP, pkt_info->attr))
+ fxgmac_desc_wr_bits(&dma_desc->desc2, TX_DESC2_TTSE, 1);
+
+ /* Mark it as First Descriptor */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_FD, 1);
+
+ /* Mark it as a NORMAL descriptor */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_CTXT, 0);
+
+ /* Set OWN bit if not the first descriptor */
+ if (cur_index != start_index)
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_OWN, 1);
+
+ if (tso) {
+ /* Enable TSO */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_TSE, 1);
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_TCPPL,
+ pkt_info->tcp_payload_len);
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_TCPHDRLEN,
+ pkt_info->tcp_header_len / 4);
+ } else {
+ /* Enable CRC and Pad Insertion */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_CPC, 0);
+
+ /* Enable HW CSUM */
+ if (csum)
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_CIC,
+ 0x3);
+
+ /* Set the total length to be transmitted */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_FL,
+ pkt_info->length);
+ }
+
+ if (start_index <= cur_index)
+ i = cur_index - start_index + 1;
+ else
+ i = ring->dma_desc_count - start_index + cur_index;
+
+ for (; i < pkt_info->desc_count; i++) {
+ cur_index = FXGMAC_GET_ENTRY(cur_index, ring->dma_desc_count);
+ desc_data = FXGMAC_GET_DESC_DATA(ring, cur_index);
+ dma_desc = desc_data->dma_desc;
+
+ /* Update buffer address */
+ dma_desc->desc0 =
+ cpu_to_le32(lower_32_bits(desc_data->skb_dma));
+ dma_desc->desc1 =
+ cpu_to_le32(upper_32_bits(desc_data->skb_dma));
+
+ /* Update the buffer length */
+ fxgmac_desc_wr_bits(&dma_desc->desc2, TX_DESC2_HL_B1L,
+ desc_data->skb_dma_len);
+
+ /* Set OWN bit */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_OWN, 1);
+
+ /* Mark it as NORMAL descriptor */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_CTXT, 0);
+
+ /* Enable HW CSUM */
+ if (csum)
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_CIC,
+ 0x3);
+ }
+
+ /* Set LAST bit for the last descriptor */
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_LD, 1);
+
+ fxgmac_desc_wr_bits(&dma_desc->desc2, TX_DESC2_IC, 1);
+
+ /* Save the Tx info to report back during cleanup */
+ desc_data->tx.packets = pkt_info->tx_packets;
+ desc_data->tx.bytes = pkt_info->tx_bytes;
+
+ /* In case the Tx DMA engine is running, make sure everything
+ * is written to the descriptor(s) before setting the OWN bit
+ * for the first descriptor
+ */
+ dma_wmb();
+
+ /* Set OWN bit for the first descriptor */
+ desc_data = FXGMAC_GET_DESC_DATA(ring, start_index);
+ dma_desc = desc_data->dma_desc;
+ fxgmac_desc_wr_bits(&dma_desc->desc3, TX_DESC3_OWN, 1);
+
+ if (netif_msg_tx_queued(priv))
+ fxgmac_dump_tx_desc(priv, ring, start_index,
+ pkt_info->desc_count, 1);
+
+ smp_wmb(); /* Make sure ownership is written to the descriptor */
+
+ ring->cur = FXGMAC_GET_ENTRY(cur_index, ring->dma_desc_count);
+ fxgmac_tx_start_xmit(channel, ring);
+}
+
+static void fxgmac_prep_vlan(struct sk_buff *skb,
+ struct fxgmac_pkt_info *pkt_info)
+{
+ if (skb_vlan_tag_present(skb))
+ pkt_info->vlan_ctag = skb_vlan_tag_get(skb);
+}
+
+static int fxgmac_prep_tso(struct fxgmac_pdata *priv, struct sk_buff *skb,
+ struct fxgmac_pkt_info *pkt_info)
+{
+ int ret;
+
+ if (!field_get(ATTR_TX_TSO_ENABLE, pkt_info->attr))
+ return 0;
+
+ ret = skb_cow_head(skb, 0);
+ if (ret)
+ return ret;
+
+ pkt_info->header_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ pkt_info->tcp_header_len = tcp_hdrlen(skb);
+ pkt_info->tcp_payload_len = skb->len - pkt_info->header_len;
+ pkt_info->mss = skb_shinfo(skb)->gso_size;
+
+ /* Update the number of packets that will ultimately be transmitted
+ * along with the extra bytes for each extra packet
+ */
+ pkt_info->tx_packets = skb_shinfo(skb)->gso_segs;
+ pkt_info->tx_bytes += (pkt_info->tx_packets - 1) * pkt_info->header_len;
+
+ return 0;
+}
+
+static int fxgmac_is_tso(struct sk_buff *skb)
+{
+ if (skb->ip_summed != CHECKSUM_PARTIAL)
+ return 0;
+
+ if (!skb_is_gso(skb))
+ return 0;
+
+ return 1;
+}
+
+static void fxgmac_prep_tx_pkt(struct fxgmac_pdata *priv,
+ struct fxgmac_ring *ring, struct sk_buff *skb,
+ struct fxgmac_pkt_info *pkt_info)
+{
+ u32 len, context_desc = 0;
+
+ pkt_info->skb = skb;
+ pkt_info->desc_count = 0;
+ pkt_info->tx_packets = 1;
+ pkt_info->tx_bytes = skb->len;
+
+ if (fxgmac_is_tso(skb)) {
+ /* TSO requires an extra descriptor if mss is different */
+ if (skb_shinfo(skb)->gso_size != ring->tx.cur_mss) {
+ context_desc = 1;
+ pkt_info->desc_count++;
+ }
+
+ /* TSO requires an extra descriptor for TSO header */
+ pkt_info->desc_count++;
+ pkt_info->attr |= (ATTR_TX_TSO_ENABLE | ATTR_TX_CSUM_ENABLE);
+ } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ pkt_info->attr |= ATTR_TX_CSUM_ENABLE;
+ }
+
+ if (skb_vlan_tag_present(skb)) {
+ /* VLAN requires an extra descriptor if tag is different */
+ if (skb_vlan_tag_get(skb) != ring->tx.cur_vlan_ctag)
+ /* We can share with the TSO context descriptor */
+ if (!context_desc)
+ pkt_info->desc_count++;
+
+ pkt_info->attr |= ATTR_TX_VLAN_CTAG;
+ }
+
+ for (len = skb_headlen(skb); len;) {
+ pkt_info->desc_count++;
+ len -= min_t(unsigned int, len, FXGMAC_TX_MAX_BUF_SIZE);
+ }
+
+ for (u32 i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+ for (len = skb_frag_size(&skb_shinfo(skb)->frags[i]); len;) {
+ pkt_info->desc_count++;
+ len -= min_t(unsigned int, len, FXGMAC_TX_MAX_BUF_SIZE);
+ }
+}
+
+static netdev_tx_t fxgmac_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ struct fxgmac_pdata *priv = netdev_priv(ndev);
+ struct fxgmac_pkt_info *tx_pkt_info;
+ struct fxgmac_channel *channel;
+ struct netdev_queue *txq;
+ struct fxgmac_ring *ring;
+ int ret;
+
+ channel = priv->channel_head + skb->queue_mapping;
+ txq = netdev_get_tx_queue(ndev, channel->queue_index);
+ ring = channel->tx_ring;
+ tx_pkt_info = &ring->pkt_info;
+
+ if (skb->len == 0) {
+ netdev_err(priv->ndev, "empty skb received from stack\n");
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+ /* Prepare preliminary packet info for TX */
+ memset(tx_pkt_info, 0, sizeof(*tx_pkt_info));
+ fxgmac_prep_tx_pkt(priv, ring, skb, tx_pkt_info);
+
+ /* Check that there are enough descriptors available */
+ ret = fxgmac_maybe_stop_tx_queue(channel, ring,
+ tx_pkt_info->desc_count);
+ if (ret == NETDEV_TX_BUSY)
+ return ret;
+
+ ret = fxgmac_prep_tso(priv, skb, tx_pkt_info);
+ if (ret < 0) {
+ netdev_err(priv->ndev, "processing TSO packet failed\n");
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+ fxgmac_prep_vlan(skb, tx_pkt_info);
+
+ if (!fxgmac_tx_skb_map(channel, skb)) {
+ dev_kfree_skb_any(skb);
+ netdev_err(priv->ndev, "xmit, map tx skb failed\n");
+ return NETDEV_TX_OK;
+ }
+
+ /* Report on the actual number of bytes (to be) sent */
+ netdev_tx_sent_queue(txq, tx_pkt_info->tx_bytes);
+
+ /* Configure required descriptor fields for transmission */
+ fxgmac_dev_xmit(channel);
+
+ if (netif_msg_pktdata(priv))
+ fxgmac_dbg_pkt(priv, skb, true);
+
+ /* Stop the queue in advance if there may not be enough descriptors */
+ fxgmac_maybe_stop_tx_queue(channel, ring, FXGMAC_TX_MAX_DESC_NR);
+
+ return NETDEV_TX_OK;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void fxgmac_poll_controller(struct net_device *ndev)
+{
+ struct fxgmac_pdata *priv = netdev_priv(ndev);
+ struct fxgmac_channel *channel;
+
+ if (priv->per_channel_irq) {
+ channel = priv->channel_head;
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ fxgmac_dma_isr(channel->dma_irq_rx, channel);
+ } else {
+ disable_irq(priv->dev_irq);
+ fxgmac_isr(priv->dev_irq, priv);
+ enable_irq(priv->dev_irq);
+ }
+}
+#endif /* CONFIG_NET_POLL_CONTROLLER */
+
+static const struct net_device_ops fxgmac_netdev_ops = {
+ .ndo_open = fxgmac_open,
+ .ndo_stop = fxgmac_close,
+ .ndo_start_xmit = fxgmac_xmit,
+ .ndo_tx_timeout = fxgmac_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = fxgmac_poll_controller,
+#endif
+};
+
+const struct net_device_ops *fxgmac_get_netdev_ops(void)
+{
+ return &fxgmac_netdev_ops;
+}
+
+static void fxgmac_rx_refresh(struct fxgmac_channel *channel)
+{
+ struct fxgmac_ring *ring = channel->rx_ring;
+ struct fxgmac_pdata *priv = channel->priv;
+ struct fxgmac_desc_data *desc_data;
+
+ while (ring->dirty != ring->cur) {
+ desc_data = FXGMAC_GET_DESC_DATA(ring, ring->dirty);
+
+ /* Reset desc_data values */
+ fxgmac_desc_data_unmap(priv, desc_data);
+
+ if (fxgmac_rx_buffe_map(priv, ring, desc_data))
+ break;
+
+ fxgmac_desc_rx_reset(desc_data);
+ ring->dirty =
+ FXGMAC_GET_ENTRY(ring->dirty, ring->dma_desc_count);
+ }
+
+ /* Make sure everything is written before the register write */
+ wmb();
+
+ /* Update the Rx Tail Pointer Register with address of
+ * the last cleaned entry
+ */
+ desc_data = FXGMAC_GET_DESC_DATA(ring, (ring->dirty - 1) &
+ (ring->dma_desc_count - 1));
+ fxgmac_dma_io_wr(channel, DMA_CH_RDTR_LO,
+ lower_32_bits(desc_data->dma_desc_addr));
+}
+
+static struct sk_buff *fxgmac_create_skb(struct fxgmac_pdata *priv,
+ struct napi_struct *napi,
+ struct fxgmac_desc_data *desc_data,
+ unsigned int len)
+{
+ unsigned int copy_len;
+ struct sk_buff *skb;
+ u8 *packet;
+
+ skb = napi_alloc_skb(napi, desc_data->rx.hdr.dma_len);
+ if (!skb)
+ return NULL;
+
+ /* Start with the header buffer which may contain just the header
+ * or the header plus data
+ */
+ dma_sync_single_range_for_cpu(priv->dev, desc_data->rx.hdr.dma_base,
+ desc_data->rx.hdr.dma_off,
+ desc_data->rx.hdr.dma_len,
+ DMA_FROM_DEVICE);
+
+ packet = page_address(desc_data->rx.hdr.pa.pages) +
+ desc_data->rx.hdr.pa.pages_offset;
+ copy_len = min(desc_data->rx.hdr.dma_len, len);
+ skb_copy_to_linear_data(skb, packet, copy_len);
+ skb_put(skb, copy_len);
+
+ return skb;
+}
+
+static int fxgmac_tx_poll(struct fxgmac_channel *channel)
+{
+ struct fxgmac_pdata *priv = channel->priv;
+ unsigned int cur, tx_packets = 0, tx_bytes = 0;
+ struct fxgmac_ring *ring = channel->tx_ring;
+ struct net_device *ndev = priv->ndev;
+ struct fxgmac_desc_data *desc_data;
+ struct fxgmac_dma_desc *dma_desc;
+ struct netdev_queue *txq;
+ int processed = 0;
+
+ /* Nothing to do if there isn't a Tx ring for this channel */
+ if (!ring)
+ return 0;
+
+ if (ring->cur != ring->dirty && (netif_msg_tx_done(priv)))
+ netdev_dbg(priv->ndev, "%s, ring_cur=%d,ring_dirty=%d,qIdx=%d\n",
+ __func__, ring->cur, ring->dirty,
+ channel->queue_index);
+
+ cur = ring->cur;
+
+ /* Be sure we get ring->cur before accessing descriptor data */
+ smp_rmb();
+
+ txq = netdev_get_tx_queue(ndev, channel->queue_index);
+ while (ring->dirty != cur) {
+ desc_data = FXGMAC_GET_DESC_DATA(ring, ring->dirty);
+ dma_desc = desc_data->dma_desc;
+
+ if (!fxgmac_is_tx_complete(dma_desc))
+ break;
+
+ /* Make sure descriptor fields are read after reading
+ * the OWN bit
+ */
+ dma_rmb();
+
+ if (netif_msg_tx_done(priv))
+ fxgmac_dump_tx_desc(priv, ring, ring->dirty, 1, 0);
+
+ if (fxgmac_is_last_desc(dma_desc)) {
+ tx_packets += desc_data->tx.packets;
+ tx_bytes += desc_data->tx.bytes;
+ }
+
+ /* Free the SKB and reset the descriptor for re-use */
+ fxgmac_desc_data_unmap(priv, desc_data);
+ fxgmac_desc_tx_reset(desc_data);
+
+ processed++;
+ ring->dirty =
+ FXGMAC_GET_ENTRY(ring->dirty, ring->dma_desc_count);
+ }
+
+ if (!processed)
+ return 0;
+
+ netdev_tx_completed_queue(txq, tx_packets, tx_bytes);
+
+ /* Make sure ownership is written to the descriptor */
+ smp_wmb();
+ if (ring->tx.queue_stopped == 1 &&
+ (fxgmac_desc_tx_avail(ring) > FXGMAC_TX_DESC_MIN_FREE)) {
+ ring->tx.queue_stopped = 0;
+ netif_tx_wake_queue(txq);
+ }
+
+ return processed;
+}
+
+static int fxgmac_one_poll_tx(struct napi_struct *napi, int budget)
+{
+ struct fxgmac_channel *channel =
+ container_of(napi, struct fxgmac_channel, napi_tx);
+ struct fxgmac_pdata *priv = channel->priv;
+ int ret;
+
+ ret = fxgmac_tx_poll(channel);
+ if (napi_complete_done(napi, 0))
+ fxgmac_enable_msix_one_irq(priv, MSI_ID_TXQ0);
+
+ return ret;
+}
+
+static int fxgmac_dev_read(struct fxgmac_channel *channel)
+{
+ struct fxgmac_pdata *priv = channel->priv;
+ struct fxgmac_ring *ring = channel->rx_ring;
+ struct net_device *ndev = priv->ndev;
+ static unsigned int cnt_incomplete;
+ struct fxgmac_desc_data *desc_data;
+ struct fxgmac_dma_desc *dma_desc;
+ struct fxgmac_pkt_info *pkt_info;
+ u32 ipce, iphe, rxparser;
+ unsigned int err, etlt;
+
+ desc_data = FXGMAC_GET_DESC_DATA(ring, ring->cur);
+ dma_desc = desc_data->dma_desc;
+ pkt_info = &ring->pkt_info;
+
+ /* Check for data availability */
+ if (fxgmac_desc_rd_bits(dma_desc->desc3, RX_DESC3_OWN))
+ return 1;
+
+ /* Make sure descriptor fields are read after reading the OWN bit */
+ dma_rmb();
+
+ if (netif_msg_rx_status(priv))
+ fxgmac_dump_rx_desc(priv, ring, ring->cur);
+
+ /* Normal Descriptor, be sure Context Descriptor bit is off */
+ pkt_info->attr &= ~ATTR_RX_CONTEXT;
+
+ /* Indicate if a Context Descriptor is next */
+ /* Get the header length */
+ if (fxgmac_desc_rd_bits(dma_desc->desc3, RX_DESC3_FD)) {
+ desc_data->rx.hdr_len = fxgmac_desc_rd_bits(dma_desc->desc2,
+ RX_DESC2_HL);
+ }
+
+ /* Get the pkt_info length */
+ desc_data->rx.len =
+ fxgmac_desc_rd_bits(dma_desc->desc3, RX_DESC3_PL);
+
+ if (!fxgmac_desc_rd_bits(dma_desc->desc3, RX_DESC3_LD)) {
+ /* Not all the data has been transferred for this pkt_info */
+ pkt_info->attr |= ATTR_RX_INCOMPLETE;
+ cnt_incomplete++;
+ return 0;
+ }
+
+ if ((cnt_incomplete) && netif_msg_rx_status(priv))
+ netdev_dbg(priv->ndev, "%s, rx back to normal and incomplete cnt=%u\n",
+ __func__, cnt_incomplete);
+ cnt_incomplete = 0;
+
+ /* This is the last of the data for this pkt_info */
+ pkt_info->attr &= ~ATTR_RX_INCOMPLETE;
+
+ /* Set checksum done indicator as appropriate */
+ if (ndev->features & NETIF_F_RXCSUM) {
+ ipce = fxgmac_desc_rd_bits(dma_desc->desc1, RX_DESC1_WB_IPCE);
+ iphe = fxgmac_desc_rd_bits(dma_desc->desc1, RX_DESC1_WB_IPHE);
+ if (!ipce && !iphe)
+ pkt_info->attr |= ATTR_RX_CSUM_DONE;
+ else
+ return 0;
+ }
+
+ /* Check for errors (only valid in last descriptor) */
+ err = fxgmac_desc_rd_bits(dma_desc->desc3, RX_DESC3_ES);
+ rxparser = fxgmac_desc_rd_bits(dma_desc->desc2, RX_DESC2_WB_RAPARSER);
+ /* Error or incomplete parsing due to ECC error */
+ if (err || rxparser == 0x7) {
+ pkt_info->errors |= ERRORS_RX_FRAME;
+ return 0;
+ }
+
+ etlt = fxgmac_desc_rd_bits(dma_desc->desc3, RX_DESC3_ETLT);
+ if (etlt == 0x4 && (ndev->features & NETIF_F_HW_VLAN_CTAG_RX)) {
+ pkt_info->attr |= ATTR_RX_VLAN_CTAG;
+ pkt_info->vlan_ctag = fxgmac_desc_rd_bits(dma_desc->desc0,
+ RX_DESC0_OVT);
+ }
+
+ return 0;
+}
+
+static unsigned int fxgmac_desc_rx_dirty(struct fxgmac_ring *ring)
+{
+ unsigned int dirty;
+
+ if (ring->dirty <= ring->cur)
+ dirty = ring->cur - ring->dirty;
+ else
+ dirty = ring->dma_desc_count - ring->dirty + ring->cur;
+
+ return dirty;
+}
+
+static int fxgmac_rx_poll(struct fxgmac_channel *channel, int budget)
+{
+ struct fxgmac_pdata *priv = channel->priv;
+ struct fxgmac_ring *ring = channel->rx_ring;
+ struct net_device *ndev = priv->ndev;
+ u32 context_next, context, incomplete;
+ struct fxgmac_desc_data *desc_data;
+ struct fxgmac_pkt_info *pkt_info;
+ struct napi_struct *napi;
+ u32 len, max_len;
+ int packet_count = 0;
+
+ struct sk_buff *skb;
+
+ /* Nothing to do if there isn't a Rx ring for this channel */
+ if (!ring)
+ return 0;
+
+ napi = (priv->per_channel_irq) ? &channel->napi_rx : &priv->napi;
+ pkt_info = &ring->pkt_info;
+
+ while (packet_count < budget) {
+ memset(pkt_info, 0, sizeof(*pkt_info));
+ skb = NULL;
+ len = 0;
+
+read_again:
+ desc_data = FXGMAC_GET_DESC_DATA(ring, ring->cur);
+
+ if (fxgmac_desc_rx_dirty(ring) > FXGMAC_RX_DESC_MAX_DIRTY)
+ fxgmac_rx_refresh(channel);
+
+ if (fxgmac_dev_read(channel))
+ break;
+
+ ring->cur = FXGMAC_GET_ENTRY(ring->cur, ring->dma_desc_count);
+ incomplete = field_get(ATTR_RX_INCOMPLETE, pkt_info->attr);
+ context_next = field_get(ATTR_RX_CONTEXT_NEXT, pkt_info->attr);
+ context = field_get(ATTR_RX_CONTEXT, pkt_info->attr);
+
+ if (incomplete || context_next)
+ goto read_again;
+
+ if (pkt_info->errors) {
+ dev_kfree_skb(skb);
+ priv->ndev->stats.rx_dropped++;
+ netdev_err(priv->ndev, "Received packet failed\n");
+ goto next_packet;
+ }
+
+ if (!context) {
+ len = desc_data->rx.len;
+ if (len == 0) {
+ if (net_ratelimit())
+ netdev_err(priv->ndev, "A packet of length 0 was received\n");
+ priv->ndev->stats.rx_length_errors++;
+ priv->ndev->stats.rx_dropped++;
+ goto next_packet;
+ }
+
+ if (len && !skb) {
+ skb = fxgmac_create_skb(priv, napi, desc_data,
+ len);
+ if (unlikely(!skb)) {
+ if (net_ratelimit())
+ netdev_err(priv->ndev, "create skb failed\n");
+ priv->ndev->stats.rx_dropped++;
+ goto next_packet;
+ }
+ }
+ max_len = ndev->mtu + ETH_HLEN;
+ if (!(ndev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
+ skb->protocol == htons(ETH_P_8021Q))
+ max_len += VLAN_HLEN;
+
+ if (len > max_len) {
+ if (net_ratelimit())
+ netdev_err(priv->ndev, "len %d larger than max size %d\n",
+ len, max_len);
+ priv->ndev->stats.rx_length_errors++;
+ priv->ndev->stats.rx_dropped++;
+ dev_kfree_skb(skb);
+ goto next_packet;
+ }
+ }
+
+ if (!skb) {
+ priv->ndev->stats.rx_dropped++;
+ goto next_packet;
+ }
+
+ if (netif_msg_pktdata(priv))
+ fxgmac_dbg_pkt(priv, skb, false);
+
+ skb_checksum_none_assert(skb);
+ if (ndev->features & NETIF_F_RXCSUM)
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ if (field_get(ATTR_RX_VLAN_CTAG, pkt_info->attr))
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+ pkt_info->vlan_ctag);
+
+ if (field_get(ATTR_RX_RSS_HASH, pkt_info->attr))
+ skb_set_hash(skb, pkt_info->rss_hash,
+ pkt_info->rss_hash_type);
+
+ skb->dev = ndev;
+ skb->protocol = eth_type_trans(skb, ndev);
+ skb_record_rx_queue(skb, channel->queue_index);
+ napi_gro_receive(napi, skb);
+
+next_packet:
+ packet_count++;
+ priv->ndev->stats.rx_packets++;
+ priv->ndev->stats.rx_bytes += len;
+ }
+
+ return packet_count;
+}
+
+static int fxgmac_one_poll_rx(struct napi_struct *napi, int budget)
+{
+ struct fxgmac_channel *channel =
+ container_of(napi, struct fxgmac_channel, napi_rx);
+ int processed = fxgmac_rx_poll(channel, budget);
+
+ if (processed < budget && (napi_complete_done(napi, processed)))
+ fxgmac_enable_msix_one_irq(channel->priv, channel->queue_index);
+
+ return processed;
+}
+
+static int fxgmac_all_poll(struct napi_struct *napi, int budget)
+{
+ struct fxgmac_channel *channel;
+ struct fxgmac_pdata *priv;
+ int processed = 0;
+
+ priv = container_of(napi, struct fxgmac_pdata, napi);
+ do {
+ channel = priv->channel_head;
+ /* Only support 1 tx channel, poll ch 0. */
+ fxgmac_tx_poll(priv->channel_head + 0);
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ processed += fxgmac_rx_poll(channel, budget);
+ } while (false);
+
+ /* If we processed everything, we are done */
+ if (processed < budget) {
+ /* Turn off polling */
+ if (napi_complete_done(napi, processed))
+ fxgmac_enable_mgm_irq(priv);
+ }
+
+ if ((processed) && (netif_msg_rx_status(priv)))
+ netdev_dbg(priv->ndev, "%s,received:%d\n", __func__, processed);
+
+ return processed;
+}
+
+static void napi_add_enable(struct fxgmac_pdata *priv, struct napi_struct *napi,
+ int (*poll)(struct napi_struct *, int),
+ u32 flag)
+{
+ netif_napi_add(priv->ndev, napi, poll);
+ napi_enable(napi);
+ priv->int_flag |= flag;
+}
+
+static void fxgmac_napi_enable(struct fxgmac_pdata *priv)
+{
+ u32 rx_napi[] = {INT_FLAG_RX0_NAPI, INT_FLAG_RX1_NAPI,
+ INT_FLAG_RX2_NAPI, INT_FLAG_RX3_NAPI};
+ struct fxgmac_channel *channel = priv->channel_head;
+
+ if (!priv->per_channel_irq) {
+ if (field_get(INT_FLAG_LEGACY_NAPI, priv->int_flag))
+ return;
+
+ napi_add_enable(priv, &priv->napi, fxgmac_all_poll,
+ INT_FLAG_LEGACY_NAPI);
+ return;
+ }
+
+ if (!field_get(INT_FLAG_TX_NAPI, priv->int_flag))
+ napi_add_enable(priv, &channel->napi_tx, fxgmac_one_poll_tx,
+ INT_FLAG_TX_NAPI);
+
+ for (u32 i = 0; i < priv->channel_count; i++, channel++)
+ if (!(priv->int_flag & rx_napi[i]))
+ napi_add_enable(priv, &channel->napi_rx,
+ fxgmac_one_poll_rx, rx_napi[i]);
+}
+
+static int fxgmac_probe(struct pci_dev *pcidev, const struct pci_device_id *id)
+{
+ struct device *dev = &pcidev->dev;
+ struct fxgmac_resources res;
+ int i, ret;
+
+ ret = pcim_enable_device(pcidev);
+ if (ret) {
+ dev_err(dev, "%s pcim_enable_device err:%d\n", __func__, ret);
+ return ret;
+ }
+
+ for (i = 0; i < PCI_STD_NUM_BARS; i++) {
+ if (pci_resource_len(pcidev, i) == 0)
+ continue;
+
+ ret = pcim_iomap_regions(pcidev, BIT(i), FXGMAC_DRV_NAME);
+ if (ret) {
+ dev_err(dev, "%s, pcim_iomap_regions err:%d\n",
+ __func__, ret);
+ return ret;
+ }
+ break;
+ }
+
+ pci_set_master(pcidev);
+
+ memset(&res, 0, sizeof(res));
+ res.irq = pcidev->irq;
+ res.addr = pcim_iomap_table(pcidev)[i];
+
+ return fxgmac_drv_probe(&pcidev->dev, &res);
+}
+
+static void fxgmac_remove(struct pci_dev *pcidev)
+{
+ struct fxgmac_pdata *priv = dev_get_drvdata(&pcidev->dev);
+ struct net_device *ndev = priv->ndev;
+
+ unregister_netdev(ndev);
+ fxgmac_phy_reset(priv);
+ free_netdev(ndev);
+
+ if (IS_ENABLED(CONFIG_PCI_MSI) &&
+ FIELD_GET(INT_FLAG_MSIX, priv->int_flag)) {
+ pci_disable_msix(pcidev);
+ kfree(priv->msix_entries);
+ priv->msix_entries = NULL;
+ }
+}
+
+static void __fxgmac_shutdown(struct pci_dev *pcidev)
+{
+ struct fxgmac_pdata *priv = dev_get_drvdata(&pcidev->dev);
+ struct net_device *ndev = priv->ndev;
+
+ fxgmac_net_powerdown(priv);
+ netif_device_detach(ndev);
+}
+
+static void fxgmac_shutdown(struct pci_dev *pcidev)
+{
+ rtnl_lock();
+ __fxgmac_shutdown(pcidev);
+ if (system_state == SYSTEM_POWER_OFF) {
+ pci_wake_from_d3(pcidev, false);
+ pci_set_power_state(pcidev, PCI_D3hot);
+ }
+ rtnl_unlock();
+}
+
+static int fxgmac_suspend(struct device *device)
+{
+ struct fxgmac_pdata *priv = dev_get_drvdata(device);
+ struct net_device *ndev = priv->ndev;
+
+ rtnl_lock();
+ if (priv->dev_state != FXGMAC_DEV_START)
+ goto unlock;
+
+ if (netif_running(ndev))
+ __fxgmac_shutdown(to_pci_dev(device));
+
+ priv->dev_state = FXGMAC_DEV_SUSPEND;
+unlock:
+ rtnl_unlock();
+
+ return 0;
+}
+
+static int fxgmac_resume(struct device *device)
+{
+ struct fxgmac_pdata *priv = dev_get_drvdata(device);
+ struct net_device *ndev = priv->ndev;
+ int ret = 0;
+
+ rtnl_lock();
+ if (priv->dev_state != FXGMAC_DEV_SUSPEND)
+ goto unlock;
+
+ priv->dev_state = FXGMAC_DEV_RESUME;
+ __clear_bit(FXGMAC_POWER_STATE_DOWN, &priv->power_state);
+ rtnl_lock();
+ if (netif_running(ndev)) {
+ ret = fxgmac_net_powerup(priv);
+ if (ret < 0) {
+ netdev_err(priv->ndev, "%s, fxgmac net powerup failed:%d\n",
+ __func__, ret);
+ goto unlock;
+ }
+ }
+
+ netif_device_attach(ndev);
+unlock:
+ rtnl_unlock();
+
+ return ret;
+}
+
+#define MOTORCOMM_PCI_ID 0x1f0a
+#define YT6801_PCI_DEVICE_ID 0x6801
+
+static const struct pci_device_id fxgmac_pci_tbl[] = {
+ { PCI_DEVICE(MOTORCOMM_PCI_ID, YT6801_PCI_DEVICE_ID) },
+ { 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, fxgmac_pci_tbl);
+
+static const struct dev_pm_ops fxgmac_pm_ops = {
+ SYSTEM_SLEEP_PM_OPS(fxgmac_suspend, fxgmac_resume)
+};
+
+static struct pci_driver fxgmac_pci_driver = {
+ .name = FXGMAC_DRV_NAME,
+ .id_table = fxgmac_pci_tbl,
+ .probe = fxgmac_probe,
+ .remove = fxgmac_remove,
+ .driver.pm = pm_ptr(&fxgmac_pm_ops),
+ .shutdown = fxgmac_shutdown,
+};
+
+module_pci_driver(fxgmac_pci_driver);
+
+MODULE_AUTHOR("Motorcomm Electronic Tech. Co., Ltd.");
+MODULE_DESCRIPTION(FXGMAC_DRV_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/motorcomm/yt6801/yt6801_type.h b/drivers/net/ethernet/motorcomm/yt6801/yt6801_type.h
new file mode 100644
index 000000000..b5a853d70
--- /dev/null
+++ b/drivers/net/ethernet/motorcomm/yt6801/yt6801_type.h
@@ -0,0 +1,961 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* Copyright (c) 2022 - 2024 Motorcomm Electronic Technology Co.,Ltd. */
+
+#ifndef YT6801_TYPE_H
+#define YT6801_TYPE_H
+
+#include <linux/netdevice.h>
+#include <linux/bitfield.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#define FXGMAC_DRV_NAME "yt6801"
+#define FXGMAC_DRV_DESC "Motorcomm Gigabit Ethernet Driver"
+
+#define FXGMAC_RX_BUF_ALIGN 64
+#define FXGMAC_TX_MAX_BUF_SIZE (0x3fff & ~(FXGMAC_RX_BUF_ALIGN - 1))
+#define FXGMAC_RX_MIN_BUF_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
+
+/* Descriptors required for maximum contiguous TSO/GSO packet */
+#define FXGMAC_TX_MAX_SPLIT ((GSO_MAX_SIZE / FXGMAC_TX_MAX_BUF_SIZE) + 1)
+
+/* Maximum possible descriptors needed for a SKB */
+#define FXGMAC_TX_MAX_DESC_NR (MAX_SKB_FRAGS + FXGMAC_TX_MAX_SPLIT + 2)
+
+#define FXGMAC_DMA_STOP_TIMEOUT 5
+#define FXGMAC_JUMBO_PACKET_MTU 9014
+#define FXGMAC_MAX_DMA_RX_CHANNELS 4
+#define FXGMAC_MAX_DMA_TX_CHANNELS 1
+#define FXGMAC_MAX_DMA_CHANNELS \
+ (FXGMAC_MAX_DMA_RX_CHANNELS + FXGMAC_MAX_DMA_TX_CHANNELS)
+
+/**************** Other configuration register. *********************/
+#define GLOBAL_CTRL0 0x1000
+
+#define EPHY_CTRL 0x1004
+#define EPHY_CTRL_RESET BIT(0)
+#define EPHY_CTRL_STA_LINKUP BIT(1)
+#define EPHY_CTRL_STA_DUPLEX BIT(2)
+#define EPHY_CTRL_STA_SPEED GENMASK(4, 3)
+
+#define OOB_WOL_CTRL 0x1010
+#define OOB_WOL_CTRL_DIS BIT(0)
+
+/* MAC management registers */
+#define MGMT_INT_CTRL0 0x1100
+#define MGMT_INT_CTRL0_INT_STATUS GENMASK(15, 0)
+#define MGMT_INT_CTRL0_INT_STATUS_RX 0x000f
+#define MGMT_INT_CTRL0_INT_STATUS_TX 0x0010
+#define MGMT_INT_CTRL0_INT_STATUS_MISC 0x0020
+#define MGMT_INT_CTRL0_INT_STATUS_RXTX 0x0030
+#define MGMT_INT_CTRL0_INT_MASK GENMASK(31, 16)
+#define MGMT_INT_CTRL0_INT_MASK_RXCH 0x000f
+#define MGMT_INT_CTRL0_INT_MASK_TXCH 0x0010
+#define MGMT_INT_CTRL0_INT_MASK_MISC 0x0020
+#define MGMT_INT_CTRL0_INT_MASK_EX_PMT 0xf7ff
+#define MGMT_INT_CTRL0_INT_MASK_DISABLE 0xf000
+#define MGMT_INT_CTRL0_INT_MASK_MASK 0xffff
+
+/* Interrupt Moderation */
+#define INT_MOD 0x1108
+#define INT_MOD_RX GENMASK(11, 0)
+#define INT_MOD_200_US 200
+#define INT_MOD_TX GENMASK(27, 16)
+
+/* LTR_CTRL3, LTR latency message, only for System IDLE Start. */
+#define LTR_IDLE_ENTER 0x113c
+#define LTR_IDLE_ENTER_ENTER GENMASK(9, 0)
+#define LTR_IDLE_ENTER_900_US 900
+#define LTR_IDLE_ENTER_SCALE GENMASK(14, 10)
+#define LTR_IDLE_ENTER_SCALE_1_NS 0
+#define LTR_IDLE_ENTER_SCALE_32_NS 1
+#define LTR_IDLE_ENTER_SCALE_1024_NS 2
+#define LTR_IDLE_ENTER_SCALE_32768_NS 3
+#define LTR_IDLE_ENTER_SCALE_1048576_NS 4
+#define LTR_IDLE_ENTER_SCALE_33554432_NS 5
+#define LTR_IDLE_ENTER_REQUIRE BIT(15)
+
+/* LTR_CTRL4, LTR latency message, only for System IDLE End. */
+#define LTR_IDLE_EXIT 0x1140
+#define LTR_IDLE_EXIT_EXIT GENMASK(9, 0)
+#define LTR_IDLE_EXIT_171_US 171
+#define LTR_IDLE_EXIT_SCALE GENMASK(14, 10)
+#define LTR_IDLE_EXIT_REQUIRE BIT(15)
+
+#define MSIX_TBL_MASK 0x120c
+
+/* msi table */
+#define MSI_ID_RXQ0 0
+#define MSI_ID_RXQ1 1
+#define MSI_ID_RXQ2 2
+#define MSI_ID_RXQ3 3
+#define MSI_ID_TXQ0 4
+#define MSIX_TBL_MAX_NUM 5
+
+#define MSI_PBA 0x1300
+
+#define EFUSE_OP_CTRL_0 0x1500
+#define EFUSE_OP_MODE GENMASK(1, 0)
+#define EFUSE_OP_MODE_ROW_WRITE 0x0
+#define EFUSE_OP_MODE_ROW_READ 0x1
+#define EFUSE_OP_MODE_AUTO_LOAD 0x2
+#define EFUSE_OP_MODE_READ_BLANK 0x3
+#define EFUSE_OP_START BIT(2)
+#define EFUSE_OP_ADDR GENMASK(15, 8)
+#define EFUSE_OP_WR_DATA GENMASK(23, 16)
+
+#define EFUSE_OP_CTRL_1 0x1504
+#define EFUSE_OP_DONE BIT(1)
+#define EFUSE_OP_PGM_PASS BIT(2)
+#define EFUSE_OP_BIST_ERR_CNT GENMASK(15, 8)
+#define EFUSE_OP_BIST_ERR_ADDR GENMASK(23, 16)
+#define EFUSE_OP_RD_DATA GENMASK(31, 24)
+
+/* MAC addr can be configured through effuse */
+#define MACA0LR_FROM_EFUSE 0x1520
+#define MACA0HR_FROM_EFUSE 0x1524
+
+#define SYS_RESET 0x152c
+#define SYS_RESET_RESET BIT(31)
+
+#define PCIE_SERDES_PLL 0x199c
+#define PCIE_SERDES_PLL_AUTOOFF BIT(0)
+
+/**************** GMAC register. *********************/
+#define MAC_CR 0x2000
+#define MAC_CR_RE BIT(0)
+#define MAC_CR_TE BIT(1)
+#define MAC_CR_LM BIT(12)
+#define MAC_CR_DM BIT(13)
+#define MAC_CR_FES BIT(14)
+#define MAC_CR_PS BIT(15)
+#define MAC_CR_JE BIT(16)
+#define MAC_CR_ACS BIT(20)
+#define MAC_CR_CST BIT(21)
+#define MAC_CR_IPC BIT(27)
+#define MAC_CR_ARPEN BIT(31)
+
+#define MAC_ECR 0x2004
+#define MAC_ECR_DCRCC BIT(16)
+#define MAC_ECR_HDSMS GENMASK(22, 20)
+#define MAC_ECR_HDSMS_64B 0
+#define MAC_ECR_HDSMS_128B 1
+#define MAC_ECR_HDSMS_256B 2
+#define MAC_ECR_HDSMS_512B 3
+#define MAC_ECR_HDSMS_1023B 4
+
+#define MAC_PFR 0x3008
+#define MAC_PFR_PR BIT(0) /* Promiscuous Mode. */
+#define MAC_PFR_HUC BIT(1) /* Hash Unicast Mode. */
+#define MAC_PFR_HMC BIT(2)
+#define MAC_PFR_PM BIT(4) /* Pass all Multicast. */
+#define MAC_PFR_DBF BIT(5) /* Disable Broadcast Packets. */
+#define MAC_PFR_HPF BIT(10)
+#define MAC_PFR_VTFE BIT(16)
+
+#define MAC_Q0TFCR 0x2070
+#define MAC_Q0TFCR_TFE BIT(1)
+#define MAC_Q0TFCR_PT GENMASK(31, 16)
+
+#define MAC_RFCR 0x2090
+#define MAC_RFCR_RFE BIT(0)
+#define MAC_RFCR_UP BIT(1)
+#define MAC_RFCR_PFCE BIT(8)
+
+#define MAC_RQC0R 0x20a0
+#define MAC_RQC1R 0x20a4
+#define MAC_RQC2R 0x20a8
+#define MAC_RQC2_INC 4
+#define MAC_RQC2_Q_PER_REG 4
+
+#define MAC_ISR 0x20b0
+#define MAC_ISR_PHYIF_STA BIT(0)
+#define MAC_ISR_AN_SR GENMASK(3, 1)
+#define MAC_ISR_PMT_STA BIT(4)
+#define MAC_ISR_LPI_STA BIT(5)
+#define MAC_ISR_MMC_STA BIT(8)
+#define MAC_ISR_RX_MMC_STA BIT(9)
+#define MAC_ISR_TX_MMC_STA BIT(10)
+#define MAC_ISR_IPC_RXINT BIT(11)
+#define MAC_ISR_TSIS BIT(12)
+#define MAC_ISR_TX_RX_STA GENMASK(14, 13)
+#define MAC_ISR_GPIO_SR GENMASK(25, 15)
+
+#define MAC_IER 0x20b4
+#define MAC_IER_TSIE BIT(12)
+
+#define MAC_TX_RX_STA 0x20b8
+
+#define MAC_PMT_STA 0x20c0
+#define MAC_PMT_STA_PWRDWN BIT(0)
+#define MAC_PMT_STA_MGKPKTEN BIT(1)
+#define MAC_PMT_STA_RWKPKTEN BIT(2)
+#define MAC_PMT_STA_MGKPRCVD BIT(5)
+#define MAC_PMT_STA_RWKPRCVD BIT(6)
+#define MAC_PMT_STA_GLBLUCAST BIT(9)
+#define MAC_PMT_STA_RWKPTR GENMASK(27, 24)
+#define MAC_PMT_STA_RWKFILTERST BIT(31)
+
+#define MAC_RWK_PAC 0x20c4
+#define MAC_LPI_STA 0x20d0
+#define MAC_LPI_CONTROL 0x20d4
+#define MAC_LPI_TIMER 0x20d8
+#define MAC_MS_TIC_COUNTER 0x20dc
+#define MAC_AN_CR 0x20e0
+#define MAC_AN_SR 0x20e4
+#define MAC_AN_ADV 0x20e8
+#define MAC_AN_LPA 0x20ec
+#define MAC_AN_EXP 0x20f0
+#define MAC_PHYIF_STA 0x20f8
+#define MAC_VR 0x2110
+#define MAC_DBG_STA 0x2114
+
+#define MAC_HWF0R 0x211c
+#define MAC_HWF0R_VLHASH BIT(4)
+#define MAC_HWF0R_SMASEL BIT(5)
+#define MAC_HWF0R_RWKSEL BIT(6)
+#define MAC_HWF0R_MGKSEL BIT(7)
+#define MAC_HWF0R_MMCSEL BIT(8)
+#define MAC_HWF0R_ARPOFFSEL BIT(9)
+#define MAC_HWF0R_TSSEL BIT(12)
+#define MAC_HWF0R_EEESEL BIT(13)
+#define MAC_HWF0R_TXCOESEL BIT(14)
+#define MAC_HWF0R_RXCOESEL BIT(16)
+#define MAC_HWF0R_ADDMACADRSEL GENMASK(22, 18)
+#define MAC_HWF0R_TSSTSSEL GENMASK(26, 25)
+#define MAC_HWF0R_SAVLANINS BIT(27)
+#define MAC_HWF0R_ACTPHYIFSEL GENMASK(30, 28)
+
+#define MAC_HWF1R 0x2120
+#define MAC_HWF1R_RXFIFOSIZE GENMASK(4, 0)
+#define MAC_HWF1R_TXFIFOSIZE GENMASK(10, 6)
+#define MAC_HWF1R_ADVTHWORD BIT(13)
+#define MAC_HWF1R_ADDR64 GENMASK(15, 14)
+#define MAC_HWF1R_DCBEN BIT(16)
+#define MAC_HWF1R_SPHEN BIT(17)
+#define MAC_HWF1R_TSOEN BIT(18)
+#define MAC_HWF1R_DBGMEMA BIT(19)
+#define MAC_HWF1R_AVSEL BIT(20)
+#define MAC_HWF1R_RAVSEL BIT(21)
+#define MAC_HWF1R_HASHTBLSZ GENMASK(25, 24)
+#define MAC_HWF1R_L3L4FNUM GENMASK(30, 27)
+
+#define MAC_HWF2R 0x2124
+#define MAC_HWF2R_RXQCNT GENMASK(3, 0)
+#define MAC_HWF2R_TXQCNT GENMASK(9, 6)
+#define MAC_HWF2R_RXCHCNT GENMASK(15, 12)
+#define MAC_HWF2R_TXCHCNT GENMASK(21, 18)
+#define MAC_HWF2R_PPSOUTNUM GENMASK(26, 24)
+#define MAC_HWF2R_AUXSNAPNUM GENMASK(30, 28)
+
+#define MAC_HWF3R 0x2128
+
+#define MAC_MDIO_ADDR 0x2200
+#define MAC_MDIO_ADDR_BUSY BIT(0)
+#define MAC_MDIO_ADDR_GOC GENMASK(3, 2)
+
+#define MAC_MDIO_DATA 0x2204
+#define MAC_MDIO_DATA_GD GENMASK(15, 0)
+#define MAC_MDIO_DATA_RA GENMASK(31, 16)
+
+#define MAC_GPIO_CR 0x2208
+#define MAC_GPIO_SR 0x220c
+#define MAC_ARP_PROTO_ADDR 0x2210
+#define MAC_CSR_SW_CTRL 0x2230
+#define MAC_MACA0HR 0x2300
+#define MAC_MACA0LR 0x2304
+#define MAC_MACA1HR 0x2308
+#define MAC_MACA1LR 0x230c
+
+/* MMC registers */
+#define MMC_CR 0x2700
+#define MMC_CR_CR BIT(0)
+#define MMC_CR_CSR BIT(1)
+#define MMC_CR_ROR BIT(2)
+#define MMC_CR_MCF BIT(3)
+
+#define MMC_RISR 0x2704
+#define MMC_TISR 0x2708
+
+#define MMC_RIER 0x270c
+#define MMC_RIER_ALL_INTERRUPTS GENMASK(27, 0)
+
+#define MMC_TIER 0x2710
+#define MMC_TIER_ALL_INTERRUPTS GENMASK(27, 0)
+
+#define MMC_IPC_RXINT_MASK 0x2800
+#define MMC_IPC_RXINT 0x2808
+
+/* MTL registers */
+#define MTL_OMR 0x2c00
+#define MTL_OMR_RAA BIT(2)
+#define MTL_OMR_ETSALG GENMASK(6, 5)
+
+#define MTL_FDCR 0x2c08
+#define MTL_FDSR 0x2c0c
+#define MTL_FDDR 0x2c10
+#define MTL_INT_SR 0x2c20
+
+#define MTL_RQDCM_INC 4
+#define MTL_RQDCM_Q_PER_REG 4
+
+#define MTL_RQDCM0R 0x2c30
+#define MTL_RQDCM0R_Q0MDMACH 0x0
+#define MTL_RQDCM0R_Q1MDMACH 0x00000100
+#define MTL_RQDCM0R_Q2MDMACH 0x00020000
+#define MTL_RQDCM0R_Q3MDMACH 0x03000000
+
+#define MTL_ECC_INT_SR 0x2ccc
+
+#define MTL_RQDCM1R_Q4MDMACH 0x00000004
+#define MTL_RQDCM1R_Q5MDMACH 0x00000500
+#define MTL_RQDCM1R_Q6MDMACH 0x00060000
+#define MTL_RQDCM1R_Q7MDMACH 0x07000000
+
+/* MTL queue registers */
+#define MTL_Q_BASE 0x2d00
+#define MTL_Q_INC 0x40
+
+#define MTL_Q_TQOMR 0x00
+#define MTL_Q_TQOMR_FTQ BIT(0)
+#define MTL_Q_TQOMR_TSF BIT(1)
+#define MTL_Q_TQOMR_TXQEN GENMASK(3, 2)
+#define MTL_Q_DISABLED 0x00
+#define MTL_Q_EN_IF_AV 0x01
+#define MTL_Q_ENABLED 0x02
+
+#define MTL_Q_TQOMR_TTC GENMASK(6, 4)
+#define MTL_Q_TQOMR_TTC_THRESHOLD_32 0x00
+#define MTL_Q_TQOMR_TTC_THRESHOLD_64 0x01
+#define MTL_Q_TQOMR_TTC_THRESHOLD_96 0x02
+#define MTL_Q_TQOMR_TTC_THRESHOLD_128 0x03
+#define MTL_Q_TQOMR_TTC_THRESHOLD_192 0x04
+#define MTL_Q_TQOMR_TTC_THRESHOLD_256 0x05
+#define MTL_Q_TQOMR_TTC_THRESHOLD_384 0x06
+#define MTL_Q_TQOMR_TTC_THRESHOLD_512 0x07
+
+#define MTL_Q_TQOMR_TQS GENMASK(22, 16)
+
+#define MTL_Q_TQUR 0x04
+#define MTL_Q_TXDEG 0x08 /* Transmit debug */
+#define MTL_Q_IR 0x2c /* Interrupt control status */
+
+#define MTL_Q_RQOMR 0x30
+#define MTL_Q_RQOMR_RTC GENMASK(1, 0)
+#define MTL_Q_RQOMR_RTC_THRESHOLD_64 0x00
+#define MTL_Q_RQOMR_RTC_THRESHOLD_32 0x01
+#define MTL_Q_RQOMR_RTC_THRESHOLD_96 0x02
+#define MTL_Q_RQOMR_RTC_THRESHOLD_128 0x03
+
+#define MTL_Q_RQOMR_FUP BIT(3)
+#define MTL_Q_RQOMR_FEP BIT(4)
+#define MTL_Q_RQOMR_RSF BIT(5)
+#define MTL_Q_RQOMR_EHFC BIT(7)
+#define MTL_Q_RQOMR_RFA GENMASK(13, 8)
+#define MTL_Q_RQOMR_RFD GENMASK(19, 14)
+#define MTL_Q_RQOMR_RQS GENMASK(28, 20)
+
+#define MTL_Q_RQMPOCR 0x34
+
+#define MTL_Q_RQDR 0x38
+#define MTL_Q_RQDR_RXQSTS GENMASK(5, 4)
+#define MTL_Q_RQDR_PRXQ GENMASK(29, 16)
+
+#define MTL_Q_RQCR 0x3c
+
+/* MTL queue registers */
+#define MTL_ETSALG_WRR 0x00
+#define MTL_ETSALG_WFQ 0x01
+#define MTL_ETSALG_DWRR 0x02
+#define MTL_ETSALG_SP 0x03
+
+#define MTL_RAA_SP 0x00
+#define MTL_RAA_WSP 0x01
+
+/* MTL traffic class registers */
+#define MTL_TC_BASE MTL_Q_BASE
+#define MTL_TC_INC MTL_Q_INC
+
+#define MTL_TC_TQDR 0x08
+#define MTL_TC_TQDR_TRCSTS GENMASK(2, 1)
+#define MTL_TC_TQDR_TXQSTS BIT(4)
+
+#define MTL_TC_ETSCR 0x10
+#define MTL_TC_ETSCR_TSA GENMASK(1, 0)
+
+#define MTL_TC_ETSSR 0x14
+#define MTL_TC_QWR 0x18
+#define MTL_TC_QWR_QW GENMASK(20, 0)
+
+/* DMA registers */
+#define DMA_MR 0x3000
+#define DMA_MR_SWR BIT(0)
+#define DMA_MR_TXPR BIT(11)
+#define DMA_MR_INTM GENMASK(17, 16)
+#define DMA_MR_QUREAD BIT(19)
+#define DMA_MR_TNDF GENMASK(21, 20)
+#define DMA_MR_RNDF GENMASK(23, 22)
+
+#define DMA_SBMR 0x3004
+#define DMA_SBMR_FB BIT(0)
+#define DMA_SBMR_BLEN_4 BIT(1)
+#define DMA_SBMR_BLEN_8 BIT(2)
+#define DMA_SBMR_BLEN_16 BIT(3)
+#define DMA_SBMR_BLEN_32 BIT(4)
+#define DMA_SBMR_BLEN_64 BIT(5)
+#define DMA_SBMR_BLEN_128 BIT(6)
+#define DMA_SBMR_BLEN_256 BIT(7)
+#define DMA_SBMR_AALE BIT(10)
+#define DMA_SBMR_EAME BIT(11)
+#define DMA_SBMR_AAL BIT(12)
+#define DMA_SBMR_RD_OSR_LMT GENMASK(23, 16)
+#define DMA_SBMR_WR_OSR_LMT GENMASK(29, 24)
+#define DMA_SBMR_LPI_XIT_PKT BIT(30)
+#define DMA_SBMR_EN_LPI BIT(31)
+
+#define DMA_ISR 0x3008
+#define DMA_ISR_MTLIS BIT(16)
+#define DMA_ISR_MACIS BIT(17)
+
+#define DMA_DSRX_INC 4
+#define DMA_DSR0 0x300c
+#define DMA_DSR0_TPS GENMASK(15, 12)
+#define DMA_TPS_STOPPED 0x00
+#define DMA_TPS_SUSPENDED 0x06
+
+#define DMA_DSR1 0x3010
+#define DMA_DSR2 0x3014
+#define DMA_AXIARCR 0x3020
+#define DMA_AXIAWCR 0x3024
+#define DMA_AXIAWRCR 0x3028
+#define DMA_SAFE_ISR 0x3080
+#define DMA_ECC_IE 0x3084
+#define DMA_ECC_INT_SR 0x3088
+
+/* DMA channel registers */
+#define DMA_CH_BASE 0x3100
+#define DMA_CH_INC 0x80
+
+#define DMA_CH_CR 0x00
+#define DMA_CH_CR_PBLX8 BIT(16)
+#define DMA_CH_CR_SPH BIT(24)
+
+#define DMA_CH_TCR 0x04
+#define DMA_CH_TCR_ST BIT(0)
+#define DMA_CH_TCR_OSP BIT(4)
+#define DMA_CH_TCR_TSE BIT(12)
+#define DMA_CH_TCR_PBL GENMASK(21, 16)
+#define DMA_CH_PBL_1 1
+#define DMA_CH_PBL_2 2
+#define DMA_CH_PBL_4 4
+#define DMA_CH_PBL_8 8
+#define DMA_CH_PBL_16 16
+#define DMA_CH_PBL_32 32
+#define DMA_CH_PBL_64 64
+#define DMA_CH_PBL_128 128
+#define DMA_CH_PBL_256 256
+
+#define DMA_CH_RCR 0x08
+#define DMA_CH_RCR_SR BIT(0)
+#define DMA_CH_RCR_RBSZ GENMASK(14, 1)
+#define DMA_CH_RCR_PBL GENMASK(21, 16)
+
+#define DMA_CH_TDLR_HI 0x10
+#define DMA_CH_TDLR_LO 0x14
+#define DMA_CH_RDLR_HI 0x18
+#define DMA_CH_RDLR_LO 0x1c
+#define DMA_CH_TDTR_LO 0x20
+#define DMA_CH_RDTR_LO 0x28
+#define DMA_CH_TDRLR 0x2c
+#define DMA_CH_RDRLR 0x30
+
+#define DMA_CH_IER 0x34
+#define DMA_CH_IER_TIE BIT(0)
+#define DMA_CH_IER_TXSE BIT(1)
+#define DMA_CH_IER_TBUE BIT(2)
+#define DMA_CH_IER_RIE BIT(6)
+#define DMA_CH_IER_RBUE BIT(7)
+#define DMA_CH_IER_RSE BIT(8)
+#define DMA_CH_IER_FBEE BIT(12)
+#define DMA_CH_IER_AIE BIT(14)
+#define DMA_CH_IER_NIE BIT(15)
+
+#define DMA_CH_RIWT 0x38
+#define DMA_CH_RIWT_RWT GENMASK(7, 0)
+
+#define DMA_CH_CATDR_LO 0x44
+#define DMA_CH_CARDR_LO 0x4c
+#define DMA_CH_CATBR_HI 0x50
+#define DMA_CH_CATBR_LO 0x54
+#define DMA_CH_CARBR_HI 0x58
+#define DMA_CH_CARBR_LO 0x5c
+
+#define DMA_CH_SR 0x60
+#define DMA_CH_SR_TI BIT(0)
+#define DMA_CH_SR_TPS BIT(1)
+#define DMA_CH_SR_TBU BIT(2)
+#define DMA_CH_SR_RI BIT(6)
+#define DMA_CH_SR_RBU BIT(7)
+#define DMA_CH_SR_RPS BIT(8)
+#define DMA_CH_SR_FBE BIT(12)
+
+/* Receive Normal Descriptor (Read Format) */
+#define RX_DESC0_OVT GENMASK(15, 0) /* Outer VLAN Tag */
+
+#define RX_DESC2_HL GENMASK(9, 0) /* L3/L4 Header Length */
+
+#define RX_DESC3_PL GENMASK(14, 0) /* Packet Length */
+#define RX_DESC3_ES BIT(15) /* Error Summary */
+#define RX_DESC3_ETLT GENMASK(18, 16) /* Length/Type Field */
+#define RX_DESC3_BUF1V BIT(24) /* Receive Status RDES1 Valid */
+#define RX_DESC3_BUF2V BIT(25) /* Receive Status RDES2 Valid */
+#define RX_DESC3_LD BIT(28) /* Last Descriptor */
+#define RX_DESC3_FD BIT(29) /* First Descriptor */
+#define RX_DESC3_INTE BIT(30)
+#define RX_DESC3_OWN BIT(31) /* Own Bit */
+
+/* Transmit Normal Descriptor (Read Format) */
+#define TX_DESC2_HL_B1L GENMASK(13, 0) /* Header Length or Buffer 1 Length */
+#define TX_DESC2_VTIR GENMASK(15, 14) /* VLAN Tag Insertion/Replacement */
+#define TX_DESC2_TTSE BIT(30) /* Transmit Timestamp Enable */
+#define TX_DESC2_IC BIT(31) /* Interrupt on Completion. */
+#define TX_DESC3_TCPPL GENMASK(17, 0) /* TCP Packet Length.*/
+#define TX_DESC3_FL GENMASK(14, 0) /* Frame Length */
+#define TX_DESC3_CIC GENMASK(17, 16) /* Checksum Insertion Control */
+#define TX_DESC3_TSE BIT(18) /* TCP Segmentation Enable */
+#define TX_DESC3_TCPHDRLEN GENMASK(22, 19) /* TCP/UDP Header Length. */
+#define TX_DESC3_CPC GENMASK(27, 26) /* CRC Pad Control */
+#define TX_DESC3_LD BIT(28) /* Last Descriptor */
+#define TX_DESC3_FD BIT(29) /* First Descriptor */
+#define TX_DESC3_CTXT BIT(30) /* Context Type */
+#define TX_DESC3_OWN BIT(31) /* Own Bit */
+
+/* Transmit Context Descriptor */
+#define TX_CONTEXT_DESC2_MSS GENMASK(13, 0) /* Maximum Segment Size */
+#define TX_CONTEXT_DESC2_IVLTV GENMASK(31, 16) /* Inner VLAN Tag. */
+
+#define TX_CONTEXT_DESC3_VT GENMASK(15, 0) /* VLAN Tag */
+#define TX_CONTEXT_DESC3_VLTV BIT(16) /* Inner VLAN Tag Valid */
+#define TX_CONTEXT_DESC3_IVLTV BIT(17) /* Inner VLAN TAG valid. */
+/* Inner VLAN Tag Insert/Replace */
+#define TX_CONTEXT_DESC3_IVTIR GENMASK(19, 18)
+#define TX_CONTEXT_DESC3_TCMSSV BIT(26) /* Timestamp correct or MSS Valid */
+#define TX_CONTEXT_DESC3_CTXT BIT(30) /* Context Type */
+
+/* Receive Normal Descriptor (Write-Back Format) */
+#define RX_DESC0_WB_OVT GENMASK(15, 0) /* Outer VLAN Tag. */
+#define RX_DESC0_WB_IVT GENMASK(31, 16) /* Inner VLAN Tag. */
+
+#define RX_DESC1_WB_PT GENMASK(2, 0) /* Payload Type */
+#define RX_DESC1_WB_IPHE BIT(3) /* IP Header Error. */
+#define RX_DESC1_WB_IPV4 BIT(4) /* IPV4 Header Present */
+#define RX_DESC1_WB_IPV6 BIT(5) /* IPV6 Header Present. */
+#define RX_DESC1_WB_IPCE BIT(7) /* IP Payload Error. */
+
+#define RX_DESC2_WB_RAPARSER GENMASK(13, 11) /* Parse error */
+#define RX_DESC2_WB_DAF BIT(17) /* DA Filter Fail */
+#define RX_DESC2_WB_HF BIT(18) /* Hash Filter Status. */
+
+struct fxgmac_ring_buf {
+ struct sk_buff *skb;
+ dma_addr_t skb_dma;
+ unsigned int skb_len;
+};
+
+/* Common Tx and Rx DMA hardware descriptor */
+struct fxgmac_dma_desc {
+ __le32 desc0;
+ __le32 desc1;
+ __le32 desc2;
+ __le32 desc3;
+};
+
+/* Page allocation related values */
+struct fxgmac_page_alloc {
+ struct page *pages;
+ unsigned int pages_len;
+ unsigned int pages_offset;
+ dma_addr_t pages_dma;
+};
+
+/* Ring entry buffer data */
+struct fxgmac_buffer_data {
+ struct fxgmac_page_alloc pa;
+ struct fxgmac_page_alloc pa_unmap;
+
+ dma_addr_t dma_base;
+ unsigned long dma_off;
+ unsigned int dma_len;
+};
+
+struct fxgmac_tx_desc_data {
+ unsigned int packets; /* BQL packet count */
+ unsigned int bytes; /* BQL byte count */
+};
+
+struct fxgmac_rx_desc_data {
+ struct fxgmac_buffer_data hdr; /* Header locations */
+ struct fxgmac_buffer_data buf; /* Payload locations */
+ unsigned short hdr_len; /* Length of received header */
+ unsigned short len; /* Length of received packet */
+};
+
+struct fxgmac_pkt_info {
+ struct sk_buff *skb;
+#define ATTR_TX_CSUM_ENABLE BIT(0)
+#define ATTR_TX_TSO_ENABLE BIT(1)
+#define ATTR_TX_VLAN_CTAG BIT(2)
+#define ATTR_TX_PTP BIT(3)
+
+#define ATTR_RX_CSUM_DONE BIT(0)
+#define ATTR_RX_VLAN_CTAG BIT(1)
+#define ATTR_RX_INCOMPLETE BIT(2)
+#define ATTR_RX_CONTEXT_NEXT BIT(3)
+#define ATTR_RX_CONTEXT BIT(4)
+#define ATTR_RX_RX_TSTAMP BIT(5)
+#define ATTR_RX_RSS_HASH BIT(6)
+ unsigned int attr;
+
+#define ERRORS_RX_LENGTH BIT(0)
+#define ERRORS_RX_OVERRUN BIT(1)
+#define ERRORS_RX_CRC BIT(2)
+#define ERRORS_RX_FRAME BIT(3)
+ unsigned int errors;
+ unsigned int desc_count; /* descriptors needed for this packet */
+ unsigned int length;
+ unsigned int tx_packets;
+ unsigned int tx_bytes;
+
+ unsigned int header_len;
+ unsigned int tcp_header_len;
+ unsigned int tcp_payload_len;
+ unsigned short mss;
+ unsigned short vlan_ctag;
+
+ u64 rx_tstamp;
+ u32 rss_hash;
+ enum pkt_hash_types rss_hash_type;
+};
+
+struct fxgmac_desc_data {
+ struct fxgmac_dma_desc *dma_desc; /* Virtual address of descriptor */
+ dma_addr_t dma_desc_addr; /* DMA address of descriptor */
+ struct sk_buff *skb; /* Virtual address of SKB */
+ dma_addr_t skb_dma; /* DMA address of SKB data */
+ unsigned int skb_dma_len; /* Length of SKB DMA area */
+
+ /* Tx/Rx -related data */
+ struct fxgmac_tx_desc_data tx;
+ struct fxgmac_rx_desc_data rx;
+
+ unsigned int mapped_as_page;
+};
+
+struct fxgmac_ring {
+ struct fxgmac_pkt_info pkt_info; /* packet related information */
+
+ /* Virtual/DMA addresses of DMA descriptor list */
+ struct fxgmac_dma_desc *dma_desc_head;
+ dma_addr_t dma_desc_head_addr;
+ unsigned int dma_desc_count;
+
+ /* Array of descriptor data corresponding the DMA descriptor
+ * (always use the FXGMAC_GET_DESC_DATA macro to access this data)
+ */
+ struct fxgmac_desc_data *desc_data_head;
+
+ /* Page allocation for RX buffers */
+ struct fxgmac_page_alloc rx_hdr_pa;
+ struct fxgmac_page_alloc rx_buf_pa;
+
+ /* Ring index values
+ * cur - Tx: index of descriptor to be used for current transfer
+ * Rx: index of descriptor to check for packet availability
+ * dirty - Tx: index of descriptor to check for transfer complete
+ * Rx: index of descriptor to check for buffer reallocation
+ */
+ unsigned int cur;
+ unsigned int dirty;
+
+ struct {
+ unsigned int xmit_more;
+ unsigned int queue_stopped;
+ unsigned short cur_mss;
+ unsigned short cur_vlan_ctag;
+ } tx;
+} ____cacheline_aligned;
+
+struct fxgmac_channel {
+ char name[16];
+
+ /* Address of private data area for device */
+ struct fxgmac_pdata *priv;
+
+ /* Queue index and base address of queue's DMA registers */
+ unsigned int queue_index;
+
+ /* Per channel interrupt irq number */
+ u32 dma_irq_rx;
+ char dma_irq_rx_name[IFNAMSIZ + 32];
+ u32 dma_irq_tx;
+ char dma_irq_tx_name[IFNAMSIZ + 32];
+
+ /* ndev related settings */
+ struct napi_struct napi_tx;
+ struct napi_struct napi_rx;
+
+ void __iomem *dma_regs;
+ struct fxgmac_ring *tx_ring;
+ struct fxgmac_ring *rx_ring;
+} ____cacheline_aligned;
+
+/* This structure contains flags that indicate what hardware features
+ * or configurations are present in the device.
+ */
+struct fxgmac_hw_features {
+ unsigned int version; /* HW Version */
+
+ /* HW Feature Register0 */
+ unsigned int phyifsel; /* PHY interface support */
+ unsigned int vlhash; /* VLAN Hash Filter */
+ unsigned int sma; /* SMA(MDIO) Interface */
+ unsigned int rwk; /* PMT remote wake-up packet */
+ unsigned int mgk; /* PMT magic packet */
+ unsigned int mmc; /* RMON module */
+ unsigned int aoe; /* ARP Offload */
+ unsigned int ts; /* IEEE 1588-2008 Advanced Timestamp */
+ unsigned int eee; /* Energy Efficient Ethernet */
+ unsigned int tx_coe; /* Tx Checksum Offload */
+ unsigned int rx_coe; /* Rx Checksum Offload */
+ unsigned int addn_mac; /* Additional MAC Addresses */
+ unsigned int ts_src; /* Timestamp Source */
+ unsigned int sa_vlan_ins; /* Source Address or VLAN Insertion */
+
+ /* HW Feature Register1 */
+ unsigned int rx_fifo_size; /* MTL Receive FIFO Size */
+ unsigned int tx_fifo_size; /* MTL Transmit FIFO Size */
+ unsigned int adv_ts_hi; /* Advance Timestamping High Word */
+ unsigned int dma_width; /* DMA width */
+ unsigned int dcb; /* DCB Feature */
+ unsigned int sph; /* Split Header Feature */
+ unsigned int tso; /* TCP Segmentation Offload */
+ unsigned int dma_debug; /* DMA Debug Registers */
+ unsigned int rss; /* Receive Side Scaling */
+ unsigned int tc_cnt; /* Number of Traffic Classes */
+ unsigned int avsel; /* AV Feature Enable */
+ unsigned int ravsel; /* Rx Side Only AV Feature Enable */
+ unsigned int hash_table_size; /* Hash Table Size */
+ unsigned int l3l4_filter_num; /* Number of L3-L4 Filters */
+
+ /* HW Feature Register2 */
+ unsigned int rx_q_cnt; /* Number of MTL Receive Queues */
+ unsigned int tx_q_cnt; /* Number of MTL Transmit Queues */
+ unsigned int rx_ch_cnt; /* Number of DMA Receive Channels */
+ unsigned int tx_ch_cnt; /* Number of DMA Transmit Channels */
+ unsigned int pps_out_num; /* Number of PPS outputs */
+ unsigned int aux_snap_num; /* Number of Aux snapshot inputs */
+
+ u32 hwfr3; /* HW Feature Register3 */
+};
+
+struct fxgmac_resources {
+ void __iomem *addr;
+ int irq;
+};
+
+enum fxgmac_dev_state {
+ FXGMAC_DEV_OPEN = 0x0,
+ FXGMAC_DEV_CLOSE = 0x1,
+ FXGMAC_DEV_STOP = 0x2,
+ FXGMAC_DEV_START = 0x3,
+ FXGMAC_DEV_SUSPEND = 0x4,
+ FXGMAC_DEV_RESUME = 0x5,
+ FXGMAC_DEV_PROBE = 0xFF,
+};
+
+struct fxgmac_pdata {
+ struct net_device *ndev;
+ struct device *dev;
+ struct phy_device *phydev;
+
+ struct fxgmac_hw_features hw_feat; /* Hardware features */
+ void __iomem *hw_addr; /* Registers base */
+
+ /* Rings for Tx/Rx on a DMA channel */
+ struct fxgmac_channel *channel_head;
+ unsigned int channel_count;
+ unsigned int rx_ring_count;
+ unsigned int rx_desc_count;
+ unsigned int rx_q_count;
+#define FXGMAC_TX_1_RING 1
+#define FXGMAC_TX_1_Q 1
+ unsigned int tx_desc_count;
+
+ unsigned long sysclk_rate; /* Device clocks */
+ unsigned int pblx8; /* Tx/Rx common settings */
+
+ /* Tx settings */
+ unsigned int tx_sf_mode;
+ unsigned int tx_threshold;
+ unsigned int tx_pbl;
+ unsigned int tx_osp_mode;
+
+ /* Rx settings */
+ unsigned int rx_sf_mode;
+ unsigned int rx_threshold;
+ unsigned int rx_pbl;
+
+ /* Tx coalescing settings */
+ unsigned int tx_usecs;
+ unsigned int tx_frames;
+
+ /* Rx coalescing settings */
+ unsigned int rx_riwt;
+ unsigned int rx_usecs;
+ unsigned int rx_frames;
+
+ /* Flow control settings */
+ unsigned int tx_pause;
+ unsigned int rx_pause;
+
+ unsigned int rx_buf_size; /* Current Rx buffer size */
+
+ /* Device interrupt */
+ int dev_irq;
+ unsigned int per_channel_irq;
+ u32 channel_irq[FXGMAC_MAX_DMA_CHANNELS];
+ struct msix_entry *msix_entries;
+#define INT_FLAG_INTERRUPT GENMASK(4, 0)
+#define INT_FLAG_MSI BIT(1)
+#define INT_FLAG_MSIX BIT(3)
+#define INT_FLAG_LEGACY BIT(4)
+#define INT_FLAG_RX0_NAPI BIT(18)
+#define INT_FLAG_RX1_NAPI BIT(19)
+#define INT_FLAG_RX2_NAPI BIT(20)
+#define INT_FLAG_RX3_NAPI BIT(21)
+#define INT_FLAG_RX0_IRQ BIT(22)
+#define INT_FLAG_RX1_IRQ BIT(23)
+#define INT_FLAG_RX2_IRQ BIT(24)
+#define INT_FLAG_RX3_IRQ BIT(25)
+#define INT_FLAG_TX_NAPI BIT(26)
+#define INT_FLAG_TX_IRQ BIT(27)
+#define INT_FLAG_LEGACY_NAPI BIT(30)
+#define INT_FLAG_LEGACY_IRQ BIT(31)
+ u32 int_flag; /* interrupt flag */
+
+ /* ndev related settings */
+ unsigned char mac_addr[ETH_ALEN];
+ struct napi_struct napi;
+
+ int mac_speed;
+ int mac_duplex;
+
+ u32 msg_enable;
+ u32 reg_nonstick[(MSI_PBA - GLOBAL_CTRL0) >> 2];
+
+ struct work_struct restart_work;
+ enum fxgmac_dev_state dev_state;
+#define FXGMAC_POWER_STATE_DOWN 0
+#define FXGMAC_POWER_STATE_UP 1
+ unsigned long power_state;
+};
+
+/* Non-constant mask variant of FIELD_GET() and FIELD_PREP() */
+#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
+#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask))
+
+static inline u32 fxgmac_io_rd(struct fxgmac_pdata *priv, u32 reg)
+{
+ return ioread32(priv->hw_addr + reg);
+}
+
+static inline u32
+fxgmac_io_rd_bits(struct fxgmac_pdata *priv, u32 reg, u32 mask)
+{
+ u32 cfg = fxgmac_io_rd(priv, reg);
+
+ return field_get(mask, cfg);
+}
+
+static inline void fxgmac_io_wr(struct fxgmac_pdata *priv, u32 reg, u32 set)
+{
+ iowrite32(set, priv->hw_addr + reg);
+}
+
+static inline void
+fxgmac_io_wr_bits(struct fxgmac_pdata *priv, u32 reg, u32 mask, u32 set)
+{
+ u32 cfg = fxgmac_io_rd(priv, reg);
+
+ cfg &= ~mask;
+ cfg |= field_prep(mask, set);
+ fxgmac_io_wr(priv, reg, cfg);
+}
+
+static inline u32 fxgmac_mtl_io_rd(struct fxgmac_pdata *priv, u8 n, u32 reg)
+{
+ return fxgmac_io_rd(priv, reg + n * MTL_Q_INC);
+}
+
+static inline u32
+fxgmac_mtl_rd_bits(struct fxgmac_pdata *priv, u8 n, u32 reg, u32 mask)
+{
+ return fxgmac_io_rd_bits(priv, reg + n * MTL_Q_INC, mask);
+}
+
+static inline void
+fxgmac_mtl_io_wr(struct fxgmac_pdata *priv, u8 n, u32 reg, u32 set)
+{
+ return fxgmac_io_wr(priv, reg + n * MTL_Q_INC, set);
+}
+
+static inline void
+fxgmac_mtl_wr_bits(struct fxgmac_pdata *priv, u8 n, u32 reg, u32 mask, u32 set)
+{
+ return fxgmac_io_wr_bits(priv, reg + n * MTL_Q_INC, mask, set);
+}
+
+static inline u32 fxgmac_dma_io_rd(struct fxgmac_channel *channel, u32 reg)
+{
+ return ioread32(channel->dma_regs + reg);
+}
+
+static inline u32
+fxgmac_dma_rd_bits(struct fxgmac_channel *channel, u32 reg, u32 mask)
+{
+ u32 cfg = fxgmac_dma_io_rd(channel, reg);
+
+ return field_get(mask, cfg);
+}
+
+static inline void
+fxgmac_dma_io_wr(struct fxgmac_channel *channel, u32 reg, u32 set)
+{
+ iowrite32(set, channel->dma_regs + reg);
+}
+
+static inline void
+fxgmac_dma_wr_bits(struct fxgmac_channel *channel, u32 reg, u32 mask, u32 set)
+{
+ u32 cfg = fxgmac_dma_io_rd(channel, reg);
+
+ cfg &= ~mask;
+ cfg |= field_prep(mask, set);
+ fxgmac_dma_io_wr(channel, reg, cfg);
+}
+
+static inline u32 fxgmac_desc_rd_bits(__le32 desc, u32 mask)
+{
+ return field_get(mask, le32_to_cpu(desc));
+}
+
+static inline void fxgmac_desc_wr_bits(__le32 *desc, u32 mask, u32 set)
+{
+ u32 cfg = le32_to_cpu(*desc);
+
+ cfg &= ~mask;
+ cfg |= field_prep(mask, set);
+ *desc = cpu_to_le32(cfg);
+}
+
+#endif /* YT6801_TYPE_H */
diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
index 7a11fdb68..7abd5dee8 100644
--- a/drivers/net/phy/motorcomm.c
+++ b/drivers/net/phy/motorcomm.c
@@ -819,6 +819,12 @@ static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev)
val |= FIELD_PREP(YT8521_RC1R_RX_DELAY_MASK, rx_reg) |
FIELD_PREP(YT8521_RC1R_GE_TX_DELAY_MASK, tx_reg);
break;
+ case PHY_INTERFACE_MODE_INTERNAL:
+ if (phydev->drv->phy_id != PHY_ID_YT8531S)
+ return -EOPNOTSUPP;
+
+ dev_info_once(&phydev->mdio.dev, "Integrated YT8531S phy of YT6801.\n");
+ return 0;
default: /* do not support other modes */
return -EOPNOTSUPP;
}
--
2.34.1
2
1

[PATCH OLK-6.6] kvm: x86: fix infinite loop in kvm_guest_time_update when tsc is 0
by Yuntao Liu 13 May '25
by Yuntao Liu 13 May '25
13 May '25
hulk inclusion
category: bugfix
bugzilla: 190614
--------------------------------
Syzkaller testing detected a soft lockup.
watchdog: BUG: soft lockup - CPU#3 stuck for 127s! [syz.1.2088:9817]
Modules linked in:
CPU: 3 PID: 9817 Comm: syz.1.2088 Tainted: G S 6.6.0+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
RIP: 0010:__sanitizer_cov_trace_const_cmp4+0x8/0x20 kernel/kcov.c:313
Code: bf 03 00 00 00 e9 48 fe ff ff 0f 1f 84 00 00 00 00 00 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 48 8b 0c 24 <89> f2 89
fe bf 05 00 00 00 e9 1a fe ff ff 66 2e 0f 1f 84 00 00 00
RSP: 0018:ffff888016d8fad8 EFLAGS: 00000206
RAX: 0000000000080000 RBX: ffff88810e242540 RCX: ffffffff901150d6
RDX: 0000000000080000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffff888016d8fb50 R08: 0000000000000001 R09: ffffed1021c484af
R10: 0000000000000000 R11: 0000000000000277 R12: 0000000000000000
R13: fffffed357281918 R14: 0000000000000000 R15: 0000000000000001
FS: 00007f2a8f6ea6c0(0000) GS:ffff888119780000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000012c56c0 CR3: 000000000dce8001 CR4: 0000000000772ee0
DR0: 0000000000000000 DR1: 0000000000d3eb1c DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
PKRU: 80000000
Call Trace:
<TASK>
kvm_get_time_scale arch/x86/kvm/x86.c:2458 [inline]
kvm_guest_time_update+0x926/0xb00 arch/x86/kvm/x86.c:3268
vcpu_enter_guest.constprop.0+0x1e70/0x3cf0 arch/x86/kvm/x86.c:10678
vcpu_run+0x129/0x8d0 arch/x86/kvm/x86.c:11126
kvm_arch_vcpu_ioctl_run+0x37a/0x13d0 arch/x86/kvm/x86.c:11352
kvm_vcpu_ioctl+0x56b/0xe60 virt/kvm/kvm_main.c:4188
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:871 [inline]
__se_sys_ioctl+0x12d/0x190 fs/ioctl.c:857
do_syscall_x64 arch/x86/entry/common.c:51 [inline]
do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81
entry_SYSCALL_64_after_hwframe+0x78/0xe2
test case:
18.689865147s ago: executing program 1 (id=2088):
r0 = openat$kvm(0xffffffffffffff9c, &(0x7f0000002080), 0x0, 0x0)
r1 = ioctl$KVM_CREATE_VM(r0, 0xae01, 0x0)
r2 = ioctl$KVM_CREATE_VCPU(r1, 0xae41, 0x0)
ioctl$KVM_RUN(r2, 0xae80, 0x0)
ioctl$KVM_SET_TSC_KHZ(r2, 0xaea2, 0x1)
socket$nl_route(0x10, 0x3, 0x0)
r3 = socket$igmp(0x2, 0x3, 0x2)
ioctl$sock_SIOCGIFINDEX(r3, 0x8933, &(0x7f00000001c0)={'netdevsim0\x00',
<r4=>0x0})
r5 = bpf$MAP_CREATE(0x0, &(0x7f0000000140)=@base={0x1, 0x4, 0x8000, 0x2,
0x0, 0xffffffffffffffff, 0x0, '\x00', r4, 0xffffffffffffffff, 0x0, 0x0,
0x0, 0x0, @void, @value, @void, @value}, 0x50)
bpf$MAP_UPDATE_CONST_STR(0x2, &(0x7f0000000100)={{r5},
&(0x7f0000000000), &(0x7f0000000040)='%ps \x00'}, 0x20)
bpf$MAP_DELETE_ELEM(0x3, &(0x7f00000000c0)={r5, &(0x7f0000001480)},
0x20)
ioctl$KVM_SET_USER_MEMORY_REGION(r1, 0x4020ae46,
&(0x7f0000000000)={0x1ff, 0x3, 0x3000, 0x1000,
&(0x7f0000fec000/0x1000)=nil})
syz_kvm_setup_cpu$x86(r1, 0xffffffffffffffff,
&(0x7f0000fe8000/0x18000)=nil, &(0x7f0000000100)=[@textreal={0x8, 0x0}],
0x1, 0x0, 0x0, 0x0)
ioctl$KVM_SET_USER_MEMORY_REGION(0xffffffffffffffff, 0x4020ae46, 0x0)
openat$ipvs(0xffffffffffffff9c, 0x0, 0x2, 0x0)
syz_kvm_setup_cpu$x86(0xffffffffffffffff, r2,
&(0x7f0000fe8000/0x18000)=nil, &(0x7f00000000c0)=[@text64={0x40,
&(0x7f0000000040)="26f2a70f3548b807000000000000000f23c00f21f835020008000f23f80fc73eb9330800000f326666470f3880be6cc468550f01cf360f01f80f30450f01c9",
0x3f}], 0x1, 0x0, 0x0, 0x0)
ioctl$KVM_RUN(r2, 0xae80, 0x0)
ioctl$KVM_SET_TSC_KHZ(r2, 0xaea2, 0x1)
user_tsc_khz = 0x1
|
kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz)
|
ioctl$KVM_RUN(r2, 0xae80, 0x0)
|
...
kvm_guest_time_update(struct kvm_vcpu *v)
|
if (kvm_caps.has_tsc_control)
tgt_tsc_khz = kvm_scale_tsc(tgt_tsc_khz,
v->arch.l1_tsc_scaling_ratio);
|
kvm_scale_tsc(u64 tsc, u64 ratio)
|
__scale_tsc(u64 ratio, u64 tsc)
ratio=122380531, tsc=2299998, N=48
ratio*tsc >> N = 0.999... -> 0
|
kvm_get_time_scale
In function __scale_tsc, it uses fixed point number to calculate
tsc, therefore, a certain degree of precision is lost, the actual tsc
value of 0.999... would be 0. In function kvm_get_time_scale
tps32=tps64=base_hz=0, would lead second while_loop infinite. when
CONFIG_PREEMPT is n, it causes a soft lockup issue.
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
arch/x86/kvm/x86.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1fa5d89f8d27..c4e23bf4c9ba 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2605,10 +2605,13 @@ static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
* point number (mult + frac * 2^(-N)).
*
* N equals to kvm_caps.tsc_scaling_ratio_frac_bits.
+ *
+ * return 1 if _tsc is 0.
*/
static inline u64 __scale_tsc(u64 ratio, u64 tsc)
{
- return mul_u64_u64_shr(tsc, ratio, kvm_caps.tsc_scaling_ratio_frac_bits);
+ u64 _tsc = mul_u64_u64_shr(tsc, ratio, kvm_caps.tsc_scaling_ratio_frac_bits);
+ return !_tsc ? 1 : _tsc;
}
u64 kvm_scale_tsc(u64 tsc, u64 ratio)
--
2.34.1
2
1

[PATCH OLK-6.6] kvm: x86: fix infinite loop in kvm_guest_time_update when tsc is 0
by Yuntao Liu 13 May '25
by Yuntao Liu 13 May '25
13 May '25
hulk inclusion
category: bugfix
bugzilla: 190614
--------------------------------
Syzkaller testing detected a soft lockup.
watchdog: BUG: soft lockup - CPU#3 stuck for 127s! [syz.1.2088:9817]
Modules linked in:
CPU: 3 PID: 9817 Comm: syz.1.2088 Tainted: G S 6.6.0+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
RIP: 0010:__sanitizer_cov_trace_const_cmp4+0x8/0x20 kernel/kcov.c:313
Code: bf 03 00 00 00 e9 48 fe ff ff 0f 1f 84 00 00 00 00 00 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 48 8b 0c 24 <89> f2 89
fe bf 05 00 00 00 e9 1a fe ff ff 66 2e 0f 1f 84 00 00 00
RSP: 0018:ffff888016d8fad8 EFLAGS: 00000206
RAX: 0000000000080000 RBX: ffff88810e242540 RCX: ffffffff901150d6
RDX: 0000000000080000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffff888016d8fb50 R08: 0000000000000001 R09: ffffed1021c484af
R10: 0000000000000000 R11: 0000000000000277 R12: 0000000000000000
R13: fffffed357281918 R14: 0000000000000000 R15: 0000000000000001
FS: 00007f2a8f6ea6c0(0000) GS:ffff888119780000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000012c56c0 CR3: 000000000dce8001 CR4: 0000000000772ee0
DR0: 0000000000000000 DR1: 0000000000d3eb1c DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
PKRU: 80000000
Call Trace:
<TASK>
kvm_get_time_scale arch/x86/kvm/x86.c:2458 [inline]
kvm_guest_time_update+0x926/0xb00 arch/x86/kvm/x86.c:3268
vcpu_enter_guest.constprop.0+0x1e70/0x3cf0 arch/x86/kvm/x86.c:10678
vcpu_run+0x129/0x8d0 arch/x86/kvm/x86.c:11126
kvm_arch_vcpu_ioctl_run+0x37a/0x13d0 arch/x86/kvm/x86.c:11352
kvm_vcpu_ioctl+0x56b/0xe60 virt/kvm/kvm_main.c:4188
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:871 [inline]
__se_sys_ioctl+0x12d/0x190 fs/ioctl.c:857
do_syscall_x64 arch/x86/entry/common.c:51 [inline]
do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81
entry_SYSCALL_64_after_hwframe+0x78/0xe2
test case:
18.689865147s ago: executing program 1 (id=2088):
r0 = openat$kvm(0xffffffffffffff9c, &(0x7f0000002080), 0x0, 0x0)
r1 = ioctl$KVM_CREATE_VM(r0, 0xae01, 0x0)
r2 = ioctl$KVM_CREATE_VCPU(r1, 0xae41, 0x0)
ioctl$KVM_RUN(r2, 0xae80, 0x0)
ioctl$KVM_SET_TSC_KHZ(r2, 0xaea2, 0x1)
socket$nl_route(0x10, 0x3, 0x0)
r3 = socket$igmp(0x2, 0x3, 0x2)
ioctl$sock_SIOCGIFINDEX(r3, 0x8933, &(0x7f00000001c0)={'netdevsim0\x00',
<r4=>0x0})
r5 = bpf$MAP_CREATE(0x0, &(0x7f0000000140)=@base={0x1, 0x4, 0x8000, 0x2,
0x0, 0xffffffffffffffff, 0x0, '\x00', r4, 0xffffffffffffffff, 0x0, 0x0,
0x0, 0x0, @void, @value, @void, @value}, 0x50)
bpf$MAP_UPDATE_CONST_STR(0x2, &(0x7f0000000100)={{r5},
&(0x7f0000000000), &(0x7f0000000040)='%ps \x00'}, 0x20)
bpf$MAP_DELETE_ELEM(0x3, &(0x7f00000000c0)={r5, &(0x7f0000001480)},
0x20)
ioctl$KVM_SET_USER_MEMORY_REGION(r1, 0x4020ae46,
&(0x7f0000000000)={0x1ff, 0x3, 0x3000, 0x1000,
&(0x7f0000fec000/0x1000)=nil})
syz_kvm_setup_cpu$x86(r1, 0xffffffffffffffff,
&(0x7f0000fe8000/0x18000)=nil, &(0x7f0000000100)=[@textreal={0x8, 0x0}],
0x1, 0x0, 0x0, 0x0)
ioctl$KVM_SET_USER_MEMORY_REGION(0xffffffffffffffff, 0x4020ae46, 0x0)
openat$ipvs(0xffffffffffffff9c, 0x0, 0x2, 0x0)
syz_kvm_setup_cpu$x86(0xffffffffffffffff, r2,
&(0x7f0000fe8000/0x18000)=nil, &(0x7f00000000c0)=[@text64={0x40,
&(0x7f0000000040)="26f2a70f3548b807000000000000000f23c00f21f835020008000f23f80fc73eb9330800000f326666470f3880be6cc468550f01cf360f01f80f30450f01c9",
0x3f}], 0x1, 0x0, 0x0, 0x0)
ioctl$KVM_RUN(r2, 0xae80, 0x0)
ioctl$KVM_SET_TSC_KHZ(r2, 0xaea2, 0x1)
user_tsc_khz = 0x1
|
kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz)
|
ioctl$KVM_RUN(r2, 0xae80, 0x0)
|
...
kvm_guest_time_update(struct kvm_vcpu *v)
|
if (kvm_caps.has_tsc_control)
tgt_tsc_khz = kvm_scale_tsc(tgt_tsc_khz,
v->arch.l1_tsc_scaling_ratio);
|
kvm_scale_tsc(u64 tsc, u64 ratio)
|
__scale_tsc(u64 ratio, u64 tsc)
ratio=122380531, tsc=2299998, N=48
ratio*tsc >> N = 0.999... -> 0
|
kvm_get_time_scale
In function __scale_tsc, it uses fixed point number to calculate
tsc, therefore, a certain degree of precision is lost, the actual tsc
value of 0.999... would be 0. In function kvm_get_time_scale
tps32=tps64=base_hz=0, would lead second while_loop infinite. when
CONFIG_PREEMPT is n, it causes a soft lockup issue.
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
arch/x86/kvm/x86.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1fa5d89f8d27..92460a69ff0f 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2605,10 +2605,12 @@ static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
* point number (mult + frac * 2^(-N)).
*
* N equals to kvm_caps.tsc_scaling_ratio_frac_bits.
+ *
+ * add 1 to compensate for precision loss.
*/
static inline u64 __scale_tsc(u64 ratio, u64 tsc)
{
- return mul_u64_u64_shr(tsc, ratio, kvm_caps.tsc_scaling_ratio_frac_bits);
+ return mul_u64_u64_shr(tsc, ratio, kvm_caps.tsc_scaling_ratio_frac_bits) + 1;
}
u64 kvm_scale_tsc(u64 tsc, u64 ratio)
--
2.34.1
2
1

[openeuler:OLK-6.6 2220/2220] mm/page_cache_limit.c:103:52: sparse: sparse: incorrect type in argument 3 (different address spaces)
by kernel test robot 13 May '25
by kernel test robot 13 May '25
13 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: 6774b4d00f21c00ceb15ad07eb37bea260679b5a
commit: 7d1031b36ebd6c273d9aad316fd9e3e2daa01a85 [2220/2220] mm: support pagecache limit
config: x86_64-randconfig-123-20250513 (https://download.01.org/0day-ci/archive/20250513/202505131433.CYS9yklz-lkp@…)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250513/202505131433.CYS9yklz-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505131433.CYS9yklz-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
mm/page_cache_limit.c:61:5: sparse: sparse: symbol 'cache_reclaim_enable_handler' was not declared. Should it be static?
mm/page_cache_limit.c:77:5: sparse: sparse: symbol 'cache_reclaim_sysctl_handler' was not declared. Should it be static?
>> mm/page_cache_limit.c:103:52: sparse: sparse: incorrect type in argument 3 (different address spaces) @@ expected void * @@ got void [noderef] __user *buffer @@
mm/page_cache_limit.c:103:52: sparse: expected void *
mm/page_cache_limit.c:103:52: sparse: got void [noderef] __user *buffer
>> mm/page_cache_limit.c:94:5: sparse: sparse: symbol 'cache_limit_mbytes_sysctl_handler' was not declared. Should it be static?
>> mm/page_cache_limit.c:187:35: sparse: sparse: incorrect type in initializer (incompatible argument 3 (different address spaces)) @@ expected int ( [usertype] *proc_handler )( ... ) @@ got int ( * )( ... ) @@
mm/page_cache_limit.c:187:35: sparse: expected int ( [usertype] *proc_handler )( ... )
mm/page_cache_limit.c:187:35: sparse: got int ( * )( ... )
vim +103 mm/page_cache_limit.c
93
> 94 int cache_limit_mbytes_sysctl_handler(struct ctl_table *table, int write,
95 void __user *buffer, size_t *length, loff_t *ppos)
96 {
97 int ret;
98 unsigned long vm_cache_limit_mbytes_max;
99 unsigned long origin_mbytes = vm_cache_limit_mbytes;
100 int nr_retries = MAX_RECLAIM_RETRIES;
101
102 vm_cache_limit_mbytes_max = totalram_pages() >> (20 - PAGE_SHIFT);
> 103 ret = proc_doulongvec_minmax(table, write, buffer, length, ppos);
104 if (ret || !write)
105 return ret;
106
107 if (vm_cache_limit_mbytes > vm_cache_limit_mbytes_max) {
108 vm_cache_limit_mbytes = origin_mbytes;
109 return -EINVAL;
110 }
111
112 if (write) {
113 while (should_reclaim_page_cache() && page_cache_over_limit() &&
114 nr_retries--) {
115 if (signal_pending(current))
116 return -EINTR;
117
118 shrink_memory(node_reclaim_num(), false);
119 }
120 }
121
122 return 0;
123 }
124
125 static void shrink_shepherd(struct work_struct *w)
126 {
127 int node;
128
129 if (!should_periodical_reclaim())
130 return;
131
132 for_each_online_node(node) {
133 if (!work_pending(&vmscan_works[node]))
134 queue_work_node(node, system_unbound_wq, &vmscan_works[node]);
135 }
136
137 queue_delayed_work(system_unbound_wq, &shepherd,
138 round_jiffies_relative((unsigned long)vm_cache_reclaim_s * HZ));
139 }
140
141 static void shrink_page_work(struct work_struct *w)
142 {
143 shrink_memory(node_reclaim_num(), true);
144 }
145
146 static void shrink_shepherd_timer(void)
147 {
148 int i;
149
150 for (i = 0; i < MAX_NUMNODES; i++)
151 INIT_WORK(&vmscan_works[i], shrink_page_work);
152 }
153
154 static struct ctl_table page_cache_limit_table[] = {
155 {
156 .procname = "cache_reclaim_s",
157 .data = &vm_cache_reclaim_s,
158 .maxlen = sizeof(vm_cache_reclaim_s),
159 .mode = 0644,
160 .proc_handler = cache_reclaim_sysctl_handler,
161 .extra1 = SYSCTL_ZERO,
162 .extra2 = &vm_cache_reclaim_s_max,
163 },
164 {
165 .procname = "cache_reclaim_weight",
166 .data = &vm_cache_reclaim_weight,
167 .maxlen = sizeof(vm_cache_reclaim_weight),
168 .mode = 0644,
169 .proc_handler = proc_dointvec_minmax,
170 .extra1 = SYSCTL_ONE,
171 .extra2 = &vm_cache_reclaim_weight_max,
172 },
173 {
174 .procname = "cache_reclaim_enable",
175 .data = &vm_cache_reclaim_enable,
176 .maxlen = sizeof(vm_cache_reclaim_enable),
177 .mode = 0644,
178 .proc_handler = cache_reclaim_enable_handler,
179 .extra1 = SYSCTL_ZERO,
180 .extra2 = SYSCTL_ONE,
181 },
182 {
183 .procname = "cache_limit_mbytes",
184 .data = &vm_cache_limit_mbytes,
185 .maxlen = sizeof(vm_cache_limit_mbytes),
186 .mode = 0644,
> 187 .proc_handler = cache_limit_mbytes_sysctl_handler,
188 },
189 };
190
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-6.6 2220/2220] mm/memcontrol.c:4061:5: sparse: sparse: symbol 'sysctl_memcg_oom_prio' was not declared. Should it be static?
by kernel test robot 13 May '25
by kernel test robot 13 May '25
13 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: 6774b4d00f21c00ceb15ad07eb37bea260679b5a
commit: 44391f3171b05060096ff496f3507033f2460161 [2220/2220] memcg: Add sysctl memcg_qos_enable
config: x86_64-randconfig-122-20250513 (https://download.01.org/0day-ci/archive/20250513/202505131644.aKjQmueq-lkp@…)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250513/202505131644.aKjQmueq-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505131644.aKjQmueq-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
>> mm/memcontrol.c:4061:5: sparse: sparse: symbol 'sysctl_memcg_oom_prio' was not declared. Should it be static?
mm/memcontrol.c:4223:50: sparse: sparse: incorrect type in argument 3 (different address spaces) @@ expected void * @@ got void [noderef] __user *buffer @@
mm/memcontrol.c:4223:50: sparse: expected void *
mm/memcontrol.c:4223:50: sparse: got void [noderef] __user *buffer
>> mm/memcontrol.c:4245:35: sparse: sparse: incorrect type in initializer (incompatible argument 3 (different address spaces)) @@ expected int ( [usertype] *proc_handler )( ... ) @@ got int ( * )( ... ) @@
mm/memcontrol.c:4245:35: sparse: expected int ( [usertype] *proc_handler )( ... )
mm/memcontrol.c:4245:35: sparse: got int ( * )( ... )
mm/memcontrol.c:4504:21: sparse: sparse: incompatible types in comparison expression (different address spaces):
mm/memcontrol.c:4504:21: sparse: struct mem_cgroup_threshold_ary [noderef] __rcu *
mm/memcontrol.c:4504:21: sparse: struct mem_cgroup_threshold_ary *
mm/memcontrol.c:4506:21: sparse: sparse: incompatible types in comparison expression (different address spaces):
mm/memcontrol.c:4506:21: sparse: struct mem_cgroup_threshold_ary [noderef] __rcu *
mm/memcontrol.c:4506:21: sparse: struct mem_cgroup_threshold_ary *
mm/memcontrol.c:4662:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
mm/memcontrol.c:4662:9: sparse: struct mem_cgroup_threshold_ary [noderef] __rcu *
mm/memcontrol.c:4662:9: sparse: struct mem_cgroup_threshold_ary *
mm/memcontrol.c:4756:9: sparse: sparse: incompatible types in comparison expression (different address spaces):
mm/memcontrol.c:4756:9: sparse: struct mem_cgroup_threshold_ary [noderef] __rcu *
mm/memcontrol.c:4756:9: sparse: struct mem_cgroup_threshold_ary *
mm/memcontrol.c:6799:23: sparse: sparse: incompatible types in comparison expression (different address spaces):
mm/memcontrol.c:6799:23: sparse: struct task_struct [noderef] __rcu *
mm/memcontrol.c:6799:23: sparse: struct task_struct *
mm/memcontrol.c: note: in included file:
include/linux/memcontrol.h:782:9: sparse: sparse: context imbalance in 'folio_lruvec_lock' - wrong count at exit
include/linux/memcontrol.h:782:9: sparse: sparse: context imbalance in 'folio_lruvec_lock_irq' - wrong count at exit
include/linux/memcontrol.h:782:9: sparse: sparse: context imbalance in 'folio_lruvec_lock_irqsave' - wrong count at exit
mm/memcontrol.c:2134:6: sparse: sparse: context imbalance in 'folio_memcg_lock' - wrong count at exit
mm/memcontrol.c:2181:17: sparse: sparse: context imbalance in '__folio_memcg_unlock' - unexpected unlock
mm/memcontrol.c: note: in included file (through include/linux/rculist.h, include/linux/pid.h, include/linux/sched.h, ...):
include/linux/rcupdate.h:780:9: sparse: sparse: context imbalance in 'mem_cgroup_count_precharge_pte_range' - unexpected unlock
include/linux/rcupdate.h:780:9: sparse: sparse: context imbalance in 'mem_cgroup_move_charge_pte_range' - unexpected unlock
vim +/sysctl_memcg_oom_prio +4061 mm/memcontrol.c
4057
4058 #ifdef CONFIG_MEMCG_OOM_PRIORITY
4059 #define ENABLE_MEMCG_OOM_PROIRITY 1
4060 #define DISABLE_MEMCG_OOM_PROIRITY 0
> 4061 int sysctl_memcg_oom_prio = DISABLE_MEMCG_OOM_PROIRITY;
4062
4063 bool memcg_oom_prio_disabled(void)
4064 {
4065 return READ_ONCE(sysctl_memcg_oom_prio) == DISABLE_MEMCG_OOM_PROIRITY;
4066 }
4067
4068 static void memcg_oom_prio_init(struct mem_cgroup *memcg)
4069 {
4070 struct mem_cgroup *parent = parent_mem_cgroup(memcg);
4071 int oom_prio;
4072
4073 if (!parent)
4074 return;
4075
4076 oom_prio = READ_ONCE(parent->oom_prio);
4077 WRITE_ONCE(memcg->oom_prio, oom_prio);
4078 }
4079
4080 static s64 memcg_oom_prio_read(struct cgroup_subsys_state *css,
4081 struct cftype *cft)
4082 {
4083 struct mem_cgroup *memcg = mem_cgroup_from_css(css);
4084
4085 if (memcg_oom_prio_disabled())
4086 return 0;
4087
4088 return READ_ONCE(memcg->oom_prio);
4089 }
4090
4091 static int memcg_oom_prio_write(struct cgroup_subsys_state *css,
4092 struct cftype *cft, s64 val)
4093 {
4094 struct mem_cgroup *memcg = mem_cgroup_from_css(css);
4095 struct mem_cgroup *iter_memcg;
4096 struct cgroup_subsys_state *iter_css;
4097
4098 if (memcg_oom_prio_disabled())
4099 return -EACCES;
4100
4101 if (mem_cgroup_is_root(memcg))
4102 return -EINVAL;
4103
4104 if (val != MEMCG_LOW_OOM_PRIORITY && val != MEMCG_HIGH_OOM_PRIORITY)
4105 return -EINVAL;
4106
4107 rcu_read_lock();
4108 css_for_each_descendant_pre(iter_css, &memcg->css) {
4109 iter_memcg = mem_cgroup_from_css(iter_css);
4110
4111 WRITE_ONCE(iter_memcg->oom_prio, val);
4112 }
4113 rcu_read_unlock();
4114
4115 return 0;
4116 }
4117
4118 static struct mem_cgroup *memcg_find_max_usage(struct mem_cgroup *last)
4119 {
4120 struct mem_cgroup *iter, *max_memcg = NULL;
4121 struct cgroup_subsys_state *css;
4122 unsigned long usage, max_usage = 0;
4123 int oom_prio;
4124
4125 rcu_read_lock();
4126 css_for_each_descendant_pre(css, &root_mem_cgroup->css) {
4127 iter = mem_cgroup_from_css(css);
4128 oom_prio = READ_ONCE(iter->oom_prio);
4129
4130 if (oom_prio == MEMCG_HIGH_OOM_PRIORITY ||
4131 iter == root_mem_cgroup ||
4132 iter == last)
4133 continue;
4134
4135 usage = mem_cgroup_usage(iter, false);
4136 if (usage > max_usage) {
4137 max_usage = usage;
4138 max_memcg = iter;
4139 }
4140 }
4141 rcu_read_unlock();
4142
4143 return max_memcg;
4144 }
4145
4146 bool memcg_oom_prio_scan_tasks(int (*fn)(struct task_struct *, void *),
4147 void *arg)
4148 {
4149 struct mem_cgroup *max, *last = NULL;
4150 struct oom_control *oc = arg;
4151 struct css_task_iter it;
4152 struct task_struct *task;
4153 int ret = 0;
4154 bool retry = true;
4155
4156 if (memcg_oom_prio_disabled())
4157 return false;
4158 retry:
4159 max = memcg_find_max_usage(last);
4160 if (!max)
4161 return false;
4162
4163 css_task_iter_start(&max->css, 0, &it);
4164 while (!ret && (task = css_task_iter_next(&it))) {
4165 if (test_tsk_thread_flag(task, TIF_MEMDIE))
4166 continue;
4167
4168 ret = fn(task, arg);
4169 }
4170 css_task_iter_end(&it);
4171
4172 if (ret)
4173 return false;
4174
4175 if (!oc->chosen && retry) {
4176 last = max;
4177 retry = false;
4178 goto retry;
4179 }
4180
4181 if (oc->chosen)
4182 pr_info("The bad task [%d:%s] is from low-priority memcg.\n",
4183 oc->chosen->pid, oc->chosen->comm);
4184
4185 return oc->chosen ? true : false;
4186 }
4187
4188 void memcg_print_bad_task(struct oom_control *oc)
4189 {
4190 if (memcg_oom_prio_disabled())
4191 return;
4192
4193 if (oc->chosen) {
4194 struct mem_cgroup *memcg;
4195
4196 rcu_read_lock();
4197 memcg = mem_cgroup_from_task(oc->chosen);
4198 if (READ_ONCE(memcg->oom_prio) == MEMCG_LOW_OOM_PRIORITY)
4199 pr_info("The bad task [%d:%s] is from low-priority memcg.\n",
4200 oc->chosen->pid, oc->chosen->comm);
4201 rcu_read_unlock();
4202 }
4203 }
4204
4205 static void memcg_oom_prio_reset(void)
4206 {
4207 struct mem_cgroup *iter;
4208 struct cgroup_subsys_state *css;
4209
4210 rcu_read_lock();
4211 css_for_each_descendant_pre(css, &root_mem_cgroup->css) {
4212 iter = mem_cgroup_from_css(css);
4213 WRITE_ONCE(iter->oom_prio, 0);
4214 }
4215 rcu_read_unlock();
4216 }
4217
4218 static int sysctl_memcg_oom_prio_handler(struct ctl_table *table, int write,
4219 void __user *buffer, size_t *length, loff_t *ppos)
4220 {
4221 int ret;
4222
4223 ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
4224 if (ret)
4225 return ret;
4226
4227 if (write) {
4228 if (READ_ONCE(sysctl_memcg_oom_prio) == DISABLE_MEMCG_OOM_PROIRITY)
4229 memcg_oom_prio_reset();
4230 }
4231
4232 return ret;
4233 }
4234
4235 static struct ctl_table memcg_oom_prio_sysctls[] = {
4236 {
4237 /*
4238 * This sysctl is used to control memcg oom priority
4239 * feature, the sysctl name is for compatibility.
4240 */
4241 .procname = "memcg_qos_enable",
4242 .data = &sysctl_memcg_oom_prio,
4243 .maxlen = sizeof(int),
4244 .mode = 0644,
> 4245 .proc_handler = sysctl_memcg_oom_prio_handler,
4246 .extra1 = SYSCTL_ZERO,
4247 .extra2 = SYSCTL_ONE,
4248 },
4249 };
4250
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0
Binbin Zhou (1):
dt-bindings: pwm: Add Loongson PWM controller
wanghongliang (1):
pwm: Add Loongson pwm driver support
.../bindings/pwm/loongson,ls7a-pwm.yaml | 67 +++++
MAINTAINERS | 7 +
arch/loongarch/configs/loongson3_defconfig | 1 +
drivers/pwm/Kconfig | 12 +
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-loongson.c | 280 ++++++++++++++++++
6 files changed, 368 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pwm/loongson,ls7a-pwm.yaml
create mode 100644 drivers/pwm/pwm-loongson.c
--
2.33.0
2
3
Support fuse fastpath by using the newly added fast_ipc module.
Alessio Balsini (2):
fuse: 32-bit user space ioctl compat for fuse device
fuse: fix matching of FUSE_DEV_IOC_CLONE command
chenrenhui (2):
ipc: add fast_ipc module to enable fast process switching
fuse: support fastpath via fast_ipc
yangyun (1):
fuse: add fast path for fuse_range_is_writeback
Kconfig | 2 +
arch/arm64/configs/openeuler_defconfig | 2 +
fs/fuse/Kconfig | 9 +
fs/fuse/dev.c | 767 ++++++++++++++++++++++++-
fs/fuse/dir.c | 87 ++-
fs/fuse/file.c | 235 +++++++-
fs/fuse/fuse_i.h | 55 ++
fs/fuse/inode.c | 114 ++++
fs/fuse/readdir.c | 8 +
include/linux/fast_ipc.h | 45 ++
include/uapi/linux/fuse.h | 15 +-
ipc/Kconfig | 6 +
ipc/Makefile | 2 +-
ipc/fast_ipc.c | 296 ++++++++++
14 files changed, 1601 insertions(+), 42 deletions(-)
create mode 100644 include/linux/fast_ipc.h
create mode 100644 ipc/Kconfig
create mode 100644 ipc/fast_ipc.c
--
2.33.0
2
6
Support fuse fastpath by using the newly added fast_ipc module.
Alessio Balsini (2):
fuse: 32-bit user space ioctl compat for fuse device
fuse: fix matching of FUSE_DEV_IOC_CLONE command
chenrenhui (2):
ipc: add fast_ipc module to enable fast process switching
fuse: support fastpath via fast_ipc
yangyun (1):
fuse: add fast path for fuse_range_is_writeback
Kconfig | 2 +
arch/arm64/configs/openeuler_defconfig | 2 +
fs/fuse/Kconfig | 9 +
fs/fuse/dev.c | 767 ++++++++++++++++++++++++-
fs/fuse/dir.c | 87 ++-
fs/fuse/file.c | 235 +++++++-
fs/fuse/fuse_i.h | 55 ++
fs/fuse/inode.c | 116 +++-
fs/fuse/readdir.c | 8 +
include/linux/fast_ipc.h | 45 ++
include/uapi/linux/fuse.h | 15 +-
ipc/Kconfig | 6 +
ipc/Makefile | 2 +-
ipc/fast_ipc.c | 296 ++++++++++
14 files changed, 1602 insertions(+), 43 deletions(-)
create mode 100644 include/linux/fast_ipc.h
create mode 100644 ipc/Kconfig
create mode 100644 ipc/fast_ipc.c
--
2.33.0
2
6
Support fuse fastpath by using the newly added fast_ipc module.
Alessio Balsini (2):
fuse: 32-bit user space ioctl compat for fuse device
fuse: fix matching of FUSE_DEV_IOC_CLONE command
chenrenhui (2):
ipc: add fast_ipc module to enable fast process switching
fuse: support fastpath via fast_ipc
yangyun (1):
fuse: add fast path for fuse_range_is_writeback
Kconfig | 2 +
arch/arm64/configs/openeuler_defconfig | 2 +
fs/fuse/Kconfig | 9 +
fs/fuse/dev.c | 769 ++++++++++++++++++++++++-
fs/fuse/dir.c | 87 ++-
fs/fuse/file.c | 236 +++++++-
fs/fuse/fuse_i.h | 55 ++
fs/fuse/inode.c | 116 +++-
fs/fuse/readdir.c | 8 +
include/linux/fast_ipc.h | 48 ++
include/uapi/linux/fuse.h | 15 +-
ipc/Kconfig | 6 +
ipc/Makefile | 2 +-
ipc/fast_ipc.c | 299 ++++++++++
14 files changed, 1611 insertions(+), 43 deletions(-)
create mode 100644 include/linux/fast_ipc.h
create mode 100644 ipc/Kconfig
create mode 100644 ipc/fast_ipc.c
--
2.33.0
2
6

[PATCH openEuler-1.0-LTS] dm ioctl: fix misbehavior if list_versions races with module loading
by Zheng Qixing 13 May '25
by Zheng Qixing 13 May '25
13 May '25
From: Mikulas Patocka <mpatocka(a)redhat.com>
stable inclusion
from stable-v4.19.267
commit 3a1c35d72dc0b34d1e746ed705790c0f630aa427
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC5BWC
CVE: CVE-2022-49771
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
------------------
commit 4fe1ec995483737f3d2a14c3fe1d8fe634972979 upstream.
__list_versions will first estimate the required space using the
"dm_target_iterate(list_version_get_needed, &needed)" call and then will
fill the space using the "dm_target_iterate(list_version_get_info,
&iter_info)" call. Each of these calls locks the targets using the
"down_read(&_lock)" and "up_read(&_lock)" calls, however between the first
and second "dm_target_iterate" there is no lock held and the target
modules can be loaded at this point, so the second "dm_target_iterate"
call may need more space than what was the first "dm_target_iterate"
returned.
The code tries to handle this overflow (see the beginning of
list_version_get_info), however this handling is incorrect.
The code sets "param->data_size = param->data_start + needed" and
"iter_info.end = (char *)vers+len" - "needed" is the size returned by the
first dm_target_iterate call; "len" is the size of the buffer allocated by
userspace.
"len" may be greater than "needed"; in this case, the code will write up
to "len" bytes into the buffer, however param->data_size is set to
"needed", so it may write data past the param->data_size value. The ioctl
interface copies only up to param->data_size into userspace, thus part of
the result will be truncated.
Fix this bug by setting "iter_info.end = (char *)vers + needed;" - this
guarantees that the second "dm_target_iterate" call will write only up to
the "needed" buffer and it will exit with "DM_BUFFER_FULL_FLAG" if it
overflows the "needed" space - in this case, userspace will allocate a
larger buffer and retry.
Note that there is also a bug in list_version_get_needed - we need to add
"strlen(tt->name) + 1" to the needed size, not "strlen(tt->name)".
Cc: stable(a)vger.kernel.org
Signed-off-by: Mikulas Patocka <mpatocka(a)redhat.com>
Signed-off-by: Mike Snitzer <snitzer(a)kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Zheng Qixing <zhengqixing(a)huawei.com>
---
drivers/md/dm-ioctl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index c8c27d23bb45..2b00359e4825 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -573,7 +573,7 @@ static void list_version_get_needed(struct target_type *tt, void *needed_param)
size_t *needed = needed_param;
*needed += sizeof(struct dm_target_versions);
- *needed += strlen(tt->name);
+ *needed += strlen(tt->name) + 1;
*needed += ALIGN_MASK;
}
@@ -628,7 +628,7 @@ static int list_versions(struct file *filp, struct dm_ioctl *param, size_t param
iter_info.old_vers = NULL;
iter_info.vers = vers;
iter_info.flags = 0;
- iter_info.end = (char *)vers+len;
+ iter_info.end = (char *)vers + needed;
/*
* Now loop through filling out the names & versions.
--
2.39.2
2
1

[openeuler:OLK-6.6 2220/2220] kernel/sched/fair.c:8325:9: error: call to undeclared function 'sched_idle_cpu'; ISO C99 and later do not support implicit function declarations
by kernel test robot 13 May '25
by kernel test robot 13 May '25
13 May '25
Hi Zhang,
FYI, the error/warning still remains.
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: e1106320058bf1d983657f80490249b4f919ebad
commit: 926b9b0cd97e640ee680347cf449c3dc152dddd2 [2220/2220] sched: Throttle qos cfs_rq when current cpu is running online task
config: x86_64-randconfig-122-20250513 (https://download.01.org/0day-ci/archive/20250513/202505131239.WbFmKdYn-lkp@…)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250513/202505131239.WbFmKdYn-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505131239.WbFmKdYn-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from kernel/sched/fair.c:27:
In file included from include/linux/mm_api.h:1:
In file included from include/linux/mm.h:2174:
include/linux/vmstat.h:522:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
522 | return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
| ~~~~~~~~~~~ ^ ~~~
>> kernel/sched/fair.c:8325:9: error: call to undeclared function 'sched_idle_cpu'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
8325 | !sched_idle_cpu(smp_processor_id()) &&
| ^
kernel/sched/fair.c:8325:9: note: did you mean 'sched_idle_rq'?
kernel/sched/fair.c:6517:12: note: 'sched_idle_rq' declared here
6517 | static int sched_idle_rq(struct rq *rq)
| ^
>> kernel/sched/fair.c:8328:23: error: no member named 'online' in 'struct rq'
8328 | if (!rq_of(cfs_rq)->online)
| ~~~~~~~~~~~~~ ^
>> kernel/sched/fair.c:8531:7: error: no member named 'idle_stamp' in 'struct rq'; did you mean 'idle_state'?
8531 | rq->idle_stamp = 0;
| ^~~~~~~~~~
| idle_state
kernel/sched/sched.h:1143:24: note: 'idle_state' declared here
1143 | struct cpuidle_state *idle_state;
| ^
1 warning and 3 errors generated.
vim +/sched_idle_cpu +8325 kernel/sched/fair.c
8321
8322 static bool check_qos_cfs_rq(struct cfs_rq *cfs_rq)
8323 {
8324 if (unlikely(cfs_rq && cfs_rq->tg->qos_level < 0 &&
> 8325 !sched_idle_cpu(smp_processor_id()) &&
8326 cfs_rq->h_nr_running == cfs_rq->idle_h_nr_running)) {
8327
> 8328 if (!rq_of(cfs_rq)->online)
8329 return false;
8330
8331 throttle_qos_cfs_rq(cfs_rq);
8332 return true;
8333 }
8334
8335 return false;
8336 }
8337
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-6.6 2220/2220] mm/page_cache_limit.c:35:5: sparse: sparse: symbol 'cache_reclaim_enable_handler' was not declared. Should it be static?
by kernel test robot 13 May '25
by kernel test robot 13 May '25
13 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: e1106320058bf1d983657f80490249b4f919ebad
commit: 621647ce254f1d347ae9bc3d328c09cbb2732487 [2220/2220] mm: support periodical memory reclaim
config: x86_64-randconfig-123-20250513 (https://download.01.org/0day-ci/archive/20250513/202505130948.VRZsdeDC-lkp@…)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250513/202505130948.VRZsdeDC-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505130948.VRZsdeDC-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
>> mm/page_cache_limit.c:35:5: sparse: sparse: symbol 'cache_reclaim_enable_handler' was not declared. Should it be static?
>> mm/page_cache_limit.c:51:5: sparse: sparse: symbol 'cache_reclaim_sysctl_handler' was not declared. Should it be static?
vim +/cache_reclaim_enable_handler +35 mm/page_cache_limit.c
34
> 35 int cache_reclaim_enable_handler(struct ctl_table *table, int write,
36 void *buffer, size_t *length, loff_t *ppos)
37 {
38 int ret;
39
40 ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
41 if (ret || !write)
42 return ret;
43
44 if (should_periodical_reclaim())
45 schedule_delayed_work(&shepherd, round_jiffies_relative(
46 (unsigned long)vm_cache_reclaim_s * HZ));
47
48 return 0;
49 }
50
> 51 int cache_reclaim_sysctl_handler(struct ctl_table *table, int write,
52 void *buffer, size_t *length, loff_t *ppos)
53 {
54 int ret;
55
56 ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
57 if (ret || !write)
58 return ret;
59
60 if (should_periodical_reclaim())
61 mod_delayed_work(system_unbound_wq, &shepherd,
62 round_jiffies_relative(
63 (unsigned long)vm_cache_reclaim_s * HZ));
64
65 return ret;
66 }
67
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[PATCH OLK-6.6] pds_core: handle unsupported PDS_CORE_CMD_FW_CONTROL result
by Yifan Qiao 13 May '25
by Yifan Qiao 13 May '25
13 May '25
From: Brett Creeley <brett.creeley(a)amd.com>
stable inclusion
from stable-v6.6.89
commit cdd784c96fe2e5edbf0ed9b3e96fe776e8092385
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC6LWK
CVE: CVE-2025-37887
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 2567daad69cd1107fc0ec29b1615f110d7cf7385 ]
If the FW doesn't support the PDS_CORE_CMD_FW_CONTROL command
the driver might at the least print garbage and at the worst
crash when the user runs the "devlink dev info" devlink command.
This happens because the stack variable fw_list is not 0
initialized which results in fw_list.num_fw_slots being a
garbage value from the stack. Then the driver tries to access
fw_list.fw_names[i] with i >= ARRAY_SIZE and runs off the end
of the array.
Fix this by initializing the fw_list and by not failing
completely if the devcmd fails because other useful information
is printed via devlink dev info even if the devcmd fails.
Fixes: 45d76f492938 ("pds_core: set up device and adminq")
Signed-off-by: Brett Creeley <brett.creeley(a)amd.com>
Reviewed-by: Simon Horman <horms(a)kernel.org>
Signed-off-by: Shannon Nelson <shannon.nelson(a)amd.com>
Reviewed-by: Jacob Keller <jacob.e.keller(a)intel.com>
Link: https://patch.msgid.link/20250421174606.3892-3-shannon.nelson@amd.com
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Yifan Qiao <qiaoyifan4(a)huawei.com>
---
drivers/net/ethernet/amd/pds_core/devlink.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/amd/pds_core/devlink.c b/drivers/net/ethernet/amd/pds_core/devlink.c
index 971d4278280d..0032e8e35181 100644
--- a/drivers/net/ethernet/amd/pds_core/devlink.c
+++ b/drivers/net/ethernet/amd/pds_core/devlink.c
@@ -101,7 +101,7 @@ int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
.fw_control.opcode = PDS_CORE_CMD_FW_CONTROL,
.fw_control.oper = PDS_CORE_FW_GET_LIST,
};
- struct pds_core_fw_list_info fw_list;
+ struct pds_core_fw_list_info fw_list = {};
struct pdsc *pdsc = devlink_priv(dl);
union pds_core_dev_comp comp;
char buf[32];
@@ -114,8 +114,6 @@ int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
if (!err)
memcpy_fromio(&fw_list, pdsc->cmd_regs->data, sizeof(fw_list));
mutex_unlock(&pdsc->devcmd_lock);
- if (err && err != -EIO)
- return err;
listlen = min(fw_list.num_fw_slots, ARRAY_SIZE(fw_list.fw_names));
for (i = 0; i < listlen; i++) {
--
2.39.2
2
2

[openeuler:OLK-6.6 2220/2220] drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c: mag_mpu_cmd_defs.h is included more than once.
by kernel test robot 13 May '25
by kernel test robot 13 May '25
13 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: e1106320058bf1d983657f80490249b4f919ebad
commit: 0bf0c942a09ba92e1d22e6960464b628dd4408fa [2220/2220] net/hinic3: Synchronize new NIC features and bug fixes
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505130655.7iroL05g-lkp@intel.com/
includecheck warnings: (new ones prefixed by >>)
>> drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c: mag_mpu_cmd_defs.h is included more than once.
vim +21 drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
16
17 #include "ossl_knl.h"
18 #include "hinic3_crm.h"
19 #include "hinic3_hw.h"
20 #include "mag_mpu_cmd.h"
> 21 #include "mag_mpu_cmd_defs.h"
22 #include "hinic3_nic_io.h"
23 #include "hinic3_nic_cfg.h"
24 #include "hinic3_srv_nic.h"
25 #include "hinic3_nic.h"
26 #include "hinic3_common.h"
> 27 #include "mag_mpu_cmd_defs.h"
28
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-6.6] BUILD REGRESSION e1106320058bf1d983657f80490249b4f919ebad
by kernel test robot 13 May '25
by kernel test robot 13 May '25
13 May '25
tree/branch: https://gitee.com/openeuler/kernel.git OLK-6.6
branch HEAD: e1106320058bf1d983657f80490249b4f919ebad !16196 net/hinic3: Synchronize new NIC features and bug fixes
Error/Warning (recently discovered and may have been fixed):
https://lore.kernel.org/oe-kbuild-all/202504240137.L2xvmv1X-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504240638.PM73jDId-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504250828.wJjuSU89-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290703.q8lvsdB3-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290927.uassI0w9-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504291722.ZB4nQmaR-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504300433.T31occlR-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504300733.mAi3Indd-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505080526.qCQgtY7V-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505080910.94UlZrA0-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505100830.TI8oJiuj-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505101047.t5A72bmv-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505111315.WMDsDGlI-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505122110.l7rKvRzx-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505122209.a4CThmkS-lkp@intel.com
arch/loongarch/kernel/paravirt.c:57:(.text+0x1f4): undefined reference to `__ashlti3'
block/blk-io-hierarchy/iodump.c:561:7: warning: no previous prototype for '__bio_stage_hierarchy_start' [-Wmissing-prototypes]
block/blk-io-hierarchy/iodump.c:561:7: warning: no previous prototype for function '__bio_stage_hierarchy_start' [-Wmissing-prototypes]
crypto/asymmetric_keys/pgp_library.c:189: warning: Excess function parameter '_data' description in 'pgp_parse_packets'
crypto/asymmetric_keys/pgp_library.c:189: warning: Excess function parameter '_datalen' description in 'pgp_parse_packets'
crypto/asymmetric_keys/pgp_library.c:189: warning: Function parameter or member 'data' not described in 'pgp_parse_packets'
crypto/asymmetric_keys/pgp_library.c:189: warning: Function parameter or member 'datalen' not described in 'pgp_parse_packets'
drivers/irqchip/irq-gic-v3.c:1517:6: warning: no previous prototype for 'is_gicv4p1' [-Wmissing-prototypes]
drivers/irqchip/irq-gic-v3.c:1517:6: warning: no previous prototype for function 'is_gicv4p1' [-Wmissing-prototypes]
drivers/irqchip/irq-gic-v3.c:1526:6: warning: no previous prototype for 'gic_dist_enable_ipiv' [-Wmissing-prototypes]
drivers/irqchip/irq-gic-v3.c:1526:6: warning: no previous prototype for function 'gic_dist_enable_ipiv' [-Wmissing-prototypes]
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c:445:23: error: invalid application of 'sizeof' to an incomplete type 'const struct free_memory[]'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:862: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/base/trace/sxe_trace.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb_nl.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debug.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:432:6: error: no previous prototype for function 'sxe_debugfs_entries_init' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:459:6: error: no previous prototype for function 'sxe_debugfs_entries_exit' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:465:6: error: no previous prototype for function 'sxe_debugfs_init' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:470:6: error: no previous prototype for function 'sxe_debugfs_exit' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c:2022:5: error: no previous prototype for function 'sxe_reg_test' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c:2644:5: error: no previous prototype for function 'sxe_phys_id_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_filter.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_cli.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_hdc.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:230:6: error: no previous prototype for function 'sxe_hw_no_snoop_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:262:6: error: no previous prototype for function 'sxe_hw_uc_addr_pool_del' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:283:5: error: no previous prototype for function 'sxe_hw_uc_addr_pool_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:337:5: error: no previous prototype for function 'sxe_hw_nic_reset' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:367:6: error: no previous prototype for function 'sxe_hw_pf_rst_done_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:735:5: error: no previous prototype for function 'sxe_hw_pending_irq_read_clear' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:740:6: error: no previous prototype for function 'sxe_hw_pending_irq_write_clear' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:745:5: error: no previous prototype for function 'sxe_hw_irq_cause_get' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:765:6: error: no previous prototype for function 'sxe_hw_ring_irq_auto_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:775:6: error: no previous prototype for function 'sxe_hw_irq_general_reg_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:780:5: error: no previous prototype for function 'sxe_hw_irq_general_reg_get' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:790:6: error: no previous prototype for function 'sxe_hw_event_irq_map' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:806:6: error: no previous prototype for function 'sxe_hw_ring_irq_map' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:823:6: error: no previous prototype for function 'sxe_hw_ring_irq_interval_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:838:6: error: no previous prototype for function 'sxe_hw_event_irq_auto_clear_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:843:6: error: no previous prototype for function 'sxe_hw_specific_irq_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:848:6: error: no previous prototype for function 'sxe_hw_specific_irq_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:876:6: error: no previous prototype for function 'sxe_hw_all_irq_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:994:5: error: no previous prototype for function 'sxe_hw_link_speed_get' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ipsec.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:136:5: error: no previous prototype for function 'sxe_msi_irq_init' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:182:6: error: no previous prototype for function 'sxe_disable_dcb' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:212:6: error: no previous prototype for function 'sxe_disable_rss' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:729:6: error: no previous prototype for function 'sxe_lsc_irq_handler' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:745:6: error: no previous prototype for function 'sxe_mailbox_irq_handler' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c:70:6: error: no previous prototype for function 'sxe_allow_inval_mac' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_monitor.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_phy.c:733:5: error: no previous prototype for function 'sxe_multispeed_sfp_link_configure' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ptp.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ring.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c:1431:6: error: no previous prototype for function 'sxe_headers_cleanup' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c:1569:6: error: no previous prototype for function 'sxe_rx_buffer_page_offset_update' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c:1552:6: error: no previous prototype for function 'sxe_set_vf_link_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c:766:6: error: variable 'ret' set but not used [-Werror,-Wunused-but-set-variable]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_xdp.c:410:6: error: no previous prototype for function 'sxe_txrx_ring_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/base/trace/sxe_trace.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_debug.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ethtool.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:160:6: error: no previous prototype for function 'sxevf_hw_stop' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:187:6: error: no previous prototype for function 'sxevf_msg_write' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:196:5: error: no previous prototype for function 'sxevf_msg_read' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:206:5: error: no previous prototype for function 'sxevf_mailbox_read' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:211:6: error: no previous prototype for function 'sxevf_mailbox_write' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:216:6: error: no previous prototype for function 'sxevf_pf_req_irq_trigger' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:221:6: error: no previous prototype for function 'sxevf_pf_ack_irq_trigger' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:226:6: error: no previous prototype for function 'sxevf_event_irq_map' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:240:6: error: no previous prototype for function 'sxevf_specific_irq_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:245:6: error: no previous prototype for function 'sxevf_irq_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:251:6: error: no previous prototype for function 'sxevf_irq_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:259:6: error: no previous prototype for function 'sxevf_hw_ring_irq_map' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:276:6: error: no previous prototype for function 'sxevf_ring_irq_interval_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:313:6: error: no previous prototype for function 'sxevf_hw_reset' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:324:5: error: no previous prototype for function 'sxevf_link_state_get' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:539:6: error: no previous prototype for function 'sxevf_tx_ring_switch' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:594:6: error: no previous prototype for function 'sxevf_rx_ring_switch' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:626:6: error: no previous prototype for function 'sxevf_rx_ring_desc_configure' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:640:6: error: no previous prototype for function 'sxevf_rx_rcv_ctl_configure' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ipsec.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:543:12: error: unused function 'sxevf_resume' [-Werror,-Wunused-function]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_monitor.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_msg.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ring.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_rx_proc.c:362:6: error: no previous prototype for function 'sxevf_rx_ring_buffers_alloc' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:127:5: error: no previous prototype for function 'sxevf_tx_ring_alloc' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:88:6: error: no previous prototype for function 'sxevf_tx_ring_free' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/yunsilicon/xsc/pci/sriov_sysfs.c:911:31: warning: unused variable 'vf_type_ib' [-Wunused-const-variable]
drivers/net/ethernet/yunsilicon/xsc/pci/xsc_lag.c:1128:21: warning: variable 'bond_dev' set but not used [-Wunused-but-set-variable]
drivers/vhost/vdpa.c:589:14: error: incompatible integer to pointer conversion assigning to 'struct iommufd_ctx *' from 'int' [-Wint-conversion]
drivers/vhost/vdpa.c:589:16: error: call to undeclared function 'iommufd_ctx_from_fd'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
include/linux/fortify-string.h:606:4: error: call to '__read_overflow2_field' declared with 'warning' attribute: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Werror,-Wattribute-warning]
include/linux/sched/signal.h: linux/kabi.h is included more than once.
include/trace/stages/init.h:2:23: warning: 'str__bonding__trace_system_name' defined but not used [-Wunused-const-variable=]
kismet: WARNING: unmet direct dependencies detected for ARM64_ERRATUM_845719 when selected by ARCH_MXC
kismet: WARNING: unmet direct dependencies detected for RESCTRL_FS when selected by ARM64_MPAM
Unverified Error/Warning (likely false positive, kindly check if interested):
drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_sysfs.c: linux/types.h is included more than once.
include/linux/gpio/driver.h: asm/bug.h is included more than once.
include/net/tcp.h: linux/kabi.h is included more than once.
Error/Warning ids grouped by kconfigs:
recent_errors
|-- arm64-alldefconfig
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-gic_dist_enable_ipiv
| `-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-is_gicv4p1
|-- arm64-allmodconfig
| |-- block-blk-io-hierarchy-iodump.c:warning:no-previous-prototype-for-function-__bio_stage_hierarchy_start
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_data-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_datalen-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-data-not-described-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-datalen-not-described-in-pgp_parse_packets
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-gic_dist_enable_ipiv
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-is_gicv4p1
| |-- drivers-net-ethernet-huawei-hinic3-cqm-cqm_bitmap_table.c:error:invalid-application-of-sizeof-to-an-incomplete-type-const-struct-free_memory
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_hwif.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-mucse-rnp-rnp_mbx_fw.c:warning:Cannot-understand-force_free:
| |-- drivers-net-ethernet-yunsilicon-xsc-pci-sriov_sysfs.c:warning:unused-variable-vf_type_ib
| |-- drivers-net-ethernet-yunsilicon-xsc-pci-xsc_lag.c:warning:variable-bond_dev-set-but-not-used
| `-- include-linux-fortify-string.h:error:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()-Werror-Wattribute-warnin
|-- arm64-allnoconfig
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-gic_dist_enable_ipiv
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-is_gicv4p1
| |-- kismet:WARNING:unmet-direct-dependencies-detected-for-ARM64_ERRATUM_845719-when-selected-by-ARCH_MXC
| `-- kismet:WARNING:unmet-direct-dependencies-detected-for-RESCTRL_FS-when-selected-by-ARM64_MPAM
|-- arm64-defconfig
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-gic_dist_enable_ipiv
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-is_gicv4p1
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- arm64-randconfig-002-20250512
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-gic_dist_enable_ipiv
| `-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-is_gicv4p1
|-- arm64-randconfig-003-20250512
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-gic_dist_enable_ipiv
| `-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-is_gicv4p1
|-- arm64-randconfig-004-20250512
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-gic_dist_enable_ipiv
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-is_gicv4p1
| |-- drivers-vhost-vdpa.c:error:call-to-undeclared-function-iommufd_ctx_from_fd-ISO-C99-and-later-do-not-support-implicit-function-declarations
| `-- drivers-vhost-vdpa.c:error:incompatible-integer-to-pointer-conversion-assigning-to-struct-iommufd_ctx-from-int
|-- loongarch-allmodconfig
| |-- block-blk-io-hierarchy-iodump.c:warning:no-previous-prototype-for-__bio_stage_hierarchy_start
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_data-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_datalen-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-data-not-described-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-datalen-not-described-in-pgp_parse_packets
| |-- drivers-net-ethernet-mucse-rnp-rnp_mbx_fw.c:warning:Cannot-understand-force_free:
| `-- include-trace-stages-init.h:warning:str__bonding__trace_system_name-defined-but-not-used
|-- loongarch-allyesconfig
| |-- block-blk-io-hierarchy-iodump.c:warning:no-previous-prototype-for-__bio_stage_hierarchy_start
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_data-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_datalen-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-data-not-described-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-datalen-not-described-in-pgp_parse_packets
| |-- drivers-net-ethernet-mucse-rnp-rnp_mbx_fw.c:warning:Cannot-understand-force_free:
| `-- include-trace-stages-init.h:warning:str__bonding__trace_system_name-defined-but-not-used
|-- loongarch-randconfig-001-20250512
| |-- arch-loongarch-kernel-paravirt.c:(.text):undefined-reference-to-__ashlti3
| |-- arch-loongarch-kernel-ptrace.o:warning:objtool:fpr_set:unreachable-instruction
| |-- arch-loongarch-kernel-vdso.o:warning:objtool:init_vdso:unreachable-instruction
| |-- block-bio.o:warning:objtool:bio_split:unreachable-instruction
| |-- block-blk-merge.o:warning:objtool:__blk_bios_map_sg:unreachable-instruction
| |-- block-blk-merge.o:warning:objtool:__blk_rq_map_sg:unreachable-instruction
| |-- block-blk-throttle.o:warning:objtool:tg_dispatch_one_bio:unreachable-instruction
| |-- block-mq-deadline.o:warning:objtool:__dd_dispatch_request:unreachable-instruction
| |-- crypto-af_alg.o:warning:objtool:af_alg_pull_tsgl:unreachable-instruction
| |-- crypto-af_alg.o:warning:objtool:af_alg_sendmsg:unreachable-instruction
| |-- crypto-async_tx-async_pq.o:warning:objtool:do_sync_gen_syndrome:unreachable-instruction
| |-- crypto-ccm.o:warning:objtool:crypto_ccm_auth:unreachable-instruction
| |-- crypto-ccm.o:warning:objtool:crypto_ccm_init_crypt:unreachable-instruction
| |-- crypto-ccm.o:warning:objtool:crypto_rfc4309_crypt:unreachable-instruction
| |-- crypto-drbg.o:warning:objtool:drbg_kcapi_sym_ctr:unreachable-instruction
| |-- crypto-essiv.o:warning:objtool:essiv_aead_crypt:unreachable-instruction
| |-- crypto-gcm.o:warning:objtool:crypto_gcm_init_common:unreachable-instruction
| |-- crypto-gcm.o:warning:objtool:crypto_rfc4106_crypt:unreachable-instruction
| |-- crypto-testmgr.o:warning:objtool:build_test_sglist:unreachable-instruction
| |-- crypto-testmgr.o:warning:objtool:test_akcipher_one:unreachable-instruction
| |-- drivers-dma-buf-heaps-system_heap.o:warning:objtool:system_heap_allocate:unreachable-instruction
| |-- drivers-dma-buf-heaps-system_heap.o:warning:objtool:system_heap_attach:unreachable-instruction
| |-- drivers-dma-sh-shdma-base.o:warning:objtool:shdma_prep_dma_cyclic:unreachable-instruction
| |-- drivers-dma-sh-shdma-base.o:warning:objtool:shdma_prep_memcpy:unreachable-instruction
| |-- drivers-gpu-drm-amd-amdgpu-amdgpu_ttm.o:warning:objtool:amdgpu_ttm_access_memory:unreachable-instruction
| |-- drivers-gpu-drm-amd-amdgpu-amdgpu_ttm.o:warning:objtool:amdgpu_ttm_copy_mem_to_mem:unreachable-instruction
| |-- drivers-gpu-drm-amd-amdgpu-gfx_v10_0.o:warning:objtool:gfx_v10_0_ring_emit_patch_cond_exec:unreachable-instruction
| |-- drivers-gpu-drm-amd-amdgpu-gfx_v11_0.o:warning:objtool:gfx_v11_0_ring_emit_patch_cond_exec:unreachable-instruction
| |-- drivers-gpu-drm-amd-amdgpu-gfx_v8_0.o:warning:objtool:gfx_v8_0_ring_emit_patch_cond_exec:unreachable-instruction
| |-- drivers-gpu-drm-amd-amdgpu-gfx_v9_0.o:warning:objtool:gfx_v9_0_ring_emit_patch_cond_exec:unreachable-instruction
| |-- drivers-gpu-drm-amd-amdgpu-sdma_v5_0.o:warning:objtool:sdma_v5_0_ring_patch_cond_exec:unreachable-instruction
| |-- drivers-gpu-drm-amd-amdgpu-sdma_v5_2.o:warning:objtool:sdma_v5_2_ring_patch_cond_exec:unreachable-instruction
| |-- drivers-gpu-drm-amd-amdgpu-sdma_v6_0.o:warning:objtool:sdma_v6_0_ring_patch_cond_exec:unreachable-instruction
| |-- drivers-gpu-drm-tests-drm_mm_test.o:warning:objtool:__drm_test_mm_insert:unreachable-instruction
| |-- drivers-gpu-drm-tests-drm_mm_test.o:warning:objtool:__drm_test_mm_insert_range:unreachable-instruction
| |-- drivers-gpu-drm-tests-drm_mm_test.o:warning:objtool:__drm_test_mm_reserve:unreachable-instruction
| |-- drivers-gpu-drm-tests-drm_mm_test.o:warning:objtool:drm_test_mm_bottomup:unreachable-instruction
| |-- drivers-gpu-drm-tests-drm_mm_test.o:warning:objtool:drm_test_mm_topdown:unreachable-instruction
| |-- drivers-md-bcache-btree.o:warning:objtool:do_btree_node_write:unreachable-instruction
| |-- drivers-md-bcache-extents.o:warning:objtool:bch_extent_sort_fixup:unreachable-instruction
| |-- drivers-md-bcache-request.o:warning:objtool:cached_dev_read_done:unreachable-instruction
| |-- drivers-net-ethernet-broadcom-bnxt-bnxt.o:warning:objtool:bnxt_start_xmit:unreachable-instruction
| |-- drivers-net-ethernet-intel-igc-igc_main.o:warning:objtool:igc_construct_skb:unreachable-instruction
| |-- drivers-net-ethernet-intel-igc-igc_main.o:warning:objtool:igc_construct_skb_zc:unreachable-instruction
| |-- drivers-scsi-hpsa.o:warning:objtool:cmd_tagged_alloc:unreachable-instruction
| |-- drivers-scsi-scsi_debug.o:warning:objtool:resp_unmap.isra.:unreachable-instruction
| |-- drivers-scsi-scsi_error.o:warning:objtool:scsi_abort_command:unreachable-instruction
| |-- drivers-tty-serial-fsl_lpuart.o:warning:objtool:lpuart_dma_tx:unreachable-instruction
| |-- drivers-virtio-virtio_ring.o:warning:objtool:virtqueue_add_inbuf:unreachable-instruction
| |-- drivers-virtio-virtio_ring.o:warning:objtool:virtqueue_add_inbuf_ctx:unreachable-instruction
| |-- drivers-virtio-virtio_ring.o:warning:objtool:virtqueue_add_sgs:unreachable-instruction
| |-- fs-btrfs-backref.o:warning:objtool:btrfs_backref_cleanup_node:unreachable-instruction
| |-- fs-btrfs-backref.o:warning:objtool:btrfs_backref_error_cleanup:unreachable-instruction
| |-- fs-btrfs-backref.o:warning:objtool:extent_from_logical:unreachable-instruction
| |-- fs-btrfs-block-group.o:warning:objtool:btrfs_remove_block_group:unreachable-instruction
| |-- fs-btrfs-disk-io.o:warning:objtool:btrfs_destroy_delayed_refs:unreachable-instruction
| |-- fs-btrfs-extent-tree.o:warning:objtool:do_walk_down:unreachable-instruction
| |-- fs-btrfs-extent_io.o:warning:objtool:btree_clear_page_dirty:unreachable-instruction
| |-- fs-btrfs-extent_io.o:warning:objtool:detach_extent_buffer_page:unreachable-instruction
| |-- fs-btrfs-extent_io.o:warning:objtool:end_bio_extent_readpage:unreachable-instruction
| |-- fs-btrfs-extent_io.o:warning:objtool:fiemap_find_last_extent_offset:unreachable-instruction
| |-- fs-btrfs-extent_map.o:warning:objtool:mergable_maps:unreachable-instruction
| |-- fs-btrfs-free-space-cache.o:warning:objtool:btrfs_alloc_from_bitmap:unreachable-instruction
| |-- fs-btrfs-free-space-cache.o:warning:objtool:btrfs_bitmap_set_bits:unreachable-instruction
| |-- fs-btrfs-free-space-cache.o:warning:objtool:btrfs_find_space_for_alloc:unreachable-instruction
| |-- fs-btrfs-free-space-cache.o:warning:objtool:copy_free_space_cache:unreachable-instruction
| |-- fs-btrfs-free-space-cache.o:warning:objtool:remove_from_bitmap:unreachable-instruction
| |-- fs-btrfs-free-space-cache.o:warning:objtool:steal_from_bitmap_to_end:unreachable-instruction
| |-- fs-btrfs-free-space-cache.o:warning:objtool:steal_from_bitmap_to_front:unreachable-instruction
| |-- fs-btrfs-free-space-cache.o:warning:objtool:trim_bitmaps:unreachable-instruction
| |-- fs-btrfs-inode.o:warning:objtool:__btrfs_del_delalloc_inode:unreachable-instruction
| |-- fs-btrfs-lzo.o:warning:objtool:lzo_compress_pages:unreachable-instruction
| |-- fs-btrfs-relocation.o:warning:objtool:__update_reloc_root:unreachable-instruction
| |-- fs-btrfs-relocation.o:warning:objtool:handle_useless_nodes:unreachable-instruction
| |-- fs-btrfs-relocation.o:warning:objtool:insert_dirty_subvol:unreachable-instruction
| |-- fs-btrfs-scrub.o:warning:objtool:find_first_extent_item:unreachable-instruction
| |-- fs-btrfs-subpage.o:warning:objtool:btrfs_page_assert_not_dirty:unreachable-instruction
| |-- fs-btrfs-subpage.o:warning:objtool:btrfs_page_dec_eb_refs:unreachable-instruction
| |-- fs-btrfs-subpage.o:warning:objtool:btrfs_page_unlock_writer:unreachable-instruction
| |-- fs-btrfs-zoned.o:warning:objtool:btrfs_advance_sb_log:unreachable-instruction
| |-- fs-btrfs-zoned.o:warning:objtool:btrfs_reset_sb_log_zones:unreachable-instruction
| |-- fs-btrfs-zoned.o:warning:objtool:btrfs_sb_log_location:unreachable-instruction
| |-- fs-btrfs-zoned.o:warning:objtool:btrfs_sb_log_location_bdev:unreachable-instruction
| |-- fs-buffer.o:warning:objtool:folio_zero_new_buffers:unreachable-instruction
| |-- fs-dcache.o:warning:objtool:d_splice_alias:unreachable-instruction
| |-- fs-ext4-bitmap.o:warning:objtool:ext4_block_bitmap_csum_set:unreachable-instruction
| |-- fs-ext4-bitmap.o:warning:objtool:ext4_block_bitmap_csum_verify:unreachable-instruction
| |-- fs-ext4-bitmap.o:warning:objtool:ext4_inode_bitmap_csum_set:unreachable-instruction
| |-- fs-ext4-extents.o:warning:objtool:ext4_ext_try_to_merge_right:unreachable-instruction
| |-- fs-ext4-extents_status.o:warning:objtool:__es_insert_extent:unreachable-instruction
| |-- fs-ext4-extents_status.o:warning:objtool:ext4_es_lookup_extent:unreachable-instruction
| |-- fs-ext4-fast_commit.o:warning:objtool:ext4_fc_replay_scan:unreachable-instruction
| |-- fs-ext4-fast_commit.o:warning:objtool:ext4_fc_reserve_space:unreachable-instruction
| |-- fs-ext4-fast_commit.o:warning:objtool:ext4_fc_write_tail:unreachable-instruction
| |-- fs-ext4-ialloc.o:warning:objtool:__ext4_new_inode:unreachable-instruction
| |-- fs-ext4-inode.o:warning:objtool:__ext4_block_zero_page_range:unreachable-instruction
| |-- fs-ext4-inode.o:warning:objtool:__ext4_iget:unreachable-instruction
| |-- fs-ext4-inode.o:warning:objtool:ext4_inode_csum:unreachable-instruction
| |-- fs-ext4-ioctl.o:warning:objtool:ext4_reset_inode_seed:unreachable-instruction
| |-- fs-ext4-mballoc.o:warning:objtool:ext4_mb_discard_group_preallocations:unreachable-instruction
| |-- fs-ext4-mballoc.o:warning:objtool:ext4_mb_pa_callback:unreachable-instruction
| |-- fs-ext4-mballoc.o:warning:objtool:ext4_mb_pa_put_free:unreachable-instruction
| |-- fs-ext4-mballoc.o:warning:objtool:ext4_mb_put_pa:unreachable-instruction
| |-- fs-ext4-namei.o:warning:objtool:ext4_dirblock_csum:unreachable-instruction
| |-- fs-ext4-namei.o:warning:objtool:ext4_dx_csum:unreachable-instruction
| |-- fs-ext4-orphan.o:warning:objtool:ext4_orphan_file_block_csum_verify:unreachable-instruction
| |-- fs-ext4-orphan.o:warning:objtool:ext4_orphan_file_block_trigger:unreachable-instruction
| |-- fs-ext4-super.o:warning:objtool:ext4_group_desc_csum:unreachable-instruction
| |-- fs-ext4-super.o:warning:objtool:ext4_init_metadata_csum:unreachable-instruction
| |-- fs-ext4-super.o:warning:objtool:ext4_superblock_csum:unreachable-instruction
| |-- fs-ext4-xattr.o:warning:objtool:ext4_xattr_block_csum:unreachable-instruction
| |-- fs-ext4-xattr.o:warning:objtool:ext4_xattr_inode_hash:unreachable-instruction
| |-- fs-f2fs-checkpoint.o:warning:objtool:f2fs_checkpoint_chksum:unreachable-instruction
| |-- fs-f2fs-data.o:warning:objtool:f2fs_mpage_readpages:unreachable-instruction
| |-- fs-f2fs-inode.o:warning:objtool:f2fs_inode_chksum:unreachable-instruction
| |-- fs-f2fs-super.o:warning:objtool:f2fs_commit_super:unreachable-instruction
| |-- fs-f2fs-super.o:warning:objtool:f2fs_fill_super:unreachable-instruction
| |-- fs-f2fs-super.o:warning:objtool:sanity_check_raw_super:unreachable-instruction
| |-- fs-fscache-cookie.o:warning:objtool:__fscache_relinquish_cookie:unreachable-instruction
| |-- fs-gfs2-bmap.o:warning:objtool:__gfs2_unstuff_inode:unreachable-instruction
| |-- fs-gfs2-dir.o:warning:objtool:dir_make_exhash:unreachable-instruction
| |-- fs-gfs2-glock.o:warning:objtool:find_insert_glock:unreachable-instruction
| |-- fs-gfs2-glock.o:warning:objtool:gfs2_glock_nq:unreachable-instruction
| |-- fs-gfs2-quota.o:warning:objtool:gfs2_quota_init:unreachable-instruction
| |-- fs-gfs2-rgrp.o:warning:objtool:gfs2_adjust_reservation:unreachable-instruction
| |-- fs-gfs2-rgrp.o:warning:objtool:gfs2_alloc_extent:unreachable-instruction
| |-- fs-gfs2-xattr.o:warning:objtool:ea_alloc_blk:unreachable-instruction
| |-- fs-gfs2-xattr.o:warning:objtool:ea_set_block:unreachable-instruction
| |-- fs-jbd2-commit.o:warning:objtool:jbd2_block_tag_csum_set:unreachable-instruction
| |-- fs-jbd2-journal.o:warning:objtool:jbd2_journal_add_journal_head:unreachable-instruction
| |-- fs-jbd2-journal.o:warning:objtool:jbd2_journal_set_features:unreachable-instruction
| |-- fs-jbd2-journal.o:warning:objtool:jbd2_superblock_csum:unreachable-instruction
| |-- fs-jbd2-journal.o:warning:objtool:journal_load_superblock:unreachable-instruction
| |-- fs-jbd2-recovery.o:warning:objtool:jbd2_block_tag_csum_verify:unreachable-instruction
| |-- fs-jbd2-recovery.o:warning:objtool:jbd2_commit_block_csum_verify_partial:unreachable-instruction
| |-- fs-jfs-jfs_metapage.o:warning:objtool:metapage_writepage:unreachable-instruction
| |-- fs-jfs-jfs_metapage.o:warning:objtool:release_metapage:unreachable-instruction
| |-- fs-nilfs2-page.o:warning:objtool:nilfs_clear_dirty_page:unreachable-instruction
| |-- fs-nilfs2-page.o:warning:objtool:nilfs_copy_page:unreachable-instruction
| |-- fs-ntfs3-file.o:warning:objtool:ntfs_zero_range:unreachable-instruction
| |-- fs-seq_file.o:warning:objtool:seq_dentry:unreachable-instruction
| |-- fs-seq_file.o:warning:objtool:seq_escape_mem:unreachable-instruction
| |-- fs-seq_file.o:warning:objtool:seq_hex_dump:unreachable-instruction
| |-- fs-seq_file.o:warning:objtool:seq_path:unreachable-instruction
| |-- fs-seq_file.o:warning:objtool:seq_path_root:unreachable-instruction
| |-- fs-ufs-balloc.o:warning:objtool:ufs_change_blocknr:unreachable-instruction
| |-- fs-userfaultfd.o:warning:objtool:userfaultfd_register:unreachable-instruction
| |-- fs-xfs-xfs_buf.o:warning:objtool:xfs_buf_find_insert:unreachable-instruction
| |-- kernel-cgroup-cgroup.o:warning:objtool:compare_css_sets:unreachable-instruction
| |-- kernel-dma-swiotlb.o:warning:objtool:swiotlb_area_find_slots:unreachable-instruction
| |-- kernel-sched-core.o:warning:objtool:idle_task_exit:unreachable-instruction
| |-- kernel-sched-core.o:warning:objtool:pick_next_task:unreachable-instruction
| |-- lib-maple_tree.o:warning:objtool:mas_alloc_cyclic:unreachable-instruction
| |-- lib-maple_tree.o:warning:objtool:mas_destroy:unreachable-instruction
| |-- lib-maple_tree.o:warning:objtool:mas_erase:unreachable-instruction
| |-- lib-maple_tree.o:warning:objtool:mas_spanning_rebalance:unreachable-instruction
| |-- lib-maple_tree.o:warning:objtool:mas_split:unreachable-instruction
| |-- lib-maple_tree.o:warning:objtool:mas_store:unreachable-instruction
| |-- lib-maple_tree.o:warning:objtool:mas_store_gfp:unreachable-instruction
| |-- lib-maple_tree.o:warning:objtool:mas_store_prealloc:unreachable-instruction
| |-- lib-maple_tree.o:warning:objtool:mas_wr_bnode:unreachable-instruction
| |-- lib-maple_tree.o:warning:objtool:mtree_alloc_range:unreachable-instruction
| |-- lib-maple_tree.o:warning:objtool:mtree_alloc_rrange:unreachable-instruction
| |-- lib-maple_tree.o:warning:objtool:mtree_insert_range:unreachable-instruction
| |-- lib-maple_tree.o:warning:objtool:mtree_store_range:unreachable-instruction
| |-- lib-scatterlist.o:warning:objtool:extract_iter_to_sg:unreachable-instruction
| |-- lib-scatterlist.o:warning:objtool:extract_kvec_to_sg:unreachable-instruction
| |-- lib-scatterlist.o:warning:objtool:extract_user_to_sg:unreachable-instruction
| |-- lib-scatterlist.o:warning:objtool:sg_alloc_append_table_from_pages:unreachable-instruction
| |-- lib-scatterlist.o:warning:objtool:sg_init_one:unreachable-instruction
| |-- lib-scatterlist.o:warning:objtool:sgl_alloc_order:unreachable-instruction
| |-- mm-huge_memory.o:warning:objtool:__split_huge_pmd_locked:unreachable-instruction
| |-- mm-list_lru.o:warning:objtool:__list_lru_walk_one:unreachable-instruction
| |-- mm-mmap.o:warning:objtool:mm_drop_all_locks:unreachable-instruction
| |-- mm-readahead.o:warning:objtool:read_pages:unreachable-instruction
| |-- mm-slub.o:warning:objtool:early_kmem_cache_node_alloc:unreachable-instruction
| |-- mm-truncate.o:warning:objtool:invalidate_inode_pages2_range:unreachable-instruction
| |-- mm-zswap.o:warning:objtool:zswap_store:unreachable-instruction
| |-- mm-zswap.o:warning:objtool:zswap_writeback_entry:unreachable-instruction
| |-- net-atm-resources.o:warning:objtool:atm_dev_deregister:unreachable-instruction
| |-- net-core-dev.o:warning:objtool:__netif_receive_skb_core:unreachable-instruction
| |-- net-core-filter.o:warning:objtool:bpf_msg_pop_data:unreachable-instruction
| |-- net-core-filter.o:warning:objtool:bpf_msg_pull_data:unreachable-instruction
| |-- net-core-filter.o:warning:objtool:bpf_msg_push_data:unreachable-instruction
| |-- net-core-gro.o:warning:objtool:napi_reuse_skb:unreachable-instruction
| |-- net-core-rtnetlink.o:warning:objtool:rtnl_unregister:unreachable-instruction
| |-- net-core-skbuff.o:warning:objtool:skb_pull_rcsum:unreachable-instruction
| |-- net-netlink-af_netlink.o:warning:objtool:__netlink_insert:unreachable-instruction
| |-- net-sched-cls_flower.o:warning:objtool:fl_check_assign_mask:unreachable-instruction
| |-- net-sched-cls_flower.o:warning:objtool:fl_ht_insert_unique:unreachable-instruction
| `-- net-wireless-mlme.o:warning:objtool:cfg80211_rx_assoc_resp:unreachable-instruction
|-- x86_64-allnoconfig
| |-- drivers-net-ethernet-yunsilicon-xsc-net-xsc_eth_sysfs.c:linux-types.h-is-included-more-than-once.
| |-- include-linux-gpio-driver.h:asm-bug.h-is-included-more-than-once.
| |-- include-linux-sched-signal.h:linux-kabi.h-is-included-more-than-once.
| `-- include-net-tcp.h:linux-kabi.h-is-included-more-than-once.
|-- x86_64-allyesconfig
| |-- block-blk-io-hierarchy-iodump.c:warning:no-previous-prototype-for-function-__bio_stage_hierarchy_start
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_data-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_datalen-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-data-not-described-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-datalen-not-described-in-pgp_parse_packets
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-mucse-rnp-rnp_mbx_fw.c:warning:Cannot-understand-force_free:
| |-- drivers-net-ethernet-yunsilicon-xsc-pci-sriov_sysfs.c:warning:unused-variable-vf_type_ib
| |-- drivers-net-ethernet-yunsilicon-xsc-pci-xsc_lag.c:warning:variable-bond_dev-set-but-not-used
| `-- include-linux-fortify-string.h:error:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()-Werror-Wattribute-warnin
|-- x86_64-buildonly-randconfig-003-20250512
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- x86_64-defconfig
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- x86_64-randconfig-101-20250512
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-vhost-vdpa.c:error:call-to-undeclared-function-iommufd_ctx_from_fd-ISO-C99-and-later-do-not-support-implicit-function-declarations
| |-- drivers-vhost-vdpa.c:error:incompatible-integer-to-pointer-conversion-assigning-to-struct-iommufd_ctx-from-int
| `-- include-linux-fortify-string.h:error:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()-Werror-Wattribute-warnin
|-- x86_64-randconfig-102-20250512
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- x86_64-randconfig-103-20250512
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- x86_64-randconfig-104-20250512
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- x86_64-randconfig-161-20250512
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:error:unused-function-sxevf_resume-Werror-Wunused-function
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| `-- include-linux-fortify-string.h:error:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()-Werror-Wattribute-warnin
|-- x86_64-randconfig-r051-20250512
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| `-- include-linux-fortify-string.h:error:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()-Werror-Wattribute-warnin
`-- x86_64-rhel-9.4-rust
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
`-- include-linux-fortify-string.h:error:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()-Werror-Wattribute-warnin
elapsed time: 729m
configs tested: 23
configs skipped: 122
tested configs:
arm64 alldefconfig gcc-14.2.0
arm64 allmodconfig clang-19
arm64 allnoconfig gcc-14.2.0
arm64 defconfig gcc-14.2.0
arm64 randconfig-001-20250512 gcc-7.5.0
arm64 randconfig-002-20250512 clang-21
arm64 randconfig-003-20250512 clang-21
arm64 randconfig-004-20250512 clang-21
loongarch allmodconfig gcc-14.2.0
loongarch allnoconfig gcc-14.2.0
loongarch defconfig gcc-14.2.0
loongarch randconfig-001-20250512 gcc-13.3.0
loongarch randconfig-002-20250512 gcc-13.3.0
x86_64 allnoconfig clang-20
x86_64 allyesconfig clang-20
x86_64 buildonly-randconfig-001-20250512 gcc-12
x86_64 buildonly-randconfig-002-20250512 gcc-12
x86_64 buildonly-randconfig-003-20250512 clang-20
x86_64 buildonly-randconfig-004-20250512 clang-20
x86_64 buildonly-randconfig-005-20250512 clang-20
x86_64 buildonly-randconfig-006-20250512 clang-20
x86_64 defconfig gcc-11
x86_64 rhel-9.4-rust clang-18
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0
Support fuse fastpath by using the newly added fast_ipc module.
Alessio Balsini (2):
fuse: 32-bit user space ioctl compat for fuse device
fuse: fix matching of FUSE_DEV_IOC_CLONE command
chenrenhui (2):
ipc: add fast_ipc module to enable fast process switching
fuse: support fastpath via fast_ipc
yangyun (1):
fuse: add fast path for fuse_range_is_writeback
Kconfig | 2 +
arch/arm64/configs/openeuler_defconfig | 2 +
fs/fuse/Kconfig | 9 +
fs/fuse/dev.c | 769 ++++++++++++++++++++++++-
fs/fuse/dir.c | 87 ++-
fs/fuse/file.c | 241 +++++++-
fs/fuse/fuse_i.h | 55 ++
fs/fuse/inode.c | 112 ++++
fs/fuse/readdir.c | 8 +
include/linux/fast_ipc.h | 48 ++
include/uapi/linux/fuse.h | 15 +-
ipc/Kconfig | 6 +
ipc/Makefile | 2 +-
ipc/fast_ipc.c | 299 ++++++++++
14 files changed, 1613 insertions(+), 42 deletions(-)
create mode 100644 include/linux/fast_ipc.h
create mode 100644 ipc/Kconfig
create mode 100644 ipc/fast_ipc.c
--
2.33.0
2
6
Support fuse fastpath by using the newly added fast_ipc module.
Alessio Balsini (2):
fuse: 32-bit user space ioctl compat for fuse device
fuse: fix matching of FUSE_DEV_IOC_CLONE command
chenrenhui (2):
ipc: add fast_ipc module to enable fast process switching
fuse: support fastpath via fast_ipc
yangyun (1):
fuse: add fast path for fuse_range_is_writeback
Kconfig | 2 +
arch/arm64/configs/openeuler_defconfig | 2 +
fs/fuse/Kconfig | 9 +
fs/fuse/dev.c | 769 ++++++++++++++++++++++++-
fs/fuse/dir.c | 87 ++-
fs/fuse/file.c | 241 +++++++-
fs/fuse/fuse_i.h | 55 ++
fs/fuse/inode.c | 112 ++++
fs/fuse/readdir.c | 8 +
include/linux/fast_ipc.h | 48 ++
include/uapi/linux/fuse.h | 15 +-
ipc/Kconfig | 6 +
ipc/Makefile | 2 +-
ipc/fast_ipc.c | 299 ++++++++++
14 files changed, 1613 insertions(+), 42 deletions(-)
create mode 100644 include/linux/fast_ipc.h
create mode 100644 ipc/Kconfig
create mode 100644 ipc/fast_ipc.c
--
2.33.0
2
7
From: Fedor Pchelkin <pchelkin(a)ispras.ru>
stable inclusion
from stable-6.6.90
commit 121e9f80ea5478bca3a8f3f26593fd66f87da649
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC6BLK
CVE: CVE-2025-37811
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 4e28f79e3dffa52d327b46d1a78dac16efb5810b upstream.
usbmisc is an optional device property so it is totally valid for the
corresponding data->usbmisc_data to have a NULL value.
Check that before dereferencing the pointer.
Found by Linux Verification Center (linuxtesting.org) with Svace static
analysis tool.
Fixes: 74adad500346 ("usb: chipidea: ci_hdrc_imx: decrement device's refcount in .remove() and in the error path of .probe()")
Cc: stable <stable(a)kernel.org>
Signed-off-by: Fedor Pchelkin <pchelkin(a)ispras.ru>
Acked-by: Peter Chen <peter.chen(a)kernel.org>
Link: https://lore.kernel.org/r/20250316102658.490340-2-pchelkin@ispras.ru
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Tengda Wu <wutengda2(a)huawei.com>
---
drivers/usb/chipidea/ci_hdrc_imx.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index b3cbca361a96..1a050bdf7bdb 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -520,7 +520,8 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
cpu_latency_qos_remove_request(&data->pm_qos_req);
data->ci_pdev = NULL;
err_put:
- put_device(data->usbmisc_data->dev);
+ if (data->usbmisc_data)
+ put_device(data->usbmisc_data->dev);
return ret;
}
@@ -544,7 +545,8 @@ static void ci_hdrc_imx_remove(struct platform_device *pdev)
if (data->hsic_pad_regulator)
regulator_disable(data->hsic_pad_regulator);
}
- put_device(data->usbmisc_data->dev);
+ if (data->usbmisc_data)
+ put_device(data->usbmisc_data->dev);
}
static void ci_hdrc_imx_shutdown(struct platform_device *pdev)
--
2.34.1
2
1

[openeuler:OLK-6.6 2220/2220] arch/loongarch/kernel/paravirt.c:57:undefined reference to `__ashlti3'
by kernel test robot 12 May '25
by kernel test robot 12 May '25
12 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: e1106320058bf1d983657f80490249b4f919ebad
commit: 462dd429f52a7659ea1c74f02f7134a43fccccc8 [2220/2220] LoongArch: Add pv ipi support on guest kernel side
config: loongarch-randconfig-001-20250512 (https://download.01.org/0day-ci/archive/20250512/202505122209.a4CThmkS-lkp@…)
compiler: loongarch64-linux-gcc (GCC) 13.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250512/202505122209.a4CThmkS-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505122209.a4CThmkS-lkp@intel.com/
All errors (new ones prefixed by >>):
loongarch64-linux-ld: arch/loongarch/kernel/paravirt.o: in function `pv_send_ipi_mask':
>> arch/loongarch/kernel/paravirt.c:57:(.text+0x1f4): undefined reference to `__ashlti3'
vim +57 arch/loongarch/kernel/paravirt.c
33
34 #define KVM_IPI_CLUSTER_SIZE (2 * BITS_PER_LONG)
35 static void pv_send_ipi_mask(const struct cpumask *mask, unsigned int action)
36 {
37 unsigned int cpu, i, min = 0, max = 0, old;
38 __uint128_t bitmap = 0;
39 irq_cpustat_t *info;
40
41 if (cpumask_empty(mask))
42 return;
43
44 action = BIT(action);
45 for_each_cpu(i, mask) {
46 info = &per_cpu(irq_stat, i);
47 old = atomic_fetch_or(action, &info->message);
48 if (old)
49 continue;
50
51 cpu = cpu_logical_map(i);
52 if (!bitmap) {
53 min = max = cpu;
54 } else if (cpu > min && cpu < min + KVM_IPI_CLUSTER_SIZE) {
55 max = cpu > max ? cpu : max;
56 } else if (cpu < min && (max - cpu) < KVM_IPI_CLUSTER_SIZE) {
> 57 bitmap <<= min - cpu;
58 min = cpu;
59 } else {
60 /*
61 * Physical cpuid is sorted in ascending order ascend
62 * for the next mask calculation, send IPI here
63 * directly and skip the remainding cpus
64 */
65 kvm_hypercall3(KVM_HCALL_FUNC_PV_IPI,
66 (unsigned long)bitmap,
67 (unsigned long)(bitmap >> BITS_PER_LONG), min);
68 min = max = cpu;
69 bitmap = 0;
70 }
71 __set_bit(cpu - min, (unsigned long *)&bitmap);
72 }
73
74 if (bitmap)
75 kvm_hypercall3(KVM_HCALL_FUNC_PV_IPI, (unsigned long)bitmap,
76 (unsigned long)(bitmap >> BITS_PER_LONG), min);
77 }
78
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-6.6 2220/2220] drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c:445:23: error: invalid application of 'sizeof' to an incomplete type 'const struct free_memory[]'
by kernel test robot 12 May '25
by kernel test robot 12 May '25
12 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: e1106320058bf1d983657f80490249b4f919ebad
commit: 0bf0c942a09ba92e1d22e6960464b628dd4408fa [2220/2220] net/hinic3: Synchronize new NIC features and bug fixes
config: arm64-allmodconfig (https://download.01.org/0day-ci/archive/20250512/202505122110.l7rKvRzx-lkp@…)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250512/202505122110.l7rKvRzx-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505122110.l7rKvRzx-lkp@intel.com/
All error/warnings (new ones prefixed by >>):
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:312: warning: Function parameter or member 'attr6' not described in 'set_hwif_attr'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:774: warning: Function parameter or member 'hwdev' not described in 'hinic3_init_hwif'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:774: warning: Function parameter or member 'cfg_reg_base' not described in 'hinic3_init_hwif'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:774: warning: Function parameter or member 'intr_reg_base' not described in 'hinic3_init_hwif'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:774: warning: Function parameter or member 'mgmt_regs_base' not described in 'hinic3_init_hwif'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:774: warning: Function parameter or member 'db_base_phy' not described in 'hinic3_init_hwif'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:774: warning: Function parameter or member 'db_base' not described in 'hinic3_init_hwif'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:774: warning: Function parameter or member 'db_dwqe_len' not described in 'hinic3_init_hwif'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:774: warning: Excess function parameter 'hwif' description in 'hinic3_init_hwif'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:774: warning: Excess function parameter 'pdev' description in 'hinic3_init_hwif'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:840: warning: Function parameter or member 'hwdev' not described in 'hinic3_free_hwif'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:840: warning: Excess function parameter 'hwif' description in 'hinic3_free_hwif'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:840: warning: Excess function parameter 'pdev' description in 'hinic3_free_hwif'
>> drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:862: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
* get function id from register,used by sriov hot migration process
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:878: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
* get function id, used by sriov hot migratition process.
--
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c:415:3: error: a randomized struct can only be initialized with a designated initializer
415 | {check_use_vram, cqm_buf_vram_kalloc},
| ^
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c:416:3: error: a randomized struct can only be initialized with a designated initializer
416 | {check_for_use_node_alloc, cqm_buf_use_node_alloc_page},
| ^
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c:417:3: error: a randomized struct can only be initialized with a designated initializer
417 | {check_for_nouse_node_alloc, cqm_buf_unused_node_alloc_page}
| ^
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c:421:3: error: a randomized struct can only be initialized with a designated initializer
421 | {check_use_vram, cqm_buf_vram_free},
| ^
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c:422:3: error: a randomized struct can only be initialized with a designated initializer
422 | {check_use_non_vram, cqm_buf_free_page_common}
| ^
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c:428:25: error: invalid application of 'sizeof' to an incomplete type 'const struct malloc_memory[]'
428 | u32 malloc_funcs_num = ARRAY_SIZE(g_malloc_funcs);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:57:32: note: expanded from macro 'ARRAY_SIZE'
57 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
| ^~~~~
>> drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c:445:23: error: invalid application of 'sizeof' to an incomplete type 'const struct free_memory[]'
445 | u32 free_funcs_num = ARRAY_SIZE(g_free_funcs);
| ^~~~~~~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:57:32: note: expanded from macro 'ARRAY_SIZE'
57 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
| ^~~~~
7 errors generated.
vim +445 drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
419
420 static const struct free_memory g_free_funcs[] = {
421 {check_use_vram, cqm_buf_vram_free},
> 422 {check_use_non_vram, cqm_buf_free_page_common}
423 };
424
425 static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *buf)
426 {
427 struct hinic3_hwdev *handle = cqm_handle->ex_handle;
428 u32 malloc_funcs_num = ARRAY_SIZE(g_malloc_funcs);
429 u32 i;
430
431 for (i = 0; i < malloc_funcs_num; i++) {
432 if (g_malloc_funcs[i].check_alloc_mode &&
433 g_malloc_funcs[i].malloc_func &&
434 g_malloc_funcs[i].check_alloc_mode(handle, buf))
435 return g_malloc_funcs[i].malloc_func(handle, buf);
436 }
437
438 cqm_err(handle->dev_hdl, "Unknown alloc mode\n");
439
440 return CQM_FAIL;
441 }
442
443 static void cqm_buf_free_page(struct tag_cqm_buf *buf)
444 {
> 445 u32 free_funcs_num = ARRAY_SIZE(g_free_funcs);
446 u32 i;
447
448 for (i = 0; i < free_funcs_num; i++) {
449 if (g_free_funcs[i].check_alloc_mode &&
450 g_free_funcs[i].free_func &&
451 g_free_funcs[i].check_alloc_mode(NULL, buf))
452 return g_free_funcs[i].free_func(buf);
453 }
454 }
455
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0
CVE-2024-27079
Lu Baolu (2):
iommu: Add static iommu_ops->release_domain
iommu/vt-d: Fix NULL domain on device release
drivers/iommu/intel/iommu.c | 31 ++++--------------
drivers/iommu/intel/pasid.c | 64 +++++++++++++++++++++++++++++++++++++
drivers/iommu/intel/pasid.h | 1 +
drivers/iommu/iommu.c | 19 ++++++++---
include/linux/iommu.h | 2 +-
5 files changed, 87 insertions(+), 30 deletions(-)
--
2.22.0
2
3

[PATCH OLK-6.6] LoongArch: Return NULL from huge_pte_offset() for invalid PMD
by Xiaomeng Zhang 12 May '25
by Xiaomeng Zhang 12 May '25
12 May '25
From: Ming Wang <wangming01(a)loongson.cn>
stable inclusion
from stable-v6.6.89
commit 2ca9380b12711afe95b3589bd82b59623b3c96b3
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC6BTY
CVE: CVE-2025-37818
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit bd51834d1cf65a2c801295d230c220aeebf87a73 upstream.
LoongArch's huge_pte_offset() currently returns a pointer to a PMD slot
even if the underlying entry points to invalid_pte_table (indicating no
mapping). Callers like smaps_hugetlb_range() fetch this invalid entry
value (the address of invalid_pte_table) via this pointer.
The generic is_swap_pte() check then incorrectly identifies this address
as a swap entry on LoongArch, because it satisfies the "!pte_present()
&& !pte_none()" conditions. This misinterpretation, combined with a
coincidental match by is_migration_entry() on the address bits, leads to
kernel crashes in pfn_swap_entry_to_page().
Fix this at the architecture level by modifying huge_pte_offset() to
check the PMD entry's content using pmd_none() before returning. If the
entry is invalid (i.e., it points to invalid_pte_table), return NULL
instead of the pointer to the slot.
Cc: stable(a)vger.kernel.org
Acked-by: Peter Xu <peterx(a)redhat.com>
Co-developed-by: Hongchen Zhang <zhanghongchen(a)loongson.cn>
Signed-off-by: Hongchen Zhang <zhanghongchen(a)loongson.cn>
Signed-off-by: Ming Wang <wangming01(a)loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai(a)loongson.cn>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Conflicts:
arch/loongarch/mm/hugetlbpage.c
[The conflicts were due to some minor issue.]
Signed-off-by: Xiaomeng Zhang <zhangxiaomeng13(a)huawei.com>
---
arch/loongarch/mm/hugetlbpage.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/loongarch/mm/hugetlbpage.c b/arch/loongarch/mm/hugetlbpage.c
index 62ddcea0aa14..aca52c42e94e 100644
--- a/arch/loongarch/mm/hugetlbpage.c
+++ b/arch/loongarch/mm/hugetlbpage.c
@@ -47,7 +47,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr,
pmd = pmd_offset(pud, addr);
}
}
- return (pte_t *) pmd;
+ return pmd_none(pmdp_get(pmd)) ? NULL : (pte_t *) pmd;
}
int pmd_huge(pmd_t pmd)
--
2.34.1
2
1
感谢反馈,
On 2025/5/9 18:02, Funda Wang wrote:
> 建议明确“2026 年 LTS 版本”意味着什么,因为这还涉及到 26.03 LTS 生命周期(约四年)内后续 SP 版本的内核版本序列。字面上的歧义尽可能避免。
>
2026 年 LTS 版本,就是说2026年新发的 LTS 版本,不管是不是叫 26.03,都是选择 6.6 版本。因为选型是内核先选型,
26.03 的计划还没有出来,所以,为了避免歧义,这里笼统的说 2026 年 LTS 版本。
生命周期的问题:6.6 内核会支持 26 年发的 LTS 整个生命周期。至于后续的SP是否有多版本的内核,这是另外一个问题,
为了公示邮件简单明确,这里没有把其他事情混在一起讲。
>
> 在 2025-05-09 16:52:25,"Xie XiuQi" <xiexiuqi(a)huawei.com> 写道:
>>各位开发者和用户,
>>
>> 经2025年5月9日 openEuler Kernel SIG 会议讨论,拟定继续使用 6.6 内核支撑 openEuler 2026 年 LTS 版本发布,
>>特此公示。
>> 公示时间:2025-5-9 18:00 - 2025-5-23 18:00, 公示14天。
>> 公示期间,如果您有任何意见,请邮件反馈至:xiexiuqi@huawei.com,jason.zeng@intel.com,sanglipeng1@jd.com.
>>如需反馈意见,请说明您所在的团队,您的联系方式,并详细描述原因。您的反馈意见可能会在社区会议中公开讨论,请
>>不要包含保密信息。
>>
>> openEuler Kernel SIG
>> 2025年5月9日
>>_______________________________________________
>>Dev mailing list -- dev(a)openeuler.org
>>To unsubscribe send an email to dev-leave(a)openeuler.org
>
1
0
Support arm64 xcall prefetch.
Changes in v2:
- Remove is_read_cache.
- Simplify the ksys_read().
- Use percpu cache_hit/miss_wait and remove cache_queued and sync_mode.
- Remove keep_running in prefetch_item struct.
- Add /proc/xcall/stats dir.
- Remove pfi in file struct and use hash table.
Jinjie Ruan (3):
arm64: Introduce Xint software solution
arm64: Add debugfs dir for xint
xcall: Add /proc/xcall/stats dir for performance tuning
Liao Chen (1):
revert kpti bypass
Yipeng Zou (5):
arm64: Introduce xcall a faster svc exception handling
arm64: Faster SVC exception handler with xcall
xcall: introduce xcall_select to implement a custom xcall function
eventpoll: xcall: Support sync and async prefetch data in epoll
xcall: eventpoll: add tracepoint
arch/Kconfig | 64 +++++++
arch/arm64/Kconfig | 2 +
arch/arm64/configs/openeuler_defconfig | 4 +
arch/arm64/include/asm/cpucaps.h | 2 +
arch/arm64/include/asm/exception.h | 6 +
arch/arm64/include/asm/syscall.h | 14 ++
arch/arm64/include/asm/syscall_wrapper.h | 25 +++
arch/arm64/kernel/asm-offsets.c | 3 +
arch/arm64/kernel/cpufeature.c | 54 ++++++
arch/arm64/kernel/entry-common.c | 22 +++
arch/arm64/kernel/entry.S | 183 +++++++++++++++++-
arch/arm64/kernel/sys.c | 20 ++
arch/arm64/kernel/syscall.c | 69 +++++++
drivers/irqchip/irq-gic-v3.c | 123 ++++++++++++
fs/eventpoll.c | 232 +++++++++++++++++++++++
fs/open.c | 4 +
fs/proc/base.c | 214 +++++++++++++++++++++
fs/read_write.c | 95 +++++++++-
include/linux/fs.h | 31 +++
include/linux/hardirq.h | 5 +
include/linux/irqchip/arm-gic-v3.h | 13 ++
include/linux/sched.h | 5 +
include/linux/syscalls.h | 19 ++
include/trace/events/fs.h | 91 +++++++++
include/uapi/asm-generic/unistd.h | 11 ++
kernel/fork.c | 32 ++++
kernel/irq/debugfs.c | 33 ++++
kernel/irq/internals.h | 18 ++
kernel/irq/irqdesc.c | 19 ++
kernel/irq/proc.c | 10 +
kernel/softirq.c | 73 +++++++
kernel/sysctl.c | 36 ++++
32 files changed, 1529 insertions(+), 3 deletions(-)
--
2.34.1
2
10

[PATCH OLK-6.6] kvm: x86: fix infinite loop in kvm_guest_time_update when tsc is 0
by Yuntao Liu 12 May '25
by Yuntao Liu 12 May '25
12 May '25
Offering: HULK
hulk inclusion
category: bugfix
bugzilla: 190614
--------------------------------
Syzkaller testing detected a soft lockup.
watchdog: BUG: soft lockup - CPU#3 stuck for 127s! [syz.1.2088:9817]
Modules linked in:
CPU: 3 PID: 9817 Comm: syz.1.2088 Tainted: G S 6.6.0+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
RIP: 0010:__sanitizer_cov_trace_const_cmp4+0x8/0x20 kernel/kcov.c:313
Code: bf 03 00 00 00 e9 48 fe ff ff 0f 1f 84 00 00 00 00 00 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 48 8b 0c 24 <89> f2 89
fe bf 05 00 00 00 e9 1a fe ff ff 66 2e 0f 1f 84 00 00 00
RSP: 0018:ffff888016d8fad8 EFLAGS: 00000206
RAX: 0000000000080000 RBX: ffff88810e242540 RCX: ffffffff901150d6
RDX: 0000000000080000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffff888016d8fb50 R08: 0000000000000001 R09: ffffed1021c484af
R10: 0000000000000000 R11: 0000000000000277 R12: 0000000000000000
R13: fffffed357281918 R14: 0000000000000000 R15: 0000000000000001
FS: 00007f2a8f6ea6c0(0000) GS:ffff888119780000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000012c56c0 CR3: 000000000dce8001 CR4: 0000000000772ee0
DR0: 0000000000000000 DR1: 0000000000d3eb1c DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
PKRU: 80000000
Call Trace:
<TASK>
kvm_get_time_scale arch/x86/kvm/x86.c:2458 [inline]
kvm_guest_time_update+0x926/0xb00 arch/x86/kvm/x86.c:3268
vcpu_enter_guest.constprop.0+0x1e70/0x3cf0 arch/x86/kvm/x86.c:10678
vcpu_run+0x129/0x8d0 arch/x86/kvm/x86.c:11126
kvm_arch_vcpu_ioctl_run+0x37a/0x13d0 arch/x86/kvm/x86.c:11352
kvm_vcpu_ioctl+0x56b/0xe60 virt/kvm/kvm_main.c:4188
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:871 [inline]
__se_sys_ioctl+0x12d/0x190 fs/ioctl.c:857
do_syscall_x64 arch/x86/entry/common.c:51 [inline]
do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81
entry_SYSCALL_64_after_hwframe+0x78/0xe2
test case:
18.689865147s ago: executing program 1 (id=2088):
r0 = openat$kvm(0xffffffffffffff9c, &(0x7f0000002080), 0x0, 0x0)
r1 = ioctl$KVM_CREATE_VM(r0, 0xae01, 0x0)
r2 = ioctl$KVM_CREATE_VCPU(r1, 0xae41, 0x0)
ioctl$KVM_RUN(r2, 0xae80, 0x0)
ioctl$KVM_SET_TSC_KHZ(r2, 0xaea2, 0x1)
socket$nl_route(0x10, 0x3, 0x0)
r3 = socket$igmp(0x2, 0x3, 0x2)
ioctl$sock_SIOCGIFINDEX(r3, 0x8933, &(0x7f00000001c0)={'netdevsim0\x00',
<r4=>0x0})
r5 = bpf$MAP_CREATE(0x0, &(0x7f0000000140)=@base={0x1, 0x4, 0x8000, 0x2,
0x0, 0xffffffffffffffff, 0x0, '\x00', r4, 0xffffffffffffffff, 0x0, 0x0,
0x0, 0x0, @void, @value, @void, @value}, 0x50)
bpf$MAP_UPDATE_CONST_STR(0x2, &(0x7f0000000100)={{r5},
&(0x7f0000000000), &(0x7f0000000040)='%ps \x00'}, 0x20)
bpf$MAP_DELETE_ELEM(0x3, &(0x7f00000000c0)={r5, &(0x7f0000001480)},
0x20)
ioctl$KVM_SET_USER_MEMORY_REGION(r1, 0x4020ae46,
&(0x7f0000000000)={0x1ff, 0x3, 0x3000, 0x1000,
&(0x7f0000fec000/0x1000)=nil})
syz_kvm_setup_cpu$x86(r1, 0xffffffffffffffff,
&(0x7f0000fe8000/0x18000)=nil, &(0x7f0000000100)=[@textreal={0x8, 0x0}],
0x1, 0x0, 0x0, 0x0)
ioctl$KVM_SET_USER_MEMORY_REGION(0xffffffffffffffff, 0x4020ae46, 0x0)
openat$ipvs(0xffffffffffffff9c, 0x0, 0x2, 0x0)
syz_kvm_setup_cpu$x86(0xffffffffffffffff, r2,
&(0x7f0000fe8000/0x18000)=nil, &(0x7f00000000c0)=[@text64={0x40,
&(0x7f0000000040)="26f2a70f3548b807000000000000000f23c00f21f835020008000f23f80fc73eb9330800000f326666470f3880be6cc468550f01cf360f01f80f30450f01c9",
0x3f}], 0x1, 0x0, 0x0, 0x0)
ioctl$KVM_RUN(r2, 0xae80, 0x0)
ioctl$KVM_SET_TSC_KHZ(r2, 0xaea2, 0x1)
user_tsc_khz = 0x1
|
kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz)
|
ioctl$KVM_RUN(r2, 0xae80, 0x0)
|
...
kvm_guest_time_update(struct kvm_vcpu *v)
|
if (kvm_caps.has_tsc_control)
tgt_tsc_khz = kvm_scale_tsc(tgt_tsc_khz,
v->arch.l1_tsc_scaling_ratio);
|
kvm_scale_tsc(u64 tsc, u64 ratio)
|
__scale_tsc(u64 ratio, u64 tsc)
ratio=122380531, tsc=2299998, N=48
ratio*tsc >> N = 0.999... -> 0
|
kvm_get_time_scale
In function __scale_tsc, it uses fixed point number to calculate
tsc, therefore, a certain degree of precision is lost, the actual tsc
value of 0.999... would be 0. In function kvm_get_time_scale
tps32=tps64=base_hz=0, would lead second while_loop infinite. when
CONFIG_PREEMPT is n, it causes a soft lockup issue.
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
arch/x86/kvm/x86.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1fa5d89f8d27..92460a69ff0f 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2605,10 +2605,12 @@ static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
* point number (mult + frac * 2^(-N)).
*
* N equals to kvm_caps.tsc_scaling_ratio_frac_bits.
+ *
+ * add 1 to compensate for precision loss.
*/
static inline u64 __scale_tsc(u64 ratio, u64 tsc)
{
- return mul_u64_u64_shr(tsc, ratio, kvm_caps.tsc_scaling_ratio_frac_bits);
+ return mul_u64_u64_shr(tsc, ratio, kvm_caps.tsc_scaling_ratio_frac_bits) + 1;
}
u64 kvm_scale_tsc(u64 tsc, u64 ratio)
--
2.34.1
2
1
Support fuse fastpath by using the newly added fast_ipc module.
Alessio Balsini (1):
fuse: 32-bit user space ioctl compat for fuse device
chenrenhui (2):
ipc: add fast_ipc module to enable fast process switching
fuse: support fastpath via fast_ipc
yangyun (1):
fuse: add fast path for fuse_range_is_writeback
Kconfig | 2 +
arch/arm64/configs/openeuler_defconfig | 2 +
fs/fuse/Kconfig | 9 +
fs/fuse/dev.c | 770 ++++++++++++++++++++++++-
fs/fuse/dir.c | 87 ++-
fs/fuse/file.c | 241 +++++++-
fs/fuse/fuse_i.h | 55 ++
fs/fuse/inode.c | 112 ++++
fs/fuse/readdir.c | 8 +
include/linux/fast_ipc.h | 48 ++
include/uapi/linux/fuse.h | 15 +-
ipc/Kconfig | 6 +
ipc/Makefile | 2 +-
ipc/fast_ipc.c | 299 ++++++++++
14 files changed, 1615 insertions(+), 41 deletions(-)
create mode 100644 include/linux/fast_ipc.h
create mode 100644 ipc/Kconfig
create mode 100644 ipc/fast_ipc.c
--
2.33.0
2
5

[PATCH OLK-5.10] [Backport] backlight: led_bl: Hold led_access lock when calling led_sysfs_disable()
by Yuntao Liu 12 May '25
by Yuntao Liu 12 May '25
12 May '25
From: Herve Codina <herve.codina(a)bootlin.com>
stable inclusion
from stable-v5.10.237
commit 87d947a0607be384bfe7bb0935884a711e35ca07
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC5BJZ
CVE: CVE-2025-23144
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 276822a00db3c1061382b41e72cafc09d6a0ec30 ]
Lockdep detects the following issue on led-backlight removal:
[ 142.315935] ------------[ cut here ]------------
[ 142.315954] WARNING: CPU: 2 PID: 292 at drivers/leds/led-core.c:455 led_sysfs_enable+0x54/0x80
...
[ 142.500725] Call trace:
[ 142.503176] led_sysfs_enable+0x54/0x80 (P)
[ 142.507370] led_bl_remove+0x80/0xa8 [led_bl]
[ 142.511742] platform_remove+0x30/0x58
[ 142.515501] device_remove+0x54/0x90
...
Indeed, led_sysfs_enable() has to be called with the led_access
lock held.
Hold the lock when calling led_sysfs_disable().
Fixes: ae232e45acf9 ("backlight: add led-backlight driver")
Cc: stable(a)vger.kernel.org
Signed-off-by: Herve Codina <herve.codina(a)bootlin.com>
Link: https://lore.kernel.org/r/20250122091914.309533-1-herve.codina@bootlin.com
Signed-off-by: Lee Jones <lee(a)kernel.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
drivers/video/backlight/led_bl.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c
index f54d256e2d54..1020e4405a4d 100644
--- a/drivers/video/backlight/led_bl.c
+++ b/drivers/video/backlight/led_bl.c
@@ -226,8 +226,11 @@ static int led_bl_remove(struct platform_device *pdev)
backlight_device_unregister(bl);
led_bl_power_off(priv);
- for (i = 0; i < priv->nb_leds; i++)
+ for (i = 0; i < priv->nb_leds; i++) {
+ mutex_lock(&priv->leds[i]->led_access);
led_sysfs_enable(priv->leds[i]);
+ mutex_unlock(&priv->leds[i]->led_access);
+ }
return 0;
}
--
2.34.1
2
1

[PATCH OLK-6.6] backlight: led_bl: Hold led_access lock when calling led_sysfs_disable()
by Yuntao Liu 12 May '25
by Yuntao Liu 12 May '25
12 May '25
From: Herve Codina <herve.codina(a)bootlin.com>
stable inclusion
from stable-v6.6.88
commit 1c82f5a393d8b9a5c1ea032413719862098afd4b
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC5BJZ
CVE: CVE-2025-23144
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 276822a00db3c1061382b41e72cafc09d6a0ec30 upstream.
Lockdep detects the following issue on led-backlight removal:
[ 142.315935] ------------[ cut here ]------------
[ 142.315954] WARNING: CPU: 2 PID: 292 at drivers/leds/led-core.c:455 led_sysfs_enable+0x54/0x80
...
[ 142.500725] Call trace:
[ 142.503176] led_sysfs_enable+0x54/0x80 (P)
[ 142.507370] led_bl_remove+0x80/0xa8 [led_bl]
[ 142.511742] platform_remove+0x30/0x58
[ 142.515501] device_remove+0x54/0x90
...
Indeed, led_sysfs_enable() has to be called with the led_access
lock held.
Hold the lock when calling led_sysfs_disable().
Fixes: ae232e45acf9 ("backlight: add led-backlight driver")
Cc: stable(a)vger.kernel.org
Signed-off-by: Herve Codina <herve.codina(a)bootlin.com>
Link: https://lore.kernel.org/r/20250122091914.309533-1-herve.codina@bootlin.com
Signed-off-by: Lee Jones <lee(a)kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
drivers/video/backlight/led_bl.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c
index 032f8bddf872..0e53e427a91d 100644
--- a/drivers/video/backlight/led_bl.c
+++ b/drivers/video/backlight/led_bl.c
@@ -229,8 +229,11 @@ static void led_bl_remove(struct platform_device *pdev)
backlight_device_unregister(bl);
led_bl_power_off(priv);
- for (i = 0; i < priv->nb_leds; i++)
+ for (i = 0; i < priv->nb_leds; i++) {
+ mutex_lock(&priv->leds[i]->led_access);
led_sysfs_enable(priv->leds[i]);
+ mutex_unlock(&priv->leds[i]->led_access);
+ }
}
static const struct of_device_id led_bl_of_match[] = {
--
2.34.1
2
1

12 May '25
From: Alexandra Diupina <adiupina(a)astralinux.ru>
mainline inclusion
from mainline-v6.15-rc1
commit b4885bd5935bb26f0a414ad55679a372e53f9b9b
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC6Q1P
CVE: CVE-2025-37844
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
cifs_server_dbg() implies server to be non-NULL so
move call under condition to avoid NULL pointer dereference.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: e79b0332ae06 ("cifs: ignore cached share root handle closing errors")
Cc: stable(a)vger.kernel.org
Signed-off-by: Alexandra Diupina <adiupina(a)astralinux.ru>
Signed-off-by: Steve French <stfrench(a)microsoft.com>
Signed-off-by: Wang Zhaolong <wangzhaolong1(a)huawei.com>
---
fs/smb/client/smb2misc.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c
index 677ef6f99a5b..fadc5fc274eb 100644
--- a/fs/smb/client/smb2misc.c
+++ b/fs/smb/client/smb2misc.c
@@ -814,15 +814,16 @@ smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
netfs_trace_tcon_ref_see_cancelled_close);
WARN_ONCE(tcon->tc_count < 0, "tcon refcount is negative");
spin_unlock(&cifs_tcp_ses_lock);
- if (tcon->ses)
+ if (tcon->ses) {
server = tcon->ses->server;
-
- cifs_server_dbg(FYI, "tid=0x%x: tcon is closing, skipping async close retry of fid %llu %llu\n",
- tcon->tid, persistent_fid, volatile_fid);
+ cifs_server_dbg(FYI,
+ "tid=0x%x: tcon is closing, skipping async close retry of fid %llu %llu\n",
+ tcon->tid, persistent_fid, volatile_fid);
+ }
return 0;
}
tcon->tc_count++;
trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
--
2.34.3
2
1

12 May '25
From: Alexandra Diupina <adiupina(a)astralinux.ru>
mainline inclusion
from mainline-v6.15-rc1
commit b4885bd5935bb26f0a414ad55679a372e53f9b9b
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC6Q1P
CVE: CVE-2025-37844
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
cifs_server_dbg() implies server to be non-NULL so
move call under condition to avoid NULL pointer dereference.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: e79b0332ae06 ("cifs: ignore cached share root handle closing errors")
Cc: stable(a)vger.kernel.org
Signed-off-by: Alexandra Diupina <adiupina(a)astralinux.ru>
Signed-off-by: Steve French <stfrench(a)microsoft.com>
Conflicts:
fs/smb/client/smb2misc.c
fs/cifs/smb2misc.c
[The file path has been changed.]
Signed-off-by: Wang Zhaolong <wangzhaolong1(a)huawei.com>
---
fs/cifs/smb2misc.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
index edffa5657d26..074a56796092 100644
--- a/fs/cifs/smb2misc.c
+++ b/fs/cifs/smb2misc.c
@@ -807,15 +807,16 @@ smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
struct TCP_Server_Info *server = NULL;
WARN_ONCE(tcon->tc_count < 0, "tcon refcount is negative");
spin_unlock(&cifs_tcp_ses_lock);
- if (tcon->ses)
+ if (tcon->ses) {
server = tcon->ses->server;
- cifs_server_dbg(FYI, "tid=%u: tcon is closing, skipping async close retry of fid %llu %llu\n",
- tcon->tid, persistent_fid, volatile_fid);
+ cifs_server_dbg(FYI, "tid=%u: tcon is closing, skipping async close retry of fid %llu %llu\n",
+ tcon->tid, persistent_fid, volatile_fid);
+ }
return 0;
}
tcon->tc_count++;
spin_unlock(&cifs_tcp_ses_lock);
--
2.34.3
2
1
From: Jan Kara <jack(a)suse.cz>
stable inclusion
from stable-v5.10.237
commit b479839525fe7906966cdc4b5b2afbca048558a1
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC6LPS
CVE: CVE-2025-37839
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit e6eff39dd0fe4190c6146069cc16d160e71d1148 upstream.
Journal emptiness is not determined by sb->s_sequence == 0 but rather by
sb->s_start == 0 (which is set a few lines above). Furthermore 0 is a
valid transaction ID so the check can spuriously trigger. Remove the
invalid WARN_ON.
CC: stable(a)vger.kernel.org
Signed-off-by: Jan Kara <jack(a)suse.cz>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Link: https://patch.msgid.link/20250206094657.20865-3-jack@suse.cz
Signed-off-by: Theodore Ts'o <tytso(a)mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Zizhi Wo <wozizhi(a)huawei.com>
---
fs/jbd2/journal.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index bf83e1c64aa4..5dddfc493ca7 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1517,7 +1517,6 @@ int jbd2_journal_update_sb_log_tail(journal_t *journal, tid_t tail_tid,
/* Log is no longer empty */
write_lock(&journal->j_state_lock);
- WARN_ON(!sb->s_sequence);
journal->j_flags &= ~JBD2_FLUSHED;
write_unlock(&journal->j_state_lock);
--
2.39.2
2
1
From: Jan Kara <jack(a)suse.cz>
stable inclusion
from stable-v5.10.237
commit b479839525fe7906966cdc4b5b2afbca048558a1
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC6LPS
CVE: CVE-2025-37839
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit e6eff39dd0fe4190c6146069cc16d160e71d1148 upstream.
Journal emptiness is not determined by sb->s_sequence == 0 but rather by
sb->s_start == 0 (which is set a few lines above). Furthermore 0 is a
valid transaction ID so the check can spuriously trigger. Remove the
invalid WARN_ON.
CC: stable(a)vger.kernel.org
Signed-off-by: Jan Kara <jack(a)suse.cz>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Link: https://patch.msgid.link/20250206094657.20865-3-jack@suse.cz
Signed-off-by: Theodore Ts'o <tytso(a)mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Zizhi Wo <wozizhi(a)huawei.com>
---
fs/jbd2/journal.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 7775ad53b291..cc83decc6425 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1705,7 +1705,6 @@ int jbd2_journal_update_sb_log_tail(journal_t *journal, tid_t tail_tid,
/* Log is no longer empty */
write_lock(&journal->j_state_lock);
- WARN_ON(!sb->s_sequence);
journal->j_flags &= ~JBD2_FLUSHED;
write_unlock(&journal->j_state_lock);
--
2.39.2
2
1
From: Jan Kara <jack(a)suse.cz>
stable inclusion
from stable-v5.10.237
commit b479839525fe7906966cdc4b5b2afbca048558a1
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC6LPS
CVE: CVE-2025-37839
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit e6eff39dd0fe4190c6146069cc16d160e71d1148 upstream.
Journal emptiness is not determined by sb->s_sequence == 0 but rather by
sb->s_start == 0 (which is set a few lines above). Furthermore 0 is a
valid transaction ID so the check can spuriously trigger. Remove the
invalid WARN_ON.
CC: stable(a)vger.kernel.org
Signed-off-by: Jan Kara <jack(a)suse.cz>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Link: https://patch.msgid.link/20250206094657.20865-3-jack@suse.cz
Signed-off-by: Theodore Ts'o <tytso(a)mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Zizhi Wo <wozizhi(a)huawei.com>
---
fs/jbd2/journal.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index bf83e1c64aa4..5dddfc493ca7 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1517,7 +1517,6 @@ int jbd2_journal_update_sb_log_tail(journal_t *journal, tid_t tail_tid,
/* Log is no longer empty */
write_lock(&journal->j_state_lock);
- WARN_ON(!sb->s_sequence);
journal->j_flags &= ~JBD2_FLUSHED;
write_unlock(&journal->j_state_lock);
--
2.39.2
2
1

[PATCH OLK-5.10] cachefiles: Fix non-taking of sb_writers around set/removexattr
by Zizhi Wo 12 May '25
by Zizhi Wo 12 May '25
12 May '25
From: David Howells <dhowells(a)redhat.com>
stable inclusion
from stable-v6.6.54
commit 81b048b9484bf8b3c0ad6e901a6b79fb941173b0
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IC711Q
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 80887f31672970abae3aaa9cf62ac72a124e7c89 ]
Unlike other vfs_xxxx() calls, vfs_setxattr() and vfs_removexattr() don't
take the sb_writers lock, so the caller should do it for them.
Fix cachefiles to do this.
Fixes: 9ae326a69004 ("CacheFiles: A cache that backs onto a mounted filesystem")
Signed-off-by: David Howells <dhowells(a)redhat.com>
cc: Christian Brauner <brauner(a)kernel.org>
cc: Gao Xiang <xiang(a)kernel.org>
cc: netfs(a)lists.linux.dev
cc: linux-erofs(a)lists.ozlabs.org
cc: linux-fsdevel(a)vger.kernel.org
Link: https://lore.kernel.org/r/20240814203850.2240469-3-dhowells@redhat.com/ # v2
Signed-off-by: Christian Brauner <brauner(a)kernel.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Conflicts:
fs/cachefiles/internal.h
fs/cachefiles/bind.c
fs/cachefiles/xattr.c
[The code has changed and relevant adaptations have been made.]
Signed-off-by: Zizhi Wo <wozizhi(a)huawei.com>
---
fs/cachefiles/bind.c | 2 +-
fs/cachefiles/internal.h | 3 +-
fs/cachefiles/xattr.c | 69 +++++++++++++++++++++++++++++-----------
3 files changed, 54 insertions(+), 20 deletions(-)
diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c
index 3a88bef9ed4b..8c84bfcde991 100644
--- a/fs/cachefiles/bind.c
+++ b/fs/cachefiles/bind.c
@@ -206,7 +206,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache)
fsdef->dentry = cachedir;
fsdef->fscache.cookie = NULL;
- ret = cachefiles_check_object_type(fsdef);
+ ret = cachefiles_check_object_type(fsdef, cache);
if (ret < 0)
goto error_unsupported;
diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
index 97c4b4c639b4..96d96926017e 100644
--- a/fs/cachefiles/internal.h
+++ b/fs/cachefiles/internal.h
@@ -368,7 +368,8 @@ static inline void cachefiles_end_secure(struct cachefiles_cache *cache,
/*
* xattr.c
*/
-extern int cachefiles_check_object_type(struct cachefiles_object *object);
+extern int cachefiles_check_object_type(struct cachefiles_object *object,
+ struct cachefiles_cache *cache);
extern int cachefiles_set_object_xattr(struct cachefiles_object *object,
struct cachefiles_xattr *auxdata);
extern int cachefiles_update_object_xattr(struct cachefiles_object *object,
diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c
index 4aadace026d2..bac55fc7359e 100644
--- a/fs/cachefiles/xattr.c
+++ b/fs/cachefiles/xattr.c
@@ -45,7 +45,8 @@ static int cachefiles_check_new_obj_xattr(struct cachefiles_object *object);
* check the type label on an object
* - done using xattrs
*/
-int cachefiles_check_object_type(struct cachefiles_object *object)
+int cachefiles_check_object_type(struct cachefiles_object *object,
+ struct cachefiles_cache *cache)
{
struct dentry *dentry = object->dentry;
char type[3], xtype[3];
@@ -62,8 +63,12 @@ int cachefiles_check_object_type(struct cachefiles_object *object)
_enter("%p{%s}", object, type);
/* attempt to install a type label directly */
- ret = vfs_setxattr(dentry, cachefiles_xattr_cache, type, 2,
- XATTR_CREATE);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache, type, 2,
+ XATTR_CREATE);
+ mnt_drop_write(cache->mnt);
+ }
if (ret == 0) {
_debug("SET"); /* we succeeded */
goto error;
@@ -123,6 +128,7 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object,
struct cachefiles_xattr *auxdata)
{
struct dentry *dentry = object->dentry;
+ struct cachefiles_cache *cache;
int ret;
ASSERT(dentry);
@@ -132,15 +138,22 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object,
/* attempt to install the cache metadata directly */
_debug("SET #%u", auxdata->len);
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags);
- if (data_new_version(object->fscache.cookie))
- ret = cachefiles_set_new_obj_xattr(object);
- else if (volume_new_version(object->fscache.cookie))
- ret = cachefiles_set_new_vol_xattr(object);
- else
- ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
- &auxdata->type, auxdata->len,
- XATTR_CREATE);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ if (data_new_version(object->fscache.cookie))
+ ret = cachefiles_set_new_obj_xattr(object);
+ else if (volume_new_version(object->fscache.cookie))
+ ret = cachefiles_set_new_vol_xattr(object);
+ else
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
+ &auxdata->type, auxdata->len,
+ XATTR_CREATE);
+ mnt_drop_write(cache->mnt);
+ }
if (ret < 0 && ret != -ENOMEM)
cachefiles_io_error_obj(
object,
@@ -157,6 +170,7 @@ int cachefiles_update_object_xattr(struct cachefiles_object *object,
struct cachefiles_xattr *auxdata)
{
struct dentry *dentry = object->dentry;
+ struct cachefiles_cache *cache;
int ret;
if (!dentry)
@@ -167,10 +181,17 @@ int cachefiles_update_object_xattr(struct cachefiles_object *object,
/* attempt to install the cache metadata directly */
_debug("SET #%u", auxdata->len);
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags);
- ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
- &auxdata->type, auxdata->len,
- XATTR_REPLACE);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
+ &auxdata->type, auxdata->len,
+ XATTR_REPLACE);
+ mnt_drop_write(cache->mnt);
+ }
if (ret < 0 && ret != -ENOMEM)
cachefiles_io_error_obj(
object,
@@ -222,6 +243,7 @@ int cachefiles_check_old_object_xattr(struct cachefiles_object *object,
struct cachefiles_xattr *auxdata)
{
struct cachefiles_xattr *auxbuf;
+ struct cachefiles_cache *cache;
unsigned int len = sizeof(struct cachefiles_xattr) + 512;
struct dentry *dentry = object->dentry;
int ret;
@@ -279,10 +301,17 @@ int cachefiles_check_old_object_xattr(struct cachefiles_object *object,
BUG();
}
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
/* update the current label */
- ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
- &auxdata->type, auxdata->len,
- XATTR_REPLACE);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
+ &auxdata->type, auxdata->len,
+ XATTR_REPLACE);
+ mnt_drop_write(cache->mnt);
+ }
if (ret < 0) {
cachefiles_io_error_obj(object,
"Can't update xattr on %lu"
@@ -364,7 +393,11 @@ int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
{
int ret;
- ret = vfs_removexattr(dentry, cachefiles_xattr_cache);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ ret = vfs_removexattr(dentry, cachefiles_xattr_cache);
+ mnt_drop_write(cache->mnt);
+ }
if (ret < 0) {
if (ret == -ENOENT || ret == -ENODATA)
ret = 0;
--
2.39.2
2
1
From: Yonghong Song <yonghong.song(a)linux.dev>
mainline inclusion
from mainline-v6.15-rc1
commit 11ba7ce076e5903e7bdc1fd1498979c331b3c286
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC6BRF
CVE: CVE-2025-37807
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
Vlad Poenaru reported the following kmemleak issue:
unreferenced object 0x606fd7c44ac8 (size 32):
backtrace (crc 0):
pcpu_alloc_noprof+0x730/0xeb0
bpf_map_alloc_percpu+0x69/0xc0
prealloc_init+0x9d/0x1b0
htab_map_alloc+0x363/0x510
map_create+0x215/0x3a0
__sys_bpf+0x16b/0x3e0
__x64_sys_bpf+0x18/0x20
do_syscall_64+0x7b/0x150
entry_SYSCALL_64_after_hwframe+0x4b/0x53
Further investigation shows the reason is due to not 8-byte aligned
store of percpu pointer in htab_elem_set_ptr():
*(void __percpu **)(l->key + key_size) = pptr;
Note that the whole htab_elem alignment is 8 (for x86_64). If the key_size
is 4, that means pptr is stored in a location which is 4 byte aligned but
not 8 byte aligned. In mm/kmemleak.c, scan_block() scans the memory based
on 8 byte stride, so it won't detect above pptr, hence reporting the memory
leak.
In htab_map_alloc(), we already have
htab->elem_size = sizeof(struct htab_elem) +
round_up(htab->map.key_size, 8);
if (percpu)
htab->elem_size += sizeof(void *);
else
htab->elem_size += round_up(htab->map.value_size, 8);
So storing pptr with 8-byte alignment won't cause any problem and can fix
kmemleak too.
The issue can be reproduced with bpf selftest as well:
1. Enable CONFIG_DEBUG_KMEMLEAK config
2. Add a getchar() before skel destroy in test_hash_map() in prog_tests/for_each.c.
The purpose is to keep map available so kmemleak can be detected.
3. run './test_progs -t for_each/hash_map &' and a kmemleak should be reported.
Reported-by: Vlad Poenaru <thevlad(a)meta.com>
Signed-off-by: Yonghong Song <yonghong.song(a)linux.dev>
Acked-by: Martin KaFai Lau <martin.lau(a)kernel.org>
Link: https://lore.kernel.org/r/20250224175514.2207227-1-yonghong.song@linux.dev
Signed-off-by: Alexei Starovoitov <ast(a)kernel.org>
Conflicts:
kernel/bpf/hashtab.c
[The conflicts were due to not merge commit 0b56e637f7058]
Signed-off-by: Pu Lehui <pulehui(a)huawei.com>
---
kernel/bpf/hashtab.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index fc34f72702cc..fdc74aeaa164 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -197,12 +197,12 @@ static bool htab_is_percpu(const struct bpf_htab *htab)
static inline void htab_elem_set_ptr(struct htab_elem *l, u32 key_size,
void __percpu *pptr)
{
- *(void __percpu **)(l->key + key_size) = pptr;
+ *(void __percpu **)(l->key + roundup(key_size, 8)) = pptr;
}
static inline void __percpu *htab_elem_get_ptr(struct htab_elem *l, u32 key_size)
{
- return *(void __percpu **)(l->key + key_size);
+ return *(void __percpu **)(l->key + roundup(key_size, 8));
}
static void *fd_htab_map_get_ptr(const struct bpf_map *map, struct htab_elem *l)
--
2.34.1
2
1

12 May '25
From: Alexei Starovoitov <ast(a)kernel.org>
stable inclusion
from stable-v6.6.89
commit b5a528a34e1f613565115a7a6016862ccbfcb9ac
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC6LWA
CVE: CVE-2025-37884
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 4580f4e0ebdf8dc8d506ae926b88510395a0c1d1 ]
Fix the following deadlock:
CPU A
_free_event()
perf_kprobe_destroy()
mutex_lock(&event_mutex)
perf_trace_event_unreg()
synchronize_rcu_tasks_trace()
There are several paths where _free_event() grabs event_mutex
and calls sync_rcu_tasks_trace. Above is one such case.
CPU B
bpf_prog_test_run_syscall()
rcu_read_lock_trace()
bpf_prog_run_pin_on_cpu()
bpf_prog_load()
bpf_tracing_func_proto()
trace_set_clr_event()
mutex_lock(&event_mutex)
Delegate trace_set_clr_event() to workqueue to avoid
such lock dependency.
Signed-off-by: Alexei Starovoitov <ast(a)kernel.org>
Signed-off-by: Andrii Nakryiko <andrii(a)kernel.org>
Acked-by: Andrii Nakryiko <andrii(a)kernel.org>
Link: https://lore.kernel.org/bpf/20250224221637.4780-1-alexei.starovoitov@gmail.…
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Pu Lehui <pulehui(a)huawei.com>
---
kernel/trace/bpf_trace.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index dd70275d406b..042077a3abfe 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -400,7 +400,7 @@ static const struct bpf_func_proto bpf_trace_printk_proto = {
.arg2_type = ARG_CONST_SIZE,
};
-static void __set_printk_clr_event(void)
+static void __set_printk_clr_event(struct work_struct *work)
{
/*
* This program might be calling bpf_trace_printk,
@@ -413,10 +413,11 @@ static void __set_printk_clr_event(void)
if (trace_set_clr_event("bpf_trace", "bpf_trace_printk", 1))
pr_warn_ratelimited("could not enable bpf_trace_printk events");
}
+static DECLARE_WORK(set_printk_work, __set_printk_clr_event);
const struct bpf_func_proto *bpf_get_trace_printk_proto(void)
{
- __set_printk_clr_event();
+ schedule_work(&set_printk_work);
return &bpf_trace_printk_proto;
}
@@ -459,7 +460,7 @@ static const struct bpf_func_proto bpf_trace_vprintk_proto = {
const struct bpf_func_proto *bpf_get_trace_vprintk_proto(void)
{
- __set_printk_clr_event();
+ schedule_work(&set_printk_work);
return &bpf_trace_vprintk_proto;
}
--
2.34.1
2
1

[PATCH OLK-5.10] cachefiles: Fix non-taking of sb_writers around set/removexattr
by Zizhi Wo 12 May '25
by Zizhi Wo 12 May '25
12 May '25
From: David Howells <dhowells(a)redhat.com>
stable inclusion
from stable-v6.6.54
commit 81b048b9484bf8b3c0ad6e901a6b79fb941173b0
category: bugfix
bugzilla: 190608
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 80887f31672970abae3aaa9cf62ac72a124e7c89 ]
Unlike other vfs_xxxx() calls, vfs_setxattr() and vfs_removexattr() don't
take the sb_writers lock, so the caller should do it for them.
Fix cachefiles to do this.
Fixes: 9ae326a69004 ("CacheFiles: A cache that backs onto a mounted filesystem")
Signed-off-by: David Howells <dhowells(a)redhat.com>
cc: Christian Brauner <brauner(a)kernel.org>
cc: Gao Xiang <xiang(a)kernel.org>
cc: netfs(a)lists.linux.dev
cc: linux-erofs(a)lists.ozlabs.org
cc: linux-fsdevel(a)vger.kernel.org
Link: https://lore.kernel.org/r/20240814203850.2240469-3-dhowells@redhat.com/ # v2
Signed-off-by: Christian Brauner <brauner(a)kernel.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Conflicts:
fs/cachefiles/internal.h
fs/cachefiles/bind.c
fs/cachefiles/xattr.c
[The code has changed and relevant adaptations have been made.]
Signed-off-by: Zizhi Wo <wozizhi(a)huawei.com>
---
fs/cachefiles/bind.c | 2 +-
fs/cachefiles/internal.h | 3 +-
fs/cachefiles/xattr.c | 69 +++++++++++++++++++++++++++++-----------
3 files changed, 54 insertions(+), 20 deletions(-)
diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c
index 3a88bef9ed4b..8c84bfcde991 100644
--- a/fs/cachefiles/bind.c
+++ b/fs/cachefiles/bind.c
@@ -206,7 +206,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache)
fsdef->dentry = cachedir;
fsdef->fscache.cookie = NULL;
- ret = cachefiles_check_object_type(fsdef);
+ ret = cachefiles_check_object_type(fsdef, cache);
if (ret < 0)
goto error_unsupported;
diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
index 97c4b4c639b4..96d96926017e 100644
--- a/fs/cachefiles/internal.h
+++ b/fs/cachefiles/internal.h
@@ -368,7 +368,8 @@ static inline void cachefiles_end_secure(struct cachefiles_cache *cache,
/*
* xattr.c
*/
-extern int cachefiles_check_object_type(struct cachefiles_object *object);
+extern int cachefiles_check_object_type(struct cachefiles_object *object,
+ struct cachefiles_cache *cache);
extern int cachefiles_set_object_xattr(struct cachefiles_object *object,
struct cachefiles_xattr *auxdata);
extern int cachefiles_update_object_xattr(struct cachefiles_object *object,
diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c
index 4aadace026d2..bac55fc7359e 100644
--- a/fs/cachefiles/xattr.c
+++ b/fs/cachefiles/xattr.c
@@ -45,7 +45,8 @@ static int cachefiles_check_new_obj_xattr(struct cachefiles_object *object);
* check the type label on an object
* - done using xattrs
*/
-int cachefiles_check_object_type(struct cachefiles_object *object)
+int cachefiles_check_object_type(struct cachefiles_object *object,
+ struct cachefiles_cache *cache)
{
struct dentry *dentry = object->dentry;
char type[3], xtype[3];
@@ -62,8 +63,12 @@ int cachefiles_check_object_type(struct cachefiles_object *object)
_enter("%p{%s}", object, type);
/* attempt to install a type label directly */
- ret = vfs_setxattr(dentry, cachefiles_xattr_cache, type, 2,
- XATTR_CREATE);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache, type, 2,
+ XATTR_CREATE);
+ mnt_drop_write(cache->mnt);
+ }
if (ret == 0) {
_debug("SET"); /* we succeeded */
goto error;
@@ -123,6 +128,7 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object,
struct cachefiles_xattr *auxdata)
{
struct dentry *dentry = object->dentry;
+ struct cachefiles_cache *cache;
int ret;
ASSERT(dentry);
@@ -132,15 +138,22 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object,
/* attempt to install the cache metadata directly */
_debug("SET #%u", auxdata->len);
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags);
- if (data_new_version(object->fscache.cookie))
- ret = cachefiles_set_new_obj_xattr(object);
- else if (volume_new_version(object->fscache.cookie))
- ret = cachefiles_set_new_vol_xattr(object);
- else
- ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
- &auxdata->type, auxdata->len,
- XATTR_CREATE);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ if (data_new_version(object->fscache.cookie))
+ ret = cachefiles_set_new_obj_xattr(object);
+ else if (volume_new_version(object->fscache.cookie))
+ ret = cachefiles_set_new_vol_xattr(object);
+ else
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
+ &auxdata->type, auxdata->len,
+ XATTR_CREATE);
+ mnt_drop_write(cache->mnt);
+ }
if (ret < 0 && ret != -ENOMEM)
cachefiles_io_error_obj(
object,
@@ -157,6 +170,7 @@ int cachefiles_update_object_xattr(struct cachefiles_object *object,
struct cachefiles_xattr *auxdata)
{
struct dentry *dentry = object->dentry;
+ struct cachefiles_cache *cache;
int ret;
if (!dentry)
@@ -167,10 +181,17 @@ int cachefiles_update_object_xattr(struct cachefiles_object *object,
/* attempt to install the cache metadata directly */
_debug("SET #%u", auxdata->len);
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags);
- ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
- &auxdata->type, auxdata->len,
- XATTR_REPLACE);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
+ &auxdata->type, auxdata->len,
+ XATTR_REPLACE);
+ mnt_drop_write(cache->mnt);
+ }
if (ret < 0 && ret != -ENOMEM)
cachefiles_io_error_obj(
object,
@@ -222,6 +243,7 @@ int cachefiles_check_old_object_xattr(struct cachefiles_object *object,
struct cachefiles_xattr *auxdata)
{
struct cachefiles_xattr *auxbuf;
+ struct cachefiles_cache *cache;
unsigned int len = sizeof(struct cachefiles_xattr) + 512;
struct dentry *dentry = object->dentry;
int ret;
@@ -279,10 +301,17 @@ int cachefiles_check_old_object_xattr(struct cachefiles_object *object,
BUG();
}
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
/* update the current label */
- ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
- &auxdata->type, auxdata->len,
- XATTR_REPLACE);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
+ &auxdata->type, auxdata->len,
+ XATTR_REPLACE);
+ mnt_drop_write(cache->mnt);
+ }
if (ret < 0) {
cachefiles_io_error_obj(object,
"Can't update xattr on %lu"
@@ -364,7 +393,11 @@ int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
{
int ret;
- ret = vfs_removexattr(dentry, cachefiles_xattr_cache);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ ret = vfs_removexattr(dentry, cachefiles_xattr_cache);
+ mnt_drop_write(cache->mnt);
+ }
if (ret < 0) {
if (ret == -ENOENT || ret == -ENODATA)
ret = 0;
--
2.39.2
2
1
This series includes adding Motorcomm YT6801 Gigabit ethernet driver
and adding yt6801 ethernet driver entry in MAINTAINERS file.
YT6801 integrates a YT8531S phy.
Frank_Sae (14):
yt6801: Add support for a pci table in this module
yt6801: Implement mdio register
yt6801: Implement pci_driver shutdown
yt6801: Implement the fxgmac_init function
yt6801: Implement the .ndo_open function
yt6801: Implement the fxgmac_start function
net:phy:motorcomm: Add PHY_INTERFACE_MODE_INTERNAL to support YT6801
yt6801: Implement the fxgmac_hw_init function
yt6801: Implement the poll functions
yt6801: Implement .ndo_start_xmit function
yt6801: Implement some net_device_ops function
yt6801: Implement pci_driver suspend and resume
yt6801: Add makefile and Kconfig
yt6801: Update the Makefile, Kconfig and maintainer for yt6801
MAINTAINERS | 7 +
arch/arm64/configs/openeuler_defconfig | 4 +-
arch/loongarch/configs/loongson3_defconfig | 3 +
arch/powerpc/configs/openeuler_defconfig | 4 +-
arch/riscv/configs/openeuler_defconfig | 4 +-
arch/x86/configs/openeuler_defconfig | 4 +-
drivers/net/ethernet/Kconfig | 1 +
drivers/net/ethernet/Makefile | 1 +
drivers/net/ethernet/motorcomm/Kconfig | 27 +
drivers/net/ethernet/motorcomm/Makefile | 6 +
.../net/ethernet/motorcomm/yt6801/Makefile | 8 +
.../ethernet/motorcomm/yt6801/yt6801_desc.c | 565 +++
.../ethernet/motorcomm/yt6801/yt6801_desc.h | 35 +
.../ethernet/motorcomm/yt6801/yt6801_main.c | 3020 +++++++++++++++++
.../ethernet/motorcomm/yt6801/yt6801_type.h | 961 ++++++
drivers/net/phy/motorcomm.c | 6 +
16 files changed, 4652 insertions(+), 4 deletions(-)
create mode 100644 drivers/net/ethernet/motorcomm/Kconfig
create mode 100644 drivers/net/ethernet/motorcomm/Makefile
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/Makefile
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.c
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.h
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_main.c
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_type.h
--
2.34.1
2
18

[PATCH OLK-5.10] cachefiles: Fix non-taking of sb_writers around set/removexattr
by Zizhi Wo 12 May '25
by Zizhi Wo 12 May '25
12 May '25
From: David Howells <dhowells(a)redhat.com>
stable inclusion
from stable-v6.6.54
commit 81b048b9484bf8b3c0ad6e901a6b79fb941173b0
category: bugfix
bugzilla: 190608
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 80887f31672970abae3aaa9cf62ac72a124e7c89 ]
Unlike other vfs_xxxx() calls, vfs_setxattr() and vfs_removexattr() don't
take the sb_writers lock, so the caller should do it for them.
Fix cachefiles to do this.
Fixes: 9ae326a69004 ("CacheFiles: A cache that backs onto a mounted filesystem")
Signed-off-by: David Howells <dhowells(a)redhat.com>
cc: Christian Brauner <brauner(a)kernel.org>
cc: Gao Xiang <xiang(a)kernel.org>
cc: netfs(a)lists.linux.dev
cc: linux-erofs(a)lists.ozlabs.org
cc: linux-fsdevel(a)vger.kernel.org
Link: https://lore.kernel.org/r/20240814203850.2240469-3-dhowells@redhat.com/ # v2
Signed-off-by: Christian Brauner <brauner(a)kernel.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Conflicts:
fs/cachefiles/internal.h
fs/cachefiles/bind.c
fs/cachefiles/xattr.c
[The code has changed and relevant adaptations have been made.]
Signed-off-by: Zizhi Wo <wozizhi(a)huawei.com>
---
fs/cachefiles/bind.c | 2 +-
fs/cachefiles/internal.h | 3 +-
fs/cachefiles/xattr.c | 69 +++++++++++++++++++++++++++++-----------
3 files changed, 54 insertions(+), 20 deletions(-)
diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c
index 3a88bef9ed4b..8c84bfcde991 100644
--- a/fs/cachefiles/bind.c
+++ b/fs/cachefiles/bind.c
@@ -206,7 +206,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache)
fsdef->dentry = cachedir;
fsdef->fscache.cookie = NULL;
- ret = cachefiles_check_object_type(fsdef);
+ ret = cachefiles_check_object_type(fsdef, cache);
if (ret < 0)
goto error_unsupported;
diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
index 97c4b4c639b4..96d96926017e 100644
--- a/fs/cachefiles/internal.h
+++ b/fs/cachefiles/internal.h
@@ -368,7 +368,8 @@ static inline void cachefiles_end_secure(struct cachefiles_cache *cache,
/*
* xattr.c
*/
-extern int cachefiles_check_object_type(struct cachefiles_object *object);
+extern int cachefiles_check_object_type(struct cachefiles_object *object,
+ struct cachefiles_cache *cache);
extern int cachefiles_set_object_xattr(struct cachefiles_object *object,
struct cachefiles_xattr *auxdata);
extern int cachefiles_update_object_xattr(struct cachefiles_object *object,
diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c
index 4aadace026d2..bac55fc7359e 100644
--- a/fs/cachefiles/xattr.c
+++ b/fs/cachefiles/xattr.c
@@ -45,7 +45,8 @@ static int cachefiles_check_new_obj_xattr(struct cachefiles_object *object);
* check the type label on an object
* - done using xattrs
*/
-int cachefiles_check_object_type(struct cachefiles_object *object)
+int cachefiles_check_object_type(struct cachefiles_object *object,
+ struct cachefiles_cache *cache)
{
struct dentry *dentry = object->dentry;
char type[3], xtype[3];
@@ -62,8 +63,12 @@ int cachefiles_check_object_type(struct cachefiles_object *object)
_enter("%p{%s}", object, type);
/* attempt to install a type label directly */
- ret = vfs_setxattr(dentry, cachefiles_xattr_cache, type, 2,
- XATTR_CREATE);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache, type, 2,
+ XATTR_CREATE);
+ mnt_drop_write(cache->mnt);
+ }
if (ret == 0) {
_debug("SET"); /* we succeeded */
goto error;
@@ -123,6 +128,7 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object,
struct cachefiles_xattr *auxdata)
{
struct dentry *dentry = object->dentry;
+ struct cachefiles_cache *cache;
int ret;
ASSERT(dentry);
@@ -132,15 +138,22 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object,
/* attempt to install the cache metadata directly */
_debug("SET #%u", auxdata->len);
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags);
- if (data_new_version(object->fscache.cookie))
- ret = cachefiles_set_new_obj_xattr(object);
- else if (volume_new_version(object->fscache.cookie))
- ret = cachefiles_set_new_vol_xattr(object);
- else
- ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
- &auxdata->type, auxdata->len,
- XATTR_CREATE);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ if (data_new_version(object->fscache.cookie))
+ ret = cachefiles_set_new_obj_xattr(object);
+ else if (volume_new_version(object->fscache.cookie))
+ ret = cachefiles_set_new_vol_xattr(object);
+ else
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
+ &auxdata->type, auxdata->len,
+ XATTR_CREATE);
+ mnt_drop_write(cache->mnt);
+ }
if (ret < 0 && ret != -ENOMEM)
cachefiles_io_error_obj(
object,
@@ -157,6 +170,7 @@ int cachefiles_update_object_xattr(struct cachefiles_object *object,
struct cachefiles_xattr *auxdata)
{
struct dentry *dentry = object->dentry;
+ struct cachefiles_cache *cache;
int ret;
if (!dentry)
@@ -167,10 +181,17 @@ int cachefiles_update_object_xattr(struct cachefiles_object *object,
/* attempt to install the cache metadata directly */
_debug("SET #%u", auxdata->len);
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags);
- ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
- &auxdata->type, auxdata->len,
- XATTR_REPLACE);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
+ &auxdata->type, auxdata->len,
+ XATTR_REPLACE);
+ mnt_drop_write(cache->mnt);
+ }
if (ret < 0 && ret != -ENOMEM)
cachefiles_io_error_obj(
object,
@@ -222,6 +243,7 @@ int cachefiles_check_old_object_xattr(struct cachefiles_object *object,
struct cachefiles_xattr *auxdata)
{
struct cachefiles_xattr *auxbuf;
+ struct cachefiles_cache *cache;
unsigned int len = sizeof(struct cachefiles_xattr) + 512;
struct dentry *dentry = object->dentry;
int ret;
@@ -279,10 +301,17 @@ int cachefiles_check_old_object_xattr(struct cachefiles_object *object,
BUG();
}
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
/* update the current label */
- ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
- &auxdata->type, auxdata->len,
- XATTR_REPLACE);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
+ &auxdata->type, auxdata->len,
+ XATTR_REPLACE);
+ mnt_drop_write(cache->mnt);
+ }
if (ret < 0) {
cachefiles_io_error_obj(object,
"Can't update xattr on %lu"
@@ -364,7 +393,11 @@ int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
{
int ret;
- ret = vfs_removexattr(dentry, cachefiles_xattr_cache);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ ret = vfs_removexattr(dentry, cachefiles_xattr_cache);
+ mnt_drop_write(cache->mnt);
+ }
if (ret < 0) {
if (ret == -ENOENT || ret == -ENODATA)
ret = 0;
--
2.39.2
2
5
This series includes adding Motorcomm YT6801 Gigabit ethernet driver
and adding yt6801 ethernet driver entry in MAINTAINERS file.
YT6801 integrates a YT8531S phy.
Frank_Sae (14):
yt6801: Add support for a pci table in this module
yt6801: Implement mdio register
yt6801: Implement pci_driver shutdown
yt6801: Implement the fxgmac_init function
yt6801: Implement the .ndo_open function
yt6801: Implement the fxgmac_start function
net:phy:motorcomm: Add PHY_INTERFACE_MODE_INTERNAL to support YT6801
yt6801: Implement the fxgmac_hw_init function
yt6801: Implement the poll functions
yt6801: Implement .ndo_start_xmit function
yt6801: Implement some net_device_ops function
yt6801: Implement pci_driver suspend and resume
yt6801: Add makefile and Kconfig
yt6801: Update the Makefile, Kconfig and maintainer for yt6801
MAINTAINERS | 7 +
arch/arm64/configs/openeuler_defconfig | 4 +-
arch/loongarch/configs/loongson3_defconfig | 3 +
arch/powerpc/configs/openeuler_defconfig | 4 +-
arch/riscv/configs/openeuler_defconfig | 4 +-
arch/x86/configs/openeuler_defconfig | 4 +-
drivers/net/ethernet/Kconfig | 1 +
drivers/net/ethernet/Makefile | 1 +
drivers/net/ethernet/motorcomm/Kconfig | 27 +
drivers/net/ethernet/motorcomm/Makefile | 6 +
.../net/ethernet/motorcomm/yt6801/Makefile | 8 +
.../ethernet/motorcomm/yt6801/yt6801_desc.c | 565 +++
.../ethernet/motorcomm/yt6801/yt6801_desc.h | 35 +
.../ethernet/motorcomm/yt6801/yt6801_main.c | 3020 +++++++++++++++++
.../ethernet/motorcomm/yt6801/yt6801_type.h | 961 ++++++
drivers/net/phy/motorcomm.c | 6 +
16 files changed, 4652 insertions(+), 4 deletions(-)
create mode 100644 drivers/net/ethernet/motorcomm/Kconfig
create mode 100644 drivers/net/ethernet/motorcomm/Makefile
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/Makefile
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.c
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.h
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_main.c
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_type.h
--
2.34.1
2
19
This series includes adding Motorcomm YT6801 Gigabit ethernet driver
and adding yt6801 ethernet driver entry in MAINTAINERS file.
YT6801 integrates a YT8531S phy.
Frank_Sae (14):
yt6801: Add support for a pci table in this module
yt6801: Implement mdio register
yt6801: Implement pci_driver shutdown
yt6801: Implement the fxgmac_init function
yt6801: Implement the .ndo_open function
yt6801: Implement the fxgmac_start function
net:phy:motorcomm: Add PHY_INTERFACE_MODE_INTERNAL to support YT6801
yt6801: Implement the fxgmac_hw_init function
yt6801: Implement the poll functions
yt6801: Implement .ndo_start_xmit function
yt6801: Implement some net_device_ops function
yt6801: Implement pci_driver suspend and resume
yt6801: Add makefile and Kconfig
yt6801: Update the Makefile, Kconfig and maintainer for yt6801
MAINTAINERS | 7 +
arch/arm64/configs/openeuler_defconfig | 4 +-
arch/loongarch/configs/loongson3_defconfig | 3 +
arch/powerpc/configs/openeuler_defconfig | 4 +-
arch/riscv/configs/openeuler_defconfig | 4 +-
arch/x86/configs/openeuler_defconfig | 4 +-
drivers/net/ethernet/Kconfig | 1 +
drivers/net/ethernet/Makefile | 1 +
drivers/net/ethernet/motorcomm/Kconfig | 27 +
drivers/net/ethernet/motorcomm/Makefile | 6 +
.../net/ethernet/motorcomm/yt6801/Makefile | 8 +
.../ethernet/motorcomm/yt6801/yt6801_desc.c | 565 +++
.../ethernet/motorcomm/yt6801/yt6801_desc.h | 35 +
.../ethernet/motorcomm/yt6801/yt6801_main.c | 3020 +++++++++++++++++
.../ethernet/motorcomm/yt6801/yt6801_type.h | 961 ++++++
drivers/net/phy/motorcomm.c | 6 +
16 files changed, 4652 insertions(+), 4 deletions(-)
create mode 100644 drivers/net/ethernet/motorcomm/Kconfig
create mode 100644 drivers/net/ethernet/motorcomm/Makefile
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/Makefile
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.c
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.h
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_main.c
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_type.h
--
2.34.1
2
19
This series includes adding Motorcomm YT6801 Gigabit ethernet driver
and adding yt6801 ethernet driver entry in MAINTAINERS file.
YT6801 integrates a YT8531S phy.
Frank_Sae (14):
yt6801: Add support for a pci table in this module
yt6801: Implement mdio register
yt6801: Implement pci_driver shutdown
yt6801: Implement the fxgmac_init function
yt6801: Implement the .ndo_open function
yt6801: Implement the fxgmac_start function
net:phy:motorcomm: Add PHY_INTERFACE_MODE_INTERNAL to support YT6801
yt6801: Implement the fxgmac_hw_init function
yt6801: Implement the poll functions
yt6801: Implement .ndo_start_xmit function
yt6801: Implement some net_device_ops function
yt6801: Implement pci_driver suspend and resume
yt6801: Add makefile and Kconfig
yt6801: Update the Makefile, Kconfig and maintainer for yt6801
MAINTAINERS | 7 +
arch/arm64/configs/openeuler_defconfig | 4 +-
arch/loongarch/configs/loongson3_defconfig | 3 +
arch/powerpc/configs/openeuler_defconfig | 4 +-
arch/riscv/configs/openeuler_defconfig | 4 +-
arch/x86/configs/openeuler_defconfig | 4 +-
drivers/net/ethernet/Kconfig | 1 +
drivers/net/ethernet/Makefile | 1 +
drivers/net/ethernet/motorcomm/Kconfig | 27 +
drivers/net/ethernet/motorcomm/Makefile | 6 +
.../net/ethernet/motorcomm/yt6801/Makefile | 8 +
.../ethernet/motorcomm/yt6801/yt6801_desc.c | 565 +++
.../ethernet/motorcomm/yt6801/yt6801_desc.h | 35 +
.../ethernet/motorcomm/yt6801/yt6801_main.c | 3020 +++++++++++++++++
.../ethernet/motorcomm/yt6801/yt6801_type.h | 961 ++++++
drivers/net/phy/motorcomm.c | 6 +
16 files changed, 4652 insertions(+), 4 deletions(-)
create mode 100644 drivers/net/ethernet/motorcomm/Kconfig
create mode 100644 drivers/net/ethernet/motorcomm/Makefile
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/Makefile
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.c
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_desc.h
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_main.c
create mode 100644 drivers/net/ethernet/motorcomm/yt6801/yt6801_type.h
--
2.34.1
1
14

[openeuler:OLK-6.6] BUILD REGRESSION 442ac780432f43fa8a38f46ec20260ff35d95ad5
by kernel test robot 11 May '25
by kernel test robot 11 May '25
11 May '25
tree/branch: https://gitee.com/openeuler/kernel.git OLK-6.6
branch HEAD: 442ac780432f43fa8a38f46ec20260ff35d95ad5 !16165 vmxnet3: Fix malformed packet sizing in vmxnet3_process_xdp
Error/Warning (recently discovered and may have been fixed):
https://lore.kernel.org/oe-kbuild-all/202504240137.L2xvmv1X-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504240638.PM73jDId-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504250828.wJjuSU89-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290703.q8lvsdB3-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290927.uassI0w9-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504291722.ZB4nQmaR-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504300433.T31occlR-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504300733.mAi3Indd-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505070025.y1C68ZCV-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505080526.qCQgtY7V-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505080910.94UlZrA0-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505100830.TI8oJiuj-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505101047.t5A72bmv-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505111315.WMDsDGlI-lkp@intel.com
block/blk-io-hierarchy/iodump.c:561:7: warning: no previous prototype for '__bio_stage_hierarchy_start' [-Wmissing-prototypes]
block/blk-io-hierarchy/iodump.c:561:7: warning: no previous prototype for function '__bio_stage_hierarchy_start' [-Wmissing-prototypes]
crypto/asymmetric_keys/pgp_library.c:189: warning: Excess function parameter '_data' description in 'pgp_parse_packets'
crypto/asymmetric_keys/pgp_library.c:189: warning: Excess function parameter '_datalen' description in 'pgp_parse_packets'
crypto/asymmetric_keys/pgp_library.c:189: warning: Function parameter or member 'data' not described in 'pgp_parse_packets'
crypto/asymmetric_keys/pgp_library.c:189: warning: Function parameter or member 'datalen' not described in 'pgp_parse_packets'
drivers/irqchip/irq-gic-v3.c:1517:6: warning: no previous prototype for 'is_gicv4p1' [-Wmissing-prototypes]
drivers/irqchip/irq-gic-v3.c:1517:6: warning: no previous prototype for function 'is_gicv4p1' [-Wmissing-prototypes]
drivers/irqchip/irq-gic-v3.c:1526:6: warning: no previous prototype for 'gic_dist_enable_ipiv' [-Wmissing-prototypes]
drivers/irqchip/irq-gic-v3.c:1526:6: warning: no previous prototype for function 'gic_dist_enable_ipiv' [-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/base/trace/sxe_trace.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb_nl.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debug.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:432:6: error: no previous prototype for function 'sxe_debugfs_entries_init' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:459:6: error: no previous prototype for function 'sxe_debugfs_entries_exit' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:465:6: error: no previous prototype for function 'sxe_debugfs_init' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:470:6: error: no previous prototype for function 'sxe_debugfs_exit' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c:2022:5: error: no previous prototype for function 'sxe_reg_test' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c:2644:5: error: no previous prototype for function 'sxe_phys_id_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_filter.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_cli.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_hdc.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:230:6: error: no previous prototype for function 'sxe_hw_no_snoop_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:262:6: error: no previous prototype for function 'sxe_hw_uc_addr_pool_del' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:283:5: error: no previous prototype for function 'sxe_hw_uc_addr_pool_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:337:5: error: no previous prototype for function 'sxe_hw_nic_reset' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:367:6: error: no previous prototype for function 'sxe_hw_pf_rst_done_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:735:5: error: no previous prototype for function 'sxe_hw_pending_irq_read_clear' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:740:6: error: no previous prototype for function 'sxe_hw_pending_irq_write_clear' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:745:5: error: no previous prototype for function 'sxe_hw_irq_cause_get' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:765:6: error: no previous prototype for function 'sxe_hw_ring_irq_auto_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:775:6: error: no previous prototype for function 'sxe_hw_irq_general_reg_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:780:5: error: no previous prototype for function 'sxe_hw_irq_general_reg_get' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:790:6: error: no previous prototype for function 'sxe_hw_event_irq_map' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:806:6: error: no previous prototype for function 'sxe_hw_ring_irq_map' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:823:6: error: no previous prototype for function 'sxe_hw_ring_irq_interval_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:838:6: error: no previous prototype for function 'sxe_hw_event_irq_auto_clear_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:843:6: error: no previous prototype for function 'sxe_hw_specific_irq_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:848:6: error: no previous prototype for function 'sxe_hw_specific_irq_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:876:6: error: no previous prototype for function 'sxe_hw_all_irq_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:994:5: error: no previous prototype for function 'sxe_hw_link_speed_get' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ipsec.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:136:5: error: no previous prototype for function 'sxe_msi_irq_init' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:182:6: error: no previous prototype for function 'sxe_disable_dcb' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:212:6: error: no previous prototype for function 'sxe_disable_rss' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:729:6: error: no previous prototype for function 'sxe_lsc_irq_handler' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:745:6: error: no previous prototype for function 'sxe_mailbox_irq_handler' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c:70:6: error: no previous prototype for function 'sxe_allow_inval_mac' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_monitor.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_phy.c:733:5: error: no previous prototype for function 'sxe_multispeed_sfp_link_configure' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ptp.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ring.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c:1431:6: error: no previous prototype for function 'sxe_headers_cleanup' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c:1569:6: error: no previous prototype for function 'sxe_rx_buffer_page_offset_update' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c:1552:6: error: no previous prototype for function 'sxe_set_vf_link_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c:766:6: error: variable 'ret' set but not used [-Werror,-Wunused-but-set-variable]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_xdp.c:410:6: error: no previous prototype for function 'sxe_txrx_ring_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/base/trace/sxe_trace.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_debug.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ethtool.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:160:6: error: no previous prototype for function 'sxevf_hw_stop' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:187:6: error: no previous prototype for function 'sxevf_msg_write' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:196:5: error: no previous prototype for function 'sxevf_msg_read' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:206:5: error: no previous prototype for function 'sxevf_mailbox_read' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:211:6: error: no previous prototype for function 'sxevf_mailbox_write' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:216:6: error: no previous prototype for function 'sxevf_pf_req_irq_trigger' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:221:6: error: no previous prototype for function 'sxevf_pf_ack_irq_trigger' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:226:6: error: no previous prototype for function 'sxevf_event_irq_map' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:240:6: error: no previous prototype for function 'sxevf_specific_irq_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:245:6: error: no previous prototype for function 'sxevf_irq_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:251:6: error: no previous prototype for function 'sxevf_irq_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:259:6: error: no previous prototype for function 'sxevf_hw_ring_irq_map' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:276:6: error: no previous prototype for function 'sxevf_ring_irq_interval_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:313:6: error: no previous prototype for function 'sxevf_hw_reset' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:324:5: error: no previous prototype for function 'sxevf_link_state_get' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:539:6: error: no previous prototype for function 'sxevf_tx_ring_switch' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:594:6: error: no previous prototype for function 'sxevf_rx_ring_switch' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:626:6: error: no previous prototype for function 'sxevf_rx_ring_desc_configure' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:640:6: error: no previous prototype for function 'sxevf_rx_rcv_ctl_configure' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ipsec.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:543:12: error: unused function 'sxevf_resume' [-Werror,-Wunused-function]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_monitor.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_msg.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ring.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_rx_proc.c:362:6: error: no previous prototype for function 'sxevf_rx_ring_buffers_alloc' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:127:5: error: no previous prototype for function 'sxevf_tx_ring_alloc' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:88:6: error: no previous prototype for function 'sxevf_tx_ring_free' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/yunsilicon/xsc/pci/sriov_sysfs.c:911:31: warning: unused variable 'vf_type_ib' [-Wunused-const-variable]
drivers/net/ethernet/yunsilicon/xsc/pci/xsc_lag.c:1128:21: warning: variable 'bond_dev' set but not used [-Wunused-but-set-variable]
drivers/vhost/vdpa.c:589:21: error: assignment to 'struct iommufd_ctx *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
drivers/vhost/vdpa.c:589:23: error: implicit declaration of function 'iommufd_ctx_from_fd'; did you mean 'iommufd_ctx_from_file'? [-Wimplicit-function-declaration]
include/linux/fortify-string.h:606:4: error: call to '__read_overflow2_field' declared with 'warning' attribute: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Werror,-Wattribute-warning]
include/linux/sched/signal.h: linux/kabi.h is included more than once.
include/trace/stages/init.h:2:23: warning: 'str__bonding__trace_system_name' defined but not used [-Wunused-const-variable=]
kismet: WARNING: unmet direct dependencies detected for ARM64_ERRATUM_845719 when selected by ARCH_MXC
kismet: WARNING: unmet direct dependencies detected for RESCTRL_FS when selected by ARM64_MPAM
Unverified Error/Warning (likely false positive, kindly check if interested):
drivers/net/ethernet/yunsilicon/xsc/net/xsc_eth_sysfs.c: linux/types.h is included more than once.
include/linux/gpio/driver.h: asm/bug.h is included more than once.
include/net/tcp.h: linux/kabi.h is included more than once.
Error/Warning ids grouped by kconfigs:
recent_errors
|-- arm64-allmodconfig
| |-- block-blk-io-hierarchy-iodump.c:warning:no-previous-prototype-for-function-__bio_stage_hierarchy_start
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_data-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_datalen-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-data-not-described-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-datalen-not-described-in-pgp_parse_packets
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-gic_dist_enable_ipiv
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-is_gicv4p1
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-mucse-rnp-rnp_mbx_fw.c:warning:Cannot-understand-force_free:
| |-- drivers-net-ethernet-yunsilicon-xsc-pci-sriov_sysfs.c:warning:unused-variable-vf_type_ib
| |-- drivers-net-ethernet-yunsilicon-xsc-pci-xsc_lag.c:warning:variable-bond_dev-set-but-not-used
| `-- include-linux-fortify-string.h:error:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()-Werror-Wattribute-warnin
|-- arm64-allnoconfig
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-gic_dist_enable_ipiv
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-is_gicv4p1
| |-- kismet:WARNING:unmet-direct-dependencies-detected-for-ARM64_ERRATUM_845719-when-selected-by-ARCH_MXC
| `-- kismet:WARNING:unmet-direct-dependencies-detected-for-RESCTRL_FS-when-selected-by-ARM64_MPAM
|-- arm64-defconfig
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-gic_dist_enable_ipiv
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-is_gicv4p1
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- arm64-randconfig-001-20250511
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-gic_dist_enable_ipiv
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-is_gicv4p1
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:error:unused-function-sxevf_resume-Werror-Wunused-function
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- arm64-randconfig-002-20250511
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-gic_dist_enable_ipiv
| `-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-is_gicv4p1
|-- arm64-randconfig-003-20250511
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-gic_dist_enable_ipiv
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-is_gicv4p1
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- arm64-randconfig-004-20250511
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-gic_dist_enable_ipiv
| `-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-is_gicv4p1
|-- loongarch-allmodconfig
| |-- block-blk-io-hierarchy-iodump.c:warning:no-previous-prototype-for-__bio_stage_hierarchy_start
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_data-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_datalen-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-data-not-described-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-datalen-not-described-in-pgp_parse_packets
| |-- drivers-net-ethernet-mucse-rnp-rnp_mbx_fw.c:warning:Cannot-understand-force_free:
| `-- include-trace-stages-init.h:warning:str__bonding__trace_system_name-defined-but-not-used
|-- loongarch-allyesconfig
| |-- block-blk-io-hierarchy-iodump.c:warning:no-previous-prototype-for-__bio_stage_hierarchy_start
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_data-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_datalen-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-data-not-described-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-datalen-not-described-in-pgp_parse_packets
| |-- drivers-net-ethernet-mucse-rnp-rnp_mbx_fw.c:warning:Cannot-understand-force_free:
| `-- include-trace-stages-init.h:warning:str__bonding__trace_system_name-defined-but-not-used
|-- loongarch-randconfig-001-20250511
| |-- drivers-vhost-vdpa.c:error:assignment-to-struct-iommufd_ctx-from-int-makes-pointer-from-integer-without-a-cast
| `-- drivers-vhost-vdpa.c:error:implicit-declaration-of-function-iommufd_ctx_from_fd
|-- x86_64-allnoconfig
| |-- drivers-net-ethernet-yunsilicon-xsc-net-xsc_eth_sysfs.c:linux-types.h-is-included-more-than-once.
| |-- include-linux-gpio-driver.h:asm-bug.h-is-included-more-than-once.
| |-- include-linux-sched-signal.h:linux-kabi.h-is-included-more-than-once.
| `-- include-net-tcp.h:linux-kabi.h-is-included-more-than-once.
|-- x86_64-allyesconfig
| |-- block-blk-io-hierarchy-iodump.c:warning:no-previous-prototype-for-function-__bio_stage_hierarchy_start
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_data-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_datalen-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-data-not-described-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-datalen-not-described-in-pgp_parse_packets
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-mucse-rnp-rnp_mbx_fw.c:warning:Cannot-understand-force_free:
| |-- drivers-net-ethernet-yunsilicon-xsc-pci-sriov_sysfs.c:warning:unused-variable-vf_type_ib
| |-- drivers-net-ethernet-yunsilicon-xsc-pci-xsc_lag.c:warning:variable-bond_dev-set-but-not-used
| `-- include-linux-fortify-string.h:error:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()-Werror-Wattribute-warnin
|-- x86_64-defconfig
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- x86_64-randconfig-161-20250511
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| `-- include-linux-fortify-string.h:error:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()-Werror-Wattribute-warnin
|-- x86_64-randconfig-r052-20250511
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
`-- x86_64-rhel-9.4-rust
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
`-- include-linux-fortify-string.h:error:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()-Werror-Wattribute-warnin
elapsed time: 724m
configs tested: 22
configs skipped: 123
tested configs:
arm64 allmodconfig clang-19
arm64 allnoconfig gcc-14.2.0
arm64 defconfig gcc-14.2.0
arm64 randconfig-001-20250511 clang-21
arm64 randconfig-002-20250511 clang-21
arm64 randconfig-003-20250511 clang-21
arm64 randconfig-004-20250511 clang-21
loongarch allmodconfig gcc-14.2.0
loongarch allnoconfig gcc-14.2.0
loongarch defconfig gcc-14.2.0
loongarch randconfig-001-20250511 gcc-14.2.0
loongarch randconfig-002-20250511 gcc-14.2.0
x86_64 allnoconfig clang-20
x86_64 allyesconfig clang-20
x86_64 buildonly-randconfig-001-20250511 clang-20
x86_64 buildonly-randconfig-002-20250511 clang-20
x86_64 buildonly-randconfig-003-20250511 clang-20
x86_64 buildonly-randconfig-004-20250511 clang-20
x86_64 buildonly-randconfig-005-20250511 gcc-12
x86_64 buildonly-randconfig-006-20250511 clang-20
x86_64 defconfig gcc-11
x86_64 rhel-9.4-rust clang-18
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-6.6 2219/2219] drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:543:12: error: unused function 'sxevf_resume'
by kernel test robot 11 May '25
by kernel test robot 11 May '25
11 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: 442ac780432f43fa8a38f46ec20260ff35d95ad5
commit: 0ba0ebb029b99864fa5963024535f48299373354 [2219/2219] !15589 [OLK-6.6] Ethernet: Supports Linkdata ethernet Controllers
config: arm64-randconfig-001-20250511 (https://download.01.org/0day-ci/archive/20250511/202505111315.WMDsDGlI-lkp@…)
compiler: clang version 21.0.0git (https://github.com/llvm/llvm-project f819f46284f2a79790038e1f6649172789734ae8)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250511/202505111315.WMDsDGlI-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505111315.WMDsDGlI-lkp@intel.com/
All errors (new ones prefixed by >>):
>> drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:543:12: error: unused function 'sxevf_resume' [-Werror,-Wunused-function]
543 | static s32 sxevf_resume(struct device *dev)
| ^~~~~~~~~~~~
1 error generated.
Kconfig warnings: (for reference only)
WARNING: unmet direct dependencies detected for HALTPOLL_CPUIDLE
Depends on [n]: CPU_IDLE [=n] && ARCH_CPUIDLE_HALTPOLL [=y] && ARCH_HAS_OPTIMIZED_POLL [=y]
Selected by [y]:
- ARM64 [=y]
vim +/sxevf_resume +543 drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c
dd013ad487534c liujie_answer 2025-04-15 541
dd013ad487534c liujie_answer 2025-04-15 542 #ifdef CONFIG_PM
dd013ad487534c liujie_answer 2025-04-15 @543 static s32 sxevf_resume(struct device *dev)
dd013ad487534c liujie_answer 2025-04-15 544 {
dd013ad487534c liujie_answer 2025-04-15 545 struct pci_dev *pdev = to_pci_dev(dev);
dd013ad487534c liujie_answer 2025-04-15 546 struct sxevf_adapter *adapter = pci_get_drvdata(pdev);
dd013ad487534c liujie_answer 2025-04-15 547 struct net_device *netdev = adapter->netdev;
dd013ad487534c liujie_answer 2025-04-15 548 s32 ret;
dd013ad487534c liujie_answer 2025-04-15 549
dd013ad487534c liujie_answer 2025-04-15 550 pci_restore_state(pdev);
dd013ad487534c liujie_answer 2025-04-15 551 pci_save_state(pdev);
dd013ad487534c liujie_answer 2025-04-15 552
dd013ad487534c liujie_answer 2025-04-15 553 ret = pci_enable_device_mem(pdev);
dd013ad487534c liujie_answer 2025-04-15 554 if (ret) {
dd013ad487534c liujie_answer 2025-04-15 555 LOG_DEV_ERR("enable pci device from suspend fail.(err:%d)", ret);
dd013ad487534c liujie_answer 2025-04-15 556 goto l_end;
dd013ad487534c liujie_answer 2025-04-15 557 }
dd013ad487534c liujie_answer 2025-04-15 558
dd013ad487534c liujie_answer 2025-04-15 559 /* in order to force CPU ordering */
dd013ad487534c liujie_answer 2025-04-15 560 smp_mb__before_atomic();
dd013ad487534c liujie_answer 2025-04-15 561 clear_bit(SXEVF_DISABLED, &adapter->state);
dd013ad487534c liujie_answer 2025-04-15 562 pci_set_master(pdev);
dd013ad487534c liujie_answer 2025-04-15 563 sxevf_reset(adapter);
dd013ad487534c liujie_answer 2025-04-15 564
dd013ad487534c liujie_answer 2025-04-15 565 rtnl_lock();
dd013ad487534c liujie_answer 2025-04-15 566 sxevf_ring_num_set(adapter);
dd013ad487534c liujie_answer 2025-04-15 567 ret = sxevf_irq_ctxt_init(adapter);
dd013ad487534c liujie_answer 2025-04-15 568 if (!ret && netif_running(netdev))
dd013ad487534c liujie_answer 2025-04-15 569 ret = sxevf_open(netdev);
dd013ad487534c liujie_answer 2025-04-15 570 rtnl_unlock();
dd013ad487534c liujie_answer 2025-04-15 571
dd013ad487534c liujie_answer 2025-04-15 572 if (ret) {
dd013ad487534c liujie_answer 2025-04-15 573 LOG_ERROR_BDF("pci device resume fail.(err:%d)\n", ret);
dd013ad487534c liujie_answer 2025-04-15 574 goto l_end;
dd013ad487534c liujie_answer 2025-04-15 575 }
dd013ad487534c liujie_answer 2025-04-15 576
dd013ad487534c liujie_answer 2025-04-15 577 netif_device_attach(netdev);
dd013ad487534c liujie_answer 2025-04-15 578
dd013ad487534c liujie_answer 2025-04-15 579 l_end:
dd013ad487534c liujie_answer 2025-04-15 580 return ret;
dd013ad487534c liujie_answer 2025-04-15 581 }
dd013ad487534c liujie_answer 2025-04-15 582 #endif
dd013ad487534c liujie_answer 2025-04-15 583
:::::: The code at line 543 was first introduced by commit
:::::: dd013ad487534c1838afc2f55efdb5daec15aace Ethernet: Linkdata: Supports Linkdata ethernet Controllers
:::::: TO: liujie_answer <liujie5(a)linkdatatechnology.com>
:::::: CC: liujie_answer <liujie5(a)linkdatatechnology.com>
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:openEuler-1.0-LTS 1627/1627] drivers/i2c/busses/i2c-owl.o: warning: objtool: missing symbol for section .exit.text
by kernel test robot 11 May '25
by kernel test robot 11 May '25
11 May '25
tree: https://gitee.com/openeuler/kernel.git openEuler-1.0-LTS
head: 191661de6f001a77246c2d23ec77d8d23fe4114a
commit: d211e62af46693f90f6386085817e22239e3fe79 [1627/1627] i2c: Add Actions Semiconductor Owl family S900 I2C driver
config: x86_64-buildonly-randconfig-005-20250510 (https://download.01.org/0day-ci/archive/20250511/202505110553.bsdHvTXR-lkp@…)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250511/202505110553.bsdHvTXR-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505110553.bsdHvTXR-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from drivers/i2c/busses/i2c-owl.c:17:
include/linux/module.h:138:14: warning: 'cleanup_module' specifies less restrictive attribute than its target 'owl_i2c_driver_exit': 'cold' [-Wmissing-attributes]
138 | void cleanup_module(void) __attribute__((alias(#exitfn)));
| ^~~~~~~~~~~~~~
include/linux/device.h:1558:1: note: in expansion of macro 'module_exit'
1558 | module_exit(__driver##_exit);
| ^~~~~~~~~~~
include/linux/platform_device.h:228:9: note: in expansion of macro 'module_driver'
228 | module_driver(__platform_driver, platform_driver_register, \
| ^~~~~~~~~~~~~
drivers/i2c/busses/i2c-owl.c:490:1: note: in expansion of macro 'module_platform_driver'
490 | module_platform_driver(owl_i2c_driver);
| ^~~~~~~~~~~~~~~~~~~~~~
In file included from include/linux/i2c.h:30,
from drivers/i2c/busses/i2c-owl.c:14:
drivers/i2c/busses/i2c-owl.c:490:24: note: 'cleanup_module' target declared here
490 | module_platform_driver(owl_i2c_driver);
| ^~~~~~~~~~~~~~
include/linux/device.h:1554:20: note: in definition of macro 'module_driver'
1554 | static void __exit __driver##_exit(void) \
| ^~~~~~~~
drivers/i2c/busses/i2c-owl.c:490:1: note: in expansion of macro 'module_platform_driver'
490 | module_platform_driver(owl_i2c_driver);
| ^~~~~~~~~~~~~~~~~~~~~~
include/linux/module.h:132:13: warning: 'init_module' specifies less restrictive attribute than its target 'owl_i2c_driver_init': 'cold' [-Wmissing-attributes]
132 | int init_module(void) __attribute__((alias(#initfn)));
| ^~~~~~~~~~~
include/linux/device.h:1553:1: note: in expansion of macro 'module_init'
1553 | module_init(__driver##_init); \
| ^~~~~~~~~~~
include/linux/platform_device.h:228:9: note: in expansion of macro 'module_driver'
228 | module_driver(__platform_driver, platform_driver_register, \
| ^~~~~~~~~~~~~
drivers/i2c/busses/i2c-owl.c:490:1: note: in expansion of macro 'module_platform_driver'
490 | module_platform_driver(owl_i2c_driver);
| ^~~~~~~~~~~~~~~~~~~~~~
drivers/i2c/busses/i2c-owl.c:490:24: note: 'init_module' target declared here
490 | module_platform_driver(owl_i2c_driver);
| ^~~~~~~~~~~~~~
include/linux/device.h:1549:19: note: in definition of macro 'module_driver'
1549 | static int __init __driver##_init(void) \
| ^~~~~~~~
drivers/i2c/busses/i2c-owl.c:490:1: note: in expansion of macro 'module_platform_driver'
490 | module_platform_driver(owl_i2c_driver);
| ^~~~~~~~~~~~~~~~~~~~~~
>> drivers/i2c/busses/i2c-owl.o: warning: objtool: missing symbol for section .exit.text
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:openEuler-1.0-LTS] BUILD REGRESSION 191661de6f001a77246c2d23ec77d8d23fe4114a
by kernel test robot 11 May '25
by kernel test robot 11 May '25
11 May '25
tree/branch: https://gitee.com/openeuler/kernel.git openEuler-1.0-LTS
branch HEAD: 191661de6f001a77246c2d23ec77d8d23fe4114a !16175 Fix CVE-2022-49915
Error/Warning (recently discovered and may have been fixed):
https://lore.kernel.org/oe-kbuild-all/202504180904.aJTbSHsO-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504250657.SBZLGq3K-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504250827.FCNrED1Z-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504250942.HWyvS6HD-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504251109.LNg7C0pb-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504251357.XH0GnYXx-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290542.wZ43d7od-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290604.Y62ysEZs-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290804.SFjtS4nf-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290808.iYcj1P8f-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504291102.S4UEqzyV-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504291551.FOwjwu8e-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505070314.0zdCBK7T-lkp@intel.com
arch/x86/kernel/apic/io_apic.o: warning: objtool: acpi_get_override_irq()+0xfe: can't find switch jump table
block/bio-integrity.c:41:6: warning: no previous prototype for '__bio_integrity_free' [-Wmissing-prototypes]
block/bio-integrity.c:41:6: warning: no previous prototype for function '__bio_integrity_free' [-Wmissing-prototypes]
block/blk-iolatency.c:308:14: warning: variable 'changed' set but not used [-Wunused-but-set-variable]
block/blk-iolatency.c:308:7: warning: variable 'changed' set but not used [-Wunused-but-set-variable]
block/blk-iolatency.c:800:24: warning: variable 'blkiolat' set but not used [-Wunused-but-set-variable]
block/blk-iolatency.c:800:31: warning: variable 'blkiolat' set but not used [-Wunused-but-set-variable]
block/blk-merge.c:696:16: warning: no previous prototype for 'blk_try_req_merge' [-Wmissing-prototypes]
block/blk-mq-sched.c:220:5: warning: no previous prototype for '__blk_mq_sched_dispatch_requests' [-Wmissing-prototypes]
block/blk-mq-sched.c:220:5: warning: no previous prototype for function '__blk_mq_sched_dispatch_requests' [-Wmissing-prototypes]
block/blk-wbt.c:674:6: warning: no previous prototype for 'wbt_issue' [-Wmissing-prototypes]
block/blk-wbt.c:674:6: warning: no previous prototype for function 'wbt_issue' [-Wmissing-prototypes]
block/blk-wbt.c:694:6: warning: no previous prototype for 'wbt_requeue' [-Wmissing-prototypes]
block/blk-wbt.c:694:6: warning: no previous prototype for function 'wbt_requeue' [-Wmissing-prototypes]
block/genhd.c:533: warning: Function parameter or member 'devt' not described in 'blk_invalidate_devt'
block/genhd.c:642:5: warning: no previous prototype for 'disk_scan_partitions' [-Wmissing-prototypes]
block/genhd.c:642:5: warning: no previous prototype for function 'disk_scan_partitions' [-Wmissing-prototypes]
crypto/blowfish_generic.o: warning: objtool: missing symbol for section .exit.text
crypto/chacha20poly1305.o: warning: objtool: missing symbol for section .exit.text
crypto/crc32_generic.o: warning: objtool: missing symbol for section .exit.text
crypto/crc32c_generic.o: warning: objtool: missing symbol for section .exit.text
crypto/echainiv.o: warning: objtool: missing symbol for section .exit.text
crypto/fcrypt.o: warning: objtool: missing symbol for section .exit.text
crypto/lz4hc.o: warning: objtool: missing symbol for section .exit.text
crypto/lzo.o: warning: objtool: missing symbol for section .exit.text
crypto/md4.o: warning: objtool: missing symbol for section .exit.text
crypto/md5.o: warning: objtool: missing symbol for section .exit.text
crypto/poly1305_generic.o: warning: objtool: missing symbol for section .exit.text
crypto/sm4_generic.o: warning: objtool: missing symbol for section .text
crypto/tcrypt.o: warning: objtool: missing symbol for section .exit.text
drivers/char/hw_random/timeriomem-rng.o: warning: objtool: missing symbol for section .exit.text
drivers/char/tpm/tpm-interface.o: warning: objtool: missing symbol for section .exit.text
drivers/char/tpm/tpm_i2c_atmel.o: warning: objtool: missing symbol for section .exit.text
drivers/clk/clk-pwm.o: warning: objtool: missing symbol for section .exit.text
drivers/cpufreq/cpufreq_userspace.o: warning: objtool: missing symbol for section .exit.text
drivers/crypto/atmel-aes.o: warning: objtool: missing symbol for section .exit.text
drivers/crypto/atmel-sha.o: warning: objtool: missing symbol for section .exit.text
drivers/firmware/edd.o: warning: objtool: missing symbol for section .exit.text
drivers/firmware/scpi_pm_domain.o: warning: objtool: missing symbol for section .exit.text
drivers/gpio/gpio-clps711x.o: warning: objtool: missing symbol for section .exit.text
drivers/hwmon/lm95245.o: warning: objtool: missing symbol for section .exit.text
drivers/i2c/busses/i2c-rcar.o: warning: objtool: missing symbol for section .exit.text
drivers/i2c/busses/i2c-simtec.o: warning: objtool: missing symbol for section .exit.text
drivers/input/mouse/sermouse.o: warning: objtool: missing symbol for section .exit.text
drivers/leds/leds-lp8788.o: warning: objtool: missing symbol for section .exit.text
drivers/leds/leds-lt3593.o: warning: objtool: missing symbol for section .exit.text
drivers/leds/leds-wm8350.o: warning: objtool: missing symbol for section .exit.text
drivers/leds/trigger/ledtrig-transient.o: warning: objtool: missing symbol for section .exit.text
drivers/media/rc/gpio-ir-tx.o: warning: objtool: missing symbol for section .exit.text
drivers/mfd/rt5033.o: warning: objtool: missing symbol for section .exit.text
drivers/net/ethernet/mscc/ocelot_io.o: warning: objtool: missing symbol for section .text
drivers/power/supply/bq24735-charger.o: warning: objtool: missing symbol for section .exit.text
drivers/pwm/pwm-img.o: warning: objtool: missing symbol for section .exit.text
drivers/pwm/pwm-lpss-pci.o: warning: objtool: missing symbol for section .exit.text
drivers/pwm/pwm-renesas-tpu.o: warning: objtool: missing symbol for section .exit.text
drivers/rtc/rtc-lp8788.o: warning: objtool: missing symbol for section .exit.text
drivers/rtc/rtc-xgene.o: warning: objtool: missing symbol for section .exit.text
drivers/thermal/rockchip_thermal.o: warning: objtool: missing symbol for section .exit.text
drivers/tty/serial/fsl_lpuart.o: warning: objtool: missing symbol for section .exit.text
drivers/tty/serial/timbuart.o: warning: objtool: missing symbol for section .exit.text
fs/cramfs/inode.o: warning: objtool: missing symbol for section .exit.text
fs/nls/mac-gaelic.o: warning: objtool: missing symbol for section .exit.text
fs/nls/nls_cp932.o: warning: objtool: missing symbol for section .exit.text
fs/nls/nls_euc-jp.o: warning: objtool: missing symbol for section .exit.text
include/linux/device.h:1509:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
include/linux/device.h:1513:2: warning: this statement may fall through [-Wimplicit-fallthrough=]
include/linux/device.h:1513:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
include/linux/device.h:1530:12: warning: this statement may fall through [-Wimplicit-fallthrough=]
include/linux/filter.h:787:10: warning: cast between incompatible function types from 'u64 (*)(u64, u64, u64, u64, u64)' {aka 'long long unsigned int (*)(long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int)'} to 'u64 (*)(u64, u64, u64, u64, u64, const struct bpf_insn *)' {aka 'long long unsigned int (*)(long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int, const struct bpf_insn *)'} [-Wcast-function-type]
include/linux/ktask.h:123:35: warning: cast between incompatible function types from 'int (*)(long unsigned int, long unsigned int, struct cgp_args *)' to 'int (*)(void *, void *, void *)' [-Wcast-function-type]
include/linux/ktask.h:123:35: warning: cast between incompatible function types from 'int (*)(long unsigned int, long unsigned int, struct deferred_args *)' to 'int (*)(void *, void *, void *)' [-Wcast-function-type]
include/linux/ktask.h:123:35: warning: cast between incompatible function types from 'int (*)(long unsigned int, long unsigned int, struct hf_args *)' to 'int (*)(void *, void *, void *)' [-Wcast-function-type]
include/linux/ktask.h:123:35: warning: cast between incompatible function types from 'int (*)(long unsigned int, long unsigned int, struct vfio_pin_args *)' to 'int (*)(void *, void *, void *)' [-Wcast-function-type]
include/linux/ktask.h:163:32: warning: cast between incompatible function types from 'void (*)(long unsigned int, long unsigned int, struct vfio_pin_args *)' to 'void (*)(void *, void *, void *)' [-Wcast-function-type]
include/linux/mempolicy.h:329:13: warning: '__do_mbind' defined but not used [-Wunused-function]
include/linux/skbuff.h:3551:17: warning: this statement may fall through [-Wimplicit-fallthrough=]
include/linux/skbuff.h:3551:24: warning: this statement may fall through [-Wimplicit-fallthrough=]
include/linux/string.h:249:16: warning: '__builtin_strncpy' accessing 80 bytes at offsets 100 and 36 may overlap up to 0 bytes at offset [9223372036854775807, -9223372036854775808] [-Wrestrict]
include/trace/trace_events.h:26:23: warning: 'str__fs__trace_system_name' defined but not used [-Wunused-const-variable=]
mm/mmu_gather.o: warning: objtool: missing symbol for section .text
mm/sparse.o: warning: objtool: missing symbol for section .meminit.text
samples/configfs/configfs_sample.o: warning: objtool: missing symbol for section .exit.text
samples/hw_breakpoint/data_breakpoint.o: warning: objtool: missing symbol for section .exit.text
samples/kobject/kobject-example.o: warning: objtool: missing symbol for section .exit.text
samples/kobject/kset-example.o: warning: objtool: missing symbol for section .exit.text
samples/rpmsg/rpmsg_client_sample.o: warning: objtool: missing symbol for section .exit.text
Unverified Error/Warning (likely false positive, kindly check if interested):
crypto/jitterentropy.c:204: warning: Function parameter or member 'ec' not described in 'jent_fold_time'
crypto/jitterentropy.c:204: warning: Function parameter or member 'folded' not described in 'jent_fold_time'
crypto/jitterentropy.c:204: warning: Function parameter or member 'loop_cnt' not described in 'jent_fold_time'
crypto/jitterentropy.c:204: warning: Function parameter or member 'time' not described in 'jent_fold_time'
crypto/jitterentropy.c:390: warning: Function parameter or member 'entropy_collector' not described in 'jent_unbiased_bit'
crypto/jitterentropy.c:422: warning: Function parameter or member 'entropy_collector' not described in 'jent_stir_pool'
kernel/sched/debug.o: warning: objtool: missing symbol for section .text.unlikely.
Error/Warning ids grouped by kconfigs:
recent_errors
|-- arm64-allmodconfig
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-__bio_integrity_free
| |-- block-blk-iolatency.c:warning:variable-blkiolat-set-but-not-used
| |-- block-blk-iolatency.c:warning:variable-changed-set-but-not-used
| |-- block-blk-merge.c:warning:no-previous-prototype-for-blk_try_req_merge
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-__blk_mq_sched_dispatch_requests
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-wbt_issue
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-wbt_requeue
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- include-asm-generic-bitops-non-atomic.h:warning:array-subscript-long-unsigned-int-is-partly-outside-array-bounds-of-u32-aka-unsigned-int
| |-- include-linux-device.h:warning:this-statement-may-fall-through
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-cgp_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-deferred_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-hf_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-vfio_pin_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-void-(-)(long-unsigned-int-long-unsigned-int-struct-vfio_pin_args-)-to-void-(-)(void-void-void-)
| |-- include-linux-skbuff.h:warning:this-statement-may-fall-through
| |-- include-linux-string.h:warning:__builtin_strncpy-accessing-bytes-at-offsets-and-may-overlap-up-to-bytes-at-offset
| |-- include-linux-thread_info.h:warning:b-may-be-used-uninitialized
| `-- include-trace-trace_events.h:warning:str__fs__trace_system_name-defined-but-not-used
|-- arm64-allnoconfig
| `-- include-linux-mempolicy.h:warning:__do_mbind-defined-but-not-used
|-- arm64-randconfig-001-20250510
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- include-linux-device.h:warning:this-statement-may-fall-through
| `-- include-trace-trace_events.h:warning:str__fs__trace_system_name-defined-but-not-used
|-- arm64-randconfig-003-20250510
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-__bio_integrity_free
| |-- block-blk-merge.c:warning:no-previous-prototype-for-blk_try_req_merge
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-__blk_mq_sched_dispatch_requests
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- include-linux-filter.h:warning:cast-between-incompatible-function-types-from-u64-(-)(u64-u64-u64-u64-u64)-aka-long-long-unsigned-int-(-)(long-long-unsigned-int-long-long-unsigned-int-long-long-unsigne
| `-- include-linux-skbuff.h:warning:this-statement-may-fall-through
|-- arm64-randconfig-004-20250510
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- include-linux-mempolicy.h:warning:__do_mbind-defined-but-not-used
| |-- include-linux-skbuff.h:warning:this-statement-may-fall-through
| `-- include-trace-trace_events.h:warning:str__fs__trace_system_name-defined-but-not-used
|-- x86_64-allnoconfig
| |-- mm-mmu_gather.o:warning:objtool:missing-symbol-for-section-.text
| `-- mm-vmscan.c:error:implicit-declaration-of-function-kernel_swap_enabled-Werror-Wimplicit-function-declaration
|-- x86_64-allyesconfig
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-function-__bio_integrity_free
| |-- block-blk-iolatency.c:warning:variable-blkiolat-set-but-not-used
| |-- block-blk-iolatency.c:warning:variable-changed-set-but-not-used
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-function-__blk_mq_sched_dispatch_requests
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-function-wbt_issue
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-function-wbt_requeue
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-function-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| `-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
|-- x86_64-buildonly-randconfig-001-20250510
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-function-__bio_integrity_free
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-function-__blk_mq_sched_dispatch_requests
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-function-wbt_issue
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-function-wbt_requeue
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-function-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| `-- mm-vmscan.c:error:implicit-declaration-of-function-kernel_swap_enabled-Werror-Wimplicit-function-declaration
|-- x86_64-buildonly-randconfig-002-20250510
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-function-__blk_mq_sched_dispatch_requests
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-function-wbt_issue
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-function-wbt_requeue
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-function-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- crypto-sm4_generic.o:warning:objtool:missing-symbol-for-section-.text
| `-- kernel-sched-debug.o:warning:objtool:missing-symbol-for-section-.text.unlikely.
|-- x86_64-buildonly-randconfig-003-20250510
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-__bio_integrity_free
| |-- block-blk-merge.c:warning:no-previous-prototype-for-blk_try_req_merge
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-__blk_mq_sched_dispatch_requests
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-wbt_issue
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-wbt_requeue
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- crypto-sm4_generic.o:warning:objtool:missing-symbol-for-section-.text
| |-- drivers-net-ethernet-mscc-ocelot_io.o:warning:objtool:missing-symbol-for-section-.text
| |-- include-linux-device.h:warning:this-statement-may-fall-through
| |-- include-linux-filter.h:warning:cast-between-incompatible-function-types-from-u64-(-)(u64-u64-u64-u64-u64)-aka-long-long-unsigned-int-(-)(long-long-unsigned-int-long-long-unsigned-int-long-long-unsigne
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-cgp_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-hf_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-skbuff.h:warning:this-statement-may-fall-through
| `-- include-trace-trace_events.h:warning:str__fs__trace_system_name-defined-but-not-used
|-- x86_64-buildonly-randconfig-004-20250510
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-__bio_integrity_free
| |-- block-blk-merge.c:warning:no-previous-prototype-for-blk_try_req_merge
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-__blk_mq_sched_dispatch_requests
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-wbt_issue
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-wbt_requeue
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- include-linux-device.h:warning:this-statement-may-fall-through
| |-- include-linux-filter.h:warning:cast-between-incompatible-function-types-from-u64-(-)(u64-u64-u64-u64-u64)-aka-long-long-unsigned-int-(-)(long-long-unsigned-int-long-long-unsigned-int-long-long-unsigne
| |-- include-linux-mempolicy.h:warning:__do_mbind-defined-but-not-used
| |-- include-linux-skbuff.h:warning:this-statement-may-fall-through
| `-- include-trace-trace_events.h:warning:str__fs__trace_system_name-defined-but-not-used
|-- x86_64-buildonly-randconfig-005-20250510
| |-- crypto-blowfish_generic.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- crypto-chacha20poly1305.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- crypto-crc32_generic.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- crypto-crc32c_generic.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- crypto-echainiv.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- crypto-fcrypt.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- crypto-lz4hc.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- crypto-lzo.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- crypto-md4.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- crypto-md5.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- crypto-poly1305_generic.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- crypto-tcrypt.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-char-hw_random-timeriomem-rng.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-char-tpm-tpm-interface.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-char-tpm-tpm_i2c_atmel.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-clk-clk-pwm.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-cpufreq-cpufreq_userspace.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-crypto-atmel-aes.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-crypto-atmel-sha.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-firmware-edd.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-firmware-scpi_pm_domain.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-gpio-gpio-clps711x.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-hwmon-lm95245.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-i2c-busses-i2c-rcar.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-i2c-busses-i2c-simtec.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-input-mouse-sermouse.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-leds-leds-lp8788.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-leds-leds-lt3593.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-leds-leds-wm8350.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-leds-trigger-ledtrig-transient.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-media-rc-gpio-ir-tx.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-mfd-rt5033.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-power-supply-bq24735-charger.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-pwm-pwm-img.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-pwm-pwm-lpss-pci.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-pwm-pwm-renesas-tpu.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-rtc-rtc-lp8788.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-rtc-rtc-xgene.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-thermal-rockchip_thermal.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-tty-serial-fsl_lpuart.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- drivers-tty-serial-timbuart.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- fs-cramfs-inode.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- fs-nls-mac-gaelic.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- fs-nls-nls_cp932.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- fs-nls-nls_euc-jp.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- include-linux-filter.h:warning:cast-between-incompatible-function-types-from-u64-(-)(u64-u64-u64-u64-u64)-aka-long-long-unsigned-int-(-)(long-long-unsigned-int-long-long-unsigned-int-long-long-unsigne
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-cgp_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-deferred_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-hf_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-mempolicy.h:warning:__do_mbind-defined-but-not-used
| |-- include-trace-trace_events.h:warning:str__fs__trace_system_name-defined-but-not-used
| |-- mm-sparse.o:warning:objtool:missing-symbol-for-section-.meminit.text
| |-- samples-configfs-configfs_sample.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- samples-hw_breakpoint-data_breakpoint.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- samples-kobject-kobject-example.o:warning:objtool:missing-symbol-for-section-.exit.text
| |-- samples-kobject-kset-example.o:warning:objtool:missing-symbol-for-section-.exit.text
| `-- samples-rpmsg-rpmsg_client_sample.o:warning:objtool:missing-symbol-for-section-.exit.text
|-- x86_64-buildonly-randconfig-006-20250510
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-function-__blk_mq_sched_dispatch_requests
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-function-wbt_issue
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-function-wbt_requeue
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-function-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- kernel-sched-debug.o:warning:objtool:missing-symbol-for-section-.text.unlikely.
| `-- mm-vmscan.c:error:implicit-declaration-of-function-kernel_swap_enabled-Werror-Wimplicit-function-declaration
|-- x86_64-defconfig
| |-- block-blk-merge.c:warning:no-previous-prototype-for-blk_try_req_merge
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-__blk_mq_sched_dispatch_requests
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- include-linux-filter.h:warning:cast-between-incompatible-function-types-from-u64-(-)(u64-u64-u64-u64-u64)-aka-long-long-unsigned-int-(-)(long-long-unsigned-int-long-long-unsigned-int-long-long-unsigne
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-cgp_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-hf_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-skbuff.h:warning:this-statement-may-fall-through
| `-- include-trace-trace_events.h:warning:str__fs__trace_system_name-defined-but-not-used
|-- x86_64-randconfig-161-20250510
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-__bio_integrity_free
| |-- block-blk-merge.c:warning:no-previous-prototype-for-blk_try_req_merge
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-__blk_mq_sched_dispatch_requests
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-wbt_issue
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-wbt_requeue
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- include-linux-device.h:warning:this-statement-may-fall-through
| |-- include-linux-filter.h:warning:cast-between-incompatible-function-types-from-u64-(-)(u64-u64-u64-u64-u64)-aka-long-long-unsigned-int-(-)(long-long-unsigned-int-long-long-unsigned-int-long-long-unsigne
| |-- include-linux-skbuff.h:warning:this-statement-may-fall-through
| `-- include-trace-trace_events.h:warning:str__fs__trace_system_name-defined-but-not-used
`-- x86_64-rhel-9.4-rust
|-- arch-x86-kernel-apic-io_apic.o:warning:objtool:acpi_get_override_irq:can-t-find-switch-jump-table
|-- block-bio-integrity.c:warning:no-previous-prototype-for-function-__bio_integrity_free
|-- block-blk-iolatency.c:warning:variable-blkiolat-set-but-not-used
|-- block-blk-iolatency.c:warning:variable-changed-set-but-not-used
|-- block-blk-mq-sched.c:warning:no-previous-prototype-for-function-__blk_mq_sched_dispatch_requests
|-- block-blk-wbt.c:warning:no-previous-prototype-for-function-wbt_issue
|-- block-blk-wbt.c:warning:no-previous-prototype-for-function-wbt_requeue
|-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
|-- block-genhd.c:warning:no-previous-prototype-for-function-disk_scan_partitions
|-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
|-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
|-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
|-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
|-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
|-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
`-- mm-hugetlb.c:warning:no-previous-prototype-for-function-free_huge_page_to_dhugetlb_pool
elapsed time: 725m
configs tested: 16
configs skipped: 108
tested configs:
arm64 allmodconfig gcc-14.2.0
arm64 allnoconfig gcc-14.2.0
arm64 randconfig-001-20250510 gcc-7.5.0
arm64 randconfig-002-20250510 gcc-5.5.0
arm64 randconfig-003-20250510 gcc-11.5.0
arm64 randconfig-004-20250510 gcc-7.5.0
x86_64 allnoconfig clang-20
x86_64 allyesconfig clang-20
x86_64 buildonly-randconfig-001-20250510 clang-20
x86_64 buildonly-randconfig-002-20250510 clang-20
x86_64 buildonly-randconfig-003-20250510 gcc-12
x86_64 buildonly-randconfig-004-20250510 gcc-11
x86_64 buildonly-randconfig-005-20250510 gcc-12
x86_64 buildonly-randconfig-006-20250510 clang-20
x86_64 defconfig gcc-11
x86_64 rhel-9.4-rust clang-18
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[PATCH OLK-5.10] cachefiles: Fix non-taking of sb_writers around set/removexattr
by Zizhi Wo 10 May '25
by Zizhi Wo 10 May '25
10 May '25
From: David Howells <dhowells(a)redhat.com>
stable inclusion
from stable-v6.6.54
commit 81b048b9484bf8b3c0ad6e901a6b79fb941173b0
category: bugfix
bugzilla: 190608
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 80887f31672970abae3aaa9cf62ac72a124e7c89 ]
Unlike other vfs_xxxx() calls, vfs_setxattr() and vfs_removexattr() don't
take the sb_writers lock, so the caller should do it for them.
Fix cachefiles to do this.
Fixes: 9ae326a69004 ("CacheFiles: A cache that backs onto a mounted filesystem")
Signed-off-by: David Howells <dhowells(a)redhat.com>
cc: Christian Brauner <brauner(a)kernel.org>
cc: Gao Xiang <xiang(a)kernel.org>
cc: netfs(a)lists.linux.dev
cc: linux-erofs(a)lists.ozlabs.org
cc: linux-fsdevel(a)vger.kernel.org
Link: https://lore.kernel.org/r/20240814203850.2240469-3-dhowells@redhat.com/ # v2
Signed-off-by: Christian Brauner <brauner(a)kernel.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Conflicts:
fs/cachefiles/internal.h
fs/cachefiles/bind.c
fs/cachefiles/xattr.c
[The code has changed and relevant adaptations have been made.]
Signed-off-by: Zizhi Wo <wozizhi(a)huawei.com>
---
fs/cachefiles/bind.c | 2 +-
fs/cachefiles/internal.h | 3 +-
fs/cachefiles/xattr.c | 69 +++++++++++++++++++++++++++++-----------
3 files changed, 54 insertions(+), 20 deletions(-)
diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c
index 3a88bef9ed4b..8c84bfcde991 100644
--- a/fs/cachefiles/bind.c
+++ b/fs/cachefiles/bind.c
@@ -206,7 +206,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache)
fsdef->dentry = cachedir;
fsdef->fscache.cookie = NULL;
- ret = cachefiles_check_object_type(fsdef);
+ ret = cachefiles_check_object_type(fsdef, cache);
if (ret < 0)
goto error_unsupported;
diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
index 97c4b4c639b4..96d96926017e 100644
--- a/fs/cachefiles/internal.h
+++ b/fs/cachefiles/internal.h
@@ -368,7 +368,8 @@ static inline void cachefiles_end_secure(struct cachefiles_cache *cache,
/*
* xattr.c
*/
-extern int cachefiles_check_object_type(struct cachefiles_object *object);
+extern int cachefiles_check_object_type(struct cachefiles_object *object,
+ struct cachefiles_cache *cache);
extern int cachefiles_set_object_xattr(struct cachefiles_object *object,
struct cachefiles_xattr *auxdata);
extern int cachefiles_update_object_xattr(struct cachefiles_object *object,
diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c
index 4aadace026d2..bac55fc7359e 100644
--- a/fs/cachefiles/xattr.c
+++ b/fs/cachefiles/xattr.c
@@ -45,7 +45,8 @@ static int cachefiles_check_new_obj_xattr(struct cachefiles_object *object);
* check the type label on an object
* - done using xattrs
*/
-int cachefiles_check_object_type(struct cachefiles_object *object)
+int cachefiles_check_object_type(struct cachefiles_object *object,
+ struct cachefiles_cache *cache)
{
struct dentry *dentry = object->dentry;
char type[3], xtype[3];
@@ -62,8 +63,12 @@ int cachefiles_check_object_type(struct cachefiles_object *object)
_enter("%p{%s}", object, type);
/* attempt to install a type label directly */
- ret = vfs_setxattr(dentry, cachefiles_xattr_cache, type, 2,
- XATTR_CREATE);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache, type, 2,
+ XATTR_CREATE);
+ mnt_drop_write(cache->mnt);
+ }
if (ret == 0) {
_debug("SET"); /* we succeeded */
goto error;
@@ -123,6 +128,7 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object,
struct cachefiles_xattr *auxdata)
{
struct dentry *dentry = object->dentry;
+ struct cachefiles_cache *cache;
int ret;
ASSERT(dentry);
@@ -132,15 +138,22 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object,
/* attempt to install the cache metadata directly */
_debug("SET #%u", auxdata->len);
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags);
- if (data_new_version(object->fscache.cookie))
- ret = cachefiles_set_new_obj_xattr(object);
- else if (volume_new_version(object->fscache.cookie))
- ret = cachefiles_set_new_vol_xattr(object);
- else
- ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
- &auxdata->type, auxdata->len,
- XATTR_CREATE);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ if (data_new_version(object->fscache.cookie))
+ ret = cachefiles_set_new_obj_xattr(object);
+ else if (volume_new_version(object->fscache.cookie))
+ ret = cachefiles_set_new_vol_xattr(object);
+ else
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
+ &auxdata->type, auxdata->len,
+ XATTR_CREATE);
+ mnt_drop_write(cache->mnt);
+ }
if (ret < 0 && ret != -ENOMEM)
cachefiles_io_error_obj(
object,
@@ -157,6 +170,7 @@ int cachefiles_update_object_xattr(struct cachefiles_object *object,
struct cachefiles_xattr *auxdata)
{
struct dentry *dentry = object->dentry;
+ struct cachefiles_cache *cache;
int ret;
if (!dentry)
@@ -167,10 +181,17 @@ int cachefiles_update_object_xattr(struct cachefiles_object *object,
/* attempt to install the cache metadata directly */
_debug("SET #%u", auxdata->len);
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags);
- ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
- &auxdata->type, auxdata->len,
- XATTR_REPLACE);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
+ &auxdata->type, auxdata->len,
+ XATTR_REPLACE);
+ mnt_drop_write(cache->mnt);
+ }
if (ret < 0 && ret != -ENOMEM)
cachefiles_io_error_obj(
object,
@@ -222,6 +243,7 @@ int cachefiles_check_old_object_xattr(struct cachefiles_object *object,
struct cachefiles_xattr *auxdata)
{
struct cachefiles_xattr *auxbuf;
+ struct cachefiles_cache *cache;
unsigned int len = sizeof(struct cachefiles_xattr) + 512;
struct dentry *dentry = object->dentry;
int ret;
@@ -279,10 +301,17 @@ int cachefiles_check_old_object_xattr(struct cachefiles_object *object,
BUG();
}
+ cache = container_of(object->fscache.cache,
+ struct cachefiles_cache, cache);
+
/* update the current label */
- ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
- &auxdata->type, auxdata->len,
- XATTR_REPLACE);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
+ &auxdata->type, auxdata->len,
+ XATTR_REPLACE);
+ mnt_drop_write(cache->mnt);
+ }
if (ret < 0) {
cachefiles_io_error_obj(object,
"Can't update xattr on %lu"
@@ -364,7 +393,11 @@ int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
{
int ret;
- ret = vfs_removexattr(dentry, cachefiles_xattr_cache);
+ ret = mnt_want_write(cache->mnt);
+ if (ret == 0) {
+ ret = vfs_removexattr(dentry, cachefiles_xattr_cache);
+ mnt_drop_write(cache->mnt);
+ }
if (ret < 0) {
if (ret == -ENOENT || ret == -ENODATA)
ret = 0;
--
2.39.2
2
5

[openeuler:OLK-6.6 2218/2218] kismet: WARNING: unmet direct dependencies detected for RESCTRL_FS when selected by ARM64_MPAM
by kernel test robot 10 May '25
by kernel test robot 10 May '25
10 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: eb29ec38301f3cfe72a33627aef774ac499803cb
commit: c5a4bf91167c714de74c47f5cd6d888c66e9860d [2218/2218] arm64: mpam: Select ARCH_HAS_CPU_RESCTRL
config: arm64-kismet-CONFIG_RESCTRL_FS-CONFIG_ARM64_MPAM-0-0 (https://download.01.org/0day-ci/archive/20250510/202505101047.t5A72bmv-lkp@…)
reproduce: (https://download.01.org/0day-ci/archive/20250510/202505101047.t5A72bmv-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505101047.t5A72bmv-lkp@intel.com/
kismet warnings: (new ones prefixed by >>)
>> kismet: WARNING: unmet direct dependencies detected for RESCTRL_FS when selected by ARM64_MPAM
WARNING: unmet direct dependencies detected for RESCTRL_FS
Depends on [n]: MISC_FILESYSTEMS [=n] && ARCH_HAS_CPU_RESCTRL [=y]
Selected by [y]:
- ARM64_MPAM [=y]
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-6.6 2218/2218] kismet: WARNING: unmet direct dependencies detected for ARM64_ERRATUM_845719 when selected by ARCH_MXC
by kernel test robot 10 May '25
by kernel test robot 10 May '25
10 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: eb29ec38301f3cfe72a33627aef774ac499803cb
commit: f9b54a6714445cde83aeff0318cf767b3b81229d [2218/2218] arm64:ilp32: add ARM64_ILP32 to Kconfig
config: arm64-kismet-CONFIG_ARM64_ERRATUM_845719-CONFIG_ARCH_MXC-0-0 (https://download.01.org/0day-ci/archive/20250510/202505100830.TI8oJiuj-lkp@…)
reproduce: (https://download.01.org/0day-ci/archive/20250510/202505100830.TI8oJiuj-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505100830.TI8oJiuj-lkp@intel.com/
kismet warnings: (new ones prefixed by >>)
>> kismet: WARNING: unmet direct dependencies detected for ARM64_ERRATUM_845719 when selected by ARCH_MXC
WARNING: unmet direct dependencies detected for ARM64_ERRATUM_845719
Depends on [n]: AARCH32_EL0 [=n]
Selected by [y]:
- ARCH_MXC [=y] && ARCH_NXP [=y] && COMPAT [=y]
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-6.6] BUILD REGRESSION eb29ec38301f3cfe72a33627aef774ac499803cb
by kernel test robot 10 May '25
by kernel test robot 10 May '25
10 May '25
tree/branch: https://gitee.com/openeuler/kernel.git OLK-6.6
branch HEAD: eb29ec38301f3cfe72a33627aef774ac499803cb !12616 [OLK-6.6] fix bug:compiler error on loongarch64 for mucse rnpm driver
Error/Warning (recently discovered and may have been fixed):
https://lore.kernel.org/oe-kbuild-all/202504240137.L2xvmv1X-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504240638.PM73jDId-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504250828.wJjuSU89-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290703.q8lvsdB3-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290927.uassI0w9-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504291722.ZB4nQmaR-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504300433.T31occlR-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504300733.mAi3Indd-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505080526.qCQgtY7V-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505080910.94UlZrA0-lkp@intel.com
block/blk-io-hierarchy/iodump.c:561:7: warning: no previous prototype for '__bio_stage_hierarchy_start' [-Wmissing-prototypes]
block/blk-io-hierarchy/iodump.c:561:7: warning: no previous prototype for function '__bio_stage_hierarchy_start' [-Wmissing-prototypes]
crypto/asymmetric_keys/pgp_library.c:189: warning: Excess function parameter '_data' description in 'pgp_parse_packets'
crypto/asymmetric_keys/pgp_library.c:189: warning: Excess function parameter '_datalen' description in 'pgp_parse_packets'
crypto/asymmetric_keys/pgp_library.c:189: warning: Function parameter or member 'data' not described in 'pgp_parse_packets'
crypto/asymmetric_keys/pgp_library.c:189: warning: Function parameter or member 'datalen' not described in 'pgp_parse_packets'
drivers/irqchip/irq-gic-v3.c:1517:6: warning: no previous prototype for 'is_gicv4p1' [-Wmissing-prototypes]
drivers/irqchip/irq-gic-v3.c:1517:6: warning: no previous prototype for function 'is_gicv4p1' [-Wmissing-prototypes]
drivers/irqchip/irq-gic-v3.c:1526:6: warning: no previous prototype for 'gic_dist_enable_ipiv' [-Wmissing-prototypes]
drivers/irqchip/irq-gic-v3.c:1526:6: warning: no previous prototype for function 'gic_dist_enable_ipiv' [-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/base/trace/sxe_trace.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb_nl.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debug.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:432:6: error: no previous prototype for function 'sxe_debugfs_entries_init' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:459:6: error: no previous prototype for function 'sxe_debugfs_entries_exit' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:465:6: error: no previous prototype for function 'sxe_debugfs_init' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:470:6: error: no previous prototype for function 'sxe_debugfs_exit' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c:2022:5: error: no previous prototype for function 'sxe_reg_test' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c:2644:5: error: no previous prototype for function 'sxe_phys_id_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_filter.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_cli.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_hdc.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:230:6: error: no previous prototype for function 'sxe_hw_no_snoop_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:262:6: error: no previous prototype for function 'sxe_hw_uc_addr_pool_del' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:283:5: error: no previous prototype for function 'sxe_hw_uc_addr_pool_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:337:5: error: no previous prototype for function 'sxe_hw_nic_reset' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:367:6: error: no previous prototype for function 'sxe_hw_pf_rst_done_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:735:5: error: no previous prototype for function 'sxe_hw_pending_irq_read_clear' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:740:6: error: no previous prototype for function 'sxe_hw_pending_irq_write_clear' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:745:5: error: no previous prototype for function 'sxe_hw_irq_cause_get' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:765:6: error: no previous prototype for function 'sxe_hw_ring_irq_auto_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:775:6: error: no previous prototype for function 'sxe_hw_irq_general_reg_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:780:5: error: no previous prototype for function 'sxe_hw_irq_general_reg_get' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:790:6: error: no previous prototype for function 'sxe_hw_event_irq_map' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:806:6: error: no previous prototype for function 'sxe_hw_ring_irq_map' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:823:6: error: no previous prototype for function 'sxe_hw_ring_irq_interval_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:838:6: error: no previous prototype for function 'sxe_hw_event_irq_auto_clear_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:843:6: error: no previous prototype for function 'sxe_hw_specific_irq_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:848:6: error: no previous prototype for function 'sxe_hw_specific_irq_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:876:6: error: no previous prototype for function 'sxe_hw_all_irq_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:994:5: error: no previous prototype for function 'sxe_hw_link_speed_get' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ipsec.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:136:5: error: no previous prototype for function 'sxe_msi_irq_init' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:182:6: error: no previous prototype for function 'sxe_disable_dcb' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:212:6: error: no previous prototype for function 'sxe_disable_rss' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:729:6: error: no previous prototype for function 'sxe_lsc_irq_handler' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:745:6: error: no previous prototype for function 'sxe_mailbox_irq_handler' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c:70:6: error: no previous prototype for function 'sxe_allow_inval_mac' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_monitor.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_phy.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_phy.c:733:5: error: no previous prototype for function 'sxe_multispeed_sfp_link_configure' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ptp.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ring.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c:1431:6: error: no previous prototype for function 'sxe_headers_cleanup' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c:1569:6: error: no previous prototype for function 'sxe_rx_buffer_page_offset_update' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c:1552:6: error: no previous prototype for function 'sxe_set_vf_link_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c:766:6: error: variable 'ret' set but not used [-Werror,-Wunused-but-set-variable]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_xdp.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_xdp.c:410:6: error: no previous prototype for function 'sxe_txrx_ring_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/base/trace/sxe_trace.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_debug.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ethtool.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:160:6: error: no previous prototype for function 'sxevf_hw_stop' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:187:6: error: no previous prototype for function 'sxevf_msg_write' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:196:5: error: no previous prototype for function 'sxevf_msg_read' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:206:5: error: no previous prototype for function 'sxevf_mailbox_read' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:211:6: error: no previous prototype for function 'sxevf_mailbox_write' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:216:6: error: no previous prototype for function 'sxevf_pf_req_irq_trigger' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:221:6: error: no previous prototype for function 'sxevf_pf_ack_irq_trigger' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:226:6: error: no previous prototype for function 'sxevf_event_irq_map' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:240:6: error: no previous prototype for function 'sxevf_specific_irq_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:245:6: error: no previous prototype for function 'sxevf_irq_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:251:6: error: no previous prototype for function 'sxevf_irq_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:259:6: error: no previous prototype for function 'sxevf_hw_ring_irq_map' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:276:6: error: no previous prototype for function 'sxevf_ring_irq_interval_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:313:6: error: no previous prototype for function 'sxevf_hw_reset' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:324:5: error: no previous prototype for function 'sxevf_link_state_get' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:539:6: error: no previous prototype for function 'sxevf_tx_ring_switch' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:594:6: error: no previous prototype for function 'sxevf_rx_ring_switch' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:626:6: error: no previous prototype for function 'sxevf_rx_ring_desc_configure' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:640:6: error: no previous prototype for function 'sxevf_rx_rcv_ctl_configure' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ipsec.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_monitor.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_msg.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ring.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_rx_proc.c:362:6: error: no previous prototype for function 'sxevf_rx_ring_buffers_alloc' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_rx_proc.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:127:5: error: no previous prototype for function 'sxevf_tx_ring_alloc' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:88:6: error: no previous prototype for function 'sxevf_tx_ring_free' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/yunsilicon/xsc/pci/sriov_sysfs.c:911:31: warning: unused variable 'vf_type_ib' [-Wunused-const-variable]
drivers/net/ethernet/yunsilicon/xsc/pci/xsc_lag.c:1128:21: warning: variable 'bond_dev' set but not used [-Wunused-but-set-variable]
include/linux/fortify-string.h:606:4: error: call to '__read_overflow2_field' declared with 'warning' attribute: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Werror,-Wattribute-warning]
include/linux/sched/signal.h: linux/kabi.h is included more than once.
include/trace/stages/init.h:2:23: warning: 'str__bonding__trace_system_name' defined but not used [-Wunused-const-variable=]
Unverified Error/Warning (likely false positive, kindly check if interested):
include/linux/gpio/driver.h: asm/bug.h is included more than once.
Error/Warning ids grouped by kconfigs:
recent_errors
|-- arm64-allmodconfig
| |-- block-blk-io-hierarchy-iodump.c:warning:no-previous-prototype-for-function-__bio_stage_hierarchy_start
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_data-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_datalen-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-data-not-described-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-datalen-not-described-in-pgp_parse_packets
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-gic_dist_enable_ipiv
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-is_gicv4p1
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-mucse-rnp-rnp_mbx_fw.c:warning:Cannot-understand-force_free:
| |-- drivers-net-ethernet-yunsilicon-xsc-pci-sriov_sysfs.c:warning:unused-variable-vf_type_ib
| |-- drivers-net-ethernet-yunsilicon-xsc-pci-xsc_lag.c:warning:variable-bond_dev-set-but-not-used
| `-- include-linux-fortify-string.h:error:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()-Werror-Wattribute-warnin
|-- arm64-allnoconfig
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-gic_dist_enable_ipiv
| `-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-is_gicv4p1
|-- arm64-randconfig-002-20250509
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- arm64-randconfig-003-20250509
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-gic_dist_enable_ipiv
| `-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-is_gicv4p1
|-- loongarch-allmodconfig
| |-- block-blk-io-hierarchy-iodump.c:warning:no-previous-prototype-for-__bio_stage_hierarchy_start
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_data-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_datalen-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-data-not-described-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-datalen-not-described-in-pgp_parse_packets
| |-- drivers-net-ethernet-mucse-rnp-rnp_mbx_fw.c:warning:Cannot-understand-force_free:
| `-- include-trace-stages-init.h:warning:str__bonding__trace_system_name-defined-but-not-used
|-- loongarch-allyesconfig
| |-- block-blk-io-hierarchy-iodump.c:warning:no-previous-prototype-for-__bio_stage_hierarchy_start
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_data-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_datalen-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-data-not-described-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-datalen-not-described-in-pgp_parse_packets
| |-- drivers-net-ethernet-mucse-rnp-rnp_mbx_fw.c:warning:Cannot-understand-force_free:
| `-- include-trace-stages-init.h:warning:str__bonding__trace_system_name-defined-but-not-used
|-- x86_64-allnoconfig
| |-- include-linux-gpio-driver.h:asm-bug.h-is-included-more-than-once.
| `-- include-linux-sched-signal.h:linux-kabi.h-is-included-more-than-once.
|-- x86_64-allyesconfig
| |-- block-blk-io-hierarchy-iodump.c:warning:no-previous-prototype-for-function-__bio_stage_hierarchy_start
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_data-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_datalen-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-data-not-described-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-datalen-not-described-in-pgp_parse_packets
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-mucse-rnp-rnp_mbx_fw.c:warning:Cannot-understand-force_free:
| |-- drivers-net-ethernet-yunsilicon-xsc-pci-sriov_sysfs.c:warning:unused-variable-vf_type_ib
| |-- drivers-net-ethernet-yunsilicon-xsc-pci-xsc_lag.c:warning:variable-bond_dev-set-but-not-used
| `-- include-linux-fortify-string.h:error:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()-Werror-Wattribute-warnin
|-- x86_64-buildonly-randconfig-005-20250509
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- x86_64-defconfig
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- x86_64-randconfig-161-20250509
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| `-- include-linux-fortify-string.h:error:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()-Werror-Wattribute-warnin
`-- x86_64-rhel-9.4-rust
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
`-- include-linux-fortify-string.h:error:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()-Werror-Wattribute-warnin
elapsed time: 744m
configs tested: 20
configs skipped: 124
tested configs:
arm64 allmodconfig clang-19
arm64 allnoconfig gcc-14.2.0
arm64 randconfig-001-20250509 gcc-7.5.0
arm64 randconfig-002-20250509 gcc-7.5.0
arm64 randconfig-003-20250509 clang-21
arm64 randconfig-004-20250509 gcc-5.5.0
loongarch allmodconfig gcc-14.2.0
loongarch allnoconfig gcc-14.2.0
loongarch randconfig-001-20250509 gcc-13.3.0
loongarch randconfig-002-20250509 gcc-14.2.0
x86_64 allnoconfig clang-20
x86_64 allyesconfig clang-20
x86_64 buildonly-randconfig-001-20250509 gcc-11
x86_64 buildonly-randconfig-002-20250509 gcc-11
x86_64 buildonly-randconfig-003-20250509 clang-20
x86_64 buildonly-randconfig-004-20250509 clang-20
x86_64 buildonly-randconfig-005-20250509 gcc-12
x86_64 buildonly-randconfig-006-20250509 gcc-12
x86_64 defconfig gcc-11
x86_64 rhel-9.4-rust clang-18
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-5.10] BUILD REGRESSION 2e5032bf08eca1f3b062773540ff27c51788390d
by kernel test robot 09 May '25
by kernel test robot 09 May '25
09 May '25
tree/branch: https://gitee.com/openeuler/kernel.git OLK-5.10
branch HEAD: 2e5032bf08eca1f3b062773540ff27c51788390d !16164 fix CVE-2023-53093
Error/Warning (recently discovered and may have been fixed):
https://lore.kernel.org/oe-kbuild-all/202504290538.Gt6tWC7N-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290659.kdYkNrXR-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290828.J8Cynzh6-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504300001.MoxWgMgI-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504300111.nH5Pw0yV-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504300151.RfBZyPgj-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504302232.oeU1VyOU-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505020850.kZitpRTl-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505062356.u2rMcCQF-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505091231.o5lexadJ-lkp@intel.com
./drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c: 682: need linux/version.h
./drivers/net/ethernet/linkdata/sxe/base/compat/sxe_compat.h: 16 linux/version.h not needed.
./drivers/net/ethernet/linkdata/sxevf/base/compat/sxe_compat.h: 16 linux/version.h not needed.
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:24: warning: Excess function parameter 'author' description in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:24: warning: Excess function parameter 'date' description in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:24: warning: Excess function parameter 'file' description in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:24: warning: Function parameter or member 'buf_len' not described in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:24: warning: Function parameter or member 'buff' not described in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxe/base/trace/sxe_trace.c:21: warning: Excess function parameter 'author' description in 'SXE_FILE_NAME_LEN'
drivers/net/ethernet/linkdata/sxe/base/trace/sxe_trace.c:21: warning: Excess function parameter 'date' description in 'SXE_FILE_NAME_LEN'
drivers/net/ethernet/linkdata/sxe/base/trace/sxe_trace.c:21: warning: Excess function parameter 'file' description in 'SXE_FILE_NAME_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:23: warning: Excess function parameter 'author' description in 'sxe_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:23: warning: Excess function parameter 'date' description in 'sxe_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:23: warning: Excess function parameter 'file' description in 'sxe_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:23: warning: Function parameter or member 'protocol' not described in 'sxe_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:23: warning: Function parameter or member 'skb' not described in 'sxe_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb.c:16: warning: Excess function parameter 'author' description in 'SXE_TC_BWG_PERCENT_PER_CHAN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb.c:16: warning: Excess function parameter 'date' description in 'SXE_TC_BWG_PERCENT_PER_CHAN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb.c:16: warning: Excess function parameter 'file' description in 'SXE_TC_BWG_PERCENT_PER_CHAN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb_nl.c:20: warning: Excess function parameter 'author' description in 'BIT_PFC'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb_nl.c:20: warning: Excess function parameter 'date' description in 'BIT_PFC'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb_nl.c:20: warning: Excess function parameter 'file' description in 'BIT_PFC'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debug.c:18: warning: Excess function parameter 'author' description in 'SKB_DESCRIPTION_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debug.c:18: warning: Excess function parameter 'date' description in 'SKB_DESCRIPTION_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debug.c:18: warning: Excess function parameter 'file' description in 'SKB_DESCRIPTION_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:432:6: error: no previous prototype for 'sxe_debugfs_entries_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:459:6: error: no previous prototype for 'sxe_debugfs_entries_exit' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:465:6: error: no previous prototype for 'sxe_debugfs_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:470:6: error: no previous prototype for 'sxe_debugfs_exit' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c:2022:5: error: no previous prototype for 'sxe_reg_test' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c:2644:5: error: no previous prototype for 'sxe_phys_id_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c:2736:33: error: suggest braces around empty body in an 'if' statement [-Werror=empty-body]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c:2736:47: error: suggest braces around empty body in an 'if' statement [-Werror=empty-body]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_filter.c:24: warning: cannot understand function prototype: 'struct workqueue_struct *sxe_fnav_workqueue; '
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_cli.c:18: warning: cannot understand function prototype: 'dev_t sxe_cdev_major; '
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_hdc.c:27: warning: cannot understand function prototype: 'atomic_t hdc_available = ATOMIC_INIT(1); '
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1014:6: error: no previous prototype for 'sxe_hw_link_speed_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1033:6: error: no previous prototype for 'sxe_hw_is_link_state_up' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1055:6: error: no previous prototype for 'sxe_hw_mac_pad_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1064:5: error: no previous prototype for 'sxe_hw_fc_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1135:6: error: no previous prototype for 'sxe_fc_autoneg_localcap_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1164:5: error: no previous prototype for 'sxe_hw_pfc_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1256:6: error: no previous prototype for 'sxe_hw_crc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1264:6: error: no previous prototype for 'sxe_hw_loopback_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1276:6: error: no previous prototype for 'sxe_hw_mac_txrx_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1285:6: error: no previous prototype for 'sxe_hw_mac_max_frame_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1298:5: error: no previous prototype for 'sxe_hw_mac_max_frame_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1330:6: error: no previous prototype for 'sxe_hw_fc_tc_high_water_mark_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1335:6: error: no previous prototype for 'sxe_hw_fc_tc_low_water_mark_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1340:6: error: no previous prototype for 'sxe_hw_is_fc_autoneg_disabled' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1345:6: error: no previous prototype for 'sxe_hw_fc_autoneg_disable_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1360:6: error: no previous prototype for 'sxe_hw_fc_requested_mode_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1388:5: error: no previous prototype for 'sxe_hw_rx_mode_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1393:5: error: no previous prototype for 'sxe_hw_pool_rx_mode_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1398:6: error: no previous prototype for 'sxe_hw_rx_mode_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1403:6: error: no previous prototype for 'sxe_hw_pool_rx_mode_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1408:6: error: no previous prototype for 'sxe_hw_rx_lro_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1420:6: error: no previous prototype for 'sxe_hw_rx_nfs_filter_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1428:6: error: no previous prototype for 'sxe_hw_rx_udp_frag_checksum_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1437:6: error: no previous prototype for 'sxe_hw_fc_mac_addr_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1449:5: error: no previous prototype for 'sxe_hw_uc_addr_add' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1484:5: error: no previous prototype for 'sxe_hw_uc_addr_del' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1510:6: error: no previous prototype for 'sxe_hw_mta_hash_table_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1515:6: error: no previous prototype for 'sxe_hw_mta_hash_table_update' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1525:5: error: no previous prototype for 'sxe_hw_mc_filter_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1530:6: error: no previous prototype for 'sxe_hw_mc_filter_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1554:6: error: no previous prototype for 'sxe_hw_uc_addr_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1587:6: error: no previous prototype for 'sxe_hw_vt_ctrl_cfg' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1601:6: error: no previous prototype for 'sxe_hw_vt_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1675:5: error: no previous prototype for 'sxe_hw_vlan_pool_filter_read' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1697:6: error: no previous prototype for 'sxe_hw_vlan_filter_array_write' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1702:5: error: no previous prototype for 'sxe_hw_vlan_filter_array_read' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1707:6: error: no previous prototype for 'sxe_hw_vlan_filter_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1735:5: error: no previous prototype for 'sxe_hw_vlvf_slot_find' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1769:5: error: no previous prototype for 'sxe_hw_vlan_filter_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1836:6: error: no previous prototype for 'sxe_hw_vlan_filter_array_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1910:5: error: no previous prototype for 'sxe_hw_rx_pkt_buf_size_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1915:6: error: no previous prototype for 'sxe_hw_rx_multi_ring_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1996:6: error: no previous prototype for 'sxe_hw_rss_key_set_all' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2004:6: error: no previous prototype for 'sxe_hw_rss_redir_tbl_reg_write' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2009:6: error: no previous prototype for 'sxe_hw_rss_redir_tbl_set_all' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2024:6: error: no previous prototype for 'sxe_hw_rx_cap_switch_on' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2041:6: error: no previous prototype for 'sxe_hw_rx_cap_switch_off' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2070:6: error: no previous prototype for 'sxe_hw_tx_pkt_buf_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2086:6: error: no previous prototype for 'sxe_hw_tx_pkt_buf_size_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2101:6: error: no previous prototype for 'sxe_hw_rx_lro_ack_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2147:6: error: no previous prototype for 'sxe_hw_fnav_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2204:5: error: no previous prototype for 'sxe_hw_fnav_port_mask_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:230:6: error: no previous prototype for 'sxe_hw_no_snoop_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2310:5: error: no previous prototype for 'sxe_hw_fnav_specific_rule_mask_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2445:5: error: no previous prototype for 'sxe_hw_fnav_specific_rule_add' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2469:5: error: no previous prototype for 'sxe_hw_fnav_specific_rule_del' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2500:6: error: no previous prototype for 'sxe_hw_fnav_sample_rule_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2587:5: error: no previous prototype for 'sxe_hw_fnav_sample_rules_table_reinit' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:262:6: error: no previous prototype for 'sxe_hw_uc_addr_pool_del' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2651:5: error: no previous prototype for 'sxe_hw_ptp_systime_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2667:6: error: no previous prototype for 'sxe_hw_ptp_systime_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2676:6: error: no previous prototype for 'sxe_hw_ptp_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2692:6: error: no previous prototype for 'sxe_hw_ptp_rx_timestamp_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2697:6: error: no previous prototype for 'sxe_hw_ptp_tx_timestamp_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2729:5: error: no previous prototype for 'sxe_hw_ptp_rx_timestamp_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2746:6: error: no previous prototype for 'sxe_hw_ptp_is_rx_timestamp_valid' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2758:6: error: no previous prototype for 'sxe_hw_ptp_timestamp_mode_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2782:6: error: no previous prototype for 'sxe_hw_ptp_timestamp_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:283:5: error: no previous prototype for 'sxe_hw_uc_addr_pool_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2922:6: error: no previous prototype for 'sxe_hw_rx_dma_ctrl_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2930:6: error: no previous prototype for 'sxe_hw_rx_dma_lro_ctrl_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2938:6: error: no previous prototype for 'sxe_hw_rx_desc_thresh_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2949:6: error: no previous prototype for 'sxe_hw_rx_ring_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2983:6: error: no previous prototype for 'sxe_hw_rx_ring_switch_not_polling' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2999:6: error: no previous prototype for 'sxe_hw_rx_queue_desc_reg_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3016:6: error: no previous prototype for 'sxe_hw_rx_ring_desc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3030:6: error: no previous prototype for 'sxe_hw_rx_rcv_ctl_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3043:6: error: no previous prototype for 'sxe_hw_rx_lro_ctl_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3111:6: error: no previous prototype for 'sxe_hw_tx_ring_head_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3116:6: error: no previous prototype for 'sxe_hw_tx_ring_tail_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3121:6: error: no previous prototype for 'sxe_hw_tx_ring_desc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3136:6: error: no previous prototype for 'sxe_hw_tx_desc_thresh_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3147:6: error: no previous prototype for 'sxe_hw_all_ring_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3165:6: error: no previous prototype for 'sxe_hw_tx_ring_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3195:6: error: no previous prototype for 'sxe_hw_tx_ring_switch_not_polling' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3209:6: error: no previous prototype for 'sxe_hw_tx_pkt_buf_thresh_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3230:6: error: no previous prototype for 'sxe_hw_tx_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3257:6: error: no previous prototype for 'sxe_hw_vlan_tag_strip_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3279:6: error: no previous prototype for 'sxe_hw_tx_vlan_tag_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3284:5: error: no previous prototype for 'sxe_hw_tx_vlan_insert_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3289:6: error: no previous prototype for 'sxe_hw_tx_ring_info_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3295:6: error: no previous prototype for 'sxe_hw_dcb_rx_bw_alloc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3330:6: error: no previous prototype for 'sxe_hw_dcb_tx_desc_bw_alloc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3360:6: error: no previous prototype for 'sxe_hw_dcb_tx_data_bw_alloc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:337:5: error: no previous prototype for 'sxe_hw_nic_reset' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3397:6: error: no previous prototype for 'sxe_hw_dcb_pfc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3515:6: error: no previous prototype for 'sxe_hw_vt_pool_loopback_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3523:6: error: no previous prototype for 'sxe_hw_pool_rx_ring_drop_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3545:5: error: no previous prototype for 'sxe_hw_rx_pool_bitmap_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3550:6: error: no previous prototype for 'sxe_hw_rx_pool_bitmap_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3555:5: error: no previous prototype for 'sxe_hw_tx_pool_bitmap_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3560:6: error: no previous prototype for 'sxe_hw_tx_pool_bitmap_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3565:6: error: no previous prototype for 'sxe_hw_dcb_max_mem_window_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3570:6: error: no previous prototype for 'sxe_hw_dcb_tx_ring_rate_factor_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3577:6: error: no previous prototype for 'sxe_hw_spoof_count_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3586:6: error: no previous prototype for 'sxe_hw_pool_mac_anti_spoof_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3613:6: error: no previous prototype for 'sxe_hw_rx_drop_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3674:6: error: no previous prototype for 'sxe_hw_dcb_rate_limiter_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:367:6: error: no previous prototype for 'sxe_hw_pf_rst_done_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3990:6: error: no previous prototype for 'sxe_hw_stats_regs_clean' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4099:6: error: no previous prototype for 'sxe_hw_stats_seq_clean' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4115:36: error: suggest braces around empty body in an 'if' statement [-Werror=empty-body]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4115:50: error: suggest braces around empty body in an 'if' statement [-Werror=empty-body]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4125:6: error: no previous prototype for 'sxe_hw_stats_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4301:6: error: no previous prototype for 'sxe_hw_mbx_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4326:6: error: no previous prototype for 'sxe_hw_vf_rst_check' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4342:6: error: no previous prototype for 'sxe_hw_vf_req_check' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4355:6: error: no previous prototype for 'sxe_hw_vf_ack_check' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4389:5: error: no previous prototype for 'sxe_hw_rcv_msg_from_vf' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4419:5: error: no previous prototype for 'sxe_hw_send_msg_to_vf' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4462:6: error: no previous prototype for 'sxe_hw_mbx_mem_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4488:6: error: no previous prototype for 'sxe_hw_pcie_vt_mode_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4497:5: error: no previous prototype for 'sxe_hw_hdc_lock_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4536:6: error: no previous prototype for 'sxe_hw_hdc_lock_release' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4552:6: error: no previous prototype for 'sxe_hw_hdc_fw_ov_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4557:6: error: no previous prototype for 'sxe_hw_hdc_is_fw_over_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4567:6: error: no previous prototype for 'sxe_hw_hdc_packet_send_done' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4573:6: error: no previous prototype for 'sxe_hw_hdc_packet_header_send' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4578:6: error: no previous prototype for 'sxe_hw_hdc_packet_data_dword_send' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4584:5: error: no previous prototype for 'sxe_hw_hdc_fw_ack_header_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4589:5: error: no previous prototype for 'sxe_hw_hdc_packet_data_dword_rcv' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4594:5: error: no previous prototype for 'sxe_hw_hdc_fw_status_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4604:6: error: no previous prototype for 'sxe_hw_hdc_drv_status_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4609:5: error: no previous prototype for 'sxe_hw_hdc_channel_state_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:735:5: error: no previous prototype for 'sxe_hw_pending_irq_read_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:740:6: error: no previous prototype for 'sxe_hw_pending_irq_write_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:745:5: error: no previous prototype for 'sxe_hw_irq_cause_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:765:6: error: no previous prototype for 'sxe_hw_ring_irq_auto_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:775:6: error: no previous prototype for 'sxe_hw_irq_general_reg_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:780:5: error: no previous prototype for 'sxe_hw_irq_general_reg_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:790:6: error: no previous prototype for 'sxe_hw_event_irq_map' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:806:6: error: no previous prototype for 'sxe_hw_ring_irq_map' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:823:6: error: no previous prototype for 'sxe_hw_ring_irq_interval_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:838:6: error: no previous prototype for 'sxe_hw_event_irq_auto_clear_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:843:6: error: no previous prototype for 'sxe_hw_specific_irq_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:848:6: error: no previous prototype for 'sxe_hw_specific_irq_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:876:6: error: no previous prototype for 'sxe_hw_all_irq_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:994:5: error: no previous prototype for 'sxe_hw_link_speed_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ipsec.c:23: warning: cannot understand function prototype: 'const char ipsec_aes_name[] = "rfc4106(gcm(aes))"; '
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:136:5: error: no previous prototype for 'sxe_msi_irq_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:182:6: error: no previous prototype for 'sxe_disable_dcb' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:212:6: error: no previous prototype for 'sxe_disable_rss' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:729:6: error: no previous prototype for 'sxe_lsc_irq_handler' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:745:6: error: no previous prototype for 'sxe_mailbox_irq_handler' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c: linux/moduleparam.h is included more than once.
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c:1038:12: error: 'sxe_suspend' defined but not used [-Werror=unused-function]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c:1071:12: error: 'sxe_resume' defined but not used [-Werror=unused-function]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c:70:6: error: no previous prototype for 'sxe_allow_inval_mac' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_monitor.c:24: warning: cannot understand function prototype: 'struct workqueue_struct *sxe_fnav_workqueue; '
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c: sxe_netdev.h is included more than once.
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c:40: warning: Excess function parameter 'author' description in 'SXE_HW_REINIT_SRIOV_DELAY'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c:40: warning: Excess function parameter 'date' description in 'SXE_HW_REINIT_SRIOV_DELAY'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c:40: warning: Excess function parameter 'file' description in 'SXE_HW_REINIT_SRIOV_DELAY'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:16: warning: Excess function parameter 'author' description in 'sxe_check_cfg_fault'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:16: warning: Excess function parameter 'date' description in 'sxe_check_cfg_fault'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:16: warning: Excess function parameter 'file' description in 'sxe_check_cfg_fault'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:16: warning: Function parameter or member 'dev' not described in 'sxe_check_cfg_fault'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:16: warning: Function parameter or member 'hw' not described in 'sxe_check_cfg_fault'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_phy.c:733:5: error: no previous prototype for 'sxe_multispeed_sfp_link_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ptp.c:18: warning: Excess function parameter 'author' description in 'sxe_ptp_read'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ptp.c:18: warning: Excess function parameter 'date' description in 'sxe_ptp_read'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ptp.c:18: warning: Excess function parameter 'file' description in 'sxe_ptp_read'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ptp.c:18: warning: Function parameter or member 'cc' not described in 'sxe_ptp_read'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ring.c:18: warning: Excess function parameter 'author' description in 'sxe_rss_num_get'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ring.c:18: warning: Excess function parameter 'date' description in 'sxe_rss_num_get'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ring.c:18: warning: Excess function parameter 'file' description in 'sxe_rss_num_get'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ring.c:18: warning: Function parameter or member 'adapter' not described in 'sxe_rss_num_get'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c:1431:6: error: no previous prototype for 'sxe_headers_cleanup' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c:1569:6: error: no previous prototype for 'sxe_rx_buffer_page_offset_update' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c: sxe_ipsec.h is included more than once.
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c:1552:6: error: no previous prototype for 'sxe_set_vf_link_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c:766:13: error: variable 'ret' set but not used [-Werror=unused-but-set-variable]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c:766:6: error: variable 'ret' set but not used [-Werror=unused-but-set-variable]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:41: warning: Excess function parameter 'author' description in 'SXE_SKB_MIN_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:41: warning: Excess function parameter 'date' description in 'SXE_SKB_MIN_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:41: warning: Excess function parameter 'file' description in 'SXE_SKB_MIN_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_xdp.c:403:6: error: no previous prototype for 'sxe_txrx_ring_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:24: warning: Excess function parameter 'author' description in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:24: warning: Excess function parameter 'date' description in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:24: warning: Excess function parameter 'file' description in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:24: warning: Function parameter or member 'buf_len' not described in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:24: warning: Function parameter or member 'buff' not described in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxevf/base/trace/sxe_trace.c:21: warning: Excess function parameter 'author' description in 'SXE_FILE_NAME_LEN'
drivers/net/ethernet/linkdata/sxevf/base/trace/sxe_trace.c:21: warning: Excess function parameter 'date' description in 'SXE_FILE_NAME_LEN'
drivers/net/ethernet/linkdata/sxevf/base/trace/sxe_trace.c:21: warning: Excess function parameter 'file' description in 'SXE_FILE_NAME_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf.h: sxe_errno.h is included more than once.
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:23: warning: Excess function parameter 'author' description in 'sxevf_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:23: warning: Excess function parameter 'date' description in 'sxevf_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:23: warning: Excess function parameter 'file' description in 'sxevf_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:23: warning: Function parameter or member 'protocol' not described in 'sxevf_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:23: warning: Function parameter or member 'skb' not described in 'sxevf_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_debug.c:18: warning: Excess function parameter 'author' description in 'SKB_DESCRIPTION_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_debug.c:18: warning: Excess function parameter 'date' description in 'SKB_DESCRIPTION_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_debug.c:18: warning: Excess function parameter 'file' description in 'SKB_DESCRIPTION_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ethtool.c:22: warning: Excess function parameter 'author' description in 'SXEVF_DIAG_REGS_TEST'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ethtool.c:22: warning: Excess function parameter 'date' description in 'SXEVF_DIAG_REGS_TEST'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ethtool.c:22: warning: Excess function parameter 'file' description in 'SXEVF_DIAG_REGS_TEST'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c: sxevf.h is included more than once.
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c: sxevf_hw.h is included more than once.
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:160:6: error: no previous prototype for 'sxevf_hw_stop' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:187:6: error: no previous prototype for 'sxevf_msg_write' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:196:5: error: no previous prototype for 'sxevf_msg_read' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:206:5: error: no previous prototype for 'sxevf_mailbox_read' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:211:6: error: no previous prototype for 'sxevf_mailbox_write' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:216:6: error: no previous prototype for 'sxevf_pf_req_irq_trigger' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:221:6: error: no previous prototype for 'sxevf_pf_ack_irq_trigger' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:226:6: error: no previous prototype for 'sxevf_event_irq_map' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:240:6: error: no previous prototype for 'sxevf_specific_irq_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:245:6: error: no previous prototype for 'sxevf_irq_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:251:6: error: no previous prototype for 'sxevf_irq_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:259:6: error: no previous prototype for 'sxevf_hw_ring_irq_map' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:276:6: error: no previous prototype for 'sxevf_ring_irq_interval_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:313:6: error: no previous prototype for 'sxevf_hw_reset' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:324:5: error: no previous prototype for 'sxevf_link_state_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:539:6: error: no previous prototype for 'sxevf_tx_ring_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:594:6: error: no previous prototype for 'sxevf_rx_ring_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:626:6: error: no previous prototype for 'sxevf_rx_ring_desc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:640:6: error: no previous prototype for 'sxevf_rx_rcv_ctl_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:697:6: error: no previous prototype for 'sxevf_32bit_counter_update' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:710:6: error: no previous prototype for 'sxevf_36bit_counter_update' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:726:6: error: no previous prototype for 'sxevf_packet_stats_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:740:6: error: no previous prototype for 'sxevf_stats_init_value_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ipsec.c:21: warning: cannot understand function prototype: 'const char ipsec_aes_name[] = "rfc4106(gcm(aes))"; '
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Excess function parameter 'author' description in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Excess function parameter 'date' description in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Excess function parameter 'file' description in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Function parameter or member 'dev' not described in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Function parameter or member 'napi' not described in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Function parameter or member 'poll' not described in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Function parameter or member 'weight' not described in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:28: warning: Excess function parameter 'author' description in 'SXEVF_MSG_LEVEL_DEFAULT'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:28: warning: Excess function parameter 'date' description in 'SXEVF_MSG_LEVEL_DEFAULT'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:28: warning: Excess function parameter 'file' description in 'SXEVF_MSG_LEVEL_DEFAULT'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:543:12: error: 'sxevf_resume' defined but not used [-Werror=unused-function]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_monitor.c:19: warning: Excess function parameter 'author' description in 'SXEVF_CHECK_LINK_TIMER_PERIOD'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_monitor.c:19: warning: Excess function parameter 'date' description in 'SXEVF_CHECK_LINK_TIMER_PERIOD'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_monitor.c:19: warning: Excess function parameter 'file' description in 'SXEVF_CHECK_LINK_TIMER_PERIOD'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_msg.c:20: warning: Excess function parameter 'author' description in 'SXEVF_PFMSG_MASK'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_msg.c:20: warning: Excess function parameter 'date' description in 'SXEVF_PFMSG_MASK'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_msg.c:20: warning: Excess function parameter 'file' description in 'SXEVF_PFMSG_MASK'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c: sxevf_hw.h is included more than once.
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c:32: warning: Excess function parameter 'author' description in 'SXEVF_MAX_MAC_HDR_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c:32: warning: Excess function parameter 'date' description in 'SXEVF_MAX_MAC_HDR_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c:32: warning: Excess function parameter 'file' description in 'SXEVF_MAX_MAC_HDR_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ring.c:19: warning: Excess function parameter 'author' description in 'sxevf_ring_feature_init'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ring.c:19: warning: Excess function parameter 'date' description in 'sxevf_ring_feature_init'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ring.c:19: warning: Excess function parameter 'file' description in 'sxevf_ring_feature_init'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ring.c:19: warning: Function parameter or member 'adapter' not described in 'sxevf_ring_feature_init'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_rx_proc.c:362:6: error: no previous prototype for 'sxevf_rx_ring_buffers_alloc' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:127:5: error: no previous prototype for 'sxevf_tx_ring_alloc' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:703:38: error: suggest braces around empty body in an 'if' statement [-Werror=empty-body]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:703:66: error: suggest braces around empty body in an 'if' statement [-Werror=empty-body]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:838:57: error: suggest braces around empty body in an 'else' statement [-Werror=empty-body]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:838:71: error: suggest braces around empty body in an 'else' statement [-Werror=empty-body]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:88:6: error: no previous prototype for 'sxevf_tx_ring_free' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:23: warning: Excess function parameter 'author' description in 'bpf_warn_invalid_xdp_action_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:23: warning: Excess function parameter 'date' description in 'bpf_warn_invalid_xdp_action_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:23: warning: Excess function parameter 'file' description in 'bpf_warn_invalid_xdp_action_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:23: warning: Function parameter or member 'act' not described in 'bpf_warn_invalid_xdp_action_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:23: warning: Function parameter or member 'dev' not described in 'bpf_warn_invalid_xdp_action_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:23: warning: Function parameter or member 'prog' not described in 'bpf_warn_invalid_xdp_action_compat'
include/linux/backing-dev.h:430:49: warning: 'struct cgroup_subsys' declared inside parameter list will not be visible outside of this definition or declaration
include/linux/backing-dev.h:430:49: warning: declaration of 'struct cgroup_subsys' will not be visible outside of this function [-Wvisibility]
include/linux/blk_types.h: linux/kabi.h is included more than once.
include/linux/cred.h: linux/kabi.h is included more than once.
include/linux/device.h: linux/kabi.h is included more than once.
include/linux/device/class.h: linux/kabi.h is included more than once.
include/linux/ioport.h: linux/kabi.h is included more than once.
include/linux/minmax.h:20:28: warning: comparison of distinct pointer types lacks a cast
include/linux/minmax.h:20:35: warning: comparison of distinct pointer types lacks a cast
include/linux/mm.h: linux/kabi.h is included more than once.
include/linux/swap.h: linux/kabi.h is included more than once.
kismet: WARNING: unmet direct dependencies detected for PGP_KEY_PARSER when selected by PGP_PRELOAD
kismet: WARNING: unmet direct dependencies detected for PGP_PRELOAD when selected by PGP_PRELOAD_PUBLIC_KEYS
kismet: WARNING: unmet direct dependencies detected for PTP_1588_CLOCK when selected by SXE
kismet: WARNING: unmet direct dependencies detected for PTP_1588_CLOCK when selected by SXE_VF
samples/bpf/hbm.c: bpf/bpf.h is included more than once.
Unverified Error/Warning (likely false positive, kindly check if interested):
mm/vmscan.o: warning: objtool: do_shrink_slab() falls through to next function pageout()
Error/Warning ids grouped by kconfigs:
recent_errors
|-- arm64-allnoconfig
| `-- include-linux-backing-dev.h:warning:struct-cgroup_subsys-declared-inside-parameter-list-will-not-be-visible-outside-of-this-definition-or-declaration
|-- arm64-defconfig
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-author-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-date-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-file-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-author-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-date-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-file-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-author-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-date-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-file-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_entries_exit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_entries_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_exit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-sxe_phys_id_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-sxe_reg_test
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:cannot-understand-function-prototype:dev_t-sxe_cdev_major
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:cannot-understand-function-prototype:atomic_t-hdc_available-ATOMIC_INIT()
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_fc_autoneg_localcap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_all_irq_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_all_ring_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_crc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_max_mem_window_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_pfc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_rate_limiter_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_rx_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_data_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_desc_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_ring_rate_factor_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_event_irq_auto_clear_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_event_irq_map
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_autoneg_disable_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_mac_addr_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_requested_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_tc_high_water_mark_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_tc_low_water_mark_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_port_mask_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_sample_rule_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_sample_rules_table_reinit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_add
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_mask_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_channel_state_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_drv_status_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_ack_header_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_ov_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_status_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_is_fw_over_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_lock_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_lock_release
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_data_dword_rcv
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_data_dword_send
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_header_send
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_send_done
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_cause_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_general_reg_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_general_reg_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_is_fc_autoneg_disabled
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_is_link_state_up
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_link_speed_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_link_speed_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_loopback_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_max_frame_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_max_frame_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_pad_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_txrx_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mbx_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mbx_mem_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mc_filter_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mc_filter_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mta_hash_table_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mta_hash_table_update
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_nic_reset
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_no_snoop_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pcie_vt_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pending_irq_read_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pending_irq_write_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pf_rst_done_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pfc_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_mac_anti_spoof_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_mode_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_ring_drop_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_is_rx_timestamp_valid
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_rx_timestamp_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_rx_timestamp_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_systime_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_systime_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_timestamp_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_timestamp_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_tx_timestamp_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rcv_msg_from_vf
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_auto_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_interval_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_map
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_key_set_all
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_redir_tbl_reg_write
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_redir_tbl_set_all
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_cap_switch_off
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_cap_switch_on
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_desc_thresh_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_dma_ctrl_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_dma_lro_ctrl_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_drop_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_ack_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_mode_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_multi_ring_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_nfs_filter_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pkt_buf_size_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pool_bitmap_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pool_bitmap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_queue_desc_reg_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_rcv_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_switch_not_polling
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_udp_frag_checksum_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_send_msg_to_vf
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_specific_irq_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_specific_irq_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_spoof_count_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_regs_clean
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_seq_clean
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_desc_thresh_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_size_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_thresh_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pool_bitmap_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pool_bitmap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_head_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_info_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_switch_not_polling
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_tail_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_vlan_insert_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_vlan_tag_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_add
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_pool_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_pool_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_ack_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_req_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_rst_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_write
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_pool_filter_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_tag_strip_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlvf_slot_find
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_ctrl_cfg
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_pool_loopback_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_disable_dcb
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_disable_rss
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_lsc_irq_handler
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_mailbox_irq_handler
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_msi_irq_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-sxe_allow_inval_mac
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-author-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-date-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-file-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-author-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-date-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-file-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-dev-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-hw-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-sxe_multispeed_sfp_link_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-author-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-date-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-file-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Function-parameter-or-member-cc-not-described-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-author-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-date-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-file-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-sxe_headers_cleanup
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-sxe_rx_buffer_page_offset_update
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-sxe_set_vf_link_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-author-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-date-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-file-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-sxe_txrx_ring_enable
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-author-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-date-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-file-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-author-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-date-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-file-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_32bit_counter_update
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_36bit_counter_update
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_event_irq_map
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_reset
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_ring_irq_map
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_stop
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_irq_disable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_irq_enable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_link_state_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_mailbox_read
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_mailbox_write
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_msg_read
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_msg_write
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_packet_stats_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_pf_ack_irq_trigger
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_pf_req_irq_trigger
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_ring_irq_interval_set
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_rcv_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_specific_irq_enable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_stats_init_value_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_tx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-author-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-date-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-file-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-dev-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-napi-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-poll-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-weight-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-author-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-date-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-file-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-author-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-date-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-file-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-author-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-date-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-file-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-author-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-date-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-file-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-author-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-date-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-file-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-sxevf_rx_ring_buffers_alloc
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-sxevf_tx_ring_alloc
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-sxevf_tx_ring_free
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:suggest-braces-around-empty-body-in-an-else-statement
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-author-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-date-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-file-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-act-not-described-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-dev-not-described-in-bpf_warn_invalid_xdp_action_compat
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-prog-not-described-in-bpf_warn_invalid_xdp_action_compat
|-- arm64-randconfig-001-20250509
| |-- include-linux-backing-dev.h:warning:struct-cgroup_subsys-declared-inside-parameter-list-will-not-be-visible-outside-of-this-definition-or-declaration
| `-- include-linux-minmax.h:warning:comparison-of-distinct-pointer-types-lacks-a-cast
|-- arm64-randconfig-002-20250509
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-author-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-date-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-file-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-author-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-date-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-file-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-author-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-date-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-file-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:cannot-understand-function-prototype:dev_t-sxe_cdev_major
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:cannot-understand-function-prototype:atomic_t-hdc_available-ATOMIC_INIT()
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:sxe_resume-defined-but-not-used
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:sxe_suspend-defined-but-not-used
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-author-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-date-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-file-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-author-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-date-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-file-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-dev-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-hw-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-author-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-date-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-file-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Function-parameter-or-member-cc-not-described-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-author-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-date-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-file-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-author-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-date-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-file-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-author-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-date-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-file-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-author-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-date-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-file-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-author-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-date-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-file-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-dev-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-napi-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-poll-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-weight-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:error:sxevf_resume-defined-but-not-used
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-author-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-date-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-file-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-author-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-date-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-file-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-author-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-date-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-file-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-author-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-date-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-file-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:suggest-braces-around-empty-body-in-an-else-statement
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-author-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-date-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-file-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-act-not-described-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-dev-not-described-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-prog-not-described-in-bpf_warn_invalid_xdp_action_compat
| `-- include-linux-backing-dev.h:warning:struct-cgroup_subsys-declared-inside-parameter-list-will-not-be-visible-outside-of-this-definition-or-declaration
|-- x86_64-allnoconfig
| |-- drivers-net-ethernet-huawei-hinic3-cqm-cqm_memsec.c::need-linux-version.h
| |-- drivers-net-ethernet-linkdata-sxe-base-compat-sxe_compat.h:linux-version.h-not-needed.
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:linux-moduleparam.h-is-included-more-than-once.
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:sxe_netdev.h-is-included-more-than-once.
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:sxe_ipsec.h-is-included-more-than-once.
| |-- drivers-net-ethernet-linkdata-sxevf-base-compat-sxe_compat.h:linux-version.h-not-needed.
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf.h:sxe_errno.h-is-included-more-than-once.
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:sxevf.h-is-included-more-than-once.
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:sxevf_hw.h-is-included-more-than-once.
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:sxevf_hw.h-is-included-more-than-once.
| |-- include-linux-backing-dev.h:warning:declaration-of-struct-cgroup_subsys-will-not-be-visible-outside-of-this-function
| |-- include-linux-blk_types.h:linux-kabi.h-is-included-more-than-once.
| |-- include-linux-cred.h:linux-kabi.h-is-included-more-than-once.
| |-- include-linux-device-class.h:linux-kabi.h-is-included-more-than-once.
| |-- include-linux-device.h:linux-kabi.h-is-included-more-than-once.
| |-- include-linux-ioport.h:linux-kabi.h-is-included-more-than-once.
| |-- include-linux-mm.h:linux-kabi.h-is-included-more-than-once.
| |-- include-linux-swap.h:linux-kabi.h-is-included-more-than-once.
| |-- kismet:WARNING:unmet-direct-dependencies-detected-for-PGP_KEY_PARSER-when-selected-by-PGP_PRELOAD
| |-- kismet:WARNING:unmet-direct-dependencies-detected-for-PGP_PRELOAD-when-selected-by-PGP_PRELOAD_PUBLIC_KEYS
| |-- kismet:WARNING:unmet-direct-dependencies-detected-for-PTP_1588_CLOCK-when-selected-by-SXE
| |-- kismet:WARNING:unmet-direct-dependencies-detected-for-PTP_1588_CLOCK-when-selected-by-SXE_VF
| `-- samples-bpf-hbm.c:bpf-bpf.h-is-included-more-than-once.
|-- x86_64-allyesconfig
| |-- drivers-net-ethernet-huawei-hinic3-cqm-cqm_cmd.c:warning:no-previous-prototype-for-function-cqm3_lb_send_cmd_box_async
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_dbg.c:warning:variable-cos_num-set-but-not-used
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_ethtool_stats.c:warning:no-previous-prototype-for-function-hinic3_rx_queue_stat_pack
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_ethtool_stats.c:warning:no-previous-prototype-for-function-hinic3_tx_queue_stat_pack
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_mag_cfg.c:warning:no-previous-prototype-for-function-get_fecparam
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_mag_cfg.c:warning:no-previous-prototype-for-function-hinic3_notify_all_vfs_bond_changed
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_mag_cfg.c:warning:no-previous-prototype-for-function-hinic3_notify_vf_bond_status
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_mag_cfg.c:warning:no-previous-prototype-for-function-print_port_info
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_mag_cfg.c:warning:no-previous-prototype-for-function-set_fecparam
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_main.c:warning:no-previous-prototype-for-function-hinic3_need_proc_bond_event
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_main.c:warning:no-previous-prototype-for-function-hinic3_need_proc_link_event
| |-- drivers-net-ethernet-huawei-hinic3-hinic3_netdev_ops.c:warning:variable-size-set-but-not-used
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_dev_mgmt.c:warning:no-previous-prototype-for-function-hinic3_write_oshr_info
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_hw_api.c:warning:Function-parameter-or-member-instance-not-described-in-hinic3_sm_ctr_rd16_clear
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_hw_comm.c:warning:no-previous-prototype-for-function-hinic3_is_optical_module_mode
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_hwif.c:warning:no-previous-prototype-for-function-hinic3_global_func_id_hw
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_lld.c:warning:no-previous-prototype-for-function-__set_vroce_func_state
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_lld.c:warning:no-previous-prototype-for-function-hinic3_get_roce_uld_by_pdev
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_lld.c:warning:no-previous-prototype-for-function-hinic3_pdev_is_virtfn
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_lld.c:warning:no-previous-prototype-for-function-hinic3_set_func_state
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_lld.c:warning:no-previous-prototype-for-function-slave_host_mgmt_vroce_work
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_lld.c:warning:no-previous-prototype-for-function-slave_host_mgmt_work
| |-- drivers-net-ethernet-huawei-hinic3-hw-hinic3_sriov.c:warning:no-previous-prototype-for-function-hinic3_pci_sriov_check
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-author-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-date-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-file-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-author-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-date-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-file-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-author-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-date-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-file-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:cannot-understand-function-prototype:dev_t-sxe_cdev_major
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:cannot-understand-function-prototype:atomic_t-hdc_available-ATOMIC_INIT()
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-author-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-date-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-file-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-author-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-date-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-file-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-dev-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-hw-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-author-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-date-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-file-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Function-parameter-or-member-cc-not-described-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-author-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-date-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-file-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-author-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-date-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-file-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-author-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-date-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-file-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-author-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-date-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-file-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-author-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-date-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-file-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-dev-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-napi-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-poll-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-weight-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-author-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-date-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-file-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-author-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-date-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-file-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-author-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-date-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-file-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-author-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-date-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-file-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-author-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-date-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-file-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-author-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-date-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-file-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-act-not-described-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-dev-not-described-in-bpf_warn_invalid_xdp_action_compat
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-prog-not-described-in-bpf_warn_invalid_xdp_action_compat
|-- x86_64-buildonly-randconfig-002-20250509
| |-- include-linux-backing-dev.h:warning:struct-cgroup_subsys-declared-inside-parameter-list-will-not-be-visible-outside-of-this-definition-or-declaration
| `-- include-linux-minmax.h:warning:comparison-of-distinct-pointer-types-lacks-a-cast
|-- x86_64-buildonly-randconfig-003-20250509
| `-- include-linux-backing-dev.h:warning:declaration-of-struct-cgroup_subsys-will-not-be-visible-outside-of-this-function
|-- x86_64-buildonly-randconfig-005-20250509
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-author-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-date-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-file-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-author-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-date-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-file-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-author-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-date-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-file-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_entries_exit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_entries_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_exit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-sxe_phys_id_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-sxe_reg_test
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:cannot-understand-function-prototype:dev_t-sxe_cdev_major
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:cannot-understand-function-prototype:atomic_t-hdc_available-ATOMIC_INIT()
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_fc_autoneg_localcap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_all_irq_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_all_ring_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_crc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_max_mem_window_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_pfc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_rate_limiter_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_rx_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_data_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_desc_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_ring_rate_factor_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_event_irq_auto_clear_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_event_irq_map
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_autoneg_disable_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_mac_addr_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_requested_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_tc_high_water_mark_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_tc_low_water_mark_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_port_mask_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_sample_rule_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_sample_rules_table_reinit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_add
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_mask_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_channel_state_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_drv_status_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_ack_header_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_ov_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_status_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_is_fw_over_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_lock_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_lock_release
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_data_dword_rcv
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_data_dword_send
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_header_send
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_send_done
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_cause_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_general_reg_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_general_reg_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_is_fc_autoneg_disabled
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_is_link_state_up
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_link_speed_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_link_speed_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_loopback_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_max_frame_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_max_frame_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_pad_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_txrx_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mbx_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mbx_mem_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mc_filter_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mc_filter_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mta_hash_table_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mta_hash_table_update
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_nic_reset
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_no_snoop_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pcie_vt_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pending_irq_read_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pending_irq_write_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pf_rst_done_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pfc_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_mac_anti_spoof_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_mode_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_ring_drop_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_is_rx_timestamp_valid
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_rx_timestamp_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_rx_timestamp_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_systime_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_systime_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_timestamp_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_timestamp_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_tx_timestamp_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rcv_msg_from_vf
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_auto_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_interval_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_map
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_key_set_all
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_redir_tbl_reg_write
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_redir_tbl_set_all
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_cap_switch_off
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_cap_switch_on
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_desc_thresh_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_dma_ctrl_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_dma_lro_ctrl_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_drop_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_ack_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_mode_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_multi_ring_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_nfs_filter_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pkt_buf_size_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pool_bitmap_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pool_bitmap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_queue_desc_reg_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_rcv_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_switch_not_polling
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_udp_frag_checksum_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_send_msg_to_vf
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_specific_irq_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_specific_irq_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_spoof_count_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_regs_clean
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_seq_clean
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_desc_thresh_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_size_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_thresh_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pool_bitmap_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pool_bitmap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_head_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_info_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_switch_not_polling
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_tail_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_vlan_insert_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_vlan_tag_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_add
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_pool_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_pool_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_ack_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_req_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_rst_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_write
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_pool_filter_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_tag_strip_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlvf_slot_find
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_ctrl_cfg
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_pool_loopback_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_disable_dcb
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_disable_rss
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_lsc_irq_handler
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_mailbox_irq_handler
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_msi_irq_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-sxe_allow_inval_mac
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:sxe_resume-defined-but-not-used
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:sxe_suspend-defined-but-not-used
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-author-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-date-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-file-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-author-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-date-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-file-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-dev-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-hw-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-sxe_multispeed_sfp_link_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-author-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-date-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-file-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Function-parameter-or-member-cc-not-described-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-author-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-date-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-file-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-sxe_headers_cleanup
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-sxe_rx_buffer_page_offset_update
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-sxe_set_vf_link_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-author-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-date-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-file-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-sxe_txrx_ring_enable
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-author-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-date-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-file-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-author-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-date-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-file-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_32bit_counter_update
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_36bit_counter_update
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_event_irq_map
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_reset
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_ring_irq_map
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_stop
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_irq_disable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_irq_enable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_link_state_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_mailbox_read
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_mailbox_write
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_msg_read
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_msg_write
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_packet_stats_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_pf_ack_irq_trigger
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_pf_req_irq_trigger
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_ring_irq_interval_set
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_rcv_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_specific_irq_enable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_stats_init_value_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_tx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-author-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-date-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-file-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-dev-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-napi-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-poll-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-weight-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:error:sxevf_resume-defined-but-not-used
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-author-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-date-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-file-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-author-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-date-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-file-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-author-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-date-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-file-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-author-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-date-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-file-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-sxevf_rx_ring_buffers_alloc
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-sxevf_tx_ring_alloc
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-sxevf_tx_ring_free
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:suggest-braces-around-empty-body-in-an-else-statement
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-author-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-date-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-file-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-act-not-described-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-dev-not-described-in-bpf_warn_invalid_xdp_action_compat
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-prog-not-described-in-bpf_warn_invalid_xdp_action_compat
|-- x86_64-buildonly-randconfig-006-20250509
| `-- include-linux-backing-dev.h:warning:struct-cgroup_subsys-declared-inside-parameter-list-will-not-be-visible-outside-of-this-definition-or-declaration
|-- x86_64-defconfig
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-author-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-date-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-file-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-author-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-date-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-file-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-author-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-date-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-file-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_entries_exit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_entries_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_exit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-sxe_phys_id_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-sxe_reg_test
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:cannot-understand-function-prototype:dev_t-sxe_cdev_major
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:cannot-understand-function-prototype:atomic_t-hdc_available-ATOMIC_INIT()
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_fc_autoneg_localcap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_all_irq_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_all_ring_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_crc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_max_mem_window_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_pfc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_rate_limiter_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_rx_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_data_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_desc_bw_alloc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_ring_rate_factor_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_event_irq_auto_clear_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_event_irq_map
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_autoneg_disable_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_mac_addr_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_requested_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_tc_high_water_mark_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_tc_low_water_mark_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_port_mask_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_sample_rule_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_sample_rules_table_reinit
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_add
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_mask_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_channel_state_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_drv_status_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_ack_header_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_ov_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_status_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_is_fw_over_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_lock_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_lock_release
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_data_dword_rcv
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_data_dword_send
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_header_send
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_send_done
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_cause_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_general_reg_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_general_reg_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_is_fc_autoneg_disabled
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_is_link_state_up
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_link_speed_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_link_speed_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_loopback_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_max_frame_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_max_frame_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_pad_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_txrx_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mbx_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mbx_mem_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mc_filter_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mc_filter_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mta_hash_table_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mta_hash_table_update
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_nic_reset
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_no_snoop_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pcie_vt_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pending_irq_read_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pending_irq_write_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pf_rst_done_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pfc_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_mac_anti_spoof_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_mode_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_ring_drop_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_is_rx_timestamp_valid
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_rx_timestamp_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_rx_timestamp_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_systime_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_systime_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_timestamp_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_timestamp_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_tx_timestamp_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rcv_msg_from_vf
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_auto_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_interval_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_map
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_key_set_all
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_redir_tbl_reg_write
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_redir_tbl_set_all
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_cap_switch_off
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_cap_switch_on
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_desc_thresh_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_dma_ctrl_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_dma_lro_ctrl_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_drop_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_ack_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_mode_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_mode_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_multi_ring_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_nfs_filter_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pkt_buf_size_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pool_bitmap_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pool_bitmap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_queue_desc_reg_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_rcv_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_switch_not_polling
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_udp_frag_checksum_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_send_msg_to_vf
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_specific_irq_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_specific_irq_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_spoof_count_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_regs_clean
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_seq_clean
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_desc_thresh_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_size_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_thresh_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pool_bitmap_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pool_bitmap_set
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_head_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_info_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_switch_not_polling
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_tail_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_vlan_insert_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_vlan_tag_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_add
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_pool_del
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_pool_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_ack_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_req_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_rst_check
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_clear
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_write
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_pool_filter_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_tag_strip_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlvf_slot_find
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_ctrl_cfg
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_disable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_pool_loopback_switch
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_disable_dcb
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_disable_rss
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_lsc_irq_handler
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_mailbox_irq_handler
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_msi_irq_init
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-sxe_allow_inval_mac
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-author-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-date-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-file-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-author-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-date-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-file-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-dev-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-hw-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-sxe_multispeed_sfp_link_configure
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-author-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-date-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-file-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Function-parameter-or-member-cc-not-described-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-author-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-date-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-file-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-sxe_headers_cleanup
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-sxe_rx_buffer_page_offset_update
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-sxe_set_vf_link_enable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-author-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-date-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-file-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-sxe_txrx_ring_enable
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-author-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-date-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-file-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-author-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-date-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-file-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_32bit_counter_update
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_36bit_counter_update
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_event_irq_map
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_reset
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_ring_irq_map
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_stop
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_irq_disable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_irq_enable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_link_state_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_mailbox_read
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_mailbox_write
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_msg_read
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_msg_write
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_packet_stats_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_pf_ack_irq_trigger
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_pf_req_irq_trigger
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_ring_irq_interval_set
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_rcv_ctl_configure
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_ring_desc_configure
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_specific_irq_enable
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_stats_init_value_get
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_tx_ring_switch
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-author-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-date-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-file-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-dev-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-napi-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-poll-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-weight-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-author-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-date-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-file-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-author-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-date-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-file-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-author-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-date-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-file-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-author-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-date-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-file-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-author-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-date-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-file-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-sxevf_rx_ring_buffers_alloc
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-sxevf_tx_ring_alloc
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-sxevf_tx_ring_free
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:suggest-braces-around-empty-body-in-an-else-statement
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:suggest-braces-around-empty-body-in-an-if-statement
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-author-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-date-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-file-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-act-not-described-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-dev-not-described-in-bpf_warn_invalid_xdp_action_compat
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-prog-not-described-in-bpf_warn_invalid_xdp_action_compat
|-- x86_64-randconfig-161-20250509
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-author-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-date-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-file-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-author-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-date-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-file-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-author-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-date-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-file-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:cannot-understand-function-prototype:dev_t-sxe_cdev_major
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:cannot-understand-function-prototype:atomic_t-hdc_available-ATOMIC_INIT()
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-author-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-date-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-file-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-author-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-date-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-file-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-dev-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-hw-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-author-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-date-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-file-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Function-parameter-or-member-cc-not-described-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-author-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-date-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-file-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-author-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-date-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-file-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-author-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-date-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-file-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-author-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-date-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-file-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-author-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-date-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-file-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-dev-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-napi-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-poll-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-weight-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-author-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-date-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-file-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-author-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-date-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-file-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-author-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-date-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-file-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-author-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-date-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-file-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-author-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-date-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-file-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-author-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-date-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-file-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-act-not-described-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-dev-not-described-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-prog-not-described-in-bpf_warn_invalid_xdp_action_compat
| `-- mm-vmscan.o:warning:objtool:do_shrink_slab-falls-through-to-next-function-pageout()
`-- x86_64-rhel-9.4-rust
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
|-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
|-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-author-description-in-sxe_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-date-description-in-sxe_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-file-description-in-sxe_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxe_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxe_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-author-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-date-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-file-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-author-description-in-BIT_PFC
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-date-description-in-BIT_PFC
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-file-description-in-BIT_PFC
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:cannot-understand-function-prototype:dev_t-sxe_cdev_major
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:cannot-understand-function-prototype:atomic_t-hdc_available-ATOMIC_INIT()
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-author-description-in-SXE_HW_REINIT_SRIOV_DELAY
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-date-description-in-SXE_HW_REINIT_SRIOV_DELAY
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-file-description-in-SXE_HW_REINIT_SRIOV_DELAY
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-author-description-in-sxe_check_cfg_fault
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-date-description-in-sxe_check_cfg_fault
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-file-description-in-sxe_check_cfg_fault
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-dev-not-described-in-sxe_check_cfg_fault
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-hw-not-described-in-sxe_check_cfg_fault
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-author-description-in-sxe_ptp_read
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-date-description-in-sxe_ptp_read
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-file-description-in-sxe_ptp_read
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Function-parameter-or-member-cc-not-described-in-sxe_ptp_read
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-author-description-in-sxe_rss_num_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-date-description-in-sxe_rss_num_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-file-description-in-sxe_rss_num_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxe_rss_num_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-author-description-in-SXE_SKB_MIN_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-date-description-in-SXE_SKB_MIN_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-file-description-in-SXE_SKB_MIN_LEN
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
|-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
|-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-author-description-in-sxevf_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-date-description-in-sxevf_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-file-description-in-sxevf_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxevf_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxevf_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-author-description-in-SXEVF_DIAG_REGS_TEST
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-date-description-in-SXEVF_DIAG_REGS_TEST
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-file-description-in-SXEVF_DIAG_REGS_TEST
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-author-description-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-date-description-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-file-description-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-dev-not-described-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-napi-not-described-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-poll-not-described-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-weight-not-described-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-author-description-in-SXEVF_MSG_LEVEL_DEFAULT
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-date-description-in-SXEVF_MSG_LEVEL_DEFAULT
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-file-description-in-SXEVF_MSG_LEVEL_DEFAULT
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-author-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-date-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-file-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-author-description-in-SXEVF_PFMSG_MASK
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-date-description-in-SXEVF_PFMSG_MASK
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-file-description-in-SXEVF_PFMSG_MASK
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-author-description-in-SXEVF_MAX_MAC_HDR_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-date-description-in-SXEVF_MAX_MAC_HDR_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-file-description-in-SXEVF_MAX_MAC_HDR_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-author-description-in-sxevf_ring_feature_init
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-date-description-in-sxevf_ring_feature_init
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-file-description-in-sxevf_ring_feature_init
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxevf_ring_feature_init
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-author-description-in-bpf_warn_invalid_xdp_action_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-date-description-in-bpf_warn_invalid_xdp_action_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-file-description-in-bpf_warn_invalid_xdp_action_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-act-not-described-in-bpf_warn_invalid_xdp_action_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-dev-not-described-in-bpf_warn_invalid_xdp_action_compat
`-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-prog-not-described-in-bpf_warn_invalid_xdp_action_compat
elapsed time: 728m
configs tested: 17
configs skipped: 128
tested configs:
arm64 allmodconfig clang-19
arm64 allnoconfig gcc-14.2.0
arm64 defconfig gcc-14.2.0
arm64 randconfig-001-20250509 gcc-7.5.0
arm64 randconfig-002-20250509 gcc-7.5.0
arm64 randconfig-003-20250509 clang-21
arm64 randconfig-004-20250509 gcc-5.5.0
x86_64 allnoconfig clang-20
x86_64 allyesconfig clang-20
x86_64 buildonly-randconfig-001-20250509 gcc-11
x86_64 buildonly-randconfig-002-20250509 gcc-11
x86_64 buildonly-randconfig-003-20250509 clang-20
x86_64 buildonly-randconfig-004-20250509 clang-20
x86_64 buildonly-randconfig-005-20250509 gcc-12
x86_64 buildonly-randconfig-006-20250509 gcc-12
x86_64 defconfig gcc-11
x86_64 rhel-9.4-rust clang-18
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-5.10 2891/2891] drivers/net/ethernet/huawei/hinic3/hinic3_main.c:1211:6: warning: no previous prototype for function 'hinic3_need_proc_link_event'
by kernel test robot 09 May '25
by kernel test robot 09 May '25
09 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-5.10
head: 2e5032bf08eca1f3b062773540ff27c51788390d
commit: 79871cd2cd720225eb582c9ed49fb4a96a270b3b [2891/2891] net/hinic3: Synchronize new NIC features and bug fixes
config: x86_64-allyesconfig (https://download.01.org/0day-ci/archive/20250510/202505100150.DG1QGwH3-lkp@…)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250510/202505100150.DG1QGwH3-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505100150.DG1QGwH3-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c:1671:6: warning: no previous prototype for function 'hinic3_is_optical_module_mode' [-Wmissing-prototypes]
1671 | bool hinic3_is_optical_module_mode(void *hwdev)
| ^
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c:1671:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
1671 | bool hinic3_is_optical_module_mode(void *hwdev)
| ^
| static
1 warning generated.
--
>> drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c:176:5: warning: no previous prototype for function 'hinic3_pci_sriov_check' [-Wmissing-prototypes]
176 | int hinic3_pci_sriov_check(struct hinic3_sriov_info *sriov_info, struct pci_dev *dev, int num_vfs)
| ^
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c:176:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
176 | int hinic3_pci_sriov_check(struct hinic3_sriov_info *sriov_info, struct pci_dev *dev, int num_vfs)
| ^
| static
1 warning generated.
--
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:103:6: warning: no previous prototype for function 'hinic3_uld_lock_init' [-Wmissing-prototypes]
103 | void hinic3_uld_lock_init(void)
| ^
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:103:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
103 | void hinic3_uld_lock_init(void)
| ^
| static
>> drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:525:5: warning: no previous prototype for function 'hinic3_pdev_is_virtfn' [-Wmissing-prototypes]
525 | u32 hinic3_pdev_is_virtfn(struct pci_dev *pdev)
| ^
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:525:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
525 | u32 hinic3_pdev_is_virtfn(struct pci_dev *pdev)
| ^
| static
>> drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:785:5: warning: no previous prototype for function '__set_vroce_func_state' [-Wmissing-prototypes]
785 | int __set_vroce_func_state(struct hinic3_pcidev *pci_adapter)
| ^
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:785:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
785 | int __set_vroce_func_state(struct hinic3_pcidev *pci_adapter)
| ^
| static
>> drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:826:6: warning: no previous prototype for function 'slave_host_mgmt_vroce_work' [-Wmissing-prototypes]
826 | void slave_host_mgmt_vroce_work(struct work_struct *work)
| ^
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:826:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
826 | void slave_host_mgmt_vroce_work(struct work_struct *work)
| ^
| static
>> drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:834:7: warning: no previous prototype for function 'hinic3_get_roce_uld_by_pdev' [-Wmissing-prototypes]
834 | void *hinic3_get_roce_uld_by_pdev(struct pci_dev *pdev)
| ^
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:834:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
834 | void *hinic3_get_roce_uld_by_pdev(struct pci_dev *pdev)
| ^
| static
>> drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:1796:6: warning: no previous prototype for function 'hinic3_set_func_state' [-Wmissing-prototypes]
1796 | void hinic3_set_func_state(struct hinic3_pcidev *pci_adapter)
| ^
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:1796:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
1796 | void hinic3_set_func_state(struct hinic3_pcidev *pci_adapter)
| ^
| static
>> drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:1822:6: warning: no previous prototype for function 'slave_host_mgmt_work' [-Wmissing-prototypes]
1822 | void slave_host_mgmt_work(struct work_struct *work)
| ^
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c:1822:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
1822 | void slave_host_mgmt_work(struct work_struct *work)
| ^
| static
7 warnings generated.
--
>> drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c:618:6: warning: no previous prototype for function 'hinic3_write_oshr_info' [-Wmissing-prototypes]
618 | void hinic3_write_oshr_info(struct os_hot_replace_info *out_oshr_info,
| ^
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c:618:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
618 | void hinic3_write_oshr_info(struct os_hot_replace_info *out_oshr_info,
| ^
| static
1 warning generated.
--
>> drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:865:5: warning: no previous prototype for function 'hinic3_global_func_id_hw' [-Wmissing-prototypes]
865 | u16 hinic3_global_func_id_hw(void *hwdev)
| ^
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c:865:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
865 | u16 hinic3_global_func_id_hw(void *hwdev)
| ^
| static
1 warning generated.
--
>> drivers/net/ethernet/huawei/hinic3/hinic3_main.c:1211:6: warning: no previous prototype for function 'hinic3_need_proc_link_event' [-Wmissing-prototypes]
1211 | bool hinic3_need_proc_link_event(struct hinic3_lld_dev *lld_dev)
| ^
drivers/net/ethernet/huawei/hinic3/hinic3_main.c:1211:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
1211 | bool hinic3_need_proc_link_event(struct hinic3_lld_dev *lld_dev)
| ^
| static
>> drivers/net/ethernet/huawei/hinic3/hinic3_main.c:1258:6: warning: no previous prototype for function 'hinic3_need_proc_bond_event' [-Wmissing-prototypes]
1258 | bool hinic3_need_proc_bond_event(struct hinic3_lld_dev *lld_dev)
| ^
drivers/net/ethernet/huawei/hinic3/hinic3_main.c:1258:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
1258 | bool hinic3_need_proc_bond_event(struct hinic3_lld_dev *lld_dev)
| ^
| static
2 warnings generated.
--
>> drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c:342:5: warning: no previous prototype for function 'hinic3_rx_queue_stat_pack' [-Wmissing-prototypes]
342 | int hinic3_rx_queue_stat_pack(struct hinic3_show_item *item,
| ^
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c:342:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
342 | int hinic3_rx_queue_stat_pack(struct hinic3_show_item *item,
| ^
| static
>> drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c:357:5: warning: no previous prototype for function 'hinic3_tx_queue_stat_pack' [-Wmissing-prototypes]
357 | int hinic3_tx_queue_stat_pack(struct hinic3_show_item *item,
| ^
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c:357:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
357 | int hinic3_tx_queue_stat_pack(struct hinic3_show_item *item,
| ^
| static
2 warnings generated.
--
>> drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c:689:5: warning: variable 'cos_num' set but not used [-Wunused-but-set-variable]
689 | u8 cos_num, valid_cos_bitmap;
| ^
1 warning generated.
--
>> drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c:59:6: warning: variable 'size' set but not used [-Wunused-but-set-variable]
59 | u32 size;
| ^
drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c:1757:5: warning: no previous prototype for function 'hinic3_ndo_set_vf_link_state' [-Wmissing-prototypes]
1757 | int hinic3_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link)
| ^
drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c:1757:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
1757 | int hinic3_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link)
| ^
| static
2 warnings generated.
--
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c:54: warning: Function parameter or member 'instance' not described in 'hinic3_sm_ctr_rd16'
>> drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c:95: warning: Function parameter or member 'instance' not described in 'hinic3_sm_ctr_rd16_clear'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c:137: warning: Function parameter or member 'instance' not described in 'hinic3_sm_ctr_rd32'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c:179: warning: Function parameter or member 'instance' not described in 'hinic3_sm_ctr_rd32_clear'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c:222: warning: Function parameter or member 'instance' not described in 'hinic3_sm_ctr_rd64_pair'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c:277: warning: Function parameter or member 'instance' not described in 'hinic3_sm_ctr_rd64_pair_clear'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c:319: warning: Function parameter or member 'instance' not described in 'hinic3_sm_ctr_rd64'
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c:360: warning: Function parameter or member 'instance' not described in 'hinic3_sm_ctr_rd64_clear'
--
>> drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c:623:6: warning: no previous prototype for function 'print_port_info' [-Wmissing-prototypes]
623 | void print_port_info(struct hinic3_nic_io *nic_io,
| ^
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c:623:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
623 | void print_port_info(struct hinic3_nic_io *nic_io,
| ^
| static
>> drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c:802:6: warning: no previous prototype for function 'hinic3_notify_vf_bond_status' [-Wmissing-prototypes]
802 | void hinic3_notify_vf_bond_status(struct hinic3_nic_io *nic_io,
| ^
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c:802:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
802 | void hinic3_notify_vf_bond_status(struct hinic3_nic_io *nic_io,
| ^
| static
>> drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c:832:6: warning: no previous prototype for function 'hinic3_notify_all_vfs_bond_changed' [-Wmissing-prototypes]
832 | void hinic3_notify_all_vfs_bond_changed(void *hwdev, u8 bond_status)
| ^
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c:832:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
832 | void hinic3_notify_all_vfs_bond_changed(void *hwdev, u8 bond_status)
| ^
| static
>> drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c:1678:5: warning: no previous prototype for function 'set_fecparam' [-Wmissing-prototypes]
1678 | int set_fecparam(void *hwdev, u8 fecparam)
| ^
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c:1678:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
1678 | int set_fecparam(void *hwdev, u8 fecparam)
| ^
| static
>> drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c:1706:5: warning: no previous prototype for function 'get_fecparam' [-Wmissing-prototypes]
1706 | int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec)
| ^
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c:1706:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
1706 | int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec)
| ^
| static
5 warnings generated.
..
vim +/hinic3_need_proc_link_event +1211 drivers/net/ethernet/huawei/hinic3/hinic3_main.c
1210
> 1211 bool hinic3_need_proc_link_event(struct hinic3_lld_dev *lld_dev)
1212 {
1213 int ret = 0;
1214 u16 func_id;
1215 u8 roce_enable = false;
1216 bool is_slave_func = false;
1217 struct hinic3_hw_bond_infos hw_bond_infos = {0};
1218
1219 if (!lld_dev)
1220 return false;
1221
1222 /* 非slave设备需要处理link down事件 */
1223 ret = hinic3_is_slave_func(lld_dev->hwdev, &is_slave_func);
1224 if (ret != 0) {
1225 nic_err(&lld_dev->pdev->dev, "NIC get info, lld_dev is null\n");
1226 return true;
1227 }
1228
1229 if (!is_slave_func)
1230 return true;
1231
1232 /* 未使能了vroce功能,需处理link down事件 */
1233 func_id = hinic3_global_func_id(lld_dev->hwdev);
1234 ret = hinic3_get_func_vroce_enable(lld_dev->hwdev, func_id,
1235 &roce_enable);
1236 if (ret != 0)
1237 return true;
1238
1239 if (!roce_enable)
1240 return true;
1241
1242 /* 未创建bond,需要处理link down事件 */
1243 hw_bond_infos.bond_id = HINIC_OVS_BOND_DEFAULT_ID;
1244
1245 ret = hinic3_get_hw_bond_infos(lld_dev->hwdev, &hw_bond_infos,
1246 HINIC3_CHANNEL_COMM);
1247 if (ret != 0) {
1248 pr_err("[ROCE, ERR] Get chipf bond info failed (%d)\n", ret);
1249 return true;
1250 }
1251
1252 if (!hw_bond_infos.valid)
1253 return true;
1254
1255 return false;
1256 }
1257
> 1258 bool hinic3_need_proc_bond_event(struct hinic3_lld_dev *lld_dev)
1259 {
1260 return !hinic3_need_proc_link_event(lld_dev);
1261 }
1262
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[PATCH OLK-5.10] ext4: update s_journal_inum if it changes after journal replay
by Zizhi Wo 09 May '25
by Zizhi Wo 09 May '25
09 May '25
From: Baokun Li <libaokun1(a)huawei.com>
stable inclusion
from stable-v5.15.104
commit 499fef2030fb754c68b1c7cb3a799a3bc1d0d925
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC5DGP
CVE: CVE-2023-53091
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 3039d8b8692408438a618fac2776b629852663c3 ]
When mounting a crafted ext4 image, s_journal_inum may change after journal
replay, which is obviously unreasonable because we have successfully loaded
and replayed the journal through the old s_journal_inum. And the new
s_journal_inum bypasses some of the checks in ext4_get_journal(), which
may trigger a null pointer dereference problem. So if s_journal_inum
changes after the journal replay, we ignore the change, and rewrite the
current journal_inum to the superblock.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216541
Reported-by: Luís Henriques <lhenriques(a)suse.de>
Signed-off-by: Baokun Li <libaokun1(a)huawei.com>
Reviewed-by: Jan Kara <jack(a)suse.cz>
Link: https://lore.kernel.org/r/20230107032126.4165860-3-libaokun1@huawei.com
Signed-off-by: Theodore Ts'o <tytso(a)mit.edu>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Zizhi Wo <wozizhi(a)huawei.com>
---
fs/ext4/super.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 2adee3847415..6784c94e526e 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -5624,8 +5624,11 @@ static int ext4_load_journal(struct super_block *sb,
if (!really_read_only && journal_devnum &&
journal_devnum != le32_to_cpu(es->s_journal_dev)) {
es->s_journal_dev = cpu_to_le32(journal_devnum);
-
- /* Make sure we flush the recovery flag to disk. */
+ ext4_commit_super(sb);
+ }
+ if (!really_read_only && journal_inum &&
+ journal_inum != le32_to_cpu(es->s_journal_inum)) {
+ es->s_journal_inum = cpu_to_le32(journal_inum);
ext4_commit_super(sb);
}
--
2.39.2
2
1

[PATCH openEuler-1.0-LTS] ext4: update s_journal_inum if it changes after journal replay
by Zizhi Wo 09 May '25
by Zizhi Wo 09 May '25
09 May '25
From: Baokun Li <libaokun1(a)huawei.com>
stable inclusion
from stable-v5.15.104
commit 499fef2030fb754c68b1c7cb3a799a3bc1d0d925
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC5DGP
CVE: CVE-2023-53091
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 3039d8b8692408438a618fac2776b629852663c3 ]
When mounting a crafted ext4 image, s_journal_inum may change after journal
replay, which is obviously unreasonable because we have successfully loaded
and replayed the journal through the old s_journal_inum. And the new
s_journal_inum bypasses some of the checks in ext4_get_journal(), which
may trigger a null pointer dereference problem. So if s_journal_inum
changes after the journal replay, we ignore the change, and rewrite the
current journal_inum to the superblock.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216541
Reported-by: Luís Henriques <lhenriques(a)suse.de>
Signed-off-by: Baokun Li <libaokun1(a)huawei.com>
Reviewed-by: Jan Kara <jack(a)suse.cz>
Link: https://lore.kernel.org/r/20230107032126.4165860-3-libaokun1@huawei.com
Signed-off-by: Theodore Ts'o <tytso(a)mit.edu>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Zizhi Wo <wozizhi(a)huawei.com>
---
fs/ext4/super.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 8761fe5037a6..4ddf9bbbfd4b 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -5195,8 +5195,11 @@ static int ext4_load_journal(struct super_block *sb,
if (!really_read_only && journal_devnum &&
journal_devnum != le32_to_cpu(es->s_journal_dev)) {
es->s_journal_dev = cpu_to_le32(journal_devnum);
-
- /* Make sure we flush the recovery flag to disk. */
+ ext4_commit_super(sb);
+ }
+ if (!really_read_only && journal_inum &&
+ journal_inum != le32_to_cpu(es->s_journal_inum)) {
+ es->s_journal_inum = cpu_to_le32(journal_inum);
ext4_commit_super(sb);
}
--
2.39.2
2
1
From: Artem Sadovnikov <a.sadovnikov(a)ispras.ru>
stable inclusion
from stable-v5.10.237
commit 515c34cff899eb5dae6aa7eee01c1295b07d81af
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC5BIN
CVE: CVE-2025-23150
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 94824ac9a8aaf2fb3c54b4bdde842db80ffa555d upstream.
Syzkaller detected a use-after-free issue in ext4_insert_dentry that was
caused by out-of-bounds access due to incorrect splitting in do_split.
BUG: KASAN: use-after-free in ext4_insert_dentry+0x36a/0x6d0 fs/ext4/namei.c:2109
Write of size 251 at addr ffff888074572f14 by task syz-executor335/5847
CPU: 0 UID: 0 PID: 5847 Comm: syz-executor335 Not tainted 6.12.0-rc6-syzkaller-00318-ga9cda7c0ffed #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/30/2024
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:377 [inline]
print_report+0x169/0x550 mm/kasan/report.c:488
kasan_report+0x143/0x180 mm/kasan/report.c:601
kasan_check_range+0x282/0x290 mm/kasan/generic.c:189
__asan_memcpy+0x40/0x70 mm/kasan/shadow.c:106
ext4_insert_dentry+0x36a/0x6d0 fs/ext4/namei.c:2109
add_dirent_to_buf+0x3d9/0x750 fs/ext4/namei.c:2154
make_indexed_dir+0xf98/0x1600 fs/ext4/namei.c:2351
ext4_add_entry+0x222a/0x25d0 fs/ext4/namei.c:2455
ext4_add_nondir+0x8d/0x290 fs/ext4/namei.c:2796
ext4_symlink+0x920/0xb50 fs/ext4/namei.c:3431
vfs_symlink+0x137/0x2e0 fs/namei.c:4615
do_symlinkat+0x222/0x3a0 fs/namei.c:4641
__do_sys_symlink fs/namei.c:4662 [inline]
__se_sys_symlink fs/namei.c:4660 [inline]
__x64_sys_symlink+0x7a/0x90 fs/namei.c:4660
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
</TASK>
The following loop is located right above 'if' statement.
for (i = count-1; i >= 0; i--) {
/* is more than half of this entry in 2nd half of the block? */
if (size + map[i].size/2 > blocksize/2)
break;
size += map[i].size;
move++;
}
'i' in this case could go down to -1, in which case sum of active entries
wouldn't exceed half the block size, but previous behaviour would also do
split in half if sum would exceed at the very last block, which in case of
having too many long name files in a single block could lead to
out-of-bounds access and following use-after-free.
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Cc: stable(a)vger.kernel.org
Fixes: 5872331b3d91 ("ext4: fix potential negative array index in do_split()")
Signed-off-by: Artem Sadovnikov <a.sadovnikov(a)ispras.ru>
Reviewed-by: Jan Kara <jack(a)suse.cz>
Link: https://patch.msgid.link/20250404082804.2567-3-a.sadovnikov@ispras.ru
Signed-off-by: Theodore Ts'o <tytso(a)mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Zizhi Wo <wozizhi(a)huawei.com>
---
fs/ext4/namei.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index c5eddcd5106b..40e2ffc68990 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1958,7 +1958,7 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
* split it in half by count; each resulting block will have at least
* half the space free.
*/
- if (i > 0)
+ if (i >= 0)
split = count - move;
else
split = count/2;
--
2.39.2
2
1
From: Artem Sadovnikov <a.sadovnikov(a)ispras.ru>
stable inclusion
from stable-v5.10.237
commit 515c34cff899eb5dae6aa7eee01c1295b07d81af
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC5BIN
CVE: CVE-2025-23150
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 94824ac9a8aaf2fb3c54b4bdde842db80ffa555d upstream.
Syzkaller detected a use-after-free issue in ext4_insert_dentry that was
caused by out-of-bounds access due to incorrect splitting in do_split.
BUG: KASAN: use-after-free in ext4_insert_dentry+0x36a/0x6d0 fs/ext4/namei.c:2109
Write of size 251 at addr ffff888074572f14 by task syz-executor335/5847
CPU: 0 UID: 0 PID: 5847 Comm: syz-executor335 Not tainted 6.12.0-rc6-syzkaller-00318-ga9cda7c0ffed #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/30/2024
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:377 [inline]
print_report+0x169/0x550 mm/kasan/report.c:488
kasan_report+0x143/0x180 mm/kasan/report.c:601
kasan_check_range+0x282/0x290 mm/kasan/generic.c:189
__asan_memcpy+0x40/0x70 mm/kasan/shadow.c:106
ext4_insert_dentry+0x36a/0x6d0 fs/ext4/namei.c:2109
add_dirent_to_buf+0x3d9/0x750 fs/ext4/namei.c:2154
make_indexed_dir+0xf98/0x1600 fs/ext4/namei.c:2351
ext4_add_entry+0x222a/0x25d0 fs/ext4/namei.c:2455
ext4_add_nondir+0x8d/0x290 fs/ext4/namei.c:2796
ext4_symlink+0x920/0xb50 fs/ext4/namei.c:3431
vfs_symlink+0x137/0x2e0 fs/namei.c:4615
do_symlinkat+0x222/0x3a0 fs/namei.c:4641
__do_sys_symlink fs/namei.c:4662 [inline]
__se_sys_symlink fs/namei.c:4660 [inline]
__x64_sys_symlink+0x7a/0x90 fs/namei.c:4660
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
</TASK>
The following loop is located right above 'if' statement.
for (i = count-1; i >= 0; i--) {
/* is more than half of this entry in 2nd half of the block? */
if (size + map[i].size/2 > blocksize/2)
break;
size += map[i].size;
move++;
}
'i' in this case could go down to -1, in which case sum of active entries
wouldn't exceed half the block size, but previous behaviour would also do
split in half if sum would exceed at the very last block, which in case of
having too many long name files in a single block could lead to
out-of-bounds access and following use-after-free.
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Cc: stable(a)vger.kernel.org
Fixes: 5872331b3d91 ("ext4: fix potential negative array index in do_split()")
Signed-off-by: Artem Sadovnikov <a.sadovnikov(a)ispras.ru>
Reviewed-by: Jan Kara <jack(a)suse.cz>
Link: https://patch.msgid.link/20250404082804.2567-3-a.sadovnikov@ispras.ru
Signed-off-by: Theodore Ts'o <tytso(a)mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Zizhi Wo <wozizhi(a)huawei.com>
---
fs/ext4/namei.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index f2208337e5cb..28fb4c0c8a14 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1814,7 +1814,7 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
* split it in half by count; each resulting block will have at least
* half the space free.
*/
- if (i > 0)
+ if (i >= 0)
split = count - move;
else
split = count/2;
--
2.39.2
2
1
各位开发者和用户,
经2025年5月9日 openEuler Kernel SIG 会议讨论,拟定继续使用 6.6 内核支撑 openEuler 2026 年 LTS 版本发布,
特此公示。
公示时间:2025-5-9 18:00 - 2025-5-23 18:00, 公示14天。
公示期间,如果您有任何意见,请邮件反馈至:xiexiuqi@huawei.com,jason.zeng@intel.com,sanglipeng1@jd.com.
如需反馈意见,请说明您所在的团队,您的联系方式,并详细描述原因。您的反馈意见可能会在社区会议中公开讨论,请
不要包含保密信息。
openEuler Kernel SIG
2025年5月9日
1
0

[PATCH OLK-5.10] [Backport] backlight: led_bl: Hold led_access lock when calling led_sysfs_disable()
by Yuntao Liu 09 May '25
by Yuntao Liu 09 May '25
09 May '25
From: Herve Codina <herve.codina(a)bootlin.com>
stable inclusion
from stable-v5.10.237
commit 87d947a0607be384bfe7bb0935884a711e35ca07
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC5BJZ
CVE: CVE-2025-23144
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 276822a00db3c1061382b41e72cafc09d6a0ec30 ]
Lockdep detects the following issue on led-backlight removal:
[ 142.315935] ------------[ cut here ]------------
[ 142.315954] WARNING: CPU: 2 PID: 292 at drivers/leds/led-core.c:455 led_sysfs_enable+0x54/0x80
...
[ 142.500725] Call trace:
[ 142.503176] led_sysfs_enable+0x54/0x80 (P)
[ 142.507370] led_bl_remove+0x80/0xa8 [led_bl]
[ 142.511742] platform_remove+0x30/0x58
[ 142.515501] device_remove+0x54/0x90
...
Indeed, led_sysfs_enable() has to be called with the led_access
lock held.
Hold the lock when calling led_sysfs_disable().
Fixes: ae232e45acf9 ("backlight: add led-backlight driver")
Cc: stable(a)vger.kernel.org
Signed-off-by: Herve Codina <herve.codina(a)bootlin.com>
Link: https://lore.kernel.org/r/20250122091914.309533-1-herve.codina@bootlin.com
Signed-off-by: Lee Jones <lee(a)kernel.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
drivers/video/backlight/led_bl.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c
index f54d256e2d54..1020e4405a4d 100644
--- a/drivers/video/backlight/led_bl.c
+++ b/drivers/video/backlight/led_bl.c
@@ -226,8 +226,11 @@ static int led_bl_remove(struct platform_device *pdev)
backlight_device_unregister(bl);
led_bl_power_off(priv);
- for (i = 0; i < priv->nb_leds; i++)
+ for (i = 0; i < priv->nb_leds; i++) {
+ mutex_lock(&priv->leds[i]->led_access);
led_sysfs_enable(priv->leds[i]);
+ mutex_unlock(&priv->leds[i]->led_access);
+ }
return 0;
}
--
2.34.1
2
1

[PATCH OLK-6.6] backlight: led_bl: Hold led_access lock when calling led_sysfs_disable()
by Yuntao Liu 09 May '25
by Yuntao Liu 09 May '25
09 May '25
From: Herve Codina <herve.codina(a)bootlin.com>
stable inclusion
from stable-v6.6.88
commit 1c82f5a393d8b9a5c1ea032413719862098afd4b
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC5BJZ
CVE: CVE-2025-23144
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 276822a00db3c1061382b41e72cafc09d6a0ec30 upstream.
Lockdep detects the following issue on led-backlight removal:
[ 142.315935] ------------[ cut here ]------------
[ 142.315954] WARNING: CPU: 2 PID: 292 at drivers/leds/led-core.c:455 led_sysfs_enable+0x54/0x80
...
[ 142.500725] Call trace:
[ 142.503176] led_sysfs_enable+0x54/0x80 (P)
[ 142.507370] led_bl_remove+0x80/0xa8 [led_bl]
[ 142.511742] platform_remove+0x30/0x58
[ 142.515501] device_remove+0x54/0x90
...
Indeed, led_sysfs_enable() has to be called with the led_access
lock held.
Hold the lock when calling led_sysfs_disable().
Fixes: ae232e45acf9 ("backlight: add led-backlight driver")
Cc: stable(a)vger.kernel.org
Signed-off-by: Herve Codina <herve.codina(a)bootlin.com>
Link: https://lore.kernel.org/r/20250122091914.309533-1-herve.codina@bootlin.com
Signed-off-by: Lee Jones <lee(a)kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
drivers/video/backlight/led_bl.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c
index 032f8bddf872..0e53e427a91d 100644
--- a/drivers/video/backlight/led_bl.c
+++ b/drivers/video/backlight/led_bl.c
@@ -229,8 +229,11 @@ static void led_bl_remove(struct platform_device *pdev)
backlight_device_unregister(bl);
led_bl_power_off(priv);
- for (i = 0; i < priv->nb_leds; i++)
+ for (i = 0; i < priv->nb_leds; i++) {
+ mutex_lock(&priv->leds[i]->led_access);
led_sysfs_enable(priv->leds[i]);
+ mutex_unlock(&priv->leds[i]->led_access);
+ }
}
static const struct of_device_id led_bl_of_match[] = {
--
2.34.1
2
1

09 May '25
From: Qu Huang <qu.huang(a)linux.dev>
stable inclusion
from stable-v4.19.279
commit 5a3fb3b745af0ce46ec2e0c8e507bae45b937334
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC5DF7
CVE: CVE-2023-53090
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 4fc8fff378b2f2039f2a666d9f8c570f4e58352c ]
In the kfd_wait_on_events() function, the kfd_event_waiter structure is
allocated by alloc_event_waiters(), but the event field of the waiter
structure is not initialized; When copy_from_user() fails in the
kfd_wait_on_events() function, it will enter exception handling to
release the previously allocated memory of the waiter structure;
Due to the event field of the waiters structure being accessed
in the free_waiters() function, this results in illegal memory access
and system crash, here is the crash log:
localhost kernel: RIP: 0010:native_queued_spin_lock_slowpath+0x185/0x1e0
localhost kernel: RSP: 0018:ffffaa53c362bd60 EFLAGS: 00010082
localhost kernel: RAX: ff3d3d6bff4007cb RBX: 0000000000000282 RCX: 00000000002c0000
localhost kernel: RDX: ffff9e855eeacb80 RSI: 000000000000279c RDI: ffffe7088f6a21d0
localhost kernel: RBP: ffffe7088f6a21d0 R08: 00000000002c0000 R09: ffffaa53c362be64
localhost kernel: R10: ffffaa53c362bbd8 R11: 0000000000000001 R12: 0000000000000002
localhost kernel: R13: ffff9e7ead15d600 R14: 0000000000000000 R15: ffff9e7ead15d698
localhost kernel: FS: 0000152a3d111700(0000) GS:ffff9e855ee80000(0000) knlGS:0000000000000000
localhost kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
localhost kernel: CR2: 0000152938000010 CR3: 000000044d7a4000 CR4: 00000000003506e0
localhost kernel: Call Trace:
localhost kernel: _raw_spin_lock_irqsave+0x30/0x40
localhost kernel: remove_wait_queue+0x12/0x50
localhost kernel: kfd_wait_on_events+0x1b6/0x490 [hydcu]
localhost kernel: ? ftrace_graph_caller+0xa0/0xa0
localhost kernel: kfd_ioctl+0x38c/0x4a0 [hydcu]
localhost kernel: ? kfd_ioctl_set_trap_handler+0x70/0x70 [hydcu]
localhost kernel: ? kfd_ioctl_create_queue+0x5a0/0x5a0 [hydcu]
localhost kernel: ? ftrace_graph_caller+0xa0/0xa0
localhost kernel: __x64_sys_ioctl+0x8e/0xd0
localhost kernel: ? syscall_trace_enter.isra.18+0x143/0x1b0
localhost kernel: do_syscall_64+0x33/0x80
localhost kernel: entry_SYSCALL_64_after_hwframe+0x44/0xa9
localhost kernel: RIP: 0033:0x152a4dff68d7
Allocate the structure with kcalloc, and remove redundant 0-initialization
and a redundant loop condition check.
Signed-off-by: Qu Huang <qu.huang(a)linux.dev>
Signed-off-by: Felix Kuehling <Felix.Kuehling(a)amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling(a)amd.com>
Signed-off-by: Alex Deucher <alexander.deucher(a)amd.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Pu Lehui <pulehui(a)huawei.com>
---
drivers/gpu/drm/amd/amdkfd/kfd_events.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
index 892077377339..8f23192b6709 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
@@ -529,16 +529,13 @@ static struct kfd_event_waiter *alloc_event_waiters(uint32_t num_events)
struct kfd_event_waiter *event_waiters;
uint32_t i;
- event_waiters = kmalloc_array(num_events,
- sizeof(struct kfd_event_waiter),
- GFP_KERNEL);
+ event_waiters = kcalloc(num_events, sizeof(struct kfd_event_waiter),
+ GFP_KERNEL);
if (!event_waiters)
return NULL;
- for (i = 0; (event_waiters) && (i < num_events) ; i++) {
+ for (i = 0; i < num_events; i++)
init_wait(&event_waiters[i].wait);
- event_waiters[i].activated = false;
- }
return event_waiters;
}
--
2.34.1
2
1
Fix CVE-2025-37830.
Henry Martin (1):
cpufreq: scmi: Fix null-ptr-deref in scmi_cpufreq_get_rate()
drivers/cpufreq/scmi-cpufreq.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
--
2.34.1
2
2

09 May '25
From: fuguiming <fuguiming(a)huawei.com>
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IC5K0L?from=project-issue
CVE: NA
--------------------------------
Add optical module type adaptation.
Add ethtool fec function.
Add NIC XDP PASS function.
Add QoS persistence.
Add NIC out-of-band VLAN configuration function.
Fix NIC bifur bugs.
Fix performance test bugs.
Fix NIC RX bugs.
Fix NIC VF bugs.
Fix the bug of exiting when probing NIC.
Fix bond bugs.
Fix the bug of MAC address configuration failure in OS 6.6.
Fix the bug of reading NIC status incorrectly.
Fix and add some statistics.
Signed-off-by: fuguiming <fuguiming(a)huawei.com>
---
drivers/net/ethernet/huawei/hinic3/Makefile | 1 +
drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c | 3 +-
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c | 181 ++-
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h | 1 +
drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h | 212 ---
drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h | 239 ---
drivers/net/ethernet/huawei/hinic3/comm_defs.h | 100 --
drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h | 103 --
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c | 38 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h | 2 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c | 83 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c | 29 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c | 22 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h | 185 ---
drivers/net/ethernet/huawei/hinic3/hinic3_common.h | 118 --
drivers/net/ethernet/huawei/hinic3/hinic3_crm.h | 16 +-
drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c | 298 ++--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c | 262 +--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h | 7 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c | 247 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c | 459 +++---
drivers/net/ethernet/huawei/hinic3/hinic3_filter.c | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_hw.h | 19 +
drivers/net/ethernet/huawei/hinic3/hinic3_irq.c | 39 +-
drivers/net/ethernet/huawei/hinic3/hinic3_lld.h | 205 ---
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c | 833 +++++++++-
drivers/net/ethernet/huawei/hinic3/hinic3_main.c | 490 +++++-
drivers/net/ethernet/huawei/hinic3/hinic3_mt.h | 191 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c | 397 +++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic.h | 49 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c | 557 +++++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h | 54 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c | 186 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c | 10 +
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h | 112 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c | 105 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c | 50 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c | 15 +-
drivers/net/ethernet/huawei/hinic3/hinic3_profile.h | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rss.c | 137 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c | 41 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rx.c | 311 +++-
drivers/net/ethernet/huawei/hinic3/hinic3_rx.h | 41 +-
drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h | 7 +-
drivers/net/ethernet/huawei/hinic3/hinic3_tx.c | 79 +-
drivers/net/ethernet/huawei/hinic3/hinic3_wq.h | 4 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c | 11 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c | 6 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h | 5 -
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c | 1 -
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c | 213 ++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h | 18 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c | 3 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c | 14 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c | 42 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c | 79 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h | 7 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c | 155 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c | 115 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c | 85 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h | 31 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c | 40 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c | 1242 +++++++++++++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c | 3 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c | 4 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c | 41 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c | 122 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h | 4 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h | 31 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c | 64 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h | 14 +-
drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c | 1 +
drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h | 4 +
.../include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h | 11 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h | 42 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h | 2 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h | 70 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h | 141 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h | 5 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h | 88 +-
.../include/mpu/mpu_outband_ncsi_cmd_defs.h | 8 +
drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/vram_common.h | 25 +-
drivers/net/ethernet/huawei/hinic3/{mag_cmd.h => mag_mpu_cmd_defs.h} | 236 ++-
drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h | 27 -
drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h | 65 -
drivers/net/ethernet/huawei/hinic3/{hinic3_nic_cmd.h => nic_mpu_cmd.h} | 54 +-
drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h | 1440 +++++++++++++++++
drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h | 36 +
drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h | 28 +-
96 files changed, 8406 insertions(+), 2791 deletions(-)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_defs.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_common.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
rename drivers/net/ethernet/huawei/hinic3/{mag_cmd.h => mag_mpu_cmd_defs.h} (79%)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
rename drivers/net/ethernet/huawei/hinic3/{hinic3_nic_cmd.h => nic_mpu_cmd.h} (77%)
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
diff --git a/drivers/net/ethernet/huawei/hinic3/Makefile b/drivers/net/ethernet/huawei/hinic3/Makefile
index 6f9ed3f..457c920 100644
--- a/drivers/net/ethernet/huawei/hinic3/Makefile
+++ b/drivers/net/ethernet/huawei/hinic3/Makefile
@@ -11,6 +11,7 @@ ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/mpu/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/bond/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/vmsec/
+ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/bond/
obj-$(CONFIG_HINIC3) += hinic3.o
hinic3-objs := hw/hinic3_hwdev.o \
diff --git a/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c b/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c
index cc2e4b3..440fea6 100644
--- a/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_nic_cmdq.h"
#include "sw_cmdq_ops.h"
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
index e8c703b..dd0699b 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
@@ -9,6 +9,7 @@
#include <linux/net.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
+#include <linux/version.h>
#include "hinic3_lld.h"
#include "hinic3_srv_nic.h"
@@ -109,7 +110,8 @@ static struct hinic3_nic_dev *get_nic_dev_safe(struct net_device *ndev)
return netdev_priv(ndev);
}
-static u8 bond_get_slaves_bitmap(struct hinic3_bond_dev *bdev, struct bonding *bond)
+static u8 bond_get_slaves_bitmap(struct hinic3_bond_dev *bdev,
+ struct bonding *bond)
{
struct slave *slave = NULL;
struct list_head *iter = NULL;
@@ -203,7 +205,8 @@ static u8 bond_dev_track_port(struct hinic3_bond_dev *bdev,
bdev->tracker.netdev_state[port_id].tx_enabled = 0;
if (!bdev->ppf_hwdev)
bdev->ppf_hwdev = ppf_hwdev;
- pr_info("TRACK cnt: %d, slave_name(%s)\n", bdev->tracker.cnt, ndev->name);
+ pr_info("TRACK cnt: %d, slave_name(%s)\n",
+ bdev->tracker.cnt, ndev->name);
spin_unlock(&bdev->lock);
return port_id;
@@ -268,11 +271,16 @@ static void bond_master_event(struct hinic3_bond_dev *bdev,
queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
}
-static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
+static struct hinic3_bond_dev *bond_get_bdev(struct bonding *bond)
{
struct hinic3_bond_dev *bdev = NULL;
int bid;
+ if (!bond) {
+ pr_err("hinic3_bond: bond is NULL\n");
+ return NULL;
+ }
+
mutex_lock(&g_bond_mutex);
for (bid = BOND_FIRST_ID; bid <= BOND_MAX_ID; bid++) {
bdev = bond_mngr.bond_dev[bid];
@@ -283,38 +291,73 @@ static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
mutex_unlock(&g_bond_mutex);
return bdev;
}
+
+ if (strncmp(bond->dev->name,
+ bdev->name, BOND_NAME_MAX_LEN) == 0) {
+ bdev->bond = bond;
+ return bdev;
+ }
}
mutex_unlock(&g_bond_mutex);
return NULL;
}
-static void bond_handle_rtnl_event(struct net_device *ndev)
+static struct bonding *get_bonding_by_netdev(struct net_device *ndev)
{
- struct hinic3_bond_dev *bdev = NULL;
struct bonding *bond = NULL;
struct slave *slave = NULL;
if (netif_is_bond_master(ndev)) {
bond = netdev_priv(ndev);
- bdev = bond_get_bdev(bond);
} else if (netif_is_bond_slave(ndev)) {
- /*lint -e(160) */
slave = bond_slave_get_rtnl(ndev);
if (slave) {
bond = bond_get_bond_by_slave(slave);
- bdev = bond_get_bdev(bond);
}
}
- if (!bond || !bdev)
+ return bond;
+}
+
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+
+ if (!ndev) {
+ pr_err("hinic3_bond: netdev is NULL\n");
+ return false;
+ }
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
+ return false;
+
+ return bdev->status == BOND_DEV_STATUS_ACTIVATED;
+}
+EXPORT_SYMBOL(hinic3_is_bond_dev_status_actived);
+/*lint +e580 +e546*/
+
+static void bond_handle_rtnl_event(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+ struct slave *slave = NULL;
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
return;
bond_update_attr(bdev, bond);
- if (slave)
+ if (netif_is_bond_slave(ndev)) {
+ slave = bond_slave_get_rtnl(ndev);
bond_slave_event(bdev, slave);
- else
+ } else {
bond_master_event(bdev, bond);
+ }
}
static void bond_rtnl_data_ready(struct sock *sk)
@@ -368,7 +411,8 @@ static int bond_enable_netdev_event(void)
(*rtnl_sock)->sk->sk_data_ready = bond_rtnl_data_ready;
(*rtnl_sock)->sk->sk_allocation = GFP_KERNEL;
- err = kernel_bind(*rtnl_sock, (struct sockaddr *)(u8 *)&addr, sizeof(addr));
+ err = kernel_bind(*rtnl_sock, (struct sockaddr *)(u8 *)&addr,
+ sizeof(addr));
if (err) {
pr_err("hinic3_bond: Couldn't bind rtnl socket.\n");
sock_release(*rtnl_sock);
@@ -387,7 +431,7 @@ static void bond_disable_netdev_event(void)
static int bond_send_upcmd(struct hinic3_bond_dev *bdev, struct bond_attr *attr,
u8 cmd_type)
{
- int err, len;
+ int err, ret, len;
struct hinic3_bond_cmd cmd = {0};
u16 out_size = sizeof(cmd);
@@ -403,7 +447,9 @@ static int bond_send_upcmd(struct hinic3_bond_dev *bdev, struct bond_attr *attr,
len = sizeof(cmd.bond_name);
if (cmd_type == MPU_CMD_BOND_CREATE) {
- strscpy(cmd.bond_name, bdev->name, len);
+ ret = strscpy(cmd.bond_name, bdev->name, len);
+ if (ret < 0)
+ pr_err("strscpy bond name failed\n");
cmd.bond_name[sizeof(cmd.bond_name) - 1] = '\0';
}
@@ -478,7 +524,11 @@ static void bond_update_slave_info(struct hinic3_bond_dev *bdev,
continue;
}
+ if (!bdev->tracker.ndev[i])
+ continue;
+
bond_pf_bitmap_set(bdev, i);
+
if (!bdev->tracker.netdev_state[i].tx_enabled)
continue;
@@ -516,6 +566,7 @@ static int bond_upcmd_config(struct hinic3_bond_dev *bdev,
attr->active_slaves,
attr->lacp_collect_slaves);
pr_info("bond_pf_bitmap: 0x%x\n", attr->bond_pf_bitmap);
+ pr_info("bond user_bitmap 0x%x\n", attr->user_bitmap);
err = bond_send_upcmd(bdev, attr, MPU_CMD_BOND_SET_ATTR);
if (!err)
@@ -544,8 +595,10 @@ static int bond_upcmd_activate(struct hinic3_bond_dev *bdev,
return err;
}
-static void bond_call_service_func(struct hinic3_bond_dev *bdev, struct bond_attr *attr,
- enum bond_service_proc_pos pos, int bond_status)
+static void bond_call_service_func(struct hinic3_bond_dev *bdev,
+ struct bond_attr *attr,
+ enum bond_service_proc_pos pos,
+ int bond_status)
{
int i;
@@ -560,6 +613,18 @@ static void bond_call_service_func(struct hinic3_bond_dev *bdev, struct bond_att
mutex_unlock(&g_bond_service_func_mutex);
}
+static u32 bond_get_user_bitmap(struct hinic3_bond_dev *bdev)
+{
+ u32 user_bitmap = 0;
+ u8 user;
+
+ for (user = HINIC3_BOND_USER_OVS; user < HINIC3_BOND_USER_NUM; user++) {
+ if (bdev->slot_used[user] == 1)
+ BITMAP_SET(user_bitmap, user);
+ }
+ return user_bitmap;
+}
+
static void bond_do_work(struct hinic3_bond_dev *bdev)
{
bool is_bonded = 0;
@@ -570,7 +635,7 @@ static void bond_do_work(struct hinic3_bond_dev *bdev)
is_bonded = bdev->tracker.is_bonded;
attr = bdev->new_attr;
spin_unlock(&bdev->lock);
- attr.user_bitmap = 0;
+ attr.user_bitmap = bond_get_user_bitmap(bdev);
/* is_bonded indicates whether bond should be activated. */
if (is_bonded && !bond_dev_is_activated(bdev)) {
@@ -597,15 +662,22 @@ static void bond_try_do_work(struct work_struct *work)
struct delayed_work *delayed_work = to_delayed_work(work);
struct hinic3_bond_dev *bdev =
container_of(delayed_work, struct hinic3_bond_dev, bond_work);
+ int status;
- if (g_bond_service_func[HINIC3_BOND_USER_ROCE] && bdev->tracker.cnt < MIN_BOND_SLAVE_CNT)
+ status = mutex_trylock(&g_bond_mutex);
+ if (status == 0) {
+ /* Delay 1 sec and retry */
queue_delayed_work(bdev->wq, &bdev->bond_work, HZ);
- else
+ } else {
bond_do_work(bdev);
+ mutex_unlock(&g_bond_mutex);
+ }
}
static int bond_dev_init(struct hinic3_bond_dev *bdev, const char *name)
{
+ int err = 0;
+
bdev->wq = create_singlethread_workqueue("hinic3_bond_wq");
if (!bdev->wq) {
pr_err("hinic3_bond: Failed to create workqueue\n");
@@ -614,7 +686,13 @@ static int bond_dev_init(struct hinic3_bond_dev *bdev, const char *name)
INIT_DELAYED_WORK(&bdev->bond_work, bond_try_do_work);
bdev->status = BOND_DEV_STATUS_IDLE;
- strscpy(bdev->name, name, sizeof(bdev->name));
+ err = strscpy(bdev->name, name, strlen(name));
+ if (err < 0) {
+ pr_err("hinic3_bond: Failed to init bond dev\n");
+ cancel_delayed_work_sync(&bdev->bond_work);
+ destroy_workqueue(bdev->wq);
+ return err;
+ }
spin_lock_init(&bdev->lock);
@@ -630,6 +708,7 @@ static int bond_dev_release(struct hinic3_bond_dev *bdev)
err = bond_upcmd_deactivate(bdev);
if (err) {
pr_err("hinic3_bond: Failed to deactivate dev\n");
+ mutex_unlock(&g_bond_mutex);
return err;
}
@@ -637,7 +716,8 @@ static int bond_dev_release(struct hinic3_bond_dev *bdev)
if (bond_mngr.bond_dev[i] == bdev) {
bond_mngr.bond_dev[i] = NULL;
bond_mngr.cnt--;
- pr_info("hinic3_bond: Free bond, id: %u mngr_cnt:%u\n", i, bond_mngr.cnt);
+ pr_info("hinic3_bond: Free bond, id: %u mngr_cnt:%u\n",
+ i, bond_mngr.cnt);
break;
}
}
@@ -694,7 +774,8 @@ static struct hinic3_bond_dev *bond_dev_alloc(const char *name)
bdev->bond_attr.bond_id = i;
bond_mngr.bond_dev[i] = bdev;
bond_mngr.cnt++;
- pr_info("hinic3_bond: Create bond dev, id:%u cnt:%u\n", i, bond_mngr.cnt);
+ pr_info("hinic3_bond: Create bond dev, id:%u cnt:%u\n",
+ i, bond_mngr.cnt);
break;
}
}
@@ -764,20 +845,28 @@ static struct hinic3_bond_dev *bond_dev_by_name(const char *name)
static void bond_dev_user_attach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user)
{
+ u32 user_bitmap;
+
+ if (user < 0 || user >= HINIC3_BOND_USER_NUM)
+ return;
+
if (bdev->slot_used[user])
return;
bdev->slot_used[user] = 1;
- if (!kref_get_unless_zero(&bdev->ref))
+ if (!kref_get_unless_zero(&bdev->ref)) {
kref_init(&bdev->ref);
+ } else {
+ user_bitmap = bond_get_user_bitmap(bdev);
+ pr_info("hinic3_bond: user %u attach bond %s, user_bitmap %#x\n",
+ user, bdev->name, user_bitmap);
+ queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
+ }
}
static void bond_dev_user_detach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user, bool *freed)
{
- if (user < 0 || user >= HINIC3_BOND_USER_NUM)
- return;
-
if (bdev->slot_used[user]) {
bdev->slot_used[user] = 0;
if (kref_read(&bdev->ref) == 1)
@@ -790,16 +879,20 @@ static struct bonding *bond_get_knl_bonding(const char *name)
{
struct net_device *ndev_tmp = NULL;
+ rcu_read_lock();
for_each_netdev(&init_net, ndev_tmp) {
if (netif_is_bond_master(ndev_tmp) &&
- !strcmp(ndev_tmp->name, name))
+ !strcmp(ndev_tmp->name, name)) {
+ rcu_read_unlock();
return netdev_priv(ndev_tmp);
+ }
}
-
+ rcu_read_unlock();
return NULL;
}
-void hinic3_bond_set_user_bitmap(struct bond_attr *attr, enum hinic3_bond_user user)
+void hinic3_bond_set_user_bitmap(struct bond_attr *attr,
+ enum hinic3_bond_user user)
{
if (!BITMAP_JUDGE(attr->user_bitmap, user))
BITMAP_SET(attr->user_bitmap, user);
@@ -852,8 +945,9 @@ int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user)
int err = 0;
bool lock_freed = false;
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
- pr_warn("hinic3_bond: Invalid bond id:%u to delete\n", bond_id);
+ if (!BOND_ID_IS_VALID(bond_id) || user >= HINIC3_BOND_USER_NUM) {
+ pr_warn("hinic3_bond: Invalid bond id or user, bond_id: %u, user: %d\n",
+ bond_id, user);
return -EINVAL;
}
@@ -861,7 +955,8 @@ int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user)
if (!bond_mngr.bond_dev[bond_id])
err = -ENODEV;
else
- bond_dev_user_detach(bond_mngr.bond_dev[bond_id], user, &lock_freed);
+ bond_dev_user_detach(bond_mngr.bond_dev[bond_id],
+ user, &lock_freed);
if (!lock_freed)
mutex_unlock(&g_bond_mutex);
@@ -877,7 +972,8 @@ void hinic3_bond_clean_user(enum hinic3_bond_user user)
mutex_lock(&g_bond_mutex);
for (i = BOND_FIRST_ID; i <= BOND_MAX_ID; i++) {
if (bond_mngr.bond_dev[i]) {
- bond_dev_user_detach(bond_mngr.bond_dev[i], user, &lock_freed);
+ bond_dev_user_detach(bond_mngr.bond_dev[i],
+ user, &lock_freed);
if (lock_freed) {
mutex_lock(&g_bond_mutex);
lock_freed = false;
@@ -891,7 +987,7 @@ EXPORT_SYMBOL(hinic3_bond_clean_user);
int hinic3_bond_get_uplink_id(u16 bond_id, u32 *uplink_id)
{
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID || !uplink_id) {
+ if (!BOND_ID_IS_VALID(bond_id) || !uplink_id) {
pr_warn("hinic3_bond: Invalid args, id: %u, uplink: %d\n",
bond_id, !!uplink_id);
return -EINVAL;
@@ -941,7 +1037,7 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
int i;
int len;
- if (!info || bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
+ if (!info || !BOND_ID_IS_VALID(bond_id)) {
pr_warn("hinic3_bond: Invalid args, info: %d,id: %u\n",
!!info, bond_id);
return -EINVAL;
@@ -962,7 +1058,8 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
for (i = 0; i < BOND_PORT_MAX_NUM; i++) {
if (BITMAP_JUDGE(info->slaves, i) && tracker->ndev[i]) {
len = sizeof(info->slaves_name[0]);
- strscpy(info->slaves_name[info->cnt], tracker->ndev[i]->name, len);
+ strscpy(info->slaves_name[info->cnt],
+ tracker->ndev[i]->name, len);
info->cnt++;
}
}
@@ -972,7 +1069,8 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
}
EXPORT_SYMBOL(hinic3_bond_get_slaves);
-struct net_device *hinic3_bond_get_netdev_by_portid(const char *bond_name, u8 port_id)
+struct net_device *hinic3_bond_get_netdev_by_portid(const char *bond_name,
+ u8 port_id)
{
struct hinic3_bond_dev *bdev = NULL;
@@ -989,7 +1087,8 @@ struct net_device *hinic3_bond_get_netdev_by_portid(const char *bond_name, u8 po
}
EXPORT_SYMBOL(hinic3_bond_get_netdev_by_portid);
-int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos, u16 channel)
+int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos,
+ u16 channel)
{
struct comm_cmd_hw_bond_infos bond_infos;
u16 out_size = sizeof(bond_infos);
@@ -1002,7 +1101,8 @@ int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos, u1
bond_infos.infos.bond_id = infos->bond_id;
- err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_COMM, COMM_MGMT_CMD_GET_HW_BOND,
+ err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_COMM,
+ COMM_MGMT_CMD_GET_HW_BOND,
&bond_infos, sizeof(bond_infos),
&bond_infos, &out_size, 0, channel);
if (bond_infos.head.status || err || !out_size) {
@@ -1018,7 +1118,8 @@ int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos, u1
}
EXPORT_SYMBOL(hinic3_get_hw_bond_infos);
-int hinic3_get_bond_tracker_by_name(const char *name, struct bond_tracker *tracker)
+int hinic3_get_bond_tracker_by_name(const char *name,
+ struct bond_tracker *tracker)
{
struct hinic3_bond_dev *bdev = NULL;
int i;
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
index 024de95..5ab36f7 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
@@ -82,6 +82,7 @@ struct hinic3_bond_cmd {
char bond_name[16];
};
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev);
void hinic3_bond_set_user_bitmap(struct bond_attr *attr, enum hinic3_bond_user user);
int hinic3_bond_attach(const char *name, enum hinic3_bond_user user, u16 *bond_id);
int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user);
diff --git a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h b/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
deleted file mode 100644
index 557f326..0000000
--- a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2016-2022. All rights reserved.
- * File name: Cfg_mgt_comm_pub.h
- * Version No.: Draft
- * Generation date: 2016 year 05 month 07 day
- * Latest modification:
- * Function description: Header file for communication between the: Host and FW
- * Function list:
- * Modification history:
- * 1. Date: 2016 May 07
- * Modify content: Create a file.
- */
-#ifndef CFG_MGT_COMM_PUB_H
-#define CFG_MGT_COMM_PUB_H
-
-#include "mgmt_msg_base.h"
-
-enum servic_bit_define {
- SERVICE_BIT_NIC = 0,
- SERVICE_BIT_ROCE = 1,
- SERVICE_BIT_VBS = 2,
- SERVICE_BIT_TOE = 3,
- SERVICE_BIT_IPSEC = 4,
- SERVICE_BIT_FC = 5,
- SERVICE_BIT_VIRTIO = 6,
- SERVICE_BIT_OVS = 7,
- SERVICE_BIT_NVME = 8,
- SERVICE_BIT_ROCEAA = 9,
- SERVICE_BIT_CURRENET = 10,
- SERVICE_BIT_PPA = 11,
- SERVICE_BIT_MIGRATE = 12,
- SERVICE_BIT_MAX
-};
-
-#define CFG_SERVICE_MASK_NIC (0x1 << SERVICE_BIT_NIC)
-#define CFG_SERVICE_MASK_ROCE (0x1 << SERVICE_BIT_ROCE)
-#define CFG_SERVICE_MASK_VBS (0x1 << SERVICE_BIT_VBS)
-#define CFG_SERVICE_MASK_TOE (0x1 << SERVICE_BIT_TOE)
-#define CFG_SERVICE_MASK_IPSEC (0x1 << SERVICE_BIT_IPSEC)
-#define CFG_SERVICE_MASK_FC (0x1 << SERVICE_BIT_FC)
-#define CFG_SERVICE_MASK_VIRTIO (0x1 << SERVICE_BIT_VIRTIO)
-#define CFG_SERVICE_MASK_OVS (0x1 << SERVICE_BIT_OVS)
-#define CFG_SERVICE_MASK_NVME (0x1 << SERVICE_BIT_NVME)
-#define CFG_SERVICE_MASK_ROCEAA (0x1 << SERVICE_BIT_ROCEAA)
-#define CFG_SERVICE_MASK_CURRENET (0x1 << SERVICE_BIT_CURRENET)
-#define CFG_SERVICE_MASK_PPA (0x1 << SERVICE_BIT_PPA)
-#define CFG_SERVICE_MASK_MIGRATE (0x1 << SERVICE_BIT_MIGRATE)
-
-/* Definition of the scenario ID in the cfg_data, which is used for SML memory allocation. */
-enum scenes_id_define {
- SCENES_ID_FPGA_ETH = 0,
- SCENES_ID_FPGA_TIOE = 1, /* Discarded */
- SCENES_ID_STORAGE_ROCEAA_2x100 = 2,
- SCENES_ID_STORAGE_ROCEAA_4x25 = 3,
- SCENES_ID_CLOUD = 4,
- SCENES_ID_FC = 5,
- SCENES_ID_STORAGE_ROCE = 6,
- SCENES_ID_COMPUTE_ROCE = 7,
- SCENES_ID_STORAGE_TOE = 8,
- SCENES_ID_MAX
-};
-
-/* struct cfg_cmd_dev_cap.sf_svc_attr */
-enum {
- SF_SVC_FT_BIT = (1 << 0),
- SF_SVC_RDMA_BIT = (1 << 1),
-};
-
-enum cfg_cmd {
- CFG_CMD_GET_DEV_CAP = 0,
- CFG_CMD_GET_HOST_TIMER = 1,
-};
-
-struct cfg_cmd_host_timer {
- struct mgmt_msg_head head;
-
- u8 host_id;
- u8 rsvd1;
-
- u8 timer_pf_num;
- u8 timer_pf_id_start;
- u16 timer_vf_num;
- u16 timer_vf_id_start;
- u32 rsvd2[8];
-};
-
-struct cfg_cmd_dev_cap {
- struct mgmt_msg_head head;
-
- u16 func_id;
- u16 rsvd1;
-
- /* Public resources */
- u8 host_id;
- u8 ep_id;
- u8 er_id;
- u8 port_id;
-
- u16 host_total_func;
- u8 host_pf_num;
- u8 pf_id_start;
- u16 host_vf_num;
- u16 vf_id_start;
- u8 host_oq_id_mask_val;
- u8 timer_en;
- u8 host_valid_bitmap;
- u8 rsvd_host;
-
- u16 svc_cap_en;
- u16 max_vf;
- u8 flexq_en;
- u8 valid_cos_bitmap;
- /* Reserved for func_valid_cos_bitmap */
- u8 port_cos_valid_bitmap;
- u8 rsvd_func1;
- u32 rsvd_func2;
-
- u8 sf_svc_attr;
- u8 func_sf_en;
- u8 lb_mode;
- u8 smf_pg;
-
- u32 max_conn_num;
- u16 max_stick2cache_num;
- u16 max_bfilter_start_addr;
- u16 bfilter_len;
- u16 hash_bucket_num;
-
- /* shared resource */
- u8 host_sf_en;
- u8 master_host_id;
- u8 srv_multi_host_mode;
- u8 virtio_vq_size;
-
- u32 rsvd_func3[5];
-
- /* l2nic */
- u16 nic_max_sq_id;
- u16 nic_max_rq_id;
- u16 nic_default_num_queues;
- u16 rsvd1_nic;
- u32 rsvd2_nic[2];
-
- /* RoCE */
- u32 roce_max_qp;
- u32 roce_max_cq;
- u32 roce_max_srq;
- u32 roce_max_mpt;
- u32 roce_max_drc_qp;
-
- u32 roce_cmtt_cl_start;
- u32 roce_cmtt_cl_end;
- u32 roce_cmtt_cl_size;
-
- u32 roce_dmtt_cl_start;
- u32 roce_dmtt_cl_end;
- u32 roce_dmtt_cl_size;
-
- u32 roce_wqe_cl_start;
- u32 roce_wqe_cl_end;
- u32 roce_wqe_cl_size;
- u8 roce_srq_container_mode;
- u8 rsvd_roce1[3];
- u32 rsvd_roce2[5];
-
- /* IPsec */
- u32 ipsec_max_sactx;
- u16 ipsec_max_cq;
- u16 rsvd_ipsec1;
- u32 rsvd_ipsec[2];
-
- /* OVS */
- u32 ovs_max_qpc;
- u32 rsvd_ovs1[3];
-
- /* ToE */
- u32 toe_max_pctx;
- u32 toe_max_cq;
- u16 toe_max_srq;
- u16 toe_srq_id_start;
- u16 toe_max_mpt;
- u16 toe_max_cctxt;
- u32 rsvd_toe[2];
-
- /* FC */
- u32 fc_max_pctx;
- u32 fc_max_scq;
- u32 fc_max_srq;
-
- u32 fc_max_cctx;
- u32 fc_cctx_id_start;
-
- u8 fc_vp_id_start;
- u8 fc_vp_id_end;
- u8 rsvd_fc1[2];
- u32 rsvd_fc2[5];
-
- /* VBS */
- u16 vbs_max_volq;
- u16 rsvd0_vbs;
- u32 rsvd1_vbs[3];
-
- u16 fake_vf_start_id;
- u16 fake_vf_num;
- u32 fake_vf_max_pctx;
- u16 fake_vf_bfilter_start_addr;
- u16 fake_vf_bfilter_len;
- u32 rsvd_glb[8];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
deleted file mode 100644
index 59e20a1..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/******************************************************************************
- * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
- ******************************************************************************
- File Name : comm_cmdq_intf.h
- Version : Initial Draft
- Description : common command queue interface
- Function List :
- History :
- Modification: Created file
-
-******************************************************************************/
-
-#ifndef COMM_CMDQ_INTF_H
-#define COMM_CMDQ_INTF_H
-
-/* Cmdq ack type */
-enum hinic3_ack_type {
- HINIC3_ACK_TYPE_CMDQ,
- HINIC3_ACK_TYPE_SHARE_CQN,
- HINIC3_ACK_TYPE_APP_CQN,
-
- HINIC3_MOD_ACK_MAX = 15,
-};
-
-/* Defines the queue type of the set arm bit. */
-enum {
- SET_ARM_BIT_FOR_CMDQ = 0,
- SET_ARM_BIT_FOR_L2NIC_SQ,
- SET_ARM_BIT_FOR_L2NIC_RQ,
- SET_ARM_BIT_TYPE_NUM
-};
-
-/* Defines the type. Each function supports a maximum of eight CMDQ types. */
-enum {
- CMDQ_0 = 0,
- CMDQ_1 = 1, /* dedicated and non-blocking queues */
- CMDQ_NUM
-};
-
-/* *******************cmd common command data structure ************************ */
-// Func->ucode, which is used to set arm bit data,
-// The microcode needs to perform big-endian conversion.
-struct comm_info_ucode_set_arm_bit {
- u32 q_type;
- u32 q_id;
-};
-
-/* *******************WQE data structure ************************ */
-union cmdq_wqe_cs_dw0 {
- struct {
- u32 err_status : 29;
- u32 error_code : 2;
- u32 rsvd : 1;
- } bs;
- u32 val;
-};
-
-union cmdq_wqe_cs_dw1 {
- // This structure is used when the driver writes the wqe.
- struct {
- u32 token : 16; // [15:0]
- u32 cmd : 8; // [23:16]
- u32 mod : 5; // [28:24]
- u32 ack_type : 2; // [30:29]
- u32 obit : 1; // [31]
- } drv_wr;
-
- /* The uCode writes back the structure of the CS_DW1. */
- /* The driver reads and uses the structure. */
- struct {
- u32 mod : 5; // [4:0]
- u32 ack_type : 3; // [7:5]
- u32 cmd : 8; // [15:8]
- u32 arm : 1; // [16]
- u32 rsvd : 14; // [30:17]
- u32 obit : 1; // [31]
- } wb;
- u32 val;
-};
-
-/* CmdQ BD information or write back buffer information */
-struct cmdq_sge {
- u32 pa_h; // Upper 32 bits of the physical address
- u32 pa_l; // Upper 32 bits of the physical address
- u32 len; // Invalid bit[31].
- u32 resv;
-};
-
-/* Ctrls section definition of WQE */
-struct cmdq_wqe_ctrls {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
-};
-
-/* Complete section definition of WQE */
-struct cmdq_wqe_cs {
- union cmdq_wqe_cs_dw0 dw0;
- union cmdq_wqe_cs_dw1 dw1;
- union {
- struct cmdq_sge sge;
- u32 dw2_5[4];
- } ack;
-};
-
-/* Inline header in WQE inline, describing the length of inline data */
-union cmdq_wqe_inline_header {
- struct {
- u32 buf_len : 11; // [10:0] inline data len
- u32 rsv : 21; // [31:11]
- } bs;
- u32 val;
-};
-
-/* Definition of buffer descriptor section in WQE */
-union cmdq_wqe_bds {
- struct {
- struct cmdq_sge bds_sge;
- u32 rsvd[4]; /* Zwy is used to transfer the virtual address of the buffer. */
- } lcmd; /* Long command, non-inline, and SGE describe the buffer information. */
-};
-
-/* Definition of CMDQ WQE */
-/* (long cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(16B) |
- * | |
- * +----------------------------------------+
- * | driver section(16B) |
- * +----------------------------------------+
- *
- *
- * (middle cmd, 128B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(88B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- *
- *
- * (short cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(24B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- */
-struct cmdq_wqe {
- struct cmdq_wqe_ctrls ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds bds;
-};
-
-/* Definition of ctrls section in inline WQE */
-struct cmdq_wqe_ctrls_inline {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
- u64 db;
-};
-
-/* Buffer descriptor section definition of WQE */
-union cmdq_wqe_bds_inline {
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[80];
- } mcmd; /* Middle command, inline mode */
-
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[16];
- } scmd; /* Short command, inline mode */
-};
-
-struct cmdq_wqe_inline {
- struct cmdq_wqe_ctrls_inline ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds_inline bds;
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_defs.h b/drivers/net/ethernet/huawei/hinic3/comm_defs.h
deleted file mode 100644
index c5b1913..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_defs.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_defs.h
- * Version : Initial Draft
- * Description : common definitions
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef COMM_DEFS_H
-#define COMM_DEFS_H
-
-/* CMDQ MODULE_TYPE */
-enum hinic3_mod_type {
- HINIC3_MOD_COMM = 0, /* HW communication module */
- HINIC3_MOD_L2NIC = 1, /* L2NIC module */
- HINIC3_MOD_ROCE = 2,
- HINIC3_MOD_PLOG = 3,
- HINIC3_MOD_TOE = 4,
- HINIC3_MOD_FLR = 5,
- HINIC3_MOD_RSVD1 = 6,
- HINIC3_MOD_CFGM = 7, /* Configuration module */
- HINIC3_MOD_CQM = 8,
- HINIC3_MOD_VMSEC = 9,
- COMM_MOD_FC = 10,
- HINIC3_MOD_OVS = 11,
- HINIC3_MOD_DSW = 12,
- HINIC3_MOD_MIGRATE = 13,
- HINIC3_MOD_HILINK = 14,
- HINIC3_MOD_CRYPT = 15, /* secure crypto module */
- HINIC3_MOD_VIO = 16,
- HINIC3_MOD_IMU = 17,
- HINIC3_MOD_DFT = 18, /* DFT */
- HINIC3_MOD_HW_MAX = 19, /* hardware max module id */
- /* Software module id, for PF/VF and multi-host */
- HINIC3_MOD_SW_FUNC = 20,
- HINIC3_MOD_MAX,
-};
-
-/* func reset的flag ,用于指示清理哪种资源 */
-enum func_reset_flag {
- RES_TYPE_FLUSH_BIT = 0,
- RES_TYPE_MQM,
- RES_TYPE_SMF,
- RES_TYPE_PF_BW_CFG,
-
- RES_TYPE_COMM = 10,
- RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_NIC,
- RES_TYPE_OVS,
- RES_TYPE_VBS,
- RES_TYPE_ROCE,
- RES_TYPE_FC,
- RES_TYPE_TOE,
- RES_TYPE_IPSEC,
- RES_TYPE_MAX,
-};
-
-#define HINIC3_COMM_RES \
- ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
- (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
- (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
-
-#define HINIC3_NIC_RES BIT(RES_TYPE_NIC)
-#define HINIC3_OVS_RES BIT(RES_TYPE_OVS)
-#define HINIC3_VBS_RES BIT(RES_TYPE_VBS)
-#define HINIC3_ROCE_RES BIT(RES_TYPE_ROCE)
-#define HINIC3_FC_RES BIT(RES_TYPE_FC)
-#define HINIC3_TOE_RES BIT(RES_TYPE_TOE)
-#define HINIC3_IPSEC_RES BIT(RES_TYPE_IPSEC)
-
-/* MODE OVS、NIC、UNKNOWN */
-#define HINIC3_WORK_MODE_OVS 0
-#define HINIC3_WORK_MODE_UNKNOWN 1
-#define HINIC3_WORK_MODE_NIC 2
-
-#define DEVICE_TYPE_L2NIC 0
-#define DEVICE_TYPE_NVME 1
-#define DEVICE_TYPE_VIRTIO_NET 2
-#define DEVICE_TYPE_VIRTIO_BLK 3
-#define DEVICE_TYPE_VIRTIO_VSOCK 4
-#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
-#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
-#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
-#define DEVICE_TYPE_VIRTIO_HPC 8
-
-/* Common header control information of the COMM message
- * interaction command word between the driver and PF
- */
-struct comm_info_head {
- u8 status;
- u8 version;
- u8 rep_aeq_num;
- u8 rsvd[5];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
deleted file mode 100644
index ae998cf..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_msg_intf.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef COMM_MSG_INTF_H
-#define COMM_MSG_INTF_H
-
-#include "comm_defs.h"
-#include "mgmt_msg_base.h"
-#include "mpu_cmd_base_defs.h"
-#include "mpu_inband_cmd_defs.h"
-
-struct spu_cmd_freq_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: check */
- u8 rsvd[3];
- u32 freq;
-};
-
-struct spu_cmd_power_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: init */
- u8 slave_addr;
- u8 cmd_id;
- u8 size;
- u32 value;
-};
-
-struct spu_cmd_tsensor_operation {
- struct comm_info_head head;
-
- u8 op_code;
- u8 rsvd[3];
- s16 fabric_tsensor_temp_avg;
- s16 fabric_tsensor_temp;
- s16 sys_tsensor_temp_avg;
- s16 sys_tsensor_temp;
-};
-
-enum cfg_msix_operation {
- CFG_MSIX_OPERATION_FREE = 0,
- CFG_MSIX_OPERATION_ALLOC = 1,
-};
-
-struct comm_cmd_ffm_info {
- struct mgmt_msg_head head;
-
- u8 node_id;
- /* error level of the interrupt source */
- u8 err_level;
- /* Classification by interrupt source properties */
- u16 err_type;
- u32 err_csr_addr;
- u32 err_csr_value;
- u32 rsvd1;
-};
-
-struct hinic3_cmd_update_firmware {
- struct mgmt_msg_head msg_head;
-
- struct {
- u32 sl : 1;
- u32 sf : 1;
- u32 flag : 1;
- u32 bit_signed : 1;
- u32 reserved : 12;
- u32 fragment_len : 16;
- } ctl_info;
-
- struct {
- u32 section_crc;
- u32 section_type;
- } section_info;
-
- u32 total_len;
- u32 section_len;
- u32 section_version;
- u32 section_offset;
- u32 data[384];
-};
-
-struct hinic3_cmd_activate_firmware {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-struct hinic3_cmd_switch_config {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
index 8c95032..aad3a97 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
@@ -28,6 +28,8 @@
#include "cqm_npu_cmd.h"
#include "cqm_npu_cmd_defs.h"
+#include "vram_common.h"
+
static void cqm_bat_fill_cla_common_gpa(struct tag_cqm_handle *cqm_handle,
struct tag_cqm_cla_table *cla_table,
struct tag_cqm_bat_entry_standerd *bat_entry_standerd)
@@ -366,6 +368,13 @@ static s32 cqm_bat_update_cmd(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
struct hinic3_hwdev *handle = cqm_handle->ex_handle;
struct tag_cqm_cmdq_bat_update *bat_update_cmd = NULL;
s32 ret = CQM_FAIL;
+ int is_in_kexec;
+
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip updating the cqm_bat to chip during kexec!\n");
+ return CQM_SUCCESS;
+ }
bat_update_cmd = (struct tag_cqm_cmdq_bat_update *)(buf_in->buf);
bat_update_cmd->offset = 0;
@@ -768,8 +777,10 @@ static s32 cqm_cla_xyz_lvl1(struct tag_cqm_handle *cqm_handle,
/* Applying for CLA_Z_BUF Space */
cla_z_buf = &cla_table->cla_z_buf;
cla_z_buf->buf_size = trunk_size;
- cla_z_buf->buf_number = (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
- cla_z_buf->page_number = cla_z_buf->buf_number << cla_table->trunk_order;
+ cla_z_buf->buf_number =
+ (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
+ cla_z_buf->page_number = cla_z_buf->buf_number <<
+ cla_table->trunk_order;
/* All buffer space must be statically allocated. */
if (cla_table->alloc_static) {
@@ -840,6 +851,7 @@ static s32 cqm_cla_xyz_lvl2_xyz_apply(struct tag_cqm_handle *cqm_handle,
cla_x_buf->buf_size = trunk_size;
cla_x_buf->buf_number = 1;
cla_x_buf->page_number = cla_x_buf->buf_number << cla_table->trunk_order;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
ret = cqm_buf_alloc(cqm_handle, cla_x_buf, false);
if (ret != CQM_SUCCESS)
return CQM_FAIL;
@@ -869,14 +881,20 @@ static s32 cqm_cla_xyz_vram_name_init(struct tag_cqm_cla_table *cla_table,
cla_x_buf = &cla_table->cla_x_buf;
cla_z_buf = &cla_table->cla_z_buf;
cla_y_buf = &cla_table->cla_y_buf;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_x_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_X);
+ VRAM_NAME_MAX_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_X);
+ cla_y_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_y_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Y);
+ VRAM_NAME_MAX_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Y);
+ cla_z_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_z_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Z);
+ VRAM_NAME_MAX_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Z);
return CQM_SUCCESS;
}
@@ -1188,7 +1206,7 @@ static void cqm_cla_init_entry_extern(struct tag_cqm_handle *cqm_handle,
* exceed 128 x 4 KB. Otherwise, clearing the timer buffer of
* the function is complex.
*/
- cla_table->trunk_order = CQM_4K_PAGE_ORDER;
+ cla_table->trunk_order = CQM_8K_PAGE_ORDER;
cla_table->max_buffer_size = capability->timer_number *
capability->timer_basic_size;
cla_table->obj_size = capability->timer_basic_size;
@@ -1237,7 +1255,7 @@ static s32 cqm_cla_init_entry_condition(struct tag_cqm_handle *cqm_handle, u32 e
memcpy(cla_table_timer, cla_table, sizeof(struct tag_cqm_cla_table));
snprintf(cla_table_timer->name,
- VRAM_NAME_MAX_LEN - 1, "%s%s%01u", cla_table->name,
+ VRAM_NAME_MAX_LEN, "%s%s%01u", cla_table->name,
VRAM_CQM_CLA_SMF_BASE, i);
if (cqm_cla_xyz(cqm_handle, cla_table_timer) ==
@@ -1268,7 +1286,7 @@ static s32 cqm_cla_init_entry(struct tag_cqm_handle *cqm_handle,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
cla_table->type = bat_table->bat_entry_type[i];
- snprintf(cla_table->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(cla_table->name, VRAM_NAME_MAX_LEN,
"%s%s%s%02u", cqm_handle->name, VRAM_CQM_CLA_BASE,
VRAM_CQM_CLA_TYPE_BASE, cla_table->type);
@@ -1485,11 +1503,11 @@ static s32 cqm_cla_update(struct tag_cqm_handle *cqm_handle,
spu_en = 0;
pa = ((buf_node_parent->pa + (child_index * sizeof(dma_addr_t))) |
- (u32)spu_en);
+ spu_en);
cmd.gpa_h = CQM_ADDR_HI(pa);
cmd.gpa_l = CQM_ADDR_LW(pa);
- pa = (buf_node_child->pa | (u32)spu_en);
+ pa = (buf_node_child->pa | spu_en);
cmd.value_h = CQM_ADDR_HI(pa);
cmd.value_l = CQM_ADDR_LW(pa);
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
index dd0766e..a51c1dc 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
@@ -9,6 +9,7 @@
#include "cqm_bitmap_table.h"
#include "cqm_object.h"
+#include "vram_common.h"
/* When the connection check is enabled, the maximum number of connections
* supported by the chip is 1M - 63, which cannot reach 1M
@@ -19,6 +20,7 @@
#define CLA_TABLE_PAGE_ORDER 0
#define CQM_4K_PAGE_ORDER 0
#define CQM_4K_PAGE_SIZE 4096
+#define CQM_8K_PAGE_ORDER 1
#define CQM_BAT_ENTRY_MAX 16
#define CQM_BAT_ENTRY_SIZE 16
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
index d5fac94..61602e6 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
@@ -273,6 +273,11 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
return CQM_SUCCESS;
}
+static bool check_use_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ return buf->buf_info.use_vram ? true : false;
+}
+
static bool check_use_non_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
{
return buf->buf_info.use_vram ? false : true;
@@ -294,11 +299,46 @@ static bool check_for_nouse_node_alloc(struct hinic3_hwdev *handle, struct tag_c
return false;
}
+static s32 cqm_buf_vram_kalloc(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ void *vaddr = NULL;
+ int i;
+
+ vaddr = hi_vram_kalloc(buf->buf_info.buf_vram_name, (u64)buf->buf_size * buf->buf_number);
+ if (!vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
+ return CQM_FAIL;
+ }
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = (void *)((char *)vaddr + i * (u64)buf->buf_size);
+
+ return CQM_SUCCESS;
+}
+
+static void cqm_buf_vram_free(struct tag_cqm_buf *buf)
+{
+ s32 i;
+
+ if (!buf->buf_list)
+ return;
+
+ if (buf->buf_list[0].va)
+ hi_vram_kfree(buf->buf_list[0].va, buf->buf_info.buf_vram_name,
+ (u64)buf->buf_size * buf->buf_number);
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = NULL;
+}
+
static void cqm_buf_free_page_common(struct tag_cqm_buf *buf)
{
u32 order;
s32 i;
+ if (!buf->buf_list)
+ return;
+
order = (u32)get_order(buf->buf_size);
for (i = 0; i < (s32)buf->buf_number; i++) {
@@ -320,8 +360,10 @@ static s32 cqm_buf_use_node_alloc_page(struct hinic3_hwdev *handle, struct tag_c
node = dev_to_node(handle->dev_hdl);
for (i = 0; i < (s32)buf->buf_number; i++) {
newpage = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, order);
- if (!newpage)
+ if (!newpage) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
va = (void *)page_address(newpage);
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
@@ -349,8 +391,10 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
for (i = 0; i < (s32)buf->buf_number; i++) {
va = (void *)ossl_get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
- if (!va)
+ if (!va) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
* value must be 0.
@@ -367,21 +411,21 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
return CQM_SUCCESS;
}
-#define MALLOC_FUNCS_COUNT 2
-#define FREE_FUNCS_COUNT 1
-static const struct malloc_memory g_malloc_funcs[MALLOC_FUNCS_COUNT] = {
+static const struct malloc_memory g_malloc_funcs[] = {
+ {check_use_vram, cqm_buf_vram_kalloc},
{check_for_use_node_alloc, cqm_buf_use_node_alloc_page},
{check_for_nouse_node_alloc, cqm_buf_unused_node_alloc_page}
};
-static const struct free_memory g_free_funcs[FREE_FUNCS_COUNT] = {
+static const struct free_memory g_free_funcs[] = {
+ {check_use_vram, cqm_buf_vram_free},
{check_use_non_vram, cqm_buf_free_page_common}
};
static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *buf)
{
struct hinic3_hwdev *handle = cqm_handle->ex_handle;
- u32 malloc_funcs_num = MALLOC_FUNCS_COUNT;
+ u32 malloc_funcs_num = ARRAY_SIZE(g_malloc_funcs);
u32 i;
for (i = 0; i < malloc_funcs_num; i++) {
@@ -398,7 +442,7 @@ static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
static void cqm_buf_free_page(struct tag_cqm_buf *buf)
{
- u32 free_funcs_num = FREE_FUNCS_COUNT;
+ u32 free_funcs_num = ARRAY_SIZE(g_free_funcs);
u32 i;
for (i = 0; i < free_funcs_num; i++) {
@@ -447,8 +491,11 @@ static s32 cqm_buf_get_secure_mem_pages(struct tag_cqm_handle *cqm_handle, struc
cqm_get_secure_mem_pages(handle,
(u32)get_order(buf->buf_size),
&buf->buf_list[i].pa);
- if (!buf->buf_list[i].va)
+ if (!buf->buf_list[i].va) {
+ cqm_err(handle->dev_hdl,
+ CQM_ALLOC_FAIL(cqm_get_secure_mem_pages));
break;
+ }
}
if (i != buf->buf_number) {
@@ -777,7 +824,11 @@ static s32 cqm_single_bitmap_init(struct tag_cqm_bitmap *bitmap)
*/
bit_number = (ALIGN(bitmap->max_num, CQM_NUM_BIT_BYTE) >>
CQM_BYTE_BIT_SHIFT);
- bitmap->table = vmalloc(bit_number);
+ if (bitmap->bitmap_info.use_vram != 0)
+ bitmap->table = hi_vram_kalloc(bitmap->bitmap_info.buf_vram_name,
+ bit_number);
+ else
+ bitmap->table = vmalloc(bit_number);
if (!bitmap->table)
return CQM_FAIL;
memset(bitmap->table, 0, bit_number);
@@ -856,7 +907,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
}
bitmap = &cla_table->bitmap;
- snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_MAX_LEN,
"%s%s%02d", cla_table->name,
VRAM_CQM_BITMAP_BASE, cla_table->type);
@@ -866,6 +917,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
bitmap->reserved_top = capability->qpc_reserved;
bitmap->reserved_back = capability->qpc_reserved_back;
bitmap->last = capability->qpc_reserved;
+ bitmap->bitmap_info.use_vram = get_use_vram_flag();
cqm_info(handle->dev_hdl,
"Bitmap init: cla_table_type=%u, max_num=0x%x\n",
cla_table->type, bitmap->max_num);
@@ -945,7 +997,14 @@ void cqm_bitmap_uninit(struct tag_cqm_handle *cqm_handle)
if (cla_table->type != CQM_BAT_ENTRY_T_INVALID &&
bitmap->table) {
spin_lock_deinit(&bitmap->lock);
- vfree(bitmap->table);
+ if (bitmap->bitmap_info.use_vram != 0)
+ hi_vram_kfree(bitmap->table,
+ bitmap->bitmap_info.buf_vram_name,
+ ALIGN(bitmap->max_num,
+ CQM_NUM_BIT_BYTE) >>
+ CQM_BYTE_BIT_SHIFT);
+ else
+ vfree(bitmap->table);
bitmap->table = NULL;
}
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
index 7febf76..06b8661 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
@@ -9,6 +9,7 @@
#include <linux/spinlock.h>
#include "cqm_object.h"
+#include "vram_common.h"
struct tag_cqm_bitmap {
ulong *table;
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
index 9a13ae0..2a24e4a 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
@@ -196,6 +196,13 @@ void *cqm_get_db_addr(void *ex_handle, u32 service_type)
pr_err("[CQM]%s: ex_handle is null\n", __func__);
return NULL;
}
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return NULL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -218,6 +225,17 @@ s32 cqm_ring_hardware_db(void *ex_handle, u32 service_type, u8 db_count, u64 db)
struct tag_cqm_service *service = NULL;
struct hinic3_hwdev *handle = NULL;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -278,6 +296,17 @@ s32 cqm_ring_direct_wqe_db(void *ex_handle, u32 service_type, u8 db_count,
u64 *tmp = (u64 *)direct_wqe;
int i;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
index 19a8b56..1f1235c 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
@@ -23,6 +23,8 @@
#include "cqm_memsec.h"
#include "cqm_main.h"
+#include "vram_common.h"
+
static unsigned char roce_qpc_rsv_mode = CQM_QPC_ROCE_NORMAL;
module_param(roce_qpc_rsv_mode, byte, 0644);
MODULE_PARM_DESC(roce_qpc_rsv_mode,
@@ -98,10 +100,17 @@ static s32 cqm_set_timer_enable(void *ex_handle)
{
struct hinic3_hwdev *handle = (struct hinic3_hwdev *)ex_handle;
struct tag_cqm_handle *cqm_handle = NULL;
+ int is_in_kexec;
if (!ex_handle)
return CQM_FAIL;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip starting cqm timer during kexec\n");
+ return CQM_SUCCESS;
+ }
+
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
if (cqm_handle->func_capability.fake_func_type == CQM_FAKE_FUNC_PARENT &&
cqm_set_fake_vf_timer(cqm_handle) != CQM_SUCCESS)
@@ -473,7 +482,8 @@ static void cqm_service_capability_init_roce(struct tag_cqm_handle *cqm_handle,
func_cap->qpc_number += roce_own_cap->max_qps;
func_cap->qpc_basic_size = GET_MAX(roce_own_cap->qpc_entry_sz,
func_cap->qpc_basic_size);
- if (cqm_handle->func_attribute.func_type == CQM_PF && (IS_MASTER_HOST(handle))) {
+ if (cqm_handle->func_attribute.func_type == CQM_PF &&
+ (IS_MASTER_HOST(handle))) {
func_cap->hash_number = roce_own_cap->max_qps;
func_cap->hash_basic_size = CQM_HASH_BUCKET_SIZE_64;
}
@@ -1129,8 +1139,9 @@ static s32 cqm_fake_mem_init(struct tag_cqm_handle *cqm_handle)
for (i = 0; i < (u32)child_func_number; i++) {
fake_cqm_handle = cqm_handle->fake_cqm_handle[i];
- snprintf(fake_cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
- "%s%s%02u", cqm_handle->name, VRAM_CQM_FAKE_MEM_BASE, i);
+ snprintf(fake_cqm_handle->name, VRAM_NAME_MAX_LEN,
+ "%s%s%02u", cqm_handle->name,
+ VRAM_CQM_FAKE_MEM_BASE, i);
if (cqm_bat_init(fake_cqm_handle) != CQM_SUCCESS) {
cqm_err(handle->dev_hdl,
@@ -1174,8 +1185,9 @@ s32 cqm_mem_init(void *ex_handle)
struct tag_cqm_handle *cqm_handle = NULL;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
- snprintf(cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
- "%s%02u", VRAM_CQM_GLB_FUNC_BASE, hinic3_global_func_id(handle));
+ snprintf(cqm_handle->name, VRAM_NAME_MAX_LEN,
+ "%s%02u", VRAM_CQM_GLB_FUNC_BASE,
+ hinic3_global_func_id(handle));
if (cqm_fake_init(cqm_handle) != CQM_SUCCESS) {
cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_fake_init));
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
index 4f87bd1..8d1e481 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
@@ -362,6 +362,7 @@ s32 cqm_fake_vf_num_set(void *ex_handle, u16 fake_vf_num_cfg);
#define CQM_LOG_ID 0
#define CQM_PTR_NULL(x) "%s: " #x " is null\n", __func__
+#define CQM_ALLOC_FAIL(x) "%s: " #x " alloc fail\n", __func__
#define CQM_MAP_FAIL(x) "%s: " #x " map fail\n", __func__
#define CQM_FUNCTION_FAIL(x) "%s: " #x " return failure\n", __func__
#define CQM_WRONG_VALUE(x) "%s: " #x " %u is wrong\n", __func__, (u32)(x)
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
index 213803f..f5fce8f 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
@@ -378,7 +378,7 @@ static int hinic3_secure_mem_proc_node_remove(void *hwdev)
atomic_dec(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
@@ -401,7 +401,7 @@ static int hinic3_secure_mem_proc_node_add(void *hwdev)
atomic_inc(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
/* 0400 Read by owner */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h b/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
deleted file mode 100644
index ad732c3..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2019-2022. All rights reserved.
- * File Name : hinic3_comm_cmd.h
- * Version : Initial Draft
- * Created : 2019/4/25
- * Last Modified :
- * Description : COMM Commands between Driver and MPU
- * Function List :
- */
-
-#ifndef HINIC3_COMMON_CMD_H
-#define HINIC3_COMMON_CMD_H
-
-/* COMM Commands between Driver to MPU */
-enum hinic3_mgmt_cmd {
- /* flr及资源清理相关命令 */
- COMM_MGMT_CMD_FUNC_RESET = 0,
- COMM_MGMT_CMD_FEATURE_NEGO,
- COMM_MGMT_CMD_FLUSH_DOORBELL,
- COMM_MGMT_CMD_START_FLUSH,
- COMM_MGMT_CMD_SET_FUNC_FLR,
- COMM_MGMT_CMD_GET_GLOBAL_ATTR,
- COMM_MGMT_CMD_SET_PPF_FLR_TYPE,
- COMM_MGMT_CMD_SET_FUNC_SVC_USED_STATE,
-
- /* 分配msi-x中断资源 */
- COMM_MGMT_CMD_CFG_MSIX_NUM = 10,
-
- /* 驱动相关配置命令 */
- COMM_MGMT_CMD_SET_CMDQ_CTXT = 20,
- COMM_MGMT_CMD_SET_VAT,
- COMM_MGMT_CMD_CFG_PAGESIZE,
- COMM_MGMT_CMD_CFG_MSIX_CTRL_REG,
- COMM_MGMT_CMD_SET_CEQ_CTRL_REG,
- COMM_MGMT_CMD_SET_DMA_ATTR,
-
- /* INFRA配置相关命令字 */
- COMM_MGMT_CMD_GET_MQM_FIX_INFO = 40,
- COMM_MGMT_CMD_SET_MQM_CFG_INFO,
- COMM_MGMT_CMD_SET_MQM_SRCH_GPA,
- COMM_MGMT_CMD_SET_PPF_TMR,
- COMM_MGMT_CMD_SET_PPF_HT_GPA,
- COMM_MGMT_CMD_SET_FUNC_TMR_BITMAT,
- COMM_MGMT_CMD_SET_MBX_CRDT,
- COMM_MGMT_CMD_CFG_TEMPLATE,
- COMM_MGMT_CMD_SET_MQM_LIMIT,
-
- /* 信息获取相关命令字 */
- COMM_MGMT_CMD_GET_FW_VERSION = 60,
- COMM_MGMT_CMD_GET_BOARD_INFO,
- COMM_MGMT_CMD_SYNC_TIME,
- COMM_MGMT_CMD_GET_HW_PF_INFOS,
- COMM_MGMT_CMD_SEND_BDF_INFO,
- COMM_MGMT_CMD_GET_VIRTIO_BDF_INFO,
- COMM_MGMT_CMD_GET_SML_TABLE_INFO,
- COMM_MGMT_CMD_GET_SDI_INFO,
-
- /* 升级相关命令字 */
- COMM_MGMT_CMD_UPDATE_FW = 80,
- COMM_MGMT_CMD_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_DONE_NOTICE,
- COMM_MGMT_CMD_SWITCH_CFG,
- COMM_MGMT_CMD_CHECK_FLASH,
- COMM_MGMT_CMD_CHECK_FLASH_RW,
- COMM_MGMT_CMD_RESOURCE_CFG,
- COMM_MGMT_CMD_UPDATE_BIOS, /* TODO: merge to COMM_MGMT_CMD_UPDATE_FW */
- COMM_MGMT_CMD_MPU_GIT_CODE,
-
- /* chip reset相关 */
- COMM_MGMT_CMD_FAULT_REPORT = 100,
- COMM_MGMT_CMD_WATCHDOG_INFO,
- COMM_MGMT_CMD_MGMT_RESET,
- COMM_MGMT_CMD_FFM_SET, /* TODO: check if needed */
-
- /* chip info/log 相关 */
- COMM_MGMT_CMD_GET_LOG = 120,
- COMM_MGMT_CMD_TEMP_OP,
- COMM_MGMT_CMD_EN_AUTO_RST_CHIP,
- COMM_MGMT_CMD_CFG_REG,
- COMM_MGMT_CMD_GET_CHIP_ID,
- COMM_MGMT_CMD_SYSINFO_DFX,
- COMM_MGMT_CMD_PCIE_DFX_NTC,
- COMM_MGMT_CMD_DICT_LOG_STATUS, /* LOG STATUS 127 */
- COMM_MGMT_CMD_MSIX_INFO,
- COMM_MGMT_CMD_CHANNEL_DETECT,
- COMM_MGMT_CMD_DICT_COUNTER_STATUS,
-
- /* switch workmode 相关 */
- COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140,
- COMM_MGMT_CMD_SWITCH_WORKMODE,
-
- /* mpu 相关 */
- COMM_MGMT_CMD_MIGRATE_DFX_HPA = 150,
- COMM_MGMT_CMD_BDF_INFO,
- COMM_MGMT_CMD_NCSI_CFG_INFO_GET_PROC,
-
- /* rsvd0 section */
- COMM_MGMT_CMD_SECTION_RSVD_0 = 160,
-
- /* rsvd1 section */
- COMM_MGMT_CMD_SECTION_RSVD_1 = 170,
-
- /* rsvd2 section */
- COMM_MGMT_CMD_SECTION_RSVD_2 = 180,
-
- /* rsvd3 section */
- COMM_MGMT_CMD_SECTION_RSVD_3 = 190,
-
- /* TODO: move to DFT mode */
- COMM_MGMT_CMD_GET_DIE_ID = 200,
- COMM_MGMT_CMD_GET_EFUSE_TEST,
- COMM_MGMT_CMD_EFUSE_INFO_CFG,
- COMM_MGMT_CMD_GPIO_CTL,
- COMM_MGMT_CMD_HI30_SERLOOP_START, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_SERLOOP_STOP, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_SET_FLAG, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_GET_RESULT, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_ECC_TEST,
- COMM_MGMT_CMD_FUNC_BIST_TEST, /* 209 */
-
- COMM_MGMT_CMD_VPD_SET = 210,
- COMM_MGMT_CMD_VPD_GET,
-
- COMM_MGMT_CMD_ERASE_FLASH,
- COMM_MGMT_CMD_QUERY_FW_INFO,
- COMM_MGMT_CMD_GET_CFG_INFO,
- COMM_MGMT_CMD_GET_UART_LOG,
- COMM_MGMT_CMD_SET_UART_CMD,
- COMM_MGMT_CMD_SPI_TEST,
-
- /* TODO: ALL reg read/write merge to COMM_MGMT_CMD_CFG_REG */
- COMM_MGMT_CMD_UP_REG_GET,
- COMM_MGMT_CMD_UP_REG_SET, /* 219 */
-
- COMM_MGMT_CMD_REG_READ = 220,
- COMM_MGMT_CMD_REG_WRITE,
- COMM_MGMT_CMD_MAG_REG_WRITE,
- COMM_MGMT_CMD_ANLT_REG_WRITE,
-
- COMM_MGMT_CMD_HEART_EVENT, /* TODO: delete */
- COMM_MGMT_CMD_NCSI_OEM_GET_DRV_INFO, /* TODO: delete */
- COMM_MGMT_CMD_LASTWORD_GET,
- COMM_MGMT_CMD_READ_BIN_DATA, /* TODO: delete */
- /* COMM_MGMT_CMD_WWPN_GET, TODO: move to FC? */
- /* COMM_MGMT_CMD_WWPN_SET, TODO: move to FC? */ /* 229 */
-
- /* TODO: check if needed */
- COMM_MGMT_CMD_SET_VIRTIO_DEV = 230,
- COMM_MGMT_CMD_SET_MAC,
- /* MPU patch cmd */
- COMM_MGMT_CMD_LOAD_PATCH,
- COMM_MGMT_CMD_REMOVE_PATCH,
- COMM_MGMT_CMD_PATCH_ACTIVE,
- COMM_MGMT_CMD_PATCH_DEACTIVE,
- COMM_MGMT_CMD_PATCH_SRAM_OPTIMIZE,
- /* container host process */
- COMM_MGMT_CMD_CONTAINER_HOST_PROC,
- /* nsci counter */
- COMM_MGMT_CMD_NCSI_COUNTER_PROC,
- COMM_MGMT_CMD_CHANNEL_STATUS_CHECK, /* 239 */
-
- /* hot patch rsvd cmd */
- COMM_MGMT_CMD_RSVD_0 = 240,
- COMM_MGMT_CMD_RSVD_1,
- COMM_MGMT_CMD_RSVD_2,
- COMM_MGMT_CMD_RSVD_3,
- COMM_MGMT_CMD_RSVD_4,
- /* 无效字段,版本收编删除,编译使用 */
- COMM_MGMT_CMD_SEND_API_ACK_BY_UP,
-
- /* 注:添加cmd,不能修改已有命令字的值,请在前方rsvd
- * section中添加;原则上所有分支cmd表完全一致
- */
- COMM_MGMT_CMD_MAX = 255,
-};
-
-/* CmdQ Common subtype */
-enum comm_cmdq_cmd {
- COMM_CMD_UCODE_ARM_BIT_SET = 2,
- COMM_CMD_SEND_NPU_DFT_CMD,
-};
-
-#endif /* HINIC3_COMMON_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
deleted file mode 100644
index 9ce908e..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_COMMON_H
-#define HINIC3_COMMON_H
-
-#include <linux/types.h>
-
-struct hinic3_dma_addr_align {
- u32 real_size;
-
- void *ori_vaddr;
- dma_addr_t ori_paddr;
-
- void *align_vaddr;
- dma_addr_t align_paddr;
-};
-
-enum hinic3_wait_return {
- WAIT_PROCESS_CPL = 0,
- WAIT_PROCESS_WAITING = 1,
- WAIT_PROCESS_ERR = 2,
-};
-
-struct hinic3_sge {
- u32 hi_addr;
- u32 lo_addr;
- u32 len;
-};
-
-#ifdef static
-#undef static
-#define LLT_STATIC_DEF_SAVED
-#endif
-
-/* *
- * hinic_cpu_to_be32 - convert data to big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert, must be Multiple of 4B
- */
-static inline void hinic3_cpu_to_be32(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = cpu_to_be32(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_cpu_to_be32 - convert data from big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert
- */
-static inline void hinic3_be32_to_cpu(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = be32_to_cpu(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_set_sge - set dma area in scatter gather entry
- * @sge: scatter gather entry
- * @addr: dma address
- * @len: length of relevant data in the dma address
- */
-static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
- int len)
-{
- sge->hi_addr = upper_32_bits(addr);
- sge->lo_addr = lower_32_bits(addr);
- sge->len = len;
-}
-
-#define hinic3_hw_be32(val) (val)
-#define hinic3_hw_cpu32(val) (val)
-#define hinic3_hw_cpu16(val) (val)
-
-static inline void hinic3_hw_be32_len(void *data, int len)
-{
-}
-
-static inline void hinic3_hw_cpu32_len(void *data, int len)
-{
-}
-
-int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
- unsigned int flag,
- struct hinic3_dma_addr_align *mem_align);
-
-void hinic3_dma_free_coherent_align(void *dev_hdl,
- struct hinic3_dma_addr_align *mem_align);
-
-typedef enum hinic3_wait_return (*wait_cpl_handler)(void *priv_data);
-
-int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
- u32 wait_total_ms, u32 wait_once_us);
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
index 64139c4..4f5792f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
@@ -8,7 +8,7 @@
#include "mpu_cmd_base_defs.h"
-#define HINIC3_DRV_VERSION "15.17.1.2"
+#define HINIC3_DRV_VERSION "17.7.8.1"
#define HINIC3_DRV_DESC "Intelligent Network Interface Card Driver"
#define HIUDK_DRV_DESC "Intelligent Network Unified Driver"
@@ -45,6 +45,7 @@ enum hinic3_service_type {
SERVICE_T_CUSTOM,
SERVICE_T_VROCE,
SERVICE_T_CRYPT,
+ SERVICE_T_VSOCK,
SERVICE_T_BIFUR,
SERVICE_T_MAX,
@@ -64,6 +65,9 @@ struct nic_service_cap {
u16 max_sqs;
u16 max_rqs;
u16 default_num_queues;
+ u16 outband_vlan_cfg_en;
+ u8 lro_enable;
+ u8 rsvd1[3];
};
struct ppa_service_cap {
@@ -909,6 +913,13 @@ int hinic3_get_mgmt_version(void *hwdev, u8 *mgmt_ver, u8 version_size,
int hinic3_get_fw_version(void *hwdev, struct hinic3_fw_version *fw_ver,
u16 channel);
+/* *
+ * @brief hinic3_get_bond_create_mode - get bond create mode
+ * @param hwdev: device pointer to hwdev
+ * @retval global function id
+ */
+u8 hinic3_get_bond_create_mode(void *udkdev);
+
/* *
* @brief hinic3_global_func_id - get global function id
* @param hwdev: device pointer to hwdev
@@ -1263,4 +1274,7 @@ int hinic3_mbox_to_host_sync(void *hwdev, enum hinic3_mod_type mod,
int hinic3_get_func_vroce_enable(void *hwdev, u16 glb_func_idx, u8 *en);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type);
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
index 40ff473..1191653 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
@@ -18,9 +18,10 @@
#include "hinic3_tx.h"
#include "hinic3_dcb.h"
#include "hinic3_nic.h"
-#include "hinic3_mgmt_interface.h"
+#include "hinic3_bond.h"
+#include "nic_mpu_cmd_defs.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
typedef int (*nic_driv_module)(struct hinic3_nic_dev *nic_dev,
const void *buf_in, u32 in_size,
@@ -34,7 +35,6 @@ struct nic_drv_module_handle {
static int get_nic_drv_version(void *buf_out, const u32 *out_size)
{
struct drv_version_info *ver_info = buf_out;
- int err;
if (!buf_out) {
pr_err("Buf_out is NULL.\n");
@@ -47,10 +47,8 @@ static int get_nic_drv_version(void *buf_out, const u32 *out_size)
return -EINVAL;
}
- err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
- HINIC3_NIC_DRV_VERSION, "2023-05-17_19:56:38");
- if (err < 0)
- return -EINVAL;
+ snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
+ HINIC3_NIC_DRV_VERSION, "2025-05-08_00:00:08");
return 0;
}
@@ -126,7 +124,8 @@ static int get_tx_wqe_info(struct hinic3_nic_dev *nic_dev,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -178,7 +177,8 @@ static int get_rx_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
rq_info->delta = (u16)nic_dev->rxqs[q_id].delta;
- rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx & nic_dev->rxqs[q_id].q_mask);
+ rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx &
+ nic_dev->rxqs[q_id].q_mask);
rq_info->sw_pi = nic_dev->rxqs[q_id].next_to_update;
rq_info->msix_vector = nic_dev->rxqs[q_id].irq_id;
@@ -201,7 +201,8 @@ static int get_rx_wqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -230,7 +231,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EFAULT;
}
- if (!buf_in || !buf_out) {
+ if (!buf_in || !buf_out || !out_size) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Buf_in or buf_out is NULL.\n");
return -EINVAL;
@@ -243,7 +244,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EINVAL;
}
- if (!out_size || *out_size != sizeof(struct hinic3_rq_cqe)) {
+ if (*out_size != sizeof(struct hinic3_rq_cqe)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(struct hinic3_rq_cqe));
@@ -252,10 +253,12 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
q_id = (u16)info->q_id;
idx = (u16)info->wqe_id;
- if (q_id >= nic_dev->q_params.num_qps || idx >= nic_dev->rxqs[q_id].q_depth) {
+ if (q_id >= nic_dev->q_params.num_qps ||
+ idx >= nic_dev->rxqs[q_id].q_depth) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid q_id[%u] >= %u, or wqe idx[%u] >= %u.\n",
- q_id, nic_dev->q_params.num_qps, idx, nic_dev->rxqs[q_id].q_depth);
+ q_id, nic_dev->q_params.num_qps, idx,
+ nic_dev->rxqs[q_id].q_depth);
return -EFAULT;
}
@@ -338,7 +341,8 @@ static int set_loopback_mode(struct hinic3_nic_dev *nic_dev, const void *buf_in,
err = hinic3_set_loopback_mode(nic_dev->hwdev, (u8)mode->loop_mode,
(u8)mode->loop_ctrl);
if (err == 0)
- nicif_info(nic_dev, drv, nic_dev->netdev, "Set loopback mode %u en %u succeed\n",
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Set loopback mode %u en %u succeed\n",
mode->loop_mode, mode->loop_ctrl);
return err;
@@ -417,6 +421,59 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
{
u32 pf_bw_limit;
int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
+
+ if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To set VF bandwidth rate, please use ip link cmd\n");
+ return -EINVAL;
+ }
+
+ if (!buf_in || !buf_out || in_size != sizeof(u32) ||
+ !out_size || *out_size != sizeof(u8))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_TX;
+ pf_bw_limit = *((u32 *)buf_in);
+
+ err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
+ if (err) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %u%%\n",
+ pf_bw_limit);
+ if (err < 0)
+ return err;
+ }
+
+ *((u8 *)buf_out) = (u8)err;
+
+ return 0;
+}
+
+static int set_rx_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ u32 pf_bw_limit;
+ int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
nicif_err(nic_dev, drv, nic_dev->netdev, "To set VF bandwidth rate, please use ip link cmd\n");
@@ -426,11 +483,16 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || !buf_out || in_size != sizeof(u32) || !out_size || *out_size != sizeof(u8))
return -EINVAL;
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_RX;
pf_bw_limit = *((u32 *)buf_in);
err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %d%%\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to set pf bandwidth limit to %d%%\n",
pf_bw_limit);
if (err < 0)
return err;
@@ -445,19 +507,21 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
struct hinic3_nic_io *nic_io = NULL;
+ u32 *rate_limit = (u32 *)buf_out;
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "To get VF bandwidth rate, please use ip link cmd\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To get VF bandwidth rate, please use ip link cmd\n");
return -EINVAL;
}
if (!buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(u32)) {
+ if (*out_size != sizeof(u32) * 2) { // 2:Stored in an array, TX and RX, both length are u32
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user: %d, expect: %lu\n",
- *out_size, sizeof(u32));
+ *out_size, sizeof(u32) * 2);
return -EFAULT;
}
@@ -465,8 +529,12 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!nic_io)
return -EINVAL;
- *((u32 *)buf_out) = nic_io->nic_cfg.pf_bw_limit;
+ rate_limit[HINIC3_NIC_RX] = nic_io->nic_cfg.pf_bw_rx_limit;
+ rate_limit[HINIC3_NIC_TX] = nic_io->nic_cfg.pf_bw_tx_limit;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "read rate cfg success rx rate is: %u, tx rate is : %u\n",
+ rate_limit[HINIC3_NIC_RX], rate_limit[HINIC3_NIC_TX]);
return 0;
}
@@ -477,8 +545,8 @@ static int get_sset_count(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || in_size != sizeof(u32) || !out_size ||
*out_size != sizeof(u32) || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
@@ -504,16 +572,16 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
int err;
if (!buf_in || in_size != sizeof(u32) || !out_size || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
size = sizeof(u32);
err = get_sset_count(nic_dev, buf_in, in_size, &count, &size);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Get sset count failed, ret=%d\n",
- err);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Get sset count failed, ret=%d\n", err);
return -EINVAL;
}
if (count * sizeof(*items) != *out_size) {
@@ -527,12 +595,14 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
switch (sset) {
case HINIC3_SHOW_SSET_IO_STATS:
- hinic3_get_io_stats(nic_dev, items);
+ err = hinic3_get_io_stats(nic_dev, items);
+ if (err < 0)
+ return -EINVAL;
break;
default:
- nicif_err(nic_dev, drv, nic_dev->netdev, "Unknown %u to get stats\n",
- sset);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unknown %u to get stats\n", sset);
err = -EINVAL;
break;
}
@@ -544,15 +614,18 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int i;
u8 cos_num = 0, valid_cos_bitmap = 0;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_PCP2COS) {
for (i = 0; i < NIC_DCB_UP_MAX; i++) {
- if (!(nic_dev->func_dft_cos_bitmap & BIT(qos_in->pcp2cos[i]))) {
+ if (!(dcb->func_dft_cos_bitmap &
+ BIT(qos_in->pcp2cos[i]))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- qos_in->pcp2cos[i], nic_dev->func_dft_cos_bitmap);
+ qos_in->pcp2cos[i],
+ dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -562,7 +635,8 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
}
- memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos, sizeof(qos_in->pcp2cos));
+ memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos,
+ sizeof(qos_in->pcp2cos));
wanted_dcb_cfg->pcp_user_cos_num = cos_num;
wanted_dcb_cfg->pcp_valid_cos_map = valid_cos_bitmap;
}
@@ -572,12 +646,14 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = 0;
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++) {
u8 cos = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->wanted_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ dcb->wanted_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
- if (cos >= NIC_DCB_UP_MAX || !(nic_dev->func_dft_cos_bitmap & BIT(cos))) {
+ if (cos >= NIC_DCB_UP_MAX ||
+ !(dcb->func_dft_cos_bitmap & BIT(cos))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- cos, nic_dev->func_dft_cos_bitmap);
+ cos, dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -588,8 +664,10 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- wanted_dcb_cfg->dscp2cos[i] = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->hw_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ wanted_dcb_cfg->dscp2cos[i] =
+ qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
+ dcb->hw_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
wanted_dcb_cfg->dscp_user_cos_num = cos_num;
wanted_dcb_cfg->dscp_valid_cos_map = valid_cos_bitmap;
}
@@ -601,11 +679,12 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int ret;
u8 cos_num, valid_cos_bitmap;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_TRUST) {
- if (qos_in->trust > DCB_DSCP) {
+ if (qos_in->trust > HINIC3_DCB_DSCP) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid trust=%u\n", qos_in->trust);
return -EINVAL;
@@ -615,7 +694,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
}
if (qos_in->cfg_bitmap & CMD_QOS_DEV_DFT_COS) {
- if (!(BIT(qos_in->dft_cos) & nic_dev->func_dft_cos_bitmap)) {
+ if (!(BIT(qos_in->dft_cos) & dcb->func_dft_cos_bitmap)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid dft_cos=%u\n", qos_in->dft_cos);
return -EINVAL;
@@ -628,7 +707,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
if (ret)
return ret;
- if (wanted_dcb_cfg->trust == DCB_PCP) {
+ if (wanted_dcb_cfg->trust == HINIC3_DCB_PCP) {
cos_num = wanted_dcb_cfg->pcp_user_cos_num;
valid_cos_bitmap = wanted_dcb_cfg->pcp_valid_cos_map;
} else {
@@ -636,18 +715,11 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = wanted_dcb_cfg->dscp_valid_cos_map;
}
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "DCB is on, cos num should not more than channel num:%u\n",
- nic_dev->q_params.num_qps);
- return -EOPNOTSUPP;
- }
- }
-
if (!(BIT(wanted_dcb_cfg->default_cos) & valid_cos_bitmap)) {
- nicif_info(nic_dev, drv, nic_dev->netdev, "Current default_cos=%u, change to %u\n",
- wanted_dcb_cfg->default_cos, (u8)fls(valid_cos_bitmap) - 1);
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Current default_cos=%u, change to %u\n",
+ wanted_dcb_cfg->default_cos,
+ (u8)fls(valid_cos_bitmap) - 1);
wanted_dcb_cfg->default_cos = (u8)fls(valid_cos_bitmap) - 1;
}
@@ -657,6 +729,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_dev_cfg *qos_in = buf_in;
struct hinic3_mt_qos_dev_cfg *qos_out = buf_out;
u8 i;
@@ -675,9 +748,10 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(qos_out, qos_in, sizeof(*qos_in));
qos_out->head.status = 0;
if (qos_in->op_code & MT_DCB_OPCODE_WR) {
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg,
+ memcpy(&dcb->wanted_dcb_cfg, &dcb->hw_dcb_cfg,
sizeof(struct hinic3_dcb_config));
- err = update_wanted_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg, qos_in);
+ err = update_wanted_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg,
+ qos_in);
if (err) {
qos_out->head.status = MT_EINVAL;
return 0;
@@ -687,12 +761,12 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
qos_out->head.status = MT_EIO;
} else {
- qos_out->dft_cos = nic_dev->hw_dcb_cfg.default_cos;
- qos_out->trust = nic_dev->hw_dcb_cfg.trust;
+ qos_out->dft_cos = dcb->hw_dcb_cfg.default_cos;
+ qos_out->trust = dcb->hw_dcb_cfg.trust;
for (i = 0; i < NIC_DCB_UP_MAX; i++)
- qos_out->pcp2cos[i] = nic_dev->hw_dcb_cfg.pcp2cos[i];
+ qos_out->pcp2cos[i] = dcb->hw_dcb_cfg.pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- qos_out->dscp2cos[i] = nic_dev->hw_dcb_cfg.dscp2cos[i];
+ qos_out->dscp2cos[i] = dcb->hw_dcb_cfg.dscp2cos[i];
}
return 0;
@@ -721,27 +795,17 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(dcb_out, dcb_in, sizeof(*dcb_in));
dcb_out->head.status = 0;
if (dcb_in->op_code & MT_DCB_OPCODE_WR) {
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) == dcb_in->state)
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ==
+ dcb_in->state)
return 0;
- if (dcb_in->state) {
- if (user_cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "cos num %u should not more than channel num %u\n",
- user_cos_num,
- nic_dev->q_params.num_qps);
-
- return -EOPNOTSUPP;
- }
- }
-
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? user_cos_num : 0,
+ err = hinic3_setup_cos(nic_dev->netdev,
+ dcb_in->state ? user_cos_num : 0,
netif_run);
if (err)
goto setup_cos_fail;
@@ -751,7 +815,6 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
goto vport_up_fail;
}
- rtnl_unlock();
} else {
dcb_out->state = !!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
}
@@ -759,12 +822,12 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
vport_up_fail:
- hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num,
+ netif_run);
setup_cos_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
return err;
}
@@ -772,13 +835,15 @@ setup_cos_fail:
static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_cos_cfg *cos_cfg_in = buf_in;
struct hinic3_mt_qos_cos_cfg *cos_cfg_out = buf_out;
if (!buf_in || !buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(*cos_cfg_out) || in_size != sizeof(*cos_cfg_in)) {
+ if (*out_size != sizeof(*cos_cfg_out) ||
+ in_size != sizeof(*cos_cfg_in)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
in_size, *out_size, sizeof(*cos_cfg_in));
@@ -789,9 +854,9 @@ static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
cos_cfg_out->head.status = 0;
cos_cfg_out->port_id = hinic3_physical_port_id(nic_dev->hwdev);
- cos_cfg_out->func_cos_bitmap = (u8)nic_dev->func_dft_cos_bitmap;
- cos_cfg_out->port_cos_bitmap = (u8)nic_dev->port_dft_cos_bitmap;
- cos_cfg_out->func_max_cos_num = nic_dev->cos_config_num_max;
+ cos_cfg_out->func_cos_bitmap = (u8)dcb->func_dft_cos_bitmap;
+ cos_cfg_out->port_cos_bitmap = (u8)dcb->port_dft_cos_bitmap;
+ cos_cfg_out->func_max_cos_num = dcb->cos_config_num_max;
return 0;
}
@@ -803,7 +868,13 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
intr_num = hinic3_intr_num(nic_dev->hwdev);
- if (!buf_out || !out_size || *out_size != sizeof(u16)) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != sizeof(u16)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(u16));
@@ -817,7 +888,13 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
static int get_netdev_name(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- if (!buf_out || !out_size || *out_size != IFNAMSIZ) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != IFNAMSIZ) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %u\n",
*out_size, IFNAMSIZ);
@@ -829,8 +906,9 @@ static int get_netdev_name(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
}
-static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
int *tx_timeout = buf_out;
@@ -839,7 +917,8 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (*out_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, out_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, out_size: %u, expect: %lu\n",
*out_size, sizeof(int));
return -EINVAL;
}
@@ -849,8 +928,9 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return 0;
}
-static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
const int *tx_timeout = buf_in;
@@ -859,13 +939,15 @@ static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (in_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, in_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, in_size: %u, expect: %lu\n",
in_size, sizeof(int));
return -EINVAL;
}
net_dev->watchdog_timeo = *tx_timeout * HZ;
- nicif_info(nic_dev, drv, net_dev, "Set tx timeout check period to %ds\n", *tx_timeout);
+ nicif_info(nic_dev, drv, net_dev,
+ "Set tx timeout check period to %ds\n", *tx_timeout);
return 0;
}
@@ -891,6 +973,34 @@ static int get_xsfp_present(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
}
+static int get_xsfp_tlv_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info = buf_out;
+ const struct tag_mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req = buf_in;
+ int err;
+
+ if (!buf_in || !buf_out || !out_size)
+ return -EINVAL;
+
+ if (*out_size != sizeof(*sfp_tlv_info) ||
+ in_size != sizeof(*sfp_tlv_info_req)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
+ in_size, *out_size, sizeof(*sfp_tlv_info));
+ return -EINVAL;
+ }
+
+ err = hinic3_get_sfp_tlv_info(nic_dev->hwdev,
+ sfp_tlv_info, sfp_tlv_info_req);
+ if (err != 0) {
+ sfp_tlv_info->head.status = MT_EIO;
+ return 0;
+ }
+
+ return 0;
+}
+
static int get_xsfp_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
@@ -928,7 +1038,7 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{GET_LOOPBACK_MODE, get_loopback_mode},
{SET_LOOPBACK_MODE, set_loopback_mode},
{SET_LINK_MODE, set_link_mode},
- {SET_PF_BW_LIMIT, set_pf_bw_limit},
+ {SET_TX_PF_BW_LIMIT, set_pf_bw_limit},
{GET_PF_BW_LIMIT, get_pf_bw_limit},
{GET_SSET_COUNT, get_sset_count},
{GET_SSET_ITEMS, get_sset_stats},
@@ -940,17 +1050,22 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{SET_TX_TIMEOUT, set_netdev_tx_timeout},
{GET_XSFP_PRESENT, get_xsfp_present},
{GET_XSFP_INFO, get_xsfp_info},
+ {GET_XSFP_INFO_COMP_CMIS, get_xsfp_tlv_info},
+ {SET_RX_PF_BW_LIMIT, set_rx_pf_bw_limit}
};
static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
u32 cmd, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(nic_driv_module_cmd_handle) /
- sizeof(nic_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(nic_driv_module_cmd_handle) /
+ sizeof(nic_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type = (enum driver_cmd_type)cmd;
int err = 0;
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_lock();
+
mutex_lock(&nic_dev->nic_mutex);
for (index = 0; index < num_cmds; index++) {
if (cmd_type ==
@@ -963,6 +1078,9 @@ static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
}
mutex_unlock(&nic_dev->nic_mutex);
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_unlock();
+
if (index == num_cmds) {
pr_err("Can't find callback for %d\n", cmd_type);
return -EINVAL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
index a1fb4af..603a2ab 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
@@ -24,82 +24,80 @@
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_user_cos_num;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_user_cos_num;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_user_cos_num;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_user_cos_num;
return 0;
}
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_valid_cos_map;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_valid_cos_map;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_valid_cos_map;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_valid_cos_map;
return 0;
}
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
- u8 i, remainder, num_sq_per_cos, cur_cos_num = 0;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ struct hinic3_dcb_config *wanted_dcb_cfg =
+ &nic_dev->dcb->wanted_dcb_cfg;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
+ u8 cos_qp_num, cos_qp_offset = 0;
+ u8 i, remainder, num_qp_per_cos;
- if (num_cos == 0)
- return;
-
- num_sq_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
- if (num_sq_per_cos == 0)
+ if (num_cos == 0 || nic_dev->q_params.num_qps == 0)
return;
- remainder = nic_dev->q_params.num_qps % num_sq_per_cos;
+ num_qp_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
+ remainder = nic_dev->q_params.num_qps % num_cos;
- memset(dcb_cfg->cos_qp_offset, 0, sizeof(dcb_cfg->cos_qp_offset));
- memset(dcb_cfg->cos_qp_num, 0, sizeof(dcb_cfg->cos_qp_num));
+ memset(hw_dcb_cfg->cos_qp_offset, 0, sizeof(hw_dcb_cfg->cos_qp_offset));
+ memset(hw_dcb_cfg->cos_qp_num, 0, sizeof(hw_dcb_cfg->cos_qp_num));
for (i = 0; i < PCP_MAX_UP; i++) {
if (BIT(i) & valid_cos_map) {
- u8 cos_qp_num = num_sq_per_cos;
- u8 cos_qp_offset = (u8)(cur_cos_num * num_sq_per_cos);
-
- if (cur_cos_num < remainder) {
- cos_qp_num++;
- cos_qp_offset += cur_cos_num;
- } else {
- cos_qp_offset += remainder;
- }
-
- cur_cos_num++;
- valid_cos_map -= (u8)BIT(i);
+ cos_qp_num = num_qp_per_cos + ((remainder > 0) ?
+ (remainder--, 1) : 0);
- dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
- dcb_cfg->cos_qp_num[i] = cos_qp_num;
+ hw_dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
+ hw_dcb_cfg->cos_qp_num[i] = cos_qp_num;
hinic3_info(nic_dev, drv, "cos %u, cos_qp_offset=%u cos_qp_num=%u\n",
i, cos_qp_offset, cos_qp_num);
+
+ cos_qp_offset += cos_qp_num;
+ valid_cos_map -= (u8)BIT(i);
}
}
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_offset, dcb_cfg->cos_qp_offset,
- sizeof(dcb_cfg->cos_qp_offset));
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_num, dcb_cfg->cos_qp_num,
- sizeof(dcb_cfg->cos_qp_num));
+ memcpy(wanted_dcb_cfg->cos_qp_offset, hw_dcb_cfg->cos_qp_offset,
+ sizeof(hw_dcb_cfg->cos_qp_offset));
+ memcpy(wanted_dcb_cfg->cos_qp_num, hw_dcb_cfg->cos_qp_num,
+ sizeof(hw_dcb_cfg->cos_qp_num));
}
void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
u8 i;
u16 start_qid, q_num;
hinic3_set_txq_cos(nic_dev, 0, nic_dev->q_params.num_qps,
- nic_dev->hw_dcb_cfg.default_cos);
+ hw_dcb_cfg->default_cos);
if (!dcb_en)
return;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- q_num = (u16)nic_dev->hw_dcb_cfg.cos_qp_num[i];
+ q_num = (u16)hw_dcb_cfg->cos_qp_num[i];
if (q_num) {
- start_qid = (u16)nic_dev->hw_dcb_cfg.cos_qp_offset[i];
+ start_qid = (u16)hw_dcb_cfg->cos_qp_offset[i];
hinic3_set_txq_cos(nic_dev, start_qid, q_num, i);
hinic3_info(nic_dev, drv, "update tx db cos, start_qid %u, q_num=%u cos=%u\n",
@@ -110,30 +108,28 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ struct hinic3_dcb_config *hw_dcb_cfg = &dcb->hw_dcb_cfg;
struct hinic3_dcb_state dcb_state = {0};
u8 i;
int err;
-
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- /* VF does not support DCB, use the default cos */
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
-
- return 0;
- }
+ u32 pcp2cos_size = sizeof(dcb_state.pcp2cos);
+ u32 dscp2cos_size = sizeof(dcb_state.dscp2cos);
dcb_state.dcb_on = dcb_en;
- dcb_state.default_cos = dcb_cfg->default_cos;
- dcb_state.trust = dcb_cfg->trust;
+ dcb_state.default_cos = hw_dcb_cfg->default_cos;
+ dcb_state.trust = hw_dcb_cfg->trust;
if (dcb_en) {
for (i = 0; i < NIC_DCB_COS_MAX; i++)
- dcb_state.pcp2cos[i] = dcb_cfg->pcp2cos[i];
+ dcb_state.pcp2cos[i] = hw_dcb_cfg->pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- dcb_state.dscp2cos[i] = dcb_cfg->dscp2cos[i];
+ dcb_state.dscp2cos[i] = hw_dcb_cfg->dscp2cos[i];
} else {
- memset(dcb_state.pcp2cos, dcb_cfg->default_cos, sizeof(dcb_state.pcp2cos));
- memset(dcb_state.dscp2cos, dcb_cfg->default_cos, sizeof(dcb_state.dscp2cos));
+ memset(dcb_state.pcp2cos, hw_dcb_cfg->default_cos,
+ pcp2cos_size);
+ memset(dcb_state.dscp2cos, hw_dcb_cfg->default_cos,
+ dscp2cos_size);
}
err = hinic3_set_dcb_state(nic_dev->hwdev, &dcb_state);
@@ -143,7 +139,7 @@ static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
return err;
}
-static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
int err;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
@@ -169,11 +165,13 @@ static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
goto rx_configure_fail;
}
- if (dcb_en)
+ if (dcb_en) {
set_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
- else
+ set_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ } else {
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
-
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ }
return 0;
rx_configure_fail:
hinic3_set_tx_cos_state(nic_dev, dcb_en ? 0 : 1);
@@ -188,6 +186,7 @@ set_tx_cos_fail:
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err;
if (cos && test_bit(HINIC3_SAME_RXTX, &nic_dev->flags)) {
@@ -195,9 +194,10 @@ int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
return -EOPNOTSUPP;
}
- if (cos > nic_dev->cos_config_num_max) {
- nicif_err(nic_dev, drv, netdev, "Invalid num_tc: %u, max cos: %u\n",
- cos, nic_dev->cos_config_num_max);
+ if (cos > dcb->cos_config_num_max) {
+ nicif_err(nic_dev, drv, netdev,
+ "Invalid num_tc: %u, max cos: %u\n",
+ cos, dcb->cos_config_num_max);
return -EINVAL;
}
@@ -223,36 +223,48 @@ static u8 get_cos_num(u8 hw_valid_cos_bitmap)
static void hinic3_sync_dcb_cfg(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dcb_config *dcb_cfg)
{
- struct hinic3_dcb_config *hw_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
- memcpy(hw_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(hw_dcb_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
}
static int init_default_dcb_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *dcb_cfg)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 i, hw_dft_cos_map, port_cos_bitmap, dscp_ind;
int err;
+ int is_in_kexec;
- err = hinic3_cos_valid_bitmap(nic_dev->hwdev, &hw_dft_cos_map, &port_cos_bitmap);
+ err = hinic3_cos_valid_bitmap(nic_dev->hwdev,
+ &hw_dft_cos_map, &port_cos_bitmap);
if (err) {
hinic3_err(nic_dev, drv, "None cos supported\n");
return -EFAULT;
}
- nic_dev->func_dft_cos_bitmap = hw_dft_cos_map;
- nic_dev->port_dft_cos_bitmap = port_cos_bitmap;
- nic_dev->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+ is_in_kexec = vram_get_kexec_flag();
- dcb_cfg->trust = DCB_PCP;
- dcb_cfg->pcp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->dscp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
+ dcb->func_dft_cos_bitmap = hw_dft_cos_map;
+ dcb->port_dft_cos_bitmap = port_cos_bitmap;
+
+ dcb->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+
+ if (is_in_kexec == 0) {
+ dcb_cfg->trust = HINIC3_DCB_PCP;
+ dcb_cfg->default_cos = (u8)fls(dcb->func_dft_cos_bitmap) - 1;
+ } else {
+ dcb_cfg->trust = nic_dev->dcb->hw_dcb_cfg.trust;
+ dcb_cfg->default_cos = nic_dev->dcb->hw_dcb_cfg.default_cos;
+ }
+ dcb_cfg->pcp_user_cos_num = dcb->cos_config_num_max;
+ dcb_cfg->dscp_user_cos_num = dcb->cos_config_num_max;
dcb_cfg->pcp_valid_cos_map = hw_dft_cos_map;
dcb_cfg->dscp_valid_cos_map = hw_dft_cos_map;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i) ? i : dcb_cfg->default_cos;
+ dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i) ?
+ i : (u8)fls(dcb->func_dft_cos_bitmap) - 1;
for (dscp_ind = 0; dscp_ind < NIC_DCB_COS_MAX; dscp_ind++)
dcb_cfg->dscp2cos[i * NIC_DCB_DSCP_NUM + dscp_ind] = dcb_cfg->pcp2cos[i];
}
@@ -276,58 +288,115 @@ int hinic3_configure_dcb(struct net_device *netdev)
int err;
err = hinic3_sync_dcb_state(nic_dev->hwdev, 1,
- test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)
+ ? 1 : 0);
if (err) {
hinic3_err(nic_dev, drv, "Set dcb state failed\n");
return err;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ hinic3_sync_dcb_cfg(nic_dev, &nic_dev->dcb->wanted_dcb_cfg);
else
hinic3_dcb_reset_hw_config(nic_dev);
return 0;
}
+static int hinic3_dcb_alloc(struct hinic3_nic_dev *nic_dev)
+{
+ u16 func_id;
+ int is_use_vram;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(nic_dev->dcb_name, VRAM_NAME_MAX_LEN,
+ "%s%hu%s", VRAM_CQM_GLB_FUNC_BASE, func_id,
+ VRAM_NIC_DCB);
+
+ nic_dev->dcb = (struct hinic3_dcb *)hi_vram_kalloc(nic_dev->dcb_name,
+ sizeof(*nic_dev->dcb));
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to vram alloc dcb.\n");
+ return -EFAULT;
+ }
+ } else {
+ nic_dev->dcb = kzalloc(sizeof(*nic_dev->dcb), GFP_KERNEL);
+ if (!nic_dev->dcb)
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static void hinic3_dcb_free(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram)
+ hi_vram_kfree((void *)nic_dev->dcb, nic_dev->dcb_name,
+ sizeof(*nic_dev->dcb));
+ else
+ kfree(nic_dev->dcb);
+ nic_dev->dcb = NULL;
+}
+
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
+ hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+
+ hinic3_dcb_free(nic_dev);
+}
+
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = NULL;
int err;
u8 dcb_en = test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0;
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- return hinic3_set_tx_cos_state(nic_dev, dcb_en);
+ err = hinic3_dcb_alloc(nic_dev);
+ if (err != 0) {
+ hinic3_err(nic_dev, drv, "Dcb alloc failed.\n");
+ return err;
+ }
- err = init_default_dcb_cfg(nic_dev, dcb_cfg);
+ hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ err = init_default_dcb_cfg(nic_dev, hw_dcb_cfg);
if (err) {
- hinic3_err(nic_dev, drv, "Initialize dcb configuration failed\n");
+ hinic3_err(nic_dev, drv,
+ "Initialize dcb configuration failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&nic_dev->dcb->wanted_dcb_cfg, hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
hinic3_info(nic_dev, drv, "Support num cos %u, default cos %u\n",
- nic_dev->cos_config_num_max, dcb_cfg->default_cos);
+ nic_dev->dcb->cos_config_num_max, hw_dcb_cfg->default_cos);
err = hinic3_set_tx_cos_state(nic_dev, dcb_en);
if (err) {
hinic3_err(nic_dev, drv, "Set tx cos state failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- sema_init(&nic_dev->dcb_sem, 1);
-
return 0;
}
-static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dcb_config *dcb_cfg)
+static int change_qos_cfg(struct hinic3_nic_dev *nic_dev,
+ const struct hinic3_dcb_config *dcb_cfg)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err = 0;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags)) {
+ if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags)) {
nicif_warn(nic_dev, drv, netdev,
"Cos_up map setting in inprocess, please try again later\n");
return -EFAULT;
@@ -337,40 +406,44 @@ static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dc
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
- clear_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags);
+ clear_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags);
return err;
}
int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err, rollback_err;
u8 netif_run = 0;
struct hinic3_dcb_config old_dcb_cfg;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- memcpy(&old_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&old_dcb_cfg, &dcb->hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
- if (!memcmp(&nic_dev->wanted_dcb_cfg, &old_dcb_cfg, sizeof(struct hinic3_dcb_config))) {
+ if (!memcmp(&dcb->wanted_dcb_cfg, &old_dcb_cfg,
+ sizeof(struct hinic3_dcb_config))) {
nicif_info(nic_dev, drv, nic_dev->netdev,
"Same valid up bitmap, don't need to change anything\n");
return 0;
}
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = change_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ err = change_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Set cos_up map to hw failed\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Set cos_up map to hw failed\n");
goto change_qos_cfg_fail;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- err = hinic3_setup_cos(nic_dev->netdev, user_cos_num, netif_run);
+ err = hinic3_setup_cos(nic_dev->netdev,
+ user_cos_num, netif_run);
if (err)
goto set_err;
}
@@ -381,13 +454,12 @@ int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
goto vport_up_fail;
}
- rtnl_unlock();
-
return 0;
vport_up_fail:
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_setup_cos(nic_dev->netdev, user_cos_num ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, user_cos_num
+ ? 0 : user_cos_num, netif_run);
set_err:
rollback_err = change_qos_cfg(nic_dev, &old_dcb_cfg);
@@ -399,7 +471,5 @@ change_qos_cfg_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
-
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
index 7987f56..e0b35cb 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
@@ -24,11 +24,6 @@ struct hinic3_tc_cfg {
u16 rsvd;
};
-enum HINIC3_DCB_TRUST {
- DCB_PCP,
- DCB_DSCP,
-};
-
#define PCP_MAX_UP 8
#define DSCP_MAC_UP 64
#define DBG_DFLT_DSCP_VAL 0xFF
@@ -50,6 +45,7 @@ struct hinic3_dcb_config {
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev);
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev);
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev);
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev);
void hinic3_dcb_reset_hw_config(struct hinic3_nic_dev *nic_dev);
int hinic3_configure_dcb(struct net_device *netdev);
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run);
@@ -75,4 +71,5 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos);
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev);
int hinic3_vport_up(struct hinic3_nic_dev *nic_dev);
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
index 5a19959..e5e5578 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
@@ -56,9 +56,8 @@ static void hinic3_get_drvinfo(struct net_device *netdev,
return;
}
- err = snprintf(info->fw_version, sizeof(info->fw_version), "%s", mgmt_ver);
- if (err < 0)
- nicif_err(nic_dev, drv, netdev, "Failed to snprintf fw version\n");
+ snprintf(info->fw_version, sizeof(info->fw_version),
+ "%s", mgmt_ver);
}
static u32 hinic3_get_msglevel(struct net_device *netdev)
@@ -86,7 +85,8 @@ static int hinic3_nway_reset(struct net_device *netdev)
while (test_and_set_bit(HINIC3_AUTONEG_RESET, &nic_dev->flags))
msleep(100); /* sleep 100 ms, waiting for another autoneg restart progress done */
- err = hinic3_get_port_info(nic_dev->hwdev, &port_info, HINIC3_CHANNEL_NIC);
+ err = hinic3_get_port_info(nic_dev->hwdev, &port_info,
+ HINIC3_CHANNEL_NIC);
if (err) {
nicif_err(nic_dev, drv, netdev, "Get port info failed\n");
err = -EFAULT;
@@ -273,7 +273,7 @@ static int get_coalesce(struct net_device *netdev,
static int set_queue_coalesce(struct hinic3_nic_dev *nic_dev, u16 q_id,
struct hinic3_intr_coal_info *coal)
{
- struct hinic3_intr_coal_info *intr_coal;
+ struct hinic3_intr_coal_info *intr_coal = NULL;
struct interrupt_info info = {0};
struct net_device *netdev = nic_dev->netdev;
int err;
@@ -367,24 +367,11 @@ static int is_coalesce_exceed_limit(struct net_device *netdev,
return 0;
}
-static int is_coalesce_legal(struct net_device *netdev,
- const struct ethtool_coalesce *coal)
+static int is_coalesce_allowed_change(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct ethtool_coalesce tmp_coal = {0};
- int err;
-
- if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
- nicif_err(nic_dev, drv, netdev,
- "tx-usecs must be equal to rx-usecs\n");
- return -EINVAL;
- }
-
- if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
- nicif_err(nic_dev, drv, netdev,
- "tx-frames must be equal to rx-frames\n");
- return -EINVAL;
- }
tmp_coal.cmd = coal->cmd;
tmp_coal.rx_coalesce_usecs = coal->rx_coalesce_usecs;
@@ -409,6 +396,31 @@ static int is_coalesce_legal(struct net_device *netdev,
return -EOPNOTSUPP;
}
+ return 0;
+}
+
+static int is_coalesce_legal(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-usecs must be equal to rx-usecs\n");
+ return -EINVAL;
+ }
+
+ if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-frames must be equal to rx-frames\n");
+ return -EINVAL;
+ }
+
+ err = is_coalesce_allowed_change(netdev, coal);
+ if (err)
+ return err;
+
err = is_coalesce_exceed_limit(netdev, coal);
if (err)
return err;
@@ -444,8 +456,9 @@ static int is_coalesce_legal(struct net_device *netdev,
return 0;
}
-static inline void check_coalesce_align(struct hinic3_nic_dev *nic_dev, struct net_device *netdev,
- u32 item, u32 unit, char *str)
+static inline void check_coalesce_aligned(struct hinic3_nic_dev *nic_dev,
+ struct net_device *netdev,
+ u32 item, u32 unit, char *str)
{
if (item % unit)
nicif_warn(nic_dev, drv, netdev, "%s in %d units, change to %u\n",
@@ -453,10 +466,12 @@ static inline void check_coalesce_align(struct hinic3_nic_dev *nic_dev, struct n
}
#define CHECK_COALESCE_ALIGN(member, unit) \
- check_coalesce_align(nic_dev, netdev, member, unit, #member)
+ check_coalesce_aligned(nic_dev, netdev, member, unit, #member)
-static inline void check_coalesce_changed(struct hinic3_nic_dev *nic_dev, struct net_device *netdev,
- u32 item, u32 unit, u32 ori_val, char *obj_str, char *str)
+static inline void check_coalesce_changed(struct hinic3_nic_dev *nic_dev,
+ struct net_device *netdev,
+ u32 item, u32 unit, u32 ori_val,
+ char *obj_str, char *str)
{
if ((item / unit) != ori_val)
nicif_info(nic_dev, drv, netdev, "Change %s from %d to %u %s\n",
@@ -466,8 +481,10 @@ static inline void check_coalesce_changed(struct hinic3_nic_dev *nic_dev, struct
#define CHECK_COALESCE_CHANGED(member, unit, ori_val, obj_str) \
check_coalesce_changed(nic_dev, netdev, member, unit, ori_val, obj_str, #member)
-static inline void check_pkt_rate_changed(struct hinic3_nic_dev *nic_dev, struct net_device *netdev,
- u32 item, u32 ori_val, char *obj_str, char *str)
+static inline void check_pkt_rate_changed(struct hinic3_nic_dev *nic_dev,
+ struct net_device *netdev,
+ u32 item, u32 ori_val, char *obj_str,
+ char *str)
{
if (item != ori_val)
nicif_info(nic_dev, drv, netdev, "Change %s from %d to %u %s\n",
@@ -497,19 +514,10 @@ static int set_hw_coal_param(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static int set_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *coal, u16 queue)
+static void check_coalesce_align(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
- struct hinic3_intr_coal_info intr_coal = {0};
- struct hinic3_intr_coal_info *ori_intr_coal = NULL;
- u32 last_adaptive_rx;
- char obj_str[32] = {0};
- int err = 0;
-
- err = is_coalesce_legal(netdev, coal);
- if (err)
- return err;
CHECK_COALESCE_ALIGN(coal->rx_coalesce_usecs, COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal->rx_max_coalesced_frames,
@@ -522,6 +530,14 @@ static int set_coalesce(struct net_device *netdev,
COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal->rx_max_coalesced_frames_low,
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int check_coalesce_change(struct net_device *netdev,
+ u16 queue, struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info *ori_intr_coal = NULL;
+ char obj_str[32] = {0};
if (queue == COALESCE_ALL_QUEUE) {
ori_intr_coal = &nic_dev->intr_coalesce[0];
@@ -552,27 +568,54 @@ static int set_coalesce(struct net_device *netdev,
COALESCE_PENDING_LIMIT_UNIT,
ori_intr_coal->rx_pending_limt_low, obj_str);
- intr_coal.coalesce_timer_cfg =
+ return 0;
+}
+
+static void init_intr_coal_params(struct hinic3_intr_coal_info *intr_coal,
+ struct ethtool_coalesce *coal)
+{
+ intr_coal->coalesce_timer_cfg =
(u8)(coal->rx_coalesce_usecs / COALESCE_TIMER_CFG_UNIT);
- intr_coal.pending_limt = (u8)(coal->rx_max_coalesced_frames /
+ intr_coal->pending_limt = (u8)(coal->rx_max_coalesced_frames /
COALESCE_PENDING_LIMIT_UNIT);
- last_adaptive_rx = nic_dev->adaptive_rx_coal;
- nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
-
- intr_coal.pkt_rate_high = coal->pkt_rate_high;
- intr_coal.rx_usecs_high =
+ intr_coal->pkt_rate_high = coal->pkt_rate_high;
+ intr_coal->rx_usecs_high =
(u8)(coal->rx_coalesce_usecs_high / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_high =
+ intr_coal->rx_pending_limt_high =
(u8)(coal->rx_max_coalesced_frames_high /
COALESCE_PENDING_LIMIT_UNIT);
- intr_coal.pkt_rate_low = coal->pkt_rate_low;
- intr_coal.rx_usecs_low =
+ intr_coal->pkt_rate_low = coal->pkt_rate_low;
+ intr_coal->rx_usecs_low =
(u8)(coal->rx_coalesce_usecs_low / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_low =
+ intr_coal->rx_pending_limt_low =
(u8)(coal->rx_max_coalesced_frames_low /
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal, u16 queue)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info intr_coal = {0};
+ u32 last_adaptive_rx;
+ int err = 0;
+
+ err = is_coalesce_legal(netdev, coal);
+ if (err)
+ return err;
+
+ check_coalesce_align(netdev, coal);
+
+ err = check_coalesce_change(netdev, queue, coal);
+ if (err)
+ return err;
+
+ init_intr_coal_params(&intr_coal, coal);
+
+ last_adaptive_rx = nic_dev->adaptive_rx_coal;
+ nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
/* coalesce timer or pending set to zero will disable coalesce */
if (!nic_dev->adaptive_rx_coal &&
@@ -709,14 +752,16 @@ static int hinic3_set_pauseparam(struct net_device *netdev,
return -EFAULT;
}
- auto_neg = port_info.autoneg_state == PORT_CFG_AN_ON ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+ auto_neg = port_info.autoneg_state == PORT_CFG_AN_ON ?
+ AUTONEG_ENABLE : AUTONEG_DISABLE;
if (pause->autoneg != auto_neg) {
nicif_err(nic_dev, drv, netdev,
"To change autoneg please use: ethtool -s <dev> autoneg <on|off>\n");
return -EOPNOTSUPP;
}
- nic_pause.auto_neg = pause->autoneg == AUTONEG_ENABLE ? PORT_CFG_AN_ON : PORT_CFG_AN_OFF;
+ nic_pause.auto_neg = pause->autoneg == AUTONEG_ENABLE ?
+ PORT_CFG_AN_ON : PORT_CFG_AN_OFF;
nic_pause.rx_pause = (u8)pause->rx_pause;
nic_pause.tx_pause = (u8)pause->tx_pause;
@@ -768,6 +813,14 @@ static int hinic3_get_module_info(struct net_device *netdev,
modinfo->type = ETH_MODULE_SFF_8636;
modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
break;
+ case MODULE_TYPE_DSFP:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
+ case MODULE_TYPE_QSFP_CMIS:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
default:
nicif_warn(nic_dev, drv, netdev,
"Optical module unknown: 0x%x\n", sfp_type);
@@ -790,6 +843,11 @@ static int hinic3_get_module_eeprom(struct net_device *netdev,
memset(data, 0, ee->len);
err = hinic3_get_sfp_eeprom(nic_dev->hwdev, (u8 *)sfp_data, ee->len);
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(nic_dev->hwdev,
+ (u8 *)sfp_data,
+ sizeof(sfp_data));
+
if (err)
return err;
@@ -832,7 +890,8 @@ int hinic3_set_rxq_recovery_flag(struct net_device *netdev, u32 priv_flags)
if (test_and_set_bit(HINIC3_RXQ_RECOVERY, &nic_dev->flags))
return 0;
- queue_delayed_work(nic_dev->workq, &nic_dev->rxq_check_work, HZ);
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->rxq_check_work, HZ);
nicif_info(nic_dev, drv, netdev, "open rxq recovery\n");
} else {
if (!test_and_clear_bit(HINIC3_RXQ_RECOVERY, &nic_dev->flags))
@@ -888,7 +947,8 @@ static int hinic3_set_force_link_flag(struct net_device *netdev, u32 priv_flags)
nicif_info(nic_dev, link, netdev, "Set link up\n");
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, nic_dev->link_status);
+ hinic3_notify_all_vfs_link_changed(nic_dev->hwdev,
+ nic_dev->link_status);
} else {
if (!test_and_clear_bit(HINIC3_FORCE_LINK_UP, &nic_dev->flags))
return 0;
@@ -919,7 +979,8 @@ static int hinic3_set_force_link_flag(struct net_device *netdev, u32 priv_flags)
}
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, nic_dev->link_status);
+ hinic3_notify_all_vfs_link_changed(nic_dev->hwdev,
+ nic_dev->link_status);
}
return 0;
@@ -942,7 +1003,6 @@ static int hinic3_set_priv_flags(struct net_device *netdev, u32 priv_flags)
#define PORT_DOWN_ERR_IDX 0
#define LP_DEFAULT_TIME 5 /* seconds */
-#define LP_PKT_LEN 60
#define TEST_TIME_MULTIPLE 5
static int hinic3_run_lp_test(struct hinic3_nic_dev *nic_dev, u32 test_time)
@@ -1086,7 +1146,8 @@ static int do_lp_test(struct hinic3_nic_dev *nic_dev, u32 *flags, u32 test_time,
return err;
}
-static void hinic3_lp_test(struct net_device *netdev, struct ethtool_test *eth_test,
+static void hinic3_lp_test(struct net_device *netdev,
+ struct ethtool_test *eth_test,
u64 *data, u32 test_time)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
@@ -1109,7 +1170,8 @@ static void hinic3_lp_test(struct net_device *netdev, struct ethtool_test *eth_t
netif_carrier_off(netdev);
netif_tx_disable(netdev);
- err = do_lp_test(nic_dev, ð_test->flags, test_time_real, &test_index);
+ err = do_lp_test(nic_dev, ð_test->flags,
+ test_time_real, &test_index);
if (err) {
eth_test->flags |= ETH_TEST_FL_FAILED;
data[test_index] = 1;
@@ -1130,10 +1192,65 @@ static void hinic3_diag_test(struct net_device *netdev,
hinic3_lp_test(netdev, eth_test, data, 0);
}
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+static int hinic3_get_fecparam(struct net_device *netdev,
+ struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u8 advertised_fec = 0;
+ u8 supported_fec = 0;
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_GFECPARAM) {
+ nicif_err(nic_dev, drv, netdev,
+ "get fecparam cmd err.exp:0x%x,real:0x%x\n",
+ ETHTOOL_GFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = get_fecparam(nic_dev->hwdev, &advertised_fec, &supported_fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Get fec param failed\n");
+ return err;
+ }
+ fecparam->active_fec = (u32)advertised_fec;
+ fecparam->fec = (u32)supported_fec;
+
+ nicif_info(nic_dev, drv, netdev, "Get fec param success\n");
+ return 0;
+}
+
+static int hinic3_set_fecparam(struct net_device *netdev,
+ struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_SFECPARAM) {
+ nicif_err(nic_dev, drv, netdev,
+ "Set fecparam cmd err.exp:0x%x,real:0x%x\n",
+ ETHTOOL_SFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = set_fecparam(nic_dev->hwdev, (u8)fecparam->fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Set fec param failed\n");
+ return err;
+ }
+
+ nicif_info(nic_dev, drv, netdev, "Set fec param success\n");
+ return 0;
+}
+#endif
+
static const struct ethtool_ops hinic3_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1180,6 +1297,10 @@ static const struct ethtool_ops hinic3_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
@@ -1240,7 +1361,10 @@ static const struct ethtool_ops_ext hinic3_ethtool_ops_ext = {
static const struct ethtool_ops hinic3vf_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1267,6 +1391,11 @@ static const struct ethtool_ops hinic3vf_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
+
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
index b0e6aad..7f2537a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
@@ -24,11 +24,29 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
-#define FPGA_PORT_COUNTER 0
-#define EVB_PORT_COUNTER 1
-u16 mag_support_mode = EVB_PORT_COUNTER;
-module_param(mag_support_mode, ushort, 0444);
-MODULE_PARM_DESC(mag_support_mode, "Set mag port counter support mode, 0:FPGA 1:EVB, default is 1");
+#define HINIC_SET_LINK_STR_LEN 128
+#define HINIC_ETHTOOL_FEC_INFO_LEN 6
+#define HINIC_SUPPORTED_FEC_CMD 0
+#define HINIC_ADVERTISED_FEC_CMD 1
+
+struct hinic3_ethtool_fec {
+ u8 hinic_fec_offset;
+ u8 ethtool_bit_offset;
+};
+
+static struct hinic3_ethtool_fec
+ hinic3_ethtool_fec_info[HINIC_ETHTOOL_FEC_INFO_LEN] = {
+ /* The ethtool does not have the corresponding enumeration variable */
+ {PORT_FEC_NOT_SET, 0xFF},
+ {PORT_FEC_RSFEC, 0x32}, /* ETHTOOL_LINK_MODE_FEC_RS_BIT */
+ /* ETHTOOL_LINK_MODE_FEC_BASER_BIT */
+ {PORT_FEC_BASEFEC, 0x33},
+ {PORT_FEC_NOFEC, 0x31}, /* ETHTOOL_LINK_MODE_FEC_NONE_BIT */
+ /* ETHTOOL_LINK_MODE_FEC_LLRS_BIT: Available only in later versions */
+ {PORT_FEC_LLRSFEC, 0x4A},
+ /* The ethtool does not have the corresponding enumeration variable */
+ {PORT_FEC_AUTO, 0XFF}
+};
struct hinic3_stats {
char name[ETH_GSTRING_LEN];
@@ -36,9 +54,23 @@ struct hinic3_stats {
int offset;
};
+struct hinic3_netdev_link_count_str {
+ u64 link_down_events_phy;
+};
+
+#define HINIC3_NETDEV_LINK_COUNT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic3_netdev_link_count_str, _stat_item), \
+ .offset = offsetof(struct hinic3_netdev_link_count_str, _stat_item) \
+}
+
+static struct hinic3_stats hinic3_netdev_link_count[] = {
+ HINIC3_NETDEV_LINK_COUNT(link_down_events_phy),
+};
+
#define HINIC3_NETDEV_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct rtnl_link_stats64, _stat_item), \
+ .size = FIELD_SIZEOF(struct rtnl_link_stats64, _stat_item), \
.offset = offsetof(struct rtnl_link_stats64, _stat_item) \
}
@@ -67,7 +99,7 @@ static struct hinic3_stats hinic3_netdev_stats[] = {
#define HINIC3_NIC_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct hinic3_nic_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_nic_stats, _stat_item), \
.offset = offsetof(struct hinic3_nic_stats, _stat_item) \
}
@@ -84,17 +116,16 @@ static struct hinic3_stats hinic3_nic_dev_stats_extern[] = {
#define HINIC3_RXQ_STAT(_stat_item) { \
.name = "rxq%d_"#_stat_item, \
- .size = sizeof_field(struct hinic3_rxq_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_rxq_stats, _stat_item), \
.offset = offsetof(struct hinic3_rxq_stats, _stat_item) \
}
#define HINIC3_TXQ_STAT(_stat_item) { \
.name = "txq%d_"#_stat_item, \
- .size = sizeof_field(struct hinic3_txq_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_txq_stats, _stat_item), \
.offset = offsetof(struct hinic3_txq_stats, _stat_item) \
}
-/*lint -save -e786*/
static struct hinic3_stats hinic3_rx_queue_stats[] = {
HINIC3_RXQ_STAT(packets),
HINIC3_RXQ_STAT(bytes),
@@ -135,11 +166,9 @@ static struct hinic3_stats hinic3_tx_queue_stats_extern[] = {
HINIC3_TXQ_STAT(rsvd2),
};
-/*lint -restore*/
-
#define HINIC3_FUNC_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct hinic3_vport_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_vport_stats, _stat_item), \
.offset = offsetof(struct hinic3_vport_stats, _stat_item) \
}
@@ -166,7 +195,7 @@ static struct hinic3_stats hinic3_function_stats[] = {
#define HINIC3_PORT_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct mag_cmd_port_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct mag_cmd_port_stats, _stat_item), \
.offset = offsetof(struct mag_cmd_port_stats, _stat_item) \
}
@@ -260,49 +289,22 @@ static struct hinic3_stats hinic3_port_stats[] = {
HINIC3_PORT_STAT(mac_rx_unfilter_pkt_num),
};
-#define HINIC3_FGPA_PORT_STAT(_stat_item) { \
+#define HINIC3_RSFEC_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct hinic3_phy_fpga_port_stats, _stat_item), \
- .offset = offsetof(struct hinic3_phy_fpga_port_stats, _stat_item) \
+ .size = FIELD_SIZEOF(struct mag_cmd_rsfec_stats, _stat_item), \
+ .offset = offsetof(struct mag_cmd_rsfec_stats, _stat_item) \
}
-static struct hinic3_stats g_hinic3_fpga_port_stats[] = {
- HINIC3_FGPA_PORT_STAT(mac_rx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_under_frame_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_frag_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_crc_error_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_length_err_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_pause_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_unknown_mac_frame_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_underrun_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_pause_pkts_port),
+static struct hinic3_stats g_hinic3_rsfec_stats[] = {
+ HINIC3_RSFEC_STAT(rx_err_lane_phy),
};
+#define HINIC3_FGPA_PORT_STAT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic3_phy_fpga_port_stats, _stat_item), \
+ .offset = offsetof(struct hinic3_phy_fpga_port_stats, _stat_item) \
+}
+
static char g_hinic_priv_flags_strings[][ETH_GSTRING_LEN] = {
"Symmetric-RSS",
"Force-Link-up",
@@ -318,8 +320,7 @@ u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev)
(ARRAY_LEN(hinic3_tx_queue_stats) +
ARRAY_LEN(hinic3_tx_queue_stats_extern) +
ARRAY_LEN(hinic3_rx_queue_stats) +
- ARRAY_LEN(hinic3_rx_queue_stats_extern)) *
- nic_dev->max_qps;
+ ARRAY_LEN(hinic3_rx_queue_stats_extern)) * nic_dev->max_qps;
return count;
}
@@ -343,72 +344,89 @@ static int dev_stats_pack(struct hinic3_show_item *items, int len,
memcpy(items[item_idx].name, array[j].name,
HINIC3_SHOW_ITEM_LEN);
items[item_idx].hexadecimal = 0;
- items[item_idx].value = get_value_of_ptr(array[j].size,
- stats_ptr + array[j].offset);
+ items[item_idx].value =
+ get_value_of_ptr(array[j].size,
+ stats_ptr + array[j].offset);
item_idx++;
}
return item_idx;
}
-static int queue_stats_pack(struct hinic3_show_item *items, int len,
- struct hinic3_stats *array, void *stats_ptr,
- u16 qid)
+int hinic3_rx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat,
+ struct hinic3_rxq_stats *rxq_stats, u16 qid)
{
- int j;
- int item_idx = 0;
+ snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
- for (j = 0; j < len; j++) {
- memcpy(items[item_idx].name, array[j].name,
- HINIC3_SHOW_ITEM_LEN);
- snprintf(items[item_idx].name, HINIC3_SHOW_ITEM_LEN,
- array[j].name, qid);
- items[item_idx].hexadecimal = 0;
- items[item_idx].value = get_value_of_ptr(array[j].size,
- stats_ptr + array[j].offset);
- item_idx++;
- }
+ item->hexadecimal = 0;
+ item->value = get_value_of_ptr(stat->size, (char *)(rxq_stats) +
+ stat->offset);
- return item_idx;
+ return 0;
}
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
+int hinic3_tx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat,
+ struct hinic3_txq_stats *txq_stats, u16 qid)
+{
+ snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
+
+ item->hexadecimal = 0;
+ item->value = get_value_of_ptr(stat->size, (char *)(txq_stats) +
+ stat->offset);
+
+ return 0;
+}
+
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
{
struct hinic3_show_item *items = stats;
int item_idx = 0;
u16 qid;
+ int idx;
+ int ret;
- item_idx += dev_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_nic_dev_stats),
- hinic3_nic_dev_stats, &nic_dev->stats);
- item_idx += dev_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_nic_dev_stats_extern),
- hinic3_nic_dev_stats_extern,
- &nic_dev->stats);
+ dev_stats_pack(items, item_idx, hinic3_nic_dev_stats, &nic_dev->stats);
+ dev_stats_pack(items, item_idx, hinic3_nic_dev_stats_extern, &nic_dev->stats);
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_tx_queue_stats),
- hinic3_tx_queue_stats,
- &nic_dev->txqs[qid].txq_stats,
- qid);
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_tx_queue_stats_extern),
- hinic3_tx_queue_stats_extern,
- &nic_dev->txqs[qid].txq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++],
+ &hinic3_tx_queue_stats[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats_extern); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++],
+ &hinic3_tx_queue_stats_extern[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
}
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_rx_queue_stats),
- hinic3_rx_queue_stats,
- &nic_dev->rxqs[qid].rxq_stats,
- qid);
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_rx_queue_stats_extern),
- hinic3_rx_queue_stats_extern,
- &nic_dev->rxqs[qid].rxq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++],
+ &hinic3_rx_queue_stats[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats_extern); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++],
+ &hinic3_rx_queue_stats_extern[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
}
+
+ return 0;
}
static char g_hinic3_test_strings[][ETH_GSTRING_LEN] = {
@@ -428,16 +446,14 @@ int hinic3_get_sset_count(struct net_device *netdev, int sset)
q_num = nic_dev->q_params.num_qps;
count = ARRAY_LEN(hinic3_netdev_stats) +
ARRAY_LEN(hinic3_nic_dev_stats) +
+ ARRAY_LEN(hinic3_netdev_link_count) +
ARRAY_LEN(hinic3_function_stats) +
(ARRAY_LEN(hinic3_tx_queue_stats) +
- ARRAY_LEN(hinic3_rx_queue_stats)) *
- q_num;
+ ARRAY_LEN(hinic3_rx_queue_stats)) * q_num;
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER)
- count += ARRAY_LEN(g_hinic3_fpga_port_stats);
- else
- count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(g_hinic3_rsfec_stats);
}
return count;
@@ -486,9 +502,9 @@ static void get_drv_queue_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
}
}
-static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct hinic3_phy_fpga_port_stats *port_stats = NULL;
+ struct mag_cmd_port_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
@@ -496,19 +512,19 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
if (!port_stats) {
memset(&data[i], 0,
- ARRAY_LEN(g_hinic3_fpga_port_stats) * sizeof(*data));
- i += ARRAY_LEN(g_hinic3_fpga_port_stats);
+ ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
+ i += ARRAY_LEN(hinic3_port_stats);
return i;
}
- err = hinic3_get_fpga_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to get port stats from fw\n");
- for (j = 0; j < ARRAY_LEN(g_hinic3_fpga_port_stats); j++, i++) {
- p = (char *)(port_stats) + g_hinic3_fpga_port_stats[j].offset;
- data[i] = (g_hinic3_fpga_port_stats[j].size == sizeof(u64)) ?
+ for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
+ p = (char *)(port_stats) + hinic3_port_stats[j].offset;
+ data[i] = (hinic3_port_stats[j].size == sizeof(u64)) ?
*(u64 *)p :
*(u32 *)p;
}
@@ -518,34 +534,32 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
return i;
}
-static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_rsfec_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct mag_cmd_port_stats *port_stats = NULL;
+ struct mag_cmd_rsfec_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
- if (mag_support_mode == FPGA_PORT_COUNTER)
- return get_fpga_port_stats(nic_dev, data);
-
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
if (!port_stats) {
- memset(&data[i], 0,
- ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
- i += ARRAY_LEN(hinic3_port_stats);
- return i;
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to malloc port stats\n");
+ memset(&data[i], 0,
+ ARRAY_LEN(g_hinic3_rsfec_stats) * sizeof(*data));
+ i += ARRAY_LEN(g_hinic3_rsfec_stats);
+ return i;
}
- err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_rsfec_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to get port stats from fw\n");
+ "Failed to get rsfec stats from fw\n");
- for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
- p = (char *)(port_stats) + hinic3_port_stats[j].offset;
- data[i] = (hinic3_port_stats[j].size == sizeof(u64)) ?
- *(u64 *)p :
- *(u32 *)p;
+ for (j = 0; j < ARRAY_LEN(g_hinic3_rsfec_stats); j++, i++) {
+ p = (char *)(port_stats) + g_hinic3_rsfec_stats[j].offset;
+ data[i] = (g_hinic3_rsfec_stats[j].size ==
+ sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
kfree(port_stats);
@@ -569,6 +583,8 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
u16 i = 0, j = 0;
char *p = NULL;
int err;
+ int link_down_events_phy_tmp = 0;
+ struct hinic3_netdev_link_count_str link_count = {0};
#ifdef HAVE_NDO_GET_STATS64
net_stats = dev_get_stats(netdev, &temp);
@@ -586,6 +602,15 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = get_value_of_ptr(hinic3_nic_dev_stats[j].size, p);
}
+ err = hinic3_get_link_event_stats(nic_dev->hwdev,
+ &link_down_events_phy_tmp);
+
+ link_count.link_down_events_phy = (u64)link_down_events_phy_tmp;
+ for (j = 0; j < ARRAY_LEN(hinic3_netdev_link_count); j++, i++) {
+ p = (char *)(&link_count) + hinic3_netdev_link_count[j].offset;
+ data[i] = get_value_of_ptr(hinic3_netdev_link_count[j].size, p);
+ }
+
err = hinic3_get_vport_stats(nic_dev->hwdev,
hinic3_global_func_id(nic_dev->hwdev),
&vport_stats);
@@ -598,8 +623,10 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = get_value_of_ptr(hinic3_function_stats[j].size, p);
}
- if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
i += get_ethtool_port_stats(nic_dev, data + i);
+ i += get_ethtool_rsfec_stats(nic_dev, data + i);
+ }
get_drv_queue_stats(nic_dev, data + i);
}
@@ -620,6 +647,12 @@ static u16 get_drv_dev_strings(struct hinic3_nic_dev *nic_dev, char *p)
cnt++;
}
+ for (i = 0; i < ARRAY_LEN(hinic3_netdev_link_count); i++) {
+ memcpy(p, hinic3_netdev_link_count[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+
return cnt;
}
@@ -634,21 +667,16 @@ static u16 get_hw_stats_strings(struct hinic3_nic_dev *nic_dev, char *p)
}
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER) {
- for (i = 0; i < ARRAY_LEN(g_hinic3_fpga_port_stats);
- i++) {
- memcpy(p, g_hinic3_fpga_port_stats[i].name,
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
- } else {
- for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
- memcpy(p, hinic3_port_stats[i].name,
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
+ for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
+ memcpy(p, hinic3_port_stats[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+ for (i = 0; i < ARRAY_LEN(g_hinic3_rsfec_stats); i++) {
+ memcpy(p, g_hinic3_rsfec_stats[i].name,
+ ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
}
}
@@ -664,7 +692,8 @@ static u16 get_qp_stats_strings(const struct hinic3_nic_dev *nic_dev, char *p)
for (j = 0; j < ARRAY_LEN(hinic3_tx_queue_stats); j++) {
err = sprintf(p, hinic3_tx_queue_stats[j].name, i);
if (err < 0)
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to sprintf tx queue stats name, idx_qps: %u, idx_stats: %u\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to sprintf tx queue stats name, idx_qps: %u, idx_stats: %u\n",
i, j);
p += ETH_GSTRING_LEN;
cnt++;
@@ -675,7 +704,8 @@ static u16 get_qp_stats_strings(const struct hinic3_nic_dev *nic_dev, char *p)
for (j = 0; j < ARRAY_LEN(hinic3_rx_queue_stats); j++) {
err = sprintf(p, hinic3_rx_queue_stats[j].name, i);
if (err < 0)
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to sprintf rx queue stats name, idx_qps: %u, idx_stats: %u\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to sprintf rx queue stats name, idx_qps: %u, idx_stats: %u\n",
i, j);
p += ETH_GSTRING_LEN;
cnt++;
@@ -791,7 +821,6 @@ struct hw2ethtool_link_mode {
u32 speed;
};
-/*lint -save -e26 */
static const struct hw2ethtool_link_mode
hw2ethtool_link_mode_table[LINK_MODE_MAX_NUMBERS] = {
[LINK_MODE_GE] = {
@@ -851,8 +880,6 @@ static const struct hw2ethtool_link_mode
},
};
-/*lint -restore */
-
#define GET_SUPPORTED_MODE 0
#define GET_ADVERTISED_MODE 1
@@ -867,21 +894,35 @@ struct cmd_link_settings {
};
#define ETHTOOL_ADD_SUPPORTED_LINK_MODE(ecmd, mode) \
- set_bit(ETHTOOL_LINK_##mode##_BIT, (ecmd)->supported)
+ set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->supported)
#define ETHTOOL_ADD_ADVERTISED_LINK_MODE(ecmd, mode) \
- set_bit(ETHTOOL_LINK_##mode##_BIT, (ecmd)->advertising)
+ set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->advertising)
-static void ethtool_add_speed_link_mode(__ETHTOOL_DECLARE_LINK_MODE_MASK(bitmap), u32 mode)
+static void ethtool_add_supported_speed_link_mode(struct cmd_link_settings *link_settings,
+ u32 mode)
{
u32 i;
for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
- __ETHTOOL_LINK_MODE_MASK_NBITS)
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
continue;
+ set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
+ link_settings->supported);
+ }
+}
+static void ethtool_add_advertised_speed_link_mode(struct cmd_link_settings *link_settings,
+ u32 mode)
+{
+ u32 i;
+
+ for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
+ if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
+ continue;
set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
- bitmap);
+ link_settings->advertising);
}
}
@@ -912,9 +953,11 @@ hinic3_add_ethtool_link_mode(struct cmd_link_settings *link_settings,
for (link_mode = 0; link_mode < LINK_MODE_MAX_NUMBERS; link_mode++) {
if (hw_link_mode & BIT(link_mode)) {
if (name == GET_SUPPORTED_MODE)
- ethtool_add_speed_link_mode(link_settings->supported, link_mode);
+ ethtool_add_supported_speed_link_mode(link_settings,
+ link_mode);
else
- ethtool_add_speed_link_mode(link_settings->advertising, link_mode);
+ ethtool_add_advertised_speed_link_mode(
+ link_settings, link_mode);
}
}
}
@@ -937,10 +980,15 @@ static int hinic3_link_speed_set(struct hinic3_nic_dev *nic_dev,
err = hinic3_get_link_state(nic_dev->hwdev, &link_state);
if (!err && link_state) {
- link_settings->speed =
- port_info->speed < ARRAY_LEN(hw_to_ethtool_speed) ?
+ if (hinic3_get_bond_create_mode(nic_dev->hwdev)) {
+ link_settings->speed = port_info->bond_speed;
+ } else {
+ link_settings->speed =
+ port_info->speed <
+ ARRAY_LEN(hw_to_ethtool_speed) ?
hw_to_ethtool_speed[port_info->speed] :
(u32)SPEED_UNKNOWN;
+ }
link_settings->duplex = port_info->duplex;
} else {
@@ -956,28 +1004,28 @@ static void hinic3_link_port_type(struct cmd_link_settings *link_settings,
{
switch (port_type) {
case MAG_CMD_WIRE_TYPE_ELECTRIC:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_TP);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_TP);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, TP);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, TP);
link_settings->port = PORT_TP;
break;
case MAG_CMD_WIRE_TYPE_AOC:
case MAG_CMD_WIRE_TYPE_MM:
case MAG_CMD_WIRE_TYPE_SM:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_FIBRE);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_FIBRE);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, FIBRE);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, FIBRE);
link_settings->port = PORT_FIBRE;
break;
case MAG_CMD_WIRE_TYPE_COPPER:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_FIBRE);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_FIBRE);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, FIBRE);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, FIBRE);
link_settings->port = PORT_DA;
break;
case MAG_CMD_WIRE_TYPE_BACKPLANE:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_Backplane);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Backplane);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Backplane);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Backplane);
link_settings->port = PORT_NONE;
break;
@@ -1000,19 +1048,56 @@ static int get_link_pause_settings(struct hinic3_nic_dev *nic_dev,
return err;
}
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_Pause);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Pause);
if (nic_pause.rx_pause && nic_pause.tx_pause) {
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Pause);
} else if (nic_pause.tx_pause) {
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Asym_Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Asym_Pause);
} else if (nic_pause.rx_pause) {
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Pause);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Asym_Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Asym_Pause);
}
return 0;
}
+static bool is_bit_offset_defined(u8 bit_offset)
+{
+ if (bit_offset < __ETHTOOL_LINK_MODE_MASK_NBITS)
+ return true;
+ return false;
+}
+
+static void ethtool_add_supported_advertised_fec(struct cmd_link_settings *link_settings,
+ u32 fec, u8 cmd)
+{
+ u8 i;
+
+ for (i = 0; i < HINIC_ETHTOOL_FEC_INFO_LEN; i++) {
+ if ((fec & BIT(hinic3_ethtool_fec_info[i].hinic_fec_offset)) == 0)
+ continue;
+ if (is_bit_offset_defined(hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true &&
+ cmd == HINIC_ADVERTISED_FEC_CMD) {
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset,
+ link_settings->advertising);
+ return; /* There can be only one advertised fec mode. */
+ }
+ if (is_bit_offset_defined(hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true &&
+ cmd == HINIC_SUPPORTED_FEC_CMD)
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset,
+ link_settings->supported);
+ }
+}
+
+static void hinic3_link_fec_type(struct cmd_link_settings *link_settings,
+ u32 fec, u32 supported_fec)
+{
+ ethtool_add_supported_advertised_fec(link_settings, supported_fec,
+ HINIC_SUPPORTED_FEC_CMD);
+ ethtool_add_supported_advertised_fec(link_settings, fec,
+ HINIC_ADVERTISED_FEC_CMD);
+}
+
static int get_link_settings(struct net_device *netdev,
struct cmd_link_settings *link_settings)
{
@@ -1033,13 +1118,19 @@ static int get_link_settings(struct net_device *netdev,
hinic3_link_port_type(link_settings, port_info.port_type);
+ /* port_info.fec is bit offset, value is BIT(port_info.fec);
+ * but port_info.supported_fec_mode is bit value
+ */
+ hinic3_link_fec_type(link_settings, BIT(port_info.fec),
+ port_info.supported_fec_mode);
+
link_settings->autoneg = port_info.autoneg_state == PORT_CFG_AN_ON ?
AUTONEG_ENABLE :
AUTONEG_DISABLE;
if (port_info.autoneg_cap)
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_Autoneg);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Autoneg);
if (port_info.autoneg_state == PORT_CFG_AN_ON)
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Autoneg);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Autoneg);
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
err = get_link_pause_settings(nic_dev, link_settings);
@@ -1163,23 +1254,18 @@ static int hinic3_set_settings_to_hw(struct hinic3_nic_dev *nic_dev,
struct net_device *netdev = nic_dev->netdev;
struct hinic3_link_ksettings settings = { 0 };
int speed_level = 0;
- char set_link_str[128] = { 0 };
+ char set_link_str[HINIC_SET_LINK_STR_LEN] = {0};
+ char link_info[HINIC_SET_LINK_STR_LEN] = {0};
int err = 0;
- err = snprintf(set_link_str, sizeof(set_link_str) - 1, "%s",
- (bool)(set_settings & HILINK_LINK_SET_AUTONEG) ?
- ((bool)autoneg ? "autong enable " :
- "autong disable ") :
- "");
- if (err < 0)
- return -EINVAL;
+ snprintf(link_info, sizeof(link_info), "%s",
+ (bool)(set_settings & HILINK_LINK_SET_AUTONEG) ?
+ ((bool)autoneg ? "autong enable " : "autong disable ") : "");
if (set_settings & HILINK_LINK_SET_SPEED) {
speed_level = hinic3_ethtool_to_hw_speed_level(speed);
- err = snprintf(set_link_str, sizeof(set_link_str) - 1,
- "%sspeed %u ", set_link_str, speed);
- if (err < 0)
- return -EINVAL;
+ snprintf(set_link_str, sizeof(set_link_str),
+ "%sspeed %u ", link_info, speed);
}
settings.valid_bitmap = set_settings;
@@ -1218,7 +1304,8 @@ static int set_link_settings(struct net_device *netdev, u8 autoneg, u32 speed)
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
int hinic3_set_link_ksettings(struct net_device *netdev,
- const struct ethtool_link_ksettings *link_settings)
+ const
+ struct ethtool_link_ksettings *link_settings)
{
/* Only support to set autoneg and speed */
return set_link_settings(netdev, link_settings->base.autoneg,
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
index 70346d6..2daa7f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
@@ -82,7 +82,7 @@ static struct hinic3_mac_filter *hinic3_add_filter(struct hinic3_nic_dev *nic_de
struct list_head *mac_filter_list,
u8 *addr)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
@@ -117,7 +117,7 @@ static void hinic3_del_filter(struct hinic3_nic_dev *nic_dev,
static struct hinic3_mac_filter *hinic3_mac_filter_entry_clone(const struct hinic3_mac_filter *src)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
index ef8c62b..a3136ce 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
@@ -40,6 +40,7 @@ enum hinic3_channel_id {
HINIC3_CHANNEL_DSW,
HINIC3_CHANNEL_MIG,
HINIC3_CHANNEL_CRYPT,
+ HINIC3_CHANNEL_VROCE,
HINIC3_CHANNEL_MAX = 32,
};
@@ -397,6 +398,16 @@ void hinic3_free_cmd_buf(void *hwdev, struct hinic3_cmd_buf *cmd_buf);
**/
int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read clear
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+
/**
* @brief hinic3_sm_ctr_rd32 - small single 32 counter read
* @param hwdev: device pointer to hwdev
@@ -810,6 +821,13 @@ int hinic3_dbg_lt_wr_16byte_mask(void *hwdev, u8 dest, u8 instance,
*/
void hinic3_link_event_stats(void *dev, u8 link);
+/**
+ * @brief hinic3_get_link_event_stats - link event stats
+ * @param hwdev: device pointer to hwdev
+ * @param link: link status
+ */
+int hinic3_get_link_event_stats(void *dev, int *link_state);
+
/**
* @brief hinic3_get_hw_pf_infos - get pf infos
* @param hwdev: device pointer to hwdev
@@ -856,4 +874,5 @@ void hinic3_set_api_stop(void *hwdev);
int hinic3_activate_firmware(void *hwdev, u8 cfg_index);
int hinic3_switch_config(void *hwdev, u8 cfg_index);
+bool hinic3_is_optical_module_mode(void *hwdev);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
index 7e59c81..6525b76 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
@@ -47,12 +47,16 @@ static void qp_add_napi(struct hinic3_irq *irq_cfg)
netif_napi_add_weight(nic_dev->netdev, &irq_cfg->napi,
hinic3_poll, nic_dev->poll_weight);
napi_enable(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_IS_REGIN;
}
-static void qp_del_napi(struct hinic3_irq *irq_cfg)
+void qp_del_napi(struct hinic3_irq *irq_cfg)
{
- napi_disable(&irq_cfg->napi);
- netif_napi_del(&irq_cfg->napi);
+ if (irq_cfg->napi_reign == NAPI_IS_REGIN) {
+ napi_disable(&irq_cfg->napi);
+ netif_napi_del(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_NOT_REGIN;
+ }
}
static irqreturn_t qp_irq(int irq, void *data)
@@ -60,7 +64,8 @@ static irqreturn_t qp_irq(int irq, void *data)
struct hinic3_irq *irq_cfg = (struct hinic3_irq *)data;
struct hinic3_nic_dev *nic_dev = netdev_priv(irq_cfg->netdev);
- hinic3_misx_intr_clear_resend_bit(nic_dev->hwdev, irq_cfg->msix_entry_idx, 1);
+ hinic3_misx_intr_clear_resend_bit(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx, 1);
napi_schedule(&irq_cfg->napi);
@@ -95,7 +100,8 @@ static int hinic3_request_irq(struct hinic3_irq *irq_cfg, u16 q_id)
return err;
}
- err = request_irq(irq_cfg->irq_id, &qp_irq, 0, irq_cfg->irq_name, irq_cfg);
+ err = request_irq(irq_cfg->irq_id, &qp_irq, 0,
+ irq_cfg->irq_name, irq_cfg);
if (err) {
nicif_err(nic_dev, drv, irq_cfg->netdev, "Failed to request Rx irq\n");
qp_del_napi(irq_cfg);
@@ -138,12 +144,8 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev)
local_cpu = cpumask_local_spread(q_id, dev_to_node(&pdev->dev));
cpumask_set_cpu(local_cpu, &irq_cfg->affinity_mask);
- err = snprintf(irq_cfg->irq_name, sizeof(irq_cfg->irq_name),
- "%s_qp%u", nic_dev->netdev->name, q_id);
- if (err < 0) {
- err = -EINVAL;
- goto req_tx_irq_err;
- }
+ snprintf(irq_cfg->irq_name, sizeof(irq_cfg->irq_name),
+ "%s_qp%u", nic_dev->netdev->name, q_id);
err = hinic3_request_irq(irq_cfg, q_id);
if (err) {
@@ -151,20 +153,25 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev)
goto req_tx_irq_err;
}
- hinic3_set_msix_auto_mask_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ hinic3_set_msix_auto_mask_state(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx,
HINIC3_SET_MSIX_AUTO_MASK);
- hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx, HINIC3_MSIX_ENABLE);
+ hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ HINIC3_MSIX_ENABLE);
}
- INIT_DELAYED_WORK(&nic_dev->moderation_task, hinic3_auto_moderation_work);
+ INIT_DELAYED_WORK(&nic_dev->moderation_task,
+ hinic3_auto_moderation_work);
return 0;
req_tx_irq_err:
for (i = 0; i < q_id; i++) {
irq_cfg = &nic_dev->q_params.irq_cfg[i];
- hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx, HINIC3_MSIX_DISABLE);
- hinic3_set_msix_auto_mask_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ HINIC3_MSIX_DISABLE);
+ hinic3_set_msix_auto_mask_state(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx,
HINIC3_CLR_MSIX_AUTO_MASK);
hinic3_release_irq(irq_cfg);
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
deleted file mode 100644
index 2482c5f..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_LLD_H
-#define HINIC3_LLD_H
-
-#include "hinic3_crm.h"
-
-struct hinic3_lld_dev {
- struct pci_dev *pdev;
- void *hwdev;
-};
-
-struct hinic3_uld_info {
- /* When the function does not need to initialize the corresponding uld,
- * @probe needs to return 0 and uld_dev is set to NULL;
- * if uld_dev is NULL, @remove will not be called when uninstalling
- */
- int (*probe)(struct hinic3_lld_dev *lld_dev, void **uld_dev, char *uld_dev_name);
- void (*remove)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- int (*suspend)(struct hinic3_lld_dev *lld_dev, void *uld_dev, pm_message_t state);
- int (*resume)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- void (*event)(struct hinic3_lld_dev *lld_dev, void *uld_dev,
- struct hinic3_event_info *event);
- int (*ioctl)(void *uld_dev, u32 cmd, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size);
-};
-
-/* hinic3_register_uld - register an upper-layer driver
- * @type: uld service type
- * @uld_info: uld callback
- *
- * Registers an upper-layer driver.
- * Traverse existing devices and call @probe to initialize the uld device.
- */
-int hinic3_register_uld(enum hinic3_service_type type, struct hinic3_uld_info *uld_info);
-
-/**
- * hinic3_unregister_uld - unregister an upper-layer driver
- * @type: uld service type
- *
- * Traverse existing devices and call @remove to uninstall the uld device.
- * Unregisters an existing upper-layer driver.
- */
-void hinic3_unregister_uld(enum hinic3_service_type type);
-
-void lld_hold(void);
-void lld_put(void);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_name - get lld device by chip name
- * @param chip_name: chip name
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_name(const char *chip_name);
-
-/**
- * @brief lld_dev_hold - get reference to lld_dev
- * @param dev: lld device
- *
- * Hold reference to device to keep it from being freed
- **/
-void lld_dev_hold(struct hinic3_lld_dev *dev);
-
-/**
- * @brief lld_dev_put - release reference to lld_dev
- * @param dev: lld device
- *
- * Release reference to device to allow it to be freed
- **/
-void lld_dev_put(struct hinic3_lld_dev *dev);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name_unsafe - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * hinic3_get_lld_dev_by_dev_name_unsafe() is completely analogous to
- * hinic3_get_lld_dev_by_dev_name(), The only difference is that the reference
- * of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that lld_dev will not be freed during the remove process
- * when using lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name_unsafe(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_and_port - get lld device by chip name and port id
- * @param chip_name: chip name
- * @param port_id: port id
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name, u8 port_id);
-
-/**
- * @brief hinic3_get_ppf_lld_dev - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief hinic3_get_ppf_lld_dev_unsafe - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * hinic3_get_ppf_lld_dev_unsafe() is completely analogous to hinic3_get_ppf_lld_dev(),
- * The only difference is that the reference of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that ppf's lld_dev will not be freed during the remove process
- * when using ppf lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev_unsafe(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief uld_dev_hold - get reference to uld_dev
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * Hold reference to uld device to keep it from being freed
- **/
-void uld_dev_hold(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief uld_dev_put - release reference to lld_dev
- * @param dev: lld device
- * @param type: uld service type
- *
- * Release reference to uld device to allow it to be freed
- **/
-void uld_dev_put(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * The value of uld_dev reference increases when uld_dev is obtained. The caller needs
- * to release the reference by calling uld_dev_put.
- **/
-void *hinic3_get_uld_dev(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev_unsafe - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * hinic3_get_uld_dev_unsafe() is completely analogous to hinic3_get_uld_dev(),
- * The only difference is that the reference of uld_dev is not increased when uld_dev is obtained.
- *
- * The caller must ensure that uld_dev will not be freed during the remove process
- * when using uld_dev.
- **/
-void *hinic3_get_uld_dev_unsafe(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_chip_name - get chip name by lld device
- * @param lld_dev: lld device
- * @param chip_name: String for storing the chip name
- * @param max_len: Maximum number of characters to be copied for chip_name
- **/
-int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len);
-
-struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev);
-
-struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev);
-
-bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service);
-
-int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
- bool vf_srv_load);
-
-int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id,
- u16 service, bool en);
-
-bool hinic3_get_vf_load_state(struct pci_dev *pdev);
-
-int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state);
-
-int hinic3_attach_nic(struct hinic3_lld_dev *lld_dev);
-
-void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
-
-int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-const char **hinic3_get_uld_names(void);
-int hinic3_lld_init(void);
-void hinic3_lld_exit(void);
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
index 2fe808b..688bb7d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
@@ -17,11 +17,22 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_hw.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_common.h"
+#include "mag_mpu_cmd_defs.h"
+
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
+#define CAP_INFO_MAX_LEN 512
+#define DEVICE_VENDOR_MAX_LEN 17
+#define READ_RSFEC_REGISTER_DELAY_TIME_MS 500
+
+struct parse_tlv_info g_page_info = {0};
+struct drv_tag_mag_cmd_get_xsfp_tlv_rsp g_xsfp_tlv_info = {0};
static int mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
@@ -78,8 +89,10 @@ int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats)
return -ENOMEM;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
memset(&stats_info, 0, sizeof(stats_info));
stats_info.port_id = hinic3_physical_port_id(hwdev);
@@ -104,6 +117,64 @@ out:
}
EXPORT_SYMBOL(hinic3_get_phy_port_stats);
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats)
+{
+ struct mag_cmd_get_mag_cnt *port_stats = NULL;
+ struct mag_cmd_get_mag_cnt stats_info;
+ u16 out_size = sizeof(*port_stats);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !stats)
+ return -EINVAL;
+
+ port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
+ if (!port_stats)
+ return -ENOMEM;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ memset(&stats_info, 0, sizeof(stats_info));
+ stats_info.port_id = hinic3_physical_port_id(hwdev);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT,
+ &stats_info, sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+ /* 读2遍, 清除误码残留 */
+ msleep(READ_RSFEC_REGISTER_DELAY_TIME_MS);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT, &stats_info,
+ sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+
+ memcpy(stats, &port_stats->mag_csr[MAG_RX_RSFEC_ERR_CW_CNT],
+ sizeof(u32));
+
+out:
+ kfree(port_stats);
+
+ return err;
+}
+EXPORT_SYMBOL(hinic3_get_phy_rsfec_stats);
+
int hinic3_set_port_funcs_state(void *hwdev, bool enable)
{
return 0;
@@ -180,6 +251,8 @@ int hinic3_get_loopback_mode(void *hwdev, u8 *mode, u8 *enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_cfg_loopback_mode(nic_io, MGMT_MSG_CMD_OP_GET, mode,
enable);
@@ -195,6 +268,8 @@ int hinic3_set_loopback_mode(void *hwdev, u8 mode, u8 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) {
nic_err(nic_io->dev_hdl, "Invalid loopback mode %u to set\n",
@@ -218,6 +293,9 @@ int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&led_info, 0, sizeof(led_info));
led_info.function_id = hinic3_global_func_id(hwdev);
@@ -249,6 +327,8 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
memset(&port_msg, 0, sizeof(port_msg));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
port_msg.port_id = hinic3_physical_port_id(hwdev);
@@ -268,9 +348,12 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
port_info->port_type = port_msg.wire_type;
port_info->speed = port_msg.speed;
port_info->fec = port_msg.fec;
+ port_info->lanes = port_msg.lanes;
port_info->supported_mode = port_msg.supported_mode;
port_info->advertised_mode = port_msg.advertised_mode;
-
+ port_info->supported_fec_mode = port_msg.supported_fec_mode;
+ /* switch Gbps to Mbps */
+ port_info->bond_speed = (u32)port_msg.bond_speed * RATE_MBPS_TO_GBPS;
return 0;
}
@@ -306,6 +389,8 @@ int hinic3_set_link_settings(void *hwdev,
memset(&info, 0, sizeof(info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
info.port_id = hinic3_physical_port_id(hwdev);
info.config_bitmap = settings->valid_bitmap;
@@ -335,6 +420,8 @@ int hinic3_get_link_state(void *hwdev, u8 *link_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&get_link, 0, sizeof(get_link));
get_link.port_id = hinic3_physical_port_id(hwdev);
@@ -364,10 +451,11 @@ void hinic3_notify_vf_link_status(struct hinic3_nic_io *nic_io,
if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
link.status = link_status;
link.port_id = hinic3_physical_port_id(nic_io->hwdev);
- err = hinic3_mbox_to_vf(nic_io->hwdev, vf_id, HINIC3_MOD_HILINK,
- MAG_CMD_GET_LINK_STATUS, &link,
- sizeof(link), &link, &out_size, 0,
- HINIC3_CHANNEL_NIC);
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
+ MAG_CMD_GET_LINK_STATUS, &link,
+ sizeof(link), &link, &out_size,
+ HINIC3_CHANNEL_NIC);
if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
HW_VF_ID_TO_OS(vf_id));
@@ -387,6 +475,8 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
u16 i;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
nic_io->link_status = link_status;
for (i = 1; i <= nic_io->max_vfs; i++) {
if (!nic_io->vf_infos[HW_VF_ID_TO_OS(i)].link_forced)
@@ -394,6 +484,165 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
}
}
+static char *g_hw_to_char_fec[HILINK_FEC_MAX_TYPE] = {
+ "not set", "rsfec", "basefec",
+ "nofec", "llrsfec"};
+static char *g_hw_to_speed_info[PORT_SPEED_UNKNOWN] = {
+ "not set", "10MB", "100MB", "1GB", "10GB",
+ "25GB", "40GB", "50GB", "100GB", "200GB"};
+static char *g_hw_to_an_state_info[PORT_CFG_AN_OFF + 1] = {
+ "not set", "on", "off"};
+
+struct port_type_table {
+ u32 port_type;
+ char *port_type_name;
+};
+
+static const struct port_type_table port_optical_type_table_s[] = {
+ {LINK_PORT_UNKNOWN, "UNKNOWN"},
+ {LINK_PORT_OPTICAL_MM, "optical_sr"},
+ {LINK_PORT_OPTICAL_SM, "optical_lr"},
+ {LINK_PORT_PAS_COPPER, "copper"},
+ {LINK_PORT_ACC, "ACC"},
+ {LINK_PORT_BASET, "baset"},
+ {LINK_PORT_AOC, "AOC"},
+ {LINK_PORT_ELECTRIC, "electric"},
+ {LINK_PORT_BACKBOARD_INTERFACE, "interface"},
+};
+
+static char *get_port_type_name(u32 type)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(port_optical_type_table_s); i++) {
+ if (type == port_optical_type_table_s[i].port_type)
+ return port_optical_type_table_s[i].port_type_name;
+ }
+ return "UNKNOWN TYPE";
+}
+
+static void get_port_type(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ char **port_type)
+{
+ if (info->port_type <= LINK_PORT_BACKBOARD_INTERFACE)
+ *port_type = get_port_type_name(info->port_type);
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown port type: %u\n", info->port_type);
+}
+
+static int get_port_temperature_power(struct mag_cmd_event_port_info *info,
+ char *str)
+{
+ char cap_info[CAP_INFO_MAX_LEN];
+
+ memset(cap_info, 0, sizeof(cap_info));
+ snprintf(cap_info, CAP_INFO_MAX_LEN, "%s, %s, Temperature: %u", str,
+ info->sfp_type ? "QSFP" : "SFP", info->cable_temp);
+
+ if (info->sfp_type)
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuw %uuW %uuW %uuW",
+ cap_info, info->power[0x0], info->power[0x1],
+ info->power[0x2], info->power[0x3]);
+ else
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuW, tx power: %uuW",
+ cap_info, info->power[0x0], info->power[0x1]);
+
+ return 0;
+}
+
+static void print_cable_info(struct hinic3_nic_io *nic_io, struct mag_cmd_event_port_info *info)
+{
+ char tmp_str[CAP_INFO_MAX_LEN] = {0};
+ char tmp_vendor[DEVICE_VENDOR_MAX_LEN] = {0};
+ char *port_type = "Unknown port type";
+ int i;
+ int err = 0;
+
+ if (info->gpio_insert) {
+ sdk_info(nic_io->dev_hdl, "Cable unpresent\n");
+ return;
+ }
+
+ get_port_type(nic_io, info, &port_type);
+
+ for (i = sizeof(info->vendor_name) - 1; i >= 0; i--) {
+ if (info->vendor_name[i] == ' ')
+ info->vendor_name[i] = '\0';
+ else
+ break;
+ }
+
+ memcpy(tmp_vendor, info->vendor_name, sizeof(info->vendor_name));
+ snprintf(tmp_str, CAP_INFO_MAX_LEN, "Vendor: %s, %s, length: %um, max_speed: %uGbps",
+ tmp_vendor, port_type, info->cable_length, info->max_speed);
+
+ if (info->port_type == LINK_PORT_OPTICAL_MM ||
+ info->port_type == LINK_PORT_AOC) {
+ err = get_port_temperature_power(info, tmp_str);
+ if (err)
+ return;
+ }
+
+ sdk_info(nic_io->dev_hdl, "Cable information: %s\n", tmp_str);
+}
+
+static void print_link_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ enum hinic3_nic_event_type type)
+{
+ char *fec = "None";
+ char *speed = "None";
+ char *an_state = "None";
+
+ if (info->fec < HILINK_FEC_MAX_TYPE)
+ fec = g_hw_to_char_fec[info->fec];
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown fec type: %u\n", info->fec);
+
+ if (info->an_state > PORT_CFG_AN_OFF) {
+ sdk_info(nic_io->dev_hdl, "an_state %d is invalid",
+ info->an_state);
+ return;
+ }
+
+ an_state = g_hw_to_an_state_info[info->an_state];
+
+ if (info->speed >= PORT_SPEED_UNKNOWN) {
+ sdk_info(nic_io->dev_hdl, "speed %u is invalid", info->speed);
+ return;
+ }
+
+ speed = g_hw_to_speed_info[info->speed];
+ sdk_info(nic_io->dev_hdl, "Link information: speed %s, %s, autoneg %s",
+ speed, fec, an_state);
+}
+
+void print_port_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *port_info,
+ enum hinic3_nic_event_type type)
+{
+ print_cable_info(nic_io, port_info);
+
+ print_link_info(nic_io, port_info, type);
+
+ if (type == EVENT_NIC_LINK_UP)
+ return;
+
+ sdk_info(nic_io->dev_hdl, "PMA ctrl: %s, tx %s, rx %s, PMA fifo reg: 0x%x, PMA signal ok reg: 0x%x, RF/LF status reg: 0x%x\n",
+ port_info->pma_ctrl == 1 ? "off" : "on",
+ port_info->tx_enable ? "enable" : "disable",
+ port_info->rx_enable ? "enable" : "disable", port_info->pma_fifo_reg,
+ port_info->pma_signal_ok_reg, port_info->rf_lf);
+ sdk_info(nic_io->dev_hdl, "alos: %u, rx_los: %u, PCS 64 66b reg: 0x%x, PCS link: 0x%x, MAC link: 0x%x PCS_err_cnt: 0x%x\n",
+ port_info->alos, port_info->rx_los, port_info->pcs_64_66b_reg,
+ port_info->pcs_link, port_info->pcs_mac_link,
+ port_info->pcs_err_cnt);
+ sdk_info(nic_io->dev_hdl, "his_link_machine_state = 0x%08x, cur_link_machine_state = 0x%08x\n",
+ port_info->his_link_machine_state,
+ port_info->cur_link_machine_state);
+}
+
static int hinic3_get_vf_link_status_msg_handler(struct hinic3_nic_io *nic_io,
u16 vf_id, void *buf_in,
u16 in_size, void *buf_out,
@@ -433,6 +682,10 @@ static void get_port_info(void *hwdev,
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (hinic3_func_type(hwdev) != TYPE_VF && link_status->status) {
err = hinic3_get_port_info(hwdev, &port_info, HINIC3_CHANNEL_NIC);
if (err) {
@@ -457,8 +710,18 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
struct hinic3_event_info event_info = {0};
struct hinic3_event_link_info *link_info = (void *)event_info.event_data;
struct hinic3_nic_io *nic_io = NULL;
+#ifndef __UEFI__
+ struct pci_dev *pdev = NULL;
+#endif
+ /* Ignore link change event */
+ if (hinic3_is_bm_slave_host(hwdev))
+ return;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
link_status = buf_in;
sdk_info(nic_io->dev_hdl, "Link status report received, func_id: %u, status: %u\n",
@@ -475,6 +738,15 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
hinic3_event_callback(hwdev, &event_info);
+#ifndef __UEFI__
+ if (nic_io->pcidev_hdl) {
+ pdev = nic_io->pcidev_hdl;
+ if (pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID) {
+ return;
+ }
+ }
+#endif
+
if (hinic3_func_type(hwdev) != TYPE_VF) {
hinic3_notify_all_vfs_link_changed(hwdev, link_status->status);
ret_link_status = buf_out;
@@ -483,20 +755,142 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
}
}
+static void port_info_event_printf(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_event_port_info *port_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info;
+ enum hinic3_nic_event_type type;
+
+ if (!hwdev) {
+ pr_err("hwdev is NULL\n");
+ return;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ if (in_size != sizeof(*port_info)) {
+ sdk_info(nic_io->dev_hdl, "Invalid port info message size %d, should be %ld\n",
+ in_size, sizeof(*port_info));
+ return;
+ }
+
+ ((struct mag_cmd_event_port_info *)buf_out)->head.status = 0;
+
+ type = port_info->event_type;
+ if (type < EVENT_NIC_LINK_DOWN || type > EVENT_NIC_LINK_UP) {
+ sdk_info(nic_io->dev_hdl, "Invalid hilink info report, type: %d\n",
+ type);
+ return;
+ }
+
+ print_port_info(nic_io, port_info, type);
+
+ memset(&event_info, 0, sizeof(event_info));
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = type;
+
+ *out_size = sizeof(*port_info);
+
+ hinic3_event_callback(hwdev, &event_info);
+}
+
+void hinic3_notify_vf_bond_status(struct hinic3_nic_io *nic_io,
+ u16 vf_id, u8 bond_status)
+{
+ struct mag_cmd_get_bond_status bond;
+ struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ u16 out_size = sizeof(bond);
+ int err;
+
+ memset(&bond, 0, sizeof(bond));
+ if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
+ bond.status = bond_status;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
+ MAG_CMD_GET_BOND_STATUS, &bond,
+ sizeof(bond), &bond, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF %u not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return;
+ }
+ if (err || !out_size || bond.head.status)
+ nic_err(nic_io->dev_hdl,
+ "Send bond change event to VF %hu failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err, bond.head.status,
+ out_size);
+ }
+}
+
+void hinic3_notify_all_vfs_bond_changed(void *hwdev, u8 bond_status)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 i;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ nic_io->link_status = bond_status;
+ for (i = 1; i <= nic_io->max_vfs; i++)
+ hinic3_notify_vf_bond_status(nic_io, i, bond_status);
+}
+
+static void bond_status_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_get_bond_status *bond_status = NULL;
+ struct hinic3_event_info event_info = {};
+ struct hinic3_nic_io *nic_io = NULL;
+ struct mag_cmd_get_bond_status *ret_bond_status = NULL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+
+ bond_status = (struct mag_cmd_get_bond_status *)buf_in;
+ sdk_info(nic_io->dev_hdl, "bond status report received, func_id: %u, status: %u\n",
+ hinic3_global_func_id(hwdev), bond_status->status);
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = bond_status->status ?
+ EVENT_NIC_BOND_UP : EVENT_NIC_BOND_DOWN;
+
+ hinic3_event_callback(hwdev, &event_info);
+
+ if (hinic3_func_type(hwdev) != TYPE_VF) {
+ hinic3_notify_all_vfs_bond_changed(hwdev, bond_status->status);
+ ret_bond_status = buf_out;
+ ret_bond_status->head.status = 0;
+ *out_size = sizeof(*ret_bond_status);
+ }
+}
+
static void cable_plug_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct mag_cmd_wire_event *plug_event = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_event_info event_info;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
rt_cmd->mpu_send_sfp_abs = false;
rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
memset(&event_info, 0, sizeof(event_info));
@@ -518,9 +912,12 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
{
struct mag_cmd_get_xsfp_info *sfp_info = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_info)) {
sdk_err(nic_io->dev_hdl, "Invalid sfp info cmd, length: %u, should be %ld\n",
in_size, sizeof(*sfp_info));
@@ -528,10 +925,41 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
}
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
memcpy(&rt_cmd->std_sfp_info, sfp_info,
sizeof(struct mag_cmd_get_xsfp_info));
rt_cmd->mpu_send_sfp_info = true;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+}
+
+static void port_xsfp_tlv_info_event(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *xsfp_tlv_info = buf_in;
+ struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
+ size_t cpy_len = in_size - sizeof(struct mgmt_msg_head) -
+ XSFP_TLV_PRE_INFO_LEN;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
+
+ if (cpy_len > XSFP_CMIS_INFO_MAX_SIZE) {
+ sdk_err(nic_io->dev_hdl, "invalid cpy_len(%lu)\n", cpy_len);
+ return;
+ }
+ rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ rt_cmd_ext->std_xsfp_tlv_info.port_id = xsfp_tlv_info->port_id;
+ memcpy(&rt_cmd_ext->std_xsfp_tlv_info.tlv_buf[0],
+ &xsfp_tlv_info->tlv_buf[0], cpy_len);
+ rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = true;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
}
@@ -543,6 +971,8 @@ static void port_sfp_abs_event(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_abs)) {
sdk_err(nic_io->dev_hdl, "Invalid sfp absent cmd, length: %u, should be %ld\n",
in_size, sizeof(*sfp_abs));
@@ -564,9 +994,11 @@ bool hinic3_if_sfp_absent(void *hwdev)
u8 port_id = hinic3_physical_port_id(hwdev);
u16 out_size = sizeof(sfp_abs);
int err;
- bool sfp_abs_status;
+ bool sfp_abs_status = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return true;
memset(&sfp_abs, 0, sizeof(sfp_abs));
rt_cmd = &nic_io->nic_cfg.rt_cmd;
@@ -597,10 +1029,184 @@ bool hinic3_if_sfp_absent(void *hwdev)
return (sfp_abs.abs_status == 0 ? false : true);
}
+int hinic3_get_sfp_tlv_info(void *hwdev, struct drv_tag_mag_cmd_get_xsfp_tlv_rsp
+ *sfp_tlv_info,
+ const struct tag_mag_cmd_get_xsfp_tlv_req
+ *sfp_tlv_info_req)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ u16 out_size = sizeof(*sfp_tlv_info);
+ int err;
+
+ if (!hwdev || !sfp_tlv_info)
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ if (rt_cmd_ext->mpu_send_xsfp_tlv_info) {
+ if (rt_cmd_ext->std_xsfp_tlv_info.head.status != 0) {
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return -EIO;
+ }
+
+ memcpy(sfp_tlv_info, &rt_cmd_ext->std_xsfp_tlv_info,
+ sizeof(*sfp_tlv_info));
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_TLV_INFO,
+ (void *)sfp_tlv_info_req,
+ sizeof(*sfp_tlv_info_req),
+ sfp_tlv_info, &out_size);
+ if (sfp_tlv_info->head.status != 0 || err != 0 || out_size == 0) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get port%u tlv sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
+ hinic3_physical_port_id(hwdev), err,
+ sfp_tlv_info->head.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_get_page_pos(u32 page_id, u32 content_len, u32 *pos)
+{
+ if (page_id <= QSFP_CMIS_PAGE_03H) {
+ *pos = (page_id * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_11H) {
+ *pos = (QSFP_CMIS_PAGE_04H * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_12H) {
+ *pos = (QSFP_CMIS_PAGE_05H * content_len);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int hinic3_get_page_key_info(struct mgmt_tlv_info *tlv_info,
+ struct parse_tlv_info *page_info, u8 idx,
+ u32 *total_len)
+{
+ u8 *src_addr = NULL;
+ u8 *dst_addr = NULL;
+ u8 *tmp_addr = NULL;
+ u32 page_id = 0;
+ u32 content_len = 0;
+ u32 src_pos = 0;
+ int ret;
+
+ page_id = MGMT_TLV_GET_U32(tlv_info->value);
+ content_len = tlv_info->length - MGMT_TLV_U32_SIZE;
+ if (page_id == QSFP_CMIS_PAGE_00H) {
+ tmp_addr = (u8 *)(tlv_info + 1);
+ page_info->id = *(tmp_addr + MGMT_TLV_U32_SIZE);
+ }
+
+ ret = hinic3_trans_cmis_get_page_pos(page_id, content_len, &src_pos);
+ if (ret != 0)
+ return ret;
+
+ src_addr = page_info->tlv_page_info + src_pos;
+ tmp_addr = (u8 *)(tlv_info + 1);
+ dst_addr = tmp_addr + MGMT_TLV_U32_SIZE;
+ memcpy(src_addr, dst_addr, content_len);
+
+ if (idx < XSFP_CMIS_PARSE_PAGE_NUM)
+ page_info->tlv_page_num[idx] = page_id;
+
+ *total_len += content_len;
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_tlv_info_to_buf(u8 *sfp_tlv_info,
+ struct parse_tlv_info *page_info)
+{
+ struct mgmt_tlv_info *tlv_info = NULL;
+ u8 *tlv_buf = sfp_tlv_info;
+ u8 idx = 0;
+ u32 total_len = 0;
+ int ret = 0;
+ bool need_continue = true;
+
+ if (!sfp_tlv_info || !page_info)
+ return -EIO;
+
+ while (need_continue) {
+ tlv_info = (struct mgmt_tlv_info *)tlv_buf;
+ switch (tlv_info->type) {
+ case MAG_XSFP_TYPE_PAGE:
+ ret = hinic3_get_page_key_info(tlv_info, page_info,
+ idx, &total_len);
+ if (ret != 0) {
+ pr_err("lib_get_page_key_info fail,ret:0x%x.\n",
+ ret);
+ break;
+ }
+ idx++;
+ break;
+
+ case MAG_XSFP_TYPE_WIRE_TYPE:
+ page_info->wire_type = MGMT_TLV_GET_U32(&tlv_info->value);
+ break;
+
+ case MAG_XSFP_TYPE_END:
+ need_continue = false;
+ break;
+
+ default:
+ break;
+ }
+
+ tlv_buf += (sizeof(struct mgmt_tlv_info) + tlv_info->length);
+ }
+
+ page_info->tlv_page_info_len = total_len;
+
+ return 0;
+}
+
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len)
+{
+ int err = 0;
+ struct tag_mag_cmd_get_xsfp_tlv_req xsfp_tlv_info_req = {0};
+
+ xsfp_tlv_info_req.rsp_buf_len = XSFP_CMIS_INFO_MAX_SIZE;
+ xsfp_tlv_info_req.port_id = hinic3_physical_port_id(hwdev);
+ err = hinic3_get_sfp_tlv_info(hwdev, &g_xsfp_tlv_info,
+ &xsfp_tlv_info_req);
+ if (err != 0)
+ return err;
+
+ err = hinic3_trans_cmis_tlv_info_to_buf(g_xsfp_tlv_info.tlv_buf,
+ &g_page_info);
+ if (err)
+ return -ENOMEM;
+
+ memcpy(data, g_page_info.tlv_page_info, len);
+
+ return (err == 0) ? 0 : -ENOMEM;
+}
+
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
{
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ u8 sfp_info_status = 0;
u16 out_size = sizeof(*sfp_info);
int err;
@@ -608,13 +1214,17 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ sfp_info_status = rt_cmd->std_sfp_info.head.status;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (sfp_info_status != 0) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return -EIO;
+ return (sfp_info_status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ ? HINIC3_MGMT_CMD_UNSUPPORTED : -EIO;
}
memcpy(sfp_info, &rt_cmd->std_sfp_info, sizeof(*sfp_info));
@@ -626,7 +1236,12 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
sfp_info->port_id = hinic3_physical_port_id(hwdev);
err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_INFO, sfp_info,
sizeof(*sfp_info), sfp_info, &out_size);
- if (sfp_info->head.status || err || !out_size) {
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ return HINIC3_MGMT_CMD_UNSUPPORTED;
+
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ return -EOPNOTSUPP;
+ if (sfp_info->head.status != 0 || err != 0 || out_size == 0) {
nic_err(nic_io->dev_hdl,
"Failed to get port%u sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
hinic3_physical_port_id(hwdev), err,
@@ -642,7 +1257,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
struct mag_cmd_get_xsfp_info sfp_info;
int err;
- if (!hwdev || !data)
+ if (!hwdev || !data || len > PAGE_SIZE)
return -EINVAL;
if (hinic3_if_sfp_absent(hwdev))
@@ -654,7 +1269,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
if (err)
return err;
- memcpy(data, sfp_info.sfp_info, len);
+ memcpy(data, sfp_info.sfp_info, sizeof(sfp_info.sfp_info));
return 0;
}
@@ -664,7 +1279,7 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
- int err;
+ int err = 0;
if (!hwdev || !sfp_type || !sfp_type_ext)
return -EINVAL;
@@ -677,20 +1292,35 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (rt_cmd->std_sfp_info.head.status == 0) {
+ *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
+ *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ if (rt_cmd->std_sfp_info.head.status != HINIC3_MGMT_CMD_UNSUPPORTED) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
return -EIO;
}
- *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
- *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
- mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return 0;
+ err = HINIC3_MGMT_CMD_UNSUPPORTED; /* cmis */
}
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
- STD_SFP_INFO_MAX_SIZE);
+ if (err == 0) {
+ err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ } else {
+ /* mpu_send_sfp_info is false */
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ }
+
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+
if (err)
return err;
@@ -796,16 +1426,23 @@ int hinic3_set_pf_bw_limit(void *hwdev, u32 bw_limit)
return -EINVAL;
}
- old_bw_limit = nic_io->nic_cfg.pf_bw_limit;
- nic_io->nic_cfg.pf_bw_limit = bw_limit;
+ if (nic_io->direct == HINIC3_NIC_TX) {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_tx_limit;
+ nic_io->nic_cfg.pf_bw_tx_limit = bw_limit;
+ } else {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_rx_limit;
+ nic_io->nic_cfg.pf_bw_rx_limit = bw_limit;
+ }
err = hinic3_update_pf_bw(hwdev);
if (err) {
- nic_io->nic_cfg.pf_bw_limit = old_bw_limit;
- return err;
+ if (nic_io->direct == HINIC3_NIC_TX)
+ nic_io->nic_cfg.pf_bw_tx_limit = old_bw_limit;
+ else
+ nic_io->nic_cfg.pf_bw_rx_limit = old_bw_limit;
}
- return 0;
+ return err;
}
static const struct vf_msg_handler vf_mag_cmd_handler[] = {
@@ -828,6 +1465,9 @@ int hinic3_pf_mag_mbox_handler(void *hwdev, u16 vf_id,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
for (index = 0; index < cmd_size; index++) {
handler = &vf_mag_cmd_handler[index];
@@ -848,6 +1488,11 @@ static struct nic_event_handler mag_cmd_handler[] = {
.handler = link_status_event_handler,
},
+ {
+ .cmd = MAG_CMD_EVENT_PORT_INFO,
+ .handler = port_info_event_printf,
+ },
+
{
.cmd = MAG_CMD_WIRE_EVENT,
.handler = cable_plug_event,
@@ -862,6 +1507,16 @@ static struct nic_event_handler mag_cmd_handler[] = {
.cmd = MAG_CMD_GET_XSFP_PRESENT,
.handler = port_sfp_abs_event,
},
+
+ {
+ .cmd = MAG_CMD_GET_BOND_STATUS,
+ .handler = bond_status_event_handler,
+ },
+
+ {
+ .cmd = MAG_CMD_GET_XSFP_TLV_INFO,
+ .handler = port_xsfp_tlv_info_event,
+ },
};
static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
@@ -877,6 +1532,9 @@ static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
for (i = 0; i < size; i++) {
if (cmd == mag_cmd_handler[i].cmd) {
mag_cmd_handler[i].handler(hwdev, buf_in, in_size,
@@ -917,7 +1575,8 @@ static int _mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u32 i, cmd_cnt = ARRAY_LEN(vf_mag_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_mag_cmd_handler[i].cmd) {
cmd_to_pf = true;
@@ -949,3 +1608,123 @@ static int mag_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in,
return _mag_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out,
out_size, channel);
}
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+struct fecparam_value_map {
+ u8 hinic3_fec_offset;
+ u8 hinic3_fec_value;
+ u8 ethtool_fec_value;
+};
+
+static void fecparam_convert(u32 opcode, u8 in_fec_param, u8 *out_fec_param)
+{
+ u8 i;
+ u8 fec_value_table_lenth;
+ struct fecparam_value_map fec_value_table[] = {
+ {PORT_FEC_NOT_SET, BIT(PORT_FEC_NOT_SET), ETHTOOL_FEC_NONE},
+ {PORT_FEC_RSFEC, BIT(PORT_FEC_RSFEC), ETHTOOL_FEC_RS},
+ {PORT_FEC_BASEFEC, BIT(PORT_FEC_BASEFEC), ETHTOOL_FEC_BASER},
+ {PORT_FEC_NOFEC, BIT(PORT_FEC_NOFEC), ETHTOOL_FEC_OFF},
+#ifdef ETHTOOL_FEC_LLRS
+ {PORT_FEC_LLRSFEC, BIT(PORT_FEC_LLRSFEC), ETHTOOL_FEC_LLRS},
+#endif
+ {PORT_FEC_AUTO, BIT(PORT_FEC_AUTO), ETHTOOL_FEC_AUTO}
+ };
+
+ *out_fec_param = 0;
+ fec_value_table_lenth = (u8)(sizeof(fec_value_table) / sizeof(struct fecparam_value_map));
+
+ if (opcode == MAG_CMD_OPCODE_SET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].ethtool_fec_value) != 0)
+ /* The MPU uses the offset to determine the FEC mode. */
+ *out_fec_param =
+ fec_value_table[i].hinic3_fec_offset;
+ }
+ }
+
+ if (opcode == MAG_CMD_OPCODE_GET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].hinic3_fec_value) != 0)
+ *out_fec_param |=
+ fec_value_table[i].ethtool_fec_value;
+ }
+ }
+}
+
+/* When the ethtool is used to set the FEC mode */
+static bool check_fecparam_is_valid(u8 fec_param)
+{
+ if (fec_param == ETHTOOL_FEC_RS ||
+#ifdef ETHTOOL_FEC_LLRS
+ fec_param == ETHTOOL_FEC_LLRS ||
+#endif
+ fec_param == ETHTOOL_FEC_BASER ||
+ fec_param == ETHTOOL_FEC_OFF) {
+ return true;
+ }
+ return false;
+}
+
+int set_fecparam(void *hwdev, u8 fecparam)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ u8 advertised_fec = 0;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (check_fecparam_is_valid(fecparam) == false) {
+ nic_err(nic_io->dev_hdl, "fec param is invalid, failed to set fec param\n");
+ return -EINVAL;
+ }
+ fecparam_convert(MAG_CMD_OPCODE_SET, fecparam, &advertised_fec);
+ fec_msg.opcode = MAG_CMD_OPCODE_SET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ fec_msg.advertised_fec = advertised_fec;
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if (err != 0 || fec_msg.head.status != 0)
+ return -EINVAL;
+ return 0;
+}
+
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ fec_msg.opcode = MAG_CMD_OPCODE_GET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if (err != 0 || fec_msg.head.status != 0)
+ return -EINVAL;
+
+ /* fec_msg.advertised_fec: bit offset,
+ *value is BIT(fec_msg.advertised_fec); fec_msg.supported_fec: value
+ */
+ fecparam_convert(MAG_CMD_OPCODE_GET, BIT(fec_msg.advertised_fec),
+ advertised_fec);
+ fecparam_convert(MAG_CMD_OPCODE_GET, fec_msg.supported_fec,
+ supported_fec);
+ return 0;
+}
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
index 6f90c86..7327ee5 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
@@ -20,6 +20,9 @@
#include <linux/debugfs.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#include "hinic3_hw.h"
#include "hinic3_crm.h"
#include "hinic3_mt.h"
@@ -35,8 +38,8 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
#include "hinic3_profile.h"
+#include "hinic3_bond.h"
-/*lint -e806*/
#define DEFAULT_POLL_WEIGHT 64
static unsigned int poll_weight = DEFAULT_POLL_WEIGHT;
module_param(poll_weight, uint, 0444);
@@ -68,7 +71,9 @@ static unsigned char set_link_status_follow = HINIC3_LINK_FOLLOW_STATUS_MAX;
module_param(set_link_status_follow, byte, 0444);
MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=default,1=follow,2=separate,3=unset");
-/*lint +e806*/
+static bool page_pool_enabled = true;
+module_param(page_pool_enabled, bool, 0444);
+MODULE_PARM_DESC(page_pool_enabled, "enable/disable page_pool feature for rxq page management (default enable)");
#define HINIC3_NIC_DEV_WQ_NAME "hinic3_nic_dev_wq"
@@ -80,6 +85,8 @@ MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=
#define HINIC3_SQ_DEPTH 1024
#define HINIC3_RQ_DEPTH 1024
+#define LRO_ENABLE 1
+
enum hinic3_rx_buff_len {
RX_BUFF_VALID_2KB = 2,
RX_BUFF_VALID_4KB = 4,
@@ -87,12 +94,15 @@ enum hinic3_rx_buff_len {
RX_BUFF_VALID_16KB = 16,
};
+#define NIC_MAX_PF_NUM 32
+
#define CONVERT_UNIT 1024
-#define BIFUR_RESOURCE_PF_SSID 0x5a1
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
-static int hinic3_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr);
+static int hinic3_netdev_event(struct notifier_block *notifier,
+ unsigned long event, void *ptr);
/* used for netdev notifier register/unregister */
static DEFINE_MUTEX(hinic3_netdev_notifiers_mutex);
@@ -101,6 +111,17 @@ static struct notifier_block hinic3_netdev_notifier = {
.notifier_call = hinic3_netdev_event,
};
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+static const struct udp_tunnel_nic_info hinic3_udp_tunnels = {
+ .set_port = hinic3_udp_tunnel_set_port,
+ .unset_port = hinic3_udp_tunnel_unset_port,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static void hinic3_register_notifier(struct hinic3_nic_dev *nic_dev)
{
int err;
@@ -134,7 +155,8 @@ static void hinic3_unregister_notifier(struct hinic3_nic_dev *nic_dev)
NETIF_F_SCTP_CRC | NETIF_F_RXCSUM | \
NETIF_F_ALL_TSO)
-static int hinic3_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr)
+static int hinic3_netdev_event(struct notifier_block *notifier,
+ unsigned long event, void *ptr)
{
struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
struct net_device *real_dev = NULL;
@@ -266,6 +288,11 @@ static void netdev_feature_init(struct net_device *netdev)
netdev->features |= dft_fts | cso_fts | tso_fts | vlan_fts;
netdev->vlan_features |= dft_fts | cso_fts | tso_fts;
+ if (nic_dev->nic_cap.lro_enable == LRO_ENABLE) {
+ netdev->features |= NETIF_F_LRO;
+ netdev->vlan_features |= NETIF_F_LRO;
+ }
+
#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT
hw_features |= get_netdev_hw_features(netdev);
#else
@@ -306,7 +333,8 @@ static void init_intr_coal_param(struct hinic3_nic_dev *nic_dev)
info->pending_limt = qp_pending_limit;
info->coalesce_timer_cfg = qp_coalesc_timer_cfg;
- info->resend_timer_cfg = HINIC3_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG;
+ info->resend_timer_cfg =
+ HINIC3_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG;
info->pkt_rate_high = HINIC3_RX_RATE_HIGH;
info->rx_usecs_high = HINIC3_RX_COAL_TIME_HIGH;
@@ -350,6 +378,7 @@ static int hinic3_init_intr_coalesce(struct hinic3_nic_dev *nic_dev)
static void hinic3_free_intr_coalesce(struct hinic3_nic_dev *nic_dev)
{
kfree(nic_dev->intr_coalesce);
+ nic_dev->intr_coalesce = NULL;
}
static int hinic3_alloc_txrxqs(struct hinic3_nic_dev *nic_dev)
@@ -396,15 +425,18 @@ static void hinic3_free_txrxqs(struct hinic3_nic_dev *nic_dev)
static void hinic3_tx_rx_ops_init(struct hinic3_nic_dev *nic_dev)
{
if (HINIC3_SUPPORT_TX_COMPACT_WQE_OL(nic_dev->hwdev)) {
- nic_dev->tx_rx_ops.tx_set_wqebb_cnt = hinic3_tx_set_compact_offload_wqebb_cnt;
- nic_dev->tx_rx_ops.tx_set_wqe_task = hinic3_tx_set_compact_offload_wqe_task;
+ nic_dev->tx_rx_ops.tx_set_wqebb_cnt =
+ hinic3_tx_set_compact_offload_wqebb_cnt;
+ nic_dev->tx_rx_ops.tx_set_wqe_task =
+ hinic3_tx_set_compact_offload_wqe_task;
} else {
nic_dev->tx_rx_ops.tx_set_wqebb_cnt = hinic3_tx_set_wqebb_cnt;
nic_dev->tx_rx_ops.tx_set_wqe_task = hinic3_tx_set_wqe_task;
}
if (HINIC3_SUPPORT_RX_COMPACT_CQE(nic_dev->hwdev))
- nic_dev->tx_rx_ops.rx_get_cqe_info = hinic3_rx_get_compact_cqe_info;
+ nic_dev->tx_rx_ops.rx_get_cqe_info =
+ hinic3_rx_get_compact_cqe_info;
else
nic_dev->tx_rx_ops.rx_get_cqe_info = hinic3_rx_get_cqe_info;
}
@@ -420,53 +452,47 @@ static void hinic3_sw_deinit(struct hinic3_nic_dev *nic_dev)
HINIC3_CHANNEL_NIC);
hinic3_clear_rss_config(nic_dev);
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+
+ hinic3_dcb_deinit(nic_dev);
}
-static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
+static void hinic3_netdev_mtu_init(struct net_device *netdev)
+{
+ /* MTU range: 384 - 9600 */
+#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
+ netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+
+#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
+ netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+}
+
+static int hinic3_set_default_mac(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
u8 mac_addr[ETH_ALEN];
- u64 nic_features;
int err = 0;
- nic_features = hinic3_get_feature_cap(nic_dev->hwdev);
- /* You can update the features supported by the driver according to the
- * scenario here
- */
- nic_features &= NIC_DRV_DEFAULT_FEATURE;
- hinic3_update_nic_feature(nic_dev->hwdev, nic_features);
-
- sema_init(&nic_dev->port_state_sem, 1);
-
- err = hinic3_dcb_init(nic_dev);
- if (err) {
- nic_err(&nic_dev->pdev->dev, "Failed to init dcb\n");
- return -EFAULT;
- }
-
- nic_dev->q_params.sq_depth = HINIC3_SQ_DEPTH;
- nic_dev->q_params.rq_depth = HINIC3_RQ_DEPTH;
-
- hinic3_try_to_enable_rss(nic_dev);
-
err = hinic3_get_default_mac(nic_dev->hwdev, mac_addr);
if (err) {
nic_err(&nic_dev->pdev->dev, "Failed to get MAC address\n");
- goto get_mac_err;
+ return err;
}
+
eth_hw_addr_set(netdev, mac_addr);
if (!is_valid_ether_addr(netdev->dev_addr)) {
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
nic_err(&nic_dev->pdev->dev, "Invalid MAC address %pM\n",
- netdev->dev_addr);
- err = -EIO;
- goto err_mac;
- }
+ netdev->dev_addr);
+ return -EIO;
+ }
- nic_info(&nic_dev->pdev->dev, "Invalid MAC address %pM, using random\n",
+ nic_info(&nic_dev->pdev->dev,
+ "Invalid MAC address %pM, using random\n",
netdev->dev_addr);
eth_hw_addr_random(netdev);
}
@@ -478,21 +504,62 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
* MAC, and we can't consider this condition is error status during
* driver probe procedure.
*/
- if (err && err != HINIC3_PF_SET_VF_ALREADY) {
+ if (err && err != HINIC3_PF_SET_VF_ALREADY)
nic_err(&nic_dev->pdev->dev, "Failed to set default MAC\n");
- goto set_mac_err;
+
+ if (err == HINIC3_PF_SET_VF_ALREADY)
+ return 0;
+
+ return err;
+}
+
+static void hinic3_outband_cfg_init(struct hinic3_nic_dev *nic_dev)
+{
+ u16 outband_default_vid = 0;
+ int err = 0;
+
+ if (!nic_dev->nic_cap.outband_vlan_cfg_en)
+ return;
+
+ err = hinic3_get_outband_vlan_cfg(nic_dev->hwdev, &outband_default_vid);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev,
+ "Failed to get_outband_cfg, err: %d\n", err);
+ return;
}
- /* MTU range: 384 - 9600 */
-#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
- netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
+ nic_dev->outband_cfg.outband_default_vid = outband_default_vid;
+}
-#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
- netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
+static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
+{
+ struct net_device *netdev = nic_dev->netdev;
+ u64 nic_features;
+ int err = 0;
+
+ nic_features = hinic3_get_feature_cap(nic_dev->hwdev);
+ /* You can update the features supported by the driver according to the
+ * scenario here
+ */
+ nic_features &= NIC_DRV_DEFAULT_FEATURE;
+ hinic3_update_nic_feature(nic_dev->hwdev, nic_features);
+
+ err = hinic3_dcb_init(nic_dev);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev, "Failed to init dcb\n");
+ return -EFAULT;
+ }
+
+ nic_dev->q_params.sq_depth = HINIC3_SQ_DEPTH;
+ nic_dev->q_params.rq_depth = HINIC3_RQ_DEPTH;
+
+ hinic3_try_to_enable_rss(nic_dev);
+
+ err = hinic3_set_default_mac(nic_dev);
+ if (err)
+ goto set_mac_err;
+
+ hinic3_netdev_mtu_init(netdev);
err = hinic3_alloc_txrxqs(nic_dev);
if (err) {
@@ -500,6 +567,8 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
goto alloc_qps_err;
}
+ hinic3_outband_cfg_init(nic_dev);
+
hinic3_tx_rx_ops_init(nic_dev);
return 0;
@@ -510,8 +579,6 @@ alloc_qps_err:
HINIC3_CHANNEL_NIC);
set_mac_err:
-err_mac:
-get_mac_err:
hinic3_clear_rss_config(nic_dev);
return err;
@@ -623,7 +690,8 @@ static void calc_coal_para(struct hinic3_nic_dev *nic_dev,
*pending_limt =
(u8)((rx_rate - q_coal->pkt_rate_low) *
- (q_coal->rx_pending_limt_high - q_coal->rx_pending_limt_low) /
+ (q_coal->rx_pending_limt_high -
+ q_coal->rx_pending_limt_low) /
(q_coal->pkt_rate_high - q_coal->pkt_rate_low) +
q_coal->rx_pending_limt_low);
}
@@ -637,8 +705,10 @@ static void update_queue_coal(struct hinic3_nic_dev *nic_dev, u16 qid,
q_coal = &nic_dev->intr_coalesce[qid];
- if (rx_rate > HINIC3_RX_RATE_THRESH && avg_pkt_size > HINIC3_AVG_PKT_SMALL) {
- calc_coal_para(nic_dev, q_coal, rx_rate, &coalesc_timer_cfg, &pending_limt);
+ if (rx_rate > HINIC3_RX_RATE_THRESH &&
+ avg_pkt_size > HINIC3_AVG_PKT_SMALL) {
+ calc_coal_para(nic_dev, q_coal, rx_rate,
+ &coalesc_timer_cfg, &pending_limt);
} else {
coalesc_timer_cfg = HINIC3_LOWEST_LATENCY;
pending_limt = q_coal->rx_pending_limt_low;
@@ -701,20 +771,55 @@ void hinic3_auto_moderation_work(struct work_struct *work)
static void hinic3_periodic_work_handler(struct work_struct *work)
{
struct delayed_work *delay = to_delayed_work(work);
- struct hinic3_nic_dev *nic_dev = container_of(delay, struct hinic3_nic_dev, periodic_work);
+ struct hinic3_nic_dev *nic_dev =
+ container_of(delay, struct hinic3_nic_dev, periodic_work);
if (test_and_clear_bit(EVENT_WORK_TX_TIMEOUT, &nic_dev->event_flag))
- hinic3_fault_event_report(nic_dev->hwdev, HINIC3_FAULT_SRC_TX_TIMEOUT,
+ hinic3_fault_event_report(nic_dev->hwdev,
+ HINIC3_FAULT_SRC_TX_TIMEOUT,
FAULT_LEVEL_SERIOUS_FLR);
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
}
+static void hinic3_vport_stats_work_handler(struct work_struct *work)
+{
+ int err;
+ struct hinic3_vport_stats vport_stats = {0};
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_nic_dev *nic_dev = container_of(delay,
+ struct hinic3_nic_dev,
+ vport_stats_work);
+ err = hinic3_get_vport_stats(nic_dev->hwdev,
+ hinic3_global_func_id(nic_dev->hwdev),
+ &vport_stats);
+ if (err)
+ nic_err(&nic_dev->pdev->dev, "Failed to get dropped stats from fw\n");
+ else
+ nic_dev->vport_stats.rx_discard_vport =
+ vport_stats.rx_discard_vport;
+ queue_delayed_work(nic_dev->workq, &nic_dev->vport_stats_work, HZ);
+}
+
+static void free_nic_dev_vram(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram = get_use_vram_flag();
+
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)nic_dev->nic_vram, nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ else
+ kfree(nic_dev->nic_vram);
+ nic_dev->nic_vram = NULL;
+}
+
static void free_nic_dev(struct hinic3_nic_dev *nic_dev)
{
hinic3_deinit_nic_prof_adapter(nic_dev);
destroy_workqueue(nic_dev->workq);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+ free_nic_dev_vram(nic_dev);
}
static int setup_nic_dev(struct net_device *netdev,
@@ -724,6 +829,10 @@ static int setup_nic_dev(struct net_device *netdev,
struct hinic3_nic_dev *nic_dev;
char *netdev_name_fmt;
u32 page_num;
+ u16 func_id;
+ int ret;
+ int is_in_kexec = vram_get_kexec_flag();
+ int is_use_vram = get_use_vram_flag();
nic_dev = (struct hinic3_nic_dev *)netdev_priv(netdev);
nic_dev->netdev = netdev;
@@ -738,22 +847,58 @@ static int setup_nic_dev(struct net_device *netdev,
nic_dev->dma_rx_buff_size = RX_BUFF_NUM_PER_PAGE * nic_dev->rx_buff_len;
page_num = nic_dev->dma_rx_buff_size / PAGE_SIZE;
nic_dev->page_order = page_num > 0 ? ilog2(page_num) : 0;
+ nic_dev->page_pool_enabled = page_pool_enabled;
+ nic_dev->outband_cfg.outband_default_vid = 0;
+
+ // value other than 0 indicates hot replace
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(nic_dev->nic_vram_name, VRAM_NAME_MAX_LEN,
+ "%s%hu", VRAM_NIC_VRAM, func_id);
+
+ nic_dev->nic_vram = (struct hinic3_vram *)hi_vram_kalloc(nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+
+ if (is_in_kexec == 0)
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ else
+ netdev->mtu = nic_dev->nic_vram->vram_mtu;
+ } else {
+ nic_dev->nic_vram = kzalloc(sizeof(*nic_dev->nic_vram),
+ GFP_KERNEL);
+ if (!nic_dev->nic_vram)
+ return -ENOMEM;
+
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ }
mutex_init(&nic_dev->nic_mutex);
nic_dev->vlan_bitmap = kzalloc(VLAN_BITMAP_SIZE(nic_dev), GFP_KERNEL);
- if (!nic_dev->vlan_bitmap)
- return -ENOMEM;
+ if (!nic_dev->vlan_bitmap) {
+ nic_err(&pdev->dev, "Failed to allocate vlan bitmap\n");
+ ret = -ENOMEM;
+ goto vlan_bitmap_error;
+ }
nic_dev->workq = create_singlethread_workqueue(HINIC3_NIC_DEV_WQ_NAME);
if (!nic_dev->workq) {
nic_err(&pdev->dev, "Failed to initialize nic workqueue\n");
- kfree(nic_dev->vlan_bitmap);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto create_workq_error;
}
- INIT_DELAYED_WORK(&nic_dev->periodic_work, hinic3_periodic_work_handler);
- INIT_DELAYED_WORK(&nic_dev->rxq_check_work, hinic3_rxq_check_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->periodic_work,
+ hinic3_periodic_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->rxq_check_work,
+ hinic3_rxq_check_work_handler);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ INIT_DELAYED_WORK(&nic_dev->vport_stats_work,
+ hinic3_vport_stats_work_handler);
INIT_LIST_HEAD(&nic_dev->uc_filter_list);
INIT_LIST_HEAD(&nic_dev->mc_filter_list);
@@ -766,10 +911,23 @@ static int setup_nic_dev(struct net_device *netdev,
hinic3_init_nic_prof_adapter(nic_dev);
netdev_name_fmt = hinic3_get_dft_netdev_name_fmt(nic_dev);
- if (netdev_name_fmt)
- strscpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (netdev_name_fmt) {
+ ret = strscpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (ret < 0)
+ goto get_netdev_name_error;
+ }
return 0;
+
+get_netdev_name_error:
+ hinic3_deinit_nic_prof_adapter(nic_dev);
+ destroy_workqueue(nic_dev->workq);
+create_workq_error:
+ kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+vlan_bitmap_error:
+ free_nic_dev_vram(nic_dev);
+ return ret;
}
static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
@@ -808,6 +966,31 @@ static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
return 0;
}
+static void hinic3_bond_init(struct hinic3_nic_dev *nic_dev)
+{
+ u32 bond_id = HINIC3_INVALID_BOND_ID;
+ int err = hinic3_create_bond(nic_dev->hwdev, &bond_id);
+
+ if (err != 0)
+ goto bond_init_failed;
+
+ /* bond id does not change, means this pf is not bond active pf, no log is generated */
+ if (bond_id == HINIC3_INVALID_BOND_ID)
+ return;
+
+ err = hinic3_open_close_bond(nic_dev->hwdev, true);
+ if (err != 0) {
+ hinic3_delete_bond(nic_dev->hwdev);
+ goto bond_init_failed;
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Bond %d init success\n", bond_id);
+ return;
+
+bond_init_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond init failed\n");
+}
+
static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
char *uld_dev_name)
{
@@ -838,6 +1021,12 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
goto err_out;
}
+ err = hinic3_get_dev_cap(lld_dev->hwdev);
+ if (err != 0) {
+ nic_err(&pdev->dev, "Failed to get dev cap\n");
+ goto err_out;
+ }
+
max_qps = hinic3_func_max_nic_qnum(lld_dev->hwdev);
netdev = alloc_etherdev_mq(sizeof(*nic_dev), max_qps);
if (!netdev) {
@@ -870,10 +1059,17 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
hinic3_assign_netdev_ops(nic_dev);
netdev_feature_init(netdev);
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+ netdev->udp_tunnel_nic_info = &hinic3_udp_tunnels;
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
err = hinic3_set_default_hw_feature(nic_dev);
if (err)
goto set_features_err;
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0)
+ hinic3_bond_init(nic_dev);
+
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
hinic3_register_notifier(nic_dev);
#endif
@@ -888,6 +1084,9 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
}
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->vport_stats_work, HZ);
netif_carrier_off(netdev);
*uld_dev = nic_dev;
@@ -920,6 +1119,25 @@ err_out:
return err;
}
+static void hinic3_bond_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ int ret = 0;
+
+ ret = hinic3_open_close_bond(nic_dev->hwdev, false);
+ if (ret != 0)
+ goto bond_deinit_failed;
+
+ ret = hinic3_delete_bond(nic_dev->hwdev);
+ if (ret != 0)
+ goto bond_deinit_failed;
+
+ nic_info(&nic_dev->pdev->dev, "Bond deinit success\n");
+ return;
+
+bond_deinit_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond deinit failed\n");
+}
+
static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
{
struct hinic3_nic_dev *nic_dev = adapter;
@@ -939,6 +1157,8 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_unregister_notifier(nic_dev);
#endif
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ cancel_delayed_work_sync(&nic_dev->vport_stats_work);
cancel_delayed_work_sync(&nic_dev->periodic_work);
cancel_delayed_work_sync(&nic_dev->rxq_check_work);
cancel_work_sync(&nic_dev->rx_mode_work);
@@ -946,6 +1166,9 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_flush_rx_flow_rule(nic_dev);
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0)
+ hinic3_bond_deinit(nic_dev);
+
hinic3_update_nic_feature(nic_dev->hwdev, 0);
hinic3_set_nic_feature_to_hw(nic_dev->hwdev);
@@ -955,6 +1178,7 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_deinit_nic_prof_adapter(nic_dev);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
free_netdev(netdev);
@@ -971,8 +1195,10 @@ static void sriov_state_change(struct hinic3_nic_dev *nic_dev,
static void hinic3_port_module_event_handler(struct hinic3_nic_dev *nic_dev,
struct hinic3_event_info *event)
{
- const char *g_hinic3_module_link_err[LINK_ERR_NUM] = { "Unrecognized module" };
- struct hinic3_port_module_event *module_event = (void *)event->event_data;
+ const char *g_hinic3_module_link_err[LINK_ERR_NUM] = {
+ "Unrecognized module" };
+ struct hinic3_port_module_event *module_event =
+ (void *)event->event_data;
enum port_module_event_type type = module_event->type;
enum link_err_type err_type = module_event->err_type;
@@ -1003,6 +1229,116 @@ static void hinic3_port_module_event_handler(struct hinic3_nic_dev *nic_dev,
}
}
+bool hinic3_need_proc_link_event(struct hinic3_lld_dev *lld_dev)
+{
+ int ret = 0;
+ u16 func_id;
+ u8 roce_enable = false;
+ bool is_slave_func = false;
+ struct hinic3_hw_bond_infos hw_bond_infos = {0};
+
+ if (!lld_dev)
+ return false;
+
+ /* 非slave设备需要处理link down事件 */
+ ret = hinic3_is_slave_func(lld_dev->hwdev, &is_slave_func);
+ if (ret != 0) {
+ nic_err(&lld_dev->pdev->dev, "NIC get info, lld_dev is null\n");
+ return true;
+ }
+
+ if (!is_slave_func)
+ return true;
+
+ /* 未使能了vroce功能,需处理link down事件 */
+ func_id = hinic3_global_func_id(lld_dev->hwdev);
+ ret = hinic3_get_func_vroce_enable(lld_dev->hwdev, func_id, &roce_enable);
+ if (ret != 0)
+ return true;
+
+ if (!roce_enable)
+ return true;
+
+ /* 未创建bond,需要处理link down事件 */
+ hw_bond_infos.bond_id = HINIC_OVS_BOND_DEFAULT_ID;
+
+ ret = hinic3_get_hw_bond_infos(lld_dev->hwdev, &hw_bond_infos, HINIC3_CHANNEL_COMM);
+ if (ret != 0) {
+ pr_err("[ROCE, ERR] Get chipf bond info failed (%d)\n", ret);
+ return true;
+ }
+
+ if (!hw_bond_infos.valid)
+ return true;
+
+ return false;
+}
+
+bool hinic3_need_proc_bond_event(struct hinic3_lld_dev *lld_dev)
+{
+ return !hinic3_need_proc_link_event(lld_dev);
+}
+
+static void hinic_porc_bond_state_change(struct hinic3_lld_dev *lld_dev, void *adapter,
+ struct hinic3_event_info *event)
+{
+ struct hinic3_nic_dev *nic_dev = adapter;
+
+ if (!nic_dev || !event || !hinic3_support_nic(lld_dev->hwdev, NULL))
+ return;
+
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond down\n");
+ hinic3_link_status_change(nic_dev, false);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond up\n");
+ hinic3_link_status_change(nic_dev, true);
+ break;
+ default:
+ break;
+ }
+}
+
+static void hinic3_outband_cfg_event_handler(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_outband_cfg_info *info)
+{
+ int err = 0;
+
+ if (!nic_dev || !info || !hinic3_support_nic(nic_dev->hwdev, NULL)) {
+ pr_err("Outband cfg event invalid param\n");
+ return;
+ }
+
+ if (hinic3_func_type(nic_dev->hwdev) != TYPE_VF &&
+ info->func_id >= NIC_MAX_PF_NUM) {
+ err = hinic3_notify_vf_outband_cfg(nic_dev->hwdev,
+ info->func_id,
+ info->outband_default_vid);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev,
+ "Outband cfg event notify vf err: %d, func_id: 0x%x, vid: 0x%x\n",
+ err, info->func_id, info->outband_default_vid);
+ return;
+ }
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Change outband default vid from %u to %u\n",
+ nic_dev->outband_cfg.outband_default_vid,
+ info->outband_default_vid);
+
+ nic_dev->outband_cfg.outband_default_vid = info->outband_default_vid;
+}
+
static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
struct hinic3_event_info *event)
{
@@ -1014,21 +1350,35 @@ static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_DOWN):
+ if (!hinic3_need_proc_link_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc link event\n");
+ return;
+ }
hinic3_link_status_change(nic_dev, false);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_UP):
hinic3_link_status_change(nic_dev, true);
break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ hinic_porc_bond_state_change(lld_dev, adapter, event);
+ break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_PORT_MODULE_EVENT):
hinic3_port_module_event_handler(nic_dev, event);
break;
- case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_SRIOV_STATE_CHANGE):
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_OUTBAND_CFG):
+ hinic3_outband_cfg_event_handler(nic_dev,
+ (void *)event->event_data);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM,
+ EVENT_COMM_SRIOV_STATE_CHANGE):
sriov_state_change(nic_dev, (void *)event->event_data);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_FAULT):
fault = (void *)event->event_data;
if (fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
- fault->event.chip.func_id == hinic3_global_func_id(lld_dev->hwdev))
+ fault->event.chip.func_id ==
+ hinic3_global_func_id(lld_dev->hwdev))
hinic3_link_status_change(nic_dev, false);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_PCIE_LINK_DOWN):
@@ -1081,7 +1431,7 @@ struct hinic3_uld_info g_nic_uld_info = {
.resume = NULL,
.event = nic_event,
.ioctl = nic_ioctl,
-}; /*lint -e766*/
+};
struct hinic3_uld_info *get_nic_uld_info(void)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
index 94e606e..5bd4c3d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
@@ -9,6 +9,7 @@
/* Interrupt at most records, interrupt will be recorded in the FFM */
#define NICTOOL_CMD_TYPE (0x18)
+#define HINIC3_CARD_NAME_MAX_LEN (128)
struct api_cmd_rd {
u32 pf_id;
@@ -110,7 +111,8 @@ enum dbgtool_cmd {
DBGTOOL_CMD_NUM
};
-#define PF_MAX_SIZE (16)
+#define HINIC_PF_MAX_SIZE (16)
+#define HINIC_VF_MAX_SIZE (4096)
#define BUSINFO_LEN (32)
enum module_name {
@@ -132,7 +134,8 @@ enum module_name {
SEND_TO_MIGRATE_DRIVER,
SEND_TO_PPA_DRIVER,
SEND_TO_CUSTOM_DRIVER = SEND_TO_SRV_DRV_BASE + 11,
- SEND_TO_BIFUR_DRIVER = SEND_TO_SRV_DRV_BASE + 15,
+ SEND_TO_VSOCK_DRIVER = SEND_TO_SRV_DRV_BASE + 14,
+ SEND_TO_BIFUR_DRIVER,
SEND_TO_DRIVER_MAX = SEND_TO_SRV_DRV_BASE + 16, /* reserved */
};
@@ -160,7 +163,7 @@ enum driver_cmd_type {
GET_CHIP_FAULT_STATS,
NIC_RSVD1,
NIC_RSVD2,
- NIC_RSVD3,
+ GET_OS_HOT_REPLACE_INFO,
GET_CHIP_ID,
GET_SINGLE_CARD_INFO,
GET_FIRMWARE_ACTIVE_STATUS,
@@ -171,7 +174,7 @@ enum driver_cmd_type {
GET_LOOPBACK_MODE = 32,
SET_LOOPBACK_MODE,
SET_LINK_MODE,
- SET_PF_BW_LIMIT,
+ SET_TX_PF_BW_LIMIT,
GET_PF_BW_LIMIT,
ROCE_CMD,
GET_POLL_WEIGHT,
@@ -189,6 +192,7 @@ enum driver_cmd_type {
GET_NIC_STATS_STRING,
GET_NIC_STATS_INFO,
GET_PF_ID,
+ GET_MBOX_CNT,
NIC_RSVD4,
NIC_RSVD5,
DCB_QOS_INFO,
@@ -205,6 +209,8 @@ enum driver_cmd_type {
RSS_INDIR,
PORT_ID,
+ SET_RX_PF_BW_LIMIT = 0x43,
+
GET_FUNC_CAP = 0x50,
GET_XSFP_PRESENT = 0x51,
GET_XSFP_INFO = 0x52,
@@ -216,6 +222,10 @@ enum driver_cmd_type {
WIN_CSR_WRITE = 0x62,
WIN_API_CMD_RD = 0x63,
+ GET_FUSION_Q = 0x64,
+
+ ROCE_CMD_BOND_HASH_TYPE_SET = 0xb2,
+
BIFUR_SET_ENABLE = 0xc0,
BIFUR_GET_ENABLE = 0xc1,
@@ -234,7 +244,8 @@ enum sm_cmd_type {
SM_CTR_RD64,
SM_CTR_RD32_CLEAR,
SM_CTR_RD64_PAIR_CLEAR,
- SM_CTR_RD64_CLEAR
+ SM_CTR_RD64_CLEAR,
+ SM_CTR_RD16_CLEAR,
};
struct cqm_stats {
@@ -321,10 +332,22 @@ struct pf_info {
};
struct card_info {
- struct pf_info pf[PF_MAX_SIZE];
+ struct pf_info pf[HINIC_PF_MAX_SIZE];
u32 pf_num;
};
+struct func_mbox_cnt_info {
+ char bus_info[BUSINFO_LEN];
+ u64 send_cnt;
+ u64 ack_cnt;
+};
+
+struct card_mbox_cnt_info {
+ struct func_mbox_cnt_info func_info[HINIC_PF_MAX_SIZE +
+ HINIC_VF_MAX_SIZE];
+ u32 func_num;
+};
+
struct hinic3_nic_loop_mode {
u32 loop_mode;
u32 loop_ctrl;
@@ -665,6 +688,162 @@ struct get_card_bond_msg_s {
struct bond_all_msg_s all_msg[MAX_BONDING_CNT_PER_CARD];
};
+#define MAX_FUSION_Q_STATS_STR_LEN 16
+#define MAX_FUSION_Q_NUM 256
+struct queue_status_s {
+ pid_t tgid;
+ char status[MAX_FUSION_Q_STATS_STR_LEN];
+};
+
+struct fusion_q_status_s {
+ u16 queue_num;
+ struct queue_status_s queue[MAX_FUSION_Q_NUM];
+};
+
+struct fusion_q_tx_hw_page {
+ u64 phy_addr;
+ u64 *map_addr;
+};
+
+struct fusion_sq_info {
+ u16 q_id;
+ u16 pi;
+ u16 ci; /* sw_ci */
+ u16 fi; /* hw_ci */
+ u32 q_depth;
+ u16 pi_reverse;
+ u16 wqebb_size;
+ u8 priority;
+ u16 *ci_addr;
+ u64 cla_addr;
+ void *slq_handle;
+ struct fusion_q_tx_hw_page direct_wqe;
+ struct fusion_q_tx_hw_page doorbell;
+ u32 page_idx;
+ u32 glb_sq_id;
+};
+
+struct fusion_q_tx_wqe {
+ u32 data[4];
+};
+
+struct fusion_rq_info {
+ u16 q_id;
+ u16 delta;
+ u16 hw_pi;
+ u16 ci; /* sw_ci */
+ u16 sw_pi;
+ u16 wqebb_size;
+ u16 q_depth;
+ u16 buf_len;
+
+ void *slq_handle;
+ u64 ci_wqe_page_addr;
+ u64 ci_cla_tbl_addr;
+
+ u8 coalesc_timer_cfg;
+ u8 pending_limt;
+ u16 msix_idx;
+ u32 msix_vector;
+};
+
+struct fusion_q_rx_wqe {
+ u32 data[8];
+};
+
+struct fusion_q_rx_cqe {
+ union {
+ struct {
+ unsigned int checksum_err : 16;
+ unsigned int lro_num : 8;
+ unsigned int rsvd1 : 7;
+ unsigned int rx_done : 1;
+ } bs;
+ unsigned int value;
+ } dw0;
+
+ union {
+ struct {
+ unsigned int vlan : 16;
+ unsigned int length : 16;
+ } bs;
+ unsigned int value;
+ } dw1;
+
+ union {
+ struct {
+ unsigned int pkt_types : 12;
+ unsigned int rsvd : 4;
+ unsigned int udp_0 : 1;
+ unsigned int ipv6_ex_add : 1;
+ unsigned int loopback : 1;
+ unsigned int umbcast : 2;
+ unsigned int vlan_offload_en : 1;
+ unsigned int tag_num : 2;
+ unsigned int rss_type : 8;
+ } bs;
+ unsigned int value;
+ } dw2;
+
+ union {
+ struct {
+ unsigned int rss_hash_value;
+ } bs;
+ unsigned int value;
+ } dw3;
+
+ union {
+ struct {
+ unsigned int tx_ts_seq : 16;
+ unsigned int message_1588_offset : 8;
+ unsigned int message_1588_type : 4;
+ unsigned int rsvd : 1;
+ unsigned int if_rx_ts : 1;
+ unsigned int if_tx_ts : 1;
+ unsigned int if_1588 : 1;
+ } bs;
+ unsigned int value;
+ } dw4;
+
+ union {
+ struct {
+ unsigned int ts;
+ } bs;
+ unsigned int value;
+ } dw5;
+
+ union {
+ struct {
+ unsigned int lro_ts;
+ } bs;
+ unsigned int value;
+ } dw6;
+
+ union {
+ struct {
+ unsigned int rsvd0;
+ } bs;
+ unsigned int value;
+ } dw7; /* 16Bytes Align */
+};
+
+struct os_hot_repalce_func_info {
+ char card_name[HINIC3_CARD_NAME_MAX_LEN];
+ u32 bus_num;
+ u32 valid;
+ u32 bdf;
+ int partition;
+ u16 backup_pf;
+ u16 pf_idx;
+ int port_id;
+};
+
+#define ALL_CARD_PF_NUM 2048 /* 64 card * 32 pf */
+struct os_hot_replace_info {
+ struct os_hot_repalce_func_info func_infos[ALL_CARD_PF_NUM];
+ u32 func_cnt;
+};
+
int alloc_buff_in(void *hwdev, struct msg_module *nt_msg, u32 in_size, void **buf_in);
int alloc_buff_out(void *hwdev, struct msg_module *nt_msg, u32 out_size, void **buf_out);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
index ea1d506..c4b3d5b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
@@ -15,6 +15,9 @@
#include <linux/ip.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#ifdef HAVE_XDP_SUPPORT
#include <linux/bpf.h>
#endif
@@ -28,6 +31,10 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
+#include "nic_npu_cmd.h"
+
+#include "vram_common.h"
+
#define HINIC3_DEFAULT_RX_CSUM_OFFLOAD 0xFFF
#define HINIC3_LRO_DEFAULT_COAL_PKT_SIZE 32
@@ -47,8 +54,62 @@ static void hinic3_nic_set_rx_mode(struct net_device *netdev)
queue_work(nic_dev->workq, &nic_dev->rx_mode_work);
}
+static void hinic3_free_irq_vram(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_dyna_txrxq_params *in_q_params)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ struct hinic3_dyna_txrxq_params q_params = nic_dev->q_params;
+
+ if (!q_params.irq_cfg)
+ return;
+
+ size = sizeof(struct hinic3_irq) * (q_params.num_qps);
+
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)q_params.irq_cfg, q_params.irq_cfg_vram_name, size);
+ q_params.irq_cfg = NULL;
+ } else {
+ kfree(in_q_params->irq_cfg);
+ in_q_params->irq_cfg = NULL;
+ }
+}
+
+static int hinic3_alloc_irq_vram(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_dyna_txrxq_params *q_params,
+ bool is_up_eth)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ u16 func_id;
+
+ size = sizeof(struct hinic3_irq) * q_params->num_qps;
+
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(q_params->irq_cfg_vram_name, VRAM_NAME_MAX_LEN,
+ "%s%hu", VRAM_NIC_IRQ_VRAM, func_id);
+ q_params->irq_cfg = (struct hinic3_irq *)hi_vram_kalloc(q_params->irq_cfg_vram_name,
+ size);
+ if (!q_params->irq_cfg) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq vram alloc failed.\n");
+ return -ENOMEM;
+ }
+ /* in order to clear napi stored in vram, irq need to init when eth up */
+ if (is_up_eth)
+ memset(q_params->irq_cfg, 0, size);
+ } else {
+ q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
+ if (!q_params->irq_cfg)
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_txrxq_params *q_params)
+ struct hinic3_dyna_txrxq_params *q_params,
+ bool is_up_eth)
{
u32 size;
int err;
@@ -70,12 +131,9 @@ static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
goto alloc_rxqs_res_arr_err;
}
- size = sizeof(*q_params->irq_cfg) * q_params->num_qps;
- q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
- if (!q_params->irq_cfg) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to alloc irq resource array\n");
- err = -ENOMEM;
+ err = hinic3_alloc_irq_vram(nic_dev, q_params, is_up_eth);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc irq resource array\n");
goto alloc_irq_cfg_err;
}
@@ -102,8 +160,7 @@ alloc_rxqs_res_err:
q_params->txqs_res);
alloc_txqs_res_err:
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ hinic3_free_irq_vram(nic_dev, q_params);
alloc_irq_cfg_err:
kfree(q_params->rxqs_res);
@@ -117,15 +174,17 @@ alloc_rxqs_res_arr_err:
}
static void hinic3_free_txrxq_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_txrxq_params *q_params)
+ struct hinic3_dyna_txrxq_params *q_params)
{
+ int is_in_kexec = vram_get_kexec_flag();
+
hinic3_free_rxqs_res(nic_dev, q_params->num_qps, q_params->rq_depth,
q_params->rxqs_res);
hinic3_free_txqs_res(nic_dev, q_params->num_qps, q_params->sq_depth,
q_params->txqs_res);
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ if (is_in_kexec == 0)
+ hinic3_free_irq_vram(nic_dev, q_params);
kfree(q_params->rxqs_res);
q_params->rxqs_res = NULL;
@@ -161,6 +220,7 @@ static int hinic3_configure_txrxqs(struct hinic3_nic_dev *nic_dev,
static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos;
if (!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
@@ -171,12 +231,13 @@ static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
num_cos = hinic3_get_dev_user_cos_num(nic_dev);
hinic3_update_qp_cos_cfg(nic_dev, num_cos);
/* For now, we don't support to change num_cos */
- if (num_cos > nic_dev->cos_config_num_max ||
+ if (num_cos > dcb->cos_config_num_max ||
nic_dev->q_params.num_qps < num_cos) {
nicif_err(nic_dev, drv, netdev, "Invalid num_cos: %u or num_qps: %u, disable DCB\n",
num_cos, nic_dev->q_params.num_qps);
nic_dev->q_params.num_cos = 0;
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
/* if we can't enable rss or get enough num_qps,
* need to sync default configure to hw
*/
@@ -190,17 +251,22 @@ static int hinic3_configure(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
- err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
- if (err) {
- nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
- return err;
+ if (is_in_kexec == 0) {
+ err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
+ return err;
+ }
}
config_dcb_qps_map(nic_dev);
/* rx rss init */
- err = hinic3_rx_configure(netdev, test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ err = hinic3_rx_configure(netdev,
+ test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)
+ ? 1 : 0);
if (err) {
nicif_err(nic_dev, drv, netdev, "Failed to configure rx\n");
return err;
@@ -256,10 +322,11 @@ static void config_dcb_num_qps(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dyna_txrxq_params *q_params,
u16 max_qps)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos = q_params->num_cos;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (!num_cos || num_cos > nic_dev->cos_config_num_max || num_cos > max_qps)
+ if (!num_cos || num_cos > dcb->cos_config_num_max || num_cos > max_qps)
return; /* will disable DCB in config_dcb_qps_map() */
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
@@ -332,57 +399,10 @@ static void hinic3_destroy_num_qps(struct hinic3_nic_dev *nic_dev)
kfree(nic_dev->qps_irq_info);
}
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev)
-{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- err = hinic3_set_port_enable(nic_dev->hwdev, false, HINIC3_CHANNEL_NIC);
- if (!err)
- nic_dev->force_port_disable = true;
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
-{
- int err = 0;
-
- down(&nic_dev->port_state_sem);
-
- nic_dev->force_port_disable = false;
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
- HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- /* Do nothing when force disable
- * Port will disable when call force port disable
- * and should not enable port when in force mode
- */
- if (nic_dev->force_port_disable) {
- up(&nic_dev->port_state_sem);
- return 0;
- }
-
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
- HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
+ return hinic3_set_port_enable(nic_dev->hwdev, enable,
+ HINIC3_CHANNEL_NIC);
}
static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
@@ -398,8 +418,8 @@ static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
}
static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+ struct hinic3_dyna_qp_params *qp_params,
+ struct hinic3_dyna_txrxq_params *trxq_params, bool is_up_eth)
{
int err;
@@ -414,7 +434,7 @@ static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
return err;
}
- err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params);
+ err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params, is_up_eth);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc txrxq resources\n");
hinic3_free_qps(nic_dev->hwdev, qp_params);
@@ -425,8 +445,8 @@ static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
}
static void hinic3_free_channel_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+ struct hinic3_dyna_qp_params *qp_params,
+ struct hinic3_dyna_txrxq_params *trxq_params)
{
mutex_lock(&nic_dev->nic_mutex);
hinic3_free_txrxq_resources(nic_dev, trxq_params);
@@ -521,7 +541,8 @@ int hinic3_vport_up(struct hinic3_nic_dev *nic_dev)
queue_delayed_work(nic_dev->workq, &nic_dev->moderation_task,
HINIC3_MODERATONE_DELAY);
if (test_bit(HINIC3_RXQ_RECOVERY, &nic_dev->flags))
- queue_delayed_work(nic_dev->workq, &nic_dev->rxq_check_work, HZ);
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->rxq_check_work, HZ);
hinic3_print_link_message(nic_dev, link_status);
@@ -542,9 +563,52 @@ vport_enable_err:
return err;
}
+static int hinic3_flush_rq_and_check(struct hinic3_nic_dev *nic_dev, u16 glb_func_id)
+{
+ struct hinic3_flush_rq *rq_flush_msg = NULL;
+ struct hinic3_cmd_buf *cmd_buf = NULL;
+ int out_buf_len = sizeof(struct hinic3_flush_rq);
+ u16 rq_id;
+ u64 out_param = 0;
+ int ret;
+
+ cmd_buf = hinic3_alloc_cmd_buf(nic_dev->hwdev);
+ if (!cmd_buf) {
+ nic_err(&nic_dev->pdev->dev, "Failed to allocate cmd buf\n");
+ return -ENOMEM;
+ }
+
+ cmd_buf->size = sizeof(struct hinic3_flush_rq);
+ rq_flush_msg = (struct hinic3_flush_rq *)cmd_buf->buf;
+ rq_flush_msg->dw.bs.func_id = glb_func_id;
+ for (rq_id = 0; rq_id < nic_dev->q_params.num_qps; rq_id++) {
+ rq_flush_msg->dw.bs.rq_id = rq_id;
+ hinic3_cpu_to_be32(rq_flush_msg, out_buf_len);
+ ret = hinic3_cmdq_direct_resp(nic_dev->hwdev, HINIC3_MOD_L2NIC,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ cmd_buf, &out_param, 0,
+ HINIC3_CHANNEL_NIC);
+ if (ret != 0 || out_param != 0) {
+ nic_err(&nic_dev->pdev->dev, "Failed to flush rq, ret:%d, func:%u, rq:%u\n",
+ ret, glb_func_id, rq_id);
+ goto err;
+ }
+ hinic3_be32_to_cpu(rq_flush_msg, out_buf_len);
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Func:%u rq_num:%u flush rq success\n",
+ glb_func_id, nic_dev->q_params.num_qps);
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return 0;
+err:
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return -1;
+}
+
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
{
u16 glb_func_id;
+ int is_in_kexec = vram_get_kexec_flag();
netif_carrier_off(nic_dev->netdev);
netif_tx_disable(nic_dev->netdev);
@@ -557,18 +621,21 @@ void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, 0);
- hinic3_maybe_set_port_state(nic_dev, false);
+ if (is_in_kexec != 0)
+ nicif_info(nic_dev, drv, nic_dev->netdev, "Skip changing mag status!\n");
+ else
+ hinic3_maybe_set_port_state(nic_dev, false);
glb_func_id = hinic3_global_func_id(nic_dev->hwdev);
hinic3_set_vport_enable(nic_dev->hwdev, glb_func_id, false,
HINIC3_CHANNEL_NIC);
hinic3_flush_txqs(nic_dev->netdev);
- /* After set vport disable 100ms,
- * no packets will be send to host
- * FPGA set 2000ms
- */
- msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+
+ if (is_in_kexec == 0)
+ msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+ else
+ (void)hinic3_flush_rq_and_check(nic_dev, glb_func_id);
hinic3_flush_qps_res(nic_dev->hwdev);
}
}
@@ -581,11 +648,12 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_qp_params new_qp_params = {0};
struct hinic3_dyna_qp_params cur_qp_params = {0};
int err;
+ bool is_free_resources = false;
hinic3_config_num_qps(nic_dev, trxq_params);
err = hinic3_alloc_channel_resources(nic_dev, &new_qp_params,
- trxq_params);
+ trxq_params, false);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc channel resources\n");
@@ -597,10 +665,19 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
hinic3_close_channel(nic_dev, &cur_qp_params);
hinic3_free_channel_resources(nic_dev, &cur_qp_params,
&nic_dev->q_params);
+ is_free_resources = true;
}
if (nic_dev->num_qp_irq > trxq_params->num_qps)
hinic3_qp_irq_change(nic_dev, trxq_params->num_qps);
+
+ if (is_free_resources) {
+ err = hinic3_alloc_irq_vram(nic_dev, trxq_params, false);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Change chl alloc irq failed\n");
+ goto alloc_irq_err;
+ }
+ }
nic_dev->q_params = *trxq_params;
if (reopen_handler)
@@ -621,7 +698,7 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
vport_up_err:
hinic3_close_channel(nic_dev, &new_qp_params);
-
+alloc_irq_err:
open_channel_err:
hinic3_free_channel_resources(nic_dev, &new_qp_params, trxq_params);
@@ -652,7 +729,7 @@ int hinic3_open(struct net_device *netdev)
}
err = hinic3_alloc_channel_resources(nic_dev, &qp_params,
- &nic_dev->q_params);
+ &nic_dev->q_params, true);
if (err)
goto alloc_channel_res_err;
@@ -691,12 +768,31 @@ setup_qps_err:
return err;
}
+static void hinic3_delete_napi(struct hinic3_nic_dev *nic_dev)
+{
+ u16 q_id;
+ int is_in_kexec = vram_get_kexec_flag();
+ struct hinic3_irq *irq_cfg = NULL;
+
+ if (is_in_kexec == 0 || !nic_dev->q_params.irq_cfg)
+ return;
+
+ for (q_id = 0; q_id < nic_dev->q_params.num_qps; q_id++) {
+ irq_cfg = &nic_dev->q_params.irq_cfg[q_id];
+ qp_del_napi(irq_cfg);
+ }
+
+ hinic3_free_irq_vram(nic_dev, &nic_dev->q_params);
+}
+
int hinic3_close(struct net_device *netdev)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic3_dyna_qp_params qp_params = {0};
if (!test_and_clear_bit(HINIC3_INTF_UP, &nic_dev->flags)) {
+ /* delete napi in os hotreplace rollback */
+ hinic3_delete_napi(nic_dev);
nicif_info(nic_dev, drv, netdev, "Netdev already close, do nothing\n");
return 0;
}
@@ -776,7 +872,8 @@ static u8 parse_ipv6_info(struct sk_buff *skb, u32 *rss_tunple,
return 0;
}
-static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb,
+static u16 select_queue_by_hash_func(struct net_device *dev,
+ struct sk_buff *skb,
unsigned int num_tx_queues)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(dev);
@@ -831,17 +928,20 @@ static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb
}
#define GET_DSCP_PRI_OFFSET 2
-static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev, struct sk_buff *skb)
+static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev,
+ struct sk_buff *skb)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int dscp_cp;
if (skb->protocol == htons(ETH_P_IP))
dscp_cp = ipv4_get_dsfield(ip_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
else if (skb->protocol == htons(ETH_P_IPV6))
- dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
+ dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >>
+ GET_DSCP_PRI_OFFSET;
else
- return nic_dev->hw_dcb_cfg.default_cos;
- return nic_dev->hw_dcb_cfg.dscp2cos[dscp_cp];
+ return dcb->hw_dcb_cfg.default_cos;
+ return dcb->hw_dcb_cfg.dscp2cos[dscp_cp];
}
#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY)
@@ -867,11 +967,13 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif /* end of HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK */
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u16 txq;
u8 cos, qp_num;
if (test_bit(HINIC3_SAME_RXTX, &nic_dev->flags))
- return select_queue_by_hash_func(netdev, skb, netdev->real_num_tx_queues);
+ return select_queue_by_hash_func(netdev, skb,
+ netdev->real_num_tx_queues);
txq =
#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY)
@@ -887,18 +989,19 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (nic_dev->hw_dcb_cfg.trust == DCB_PCP) {
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP) {
if (skb->vlan_tci)
- cos = nic_dev->hw_dcb_cfg.pcp2cos[skb->vlan_tci >> VLAN_PRIO_SHIFT];
+ cos = dcb->hw_dcb_cfg.pcp2cos[skb->vlan_tci >>
+ VLAN_PRIO_SHIFT];
else
- cos = nic_dev->hw_dcb_cfg.default_cos;
+ cos = dcb->hw_dcb_cfg.default_cos;
} else {
cos = hinic3_get_dscp_up(nic_dev, skb);
}
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cos] ?
- txq % nic_dev->hw_dcb_cfg.cos_qp_num[cos] : 0;
- txq = nic_dev->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
+ qp_num = dcb->hw_dcb_cfg.cos_qp_num[cos] ?
+ txq % dcb->hw_dcb_cfg.cos_qp_num[cos] : 0;
+ txq = dcb->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
}
return txq;
@@ -976,7 +1079,7 @@ static struct net_device_stats *hinic3_get_stats(struct net_device *netdev)
stats->rx_packets = packets;
stats->rx_bytes = bytes;
stats->rx_errors = errors;
- stats->rx_dropped = dropped;
+ stats->rx_dropped = dropped + nic_dev->vport_stats.rx_discard_vport;
#ifndef HAVE_VOID_NDO_GET_STATS64
return stats;
@@ -1023,10 +1126,18 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
u32 mtu = (u32)new_mtu;
int err = 0;
+ int is_in_kexec = vram_get_kexec_flag();
#ifdef HAVE_XDP_SUPPORT
u32 xdp_max_mtu;
+#endif
+
+ if (is_in_kexec != 0) {
+ nicif_info(nic_dev, drv, netdev, "Hotreplace skip change mtu\n");
+ return err;
+ }
+#ifdef HAVE_XDP_SUPPORT
if (hinic3_is_xdp_enable(nic_dev)) {
xdp_max_mtu = hinic3_xdp_max_mtu(nic_dev);
if (mtu > xdp_max_mtu) {
@@ -1045,6 +1156,7 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
nicif_info(nic_dev, drv, nic_dev->netdev, "Change mtu from %u to %d\n",
netdev->mtu, new_mtu);
netdev->mtu = mtu;
+ nic_dev->nic_vram->vram_mtu = mtu;
}
return err;
@@ -1078,6 +1190,76 @@ static int hinic3_set_mac_addr(struct net_device *netdev, void *addr)
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+static int hinic3_udp_tunnel_port_config(struct net_device *netdev,
+ struct udp_tunnel_info *ti,
+ u8 action)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u16 func_id = hinic3_global_func_id(nic_dev->hwdev);
+ u16 dst_port;
+ int ret = 0;
+
+ switch (ti->type) {
+ case UDP_TUNNEL_TYPE_VXLAN:
+ dst_port = ntohs(ti->port);
+ ret = hinic3_vlxan_port_config(nic_dev->hwdev,
+ func_id, dst_port, action);
+ if (ret != 0) {
+ nicif_warn(nic_dev, drv, netdev,
+ "Failed to set vxlan port %u to device\n",
+ dst_port);
+ break;
+ }
+ nicif_info(nic_dev, link, netdev, "Vxlan dst port set to %u\n",
+ action == HINIC3_CMD_OP_ADD ?
+ dst_port : ntohs(VXLAN_OFFLOAD_PORT_LE));
+ break;
+ default:
+ nicif_err(nic_dev, drv, netdev, "Failed to add port, only vxlan dst port is supported\n");
+ ret = -EINVAL;
+ }
+ return ret;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+static void hinic3_udp_tunnel_add(struct net_device *netdev,
+ struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+static void hinic3_udp_tunnel_del(struct net_device *netdev,
+ struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD */
+
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev,
+ __always_unused unsigned int table,
+ __always_unused unsigned int entry,
+ struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev,
+ __always_unused unsigned int table,
+ __always_unused unsigned int entry,
+ struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static int
hinic3_vlan_rx_add_vid(struct net_device *netdev,
__always_unused __be16 proto,
@@ -1124,7 +1306,7 @@ hinic3_vlan_rx_kill_vid(struct net_device *netdev,
int err = 0;
col = VID_COL(nic_dev, vid);
- line = VID_LINE(nic_dev, vid);
+ line = (int)VID_LINE(nic_dev, vid);
/* In the broadcast scenario, ucode finds the corresponding function
* based on VLAN 0 of vlan table. If we delete VLAN 0, the VLAN function
@@ -1163,14 +1345,12 @@ static int hinic3_vlan_restore(struct net_device *netdev)
return -EFAULT;
rcu_read_lock();
for (i = 0; i < VLAN_N_VID; i++) {
-/* lint -e778 */
#ifdef HAVE_VLAN_FIND_DEV_DEEP_RCU
vlandev =
__vlan_find_dev_deep_rcu(netdev, htons(ETH_P_8021Q), i);
#else
vlandev = __vlan_find_dev_deep(netdev, htons(ETH_P_8021Q), i);
#endif
-/* lint +e778 */
col = VID_COL(nic_dev, i);
line = VID_LINE(nic_dev, i);
if (!vlandev && (vlan_bitmap[line] & (1UL << col)) != 0) {
@@ -1328,12 +1508,17 @@ static int set_feature_vlan_filter(struct hinic3_nic_dev *nic_dev,
return 0;
#ifdef NEED_VLAN_RESTORE
- if (en)
+ if (en) {
err = hinic3_vlan_restore(nic_dev->netdev);
+ if (err) {
+ hinic3_err(nic_dev, drv, "vlan restore failed\n");
+ *failed_features |= vlan_filter_feature;
+ return err;
+ }
+ }
#endif
- if (err == 0)
- err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
+ err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
if (err) {
hinic3_err(nic_dev, drv, "%s rx vlan filter failed\n",
SET_FEATURES_OP_STR(en));
@@ -1427,8 +1612,8 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
struct hinic3_nic_dev *adapter = netdev_priv(netdev);
int err;
- if (is_multicast_ether_addr(mac) || /*lint !e574*/
- vf >= pci_num_vf(adapter->pdev)) /*lint !e574*/
+ if (is_multicast_ether_addr(mac) ||
+ vf >= pci_num_vf(adapter->pdev))
return -EINVAL;
err = hinic3_set_vf_mac(adapter->hwdev, OS_VF_ID_TO_HW(vf), mac);
@@ -1446,7 +1631,6 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
return 0;
}
-/*lint -save -e574 -e734*/
#ifdef IFLA_VF_MAX
static int set_hw_vf_vlan(void *hwdev, u16 cur_vlanprio, int vf,
u16 vlan, u8 qos)
@@ -1529,7 +1713,8 @@ static int hinic3_ndo_set_vf_spoofchk(struct net_device *netdev, int vf,
#endif
#ifdef HAVE_NDO_SET_VF_TRUST
-static int hinic3_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting)
+static int hinic3_ndo_set_vf_trust(struct net_device *netdev, int vf,
+ bool setting)
{
struct hinic3_nic_dev *adapter = netdev_priv(netdev);
int err;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
index 11c1731..d8c5419 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
@@ -10,6 +10,8 @@
#include "hinic3_common.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
/* ************************ array index define ********************* */
#define ARRAY_INDEX_0 0
@@ -21,6 +23,35 @@
#define ARRAY_INDEX_6 6
#define ARRAY_INDEX_7 7
+#define XSFP_TLV_PRE_INFO_LEN 4
+
+enum hinic3_link_port_type {
+ LINK_PORT_UNKNOWN,
+ LINK_PORT_OPTICAL_MM,
+ LINK_PORT_OPTICAL_SM,
+ LINK_PORT_PAS_COPPER,
+ LINK_PORT_ACC,
+ LINK_PORT_BASET,
+ LINK_PORT_AOC = 0x40,
+ LINK_PORT_ELECTRIC,
+ LINK_PORT_BACKBOARD_INTERFACE,
+};
+
+enum hilink_fibre_subtype {
+ FIBRE_SUBTYPE_SR = 1,
+ FIBRE_SUBTYPE_LR,
+ FIBRE_SUBTYPE_MAX,
+};
+
+enum hilink_fec_type {
+ HILINK_FEC_NOT_SET,
+ HILINK_FEC_RSFEC,
+ HILINK_FEC_BASEFEC,
+ HILINK_FEC_NOFEC,
+ HILINK_FEC_LLRSFE,
+ HILINK_FEC_MAX_TYPE,
+};
+
#define SQ_CI_ADDR_SHIFT 2
#define RQ_CI_ADDR_SHIFT 4
@@ -71,6 +102,12 @@ struct hinic3_port_routine_cmd {
struct mag_cmd_get_xsfp_present abs;
};
+struct hinic3_port_routine_cmd_extern {
+ bool mpu_send_xsfp_tlv_info;
+
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp std_xsfp_tlv_info;
+};
+
struct hinic3_nic_cfg {
struct semaphore cfg_lock;
@@ -84,11 +121,13 @@ struct hinic3_nic_cfg {
struct nic_port_info port_info;
/* percentage of pf link bandwidth */
- u32 pf_bw_limit;
- u32 rsvd2;
+ u32 pf_bw_tx_limit;
+ u32 pf_bw_rx_limit;
- struct hinic3_port_routine_cmd rt_cmd;
- struct mutex sfp_mutex; /* mutex used for copy sfp info */
+ struct hinic3_port_routine_cmd rt_cmd;
+ struct hinic3_port_routine_cmd_extern rt_cmd_ext;
+ /* mutex used for copy sfp info */
+ struct mutex sfp_mutex;
};
struct hinic3_nic_cmdq_ops;
@@ -98,7 +137,7 @@ struct hinic3_nic_io {
void *dev_hdl;
u8 link_status;
- u8 rsvd1;
+ u8 direct;
u32 rsvd2;
struct hinic3_io_queue *sq;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
index 747ac03..fc3c90a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
@@ -21,11 +21,133 @@
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_nic_cmdq.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_common.h"
#include "hinic3_nic_cfg.h"
-int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_sq_attr *attr)
+#include "vram_common.h"
+
+int hinic3_delete_bond(void *hwdev)
+{
+ struct hinic3_cmd_delete_bond cmd_delete_bond;
+ u16 out_size = sizeof(cmd_delete_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_delete_bond, 0, sizeof(cmd_delete_bond));
+ cmd_delete_bond.bond_id = HINIC3_INVALID_BOND_ID;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_DELETE,
+ &cmd_delete_bond, sizeof(cmd_delete_bond),
+ &cmd_delete_bond, &out_size);
+ if (err || !out_size || cmd_delete_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to delete bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_delete_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_delete_bond.bond_id != HINIC3_INVALID_BOND_ID)
+ nic_info(nic_io->dev_hdl, "Delete bond success\n");
+
+ return 0;
+}
+
+int hinic3_open_close_bond(void *hwdev, u32 bond_en)
+{
+ struct hinic3_cmd_open_close_bond cmd_open_close_bond;
+ u16 out_size = sizeof(cmd_open_close_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_open_close_bond, 0, sizeof(cmd_open_close_bond));
+ cmd_open_close_bond.open_close_bond_info.bond_id =
+ HINIC3_INVALID_BOND_ID;
+ cmd_open_close_bond.open_close_bond_info.open_close_flag = bond_en;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_OPEN_CLOSE,
+ &cmd_open_close_bond,
+ sizeof(cmd_open_close_bond),
+ &cmd_open_close_bond, &out_size);
+ if (err || !out_size || cmd_open_close_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to %s bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ bond_en ? "open" : "close", err,
+ cmd_open_close_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_open_close_bond.open_close_bond_info.bond_id !=
+ HINIC3_INVALID_BOND_ID) {
+ nic_info(nic_io->dev_hdl, "%s bond success\n",
+ bond_en ? "Open" : "Close");
+ }
+
+ return 0;
+}
+
+int hinic3_create_bond(void *hwdev, u32 *bond_id)
+{
+ struct hinic3_cmd_create_bond cmd_create_bond;
+ u16 out_size = sizeof(cmd_create_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_create_bond, 0, sizeof(cmd_create_bond));
+ cmd_create_bond.create_bond_info.default_param_flag = true;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_CREATE,
+ &cmd_create_bond, sizeof(cmd_create_bond),
+ &cmd_create_bond, &out_size);
+ if (err || !out_size || cmd_create_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to create default bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_create_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_create_bond.create_bond_info.bond_id !=
+ HINIC3_INVALID_BOND_ID) {
+ *bond_id = cmd_create_bond.create_bond_info.bond_id;
+ nic_info(nic_io->dev_hdl, "Create bond success\n");
+ }
+
+ return 0;
+}
+
+int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io,
+ struct hinic3_sq_attr *attr)
{
struct hinic3_cmd_cons_idx_attr cons_idx_attr;
u16 out_size = sizeof(cons_idx_attr);
@@ -48,7 +170,8 @@ int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_sq_attr *at
cons_idx_attr.l2nic_sqn = attr->l2nic_sqn;
cons_idx_attr.ci_addr = attr->ci_dma_base >> SQ_CI_ADDR_SHIFT;
- err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_SQ_CI_ATTR_SET,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC3_NIC_CMD_SQ_CI_ATTR_SET,
&cons_idx_attr, sizeof(cons_idx_attr),
&cons_idx_attr, &out_size);
if (err || !out_size || cons_idx_attr.msg_head.status) {
@@ -61,7 +184,8 @@ int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_sq_attr *at
return 0;
}
-int hinic3_set_rq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_rq_attr *attr)
+int hinic3_set_rq_ci_ctx(struct hinic3_nic_io *nic_io,
+ struct hinic3_rq_attr *attr)
{
struct hinic3_rq_cqe_ctx cons_idx_ctx;
u16 out_size = sizeof(cons_idx_ctx);
@@ -76,15 +200,19 @@ int hinic3_set_rq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_rq_attr *at
cons_idx_ctx.timer_loop = attr->coalescing_time;
cons_idx_ctx.threshold_cqe_num = attr->pending_limit;
cons_idx_ctx.msix_entry_idx = attr->intr_idx;
- cons_idx_ctx.ci_addr_hi = upper_32_bits(attr->ci_dma_base >> RQ_CI_ADDR_SHIFT);
- cons_idx_ctx.ci_addr_lo = lower_32_bits(attr->ci_dma_base >> RQ_CI_ADDR_SHIFT);
+ cons_idx_ctx.ci_addr_hi = upper_32_bits(attr->ci_dma_base >>
+ RQ_CI_ADDR_SHIFT);
+ cons_idx_ctx.ci_addr_lo = lower_32_bits(attr->ci_dma_base >>
+ RQ_CI_ADDR_SHIFT);
- err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_SET_RQ_CI_CTX,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC3_NIC_CMD_SET_RQ_CI_CTX,
&cons_idx_ctx, sizeof(cons_idx_ctx),
&cons_idx_ctx, &out_size);
if (err || !out_size || cons_idx_ctx.msg_head.status) {
nic_err(nic_io->dev_hdl, "Set rq cqe ctx fail, qid: %d, err: %d, status: 0x%x, out_size: 0x%x",
- attr->l2nic_rqn, err, cons_idx_ctx.msg_head.status, out_size);
+ attr->l2nic_rqn, err,
+ cons_idx_ctx.msg_head.status, out_size);
return -EFAULT;
}
@@ -142,8 +270,8 @@ int hinic3_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
&mac_info, sizeof(mac_info),
&mac_info, &out_size, channel);
if (err || !out_size ||
- hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
- mac_info.vlan_id)) {
+ (hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
+ mac_info.vlan_id) != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, mac_info.msg_head.status, out_size, channel);
@@ -178,6 +306,8 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -193,7 +323,8 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
&mac_info, sizeof(mac_info), &mac_info,
&out_size, channel);
if (err || !out_size ||
- (mac_info.msg_head.status && !PF_SET_VF_MAC(hwdev, mac_info.msg_head.status))) {
+ (mac_info.msg_head.status &&
+ !PF_SET_VF_MAC(hwdev, mac_info.msg_head.status))) {
nic_err(nic_io->dev_hdl,
"Failed to delete MAC, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, mac_info.msg_head.status, out_size, channel);
@@ -223,6 +354,8 @@ int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -239,8 +372,8 @@ int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
&mac_info, sizeof(mac_info),
&mac_info, &out_size);
if (err || !out_size ||
- hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
- mac_info.vlan_id)) {
+ (hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
+ mac_info.vlan_id) != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x\n",
err, mac_info.msg_head.status, out_size);
@@ -273,6 +406,8 @@ int hinic3_get_default_mac(void *hwdev, u8 *mac_addr)
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
mac_info.func_id = hinic3_global_func_id(hwdev);
@@ -318,6 +453,45 @@ static int hinic3_config_vlan(struct hinic3_nic_io *nic_io, u8 opcode,
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action)
+{
+ struct hinic3_cmd_vxlan_port_info vxlan_port_info;
+ u16 out_size = sizeof(vxlan_port_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ memset(&vxlan_port_info, 0, sizeof(vxlan_port_info));
+ vxlan_port_info.opcode = action;
+ vxlan_port_info.cfg_mode = 0; // other tool set
+ vxlan_port_info.func_id = func_id;
+ vxlan_port_info.vxlan_port = port;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+ &vxlan_port_info, sizeof(vxlan_port_info),
+ &vxlan_port_info, &out_size);
+ if (err || !out_size || vxlan_port_info.msg_head.status) {
+ if (vxlan_port_info.msg_head.status == 0x2) // other tool set failed
+ nic_warn(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port because it has already been set by hinicadm\n",
+ action == HINIC3_CMD_OP_ADD
+ ? "add" : "delete");
+ else
+ nic_err(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port, err: %d, status: 0x%x, out size: 0x%x\n",
+ action == HINIC3_CMD_OP_ADD ? "add" : "delete",
+ err, vxlan_port_info.msg_head.status, out_size);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
{
struct hinic3_nic_io *nic_io = NULL;
@@ -326,6 +500,8 @@ int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan_id, func_id);
}
@@ -337,6 +513,8 @@ int hinic3_del_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_DEL, vlan_id, func_id);
}
@@ -380,6 +558,8 @@ int hinic3_set_dcb_state(void *hwdev, struct hinic3_dcb_state *dcb_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (!memcmp(&nic_io->dcb_state, dcb_state, sizeof(nic_io->dcb_state)))
return 0;
@@ -423,7 +603,8 @@ int hinic3_get_cos_by_pri(void *hwdev, u8 pri, u8 *cos)
if (pri >= NIC_DCB_UP_MAX && nic_io->dcb_state.trust == HINIC3_DCB_PCP)
return -EINVAL;
- if (pri >= NIC_DCB_IP_PRI_MAX && nic_io->dcb_state.trust == HINIC3_DCB_DSCP)
+ if (pri >= NIC_DCB_IP_PRI_MAX &&
+ nic_io->dcb_state.trust == HINIC3_DCB_DSCP)
return -EINVAL;
/*lint -e662*/
@@ -541,13 +722,15 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_cfg = &nic_io->nic_cfg;
down(&nic_cfg->cfg_lock);
err = hinic3_cfg_hw_pause(nic_io, HINIC3_CMD_OP_SET, &nic_pause);
- if (err) {
+ if (err != 0) {
up(&nic_cfg->cfg_lock);
return err;
}
@@ -566,7 +749,6 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
{
- struct hinic3_nic_cfg *nic_cfg = NULL;
struct hinic3_nic_io *nic_io = NULL;
int err = 0;
@@ -574,17 +756,13 @@ int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- nic_cfg = &nic_io->nic_cfg;
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_hw_pause(nic_io, HINIC3_CMD_OP_GET, nic_pause);
- if (err)
+ if (err != 0)
return err;
- if (nic_cfg->pause_set || !nic_pause->auto_neg) {
- nic_pause->rx_pause = nic_cfg->nic_pause.rx_pause;
- nic_pause->tx_pause = nic_cfg->nic_pause.tx_pause;
- }
-
return 0;
}
@@ -599,6 +777,8 @@ int hinic3_sync_dcb_state(void *hwdev, u8 op_code, u8 state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&dcb_state, 0, sizeof(dcb_state));
@@ -607,7 +787,8 @@ int hinic3_sync_dcb_state(void *hwdev, u8 op_code, u8 state)
dcb_state.func_id = hinic3_global_func_id(hwdev);
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_QOS_DCB_STATE,
- &dcb_state, sizeof(dcb_state), &dcb_state, &out_size);
+ &dcb_state, sizeof(dcb_state),
+ &dcb_state, &out_size);
if (err || dcb_state.head.status || !out_size) {
nic_err(nic_io->dev_hdl,
"Failed to set dcb state, err: %d, status: 0x%x, out size: 0x%x\n",
@@ -675,7 +856,8 @@ int hinic3_cache_out_qps_res(void *hwdev)
qp_res.func_id = hinic3_global_func_id(hwdev);
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
- &qp_res, sizeof(qp_res), &qp_res, &out_size);
+ &qp_res, sizeof(qp_res),
+ &qp_res, &out_size);
if (err || !out_size || qp_res.msg_head.status) {
nic_err(nic_io->dev_hdl, "Failed to cache out qp resources, err: %d, status: 0x%x, out size: 0x%x\n",
err, qp_res.msg_head.status, out_size);
@@ -685,45 +867,8 @@ int hinic3_cache_out_qps_res(void *hwdev)
return 0;
}
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats)
-{
- struct hinic3_port_stats *port_stats = NULL;
- struct hinic3_port_stats_info stats_info;
- u16 out_size = sizeof(*port_stats);
- struct hinic3_nic_io *nic_io = NULL;
- int err;
-
- port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
- if (!port_stats)
- return -ENOMEM;
-
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
-
- memset(&stats_info, 0, sizeof(stats_info));
-
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_PORT_STAT,
- &stats_info, sizeof(stats_info),
- port_stats, &out_size);
- if (err || !out_size || port_stats->msg_head.status) {
- nic_err(nic_io->dev_hdl,
- "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
- err, port_stats->msg_head.status, out_size);
- err = -EIO;
- goto out;
- }
-
- memcpy(stats, &port_stats->stats, sizeof(*stats));
-
-out:
- kfree(port_stats);
-
- return err;
-}
-EXPORT_SYMBOL(hinic3_get_fpga_phy_port_stats);
-
-int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *stats)
+int hinic3_get_vport_stats(void *hwdev, u16 func_id,
+ struct hinic3_vport_stats *stats)
{
struct hinic3_port_stats_info stats_info;
struct hinic3_cmd_vport_stats vport_stats;
@@ -738,6 +883,8 @@ int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *
memset(&vport_stats, 0, sizeof(vport_stats));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
stats_info.func_id = func_id;
@@ -756,7 +903,8 @@ int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *
return 0;
}
-static int hinic3_set_function_table(struct hinic3_nic_io *nic_io, u32 cfg_bitmap,
+static int hinic3_set_function_table(struct hinic3_nic_io *nic_io,
+ u32 cfg_bitmap,
const struct hinic3_func_tbl_cfg *cfg)
{
struct hinic3_cmd_set_func_tbl cmd_func_tbl;
@@ -804,6 +952,8 @@ int hinic3_set_port_mtu(void *hwdev, u16 new_mtu)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (new_mtu < HINIC3_MIN_MTU_SIZE) {
nic_err(nic_io->dev_hdl,
@@ -834,6 +984,8 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&feature_nego, 0, sizeof(feature_nego));
feature_nego.func_id = hinic3_global_func_id(hwdev);
feature_nego.opcode = opcode;
@@ -855,29 +1007,24 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return 0;
}
-static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
+static int hinic3_get_bios_pf_bw_tx_limit(void *hwdev,
+ struct hinic3_nic_io *nic_io,
+ u16 func_id, u32 *pf_rate)
{
- struct hinic3_nic_io *nic_io = NULL;
+ int err = 0; // default success
struct nic_cmd_bios_cfg cfg = {{0}};
u16 out_size = sizeof(cfg);
- int err;
-
- if (!hwdev || !pf_bw_limit)
- return -EINVAL;
-
- if (hinic3_func_type(hwdev) == TYPE_VF || !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
- return 0;
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- cfg.bios_cfg.func_id = (u8)hinic3_global_func_id(hwdev);
+ cfg.bios_cfg.func_id = (u8)func_id;
cfg.bios_cfg.func_valid = 1;
- cfg.op_code = 0 | NIC_NVM_DATA_PF_SPEED_LIMIT;
+ cfg.op_code = 0 | NIC_NVM_DATA_PF_TX_SPEED_LIMIT;
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BIOS_CFG, &cfg, sizeof(cfg),
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BIOS_CFG,
+ &cfg, sizeof(cfg),
&cfg, &out_size);
if (err || !out_size || cfg.head.status) {
nic_err(nic_io->dev_hdl,
- "Failed to get bios pf bandwidth limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ "Failed to get bios pf bandwidth tx limit, err: %d, status: 0x%x, out size: 0x%x\n",
err, cfg.head.status, out_size);
return -EIO;
}
@@ -887,13 +1034,86 @@ static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
nic_warn(nic_io->dev_hdl, "Invalid bios configuration data, signature: 0x%x\n",
cfg.bios_cfg.signature);
- if (cfg.bios_cfg.pf_bw > MAX_LIMIT_BW) {
+ if (cfg.bios_cfg.pf_tx_bw > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
+ cfg.bios_cfg.pf_tx_bw);
+ return -EINVAL;
+ }
+
+ (*pf_rate) = cfg.bios_cfg.pf_tx_bw;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_rx_limit(void *hwdev,
+ struct hinic3_nic_io *nic_io,
+ u16 func_id, u32 *pf_rate)
+{
+ int err = 0; // default success
+ struct nic_rx_rate_bios_cfg rx_bios_conf = {{0}};
+ u16 out_size = sizeof(rx_bios_conf);
+
+ rx_bios_conf.func_id = (u8)func_id;
+ rx_bios_conf.op_code = 0; /* 1-save, 0-read */
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_RX_RATE_CFG,
+ &rx_bios_conf, sizeof(rx_bios_conf),
+ &rx_bios_conf, &out_size);
+ if (rx_bios_conf.msg_head.status == HINIC3_MGMT_CMD_UNSUPPORTED &&
+ err == 0) { // Compatible older firmware
+ nic_warn(nic_io->dev_hdl, "Not support get bios pf bandwidth rx limit\n");
+ return 0;
+ } else if (err || !out_size || rx_bios_conf.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get bios pf bandwidth rx limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, rx_bios_conf.msg_head.status, out_size);
+ return -EIO;
+ }
+ if (rx_bios_conf.rx_rate_limit > MAX_LIMIT_BW) {
nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
- cfg.bios_cfg.pf_bw);
+ rx_bios_conf.rx_rate_limit);
return -EINVAL;
}
- *pf_bw_limit = cfg.bios_cfg.pf_bw;
+ (*pf_rate) = rx_bios_conf.rx_rate_limit;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit, u8 direct)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u32 pf_rate = 0;
+ int err = 0;
+ u16 func_id;
+
+ func_id = hinic3_global_func_id(hwdev);
+
+ if (!hwdev || !pf_bw_limit)
+ return -EINVAL;
+
+ if (hinic3_func_type(hwdev) == TYPE_VF ||
+ !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
+ return 0;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (direct == HINIC3_NIC_TX)
+ err = hinic3_get_bios_pf_bw_tx_limit(hwdev, nic_io,
+ func_id, &pf_rate);
+ else if (direct == HINIC3_NIC_RX)
+ err = hinic3_get_bios_pf_bw_rx_limit(hwdev, nic_io,
+ func_id, &pf_rate);
+
+ if (err != 0)
+ return err;
+
+ if (pf_rate > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl,
+ "Invalid bios cfg pf bandwidth limit: %u\n", pf_rate);
+ return -EINVAL;
+ }
+
+ *pf_bw_limit = pf_rate;
return 0;
}
@@ -902,8 +1122,9 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
{
struct hinic3_cmd_tx_rate_cfg rate_cfg = {{0}};
struct hinic3_nic_io *nic_io = NULL;
+ u32 rate_limit;
u16 out_size = sizeof(rate_cfg);
- u32 pf_rate;
+ u32 pf_rate = 0;
int err;
u32 speed_convert[PORT_SPEED_UNKNOWN] = {
0, 10, 100, 1000, 10000, 25000, 40000, 50000, 100000, 200000
@@ -914,15 +1135,16 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
return -EINVAL;
if (speed_level >= PORT_SPEED_UNKNOWN) {
- nic_err(nic_io->dev_hdl, "Invalid speed level: %u\n", speed_level);
+ nic_err(nic_io->dev_hdl,
+ "Invalid speed level: %u\n", speed_level);
return -EINVAL;
}
- if (nic_io->nic_cfg.pf_bw_limit == MAX_LIMIT_BW) {
- pf_rate = 0;
- } else {
+ rate_limit = (nic_io->direct == HINIC3_NIC_TX) ?
+ nic_io->nic_cfg.pf_bw_tx_limit : nic_io->nic_cfg.pf_bw_rx_limit;
+ if (rate_limit != MAX_LIMIT_BW) {
/* divided by 100 to convert to percentage */
- pf_rate = (speed_convert[speed_level] / 100) * nic_io->nic_cfg.pf_bw_limit;
+ pf_rate = (speed_convert[speed_level] / 100) * rate_limit;
/* bandwidth limit is very small but not unlimit in this case */
if (pf_rate == 0 && speed_level != PORT_SPEED_NOT_SET)
pf_rate = 1;
@@ -931,13 +1153,16 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
rate_cfg.func_id = hinic3_global_func_id(hwdev);
rate_cfg.min_rate = 0;
rate_cfg.max_rate = pf_rate;
+ rate_cfg.direct = nic_io->direct;
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_MAX_MIN_RATE, &rate_cfg,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
+ &rate_cfg,
sizeof(rate_cfg), &rate_cfg, &out_size);
if (err || !out_size || rate_cfg.msg_head.status) {
nic_err(nic_io->dev_hdl, "Failed to set rate(%u), err: %d, status: 0x%x, out size: 0x%x\n",
pf_rate, err, rate_cfg.msg_head.status, out_size);
- return rate_cfg.msg_head.status ? rate_cfg.msg_head.status : -EIO;
+ return rate_cfg.msg_head.status
+ ? rate_cfg.msg_head.status : -EIO;
}
return 0;
@@ -954,7 +1179,8 @@ int hinic3_set_nic_feature_to_hw(void *hwdev)
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- return nic_feature_nego(hwdev, HINIC3_CMD_OP_SET, &nic_io->feature_cap, 1);
+ return nic_feature_nego(hwdev, HINIC3_CMD_OP_SET,
+ &nic_io->feature_cap, 1);
}
u64 hinic3_get_feature_cap(void *hwdev)
@@ -962,6 +1188,8 @@ u64 hinic3_get_feature_cap(void *hwdev)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
return nic_io->feature_cap;
}
@@ -971,12 +1199,17 @@ void hinic3_update_nic_feature(void *hwdev, u64 s_feature)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
nic_io->feature_cap = s_feature;
- nic_info(nic_io->dev_hdl, "Update nic feature to 0x%llx\n", nic_io->feature_cap);
+ nic_info(nic_io->dev_hdl,
+ "Update nic feature to 0x%llx\n",
+ nic_io->feature_cap);
}
-static inline int init_nic_hwdev_param_valid(const void *hwdev, const void *pcidev_hdl,
+static inline int init_nic_hwdev_param_valid(const void *hwdev,
+ const void *pcidev_hdl,
const void *dev_hdl)
{
if (!hwdev || !pcidev_hdl || !dev_hdl)
@@ -1004,6 +1237,7 @@ static int hinic3_init_nic_io(void *hwdev, void *pcidev_hdl, void *dev_hdl,
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_abs = false;
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_info = false;
+ (*nic_io)->nic_cfg.rt_cmd_ext.mpu_send_xsfp_tlv_info = false;
return 0;
}
@@ -1020,27 +1254,34 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
{
struct hinic3_nic_io *nic_io = NULL;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
err = hinic3_init_nic_io(hwdev, pcidev_hdl, dev_hdl, &nic_io);
- if (err)
+ if (err != 0)
return err;
+ nic_io->rx_buff_len = rx_buff_len;
+
err = hinic3_register_service_adapter(hwdev, nic_io, SERVICE_T_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to register service adapter\n");
goto register_sa_err;
}
- err = hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 1, HINIC3_CHANNEL_NIC);
- if (err) {
+ err = hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC,
+ 1, HINIC3_CHANNEL_NIC);
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set function svc used state\n");
goto set_used_state_err;
}
- err = hinic3_init_function_table(nic_io);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to init function table\n");
- goto err_out;
+ if (is_in_kexec == 0) {
+ err = hinic3_init_function_table(nic_io);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to init function table\n");
+ goto err_out;
+ }
}
err = hinic3_get_nic_feature_from_hw(hwdev, &nic_io->feature_cap, 1);
@@ -1052,24 +1293,35 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
sdk_info(dev_hdl, "nic features: 0x%llx\n", nic_io->feature_cap);
hinic3_nic_cmdq_adapt_init(nic_io);
- err = hinic3_get_bios_pf_bw_limit(hwdev, &nic_io->nic_cfg.pf_bw_limit);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to get pf bandwidth limit\n");
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_tx_limit,
+ HINIC3_NIC_TX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf tx bandwidth limit\n");
+ goto err_out;
+ }
+
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_rx_limit,
+ HINIC3_NIC_RX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf rx bandwidth limit\n");
goto err_out;
}
err = hinic3_vf_func_init(nic_io);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to init vf info\n");
goto err_out;
}
- nic_io->rx_buff_len = rx_buff_len;
-
return 0;
err_out:
- hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 0, HINIC3_CHANNEL_NIC);
+ if (hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC,
+ 0, HINIC3_CHANNEL_NIC) != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to set function svc used state\n");
+ }
set_used_state_err:
hinic3_unregister_service_adapter(hwdev, SERVICE_T_NIC);
@@ -1119,6 +1371,8 @@ int hinic3_force_drop_tx_pkt(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&pkt_drop, 0, sizeof(pkt_drop));
pkt_drop.port = hinic3_physical_port_id(hwdev);
@@ -1147,6 +1401,8 @@ int hinic3_set_rx_mode(void *hwdev, u32 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&rx_mode_cfg, 0, sizeof(rx_mode_cfg));
rx_mode_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1175,6 +1431,8 @@ int hinic3_set_rx_vlan_offload(void *hwdev, u8 en)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_cfg, 0, sizeof(vlan_cfg));
vlan_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1192,7 +1450,8 @@ int hinic3_set_rx_vlan_offload(void *hwdev, u8 en)
return 0;
}
-int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
+int hinic3_update_mac_vlan(void *hwdev, const u16 old_vlan,
+ u16 new_vlan, int vf_id)
{
struct vf_data_storage *vf_info = NULL;
struct hinic3_nic_io *nic_io = NULL;
@@ -1203,6 +1462,8 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
if (!nic_io->vf_infos || is_zero_ether_addr(vf_info->drv_mac_addr))
return 0;
@@ -1211,7 +1472,7 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
err = hinic3_del_mac(nic_io->hwdev, vf_info->drv_mac_addr,
old_vlan, func_id, HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to delete VF %d MAC %pM vlan %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->drv_mac_addr, old_vlan);
return err;
@@ -1219,7 +1480,7 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
err = hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
new_vlan, func_id, HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to add VF %d MAC %pM vlan %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->drv_mac_addr, new_vlan);
hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
@@ -1242,6 +1503,8 @@ static int hinic3_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en,
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_cfg, 0, sizeof(lro_cfg));
lro_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1273,6 +1536,8 @@ static int hinic3_set_rx_lro_timer(void *hwdev, u32 timer_value)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_timer, 0, sizeof(lro_timer));
lro_timer.opcode = HINIC3_CMD_OP_SET;
@@ -1305,12 +1570,14 @@ int hinic3_set_rx_lro_state(void *hwdev, u8 lro_en, u32 lro_timer,
ipv6_en = lro_en ? 1 : 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_info(nic_io->dev_hdl, "Set LRO max coalesce packet size to %uK\n",
lro_max_pkt_len);
err = hinic3_set_rx_lro(hwdev, ipv4_en, ipv6_en, (u8)lro_max_pkt_len);
- if (err)
+ if (err != 0)
return err;
/* we don't set LRO timer for VF */
@@ -1333,6 +1600,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_filter, 0, sizeof(vlan_filter));
vlan_filter.func_id = hinic3_global_func_id(hwdev);
@@ -1352,7 +1621,6 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
{
- // struct hinic_hwdev *dev = hwdev;
struct nic_cmd_capture_info cap_info = {{0}};
u16 out_size = sizeof(cap_info);
int err;
@@ -1361,7 +1629,6 @@ int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
return -EINVAL;
/* 2 function capture types */
- // cap_info.op_type = UP_UCAPTURE_OP_TYPE_FUNC;
cap_info.is_en_trx = cap_en;
cap_info.func_port = func_id;
@@ -1386,6 +1653,8 @@ int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (tcam_rule->index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to add is invalid\n");
return -EINVAL;
@@ -1421,6 +1690,8 @@ int hinic3_del_tcam_rule(void *hwdev, u32 index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to del is invalid\n");
return -EINVAL;
@@ -1470,6 +1741,8 @@ static int hinic3_mgmt_tcam_block(void *hwdev, u8 alloc_en, u16 *index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&tcam_block_info, 0,
sizeof(struct nic_cmd_ctrl_tcam_block_out));
@@ -1515,6 +1788,8 @@ int hinic3_set_fdir_tcam_rule_filter(void *hwdev, bool enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
port_tcam_cmd.func_id = hinic3_global_func_id(hwdev);
port_tcam_cmd.tcam_enable = (u8)enable;
@@ -1543,6 +1818,8 @@ int hinic3_flush_tcam_rule(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&tcam_flush, 0, sizeof(struct nic_cmd_flush_tcam_rules));
tcam_flush.func_id = hinic3_global_func_id(hwdev);
@@ -1560,7 +1837,8 @@ int hinic3_flush_tcam_rule(void *hwdev)
return 0;
}
-int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type)
+int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info,
+ u16 num_qps, u16 wqe_type)
{
struct hinic3_cmd_buf *cmd_buf = NULL;
struct hinic3_nic_io *nic_io = NULL;
@@ -1573,6 +1851,8 @@ int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -1587,9 +1867,11 @@ int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
cmd_buf->size = sizeof(struct hinic3_rxq_hw);
- err = hinic3_cmdq_detail_resp(hwdev, HINIC3_MOD_L2NIC, HINIC3_UCODE_CMD_RXQ_INFO_GET,
- cmd_buf, cmd_buf, NULL, 0, HINIC3_CHANNEL_NIC);
- if (err)
+ err = hinic3_cmdq_detail_resp(hwdev, HINIC3_MOD_L2NIC,
+ HINIC3_UCODE_CMD_RXQ_INFO_GET,
+ cmd_buf, cmd_buf, NULL, 0,
+ HINIC3_CHANNEL_NIC);
+ if (err != 0)
goto get_rxq_info_failed;
rxq_info_out = cmd_buf->buf;
@@ -1604,7 +1886,8 @@ get_rxq_info_failed:
return err;
}
-int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_state)
+int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced,
+ bool link_state)
{
struct hinic3_nic_io *nic_io = NULL;
struct vf_data_storage *vf_infos = NULL;
@@ -1615,8 +1898,10 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return -EINVAL;
}
- if (hinic3_func_type(hwdev) == TYPE_VF)
+ if (hinic3_func_type(hwdev) == TYPE_VF) {
+ pr_err("VF are not supported to set link state.\n");
return -EINVAL;
+ }
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
if (!nic_io) {
@@ -1633,3 +1918,35 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return 0;
}
EXPORT_SYMBOL(hinic3_pf_set_vf_link_state);
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid)
+{
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ u16 out_size = sizeof(outband_cfg_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !outband_default_vid)
+ return -EINVAL;
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_OUTBAND_CFG,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size);
+ if (err || !out_size || outband_cfg_info.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get outband cfg, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, outband_cfg_info.msg_head.status, out_size);
+ return -EINVAL;
+ }
+
+ *outband_default_vid = outband_cfg_info.outband_default_vid;
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
index dd2c2fd..60caf68 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
@@ -7,9 +7,10 @@
#include <linux/types.h>
#include <linux/netdevice.h>
-#include "hinic3_mgmt_interface.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
+#include "nic_cfg_comm.h"
+#include "nic_mpu_cmd_defs.h"
#define OS_VF_ID_TO_HW(os_vf_id) ((os_vf_id) + 1)
#define HW_VF_ID_TO_OS(hw_vf_id) ((hw_vf_id) - 1)
@@ -54,6 +55,8 @@
#define MAX_LIMIT_BW 100
+#define HINIC3_INVALID_BOND_ID 0xffffffff
+
enum hinic3_valid_link_settings {
HILINK_LINK_SET_SPEED = 0x1,
HILINK_LINK_SET_AUTONEG = 0x2,
@@ -67,6 +70,11 @@ enum hinic3_link_follow_status {
HINIC3_LINK_FOLLOW_STATUS_MAX,
};
+enum hinic3_nic_pf_direct {
+ HINIC3_NIC_RX = 0,
+ HINIC3_NIC_TX,
+};
+
struct hinic3_link_ksettings {
u32 valid_bitmap;
u8 speed; /* enum nic_speed_level */
@@ -152,8 +160,12 @@ struct nic_port_info {
u8 duplex;
u8 speed;
u8 fec;
+ u8 lanes;
+ u8 rsvd;
u32 supported_mode;
u32 advertised_mode;
+ u32 supported_fec_mode;
+ u32 bond_speed;
};
struct nic_pause_config {
@@ -178,11 +190,17 @@ struct hinic3_rxq_hw {
#define MODULE_TYPE_QSFP28 0x11
#define MODULE_TYPE_QSFP 0x0C
#define MODULE_TYPE_QSFP_PLUS 0x0D
+#define MODULE_TYPE_DSFP 0x1B
+#define MODULE_TYPE_QSFP_CMIS 0x1E
#define TCAM_IP_TYPE_MASK 0x1
#define TCAM_TUNNEL_TYPE_MASK 0xF
#define TCAM_FUNC_ID_MASK 0x7FFF
+int hinic3_delete_bond(void *hwdev);
+int hinic3_open_close_bond(void *hwdev, u32 bond_en);
+int hinic3_create_bond(void *hwdev, u32 *bond_id);
+
int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule);
int hinic3_del_tcam_rule(void *hwdev, u32 index);
@@ -335,7 +353,7 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr);
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr);
/* *
* @brief hinic3_vf_info_vlanprio - get vf vlan priority
@@ -510,7 +528,14 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table);
*/
int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats);
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats);
+/* *
+ * @brief hinic3_get_phy_rsfec_stats - get rsfec stats
+ * @param hwdev: device pointer to hwdev
+ * @param stats: rsfec(Reed-Solomon Forward Error Correction) stats
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats);
int hinic3_set_port_funcs_state(void *hwdev, bool enable);
@@ -546,6 +571,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl);
void hinic3_clear_vfs_info(void *hwdev);
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id);
+
int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id);
int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
@@ -565,9 +592,13 @@ int hinic3_set_autoneg(void *hwdev, bool enable);
int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext);
int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len);
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len);
bool hinic3_if_sfp_absent(void *hwdev);
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info);
+int hinic3_get_sfp_tlv_info(void *hwdev,
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info,
+ const struct tag_mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req);
/* *
* @brief hinic3_set_nic_feature_to_hw - sync nic feature to hardware
@@ -620,4 +651,19 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level);
int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type);
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+/* *
+ * @brief hinic3_vlxan_port_config - add/del vxlan dst port
+ * @param hwdev: device pointer to hwdev
+ * @param func_id: function id
+ * @param port: vxlan dst port
+ * @param action: add or del, del will set to default value (0x12B5)
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action);
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
index 15d081b..c0e0a61 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
@@ -22,7 +22,8 @@
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_nic_cmdq.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
/*lint -e806*/
static unsigned char set_vf_link_state;
@@ -59,7 +60,8 @@ static int hinic3_set_vlan_ctx(struct hinic3_nic_io *nic_io, u16 func_id,
vlan_tag, q_id, vlan_mode);
err = hinic3_cmdq_direct_resp(nic_io->hwdev, HINIC3_MOD_L2NIC,
- cmd, cmd_buf, &out_param, 0, HINIC3_CHANNEL_NIC);
+ cmd, cmd_buf, &out_param,
+ 0, HINIC3_CHANNEL_NIC);
hinic3_free_cmd_buf(nic_io->hwdev, cmd_buf);
@@ -108,7 +110,7 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
err = hinic3_set_vlan_ctx(nic_io, glb_func_id, vlan_tag,
NIC_CONFIG_ALL_QUEUE_VLAN_CTX,
opcode == HINIC3_CMD_OP_ADD);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d vlan ctx, err: %d\n",
HW_VF_ID_TO_OS(vf_id), err);
@@ -129,12 +131,15 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
/* this function just be called by hinic3_ndo_set_vf_mac,
* others are not permitted.
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr)
{
- struct vf_data_storage *vf_info;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_info = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
#ifndef __VMWARE__
/* duplicate request, so just return success */
@@ -152,13 +157,15 @@ int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan, qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan = vlan;
@@ -172,17 +179,19 @@ int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
vf_infos = nic_io->vf_infos;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_DEL,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_info(nic_io->dev_hdl, "Remove VLAN %u on VF %d\n",
@@ -197,11 +206,13 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
u16 hinic3_vf_info_vlanprio(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
u16 pf_vlan, vlanprio;
u8 pf_qos;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
pf_vlan = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan;
pf_qos = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos;
@@ -214,9 +225,14 @@ int hinic3_set_vf_link_state(void *hwdev, u16 vf_id, int link)
{
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ struct vf_data_storage *vf_infos = NULL;
u8 link_status = 0;
+ if (!nic_io)
+ return -EINVAL;
+
+ vf_infos = nic_io->vf_infos;
+
switch (link) {
case HINIC3_IFLA_VF_LINK_STATE_AUTO:
vf_infos[HW_VF_ID_TO_OS(vf_id)].link_forced = false;
@@ -256,6 +272,8 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
vf_infos = nic_io->vf_infos;
memset(&spoofchk_cfg, 0, sizeof(spoofchk_cfg));
@@ -280,9 +298,11 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
bool hinic3_vf_info_spoofchk(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].spoofchk;
}
@@ -296,7 +316,7 @@ int hinic3_set_vf_trust(void *hwdev, u16 vf_id, bool trust)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
+ if (!nic_io || vf_id > nic_io->max_vfs)
return -EINVAL;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust = trust;
@@ -309,11 +329,11 @@ bool hinic3_get_vf_trust(void *hwdev, int vf_id)
struct hinic3_nic_io *nic_io = NULL;
if (!hwdev)
- return -EINVAL;
+ return false;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
- return -EINVAL;
+ if (!nic_io || vf_id > nic_io->max_vfs)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust;
}
@@ -331,6 +351,7 @@ static int hinic3_set_vf_tx_rate_max_min(struct hinic3_nic_io *nic_io,
rate_cfg.func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf_id;
rate_cfg.max_rate = max_rate;
rate_cfg.min_rate = min_rate;
+ rate_cfg.direct = HINIC3_NIC_TX;
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
&rate_cfg, sizeof(rate_cfg), &rate_cfg,
@@ -351,13 +372,15 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (!HINIC3_SUPPORT_RATE_LIMIT(hwdev)) {
nic_err(nic_io->dev_hdl, "Current function doesn't support to set vf rate limit\n");
return -EOPNOTSUPP;
}
err = hinic3_set_vf_tx_rate_max_min(nic_io, vf_id, max_rate, min_rate);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].max_rate = max_rate;
@@ -368,12 +391,16 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
void hinic3_get_vf_config(void *hwdev, u16 vf_id, struct ifla_vf_info *ivi)
{
- struct vf_data_storage *vfinfo;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vfinfo = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
vfinfo = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vfinfo)
+ return;
ivi->vf = HW_VF_ID_TO_OS(vf_id);
ether_addr_copy(ivi->mac, vfinfo->user_mac_addr);
@@ -446,13 +473,15 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
int err;
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
- nic_io->hwdev, hinic3_vf_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_vf_event_handler);
+ if (err != 0)
return err;
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
- nic_io->hwdev, hinic3_vf_mag_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_vf_mag_event_handler);
+ if (err != 0)
goto reg_hilink_err;
memset(®ister_info, 0, sizeof(register_info));
@@ -464,6 +493,11 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
®ister_info, &out_size, 0,
HINIC3_CHANNEL_NIC);
if (err || !out_size || register_info.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev)) {
+ nic_warn(nic_io->dev_hdl, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, register_info.msg_head.status, out_size);
+ return 0;
+ }
nic_err(nic_io->dev_hdl, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
err, register_info.msg_head.status, out_size);
err = -EIO;
@@ -498,18 +532,20 @@ static int pf_init_vf_infos(struct hinic3_nic_io *nic_io)
for (i = 0; i < nic_io->max_vfs; i++) {
err = hinic3_init_vf_infos(nic_io, i);
- if (err)
+ if (err != 0)
goto init_vf_infos_err;
}
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
- nic_io->hwdev, hinic3_pf_mbox_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_mbox_handler);
+ if (err != 0)
goto register_pf_mbox_cb_err;
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
- nic_io->hwdev, hinic3_pf_mag_mbox_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_mag_mbox_handler);
+ if (err != 0)
goto register_pf_mag_mbox_cb_err;
return 0;
@@ -531,17 +567,19 @@ int hinic3_vf_func_init(struct hinic3_nic_io *nic_io)
return vf_func_register(nic_io);
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
- nic_io->hwdev, hinic3_pf_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_event_handler);
+ if (err != 0)
return err;
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
- nic_io->hwdev, hinic3_pf_mag_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_mag_event_handler);
+ if (err != 0)
goto register_mgmt_msg_cb_err;
err = pf_init_vf_infos(nic_io);
- if (err)
+ if (err != 0)
goto pf_init_vf_infos_err;
return 0;
@@ -568,17 +606,24 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
&unregister, sizeof(unregister),
&unregister, &out_size, 0,
HINIC3_CHANNEL_NIC);
- if (err || !out_size || unregister.msg_head.status)
- nic_err(nic_io->dev_hdl, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
- err, unregister.msg_head.status, out_size);
-
+ if (err || !out_size || unregister.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev)) {
+ nic_info(nic_io->dev_hdl, "vRoCE VF notify PF unsuccessful is allowed");
+ } else {
+ nic_err(nic_io->dev_hdl, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, unregister.msg_head.status, out_size);
+ }
+ }
hinic3_unregister_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
} else {
if (nic_io->vf_infos) {
- hinic3_unregister_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK);
- hinic3_unregister_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
+ hinic3_unregister_pf_mbox_cb(nic_io->hwdev,
+ HINIC3_MOD_HILINK);
+ hinic3_unregister_pf_mbox_cb(nic_io->hwdev,
+ HINIC3_MOD_L2NIC);
hinic3_clear_vfs_info(nic_io->hwdev);
kfree(nic_io->vf_infos);
+ nic_io->vf_infos = NULL;
}
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
@@ -587,11 +632,15 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
static void clear_vf_infos(void *hwdev, u16 vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
u16 func_id;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
func_id = hinic3_glb_pf_vf_offset(hwdev) + vf_id;
vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
@@ -620,10 +669,59 @@ static void clear_vf_infos(void *hwdev, u16 vf_id)
void hinic3_clear_vfs_info(void *hwdev)
{
+ u16 i;
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- u16 i;
+
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
for (i = 0; i < nic_io->max_vfs; i++)
clear_vf_infos(hwdev, OS_VF_ID_TO_HW(i));
}
+
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id)
+{
+ int err = 0;
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ struct vf_data_storage *vf_infos = NULL;
+ u16 out_size = sizeof(outband_cfg_info);
+ u16 vf_id;
+ struct hinic3_nic_io *nic_io =
+ hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return 0;
+ }
+
+ vf_id = func_id - hinic3_glb_pf_vf_offset(nic_io->hwdev);
+ vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+ if (vf_infos->registered) {
+ outband_cfg_info.func_id = func_id;
+ outband_cfg_info.outband_default_vid = vlan_id;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_L2NIC,
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return 0;
+ }
+ if (err || !out_size || outband_cfg_info.msg_head.status)
+ nic_err(nic_io->dev_hdl,
+ "outband cfg event to VF %d failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err,
+ outband_cfg_info.msg_head.status, out_size);
+ }
+
+ return err;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
index 0ec4b32..b45c875 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
@@ -30,6 +30,8 @@ int hinic3_dbg_get_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (q_id >= nic_io->num_qps) {
pr_err("q_id[%u] > num_qps_cfg[%u].\n", q_id, nic_io->num_qps);
return -EINVAL;
@@ -69,6 +71,8 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -82,6 +86,8 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
sq = &nic_io->sq[q_id];
+ if (!sq)
+ return -EINVAL;
sq_info->q_id = q_id;
sq_info->pi = hinic3_get_sq_local_pi(sq);
@@ -112,6 +118,8 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -125,6 +133,8 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
rq = &nic_io->rq[q_id];
+ if (!rq)
+ return -EINVAL;
rq_info->q_id = q_id;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
index e76a66b..c219452 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
@@ -15,9 +15,10 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
#include "hinic3_dcb.h"
+#include "vram_common.h"
#define HINIC3_NIC_DRV_NAME "hinic3"
-#define HINIC3_NIC_DRV_VERSION HINIC3_DRV_VERSION
+#define HINIC3_NIC_DRV_VERSION "17.7.8.1"
#define HINIC3_FUNC_IS_VF(hwdev) (hinic3_func_type(hwdev) == TYPE_VF)
@@ -25,6 +26,10 @@
#define HINIC3_MODERATONE_DELAY HZ
#define LP_PKT_CNT 64
+#define LP_PKT_LEN 60
+
+#define NAPI_IS_REGIN 1
+#define NAPI_NOT_REGIN 0
enum hinic3_flags {
HINIC3_INTF_UP,
@@ -91,6 +96,8 @@ struct hinic3_irq {
u16 rsvd1;
u32 irq_id; /* The IRQ number from OS */
+ u32 napi_reign;
+
char irq_name[IFNAMSIZ + 16];
struct napi_struct napi;
cpumask_t affinity_mask;
@@ -123,6 +130,41 @@ struct hinic3_dyna_txrxq_params {
struct hinic3_dyna_txq_res *txqs_res;
struct hinic3_dyna_rxq_res *rxqs_res;
struct hinic3_irq *irq_cfg;
+ char irq_cfg_vram_name[VRAM_NAME_MAX_LEN];
+};
+
+struct hinic3_flush_rq {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 lb_proc : 1;
+ u32 rsvd : 10;
+ u32 rq_id : 8;
+ u32 func_id : 13;
+#else
+ u32 func_id : 13;
+ u32 rq_id : 8;
+ u32 rsvd : 10;
+ u32 lb_proc : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd2 : 2;
+ u32 src_chnl : 12;
+ u32 pkt_len : 18;
+#else
+ u32 pkt_len : 18;
+ u32 src_chnl : 12;
+ u32 rsvd2 : 2;
+#endif
+ } bs;
+ u32 value;
+ } lb_info0; /* loop back information, used by uCode */
};
#define HINIC3_NIC_STATS_INC(nic_dev, field) \
@@ -147,6 +189,10 @@ struct hinic3_nic_stats {
#endif
};
+struct hinic3_nic_vport_stats {
+ u64 rx_discard_vport;
+};
+
#define HINIC3_TCAM_DYNAMIC_BLOCK_SIZE 16
#define HINIC3_MAX_TCAM_FILTERS 512
@@ -185,6 +231,28 @@ struct hinic3_tcam_info {
struct hinic3_tcam_dynamic_block_info tcam_dynamic_info;
};
+struct hinic3_dcb {
+ u8 cos_config_num_max;
+ u8 func_dft_cos_bitmap;
+ /* used to tool validity check */
+ u16 port_dft_cos_bitmap;
+
+ struct hinic3_dcb_config hw_dcb_cfg;
+ struct hinic3_dcb_config wanted_dcb_cfg;
+ unsigned long dcb_flags;
+};
+
+struct hinic3_vram {
+ u32 vram_mtu;
+ u16 vram_num_qps;
+ unsigned long flags;
+};
+
+struct hinic3_outband_cfg {
+ u16 outband_default_vid;
+ u16 rsvd;
+};
+
struct hinic3_nic_dev {
struct pci_dev *pdev;
struct net_device *netdev;
@@ -204,6 +272,7 @@ struct hinic3_nic_dev {
u32 dma_rx_buff_size;
u16 rx_buff_len;
u32 page_order;
+ bool page_pool_enabled;
/* Rss related varibles */
u8 rss_hash_engine;
@@ -213,17 +282,13 @@ struct hinic3_nic_dev {
u32 *rss_hkey_be;
u32 *rss_indir;
- u8 cos_config_num_max;
- u8 func_dft_cos_bitmap;
- u16 port_dft_cos_bitmap; /* used to tool validity check */
+ struct hinic3_dcb *dcb;
+ char dcb_name[VRAM_NAME_MAX_LEN];
+
+ struct hinic3_vram *nic_vram;
+ char nic_vram_name[VRAM_NAME_MAX_LEN];
- struct hinic3_dcb_config hw_dcb_cfg;
- struct hinic3_dcb_config wanted_dcb_cfg;
- struct hinic3_dcb_config dcb_cfg;
- unsigned long dcb_flags;
int disable_port_cnt;
- /* lock for disable or enable traffic flow */
- struct semaphore dcb_sem;
struct hinic3_intr_coal_info *intr_coalesce;
unsigned long last_moder_jiffies;
@@ -235,11 +300,10 @@ struct hinic3_nic_dev {
#endif
struct hinic3_nic_stats stats;
+ struct hinic3_nic_vport_stats vport_stats;
/* lock for nic resource */
struct mutex nic_mutex;
- bool force_port_disable;
- struct semaphore port_state_sem;
u8 link_status;
struct nic_service_cap nic_cap;
@@ -281,9 +345,10 @@ struct hinic3_nic_dev {
struct hinic3_nic_prof_attr *prof_attr;
struct hinic3_prof_adapter *prof_adap;
u64 rsvd8[7];
- u32 rsvd9;
+ struct hinic3_outband_cfg outband_cfg;
u32 rxq_get_err_times;
struct delayed_work rxq_check_work;
+ struct delayed_work vport_stats_work;
struct hinic3_tx_rx_ops tx_rx_ops;
};
@@ -312,7 +377,7 @@ struct hinic3_uld_info *get_nic_uld_info(void);
u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev);
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
int hinic3_open(struct net_device *netdev);
@@ -331,6 +396,8 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev);
void hinic3_qps_irq_deinit(struct hinic3_nic_dev *nic_dev);
+void qp_del_napi(struct hinic3_irq *irq_cfg);
+
void hinic3_set_netdev_ops(struct hinic3_nic_dev *nic_dev);
bool hinic3_is_netdev_ops_match(const struct net_device *netdev);
@@ -348,10 +415,6 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
int hinic3_get_sset_count(struct net_device *netdev, int sset);
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev);
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
#ifdef ETHTOOL_GLINKSETTINGS
@@ -386,5 +449,18 @@ bool hinic3_is_xdp_enable(struct hinic3_nic_dev *nic_dev);
int hinic3_xdp_max_mtu(struct hinic3_nic_dev *nic_dev);
#endif
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry,
+ struct udp_tunnel_info *ti);
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+int set_fecparam(void *hwdev, u8 fecparam);
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec);
+#endif
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
index 57cf07c..87b5aa6 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
@@ -21,11 +21,12 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
{
- struct vf_data_storage *vf_info;
+ struct vf_data_storage *vf_info = NULL;
u16 func_id;
int err = 0;
@@ -38,7 +39,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
vf_info->pf_vlan, func_id,
HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d MAC\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -51,7 +52,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD,
vf_info->pf_vlan, vf_info->pf_qos,
vf_id);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to add VF %d VLAN_QOS\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -62,7 +63,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_vf_tx_rate(nic_io->hwdev, vf_id,
vf_info->max_rate,
vf_info->min_rate);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d max rate %u, min rate %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->max_rate,
vf_info->min_rate);
@@ -84,7 +85,7 @@ static int register_vf_msg_handler(struct hinic3_nic_io *nic_io, u16 vf_id)
}
err = hinic3_init_vf_config(nic_io, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].registered = true;
@@ -137,6 +138,9 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
int err;
+ if (!vf_info)
+ return -EINVAL;
+
if (register_vf->op_register) {
vf_info->support_extra_feature = register_vf->support_extra_feature;
err = register_vf_msg_handler(nic_io, vf_id);
@@ -145,7 +149,7 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
vf_info->support_extra_feature = 0;
}
- if (err)
+ if (err != 0)
register_info->msg_head.status = EFAULT;
*out_size = sizeof(*register_info);
@@ -157,6 +161,8 @@ void hinic3_unregister_vf(struct hinic3_nic_io *nic_io, u16 vf_id)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vf_info)
+ return;
unregister_vf_msg_handler(nic_io, vf_id);
vf_info->support_extra_feature = 0;
}
@@ -181,14 +187,21 @@ static int hinic3_get_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
void *buf_out, u16 *out_size)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf);
+ struct hinic3_port_mac_set *mac_in =
+ (struct hinic3_port_mac_set *)buf_in;
struct hinic3_port_mac_set *mac_info = buf_out;
int err;
+ if (!mac_info || !vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (HINIC3_SUPPORT_VF_MAC(nic_io->hwdev)) {
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_GET_MAC, buf_in,
in_size, buf_out, out_size);
- if (!err) {
+ if (err == 0) {
if (is_zero_ether_addr(mac_info->mac))
ether_addr_copy(mac_info->mac, vf_info->drv_mac_addr);
}
@@ -211,6 +224,11 @@ static int hinic3_set_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -247,6 +265,10 @@ static int hinic3_del_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -283,10 +305,13 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
struct hinic3_port_mac_update *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
if (!is_valid_ether_addr(mac_in->new_mac)) {
nic_err(nic_io->dev_hdl, "Update VF MAC is invalid.\n");
return -EINVAL;
}
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
#ifndef __VMWARE__
if (vf_info->use_specified_mac && !vf_info->trust) {
@@ -301,7 +326,7 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
HW_VF_ID_TO_OS(vf),
HINIC_CFG_VF_MAC_CHANGED,
(void *)mac_in->new_mac);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to config VF %d MAC request, err: %d\n",
HW_VF_ID_TO_OS(vf), err);
return err;
@@ -359,10 +384,11 @@ static int _l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u16 in_size, void *buf_out, u16 *out_size,
u16 channel)
{
- u32 i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
+ int i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_cmd_handler[i].cmd)
cmd_to_pf = true;
@@ -397,13 +423,15 @@ int hinic3_pf_mbox_handler(void *hwdev,
u16 vf_id, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- u32 index, cmd_size = ARRAY_LEN(vf_cmd_handler);
+ int index, cmd_size = ARRAY_LEN(vf_cmd_handler);
struct hinic3_nic_io *nic_io = NULL;
if (!hwdev)
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (index = 0; index < cmd_size; index++) {
if (cmd == vf_cmd_handler[index].cmd)
@@ -460,10 +488,14 @@ void hinic3_notify_dcb_state_event(struct hinic3_nic_io *nic_io,
static void dcb_state_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- struct hinic3_cmd_vf_dcb_state *vf_dcb;
- struct hinic3_nic_io *nic_io;
+ struct hinic3_cmd_vf_dcb_state *vf_dcb = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
vf_dcb = buf_in;
if (!vf_dcb)
@@ -479,6 +511,10 @@ static void tx_pause_excp_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*excp_info)) {
nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
@@ -501,6 +537,10 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_event_info event_info = {0};
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*active_info)) {
nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
@@ -515,6 +555,36 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
hinic3_event_callback(nic_io->hwdev, &event_info);
}
+static void outband_vlan_cfg_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out,
+ u16 *out_size)
+{
+ struct hinic3_outband_cfg_info *outband_cfg_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info = {0};
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ nic_info(nic_io->dev_hdl, "outband vlan cfg event received\n");
+
+ if (in_size != sizeof(*outband_cfg_info)) {
+ nic_err(nic_io->dev_hdl, "outband cfg info invalid in_size: %u, should be %lu\n",
+ in_size, sizeof(*outband_cfg_info));
+ return;
+ }
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = EVENT_NIC_OUTBAND_CFG;
+ memcpy((void *)event_info.event_data,
+ outband_cfg_info, sizeof(*outband_cfg_info));
+
+ hinic3_event_callback(nic_io->hwdev, &event_info);
+}
+
static const struct nic_event_handler nic_cmd_handler[] = {
{
.cmd = HINIC3_NIC_CMD_VF_COS,
@@ -529,6 +599,11 @@ static const struct nic_event_handler nic_cmd_handler[] = {
.cmd = HINIC3_NIC_CMD_BOND_ACTIVE_NOTICE,
.handler = bond_active_event_handler,
},
+
+ {
+ .cmd = HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ .handler = outband_vlan_cfg_event_handler,
+ },
};
static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
@@ -543,6 +618,8 @@ static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (i = 0; i < size; i++) {
if (cmd == nic_cmd_handler[i].cmd) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
index a827f44..f3bb4c5 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
@@ -16,9 +16,10 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
-#include "hinic3_nic_io.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_nic_cmdq.h"
+#include "hinic3_nic_io.h"
#define HINIC3_DEAULT_TX_CI_PENDING_LIMIT 1
#define HINIC3_DEAULT_TX_CI_COALESCING_TIME 1
@@ -35,7 +36,7 @@ MODULE_PARM_DESC(tx_coalescing_time, "TX CI coalescing parameter coalescing_time
static unsigned char rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
module_param(rq_wqe_type, byte, 0444);
-MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 0-8Bytes, 1-16Bytes, 2-32Bytes (default=1)");
+MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 1-16Bytes, 2-32Bytes (default=2)");
/*lint +e806*/
static u32 tx_drop_thd_on = HINIC3_DEAULT_DROP_THD_ON;
@@ -46,7 +47,7 @@ static u32 tx_drop_thd_off = HINIC3_DEAULT_DROP_THD_OFF;
module_param(tx_drop_thd_off, uint, 0644);
MODULE_PARM_DESC(tx_drop_thd_off, "TX parameter drop_thd_off (default=0)");
/* performance: ci addr RTE_CACHE_SIZE(64B) alignment */
-#define HINIC3_CI_Q_ADDR_SIZE (64)
+#define HINIC3_CI_Q_ADDR_SIZE (64U)
#define CI_TABLE_SIZE(num_qps, pg_sz) \
(ALIGN((num_qps) * HINIC3_CI_Q_ADDR_SIZE, pg_sz))
@@ -255,7 +256,7 @@ static int hinic3_create_sq(struct hinic3_nic_io *nic_io, struct hinic3_io_queue
err = hinic3_wq_create(nic_io->hwdev, &sq->wq, sq_depth,
(u16)BIT(HINIC3_SQ_WQEBB_SHIFT));
- if (err) {
+ if (err != 0) {
sdk_err(nic_io->dev_hdl, "Failed to create tx queue(%u) wq\n",
q_id);
return err;
@@ -291,13 +292,22 @@ static int hinic3_create_rq(struct hinic3_nic_io *nic_io, struct hinic3_io_queue
{
int err;
- rq->wqe_type = (u8)(hinic3_get_rq_wqe_type(nic_io->hwdev));
+ /* rq_wqe_type Only support type 1-16Bytes, 2-32Bytes */
+ if (rq_wqe_type != HINIC3_NORMAL_RQ_WQE &&
+ rq_wqe_type != HINIC3_EXTEND_RQ_WQE) {
+ sdk_warn(nic_io->dev_hdl, "Module Parameter rq_wqe_type value %d is out of range: [%d, %d].",
+ rq_wqe_type, HINIC3_NORMAL_RQ_WQE,
+ HINIC3_EXTEND_RQ_WQE);
+ rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
+ }
+
+ rq->wqe_type = rq_wqe_type;
rq->q_id = q_id;
rq->msix_entry_idx = rq_msix_idx;
err = hinic3_wq_create(nic_io->hwdev, &rq->wq, rq_depth,
(u16)BIT(HINIC3_RQ_WQEBB_SHIFT + rq->wqe_type));
- if (err) {
+ if (err != 0) {
sdk_err(nic_io->dev_hdl, "Failed to create rx queue(%u) wq\n",
q_id);
return err;
@@ -318,14 +328,14 @@ static int create_qp(struct hinic3_nic_io *nic_io, struct hinic3_io_queue *sq,
int err;
err = hinic3_create_sq(nic_io, sq, q_id, sq_depth, qp_msix_idx);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to create sq, qid: %u\n",
q_id);
return err;
}
err = hinic3_create_rq(nic_io, rq, q_id, rq_depth, qp_msix_idx);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to create rq, qid: %u\n",
q_id);
goto create_rq_err;
@@ -364,14 +374,14 @@ int hinic3_init_nicio_res(void *hwdev)
nic_io->max_qps = hinic3_func_max_qnum(hwdev);
err = hinic3_alloc_db_addr(hwdev, &db_base, NULL);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to allocate doorbell for sqs\n");
goto alloc_sq_db_fail;
}
nic_io->sqs_db_addr = (u8 *)db_base;
err = hinic3_alloc_db_addr(hwdev, &db_base, NULL);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to allocate doorbell for rqs\n");
goto alloc_rq_db_fail;
}
@@ -474,7 +484,7 @@ int hinic3_alloc_qps(void *hwdev, struct irq_info *qps_msix_arry,
for (q_id = 0; q_id < num_qps; q_id++) {
err = create_qp(nic_io, &sqs[q_id], &rqs[q_id], q_id, qp_params->sq_depth,
qp_params->rq_depth, qps_msix_arry[q_id].msix_entry_idx);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to allocate qp %u, err: %d\n", q_id, err);
goto create_qp_err;
}
@@ -599,14 +609,14 @@ int hinic3_create_qps(void *hwdev, u16 num_qp, u32 sq_depth, u32 rq_depth,
}
err = hinic3_init_nicio_res(hwdev);
- if (err)
+ if (err != 0)
return err;
qp_params.num_qps = num_qp;
qp_params.sq_depth = sq_depth;
qp_params.rq_depth = rq_depth;
err = hinic3_alloc_qps(hwdev, qps_msix_arry, &qp_params);
- if (err) {
+ if (err != 0) {
hinic3_deinit_nicio_res(hwdev);
nic_err(nic_io->dev_hdl,
"Failed to allocate qps, err: %d\n", err);
@@ -906,11 +916,11 @@ static int init_qp_ctxts(struct hinic3_nic_io *nic_io)
int err;
err = init_sq_ctxts(nic_io);
- if (err)
+ if (err != 0)
return err;
err = init_rq_ctxts(nic_io);
- if (err)
+ if (err != 0)
return err;
return 0;
@@ -1026,14 +1036,14 @@ int hinic3_init_qp_ctxts(void *hwdev)
return -EFAULT;
err = init_qp_ctxts(nic_io);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to init QP ctxts\n");
return err;
}
/* clean LRO/TSO context space */
err = clean_qp_offload_ctxt(nic_io);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to clean qp offload ctxts\n");
return err;
}
@@ -1042,13 +1052,13 @@ int hinic3_init_qp_ctxts(void *hwdev)
err = hinic3_set_root_ctxt(hwdev, rq_depth, nic_io->sq[0].wq.q_depth,
nic_io->rx_buff_len, HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set root context\n");
return err;
}
err = init_sq_ci_ctxts(nic_io);
- if (err)
+ if (err != 0)
goto clean_root_ctxt;
if (HINIC3_SUPPORT_RX_COMPACT_CQE(hwdev)) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
index 37f923d..c5e02ad 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
@@ -317,7 +317,7 @@ static inline void hinic3_write_db(struct hinic3_io_queue *queue, int cos,
wmb(); /* Write all before the doorbell */
- writeq(*((u64 *)&db), DB_ADDR(queue, pi));
+ writeq(*((u64 *)(u8 *)&db), DB_ADDR(queue, pi));
}
struct hinic3_dyna_qp_params {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
index 78d943d..9ea93a0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
@@ -32,7 +32,7 @@ struct hinic3_prof_adapter nic_prof_adap_objs[] = {
void hinic3_init_nic_prof_adapter(struct hinic3_nic_dev *nic_dev)
{
- u16 num_adap = ARRAY_SIZE(nic_prof_adap_objs);
+ int num_adap = ARRAY_LEN(nic_prof_adap_objs);
nic_dev->prof_adap = hinic3_prof_init(nic_dev, nic_prof_adap_objs, num_adap,
(void *)&nic_dev->prof_attr);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
index 6302fb8..dc4bb9e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
@@ -430,7 +430,8 @@ hinic3_dynamic_lookup_tcam_filter(struct hinic3_nic_dev *nic_dev,
list_for_each_entry(tmp,
&tcam_info->tcam_dynamic_info.tcam_dynamic_list,
block_list)
- if (tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)
+ if (tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE ||
+ !tmp)
break;
if (!tmp || tmp->dynamic_index_cnt >= HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) {
@@ -512,7 +513,7 @@ static int hinic3_add_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, queue: %d, tcam_rule_nums: %d succeed\n",
+ "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, queue: %u, tcam_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev),
tcam_filter->dynamic_block_id, index, fdir_tcam_rule->index,
fdir_tcam_rule->data.qid, tcam_info->tcam_rule_nums + 1);
@@ -579,7 +580,7 @@ static int hinic3_del_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, local_rules_nums: %d, global_rule_nums: %d succeed\n",
+ "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, local_rules_nums: %u, global_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev), dynamic_block_id,
tcam_filter->index, index, tmp->dynamic_index_cnt - 1,
tcam_info->tcam_rule_nums - 1);
@@ -605,7 +606,7 @@ static inline struct hinic3_tcam_filter *
hinic3_tcam_filter_lookup(const struct list_head *filter_list,
struct tag_tcam_key *key)
{
- struct hinic3_tcam_filter *iter;
+ struct hinic3_tcam_filter *iter = NULL;
list_for_each_entry(iter, filter_list, tcam_filter_list) {
if (memcmp(key, &iter->tcam_key,
@@ -630,7 +631,7 @@ static int hinic3_remove_one_rule(struct hinic3_nic_dev *nic_dev,
struct hinic3_ethtool_rx_flow_rule *eth_rule)
{
struct hinic3_tcam_info *tcam_info = &nic_dev->tcam;
- struct hinic3_tcam_filter *tcam_filter;
+ struct hinic3_tcam_filter *tcam_filter = NULL;
struct nic_tcam_cfg_rule fdir_tcam_rule;
struct tag_tcam_key tcam_key;
int err;
@@ -751,7 +752,7 @@ static int validate_flow(struct hinic3_nic_dev *nic_dev,
{
if (fs->location >= MAX_NUM_OF_ETHTOOL_NTUPLE_RULES) {
nicif_err(nic_dev, drv, nic_dev->netdev, "loc exceed limit[0,%lu]\n",
- MAX_NUM_OF_ETHTOOL_NTUPLE_RULES);
+ MAX_NUM_OF_ETHTOOL_NTUPLE_RULES - 1);
return -EINVAL;
}
@@ -872,7 +873,7 @@ int hinic3_ethtool_get_flow(const struct hinic3_nic_dev *nic_dev,
int hinic3_ethtool_get_all_flows(const struct hinic3_nic_dev *nic_dev,
struct ethtool_rxnfc *info, u32 *rule_locs)
{
- int idx = 0;
+ u32 idx = 0;
struct hinic3_ethtool_rx_flow_rule *eth_rule = NULL;
if (!HINIC3_SUPPORT_FDIR(nic_dev->hwdev)) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h b/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
index a93f3b6..9202218 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
@@ -38,13 +38,12 @@ struct hinic3_prof_adapter {
#define LLT_STATIC_DEF_SAVED
#endif
-/*lint -save -e661 */
static inline struct hinic3_prof_adapter *
hinic3_prof_init(void *device, struct hinic3_prof_adapter *adap_objs, int num_adap,
void **prof_attr)
{
struct hinic3_prof_adapter *prof_obj = NULL;
- u16 i;
+ int i;
for (i = 0; i < num_adap; i++) {
prof_obj = &adap_objs[i];
@@ -68,7 +67,6 @@ static inline void hinic3_prof_deinit(struct hinic3_prof_adapter *prof_obj, void
prof_obj->deinit(prof_attr);
}
-/*lint -restore*/
/* module-level interface */
#ifdef CONFIG_MODULE_PROF
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
index e4705c2..dcd79ee 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/dcbnl.h>
+#include <linux/init.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -23,7 +24,6 @@
#include "hinic3_hw.h"
#include "hinic3_rss.h"
-/*lint -e806*/
static u16 num_qps;
module_param(num_qps, ushort, 0444);
MODULE_PARM_DESC(num_qps, "Number of Queue Pairs (default=0)");
@@ -104,88 +104,83 @@ static int hinic3_get_rq2iq_map(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev, u8 num_cos, u32 *indir)
+static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev,
+ u8 group_num, u32 *indir)
{
- u16 k, group_size, start_qid = 0, qp_num = 0;
- int i = 0;
- u8 j, cur_cos = 0, default_cos;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ u16 k, group_size, start_qid = 0, cur_cos_qnum = 0;
+ u32 i = 0;
+ u8 j, cur_cos = 0, group = 0;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
- if (num_cos == 0) {
+ if (group_num == 0) {
for (i = 0; i < NIC_RSS_INDIR_SIZE; i++)
indir[i] = i % nic_dev->q_params.num_qps;
} else {
- group_size = NIC_RSS_INDIR_SIZE / num_cos;
-
- for (j = 0; j < num_cos; j++) {
- while (cur_cos < NIC_DCB_COS_MAX &&
- nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos] == 0)
- cur_cos++;
-
- if (cur_cos >= NIC_DCB_COS_MAX) {
- if (BIT(nic_dev->hw_dcb_cfg.default_cos) & valid_cos_map)
- default_cos = nic_dev->hw_dcb_cfg.default_cos;
- else
- default_cos = (u8)fls(valid_cos_map) - 1;
+ group_size = NIC_RSS_INDIR_SIZE / group_num;
+
+ for (group = 0; group < group_num; group++) {
+ cur_cos = dcb->hw_dcb_cfg.default_cos;
+ for (j = 0; j < NIC_DCB_COS_MAX; j++) {
+ if ((BIT(j) & valid_cos_map) != 0) {
+ cur_cos = j;
+ valid_cos_map -= (u8)BIT(j);
+ break;
+ }
+ }
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[default_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[default_cos];
+ cur_cos_qnum = dcb->hw_dcb_cfg.cos_qp_num[cur_cos];
+ if (cur_cos_qnum > 0) {
+ start_qid =
+ dcb->hw_dcb_cfg.cos_qp_offset[cur_cos];
} else {
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[cur_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos];
+ start_qid = cur_cos % nic_dev->q_params.num_qps;
+ /* Ensure that the offset of start_id is 0. */
+ cur_cos_qnum = 1;
}
for (k = 0; k < group_size; k++)
- indir[i++] = start_qid + k % qp_num;
-
- cur_cos++;
+ indir[i++] = start_qid + k % cur_cos_qnum;
}
}
}
-/*lint -e528*/
int hinic3_rss_init(struct hinic3_nic_dev *nic_dev, u8 *rq2iq_map, u32 map_size, u8 dcb_en)
{
struct net_device *netdev = nic_dev->netdev;
- u8 i, cos_num;
- u8 cos_map[NIC_DCB_UP_MAX] = {0};
- u8 cfg_map[NIC_DCB_UP_MAX] = {0};
+ u8 i, group_num, cos_bitmap, group = 0;
+ u8 cos_group[NIC_DCB_UP_MAX] = {0};
int err;
- if (dcb_en) {
- cos_num = hinic3_get_dev_user_cos_num(nic_dev);
-
- if (nic_dev->hw_dcb_cfg.trust == 0) {
- memcpy(cfg_map, nic_dev->hw_dcb_cfg.pcp2cos, sizeof(cfg_map));
- } else if (nic_dev->hw_dcb_cfg.trust == 1) {
- for (i = 0; i < NIC_DCB_UP_MAX; i++)
- cfg_map[i] = nic_dev->hw_dcb_cfg.dscp2cos[i * NIC_DCB_DSCP_NUM];
- }
-#define COS_CHANGE_OFFSET 4
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[COS_CHANGE_OFFSET + i] = cfg_map[i];
+ if (dcb_en != 0) {
+ group_num = (u8)roundup_pow_of_two(hinic3_get_dev_user_cos_num(nic_dev));
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[i] = cfg_map[NIC_DCB_UP_MAX - (i + 1)];
+ cos_bitmap = hinic3_get_dev_valid_cos_map(nic_dev);
- while (cos_num & (cos_num - 1))
- cos_num++;
+ for (i = 0; i < NIC_DCB_UP_MAX; i++) {
+ if ((BIT(i) & cos_bitmap) != 0)
+ cos_group[NIC_DCB_UP_MAX - i - 1] = group++;
+ else
+ cos_group[NIC_DCB_UP_MAX - i - 1] =
+ group_num - 1;
+ }
} else {
- cos_num = 0;
+ group_num = 0;
}
- err = hinic3_set_hw_rss_parameters(netdev, 1, cos_num, cos_map, dcb_en);
+ err = hinic3_set_hw_rss_parameters(netdev, 1, group_num,
+ cos_group, dcb_en);
if (err)
return err;
- err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps, cos_num, cos_map,
- NIC_DCB_UP_MAX, nic_dev->rss_indir, rq2iq_map, map_size);
+ err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps,
+ group_num, cos_group, NIC_DCB_UP_MAX,
+ nic_dev->rss_indir, rq2iq_map, map_size);
if (err)
nicif_err(nic_dev, drv, netdev, "Failed to get rq map\n");
return err;
}
-/*lint -e528*/
void hinic3_rss_deinit(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -246,11 +241,29 @@ discard_user_rss_indir:
hinic3_set_default_rss_indir(netdev);
}
+#ifdef HAVE_HOT_REPLACE_FUNC
+bool partition_slave_doing_hotupgrade(void)
+{
+ return get_partition_role() && partition_doing_hotupgrade();
+}
+#endif
+
static void decide_num_qps(struct hinic3_nic_dev *nic_dev)
{
u16 tmp_num_qps = nic_dev->max_qps;
u16 num_cpus = 0;
+ u16 max_num_cpus;
int i, node;
+ int is_in_kexec = vram_get_kexec_flag();
+
+ if (is_in_kexec != 0) {
+ nic_dev->q_params.num_qps = nic_dev->nic_vram->vram_num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Os hotreplace use vram to init num qps 1:%u 2:%u\n",
+ nic_dev->q_params.num_qps,
+ nic_dev->nic_vram->vram_num_qps);
+ return;
+ }
if (nic_dev->nic_cap.default_num_queues != 0 &&
nic_dev->nic_cap.default_num_queues < nic_dev->max_qps)
@@ -258,16 +271,29 @@ static void decide_num_qps(struct hinic3_nic_dev *nic_dev)
MOD_PARA_VALIDATE_NUM_QPS(nic_dev, num_qps, tmp_num_qps);
- for (i = 0; i < (int)num_online_cpus(); i++) {
+#ifdef HAVE_HOT_REPLACE_FUNC
+ if (partition_slave_doing_hotupgrade())
+ max_num_cpus = (u16)num_present_cpus();
+ else
+ max_num_cpus = (u16)num_online_cpus();
+#else
+ max_num_cpus = (u16)num_online_cpus();
+#endif
+
+ for (i = 0; i < max_num_cpus; i++) {
node = (int)cpu_to_node(i);
if (node == dev_to_node(&nic_dev->pdev->dev))
num_cpus++;
}
if (!num_cpus)
- num_cpus = (u16)num_online_cpus();
+ num_cpus = max_num_cpus;
nic_dev->q_params.num_qps = (u16)min_t(u16, tmp_num_qps, num_cpus);
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "init num qps 1:%u 2:%u\n",
+ nic_dev->q_params.num_qps, nic_dev->nic_vram->vram_num_qps);
}
static void copy_value_to_rss_hkey(struct hinic3_nic_dev *nic_dev,
@@ -322,7 +348,6 @@ static int alloc_rss_resource(struct hinic3_nic_dev *nic_dev)
return 0;
}
-/*lint -e528*/
void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -361,6 +386,7 @@ void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
set_q_params:
clear_bit(HINIC3_RSS_ENABLE, &nic_dev->flags);
nic_dev->q_params.num_qps = nic_dev->max_qps;
+ nic_dev->nic_vram->vram_num_qps = nic_dev->max_qps;
}
static int hinic3_config_rss_hw_resource(struct hinic3_nic_dev *nic_dev,
@@ -754,6 +780,7 @@ int hinic3_set_channels(struct net_device *netdev,
nic_dev->q_params.num_qps = (u16)count;
}
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
return 0;
}
@@ -814,7 +841,7 @@ int hinic3_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
int err = 0;
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
@@ -921,7 +948,7 @@ int hinic3_get_rxfh_indir(struct net_device *netdev, u32 *indir)
indir = indir1->ring_index;
#endif
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
index 071418d..4f4b18c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
@@ -15,14 +15,15 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_nic_cfg.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_hw.h"
#include "hinic3_nic.h"
#include "hinic3_nic_cmdq.h"
#include "hinic3_common.h"
static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
- u8 *key)
+ u8 *key, u16 key_size)
{
struct hinic3_cmd_rss_hash_key hash_key;
u16 out_size = sizeof(hash_key);
@@ -33,7 +34,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
hash_key.opcode = opcode;
if (opcode == HINIC3_CMD_OP_SET)
- memcpy(hash_key.key, key, NIC_RSS_KEY_SIZE);
+ memcpy(hash_key.key, key, key_size);
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_CFG_RSS_HASH_KEY,
@@ -47,7 +48,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
}
if (opcode == HINIC3_CMD_OP_GET)
- memcpy(key, hash_key.key, NIC_RSS_KEY_SIZE);
+ memcpy(key, hash_key.key, key_size);
return 0;
}
@@ -61,8 +62,12 @@ int hinic3_rss_set_hash_key(void *hwdev, const u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memcpy(hash_key, key, NIC_RSS_KEY_SIZE);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET, hash_key);
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET,
+ hash_key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
@@ -73,7 +78,11 @@ int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET, key);
+ if (!nic_io)
+ return -EINVAL;
+
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET,
+ key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
@@ -89,6 +98,7 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
if (nic_io == NULL)
return -EINVAL;
+
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (cmd_buf == NULL) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -159,6 +169,8 @@ static int hinic3_cmdq_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
@@ -210,6 +222,9 @@ static int hinic3_mgmt_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&ctx_tbl, 0, sizeof(ctx_tbl));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
ctx |= HINIC3_RSS_TYPE_SET(1, VALID) |
@@ -259,6 +274,8 @@ int hinic3_get_rss_type(void *hwdev, struct nic_rss_type *rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&ctx_tbl, 0, sizeof(struct hinic3_rss_context_table));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
@@ -292,6 +309,9 @@ static int hinic3_rss_cfg_hash_engine(struct hinic3_nic_io *nic_io, u8 opcode,
u16 out_size = sizeof(hash_type);
int err;
+ if (!nic_io)
+ return -EINVAL;
+
memset(&hash_type, 0, sizeof(struct hinic3_cmd_rss_engine_type));
hash_type.func_id = hinic3_global_func_id(nic_io->hwdev);
@@ -325,6 +345,9 @@ int hinic3_rss_set_hash_engine(void *hwdev, u8 type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_SET, &type);
}
@@ -336,6 +359,9 @@ int hinic3_rss_get_hash_engine(void *hwdev, u8 *type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_GET, type);
}
@@ -351,6 +377,9 @@ int hinic3_rss_cfg(void *hwdev, u8 rss_en, u8 cos_num, u8 *prio_tc, u16 num_qps)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&rss_cfg, 0, sizeof(struct hinic3_cmd_rss_config));
rss_cfg.func_id = hinic3_global_func_id(hwdev);
rss_cfg.rss_en = rss_en;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
index f8a866d..936258c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
@@ -21,6 +21,7 @@
#include <linux/ipv6.h>
#include <linux/module.h>
#include <linux/compiler.h>
+#include <linux/filter.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -63,19 +64,31 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
struct pci_dev *pdev = nic_dev->pdev;
struct page *page = rx_info->page;
dma_addr_t dma = rx_info->buf_dma_addr;
+ u32 page_offset = 0;
if (likely(dma))
return true;
/* alloc new page for storage */
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page = page_pool_alloc_frag(rx_info->page_pool, &page_offset,
+ nic_dev->rx_buff_len,
+ GFP_ATOMIC | __GFP_COLD | __GFP_COMP);
+ if (unlikely(!page))
+ return false;
+ dma = page_pool_get_dma_addr(page);
+ goto set_rx_info;
+ }
+#endif
page = alloc_pages_node(NUMA_NO_NODE, GFP_ATOMIC | __GFP_COLD |
__GFP_COMP, nic_dev->page_order);
if (unlikely(!page))
return false;
/* map page for use */
- dma = dma_map_page(&pdev->dev, page, 0, nic_dev->dma_rx_buff_size,
- DMA_FROM_DEVICE);
+ dma = dma_map_page(&pdev->dev, page, page_offset,
+ nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
/* if mapping failed free memory back to system since
* there isn't much point in holding memory we can't use
*/
@@ -83,10 +96,12 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
__free_pages(page, nic_dev->page_order);
return false;
}
+ goto set_rx_info;
+set_rx_info:
rx_info->page = page;
rx_info->buf_dma_addr = dma;
- rx_info->page_offset = 0;
+ rx_info->page_offset = page_offset;
return true;
}
@@ -108,7 +123,7 @@ static u32 hinic3_rx_fill_wqe(struct hinic3_rxq *rxq)
/* unit of cqe length is 16B */
hinic3_set_sge(&rq_wqe->extend_wqe.cqe_sect.sge,
rx_info->cqe_dma,
- (sizeof(struct hinic3_rq_cqe) >>
+ (HINIC3_CQE_LEN >>
HINIC3_CQE_SIZE_SHIFT));
/* use fixed len */
rq_wqe->extend_wqe.buf_desc.sge.len =
@@ -169,7 +184,7 @@ static u32 hinic3_rx_fill_buffers(struct hinic3_rxq *rxq)
if (likely(i)) {
hinic3_write_db(rxq->rq,
- rxq->q_id & 3,
+ rxq->q_id & (NIC_RX_DB_COS_MAX - 1),
RQ_CFLAG_DP,
(u16)((u32)rxq->next_to_update <<
rxq->rq->wqe_type));
@@ -206,6 +221,18 @@ static void hinic3_rx_free_buffers(struct hinic3_nic_dev *nic_dev, u32 q_depth,
for (i = 0; i < q_depth; i++) {
rx_info = &rx_info_arr[i];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ if (rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool,
+ rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ }
+ continue;
+ }
+#endif
+
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev,
rx_info->buf_dma_addr,
@@ -265,8 +292,15 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
DMA_FROM_DEVICE);
if (size <= HINIC3_RX_HDR_SIZE && !skb_is_nonlinear(skb)) {
- memcpy(__skb_put(skb, size), va + offset,
- ALIGN(size, sizeof(long))); /*lint !e666*/
+ __skb_put_data(skb, va + offset, size);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool,
+ page, false);
+ return false;
+ }
+#endif
/* page is not reserved, we can reuse buffer as-is */
if (likely(page_to_nid(page) == numa_node_id()))
@@ -274,25 +308,38 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
/* this page cannot be reused so discard it */
put_page(page);
- return false;
+ goto discard_page;
}
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
- (int)(rx_info->page_offset + offset), (int)size, rxq->buf_len);
+ (int)(rx_info->page_offset + offset), (int)size,
+ rxq->buf_len);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
/* avoid re-using remote pages */
if (unlikely(page_to_nid(page) != numa_node_id()))
- return false;
+ goto discard_page;
/* if we are only owner of page we can reuse it */
if (unlikely(page_count(page) != 1))
- return false;
+ goto discard_page;
/* flip page offset to other buffer */
rx_info->page_offset ^= rxq->buf_len;
get_page(page);
return true;
+
+discard_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
}
static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
@@ -338,10 +385,6 @@ static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
if (likely(hinic3_add_rx_frag(rxq, rx_info, skb, frag_size, tmp_pkt_offset))) {
hinic3_reuse_rx_page(rxq, rx_info);
- } else {
- /* we are not reusing the buffer so unmap it */
- dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
- rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
}
/* clear contents of buffer_info */
rx_info->buf_dma_addr = 0;
@@ -486,9 +529,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
protocol = hdr.eth->h_proto;
/* L2 header */
- /*lint -save -e778*/
if (protocol == htons(ETH_P_8021_AD) ||
- protocol == htons(ETH_P_8021_Q)) { /*lint -restore*/
+ protocol == htons(ETH_P_8021_Q)) {
if (unlikely(max_len < ETH_HLEN + VLAN_HLEN))
return max_len;
@@ -500,9 +542,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
}
/* L3 header */
- /*lint -save -e778*/
switch (protocol) {
- case htons(ETH_P_IP): /*lint -restore*/
+ case htons(ETH_P_IP):
if ((int)(hdr.data - data) >
(int)(max_len - sizeof(struct iphdr)))
return max_len;
@@ -713,7 +754,10 @@ static inline void hinic3_lro_set_gso_params(struct sk_buff *skb, u16 num_lro)
}
#ifdef HAVE_XDP_SUPPORT
-enum hinic3_xdp_pkt {
+enum hinic3_xdp_status {
+ // bpf_prog status
+ HINIC3_XDP_PROG_EMPTY,
+ // pkt action
HINIC3_XDP_PKT_PASS,
HINIC3_XDP_PKT_DROP,
};
@@ -724,9 +768,15 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
while (weqbb_num) {
rx_info = &rxq->rx_info[rxq->cons_idx & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool)
+ goto discard_direct;
+#endif
if (likely(page_to_nid(rx_info->page) == numa_node_id()))
hinic3_reuse_rx_page(rxq, rx_info);
+ goto discard_direct;
+discard_direct:
rx_info->buf_dma_addr = 0;
rx_info->page = NULL;
rxq->cons_idx++;
@@ -736,11 +786,11 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
}
}
-int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
+int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len, struct xdp_buff *xdp)
{
struct bpf_prog *xdp_prog = NULL;
struct hinic3_rx_info *rx_info = NULL;
- struct xdp_buff xdp;
+ struct net_device *netdev = rxq->netdev;
int result = HINIC3_XDP_PKT_PASS;
u16 weqbb_num = 1; /* xdp can only use one rx_buff */
u8 *va = NULL;
@@ -748,13 +798,14 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
rcu_read_lock();
xdp_prog = READ_ONCE(rxq->xdp_prog);
- if (!xdp_prog)
+ if (!xdp_prog) {
+ result = HINIC3_XDP_PROG_EMPTY;
goto unlock_rcu;
+ }
if (unlikely(pkt_len > rxq->buf_len)) {
RXQ_STATS_INC(rxq, xdp_large_pkt);
- weqbb_num = (u16)(pkt_len >> rxq->rx_buff_shift) +
- ((pkt_len & (rxq->buf_len - 1)) ? 1 : 0);
+ weqbb_num = HINIC3_GET_SGE_NUM(pkt_len, rxq);
result = HINIC3_XDP_PKT_DROP;
goto xdp_out;
}
@@ -765,26 +816,27 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
dma_sync_single_range_for_cpu(rxq->dev, rx_info->buf_dma_addr,
rx_info->page_offset,
rxq->buf_len, DMA_FROM_DEVICE);
- xdp.data = va;
- xdp.data_hard_start = xdp.data;
- xdp.data_end = xdp.data + pkt_len;
+ xdp->data = va;
+ xdp->data_hard_start = xdp->data;
+ xdp->data_end = xdp->data + pkt_len;
#ifdef HAVE_XDP_FRAME_SZ
- xdp.frame_sz = rxq->buf_len;
+ xdp->frame_sz = rxq->buf_len;
#endif
#ifdef HAVE_XDP_DATA_META
- xdp_set_data_meta_invalid(&xdp);
+ xdp_set_data_meta_invalid(xdp);
#endif
- prefetchw(xdp.data_hard_start);
- act = bpf_prog_run_xdp(xdp_prog, &xdp);
+ prefetchw(xdp->data_hard_start);
+ act = bpf_prog_run_xdp(xdp_prog, xdp);
switch (act) {
case XDP_PASS:
+ result = HINIC3_XDP_PKT_PASS;
break;
case XDP_DROP:
result = HINIC3_XDP_PKT_DROP;
break;
default:
result = HINIC3_XDP_PKT_DROP;
- bpf_warn_invalid_xdp_action(rxq->netdev, xdp_prog, act);
+ bpf_warn_invalid_xdp_action(netdev, xdp_prog, act);
}
xdp_out:
@@ -798,9 +850,86 @@ unlock_rcu:
return result;
}
+
+static bool hinic3_add_rx_frag_with_xdp(struct hinic3_rxq *rxq, u32 pkt_len,
+ struct hinic3_rx_info *rx_info,
+ struct sk_buff *skb, struct xdp_buff *xdp)
+{
+ struct page *page = rx_info->page;
+
+ if (pkt_len <= HINIC3_RX_HDR_SIZE) {
+ __skb_put_data(skb, xdp->data, pkt_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool, page, false);
+ return false;
+ }
+#endif
+ if (likely(page_to_nid(page) == numa_node_id()))
+ return true;
+
+ put_page(page);
+ goto umap_page;
+ }
+
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
+ (int)(rx_info->page_offset +
+ (xdp->data - xdp->data_hard_start)),
+ (int)pkt_len, rxq->buf_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
+ if (unlikely(page_to_nid(page) != numa_node_id()))
+ goto umap_page;
+ if (unlikely(page_count(page) != 1))
+ goto umap_page;
+
+ rx_info->page_offset ^= rxq->buf_len;
+ get_page(page);
+
+ return true;
+umap_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
+}
+
+static struct sk_buff *hinic3_fetch_rx_buffer_xdp(struct hinic3_rxq *rxq,
+ u32 pkt_len,
+ struct xdp_buff *xdp)
+{
+ struct sk_buff *skb;
+ struct hinic3_rx_info *rx_info;
+ u32 sw_ci;
+ bool reuse;
+
+ sw_ci = rxq->cons_idx & rxq->q_mask;
+ rx_info = &rxq->rx_info[sw_ci];
+
+ skb = netdev_alloc_skb_ip_align(rxq->netdev, HINIC3_RX_HDR_SIZE);
+ if (unlikely(!skb))
+ return NULL;
+
+ reuse = hinic3_add_rx_frag_with_xdp(rxq, pkt_len, rx_info, skb, xdp);
+ if (likely(reuse))
+ hinic3_reuse_rx_page(rxq, rx_info);
+
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+
+ rxq->cons_idx += 1;
+ rxq->delta += 1;
+
+ return skb;
+}
+
#endif
-static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_cqe_info *cqe_info)
+static int recv_one_pkt(struct hinic3_rxq *rxq,
+ struct hinic3_cqe_info *cqe_info)
{
struct sk_buff *skb = NULL;
struct net_device *netdev = rxq->netdev;
@@ -808,13 +937,25 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_cqe_info *cqe_info
#ifdef HAVE_XDP_SUPPORT
u32 xdp_status;
+ struct xdp_buff xdp = { 0 };
- xdp_status = (u32)(hinic3_run_xdp(rxq, cqe_info->pkt_len));
+ xdp_status = (u32)(hinic3_run_xdp(rxq, cqe_info->pkt_len, &xdp));
if (xdp_status == HINIC3_XDP_PKT_DROP)
return 0;
-#endif
+ // build skb
+ if (xdp_status != HINIC3_XDP_PROG_EMPTY) {
+ // xdp_prog configured, build skb with xdp
+ skb = hinic3_fetch_rx_buffer_xdp(rxq, cqe_info->pkt_len, &xdp);
+ } else {
+ // xdp_prog not configured, build skb
+ skb = hinic3_fetch_rx_buffer(rxq, cqe_info);
+ }
+#else
+
+ // xdp is not supported
skb = hinic3_fetch_rx_buffer(rxq, cqe_info);
+#endif
if (unlikely(!skb)) {
RXQ_STATS_INC(rxq, alloc_skb_err);
return -ENOMEM;
@@ -842,7 +983,7 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_cqe_info *cqe_info
if (unlikely(test_bit(HINIC3_LP_TEST, &nic_dev->flags)))
hinic3_copy_lp_data(nic_dev, skb);
- if (cqe_info->lro_num)
+ if (cqe_info->lro_num > 1)
hinic3_lro_set_gso_params(skb, cqe_info->lro_num);
skb_record_rx_queue(skb, rxq->q_id);
@@ -1021,12 +1162,39 @@ int hinic3_rx_poll(struct hinic3_rxq *rxq, int budget)
return pkts;
}
+#ifdef HAVE_PAGE_POOL_SUPPORT
+static struct page_pool *hinic3_create_page_pool(struct hinic3_nic_dev *nic_dev,
+ u32 rq_depth,
+ struct hinic3_rx_info *rx_info_arr)
+{
+ struct page_pool_params pp_params = {
+ .flags = PP_FLAG_DMA_MAP | PP_FLAG_PAGE_FRAG | PP_FLAG_DMA_SYNC_DEV,
+ .order = nic_dev->page_order,
+ .pool_size = rq_depth * nic_dev->rx_buff_len /
+ (PAGE_SIZE << nic_dev->page_order),
+ .nid = dev_to_node(&nic_dev->pdev->dev),
+ .dev = &nic_dev->pdev->dev,
+ .dma_dir = DMA_FROM_DEVICE,
+ .offset = 0,
+ .max_len = PAGE_SIZE << nic_dev->page_order,
+ };
+ struct page_pool *page_pool;
+ int i;
+
+ page_pool = nic_dev->page_pool_enabled ?
+ page_pool_create(&pp_params) : NULL;
+ for (i = 0; i < rq_depth; i++)
+ rx_info_arr[i].page_pool = page_pool;
+ return page_pool;
+}
+#endif
+
int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
u32 rq_depth, struct hinic3_dyna_rxq_res *rxqs_res)
{
struct hinic3_dyna_rxq_res *rqres = NULL;
u64 cqe_mem_size = sizeof(struct hinic3_rq_cqe) * rq_depth;
- int idx, i;
+ int idx;
u32 pkts;
u64 size;
@@ -1045,51 +1213,53 @@ int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
if (!rqres->rx_info) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx info\n", idx);
- goto err_out;
+ goto err_alloc_rx_info;
}
-
if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
rqres->cqe_start_vaddr =
- dma_zalloc_coherent(&nic_dev->pdev->dev, cqe_mem_size,
+ dma_zalloc_coherent(&nic_dev->pdev->dev,
+ cqe_mem_size,
&rqres->cqe_start_paddr,
GFP_KERNEL);
if (!rqres->cqe_start_vaddr) {
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d cqe\n", idx);
- goto err_out;
+ goto err_alloc_cqe;
}
}
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ rqres->page_pool = hinic3_create_page_pool(nic_dev, rq_depth,
+ rqres->rx_info);
+ if (nic_dev->page_pool_enabled && !rqres->page_pool) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to create rxq%d page pool\n", idx);
+ goto err_create_page_pool;
+ }
+#endif
pkts = hinic3_rx_alloc_buffers(nic_dev, rq_depth,
rqres->rx_info);
if (!pkts) {
- if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- }
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx buffers\n", idx);
- goto err_out;
+ goto err_alloc_buffers;
}
rqres->next_to_alloc = (u16)pkts;
}
return 0;
-err_out:
- for (i = 0; i < idx; i++) {
- rqres = &rxqs_res[i];
-
- hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
- if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- }
- kfree(rqres->rx_info);
- }
-
+err_alloc_buffers:
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ page_pool_destroy(rqres->page_pool);
+err_create_page_pool:
+#endif
+ dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
+ rqres->cqe_start_vaddr,
+ rqres->cqe_start_paddr);
+err_alloc_cqe:
+ kfree(rqres->rx_info);
+err_alloc_rx_info:
+ hinic3_free_rxqs_res(nic_dev, idx, rq_depth, rxqs_res);
return -ENOMEM;
}
@@ -1104,6 +1274,10 @@ void hinic3_free_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
rqres = &rxqs_res[idx];
hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rqres->page_pool)
+ page_pool_destroy(rqres->page_pool);
+#endif
if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
rqres->cqe_start_vaddr,
@@ -1191,6 +1365,7 @@ void hinic3_free_rxqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->rxqs);
+ nic_dev->rxqs = NULL;
}
int hinic3_alloc_rxqs(struct net_device *netdev)
@@ -1312,6 +1487,14 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
nic_info(&nic_dev->pdev->dev, "rxq %u restore_buf_num:%u\n", q_id, rxq->restore_buf_num);
rx_info = &rxq->rx_info[(hw_ci + rxq->q_depth - 1) & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool && rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool, rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ goto reset_rxq;
+ }
+#endif
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev, rx_info->buf_dma_addr,
nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
@@ -1322,7 +1505,9 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
__free_pages(rx_info->page, nic_dev->page_order);
rx_info->page = NULL;
}
+ goto reset_rxq;
+reset_rxq:
rxq->delta = 1;
rxq->next_to_update = (u16)((hw_ci + rxq->q_depth - 1) & rxq->q_mask);
rxq->cons_idx = (u16)((rxq->next_to_update + 1) & rxq->q_mask);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
index 586a221..480f787 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
@@ -4,6 +4,10 @@
#ifndef HINIC3_RX_H
#define HINIC3_RX_H
+#ifdef HAVE_PAGE_POOL_SUPPORT
+#include <net/page_pool/helpers.h>
+#endif
+
#include <linux/types.h>
#include <linux/device.h>
#include <linux/mm_types.h>
@@ -27,6 +31,7 @@
#define HINIC3_RX_CSUM_IPSU_OTHER_ERR BIT(8)
#define HINIC3_HEADER_DATA_UNIT 2
+#define HINIC3_CQE_LEN 32
#define HINIC3_COMPACT_CQE_8B 8
#define HINIC3_COMPACT_CQE_16B 16
@@ -35,20 +40,20 @@
#define HINIC3_RQ_CQE_INTEGRATE 1
struct hinic3_rxq_stats {
- u64 packets;
- u64 bytes;
- u64 errors;
- u64 csum_errors;
- u64 other_errors;
- u64 dropped;
- u64 xdp_dropped;
- u64 rx_buf_empty;
-
- u64 alloc_skb_err;
- u64 alloc_rx_buf_err;
- u64 xdp_large_pkt;
- u64 restore_drop_sge;
- u64 rsvd2;
+ u64 packets;
+ u64 bytes;
+ u64 errors;
+ u64 csum_errors;
+ u64 other_errors;
+ u64 dropped;
+ u64 xdp_dropped;
+ u64 rx_buf_empty;
+
+ u64 alloc_skb_err;
+ u64 alloc_rx_buf_err;
+ u64 xdp_large_pkt;
+ u64 restore_drop_sge;
+ u64 rsvd2;
#ifdef HAVE_NDO_GET_STATS64
struct u64_stats_sync syncp;
#else
@@ -62,6 +67,9 @@ struct hinic3_rx_info {
struct hinic3_rq_cqe *cqe;
dma_addr_t cqe_dma;
struct page *page;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
u32 page_offset;
u32 rsvd1;
struct hinic3_rq_wqe *rq_wqe;
@@ -102,7 +110,7 @@ struct hinic3_rxq {
u16 next_to_update;
struct device *dev; /* device for DMA mapping */
- unsigned long status;
+ u64 status;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
@@ -130,6 +138,9 @@ struct hinic3_dyna_rxq_res {
struct hinic3_rx_info *rx_info;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
};
int hinic3_alloc_rxqs(struct net_device *netdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
index bdd5a8e..d816609 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
@@ -11,10 +11,12 @@
#ifndef HINIC3_SRV_NIC_H
#define HINIC3_SRV_NIC_H
-#include "hinic3_mgmt_interface.h"
+#include <linux/netdevice.h>
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_lld.h"
+#include "nic_cfg_comm.h"
+#include "nic_mpu_cmd_defs.h"
enum hinic3_queue_type {
HINIC3_SQ,
@@ -64,6 +66,7 @@ enum hinic3_nic_event_type {
EVENT_NIC_DCB_STATE_CHANGE,
EVENT_NIC_BOND_DOWN,
EVENT_NIC_BOND_UP,
+ EVENT_NIC_OUTBAND_CFG,
};
/* *
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
index bc1a8ef..99264c7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
@@ -223,24 +223,72 @@ static void get_inner_l3_l4_type(struct sk_buff *skb, union hinic3_ip *ip,
enum sq_l3_type *l3_type, u8 *l4_proto)
{
unsigned char *exthdr = NULL;
- __be16 frag_off = 0;
if (ip->v4->version == IP4_VERSION) {
*l3_type = IPV4_PKT_WITH_CHKSUM_OFFLOAD;
*l4_proto = ip->v4->protocol;
+
+#ifdef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
+ /* inner_transport_header is wrong in centos7.0 and suse12.1 */
+ l4->hdr = ip->hdr + ((u8)ip->v4->ihl << IP_HDR_IHL_UNIT_SHIFT);
+#endif
} else if (ip->v4->version == IP6_VERSION) {
*l3_type = IPV6_PKT;
exthdr = ip->hdr + sizeof(*ip->v6);
*l4_proto = ip->v6->nexthdr;
- if (exthdr != l4->hdr)
+ if (exthdr != l4->hdr) {
+ __be16 frag_off = 0;
+#ifndef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
ipv6_skip_exthdr(skb, (int)(exthdr - skb->data),
- l4_proto, &frag_off);
+ l4_proto, &frag_off);
+#else
+ int pld_off = 0;
+
+ pld_off = ipv6_skip_exthdr(skb,
+ (int)(exthdr - skb->data),
+ l4_proto, &frag_off);
+ l4->hdr = skb->data + pld_off;
+#endif
+ }
} else {
*l3_type = UNKNOWN_L3TYPE;
*l4_proto = 0;
}
}
+static u8 hinic3_get_inner_l4_type(struct sk_buff *skb)
+{
+ enum sq_l3_type l3_type;
+ u8 l4_proto;
+ union hinic3_ip ip;
+ union hinic3_l4 l4;
+
+ ip.hdr = skb_inner_network_header(skb);
+ l4.hdr = skb_inner_transport_header(skb);
+
+ get_inner_l3_l4_type(skb, &ip, &l4, &l3_type, &l4_proto);
+
+ return l4_proto;
+}
+
+static void hinic3_set_unknown_tunnel_csum(struct sk_buff *skb)
+{
+ int csum_offset;
+ __sum16 skb_csum;
+ u8 l4_proto;
+
+ l4_proto = hinic3_get_inner_l4_type(skb);
+ /* Unsupport tunnel packet, disable csum offload */
+ skb_checksum_help(skb);
+ /* The value of csum is changed from 0xffff to 0 according to RFC1624. */
+ if (skb->ip_summed == CHECKSUM_NONE && l4_proto != IPPROTO_UDP) {
+ csum_offset = skb_checksum_start_offset(skb) + skb->csum_offset;
+ skb_csum = *(__sum16 *)(skb->data + csum_offset);
+ if (skb_csum == 0xffff)
+ *(__sum16 *)(skb->data + csum_offset) = 0;
+ }
+}
+
static int hinic3_tx_csum(struct hinic3_txq *txq, struct sk_buff *skb,
struct hinic3_offload_info *offload_info,
struct hinic3_queue_info *queue_info)
@@ -276,10 +324,9 @@ static int hinic3_tx_csum(struct hinic3_txq *txq, struct sk_buff *skb,
if (l4_proto == IPPROTO_UDP)
queue_info->udp_dp_en = 1;
- if (l4_proto != IPPROTO_UDP ||
- ((struct udphdr *)skb_transport_header(skb))->dest != VXLAN_OFFLOAD_PORT_LE) {
+ if (l4_proto != IPPROTO_UDP) {
TXQ_STATS_INC(txq, unknown_tunnel_pkt);
- skb_checksum_help(skb);
+ hinic3_set_unknown_tunnel_csum(skb);
return 0;
}
}
@@ -682,6 +729,14 @@ static netdev_tx_t hinic3_send_one_skb(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
+ /* l2nic outband vlan cfg enable */
+ if (!skb_vlan_tag_present(skb) &&
+ nic_dev->nic_cap.outband_vlan_cfg_en == 1 &&
+ nic_dev->outband_cfg.outband_default_vid != 0) {
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+ (u16)nic_dev->outband_cfg.outband_default_vid);
+ }
+
offload = hinic3_tx_offload(skb, &offload_info, &queue_info, txq);
if (unlikely(offload == TX_OFFLOAD_INVALID)) {
TXQ_STATS_INC(txq, offload_cow_skb_err);
@@ -880,6 +935,7 @@ int hinic3_alloc_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
tqres->bds = kzalloc(size, GFP_KERNEL);
if (!tqres->bds) {
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc txq%d bds info\n", idx);
goto err_out;
@@ -893,7 +949,9 @@ err_out:
tqres = &txqs_res[i];
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
return -ENOMEM;
@@ -910,7 +968,9 @@ void hinic3_free_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
free_all_tx_skbs(nic_dev, sq_depth, tqres->tx_info);
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
}
@@ -982,6 +1042,7 @@ void hinic3_free_txqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->txqs);
+ nic_dev->txqs = NULL;
}
static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
@@ -998,7 +1059,7 @@ static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
static int hinic3_stop_sq(struct hinic3_txq *txq)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(txq->netdev);
- unsigned long timeout;
+ u64 timeout;
int err;
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -1007,7 +1068,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
return 0;
usleep_range(900, 1000); /* sleep 900 us ~ 1000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* force hardware to drop packets */
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -1020,7 +1081,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
break;
usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* Avoid msleep takes too long and get a fake result */
if (is_hw_complete_sq_process(txq->sq))
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
index 1b9e509..7ae029b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
@@ -29,7 +29,7 @@ struct hinic3_wq {
#define WQ_MASK_IDX(wq, idx) ((idx) & (wq)->idx_mask)
#define WQ_MASK_PAGE(wq, pg_idx) \
- ((pg_idx) < (wq)->num_wq_pages ? (pg_idx) : 0)
+ (((pg_idx) < ((wq)->num_wq_pages)) ? (pg_idx) : 0)
#define WQ_PAGE_IDX(wq, idx) ((idx) >> (wq)->wqebbs_per_page_shift)
#define WQ_OFFSET_IN_PAGE(wq, idx) ((idx) & (wq)->wqebbs_per_page_mask)
#define WQ_GET_WQEBB_ADDR(wq, pg_idx, idx_in_pg) \
@@ -75,7 +75,7 @@ static inline void *hinic3_wq_get_multi_wqebbs(struct hinic3_wq *wq,
pg_idx = WQ_PAGE_IDX(wq, *prod_idx);
off_in_page = WQ_OFFSET_IN_PAGE(wq, *prod_idx);
- if (off_in_page + num_wqebbs > wq->wqebbs_per_page) {
+ if ((off_in_page + num_wqebbs) > wq->wqebbs_per_page) {
/* wqe across wq page boundary */
*second_part_wqebbs_addr =
WQ_GET_WQEBB_ADDR(wq, WQ_MASK_PAGE(wq, pg_idx + 1), 0);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
index 597d3fe..468351f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
@@ -400,12 +400,15 @@ static int wait_for_status_poll(struct hinic3_api_cmd_chain *chain)
API_CMD_STATUS_TIMEOUT, 100); /* wait 100 us once */
}
-static void copy_resp_data(struct hinic3_api_cmd_cell_ctxt *ctxt, void *ack,
+static void copy_resp_data(struct hinic3_api_cmd_chain *chain,
+ struct hinic3_api_cmd_cell_ctxt *ctxt, void *ack,
u16 ack_size)
{
struct hinic3_api_cmd_resp_fmt *resp = ctxt->resp;
+ int rsp_size_align = chain->rsp_size_align - 0x8;
+ int rsp_size = (ack_size > rsp_size_align) ? rsp_size_align : ack_size;
- memcpy(ack, &resp->resp_data, ack_size);
+ memcpy(ack, &resp->resp_data, rsp_size);
ctxt->status = 0;
}
@@ -464,7 +467,7 @@ static int wait_for_api_cmd_completion(struct hinic3_api_cmd_chain *chain,
case HINIC3_API_CMD_POLL_READ:
err = wait_for_resp_polling(ctxt);
if (err == 0)
- copy_resp_data(ctxt, ack, ack_size);
+ copy_resp_data(chain, ctxt, ack, ack_size);
else
sdk_err(dev, "API CMD poll response timeout\n");
break;
@@ -1054,13 +1057,11 @@ alloc_cells_buf_err:
alloc_wb_status_err:
kfree(chain->cell_ctxt);
-/*lint -save -e548*/
alloc_cell_ctxt_err:
if (chain->chain_type == HINIC3_API_CMD_WRITE_ASYNC_TO_MGMT_CPU)
spin_lock_deinit(&chain->async_lock);
else
sema_deinit(&chain->sem);
-/*lint -restore*/
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
index 38474ba..9f10131 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
@@ -801,7 +801,7 @@ static int cmdq_sync_cmd(struct hinic3_cmdq *cmdq, u8 mod, u8 cmd,
hinic3_cmdq_fill_completion_info(cmd_info, &cmpt_code, &done, &errcode, out_param);
cmdq_set_cmd_buf(cmd_info, cmdq->hwdev, buf_in, buf_out);
- memcpy(&saved_cmd_info, cmd_info, sizeof(*cmd_info));
+ memcpy(&saved_cmd_info, cmd_info, sizeof(struct hinic3_cmdq_cmd_info));
cmdq_sync_wqe_prepare(cmdq, mod, cmd, buf_in, buf_out, curr_wqe, curr_pi, nic_cmd_type);
@@ -1075,6 +1075,7 @@ int hinic3_cmdq_async(void *hwdev, u8 mod, u8 cmd, struct hinic3_cmd_buf *buf_in
return cmdq_async_cmd(&cmdqs->cmdq[HINIC3_CMDQ_SYNC], mod,
cmd, buf_in, channel);
}
+EXPORT_SYMBOL(hinic3_cmdq_async);
int hinic3_cmdq_async_cos(void *hwdev, u8 mod, u8 cmd,
u8 cos_id, struct hinic3_cmd_buf *buf_in, u16 channel)
@@ -1320,6 +1321,7 @@ cmd_infos_err:
static void free_cmdq(struct hinic3_cmdq *cmdq)
{
kfree(cmdq->cmd_infos);
+ cmdq->cmd_infos = NULL;
spin_lock_deinit(&cmdq->cmdq_lock);
}
@@ -1530,7 +1532,7 @@ static int create_cmdq_wq(struct hinic3_cmdqs *cmdqs)
type = HINIC3_CMDQ_SYNC;
for (; type < cmdqs->cmdq_num; type++)
memcpy((u8 *)cmdqs->wq_block_vaddr +
- CMDQ_WQ_CLA_SIZE * type,
+ ((u64)type * CMDQ_WQ_CLA_SIZE),
cmdqs->cmdq[type].wq.wq_block_vaddr,
cmdqs->cmdq[type].wq.num_wq_pages * sizeof(u64));
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
index b9b884f..4f4639d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
@@ -15,11 +15,6 @@
#include "hinic3_common.h"
#include "hinic3_hwdev.h"
-struct dma_pool {
- unsigned int size;
- void *dev_hdl;
-};
-
#define HINIC3_SCMD_DATA_LEN 16
#define HINIC3_CMDQ_DEPTH 4096
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c
index c212bcc..d7e4985 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c
@@ -16,7 +16,6 @@
#include "ossl_knl.h"
#include "npu_cmdq_base_defs.h"
-#include "comm_defs.h"
#include "hinic3_crm.h"
#include "hinic3_hw.h"
#include "hinic3_hwdev.h"
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
index 5e0139a..0981d94 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
@@ -22,11 +22,15 @@
#include "hinic3_sriov.h"
#include "hinic3_nictool.h"
#include "hinic3_pci_id_tbl.h"
+#include "hinic3_hwdev.h"
+#include "cfg_mgmt_mpu_cmd_defs.h"
+#include "mpu_cmd_base_defs.h"
#include "hinic3_dev_mgmt.h"
#define HINIC3_WAIT_TOOL_CNT_TIMEOUT 10000
#define HINIC3_WAIT_TOOL_MIN_USLEEP_TIME 9900
#define HINIC3_WAIT_TOOL_MAX_USLEEP_TIME 10000
+#define HIGHT_BDF 8
static unsigned long card_bit_map;
@@ -60,14 +64,24 @@ void lld_dev_cnt_init(struct hinic3_pcidev *pci_adapter)
void lld_dev_hold(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_inc(&pci_adapter->ref_cnt);
}
void lld_dev_put(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_dec(&pci_adapter->ref_cnt);
}
@@ -236,6 +250,40 @@ void hinic3_get_all_chip_id(void *id_info)
card_id->num = (u32)i;
}
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+ u64 bar1_phy_addr = 0;
+ u64 bar3_phy_addr = 0;
+ u64 bar1_size = 0;
+ u64 bar3_size = 0;
+
+ lld_hold();
+
+ /* get PF bar1 or bar3 physical address to verify */
+ list_for_each_entry(chip_node, &g_hinic3_chip_list, node) {
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (hinic3_func_type(dev->hwdev) == TYPE_VF)
+ continue;
+
+ bar1_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+ bar1_size = pci_resource_len(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+
+ bar3_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ bar3_size = pci_resource_len(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ if ((phy_addr == bar1_phy_addr && vmsize <= bar1_size) ||
+ (phy_addr == bar3_phy_addr && vmsize <= bar3_size)) {
+ lld_put();
+ return 0;
+ }
+ }
+ }
+
+ lld_put();
+ return -EINVAL;
+}
+
void hinic3_get_card_func_info_by_card_name(const char *chip_name,
struct hinic3_card_func_info *card_func)
{
@@ -422,6 +470,29 @@ struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name
return NULL;
}
+void *hinic3_get_ppf_dev(void)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct list_head *chip_list = NULL;
+
+ lld_hold();
+ chip_list = get_hinic3_chip_list();
+
+ list_for_each_entry(chip_node, chip_list, node)
+ list_for_each_entry(pci_adapter, &chip_node->func_list, node)
+ if (hinic3_func_type(pci_adapter->hwdev) == TYPE_PPF) {
+ pr_info("Get ppf_func_id:%u",
+ hinic3_global_func_id(pci_adapter->hwdev));
+ lld_put();
+ return pci_adapter->lld_dev.hwdev;
+ }
+
+ lld_put();
+ return NULL;
+}
+EXPORT_SYMBOL(hinic3_get_ppf_dev);
+
struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
enum hinic3_service_type type)
{
@@ -518,6 +589,7 @@ EXPORT_SYMBOL(hinic3_get_ppf_lld_dev_unsafe);
int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len)
{
struct hinic3_pcidev *pci_adapter = NULL;
+ int ret = 0;
if (!lld_dev || !chip_name || !max_len)
return -EINVAL;
@@ -527,12 +599,18 @@ int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 ma
return -EFAULT;
lld_hold();
- strscpy(chip_name, pci_adapter->chip_node->chip_name, max_len);
+ if (strscpy(chip_name, pci_adapter->chip_node->chip_name, max_len) < 0)
+ goto RELEASE;
chip_name[max_len - 1] = '\0';
lld_put();
return 0;
+
+RELEASE:
+ lld_put();
+
+ return ret;
}
EXPORT_SYMBOL(hinic3_get_chip_name);
@@ -541,6 +619,87 @@ struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev)
return lld_dev->hwdev;
}
+void hinic3_write_oshr_info(struct os_hot_replace_info *out_oshr_info,
+ struct hw_pf_info *info,
+ struct hinic3_board_info *board_info,
+ struct card_node *chip_node, u32 serivce_enable,
+ u32 func_info_idx)
+{
+ out_oshr_info->func_infos[func_info_idx].pf_idx = info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].backup_pf =
+ (((info->glb_func_idx) / (board_info->port_num)) %
+ HOT_REPLACE_PARTITION_NUM == 0) ?
+ ((info->glb_func_idx) + (board_info->port_num)) :
+ ((info->glb_func_idx) - (board_info->port_num));
+ out_oshr_info->func_infos[func_info_idx].partition =
+ ((info->glb_func_idx) / (board_info->port_num)) %
+ HOT_REPLACE_PARTITION_NUM;
+ out_oshr_info->func_infos[func_info_idx].port_id = info->port_id;
+ out_oshr_info->func_infos[func_info_idx].bdf =
+ (info->bus_num << HIGHT_BDF) + info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].bus_num = chip_node->bus_num;
+ out_oshr_info->func_infos[func_info_idx].valid = serivce_enable;
+ memcpy(out_oshr_info->func_infos[func_info_idx].card_name,
+ chip_node->chip_name, IFNAMSIZ);
+}
+
+void hinic3_get_os_hot_replace_info(void *oshr_info)
+{
+ struct os_hot_replace_info *out_oshr_info =
+ (struct os_hot_replace_info *)oshr_info;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dst_dev = NULL;
+ struct hinic3_board_info *board_info = NULL;
+ struct hw_pf_info *infos = NULL;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ struct hinic3_hwdev *hwdev = NULL;
+ u32 func_info_idx = 0, func_id = 0, func_num, serivce_enable = 0;
+ struct list_head *hinic3_chip_list = get_hinic3_chip_list();
+ int err;
+
+ lld_hold();
+ pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ pr_err("kzalloc pf_infos fail\n");
+ lld_put();
+ return;
+ }
+ list_for_each_entry(chip_node, hinic3_chip_list, node) {
+ list_for_each_entry(dst_dev, &chip_node->func_list, node) {
+ err = hinic3_get_hw_pf_infos(dst_dev->hwdev,
+ pf_infos,
+ HINIC3_CHANNEL_COMM);
+ if (err != 0) {
+ pr_err("get pf info failed\n");
+ break;
+ }
+ hwdev = (struct hinic3_hwdev *)dst_dev->hwdev;
+ serivce_enable = 0;
+ infos = pf_infos->infos;
+ board_info = &hwdev->board_info;
+ if (hwdev->hot_replace_mode == HOT_REPLACE_ENABLE)
+ serivce_enable = 1;
+ break;
+ }
+
+ func_num = pf_infos->num_pfs;
+ if (func_num <= 0) {
+ pr_err("get pf num failed\n");
+ break;
+ }
+
+ for (func_id = 0; func_id < func_num; func_id++) {
+ hinic3_write_oshr_info(out_oshr_info, &infos[func_id],
+ board_info, chip_node,
+ serivce_enable, func_info_idx);
+ func_info_idx++;
+ }
+ }
+ out_oshr_info->func_cnt = func_info_idx;
+ kfree(pf_infos);
+ lld_put();
+}
+
struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(lld_dev->pdev);
@@ -608,21 +767,24 @@ void hinic3_get_card_info(const void *hwdev, void *bufin)
if (hinic3_support_nic(fun_hwdev, NULL)) {
if (dev->uld_dev[SERVICE_T_NIC]) {
info->pf[i].pf_type |= (u32)BIT(SERVICE_T_NIC);
- get_dynamic_uld_dev_name(dev, SERVICE_T_NIC, info->pf[i].name);
+ get_dynamic_uld_dev_name(dev, SERVICE_T_NIC,
+ info->pf[i].name);
}
}
if (hinic3_support_ppa(fun_hwdev, NULL)) {
if (dev->uld_dev[SERVICE_T_PPA]) {
info->pf[i].pf_type |= (u32)BIT(SERVICE_T_PPA);
- get_dynamic_uld_dev_name(dev, SERVICE_T_PPA, info->pf[i].name);
+ get_dynamic_uld_dev_name(dev, SERVICE_T_PPA,
+ info->pf[i].name);
}
}
if (hinic3_func_for_mgmt(fun_hwdev))
strscpy(info->pf[i].name, "FOR_MGMT", IFNAMSIZ);
- if (dev->lld_dev.pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID)
+ if (dev->lld_dev.pdev->subsystem_device ==
+ BIFUR_RESOURCE_PF_SSID)
strscpy(info->pf[i].name, "bifur", IFNAMSIZ);
strscpy(info->pf[i].bus_info, pci_name(dev->pcidev),
@@ -721,6 +883,7 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
struct card_node *chip_node = NULL;
unsigned char i;
unsigned char bus_number = 0;
+ int err;
if (chip_node_is_exist(pci_adapter, &bus_number))
return 0;
@@ -746,7 +909,10 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
/* bus number */
chip_node->bus_num = bus_number;
- if (snprintf(chip_node->chip_name, IFNAMSIZ, "%s%u", HINIC3_CHIP_NAME, i) < 0) {
+ snprintf(chip_node->chip_name, IFNAMSIZ, "%s%u", HINIC3_CHIP_NAME, i);
+
+ err = sscanf(chip_node->chip_name, HINIC3_CHIP_NAME "%d", &chip_node->chip_id);
+ if (err <= 0) {
clear_bit(i, &card_bit_map);
kfree(chip_node);
return -EINVAL;
@@ -803,3 +969,36 @@ int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *
return 0;
}
+
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin)
+{
+ struct card_node *chip_node = NULL;
+ struct card_mbox_cnt_info *info = (struct card_mbox_cnt_info *)bufin;
+ struct hinic3_pcidev *dev = NULL;
+ struct hinic3_hwdev *func_hwdev = NULL;
+ u32 i = 0;
+
+ info->func_num = 0;
+ chip_node = hinic3_get_chip_node_by_hwdev(hwdev);
+ if (!chip_node)
+ return;
+
+ lld_hold();
+
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ func_hwdev = (struct hinic3_hwdev *)dev->hwdev;
+ strscpy(info->func_info[i].bus_info, pci_name(dev->pcidev),
+ sizeof(info->func_info[i].bus_info));
+
+ info->func_info[i].send_cnt = func_hwdev->mbox_send_cnt;
+ info->func_info[i].ack_cnt = func_hwdev->mbox_ack_cnt;
+ info->func_num++;
+ i = info->func_num;
+ if (i >= ARRAY_SIZE(info->func_info)) {
+ sdk_err(&dev->pcidev->dev, "chip_node->func_list bigger than pf_max + vf_max\n");
+ break;
+ }
+ }
+
+ lld_put();
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
index 5c7c7cd..9815082 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
@@ -22,8 +22,13 @@
#define BIFUR_RESOURCE_PF_SSID 0x05a1
-#define HINIC3_IS_VF_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_VF)
-#define HINIC3_IS_SPU_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_SPU)
+#define HINIC3_IS_VF_DEV(pdev) \
+ ((pdev)->device == HINIC3_DEV_ID_VF || \
+ (pdev)->device == HINIC3_DEV_SDI_5_1_ID_VF)
+#define HINIC3_IS_SPU_DEV(pdev) \
+ (((pdev)->device == HINIC3_DEV_ID_SPU) || \
+ ((pdev)->device == HINIC3_DEV_ID_SDI_5_0_PF) || \
+ (((pdev)->device == HINIC3_DEV_ID_DPU_PF)))
enum {
HINIC3_NOT_PROBE = 1,
@@ -79,6 +84,13 @@ struct hinic3_pcidev {
u16 probe_fault_level;
u16 rsvd2;
u64 rsvd4;
+
+ struct workqueue_struct *multi_host_mgmt_workq;
+ struct work_struct slave_nic_work;
+ struct work_struct slave_vroce_work;
+
+ struct workqueue_struct *migration_probe_workq;
+ struct delayed_work migration_probe_dwork;
};
struct hinic_chip_info {
@@ -104,4 +116,6 @@ void wait_lld_dev_unused(struct hinic3_pcidev *pci_adapter);
void *hinic3_get_hwdev_by_pcidev(struct pci_dev *pdev);
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
index 11561a0..59ff722 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
@@ -101,7 +101,8 @@ static bool check_image_device_type(struct hinic3_hwdev *hwdev, u32 device_type)
static void encapsulate_update_cmd(struct hinic3_cmd_update_firmware *msg,
struct firmware_section *section_info,
- int *remain_len, u32 *send_len, u32 *send_pos)
+ const int *remain_len, u32 *send_len,
+ u32 *send_pos)
{
memset(msg->data, 0, sizeof(msg->data));
msg->ctl_info.sf = (*remain_len == section_info->section_len) ? true : false;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
index 937d699..be7c82b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
@@ -26,6 +26,8 @@
#include "hinic3_prof_adap.h"
#include "hinic3_eqs.h"
+#include "vram_common.h"
+
#define HINIC3_EQS_WQ_NAME "hinic3_eqs"
#define AEQ_CTRL_0_INTR_IDX_SHIFT 0
@@ -66,7 +68,6 @@
#define HINIC3_TASK_PROCESS_EQE_LIMIT 1024
#define HINIC3_EQ_UPDATE_CI_STEP 64
-/*lint -e806*/
static uint g_aeq_len = HINIC3_DEFAULT_AEQ_LEN;
module_param(g_aeq_len, uint, 0444);
MODULE_PARM_DESC(g_aeq_len,
@@ -83,7 +84,6 @@ static uint g_num_ceqe_in_tasklet = HINIC3_TASK_PROCESS_EQE_LIMIT;
module_param(g_num_ceqe_in_tasklet, uint, 0444);
MODULE_PARM_DESC(g_num_ceqe_in_tasklet,
"The max number of ceqe can be processed in tasklet, default = 1024");
-/*lint +e806*/
#define CEQ_CTRL_0_INTR_IDX_SHIFT 0
#define CEQ_CTRL_0_DMA_ATTR_SHIFT 12
@@ -819,18 +819,22 @@ static int alloc_eq_pages(struct hinic3_eq *eq)
u32 reg, init_val;
u16 pg_idx, i;
int err;
+ gfp_t gfp_vram;
eq->eq_pages = kcalloc(eq->num_pages, sizeof(*eq->eq_pages),
GFP_KERNEL);
if (!eq->eq_pages)
return -ENOMEM;
+ gfp_vram = hi_vram_get_gfp_vram();
+
for (pg_idx = 0; pg_idx < eq->num_pages; pg_idx++) {
eq_page = &eq->eq_pages[pg_idx];
err = hinic3_dma_zalloc_coherent_align(eq->hwdev->dev_hdl,
eq->page_size,
HINIC3_MIN_EQ_PAGE_SIZE,
- GFP_KERNEL, eq_page);
+ GFP_KERNEL | gfp_vram,
+ eq_page);
if (err) {
sdk_err(eq->hwdev->dev_hdl, "Failed to alloc eq page, page index: %u\n",
pg_idx);
@@ -881,6 +885,7 @@ static void free_eq_pages(struct hinic3_eq *eq)
&eq->eq_pages[pg_idx]);
kfree(eq->eq_pages);
+ eq->eq_pages = NULL;
}
static inline u32 get_page_size(const struct hinic3_eq *eq)
@@ -1120,7 +1125,8 @@ int hinic3_aeqs_init(struct hinic3_hwdev *hwdev, u16 num_aeqs,
hwdev->aeqs = aeqs;
aeqs->hwdev = hwdev;
aeqs->num_aeqs = num_aeqs;
- aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME, WQ_MEM_RECLAIM,
+ aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME,
+ WQ_MEM_RECLAIM | WQ_HIGHPRI,
HINIC3_MAX_AEQS);
if (!aeqs->workq) {
sdk_err(hwdev->dev_hdl, "Failed to initialize aeq workqueue\n");
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
index a4cbac8..6b96b87 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
@@ -82,6 +82,48 @@ int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id,
return 0;
}
+/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read and clear to zero
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
+ u16 *value)
+{
+ struct chipif_sml_ctr_rd_req req;
+ union ctr_rd_rsp rsp;
+ int ret;
+
+ if (!hwdev || !value)
+ return -EFAULT;
+
+ if (!COMM_SUPPORT_API_CHAIN((struct hinic3_hwdev *)hwdev))
+ return -EPERM;
+
+ memset(&req, 0, sizeof(req));
+
+ hinic3_sml_ctr_read_build_req(&req, instance,
+ CHIPIF_SM_CTR_OP_READ_CLEAR,
+ CHIPIF_ACK, ctr_id, 0);
+
+ ret = hinic3_api_cmd_read_ack(hwdev, node, (u8 *)&req,
+ (unsigned short)sizeof(req),
+ (void *)&rsp,
+ (unsigned short)sizeof(rsp));
+ if (ret) {
+ sdk_err(((struct hinic3_hwdev *)hwdev)->dev_hdl,
+ "Sm 16bit counter clear fail, err(%d)\n", ret);
+ return ret;
+ }
+ sml_ctr_htonl_n((u32 *)&rsp, sizeof(rsp) / sizeof(u32));
+ *value = rsp.bs_ss16_rsp.value1;
+
+ return 0;
+}
+
/**
* hinic3_sm_ctr_rd32 - small single 32 counter read
* @hwdev: the hardware device
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
index 030ef6d..41c439a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
@@ -34,13 +34,18 @@ static void parse_pub_res_cap_dfx(struct hinic3_hwdev *hwdev,
cap->max_vf);
sdk_info(hwdev->dev_hdl, "Host_pf_num: 0x%x, pf_id_start: 0x%x, host_vf_num: 0x%x, vf_id_start: 0x%x\n",
cap->pf_num, cap->pf_id_start, cap->vf_num, cap->vf_id_start);
- sdk_info(hwdev->dev_hdl, "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x\n",
- cap->host_valid_bitmap, cap->master_host_id, cap->srv_multi_host_mode);
sdk_info(hwdev->dev_hdl,
- "fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
- cap->fake_vf_start_id, cap->fake_vf_num, cap->fake_vf_max_pctx);
- sdk_info(hwdev->dev_hdl, "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x\n",
- cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len);
+ "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x, hot_plug_disable: 0x%x\n",
+ cap->host_valid_bitmap, cap->master_host_id,
+ cap->srv_multi_host_mode, cap->hot_plug_disable);
+ sdk_info(hwdev->dev_hdl,
+ "os_hot_replace: 0x%x, fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
+ cap->os_hot_replace, cap->fake_vf_start_id,
+ cap->fake_vf_num, cap->fake_vf_max_pctx);
+ sdk_info(hwdev->dev_hdl,
+ "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x, bond_create_mode: 0x%x\n",
+ cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len,
+ cap->bond_create_mode);
}
static void parse_cqm_res_cap(struct hinic3_hwdev *hwdev, struct service_cap *cap,
@@ -109,6 +114,9 @@ static void parse_pub_res_cap(struct hinic3_hwdev *hwdev,
cap->host_valid_bitmap = dev_cap->host_valid_bitmap;
cap->master_host_id = dev_cap->master_host_id;
cap->srv_multi_host_mode = dev_cap->srv_multi_host_mode;
+ cap->hot_plug_disable = dev_cap->hot_plug_disable;
+ cap->bond_create_mode = dev_cap->bond_create_mode;
+ cap->os_hot_replace = dev_cap->os_hot_replace;
cap->fake_vf_en = dev_cap->fake_vf_en;
cap->fake_vf_start_bit = dev_cap->fake_vf_start_bit;
cap->fake_vf_end_bit = dev_cap->fake_vf_end_bit;
@@ -148,18 +156,27 @@ static void parse_l2nic_res_cap(struct hinic3_hwdev *hwdev,
nic_cap->max_sqs = dev_cap->nic_max_sq_id + 1;
nic_cap->max_rqs = dev_cap->nic_max_rq_id + 1;
nic_cap->default_num_queues = dev_cap->nic_default_num_queues;
+ nic_cap->outband_vlan_cfg_en = dev_cap->outband_vlan_cfg_en;
+ nic_cap->lro_enable = dev_cap->lro_enable;
sdk_info(hwdev->dev_hdl, "L2nic resource capbility, max_sqs: 0x%x, max_rqs: 0x%x\n",
nic_cap->max_sqs, nic_cap->max_rqs);
/* Check parameters from firmware */
- if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP ||
- nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
- sdk_info(hwdev->dev_hdl, "Number of qp exceed limit[1-%d]: sq: %u, rq: %u\n",
- HINIC3_CFG_MAX_QP, nic_cap->max_sqs, nic_cap->max_rqs);
+ if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of sq exceed limit[1-%d]: sq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_sqs);
nic_cap->max_sqs = HINIC3_CFG_MAX_QP;
+ }
+
+ if (nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of rq exceed limit[1-%d]: rq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_rqs);
nic_cap->max_rqs = HINIC3_CFG_MAX_QP;
}
+
+ if (nic_cap->outband_vlan_cfg_en)
+ sdk_info(hwdev->dev_hdl, "L2nic outband vlan cfg enabled\n");
}
static void parse_fc_res_cap(struct hinic3_hwdev *hwdev,
@@ -333,6 +350,28 @@ static void parse_ipsec_res_cap(struct hinic3_hwdev *hwdev,
dev_cap->ipsec_max_sactx, dev_cap->ipsec_max_cq);
}
+static void parse_vbs_res_cap(struct hinic3_hwdev *hwdev,
+ struct service_cap *cap,
+ struct cfg_cmd_dev_cap *dev_cap,
+ enum func_type type)
+{
+ struct vbs_service_cap *vbs_cap = &cap->vbs_cap;
+
+ vbs_cap->vbs_max_volq = dev_cap->vbs_max_volq;
+ vbs_cap->vbs_main_pf_enable = dev_cap->vbs_main_pf_enable;
+ vbs_cap->vbs_vsock_pf_enable = dev_cap->vbs_vsock_pf_enable;
+ vbs_cap->vbs_fushion_queue_pf_enable = dev_cap->vbs_fushion_queue_pf_enable;
+
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS resource capbility, vbs_max_volq: 0x%x\n",
+ dev_cap->vbs_max_volq);
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS pf info, vbs_main_pf_enable: 0x%x, vbs_vsock_pf_enable: 0x%x, vbs_fushion_queue_pf_enable: 0x%x\n",
+ dev_cap->vbs_main_pf_enable,
+ dev_cap->vbs_vsock_pf_enable,
+ dev_cap->vbs_fushion_queue_pf_enable);
+}
+
static void parse_dev_cap(struct hinic3_hwdev *dev,
struct cfg_cmd_dev_cap *dev_cap, enum func_type type)
{
@@ -375,6 +414,9 @@ static void parse_dev_cap(struct hinic3_hwdev *dev,
if (IS_PPA_TYPE(dev))
parse_ppa_res_cap(dev, cap, dev_cap, type);
+
+ if (IS_VBS_TYPE(dev))
+ parse_vbs_res_cap(dev, cap, dev_cap, type);
}
static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
@@ -404,6 +446,23 @@ static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
return 0;
}
+u8 hinic3_get_bond_create_mode(void *dev)
+{
+ struct hinic3_hwdev *hwdev = NULL;
+ struct service_cap *cap = NULL;
+
+ if (!dev) {
+ pr_err("pointer dev is NULL\n");
+ return -EINVAL;
+ }
+
+ hwdev = (struct hinic3_hwdev *)dev;
+ cap = &hwdev->cfg_mgmt->svc_cap;
+
+ return cap->bond_create_mode;
+}
+EXPORT_SYMBOL(hinic3_get_bond_create_mode);
+
int hinic3_get_dev_cap(void *dev)
{
enum func_type type;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
index 671eed6..2f2310a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
@@ -166,6 +166,11 @@ struct service_cap {
u8 srv_multi_host_mode;
u16 virtio_vq_size;
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 os_hot_replace;
+ u8 rsvd1;
+
u8 timer_pf_num;
u8 timer_pf_id_start;
u16 timer_vf_num;
@@ -335,5 +340,7 @@ void free_capability(struct hinic3_hwdev *dev);
int hinic3_init_vf_dev_cap(void *hwdev);
+u8 hinic3_get_bond_create_mode(void *dev);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
index 8a87d25..8659e0b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
@@ -21,6 +21,7 @@
#include "hinic3_hw_cfg.h"
#include "hinic3_cmdq.h"
#include "mpu_inband_cmd_defs.h"
+#include "vram_common.h"
#include "hinic3_hw_comm.h"
#define HINIC3_MSIX_CNT_LLI_TIMER_SHIFT 0
@@ -242,12 +243,19 @@ int hinic3_func_reset(void *dev, u16 func_id, u64 reset_flag, u16 channel)
struct hinic3_hwdev *hwdev = dev;
u16 out_size = sizeof(func_reset);
int err = 0;
+ int is_in_kexec;
if (!dev) {
pr_err("Invalid para: dev is null.\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ sdk_info(hwdev->dev_hdl, "Skip function reset!\n");
+ return 0;
+ }
+
sdk_info(hwdev->dev_hdl, "Function is reset, flag: 0x%llx, channel:0x%x\n",
reset_flag, channel);
@@ -554,7 +562,7 @@ EXPORT_SYMBOL(hinic3_set_ppf_flr_type);
int hinic3_set_ppf_tbl_hotreplace_flag(void *hwdev, u8 flag)
{
- struct comm_cmd_ppf_tbl_htrp_config htr_info = {0};
+ struct comm_cmd_ppf_tbl_htrp_config htr_info = {};
u16 out_size = sizeof(struct comm_cmd_ppf_tbl_htrp_config);
struct hinic3_hwdev *dev = hwdev;
int ret;
@@ -899,11 +907,19 @@ static int set_ppf_tmr_status(struct hinic3_hwdev *hwdev,
int hinic3_ppf_tmr_start(void *hwdev)
{
+ int is_in_kexec;
+
if (!hwdev) {
pr_err("Hwdev pointer is NULL for starting ppf timer\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ pr_info("Skip starting ppt timer during kexec");
+ return 0;
+ }
+
return set_ppf_tmr_status(hwdev, HINIC_PPF_TMR_FLAG_START);
}
EXPORT_SYMBOL(hinic3_ppf_tmr_start);
@@ -919,18 +935,114 @@ int hinic3_ppf_tmr_stop(void *hwdev)
}
EXPORT_SYMBOL(hinic3_ppf_tmr_stop);
+static int hi_vram_kalloc_align(struct hinic3_hwdev *hwdev, char *name,
+ u32 page_size, u32 page_num,
+ struct hinic3_dma_addr_align *mem_align)
+{
+ void *vaddr = NULL, *align_vaddr = NULL;
+ dma_addr_t paddr, align_paddr;
+ u64 real_size = page_size;
+ u64 align = page_size;
+
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (!vaddr) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ /* align */
+ if (align_paddr == paddr) {
+ align_vaddr = vaddr;
+ goto out;
+ }
+
+ hi_vram_kfree((void *)vaddr, name, real_size);
+
+ /* realloc memory for align */
+ real_size = page_size + align;
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (!vaddr) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc align failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ align_vaddr = (void *)((u64)vaddr + (align_paddr - paddr));
+
+out:
+ mem_align->real_size = (u32)real_size;
+ mem_align->ori_vaddr = vaddr;
+ mem_align->ori_paddr = paddr;
+ mem_align->align_vaddr = align_vaddr;
+ mem_align->align_paddr = align_paddr;
+
+ return 0;
+}
+
+static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
+{
+ u32 i;
+ struct hinic3_dma_addr_align *page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = hwdev->mqm_eqm_vram_name;
+
+ page_addr = hwdev->mqm_att.brm_srch_page_addr;
+
+ for (i = 0; i < hwdev->mqm_att.page_num; i++) {
+ if (is_use_vram != 0) {
+ hi_vram_kfree(page_addr->ori_vaddr,
+ mqm_eqm_vram_name[i].vram_name,
+ page_addr->real_size);
+ } else {
+ hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
+ }
+ page_addr->ori_vaddr = NULL;
+ page_addr++;
+ }
+
+ kfree(mqm_eqm_vram_name);
+ hwdev->mqm_eqm_vram_name = NULL;
+}
+
static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
u32 page_num)
{
struct hinic3_dma_addr_align *page_addr = hwdev->mqm_att.brm_srch_page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = NULL;
u32 valid_num = 0;
u32 flag = 1;
u32 i = 0;
int err;
+ u16 func_id;
+
+ mqm_eqm_vram_name = kcalloc(page_num, sizeof(struct mqm_eqm_vram_name_s), GFP_KERNEL);
+ if (!mqm_eqm_vram_name)
+ return -ENOMEM;
+
+ hwdev->mqm_eqm_vram_name = mqm_eqm_vram_name;
+ func_id = hinic3_global_func_id(hwdev);
for (i = 0; i < page_num; i++) {
- err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl, page_size,
- page_size, GFP_KERNEL, page_addr);
+ if (is_use_vram != 0) {
+ snprintf(mqm_eqm_vram_name[i].vram_name,
+ VRAM_NAME_MAX_LEN, "%s%hu%s%u",
+ VRAM_CQM_GLB_FUNC_BASE, func_id,
+ VRAM_NIC_MQM, i);
+ err = hi_vram_kalloc_align(hwdev,
+ mqm_eqm_vram_name[i].vram_name,
+ page_size, page_num,
+ page_addr);
+ } else {
+ err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl,
+ page_size,
+ page_size,
+ GFP_KERNEL,
+ page_addr);
+ }
if (err) {
flag = 0;
break;
@@ -939,15 +1051,12 @@ static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
page_addr++;
}
+ hwdev->mqm_att.page_num = valid_num;
+
if (flag == 1) {
hwdev->mqm_att.page_size = page_size;
- hwdev->mqm_att.page_num = page_num;
} else {
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
- for (i = 0; i < valid_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
+ mqm_eqm_free_page_mem(hwdev);
return -EFAULT;
}
@@ -986,19 +1095,6 @@ static int mqm_eqm_alloc_page_mem(struct hinic3_hwdev *hwdev)
return ret;
}
-static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
-{
- u32 i;
- struct hinic3_dma_addr_align *page_addr;
-
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
-
- for (i = 0; i < hwdev->mqm_att.page_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
-}
-
static int mqm_eqm_set_cfg_2_hw(struct hinic3_hwdev *hwdev, u8 valid)
{
struct comm_cmd_eqm_cfg info_eqm_cfg;
@@ -1129,6 +1225,7 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
{
struct comm_cmd_get_eqm_num info_eqm_fix;
int ret;
+ int is_in_kexec;
if (hwdev->hwif->attr.func_type != TYPE_PPF)
return 0;
@@ -1158,10 +1255,16 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
goto err_page;
}
- ret = mqm_eqm_set_page_2_hw(hwdev);
- if (ret) {
- sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
- goto err_ecmd;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ ret = mqm_eqm_set_page_2_hw(hwdev);
+ if (ret) {
+ sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
+ goto err_ecmd;
+ }
+ } else {
+ sdk_info(hwdev->dev_hdl,
+ "Mqm db don't set to chip when os hot replace.\r\n");
}
ret = mqm_eqm_set_cfg_2_hw(hwdev, 1);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
index e8aa7ef..722fecd 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
@@ -252,97 +252,6 @@ static u32 get_up_timeout_val(enum hinic3_mod_type mod, u16 cmd)
return 0; /* use default mbox/apichain timeout time */
}
-static int api_csr_read(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
-{
- struct up_log_msg_st *up_log_msg = (struct up_log_msg_st *)buf_in;
- u8 *buf_out_tmp = (u8 *)buf_out;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
-
- if (!buf_in || !buf_out || in_size != sizeof(*up_log_msg) ||
- *out_size != up_log_msg->rd_len || up_log_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = up_log_msg->rd_len;
- rd_addr = up_log_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_rd32(hwdev, node_id,
- rd_addr + offset,
- (u32 *)(buf_out_tmp + offset));
- if (ret) {
- pr_err("Csr rd fail, err: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, node_id, rd_addr + offset);
- return ret;
- }
- offset += DW_WIDTH;
- }
- *out_size = rd_len;
-
- return ret;
-}
-
-static int api_csr_write(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out,
- u32 *out_size)
-{
- struct csr_write_st *csr_write_msg = (struct csr_write_st *)buf_in;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
- u8 *data = NULL;
-
- if (!buf_in || in_size != sizeof(*csr_write_msg) || csr_write_msg->rd_len == 0 ||
- csr_write_msg->rd_len > API_CSR_MAX_RD_LEN || csr_write_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = csr_write_msg->rd_len;
- rd_addr = csr_write_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- data = kzalloc(rd_len, GFP_KERNEL);
- if (!data)
- return -EFAULT;
-
- if (copy_from_user(data, (void *)csr_write_msg->data, rd_len)) {
- pr_err("Copy information from user failed\n");
- kfree(data);
- return -EFAULT;
- }
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_wr32(hwdev, node_id,
- rd_addr + offset,
- *((u32 *)(data + offset)));
- if (ret) {
- pr_err("Csr wr fail, ret: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, rd_addr + offset, node_id);
- kfree(data);
- return ret;
- }
- offset += DW_WIDTH;
- }
-
- *out_size = 0;
- kfree(data);
- return ret;
-}
-
int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
@@ -369,10 +278,8 @@ int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
return ret;
}
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_BYPASS) {
- if (nt_msg->mpu_cmd.cmd == API_CSR_WRITE)
- return api_csr_write(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
-
- ret = api_csr_read(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
+ pr_err("Unsupported api_type %u\n", nt_msg->mpu_cmd.api_type);
+ return -EINVAL;
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_TO_MPU) {
timeout = get_up_timeout_val(mod, cmd);
if (hinic3_pcie_itf_id(hwdev) != SPU_HOST_ID)
@@ -439,6 +346,23 @@ static int sm_rd16(void *hwdev, u32 id, u8 instance,
return ret;
}
+static int sm_rd16_clear(void *hwdev, u32 id, u8 instance,
+ u8 node, struct sm_out_st *buf_out)
+{
+ u16 val1;
+ int ret;
+
+ ret = hinic3_sm_ctr_rd16_clear(hwdev, node, instance, id, &val1);
+ if (ret != 0) {
+ pr_err("Get sm ctr clear information (16 bits)failed!\n");
+ val1 = 0xffff;
+ }
+
+ buf_out->val1 = val1;
+
+ return ret;
+}
+
static int sm_rd32(void *hwdev, u32 id, u8 instance,
u8 node, struct sm_out_st *buf_out)
{
@@ -558,6 +482,7 @@ const struct sm_module_handle sm_module_cmd_handle[] = {
{SM_CTR_RD32, sm_rd32},
{SM_CTR_RD64_PAIR, sm_rd64_pair},
{SM_CTR_RD64, sm_rd64},
+ {SM_CTR_RD16_CLEAR, sm_rd16_clear},
{SM_CTR_RD32_CLEAR, sm_rd32_clear},
{SM_CTR_RD64_PAIR_CLEAR, sm_rd64_pair_clear},
{SM_CTR_RD64_CLEAR, sm_rd64_clear}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
index 83e7b63..c317f4a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
@@ -101,6 +101,12 @@ enum hinic3_pcie_tph {
#define SLAVE_HOST_STATUS_SET(host_id, enable) (((u8)(enable) & 1U) << (host_id))
#define SLAVE_HOST_STATUS_GET(host_id, val) (!!((val) & (1U << (host_id))))
+#ifdef HAVE_HOT_REPLACE_FUNC
+ extern int get_partition_id(void);
+#else
+ static int get_partition_id(void) {return 0; }
+#endif
+
void set_slave_host_enable(void *hwdev, u8 host_id, bool enable)
{
u32 reg_val;
@@ -207,6 +213,27 @@ static void hinic3_init_host_mode_pre(struct hinic3_hwdev *hwdev)
}
}
+static void hinic3_init_hot_plug_status(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->hot_plug_disable)
+ hwdev->hot_plug_mode = HOT_PLUG_DISABLE;
+ else
+ hwdev->hot_plug_mode = HOT_PLUG_ENABLE;
+}
+
+static void hinic3_init_os_hot_replace(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->os_hot_replace) {
+ hwdev->hot_replace_mode = HOT_REPLACE_ENABLE;
+ } else {
+ hwdev->hot_replace_mode = HOT_REPLACE_DISABLE;
+ }
+}
+
static u8 hinic3_nic_sw_aeqe_handler(void *hwdev, u8 event, u8 *data)
{
struct hinic3_hwdev *dev = hwdev;
@@ -270,14 +297,20 @@ static void chip_fault_show(struct hinic3_hwdev *hwdev,
"fatal", "reset", "host", "flr", "general", "suggestion"};
char level_str[FAULT_SHOW_STR_LEN + 1];
u8 level;
+ int ret;
memset(level_str, 0, FAULT_SHOW_STR_LEN + 1);
level = event->event.chip.err_level;
- if (level < FAULT_LEVEL_MAX)
- strscpy(level_str, fault_level[level],
- FAULT_SHOW_STR_LEN);
- else
- strscpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (level < FAULT_LEVEL_MAX) {
+ ret = strscpy(level_str, fault_level[level],
+ FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ } else {
+ ret = strscpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ }
if (level == FAULT_LEVEL_SERIOUS_FLR)
dev_err(hwdev->dev_hdl, "err_level: %u [%s], flr func_id: %u\n",
@@ -299,6 +332,7 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
"reg rd timeout", "reg wr timeout", "phy fault", "tsensor fault"};
char type_str[FAULT_SHOW_STR_LEN + 1] = {0};
struct fault_event_stats *fault = NULL;
+ int ret;
sdk_err(hwdev->dev_hdl, "Fault event report received, func_id: %u\n",
hinic3_global_func_id(hwdev));
@@ -306,10 +340,14 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
fault = &hwdev->hw_stats.fault_event_stats;
if (event->type < FAULT_TYPE_MAX) {
- strscpy(type_str, fault_type[event->type], sizeof(type_str));
+ ret = strscpy(type_str, fault_type[event->type], sizeof(type_str));
+ if (ret < 0)
+ return;
atomic_inc(&fault->fault_type_stat[event->type]);
} else {
- strscpy(type_str, "Unknown", sizeof(type_str));
+ ret = strscpy(type_str, "Unknown", sizeof(type_str));
+ if (ret < 0)
+ return;
}
sdk_err(hwdev->dev_hdl, "Fault type: %u [%s]\n", event->type, type_str);
@@ -1536,15 +1574,29 @@ int hinic3_init_hwdev(struct hinic3_init_para *para)
hinic3_init_host_mode_pre(hwdev);
+ hinic3_init_hot_plug_status(hwdev);
+
+ hinic3_init_os_hot_replace(hwdev);
+
err = hinic3_multi_host_mgmt_init(hwdev);
if (err != 0) {
sdk_err(hwdev->dev_hdl, "Failed to init function mode\n");
goto init_multi_host_fail;
}
- err = hinic3_init_ppf_work(hwdev);
- if (err != 0)
- goto init_ppf_work_fail;
+ // hot_replace_mode is enable, run ppf function only when partition_id is 0
+ // or run ppf function directly
+ if (hwdev->hot_replace_mode == HOT_REPLACE_ENABLE) {
+ if (get_partition_id() == 0) {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0)
+ goto init_ppf_work_fail;
+ }
+ } else {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0)
+ goto init_ppf_work_fail;
+ }
err = hinic3_set_comm_features(hwdev, hwdev->features, COMM_MAX_FEATURE_QWORD);
if (err != 0) {
@@ -1948,6 +2000,19 @@ void hinic3_link_event_stats(void *dev, u8 link)
}
EXPORT_SYMBOL(hinic3_link_event_stats);
+int hinic3_get_link_event_stats(void *dev, int *link_state)
+{
+ struct hinic3_hwdev *hwdev = dev;
+
+ if (!hwdev || !link_state)
+ return -EINVAL;
+
+ *link_state = hwdev->hw_stats.link_event_stats.link_down_stats.counter;
+
+ return 0;
+}
+EXPORT_SYMBOL(hinic3_get_link_event_stats);
+
u8 hinic3_max_pf_num(void *hwdev)
{
if (!hwdev)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
index b8a3356..0ca639f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
@@ -10,6 +10,7 @@
#include "hinic3_hw.h"
#include "mpu_inband_cmd_defs.h"
#include "hinic3_profile.h"
+#include "vram_common.h"
struct cfg_mgmt_info;
@@ -82,6 +83,22 @@ enum hinic3_host_mode_e {
HINIC3_SDI_MODE_MAX,
};
+enum hinic3_hot_plug_mode {
+ HOT_PLUG_ENABLE,
+ HOT_PLUG_DISABLE,
+};
+
+enum hinic3_os_hot_replace_mode {
+ HOT_REPLACE_DISABLE,
+ HOT_REPLACE_ENABLE,
+};
+
+#define UNSUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_DISABLE)
+
+#define SUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_ENABLE)
+
#define MULTI_HOST_CHIP_MODE_SHIFT 0
#define MULTI_HOST_MASTER_MBX_STS_SHIFT 17
#define MULTI_HOST_PRIV_DATA_SHIFT 0x8
@@ -100,6 +117,10 @@ enum hinic3_host_mode_e {
((val) & (~(MULTI_HOST_##member##_MASK \
<< MULTI_HOST_##member##_SHIFT)))
+struct mqm_eqm_vram_name_s {
+ char vram_name[VRAM_NAME_MAX_LEN];
+};
+
struct hinic3_hwdev {
void *adapter_hdl; /* pointer to hinic3_pcidev or NDIS_Adapter */
void *pcidev_hdl; /* pointer to pcidev or Handler */
@@ -138,6 +159,9 @@ struct hinic3_hwdev {
u32 rsvd2;
struct hinic3_multi_host_mgmt *mhost_mgmt;
+ char mhost_mgmt_name[VRAM_NAME_MAX_LEN];
+
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name;
struct mutex stateful_mutex; /* protect cqm init and deinit */
@@ -170,6 +194,8 @@ struct hinic3_hwdev {
struct hinic3_devlink *devlink_dev;
enum hinic3_func_mode func_mode;
+ enum hinic3_hot_plug_mode hot_plug_mode;
+ enum hinic3_os_hot_replace_mode hot_replace_mode;
u32 rsvd3;
DECLARE_BITMAP(func_probe_in_host, MAX_FUNCTION_NUM);
@@ -179,7 +205,10 @@ struct hinic3_hwdev {
u64 last_recv_aeq_cnt;
u16 aeq_busy_cnt;
- u64 rsvd4[8];
+ u64 mbox_send_cnt;
+ u64 mbox_ack_cnt;
+
+ u64 rsvd4[5];
u8 cmdq_mode;
};
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
index 33f1210..8590f70 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
@@ -544,6 +544,7 @@ static void free_db_area(struct hinic3_free_db_area *free_db_area)
{
spin_lock_deinit(&free_db_area->idx_lock);
kfree(free_db_area->db_bitmap_array);
+ free_db_area->db_bitmap_array = NULL;
}
static int get_db_idx(struct hinic3_hwif *hwif, u32 *idx)
@@ -841,6 +842,7 @@ void hinic3_free_hwif(struct hinic3_hwdev *hwdev)
free_db_area(&hwdev->hwif->free_db_area);
enable_all_msix(hwdev);
kfree(hwdev->hwif);
+ hwdev->hwif = NULL;
}
u16 hinic3_global_func_id(void *hwdev)
@@ -856,6 +858,44 @@ u16 hinic3_global_func_id(void *hwdev)
}
EXPORT_SYMBOL(hinic3_global_func_id);
+/**
+ * get function id from register,used by sriov hot migration process
+ * @hwdev: the pointer to hw device
+ */
+u16 hinic3_global_func_id_hw(void *hwdev)
+{
+ u32 addr, attr0;
+ struct hinic3_hwdev *dev;
+
+ dev = (struct hinic3_hwdev *)hwdev;
+ addr = HINIC3_CSR_FUNC_ATTR0_ADDR;
+ attr0 = hinic3_hwif_read_reg(dev->hwif, addr);
+
+ return HINIC3_AF0_GET(attr0, FUNC_GLOBAL_IDX);
+}
+
+/**
+ * get function id, used by sriov hot migratition process.
+ * @hwdev: the pointer to hw device
+ * @func_id: function id
+ */
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id)
+{
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)hwdev;
+
+ if (!hwdev || !func_id)
+ return -EINVAL;
+
+ /* only vf get func_id from chip reg for sriov migrate */
+ if (!HINIC3_IS_VF(dev)) {
+ *func_id = hinic3_global_func_id(hwdev);
+ return 0;
+ }
+
+ *func_id = hinic3_global_func_id_hw(dev);
+ return 0;
+}
+
u16 hinic3_intr_num(void *hwdev)
{
struct hinic3_hwif *hwif = NULL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
index 6ab1b92..b7f9db5 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
@@ -16,6 +16,7 @@
#include <linux/rtc.h>
#include <linux/aer.h>
#include <linux/debugfs.h>
+#include <linux/notifier.h>
#include "ossl_knl.h"
#include "hinic3_mt.h"
@@ -26,13 +27,38 @@
#include "hinic3_dev_mgmt.h"
#include "hinic3_nictool.h"
#include "hinic3_hw.h"
+#include "hinic3_multi_host_mgmt.h"
+#include "hinic3_hw_cfg.h"
#include "hinic3_lld.h"
#include "hinic3_profile.h"
#include "hinic3_hwdev.h"
#include "hinic3_prof_adap.h"
-#include "comm_msg_intf.h"
+#include "hinic3_devlink.h"
+#include "vram_common.h"
+
+enum partition_dev_type {
+ PARTITION_DEV_NONE = 0,
+ PARTITION_DEV_SHARED,
+ PARTITION_DEV_EXCLUSIVE,
+ PARTITION_DEV_BACKUP,
+};
+
+#ifdef HAVE_HOT_REPLACE_FUNC
+static int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type,
+ unsigned int partition_id);
+static int get_partition_id(void);
+#else
+static int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type,
+ unsigned int partition_id)
+{
+ return 0;
+}
+static int get_partition_id(void) { return 0; }
+#endif
+
+static bool g_is_pf_migrated;
static bool disable_vf_load;
module_param(disable_vf_load, bool, 0444);
MODULE_PARM_DESC(disable_vf_load,
@@ -44,10 +70,12 @@ MODULE_PARM_DESC(disable_attach, "disable_attach or not - default is false");
#define HINIC3_WAIT_SRIOV_CFG_TIMEOUT 15000
-MODULE_AUTHOR("Huawei Technologies CO., Ltd");
-MODULE_DESCRIPTION(HINIC3_DRV_DESC);
-MODULE_VERSION(HINIC3_DRV_VERSION);
-MODULE_LICENSE("GPL");
+#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
+static DEVICE_ATTR_RW(sriov_numvfs, 0644,
+ sriov_numvfs_show, sriov_numvfs_store);
+static DEVICE_ATTR_RO(sriov_totalvfs, 0444,
+ sriov_totalvfs_show, NULL);
+#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
static struct attribute *hinic3_attributes[] = {
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
@@ -64,7 +92,18 @@ static const struct attribute_group hinic3_attr_group = {
struct hinic3_uld_info g_uld_info[SERVICE_T_MAX] = { {0} };
#define HINIC3_EVENT_PROCESS_TIMEOUT 10000
+#define HINIC3_WAIT_EVENT_PROCESS_TIMEOUT 100
struct mutex g_uld_mutex; /* g_uld_info lock */
+#define BUS_MAX_DEV_NUM 256
+#define HINIC3_SLAVE_WORK_MAX_NUM 20
+
+struct vf_offset_info {
+ u8 valid;
+ u16 vf_offset_from_pf[CMD_MAX_MAX_PF_NUM];
+};
+
+static struct vf_offset_info g_vf_offset;
+DEFINE_MUTEX(g_vf_offset_lock);
void hinic3_uld_lock_init(void)
{
@@ -73,13 +112,23 @@ void hinic3_uld_lock_init(void)
static const char *s_uld_name[SERVICE_T_MAX] = {
"nic", "ovs", "roce", "toe", "ioe",
- "fc", "vbs", "ipsec", "virtio", "migrate", "ppa", "bifur", "custom"};
+ "fc", "vbs", "ipsec", "virtio", "migrate",
+ "ppa", "custom", "vroce", "crypt", "vsock", "bifur"};
const char **hinic3_get_uld_names(void)
{
return s_uld_name;
}
+#ifdef CONFIG_PCI_IOV
+static int hinic3_get_pf_device_id(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_dev = pci_physfn(pdev);
+
+ return pf_dev->device;
+}
+#endif
+
static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
const struct hinic3_uld_info *uld_info)
{
@@ -98,6 +147,10 @@ static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
atomic_set(&dev->uld_ref_cnt[type], 0);
+ if (!uld_info->probe) {
+ err = 0;
+ goto out_unlock;
+ }
err = uld_info->probe(&dev->lld_dev, &uld_dev, dev->uld_dev_name[type]);
if (err) {
sdk_err(&dev->pcidev->dev,
@@ -166,6 +219,10 @@ static void detach_uld(struct hinic3_pcidev *dev,
wait_uld_unused(dev, type);
+ if (!uld_info->remove) {
+ mutex_unlock(&dev->pdev_mutex);
+ return;
+ }
uld_info->remove(&dev->lld_dev, dev->uld_dev[type]);
dev->uld_dev[type] = NULL;
@@ -182,11 +239,14 @@ static void attach_ulds(struct hinic3_pcidev *dev)
{
enum hinic3_service_type type;
struct pci_dev *pdev = dev->pcidev;
+ int is_in_kexec = vram_get_kexec_flag();
+
+ if (is_in_kexec == 0)
+ lld_hold();
- lld_hold();
mutex_lock(&g_uld_mutex);
- for (type = SERVICE_T_NIC; type < SERVICE_T_MAX; type++) {
+ for (type = SERVICE_T_OVS; type < SERVICE_T_MAX; type++) {
if (g_uld_info[type].probe) {
if (pdev->is_virtfn &&
(!hinic3_get_vf_service_load(pdev, (u16)type))) {
@@ -198,7 +258,9 @@ static void attach_ulds(struct hinic3_pcidev *dev)
}
}
mutex_unlock(&g_uld_mutex);
- lld_put();
+
+ if (is_in_kexec == 0)
+ lld_put();
}
static void detach_ulds(struct hinic3_pcidev *dev)
@@ -305,7 +367,7 @@ void hinic3_unregister_uld(enum hinic3_service_type type)
}
uld_info = &g_uld_info[type];
- memset(uld_info, 0, sizeof(*uld_info));
+ memset(uld_info, 0, sizeof(struct hinic3_uld_info));
mutex_unlock(&g_uld_mutex);
lld_put();
}
@@ -359,6 +421,26 @@ void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_ser
}
EXPORT_SYMBOL(hinic3_detach_service);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ __module_get(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_get);
+
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ module_put(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_put);
+
static void hinic3_sync_time_to_fmw(struct hinic3_pcidev *pdev_pri)
{
struct timeval tv = {0};
@@ -441,23 +523,445 @@ static void send_event_to_all_pf(struct hinic3_pcidev *dev,
lld_put();
}
+u32 hinic3_pdev_is_virtfn(struct pci_dev *pdev)
+{
+#ifdef CONFIG_PCI_IOV
+ return pdev->is_virtfn;
+#else
+ return 0;
+#endif
+}
+
+static int hinic3_get_function_enable(struct pci_dev *pdev, bool *en)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+ int err;
+
+ /* PF in host os or function in guest os, probe sdk in default */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev) {
+ *en = true;
+ return 0;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev) {
+ /* vf in host and pf sdk not probed */
+ return -EFAULT;
+ }
+ pf_hwdev = pci_adapter->hwdev;
+
+ err = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (err) {
+ sdk_err(&pci_adapter->pcidev->dev,
+ "Func hinic3_get_vfid_by_vfpci fail %d\n", err);
+ return err;
+ }
+
+ err = hinic3_get_func_nic_enable(pf_hwdev, global_func_id, en);
+ if (!!err) {
+ sdk_info(&pdev->dev, "Failed to get function nic status, err %d.\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+int hinic3_set_func_probe_in_host(void *hwdev, u16 func_id, bool probe)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (hinic3_func_type(hwdev) != TYPE_PPF)
+ return -EINVAL;
+
+ if (probe)
+ set_bit(func_id, dev->func_probe_in_host);
+ else
+ clear_bit(func_id, dev->func_probe_in_host);
+
+ return 0;
+}
+
+bool hinic3_get_func_probe_in_host(void *hwdev, u16 func_id)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+ bool probed = false;
+
+ if (!hwdev)
+ return false;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return false;
+ }
+
+ probed = !!test_bit(func_id, ppf_dev->func_probe_in_host);
+ up(&dev->ppf_sem);
+
+ return probed;
+}
+
+void *hinic3_get_ppf_hwdev_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ chip_node = pci_adapter->chip_node;
+ lld_dev_hold(&pci_adapter->lld_dev);
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (dev->lld_state == HINIC3_IN_REMOVE)
+ continue;
+
+ if (dev->hwdev && hinic3_func_type(dev->hwdev) == TYPE_PPF) {
+ lld_dev_put(&pci_adapter->lld_dev);
+ return dev->hwdev;
+ }
+ }
+ lld_dev_put(&pci_adapter->lld_dev);
+
+ return NULL;
+}
+
+static int hinic3_set_vf_nic_used_state(void *hwdev, u16 func_id, bool opened)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+
+ if (!dev || func_id >= MAX_FUNCTION_NUM)
+ return -EINVAL;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return -EINVAL;
+ }
+
+ if (opened)
+ set_bit(func_id, ppf_dev->netdev_setup_state);
+ else
+ clear_bit(func_id, ppf_dev->netdev_setup_state);
+
+ up(&dev->ppf_sem);
+
+ return 0;
+}
+
+static void set_vf_func_in_use(struct pci_dev *pdev, bool in_use)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+
+ /* only need to be set when VF is on the host */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev)
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev)
+ return;
+
+ pf_hwdev = pci_adapter->hwdev;
+
+ global_func_id = (u16)pdev->devfn + hinic3_glb_pf_vf_offset(pf_hwdev);
+ (void)hinic3_set_vf_nic_used_state(pf_hwdev, global_func_id, in_use);
+}
+
+static int hinic3_pf_get_vf_offset_info(struct hinic3_pcidev *des_dev, u16 *vf_offset)
+{
+ int err, i;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ u16 pf_func_id;
+ struct hinic3_pcidev *pf_pci_adapter = NULL;
+
+ pf_pci_adapter = (hinic3_pdev_is_virtfn(des_dev->pcidev)) ?
+ pci_get_drvdata(des_dev->pcidev->physfn) : des_dev;
+ pf_func_id = hinic3_global_func_id(pf_pci_adapter->hwdev);
+ if (pf_func_id >= CMD_MAX_MAX_PF_NUM || !vf_offset)
+ return -EINVAL;
+
+ mutex_lock(&g_vf_offset_lock);
+ if (g_vf_offset.valid == 0) {
+ pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ err = -ENOMEM;
+ goto err_malloc;
+ }
+
+ err = hinic3_get_hw_pf_infos(pf_pci_adapter->hwdev,
+ pf_infos, HINIC3_CHANNEL_COMM);
+ if (err) {
+ sdk_warn(&pf_pci_adapter->pcidev->dev,
+ "Hinic3_get_hw_pf_infos fail err %d\n", err);
+ err = -EFAULT;
+ goto err_out;
+ }
+
+ g_vf_offset.valid = 1;
+ for (i = 0; i < CMD_MAX_MAX_PF_NUM; i++)
+ g_vf_offset.vf_offset_from_pf[i] = pf_infos->infos[i].vf_offset;
+
+ kfree(pf_infos);
+ }
+
+ *vf_offset = g_vf_offset.vf_offset_from_pf[pf_func_id];
+
+ mutex_unlock(&g_vf_offset_lock);
+
+ return 0;
+
+err_out:
+ kfree(pf_infos);
+err_malloc:
+ mutex_unlock(&g_vf_offset_lock);
+ return err;
+}
+
+static struct pci_dev *get_vf_pdev_by_pf(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ int err;
+ u16 bus_num;
+ u16 vf_start, vf_end;
+ u16 des_fn, pf_func_id, vf_offset;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ pf_func_id = hinic3_global_func_id(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end || pf_func_id >= CMD_MAX_MAX_PF_NUM)
+ return NULL;
+
+ err = hinic3_pf_get_vf_offset_info(des_dev, &vf_offset);
+ if (err) {
+ sdk_warn(&des_dev->pcidev->dev, "Hinic3_pf_get_vf_offset_info fail\n");
+ return NULL;
+ }
+
+ des_fn = ((func_id - vf_start) - 1) + pf_func_id + vf_offset;
+ bus_num = des_dev->pcidev->bus->number + des_fn / BUS_MAX_DEV_NUM;
+
+ return pci_get_domain_bus_and_slot(0, bus_num, (des_fn % BUS_MAX_DEV_NUM));
+}
+
+static struct hinic3_pcidev *get_des_pci_adapter(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ struct pci_dev *des_pdev = NULL;
+ u16 vf_start, vf_end;
+ bool probe_in_host = false;
+
+ if (hinic3_global_func_id(des_dev->hwdev) == func_id)
+ return des_dev;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end)
+ return NULL;
+
+ des_pdev = get_vf_pdev_by_pf(des_dev, func_id);
+ if (!des_pdev)
+ return NULL;
+
+ pci_dev_put(des_pdev);
+
+ probe_in_host = hinic3_get_func_probe_in_host(des_dev->hwdev, func_id);
+ if (!probe_in_host)
+ return NULL;
+
+ return pci_get_drvdata(des_pdev);
+}
+
+int __set_vroce_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ u8 enable_vroce = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_vroce_enable(pci_adapter->hwdev,
+ func_id, &enable_vroce);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Failed to get vroce state.\n");
+ return err;
+ }
+
+ mutex_lock(&g_uld_mutex);
+
+ if (!!enable_vroce) {
+ if (!g_uld_info[SERVICE_T_ROCE].probe) {
+ sdk_info(&pdev->dev, "Uld(roce_info) has not been registered!\n");
+ mutex_unlock(&g_uld_mutex);
+ return 0;
+ }
+
+ err = attach_uld(pci_adapter, SERVICE_T_ROCE,
+ &g_uld_info[SERVICE_T_ROCE]);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Failed to initialize VROCE.\n");
+ mutex_unlock(&g_uld_mutex);
+ return err;
+ }
+ } else {
+ sdk_info(&pdev->dev, "Func %u vroce state: disable.\n", func_id);
+ if (g_uld_info[SERVICE_T_ROCE].remove)
+ detach_uld(pci_adapter, SERVICE_T_ROCE);
+ }
+
+ mutex_unlock(&g_uld_mutex);
+
+ return 0;
+}
+
+void slave_host_mgmt_vroce_work(struct work_struct *work)
+{
+#ifndef __HIFC__
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_vroce_work);
+
+ __set_vroce_func_state(pci_adapter);
+#endif
+}
+
+void *hinic3_get_roce_uld_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ return pci_adapter->uld_dev[SERVICE_T_ROCE];
+}
+
+static int func_service_state_process(struct hinic3_pcidev *event_dev,
+ struct hinic3_pcidev *des_dev,
+ struct hinic3_mhost_nic_func_state *state,
+ u16 cmd)
+{
+ int err = 0;
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)event_dev->hwdev;
+
+ switch (cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ state->enable = hinic3_get_roce_uld_by_pdev(des_dev->pcidev) ? 1 : 0;
+ break;
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive nic[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ if (event_dev->multi_host_mgmt_workq) {
+ queue_work(event_dev->multi_host_mgmt_workq,
+ &des_dev->slave_nic_work);
+ } else {
+ sdk_err(&des_dev->pcidev->dev, "Can not schedule slave nic work\n");
+ err = -EFAULT;
+ }
+ break;
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive vroce[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ queue_work_on(hisdk3_get_work_cpu_affinity(dev, WORK_TYPE_MBOX),
+ event_dev->multi_host_mgmt_workq,
+ &des_dev->slave_vroce_work);
+ break;
+ default:
+ sdk_warn(&des_dev->pcidev->dev,
+ "Service state process with unknown cmd: %u\n", cmd);
+ err = -EFAULT;
+ break;
+ }
+
+ return err;
+}
+
+static void multi_host_mgmt(struct hinic3_pcidev *dev,
+ struct hinic3_multi_host_mgmt_event *mhost_mgmt)
+{
+ struct hinic3_pcidev *cur_dev = NULL;
+ struct hinic3_pcidev *des_dev = NULL;
+ struct hinic3_mhost_nic_func_state *nic_state = NULL;
+ u16 sub_cmd = mhost_mgmt->sub_cmd;
+
+ switch (sub_cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ nic_state = mhost_mgmt->data;
+ nic_state->status = 0;
+ if (!dev->hwdev)
+ return;
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)dev->hwdev))
+ return;
+
+ /* find func_idx pci_adapter and disable or enable nic */
+ lld_dev_hold(&dev->lld_dev);
+ list_for_each_entry(cur_dev, &dev->chip_node->func_list, node) {
+ if (cur_dev->lld_state == HINIC3_IN_REMOVE ||
+ hinic3_pdev_is_virtfn(cur_dev->pcidev))
+ continue;
+
+ des_dev = get_des_pci_adapter(cur_dev, nic_state->func_idx);
+ if (!des_dev)
+ continue;
+
+ if (func_service_state_process(dev, des_dev, nic_state, sub_cmd))
+ nic_state->status = 1;
+ break;
+ }
+ lld_dev_put(&dev->lld_dev);
+ break;
+ default:
+ sdk_warn(&dev->pcidev->dev, "Received unknown multi-host mgmt event: %u\n",
+ mhost_mgmt->sub_cmd);
+ break;
+ }
+}
+
static void hinic3_event_process(void *adapter, struct hinic3_event_info *event)
{
struct hinic3_pcidev *dev = adapter;
struct hinic3_fault_event *fault = (void *)event->event_data;
+ struct hinic3_multi_host_mgmt_event *mhost_event =
+ (void *)event->event_data;
u16 func_id;
- if ((event->service == EVENT_SRV_COMM && event->type == EVENT_COMM_FAULT) &&
- fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
- fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
- func_id = fault->event.chip.func_id;
- return send_event_to_dst_pf(adapter, func_id, event);
- }
-
- if (event->type == EVENT_COMM_MGMT_WATCHDOG)
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MULTI_HOST_MGMT):
+ multi_host_mgmt(dev, mhost_event);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_FAULT):
+ if (fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
+ fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
+ func_id = fault->event.chip.func_id;
+ return send_event_to_dst_pf(adapter, func_id, event);
+ }
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MGMT_WATCHDOG):
send_event_to_all_pf(adapter, event);
- else
+ break;
+ default:
send_uld_dev_event(adapter, event);
+ break;
+ }
}
static void uld_def_init(struct hinic3_pcidev *pci_adapter)
@@ -605,31 +1109,70 @@ static void hinic3_pci_deinit(struct pci_dev *pdev)
kfree(pci_adapter);
}
-#ifdef CONFIG_X86
-/**
- * cfg_order_reg - when cpu model is haswell or broadwell, should configure dma
- * order register to zero
- * @pci_adapter: pci_adapter
- **/
-/*lint -save -e40 */
-static void cfg_order_reg(struct hinic3_pcidev *pci_adapter)
+static void set_vf_load_state(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
{
- u8 cpu_model[] = {0x3c, 0x3f, 0x45, 0x46, 0x3d, 0x47, 0x4f, 0x56};
- struct cpuinfo_x86 *cpuinfo = NULL;
- u32 i;
+ /* In bm mode, slave host will load vfs in default */
+ if (IS_BMGW_SLAVE_HOST(((struct hinic3_hwdev *)pci_adapter->hwdev)) &&
+ hinic3_func_type(pci_adapter->hwdev) != TYPE_VF)
+ hinic3_set_vf_load_state(pdev, false);
- if (hinic3_func_type(pci_adapter->hwdev) == TYPE_VF)
- return;
+ if (!disable_attach) {
+ if ((hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) &&
+ hinic3_is_bm_slave_host(pci_adapter->hwdev)) {
+ if (hinic3_func_max_vf(pci_adapter->hwdev) == 0) {
+ sdk_warn(&pdev->dev, "The sriov enabling process is skipped, vfs_num: 0.\n");
+ return;
+ }
+ hinic3_pci_sriov_enable(pdev,
+ hinic3_func_max_vf(pci_adapter->hwdev));
+ }
+ }
+}
- cpuinfo = &cpu_data(0);
- for (i = 0; i < sizeof(cpu_model); i++) {
- if (cpu_model[i] == cpuinfo->x86_model)
- hinic3_set_pcie_order_cfg(pci_adapter->hwdev);
+static void hinic3_init_ppf_hwdev(struct hinic3_hwdev *hwdev)
+{
+ if (!hwdev) {
+ pr_err("[%s:%d] null hwdev pointer\n", __FILE__, __LINE__);
+ return;
}
+
+ hwdev->ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(hwdev->pcidev_hdl);
}
-/*lint -restore*/
-#endif
+static int set_nic_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ bool enable_nic = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_nic_enable(pci_adapter->hwdev, func_id, &enable_nic);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Failed to get nic state.\n");
+ return err;
+ }
+
+ if (!enable_nic) {
+ sdk_info(&pdev->dev, "Func %u nic state: disable.\n", func_id);
+ detach_uld(pci_adapter, SERVICE_T_NIC);
+ return 0;
+ }
+
+ if (IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ (void)hinic3_init_vf_dev_cap(pci_adapter->hwdev);
+
+ if (g_uld_info[SERVICE_T_NIC].probe) {
+ err = attach_uld(pci_adapter, SERVICE_T_NIC, &g_uld_info[SERVICE_T_NIC]);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Initialize NIC failed\n");
+ return err;
+ }
+ }
+
+ return 0;
+}
static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
{
@@ -689,7 +1232,16 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
list_add_tail(&pci_adapter->node, &pci_adapter->chip_node->func_list);
lld_unlock_chip_node();
+ hinic3_init_ppf_hwdev((struct hinic3_hwdev *)pci_adapter->hwdev);
+
+ set_vf_load_state(pdev, pci_adapter);
+
if (!disable_attach) {
+ /* NIC is base driver, probe firstly */
+ err = set_nic_func_state(pci_adapter);
+ if (err)
+ goto set_nic_func_state_err;
+
attach_ulds(pci_adapter);
if (hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) {
@@ -700,10 +1252,6 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
goto create_sysfs_err;
}
}
-
-#ifdef CONFIG_X86
- cfg_order_reg(pci_adapter);
-#endif
}
return 0;
@@ -711,6 +1259,7 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
create_sysfs_err:
detach_ulds(pci_adapter);
+set_nic_func_state_err:
lld_lock_chip_node();
list_del(&pci_adapter->node);
lld_unlock_chip_node();
@@ -759,6 +1308,7 @@ static void hinic3_func_deinit(struct pci_dev *pdev)
hinic3_free_stateful(pci_adapter->hwdev);
hinic3_free_hwdev(pci_adapter->hwdev);
+ pci_adapter->hwdev = NULL;
}
static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
@@ -766,18 +1316,61 @@ static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
struct hinic3_sriov_info *sriov_info;
unsigned long end;
- sriov_info = &pci_adapter->sriov_info;
- clear_bit(HINIC3_FUNC_PERSENT, &sriov_info->state);
- usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
+ sriov_info = &pci_adapter->sriov_info;
+ clear_bit(HINIC3_FUNC_PERSENT, &sriov_info->state);
+ usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
+
+ end = jiffies + msecs_to_jiffies(HINIC3_WAIT_SRIOV_CFG_TIMEOUT);
+ do {
+ if (!test_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state) &&
+ !test_bit(HINIC3_SRIOV_DISABLE, &sriov_info->state))
+ return;
+
+ usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
+ } while (time_before(jiffies, end));
+}
+
+static bool hinic3_get_vf_nic_en_status(struct pci_dev *pdev)
+{
+ bool nic_en = false;
+ u16 global_func_id;
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev) {
+ pr_err("pdev is null.\n");
+ return false;
+ }
+
+ if (pdev->is_virtfn)
+ pf_pdev = pdev->physfn;
+ else
+ return false;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return false;
+ }
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ return false;
+
+ if (hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id)) {
+ sdk_err(&pdev->dev, "Get vf id by vfpci failed\n");
+ return false;
+ }
+
+ if (hinic3_get_mhost_func_nic_enable(pci_adapter->hwdev,
+ global_func_id, &nic_en)) {
+ sdk_err(&pdev->dev, "Get function nic status failed\n");
+ return false;
+ }
- end = jiffies + msecs_to_jiffies(HINIC3_WAIT_SRIOV_CFG_TIMEOUT);
- do {
- if (!test_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state) &&
- !test_bit(HINIC3_SRIOV_DISABLE, &sriov_info->state))
- return;
+ sdk_info(&pdev->dev, "Func %hu %s default probe in host\n",
+ global_func_id, (nic_en) ? "enable" : "disable");
- usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- } while (time_before(jiffies, end));
+ return nic_en;
}
bool hinic3_get_vf_load_state(struct pci_dev *pdev)
@@ -897,6 +1490,32 @@ int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
}
EXPORT_SYMBOL(hinic3_set_vf_service_load);
+static bool hinic3_is_host_vmsec_enable(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct pci_dev *pf_pdev = NULL;
+
+ if (pdev->is_virtfn)
+ pf_pdev = pdev->physfn;
+ else
+ pf_pdev = pdev;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ pr_err("Pci_adapter is null.\n");
+ return false;
+ }
+
+ /* pf/vf used in host */
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ (hinic3_func_type(pci_adapter->hwdev) == TYPE_PF) &&
+ IS_RDMA_TYPE((struct hinic3_hwdev *)pci_adapter->hwdev)) {
+ return true;
+ }
+
+ return false;
+}
+
static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
@@ -910,6 +1529,13 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
pci_adapter->lld_state = HINIC3_IN_REMOVE;
mutex_unlock(&pci_adapter->pdev_mutex);
+ if (!(pdev->is_virtfn) && (hinic3_is_host_vmsec_enable(pdev) == true) &&
+ (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF)) {
+ cancel_delayed_work_sync(&pci_adapter->migration_probe_dwork);
+ flush_workqueue(pci_adapter->migration_probe_workq);
+ destroy_workqueue(pci_adapter->migration_probe_workq);
+ }
+
hinic3_detect_hw_present(pci_adapter->hwdev);
hisdk3_remove_pre_process(pci_adapter->hwdev);
@@ -934,23 +1560,127 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
sdk_info(&pdev->dev, "Pcie device removed function\n");
+ set_vf_func_in_use(pdev, false);
+
+ return 0;
+}
+
+int hinic3_get_vfid_by_vfpci(void *hwdev, struct pci_dev *pdev, u16 *global_func_id)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ u16 pf_bus, vf_bus, vf_offset;
+ int err;
+
+ if (!pdev || !global_func_id || !hinic3_pdev_is_virtfn(pdev))
+ return -EINVAL;
+ (void)hwdev;
+ pf_pdev = pdev->physfn;
+
+ vf_bus = pdev->bus->number;
+ pf_bus = pf_pdev->bus->number;
+
+ if (pdev->vendor == HINIC3_VIRTIO_VNEDER_ID)
+ return -EPERM;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return -EINVAL;
+ }
+
+ err = hinic3_pf_get_vf_offset_info(pci_adapter, &vf_offset);
+ if (err) {
+ sdk_err(&pdev->dev, "Func hinic3_pf_get_vf_offset_info fail\n");
+ return -EFAULT;
+ }
+
+ *global_func_id = (u16)((vf_bus - pf_bus) * BUS_MAX_DEV_NUM) + (u16)pdev->devfn +
+ (u16)(CMD_MAX_MAX_PF_NUM - g_vf_offset.vf_offset_from_pf[0]);
+
return 0;
}
+EXPORT_SYMBOL(hinic3_get_vfid_by_vfpci);
+
+static void hinic3_set_vf_status_in_host(struct pci_dev *pdev, bool status)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ void *ppf_hwdev = NULL;
+ u16 global_func_id;
+ int ret;
+
+ if (!pf_pdev)
+ return;
+
+ if (!hinic3_pdev_is_virtfn(pdev))
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ pf_hwdev = pci_adapter->hwdev;
+ ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(pf_pdev);
+ if (!pf_hwdev || !ppf_hwdev)
+ return;
+
+ ret = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (ret) {
+ sdk_err(&pci_adapter->pcidev->dev,
+ "Func hinic3_get_vfid_by_vfpci fail %d\n", ret);
+ return;
+ }
+
+ ret = hinic3_set_func_probe_in_host(ppf_hwdev, global_func_id, status);
+ if (ret)
+ sdk_err(&pci_adapter->pcidev->dev,
+ "Set the function probe status in host failed\n");
+}
+
+#ifdef CONFIG_PCI_IOV
+/* Check whether pdev is a VF and whether it belongs to the PF of the SDI card */
+static bool check_pdev_type_and_state(struct pci_dev *pdev)
+{
+ if (!(pdev->is_virtfn))
+ return false;
+
+ if ((hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_1_PF) &&
+ (hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_0_PF)) {
+ return false;
+ }
+
+ if (!hinic3_get_vf_load_state(pdev))
+ return false;
+
+ return true;
+}
+#endif
static void hinic3_remove(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
+ sdk_info(&pdev->dev, "Pcie device remove begin\n");
+
if (!pci_adapter)
- return;
+ goto out;
- sdk_info(&pdev->dev, "Pcie device remove begin\n");
+#ifdef CONFIG_PCI_IOV
+ if (check_pdev_type_and_state(pdev))
+ goto out;
+#endif
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
hinic3_remove_func(pci_adapter);
+ if (!pci_adapter->pcidev->is_virtfn &&
+ pci_adapter->multi_host_mgmt_workq)
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
hinic3_pci_deinit(pdev);
hinic3_probe_pre_unprocess(pdev);
+out:
+ hinic3_set_vf_status_in_host(pdev, false);
sdk_info(&pdev->dev, "Pcie device removed\n");
}
@@ -969,7 +1699,7 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
if (pci_adapter->lld_state >= HINIC3_PROBE_START) {
sdk_warn(&pdev->dev, "Don not probe repeat\n");
mutex_unlock(&pci_adapter->pdev_mutex);
- return 0;
+ return -EEXIST;
}
pci_adapter->lld_state = HINIC3_PROBE_START;
mutex_unlock(&pci_adapter->pdev_mutex);
@@ -977,15 +1707,28 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
return 0;
}
+static void hinic3_probe_success_process(struct hinic3_pcidev *pci_adapter)
+{
+ hinic3_probe_success(pci_adapter->hwdev);
+
+ mutex_lock(&pci_adapter->pdev_mutex);
+ pci_adapter->lld_state = HINIC3_PROBE_OK;
+ mutex_unlock(&pci_adapter->pdev_mutex);
+}
+
static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
int err;
err = probe_func_param_init(pci_adapter);
- if (err)
+ if (err == -EEXIST)
+ return 0;
+ else if (err)
return err;
+ set_vf_func_in_use(pdev, true);
+
err = mapping_bar(pdev, pci_adapter);
if (err) {
sdk_err(&pdev->dev, "Failed to map bar\n");
@@ -1017,11 +1760,7 @@ static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
}
}
- hinic3_probe_success(pci_adapter->hwdev);
-
- mutex_lock(&pci_adapter->pdev_mutex);
- pci_adapter->lld_state = HINIC3_PROBE_OK;
- mutex_unlock(&pci_adapter->pdev_mutex);
+ hinic3_probe_success_process(pci_adapter);
return 0;
@@ -1037,18 +1776,299 @@ alloc_chip_node_fail:
unmapping_bar(pci_adapter);
map_bar_failed:
+ set_vf_func_in_use(pdev, false);
sdk_err(&pdev->dev, "Pcie device probe function failed\n");
return err;
}
+void hinic3_set_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int err;
+ bool enable_func = false;
+
+ err = hinic3_get_function_enable(pdev, &enable_func);
+ if (err) {
+ sdk_info(&pdev->dev, "Get function enable failed\n");
+ return;
+ }
+
+ sdk_info(&pdev->dev, "%s function resource start\n",
+ enable_func ? "Initialize" : "Free");
+ if (enable_func) {
+ err = hinic3_probe_func(pci_adapter);
+ if (err)
+ sdk_info(&pdev->dev, "Function probe failed\n");
+ } else {
+ hinic3_remove_func(pci_adapter);
+ }
+ if (err == 0)
+ sdk_info(&pdev->dev, "%s function resource end\n",
+ enable_func ? "Initialize" : "Free");
+}
+
+void slave_host_mgmt_work(struct work_struct *work)
+{
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_nic_work);
+
+ if (hinic3_pdev_is_virtfn(pci_adapter->pcidev))
+ hinic3_set_func_state(pci_adapter);
+ else
+ set_nic_func_state(pci_adapter);
+}
+
+static int pci_adapter_assign_val(struct hinic3_pcidev **ppci_adapter,
+ struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ *ppci_adapter = pci_get_drvdata(pdev);
+ (*ppci_adapter)->disable_vf_load = disable_vf_load;
+ (*ppci_adapter)->id = *id;
+ (*ppci_adapter)->lld_state = HINIC3_NOT_PROBE;
+ (*ppci_adapter)->probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ lld_dev_cnt_init(*ppci_adapter);
+
+ (*ppci_adapter)->multi_host_mgmt_workq = alloc_workqueue("hinic_mhost_mgmt",
+ WQ_UNBOUND,
+ HINIC3_SLAVE_WORK_MAX_NUM);
+ if (!(*ppci_adapter)->multi_host_mgmt_workq) {
+ hinic3_pci_deinit(pdev);
+ sdk_err(&pdev->dev, "Alloc multi host mgmt workqueue failed\n");
+ return -ENOMEM;
+ }
+
+ INIT_WORK(&(*ppci_adapter)->slave_nic_work, slave_host_mgmt_work);
+ INIT_WORK(&(*ppci_adapter)->slave_vroce_work,
+ slave_host_mgmt_vroce_work);
+
+ return 0;
+}
+
+static void slave_host_vfio_probe_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_pcidev *pci_adapter = container_of(delay, struct hinic3_pcidev,
+ migration_probe_dwork);
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int (*dev_migration_probe)(struct pci_dev *pdev);
+ int rc;
+
+ if (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) != TYPE_PF)
+ return;
+
+ dev_migration_probe = __symbol_get("migration_dev_migration_probe");
+ if (!(dev_migration_probe)) {
+ sdk_err(&pdev->dev,
+ "Failed to find: migration_dev_migration_probe");
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork,
+ WAIT_TIME * HZ);
+ } else {
+ rc = dev_migration_probe(pdev);
+ __symbol_put("migration_dev_migration_probe");
+ if (rc) {
+ sdk_err(&pdev->dev,
+ "Failed to __dev_migration_probe, rc:0x%x, pf migrated(%d).\n",
+ rc, g_is_pf_migrated);
+ } else {
+ g_is_pf_migrated = true;
+ sdk_info(&pdev->dev,
+ "Succeeded in __dev_migration_probe, pf migrated(%d).\n",
+ g_is_pf_migrated);
+ }
+ }
+}
+
+struct vf_add_delaywork {
+ struct pci_dev *vf_pdev;
+ struct delayed_work migration_vf_add_dwork;
+};
+
+static void slave_host_migration_vf_add_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct vf_add_delaywork *vf_add = container_of(delay, struct vf_add_delaywork,
+ migration_vf_add_dwork);
+ struct pci_dev *vf_pdev = vf_add->vf_pdev;
+ struct pci_dev *pf_pdev = NULL;
+ int (*migration_dev_add_vf)(struct pci_dev *vf_pdev);
+ int ret;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!vf_pdev) {
+ pr_err("vf pdev is null.\n");
+ goto err1;
+ }
+ if (!vf_pdev->is_virtfn) {
+ sdk_err(&vf_pdev->dev, "Pdev is not virtfn.\n");
+ goto err1;
+ }
+
+ pf_pdev = vf_pdev->physfn;
+ if (!pf_pdev) {
+ sdk_err(&vf_pdev->dev, "pf_pdev is null.\n");
+ goto err1;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&vf_pdev->dev, "Pci_adapter is null.\n");
+ goto err1;
+ }
+
+ if (!g_is_pf_migrated) {
+ sdk_info(&vf_pdev->dev, "pf is not migrated yet, so vf continues to try again.\n");
+ goto delay_work;
+ }
+
+ migration_dev_add_vf = __symbol_get("migration_dev_add_vf");
+ if (migration_dev_add_vf) {
+ ret = migration_dev_add_vf(vf_pdev);
+ __symbol_put("migration_dev_add_vf");
+ if (ret)
+ sdk_err(&vf_pdev->dev, "vf get migration symbol succeeded, but dev add vf failed, ret:%d.\n",
+ ret);
+ else
+ sdk_info(&vf_pdev->dev, "vf get migration symbol succeeded, and dev add vf success.\n");
+ goto err1;
+ }
+ sdk_info(&vf_pdev->dev, "pf is migrated, but vf get migration symbol failed.\n");
+
+delay_work:
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork, WAIT_TIME * HZ);
+ return;
+
+err1:
+ kfree(vf_add);
+}
+
+static void hinic3_probe_vf_add_dwork(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct vf_add_delaywork *vf_add = NULL;
+
+ if (!hinic3_is_host_vmsec_enable(pdev))
+ return;
+
+#if defined(CONFIG_SP_VID_DID)
+ if (pdev->vendor == PCI_VENDOR_ID_SPNIC && pdev->device == HINIC3_DEV_SDI_5_1_ID_VF) {
+#elif defined(CONFIG_NF_VID_DID)
+ if (pdev->vendor == PCI_VENDOR_ID_NF && pdev->device == NFNIC_DEV_ID_VF) {
+#else
+ if (pdev->vendor == PCI_VENDOR_ID_HUAWEI && pdev->device == HINIC3_DEV_SDI_5_0_ID_VF) {
+#endif
+ vf_add = kmalloc(sizeof(*vf_add), GFP_ATOMIC);
+
+ if (!vf_add)
+ return;
+
+ vf_add->vf_pdev = pdev;
+
+ pf_pdev = pdev->physfn;
+
+ if (!pf_pdev) {
+ sdk_info(&pdev->dev, "Vf-pf_pdev is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_info(&pdev->dev, "Pci_adapter is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ INIT_DELAYED_WORK(&vf_add->migration_vf_add_dwork,
+ slave_host_migration_vf_add_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork,
+ WAIT_TIME * HZ);
+ }
+}
+
+static int hinic3_probe_migration_dwork(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+{
+ if (!hinic3_is_host_vmsec_enable(pdev)) {
+ sdk_info(&pdev->dev, "Probe_migration : hinic3_is_host_vmsec_enable is (0).\n");
+ return 0;
+ }
+
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF) {
+ pci_adapter->migration_probe_workq =
+ create_singlethread_workqueue("hinic3_migration_probe_delay");
+ if (!pci_adapter->migration_probe_workq) {
+ sdk_err(&pdev->dev, "Failed to create work queue:%s\n",
+ "hinic3_migration_probe_delay");
+ return -EINVAL;
+ }
+
+ INIT_DELAYED_WORK(&pci_adapter->migration_probe_dwork,
+ slave_host_vfio_probe_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork,
+ WAIT_TIME * HZ);
+ }
+
+ return 0;
+}
+
+static bool hinic3_os_hot_replace_allow(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_hwdev *hwdev = (struct hinic3_hwdev *)pci_adapter->hwdev;
+ // check service enable and dev is not VF
+ if (hinic3_func_type(hwdev) == TYPE_VF || hwdev->hot_replace_mode == HOT_REPLACE_DISABLE)
+ return false;
+
+ return true;
+}
+
+static bool hinic3_os_hot_replace_process(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_board_info *board_info;
+ u16 cur_pf_id = hinic3_global_func_id(pci_adapter->hwdev);
+ u8 cur_partion_id;
+
+ board_info = &((struct hinic3_hwdev *)(pci_adapter->hwdev))->board_info;
+ // probe to os
+ vpci_set_partition_attrs(pci_adapter->pcidev, PARTITION_DEV_EXCLUSIVE,
+ get_function_partition(cur_pf_id,
+ board_info->port_num));
+
+ // check pf_id is in the right partition_id
+ cur_partion_id = get_partition_id();
+ if (get_function_partition(cur_pf_id, board_info->port_num) ==
+ cur_partion_id)
+ return true;
+
+ pci_adapter->probe_fault_level = FAULT_LEVEL_SUGGESTION;
+ return false;
+}
+
static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct hinic3_pcidev *pci_adapter = NULL;
u16 probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ u32 device_id, function_id;
int err;
sdk_info(&pdev->dev, "Pcie device probe begin\n");
+#ifdef CONFIG_PCI_IOV
+ hinic3_set_vf_status_in_host(pdev, true);
+ if (check_pdev_type_and_state(pdev)) {
+ sdk_info(&pdev->dev, "VFs are not binded to hinic\n");
+ hinic3_probe_vf_add_dwork(pdev);
+ return -EINVAL;
+ }
+#endif
+
err = hinic3_probe_pre_process(pdev);
if (err != 0 && err != HINIC3_NOT_PROBE)
goto out;
@@ -1060,26 +2080,48 @@ static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (err)
goto pci_init_err;
- pci_adapter = pci_get_drvdata(pdev);
- pci_adapter->disable_vf_load = disable_vf_load;
- pci_adapter->id = *id;
- pci_adapter->lld_state = HINIC3_NOT_PROBE;
- pci_adapter->probe_fault_level = probe_fault_level;
- lld_dev_cnt_init(pci_adapter);
+ err = pci_adapter_assign_val(&pci_adapter, pdev, id);
+ if (err)
+ goto allco_queue_err;
- if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev))) {
+ if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev)) &&
+ (!hinic3_get_vf_nic_en_status(pdev))) {
sdk_info(&pdev->dev, "VF device disable load in host\n");
return 0;
}
- err = hinic3_probe_func(pci_adapter);
- if (err)
+ if (hinic3_probe_func(pci_adapter))
+ goto hinic3_probe_func_fail;
+
+ if (hinic3_os_hot_replace_allow(pci_adapter)) {
+ if (!hinic3_os_hot_replace_process(pci_adapter)) {
+ device_id = PCI_SLOT(pdev->devfn);
+ function_id = PCI_FUNC(pdev->devfn);
+ sdk_info(&pdev->dev,
+ "os hot replace: skip function %d:%d for partition %d",
+ device_id, function_id, get_partition_id());
+ goto os_hot_repalce_not_allow;
+ }
+ }
+
+ if (hinic3_probe_migration_dwork(pdev, pci_adapter))
goto hinic3_probe_func_fail;
sdk_info(&pdev->dev, "Pcie device probed\n");
return 0;
+os_hot_repalce_not_allow:
+ hinic3_func_deinit(pdev);
+ lld_lock_chip_node();
+ free_chip_node(pci_adapter);
+ lld_unlock_chip_node();
+ unmapping_bar(pci_adapter);
+ set_vf_func_in_use(pdev, false);
hinic3_probe_func_fail:
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
+allco_queue_err:
probe_fault_level = pci_adapter->probe_fault_level;
hinic3_pci_deinit(pdev);
@@ -1105,6 +2147,11 @@ static int hinic3_get_pf_info(struct pci_dev *pdev, u16 service,
}
*pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (*pf_infos == NULL) {
+ sdk_err(&pdev->dev, "pf_infos kzalloc failed\n");
+ return -EFAULT;
+ }
+
err = hinic3_get_hw_pf_infos(dev->hwdev, *pf_infos, HINIC3_CHANNEL_COMM);
if (err) {
kfree(*pf_infos);
@@ -1120,6 +2167,7 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
{
int err;
+ mutex_lock(&dst_dev->pdev_mutex);
/* unload invalid vf func id */
if (!en && vf_func_id != hinic3_global_func_id(dst_dev->hwdev) &&
!strcmp(des_pdev->driver->name, HINIC3_DRV_NAME)) {
@@ -1137,6 +2185,8 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
err = hinic3_probe_func(dst_dev);
if (err)
return -EFAULT;
+ } else {
+ mutex_unlock(&dst_dev->pdev_mutex);
}
return 0;
@@ -1161,7 +2211,6 @@ static int get_vf_service_state_param(struct pci_dev *pdev, struct hinic3_pcidev
return 0;
}
-#define BUS_MAX_DEV_NUM 256
static int hinic3_dst_pdev_valid(struct hinic3_pcidev *dst_dev, struct pci_dev **des_pdev_ptr,
u16 vf_devfn, bool en)
{
@@ -1243,7 +2292,6 @@ int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id, u16 servic
if (en)
pci_dev_put(des_pdev);
- mutex_lock(&dst_dev->pdev_mutex);
find_dst_dev = true;
break;
}
@@ -1263,19 +2311,30 @@ free_pf_info:
}
EXPORT_SYMBOL(hinic3_set_vf_service_state);
-/*lint -save -e133 -e10*/
static const struct pci_device_id hinic3_pci_table[] = {
+#if defined(CONFIG_SP_VID_DID)
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_STANDARD), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_SDI_5_1_PF), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_SDI_5_0_PF), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_SPN120), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_VF), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_SDI_5_1_ID_VF), 0},
+#elif defined(CONFIG_NF_VID_DID)
+ {PCI_VDEVICE(NF, NFNIC_DEV_ID_STANDARD), 0},
+ {PCI_VDEVICE(NF, NFNIC_DEV_ID_VF), 0},
+#else
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SPU), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_STANDARD), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_1_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_SDI_5_1_ID_VF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_VF), 0},
+#endif
{0, 0}
};
-/*lint -restore*/
-
MODULE_DEVICE_TABLE(pci, hinic3_pci_table);
/**
@@ -1307,14 +2366,27 @@ static pci_ers_result_t hinic3_io_error_detected(struct pci_dev *pdev,
return PCI_ERS_RESULT_CAN_RECOVER;
}
+static void hinic3_timer_disable(void *hwdev)
+{
+ if (!hwdev)
+ return;
+
+ if (hinic3_get_stateful_enable(hwdev) && hinic3_get_timer_enable(hwdev))
+ (void)hinic3_func_tmr_bitmap_set(hwdev,
+ hinic3_global_func_id(hwdev),
+ false);
+}
+
static void hinic3_shutdown(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
sdk_info(&pdev->dev, "Shutdown device\n");
- if (pci_adapter)
+ if (pci_adapter) {
+ hinic3_timer_disable(pci_adapter->hwdev);
hinic3_shutdown_hwdev(pci_adapter->hwdev);
+ }
pci_disable_device(pdev);
@@ -1341,6 +2413,9 @@ static struct pci_driver hinic3_driver = {
.probe = hinic3_probe,
.remove = hinic3_remove,
.shutdown = hinic3_shutdown,
+#ifdef CONFIG_PARTITION_DEVICE
+ .driver.probe_concurrency = true,
+#endif
#if defined(HAVE_SRIOV_CONFIGURE)
.sriov_configure = hinic3_pci_sriov_configure,
#elif defined(HAVE_RHEL6_SRIOV_CONFIGURE)
@@ -1362,16 +2437,21 @@ int hinic3_lld_init(void)
err = hinic3_module_pre_init();
if (err) {
pr_err("Init custom failed\n");
- return err;
+ goto module_pre_init_err;
}
err = pci_register_driver(&hinic3_driver);
if (err) {
- hinic3_module_post_exit();
- return err;
+ pr_err("sdk3 pci register driver failed\n");
+ goto register_pci_driver_err;
}
return 0;
+
+register_pci_driver_err:
+ hinic3_module_post_exit();
+module_pre_init_err:
+ return err;
}
void hinic3_lld_exit(void)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
index b2851c6..3626262 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
@@ -584,6 +584,7 @@ static void free_recv_mbox(struct hinic3_recv_mbox *recv_msg)
kfree(recv_msg->resp_buff);
kfree(recv_msg->msg);
kfree(recv_msg);
+ recv_msg = NULL;
}
static void recv_func_mbox_work_handler(struct work_struct *work)
@@ -1232,6 +1233,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
set_mbox_to_func_event(func_to_func, EVENT_FAIL);
goto send_err;
}
+ func_to_func->hwdev->mbox_send_cnt++;
if (wait_mbox_msg_completion(func_to_func, timeout) != 0) {
sdk_err(func_to_func->hwdev->dev_hdl,
@@ -1240,6 +1242,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
err = -ETIMEDOUT;
goto send_err;
}
+ func_to_func->hwdev->mbox_ack_cnt++;
if (mod != msg_desc->mod || cmd != msg_desc->cmd) {
sdk_err(func_to_func->hwdev->dev_hdl,
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
index 2bd63f1..4718458 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
@@ -861,6 +861,7 @@ static int alloc_recv_msg(struct hinic3_recv_msg *recv_msg)
static void free_recv_msg(struct hinic3_recv_msg *recv_msg)
{
kfree(recv_msg->msg);
+ recv_msg->msg = NULL;
}
/**
@@ -932,6 +933,9 @@ static void free_msg_buf(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt)
free_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
+ pf_to_mgmt->mgmt_ack_buf = NULL;
+ pf_to_mgmt->sync_msg_buf = NULL;
+ pf_to_mgmt->async_msg_buf = NULL;
}
/**
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
index 3548410..a0f5e73 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
@@ -676,6 +676,9 @@ static int hinic3_register_slave_ppf(struct hinic3_hwdev *hwdev, bool registered
if (!IS_SLAVE_HOST(hwdev))
return -EINVAL;
+ if (UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev))
+ return 0;
+
host_info = kcalloc(1, sizeof(struct register_slave_host), GFP_KERNEL);
if (!host_info)
return -ENOMEM;
@@ -1075,7 +1078,8 @@ int hinic3_get_func_nic_enable(void *hwdev, u16 glb_func_idx, bool *en)
return -EINVAL;
/* if single host, return true. */
- if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev)) {
+ if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev) ||
+ UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev)) {
*en = true;
return 0;
}
@@ -1145,11 +1149,21 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
{
int err;
struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+ int is_use_vram, is_in_kexec;
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
- hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0) {
+ snprintf(hwdev->mhost_mgmt_name, VRAM_NAME_MAX_LEN, "%s",
+ VRAM_NIC_MHOST_MGMT);
+ hwdev->mhost_mgmt = hi_vram_kalloc(hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ } else {
+ hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ }
+
if (!hwdev->mhost_mgmt)
return -ENOMEM;
@@ -1165,8 +1179,11 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK, hwdev, hilink_ppf_mbox_handler);
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC, hwdev, sw_func_ppf_mbox_handler);
- bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
- bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ }
/* Slave host:
* register slave host ppf functions
@@ -1179,7 +1196,11 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
return 0;
out_free_mhost_mgmt:
- kfree(hwdev->mhost_mgmt);
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)hwdev->mhost_mgmt, hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ else
+ kfree(hwdev->mhost_mgmt);
hwdev->mhost_mgmt = NULL;
return err;
@@ -1187,6 +1208,8 @@ out_free_mhost_mgmt:
int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
{
+ int is_use_vram;
+
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
@@ -1203,7 +1226,13 @@ int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC);
- kfree(hwdev->mhost_mgmt);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)hwdev->mhost_mgmt, hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ else
+ kfree(hwdev->mhost_mgmt);
+
hwdev->mhost_mgmt = NULL;
return 0;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
index 5e4804a..5a5ea53 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
@@ -17,14 +17,13 @@
#include "hinic3_hwdev.h"
#include "hinic3_lld.h"
#include "hinic3_hw_mt.h"
+#include "hinic3_dev_mgmt.h"
#include "hinic3_nictool.h"
static int g_nictool_ref_cnt;
static dev_t g_dev_id = {0};
-/*lint -save -e104 -e808*/
static struct class *g_nictool_class;
-/*lint -restore*/
static struct cdev g_nictool_cdev;
#define HINIC3_MAX_BUF_SIZE (2048 * 1024)
@@ -92,6 +91,23 @@ static int get_all_chip_id_cmd(struct hinic3_lld_dev *lld_dev, const void *buf_i
return 0;
}
+#ifndef __HIFC__
+static int get_os_hot_replace_info(struct hinic3_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ if (*out_size != sizeof(struct os_hot_replace_info) || !buf_out) {
+ pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
+ *out_size, sizeof(struct os_hot_replace_info));
+ return -EFAULT;
+ }
+
+ hinic3_get_os_hot_replace_info(buf_out);
+
+ return 0;
+}
+#endif
+
static int get_card_usr_api_chain_mem(int card_idx)
{
unsigned char *tmp = NULL;
@@ -166,7 +182,7 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
if (!buf_out || *out_size != sizeof(struct pf_dev_info) * PF_DEV_INFO_NUM) {
pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
- *out_size, sizeof(dev_info) * PF_DEV_INFO_NUM);
+ *out_size, sizeof(*dev_info) * PF_DEV_INFO_NUM);
return -EFAULT;
}
@@ -193,13 +209,18 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
return 0;
}
-static long dbgtool_knl_free_mem(int id)
+static void dbgtool_knl_free_mem(int id)
{
unsigned char *tmp = NULL;
int i;
+ if (id < 0 || id >= MAX_CARD_NUM) {
+ pr_err("Invalid card id\n");
+ return;
+ }
+
if (!g_card_vir_addr[id])
- return 0;
+ return;
tmp = g_card_vir_addr[id];
for (i = 0; i < (1 << DBGTOOL_PAGE_ORDER); i++) {
@@ -211,7 +232,6 @@ static long dbgtool_knl_free_mem(int id)
g_card_vir_addr[id] = NULL;
g_card_phy_addr[id] = 0;
- return 0;
}
static int free_knl_mem(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_size,
@@ -337,7 +357,6 @@ static int get_hw_drv_version(struct hinic3_lld_dev *lld_dev, const void *buf_in
void *buf_out, u32 *out_size)
{
struct drv_version_info *ver_info = buf_out;
- int err;
if (!buf_out) {
pr_err("Buf_out is NULL.\n");
@@ -350,10 +369,8 @@ static int get_hw_drv_version(struct hinic3_lld_dev *lld_dev, const void *buf_in
return -EINVAL;
}
- err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s", HINIC3_DRV_VERSION,
- "2023-05-17_19:56:38");
- if (err < 0)
- return -EINVAL;
+ snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s", HINIC3_DRV_VERSION,
+ "2025-05-08_00:00:08");
return 0;
}
@@ -386,6 +403,22 @@ static int get_pf_id(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_
return 0;
}
+#ifndef __HIFC__
+/* not support fc yet */
+static int get_mbox_cnt(struct hinic3_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ if (!buf_out || *out_size != sizeof(struct card_mbox_cnt_info)) {
+ pr_err("buf_out is NULL, or out_size != %lu\n", sizeof(struct card_info));
+ return -EINVAL;
+ }
+
+ hinic3_get_mbox_cnt(hinic3_get_sdk_hwdev_by_lld(lld_dev), buf_out);
+
+ return 0;
+}
+#endif
+
struct hw_drv_module_handle hw_driv_module_cmd_handle[] = {
{FUNC_TYPE, get_func_type},
{GET_FUNC_IDX, get_func_id},
@@ -402,6 +435,10 @@ struct hw_drv_module_handle hw_driv_module_cmd_handle[] = {
{GET_FUNC_CAP, get_pf_cap_info},
{GET_DRV_VERSION, get_hw_drv_version},
{GET_PF_ID, get_pf_id},
+#ifndef __HIFC__
+ {GET_OS_HOT_REPLACE_INFO, get_os_hot_replace_info},
+ {GET_MBOX_CNT, (hw_driv_module)get_mbox_cnt},
+#endif
};
static int alloc_tmp_buf(void *hwdev, struct msg_module *nt_msg, u32 in_size,
@@ -439,8 +476,8 @@ static void free_tmp_buf(void *hwdev, struct msg_module *nt_msg,
static int send_to_hw_driver(struct hinic3_lld_dev *lld_dev, struct msg_module *nt_msg,
const void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(hw_driv_module_cmd_handle) /
- sizeof(hw_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(hw_driv_module_cmd_handle) /
+ sizeof(hw_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type =
(enum driver_cmd_type)(nt_msg->msg_formate);
int err = 0;
@@ -482,8 +519,8 @@ static int send_to_service_driver(struct hinic3_lld_dev *lld_dev, struct msg_mod
if (nt_msg->msg_formate == GET_DRV_VERSION)
return 0;
- pr_err("Can not get the uld dev correctly: %s, %s driver may be not register\n",
- nt_msg->device_name, service_name[type]);
+ pr_err("Can not get the uld dev correctly: %s driver may be not register\n",
+ service_name[type]);
return -EINVAL;
}
@@ -597,8 +634,10 @@ static long hinicadm_k_unlocked_ioctl(struct file *pfile, unsigned long arg)
return -ENODEV;
}
- if (nt_msg.msg_formate == DEV_NAME_TEST)
+ if (nt_msg.msg_formate == DEV_NAME_TEST) {
+ lld_dev_put(lld_dev);
return 0;
+ }
ret = alloc_tmp_buf(hinic3_get_sdk_hwdev_by_lld(lld_dev), &nt_msg,
in_size, &buf_in, out_size_expect, &buf_out);
@@ -642,6 +681,9 @@ out_free_lock:
static long dbgtool_knl_ffm_info_rd(struct dbgtool_param *para,
struct dbgtool_k_glb_info *dbgtool_info)
{
+ if (!para->param.ffm_rd || !dbgtool_info->ffm)
+ return -EINVAL;
+
/* Copy the ffm_info to user mode */
if (copy_to_user(para->param.ffm_rd, dbgtool_info->ffm,
(unsigned int)sizeof(struct ffm_record_info))) {
@@ -674,13 +716,14 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
card_info = (struct card_node *)g_card_node_array[i];
if (!card_info)
continue;
- if (!strncmp(param.chip_name, card_info->chip_name, IFNAMSIZ))
+ if (memcmp(param.chip_name, card_info->chip_name,
+ strlen(card_info->chip_name) + 1) == 0)
break;
}
if (i == MAX_CARD_NUM || !card_info) {
lld_put();
- pr_err("Can't find this card %s\n", param.chip_name);
+ pr_err("Can't find this card.\n");
return -EFAULT;
}
@@ -697,10 +740,10 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
pr_err("Not suppose to use this cmd(0x%x).\n", real_cmd);
ret = 0;
break;
-
default:
pr_err("Dbgtool cmd(0x%x) not support now\n", real_cmd);
ret = -EFAULT;
+ break;
}
up(&dbgtool_info->dbgtool_sem);
@@ -746,9 +789,11 @@ static long nictool_k_unlocked_ioctl(struct file *pfile,
static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
{
+ pgprot_t vm_page_prot;
unsigned long vmsize = vma->vm_end - vma->vm_start;
phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
phys_addr_t phy_addr;
+ int err = 0;
if (vmsize > (PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER))) {
pr_err("Map size = %lu is bigger than alloc\n", vmsize);
@@ -758,13 +803,18 @@ static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
/* old version of tool set vma->vm_pgoff to 0 */
phy_addr = offset ? offset : g_card_phy_addr[card_id];
- if (!phy_addr) {
- pr_err("Card_id = %d physical address is 0\n", card_id);
- return -EAGAIN;
+ /* check phy_addr valid */
+ if (phy_addr != g_card_phy_addr[card_id]) {
+ err = hinic3_bar_mmap_param_valid(phy_addr, vmsize);
+ if (err != 0) {
+ pr_err("mmap param invalid, err: %d\n", err);
+ return err;
+ }
}
/* Disable cache and write buffer in the mapping area */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_page_prot = vm_page_prot;
if (remap_pfn_range(vma, vma->vm_start, (phy_addr >> PAGE_SHIFT),
vmsize, vma->vm_page_prot)) {
pr_err("Remap pfn range failed.\n");
@@ -787,7 +837,6 @@ static const struct file_operations fifo_operations = {
static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
{
struct dbgtool_k_glb_info *dbgtool_info = NULL;
- int err, id;
if (hinic3_func_type(hwdev) != TYPE_VF)
chip_info->func_handle_array[hinic3_global_func_id(hwdev)] = NULL;
@@ -795,23 +844,22 @@ static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
if (--chip_info->func_num)
return;
- err = sscanf(chip_info->chip_name, HINIC3_CHIP_NAME "%d", &id);
- if (err < 0)
- pr_err("Failed to get card id\n");
-
- if (id < MAX_CARD_NUM)
- g_card_node_array[id] = NULL;
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ g_card_node_array[chip_info->chip_id] = NULL;
dbgtool_info = chip_info->dbgtool_info;
/* FFM deinit */
- kfree(dbgtool_info->ffm);
- dbgtool_info->ffm = NULL;
+ if (dbgtool_info && dbgtool_info->ffm) {
+ kfree(dbgtool_info->ffm);
+ dbgtool_info->ffm = NULL;
+ }
kfree(dbgtool_info);
+
chip_info->dbgtool_info = NULL;
- if (id < MAX_CARD_NUM)
- (void)dbgtool_knl_free_mem(id);
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ dbgtool_knl_free_mem(chip_info->chip_id);
}
static int alloc_dbgtool_info(void *hwdev, struct card_node *chip_info)
@@ -872,7 +920,7 @@ dbgtool_info_fail:
* nictool_k_init - initialize the hw interface
**/
/* temp for dbgtool_info */
-/*lint -e438*/
+
int nictool_k_init(void *hwdev, void *chip_node)
{
struct card_node *chip_info = (struct card_node *)chip_node;
@@ -895,9 +943,7 @@ int nictool_k_init(void *hwdev, void *chip_node)
}
/* Create equipment */
- /*lint -save -e160*/
g_nictool_class = class_create(HIADM3_DEV_CLASS);
- /*lint -restore*/
if (IS_ERR(g_nictool_class)) {
pr_err("Create nictool_class fail\n");
err = -EFAULT;
@@ -944,7 +990,7 @@ alloc_chdev_fail:
free_dbgtool_info(hwdev, chip_info);
return err;
-} /*lint +e438*/
+}
void nictool_k_uninit(void *hwdev, void *chip_node)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
index f368133..c943dfc 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
@@ -18,6 +18,8 @@
int nictool_k_init(void *hwdev, void *chip_node);
void nictool_k_uninit(void *hwdev, void *chip_node);
+void hinic3_get_os_hot_replace_info(void *oshr_info);
+
void hinic3_get_all_chip_id(void *id_info);
void hinic3_get_card_func_info_by_card_name
@@ -29,6 +31,8 @@ bool hinic3_is_in_host(void);
int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *isvalid);
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin);
+
extern struct hinic3_uld_info g_uld_info[SERVICE_T_MAX];
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
index 2d5423e..e961ef7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
@@ -19,6 +19,20 @@
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
+#elif defined(CONFIG_NF_VID_DID)
+#define PCI_VENDOR_ID_NF 0x2036
+#define NFNIC_DEV_ID_STANDARD 0x1618
+#define NFNIC_DEV_ID_SDI_5_1_PF 0x0226
+#define NFNIC_DEV_ID_SDI_5_0_PF 0x0225
+#define NFNIC_DEV_ID_DPU_PF 0x0224
+#define NFNIC_DEV_ID_VF 0x1619
+#define NFNIC_DEV_ID_VF_HV 0x379F
+#define NFNIC_DEV_SDI_5_1_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_0_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_1_ID_VF_HV 0x379F
+#define NFNIC_DEV_ID_SPU 0xAC00
+#define NFNIC_DEV_SDI_5_1_SSDID_VF 0x1000
+#define NFNIC_DEV_SDI_V100_SSDID_MASK (3 << 12)
#else
#define PCI_VENDOR_ID_HUAWEI 0x19e5
#define HINIC3_DEV_ID_STANDARD 0x0222
@@ -28,16 +42,33 @@
#define HINIC3_DEV_ID_VF 0x375F
#define HINIC3_DEV_ID_VF_HV 0x379F
#define HINIC3_DEV_SDI_5_1_ID_VF 0x375F
+#define HINIC3_DEV_SDI_5_0_ID_VF 0x375F
#define HINIC3_DEV_SDI_5_1_ID_VF_HV 0x379F
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
#endif
+#define NFNIC_DEV_SSID_2X25G_NF 0x0860
+#define NFNIC_DEV_SSID_4X25G_NF 0x0861
+#define NFNIC_DEV_SSID_2x100G_NF 0x0862
+#define NFNIC_DEV_SSID_2x200G_NF 0x0863
+
+#define HINIC3_DEV_SSID_2X10G 0x0035
#define HINIC3_DEV_SSID_2X25G 0x0051
#define HINIC3_DEV_SSID_4X25G 0x0052
+#define HINIC3_DEV_SSID_4X25G_BD 0x0252
+#define HINIC3_DEV_SSID_4X25G_SMARTNIC 0x0152
+#define HINIC3_DEV_SSID_6X25G_VL 0x0356
#define HINIC3_DEV_SSID_2X100G 0x00A1
+#define HINIC3_DEV_SSID_2X100G_SMARTNIC 0x01A1
+#define HINIC3_DEV_SSID_2X200G 0x04B1
#define HINIC3_DEV_SSID_2X100G_VF 0x1000
+#define HINIC3_DEV_SSID_HPC_4_HOST_NIC 0x005A
+#define HINIC3_DEV_SSID_2X200G_VL 0x00B1
+#define HINIC3_DEV_SSID_1X100G 0x02A4
+
+#define BIFUR_RESOURCE_PF_SSID 0x05a1
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
index b23b69f..461272e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
@@ -52,26 +52,25 @@ static int hinic3_deinit_vf_hw(void *hwdev, u16 start_vf_id, u16 end_vf_id)
}
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
-ssize_t hinic3_sriov_totalvfs_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ssize_t sriov_totalvfs_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
return sprintf(buf, "%d\n", pci_sriov_get_totalvfs(pdev));
}
-ssize_t hinic3_sriov_numvfs_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ssize_t sriov_numvfs_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
return sprintf(buf, "%d\n", pci_num_vf(pdev));
}
-/*lint -save -e713*/
-ssize_t hinic3_sriov_numvfs_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+ssize_t sriov_numvfs_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct pci_dev *pdev = to_pci_dev(dev);
int ret;
@@ -116,7 +115,6 @@ ssize_t hinic3_sriov_numvfs_store(struct device *dev,
return count;
}
-/*lint -restore*/
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
int hinic3_pci_sriov_disable(struct pci_dev *dev)
@@ -174,24 +172,15 @@ int hinic3_pci_sriov_disable(struct pci_dev *dev)
return 0;
}
-int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
-{
#ifdef CONFIG_PCI_IOV
- struct hinic3_sriov_info *sriov_info = NULL;
- struct hinic3_event_info event = {0};
- void *hwdev = NULL;
- int pre_existing_vfs = 0;
- int err = 0;
-
- sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
- hwdev = hinic3_get_hwdev_by_pcidev(dev);
- if (!hwdev) {
- sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
- return -EPERM;
- }
+int hinic3_pci_sriov_check(struct hinic3_sriov_info *sriov_info, struct pci_dev *dev, int num_vfs)
+{
+ int pre_existing_vfs;
+ int err;
if (test_and_set_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state)) {
- sdk_err(&dev->dev, "SR-IOV enable in process, please wait, num_vfs %d\n",
+ sdk_err(&dev->dev,
+ "SR-IOV enable in process, please wait, num_vfs %d\n",
num_vfs);
return -EPERM;
}
@@ -202,6 +191,7 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
clear_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state);
return -ERANGE;
}
+
if (pre_existing_vfs && pre_existing_vfs != num_vfs) {
err = hinic3_pci_sriov_disable(dev);
if (err) {
@@ -213,6 +203,29 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
return num_vfs;
}
+ return 0;
+}
+#endif
+
+int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
+{
+#ifdef CONFIG_PCI_IOV
+ struct hinic3_sriov_info *sriov_info = NULL;
+ struct hinic3_event_info event = {0};
+ void *hwdev = NULL;
+ int err = 0;
+
+ sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
+ hwdev = hinic3_get_hwdev_by_pcidev(dev);
+ if (!hwdev) {
+ sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
+ return -EPERM;
+ }
+
+ err = hinic3_pci_sriov_check(sriov_info, dev, num_vfs);
+ if (err != 0)
+ return err;
+
err = hinic3_init_vf_hw(hwdev, 1, (u16)num_vfs);
if (err) {
sdk_err(&dev->dev, "Failed to init vf in hardware before enable sriov, error %d\n",
@@ -262,6 +275,3 @@ int hinic3_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
else
return hinic3_pci_sriov_enable(dev, num_vfs);
}
-
-/*lint -restore*/
-
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h
index 4a640ad..becb5c7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h
@@ -7,13 +7,13 @@
#include <linux/pci.h>
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
-ssize_t hinic3_sriov_totalvfs_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-ssize_t hinic3_sriov_numvfs_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-ssize_t hinic3_sriov_numvfs_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count);
+ssize_t sriov_totalvfs_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+ssize_t sriov_numvfs_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+ssize_t sriov_numvfs_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
enum hinic3_sriov_state {
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c b/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c
index f8aea696..be83022 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c
@@ -117,3 +117,4 @@ u64 ossl_get_real_time(void)
tv_msec = (u64)tv.tv_sec * MSEC_PER_SEC + (u64)tv.tv_usec / USEC_PER_MSEC;
return tv_msec;
}
+
diff --git a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
index 9e8fc75..01ab739 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
@@ -10,6 +10,10 @@
#define OVS_PORT_NUM_MAX BOND_PORT_MAX_NUM
#define DEFAULT_ROCE_BOND_FUNC 0xFFFFFFFF
+#define BOND_ID_IS_VALID(_id) \
+ (((_id) >= BOND_FIRST_ID) && ((_id) <= BOND_MAX_ID))
+#define BOND_ID_IS_INVALID(_id) (!(BOND_ID_IS_VALID(_id)))
+
enum bond_group_id {
BOND_FIRST_ID = 1,
BOND_MAX_ID = 4,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
index e7e16fc..f9737ea 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
@@ -52,6 +52,8 @@ enum scenes_id_define {
SCENES_ID_STORAGE_ROCE = 6,
SCENES_ID_COMPUTE_ROCE = 7,
SCENES_ID_STORAGE_TOE = 8,
+ SCENES_ID_COMPUTE_DPU = 100,
+ SCENES_ID_COMPUTE_SMART_NIC = 101,
SCENES_ID_MAX
};
@@ -122,13 +124,18 @@ struct cfg_cmd_dev_cap {
u8 srv_multi_host_mode;
u8 virtio_vq_size;
- u32 rsvd_func3[5];
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 lro_enable;
+ u8 os_hot_replace;
+
+ u32 rsvd_func3[4];
/* l2nic */
u16 nic_max_sq_id;
u16 nic_max_rq_id;
u16 nic_default_num_queues;
- u16 rsvd1_nic;
+ u16 outband_vlan_cfg_en;
u32 rsvd2_nic[2];
/* RoCE */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
index d9f67e2..6c5b995 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
@@ -37,7 +37,7 @@ static inline void hinic3_cpu_to_be32(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -59,7 +59,7 @@ static inline void hinic3_be32_to_cpu(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -86,52 +86,16 @@ static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
sge->len = (u32)len;
}
-#ifdef HW_CONVERT_ENDIAN
#define hinic3_hw_be32(val) (val)
#define hinic3_hw_cpu32(val) (val)
#define hinic3_hw_cpu16(val) (val)
-#else
-#define hinic3_hw_be32(val) cpu_to_be32(val)
-#define hinic3_hw_cpu32(val) be32_to_cpu(val)
-#define hinic3_hw_cpu16(val) be16_to_cpu(val)
-#endif
static inline void hinic3_hw_be32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_be32(*mem);
- mem++;
- }
-#endif
}
static inline void hinic3_hw_cpu32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_cpu32(*mem);
- mem++;
- }
-#endif
}
int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
@@ -149,6 +113,8 @@ int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
/* func_attr.glb_func_idx, global function index */
u16 hinic3_global_func_id(void *hwdev);
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id);
+
/* func_attr.p2p_idx, belongs to which pf */
u8 hinic3_pf_id_of_vf(void *hwdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
index 9a9bfe2..e36ba1d 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
@@ -219,5 +219,7 @@ void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
const char **hinic3_get_uld_names(void);
+int hinic3_lld_init(void);
+void hinic3_lld_exit(void);
#endif
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
index 97d34f0..4cd6f94 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
@@ -43,6 +43,10 @@ enum mag_cmd {
MAG_CMD_GET_XSFP_PRESENT = 62, /* get xsfp present status @see mag_cmd_get_xsfp_present */
MAG_CMD_SET_XSFP_RW = 63, /* sfp/qsfp single byte read/write, @see mag_cmd_set_xsfp_rw */
MAG_CMD_CFG_XSFP_TEMPERATURE = 64, /* get xsfp temp @see mag_cmd_sfp_temp_out_info */
+ /**< set xsfp tlv info @see struct mag_cmd_set_xsfp_tlv_req */
+ MAG_CMD_SET_XSFP_TLV_INFO = 65,
+ /**< get xsfp tlv info @see struct drv_tag_mag_cmd_get_xsfp_tlv_rsp */
+ MAG_CMD_GET_XSFP_TLV_INFO = 66,
/* Event reported 100-149 */
MAG_CMD_WIRE_EVENT = 100,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
index caaba5d..d33b9f4 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
@@ -31,17 +31,28 @@ enum board_type_define_e {
BOARD_TYPE_STRG_2X100G_ROCE_AA = 42, /* 2X100G SmartIO ROCE_AA Card */
BOARD_TYPE_CAL_2X25G_NIC_75MPPS = 100, /* 2X25G ETH Standard card 75MPPS */
BOARD_TYPE_CAL_2X25G_NIC_40MPPS = 101, /* 2X25G ETH Standard card 40MPPS */
- BOARD_TYPE_CAL_2X100G_DPU = 102, /* 2x100G DPU Card */
+ BOARD_TYPE_CAL_2X100G_DPU_VL = 102, /* 2x100G DPU Card */
BOARD_TYPE_CAL_4X25G_NIC_120MPPS = 105, /* 4X25G ETH Standard card 120MPPS */
BOARD_TYPE_CAL_4X25G_COMSTORAGE = 106, /* 4X25GE compute storage Onboard Card */
BOARD_TYPE_CAL_2X32G_FC_HBA = 110, /* 2X32G FC HBA card */
BOARD_TYPE_CAL_2X16G_FC_HBA = 111, /* 2X16G FC HBA card */
BOARD_TYPE_CAL_2X100G_NIC_120MPPS = 115, /* 2X100G ETH Standard card 120MPPS */
- BOARD_TYPE_CAL_2X25G_DPU = 116, /* 2x25G DPU Card */
- BOARD_TYPE_CAL_4X25G_DPU = 118, /* 4x25G DPU Card */
+ BOARD_TYPE_CAL_2X25G_DPU_BD = 116, /* 2x25G DPU Card */
+ BOARD_TYPE_CAL_2X100G_TCE_BACKPLANE = 117,
+ BOARD_TYPE_CAL_4X25G_DPU_VL = 118, /* 4x25G DPU Card */
+ BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS = 119,
+ BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS = 120,
+ BOARD_TYPE_CAL_6X25G_DPU_VL = 121, /* 6x25G DPU Card */
+ BOARD_TYPE_CAL_4X25G_DPU_BD = 122,
+ BOARD_TYPE_CAL_2X25G_NIC_4HOST = 123,
+ BOARD_TYPE_CAL_2X10G_LOW_POWER = 125,
+ BOARD_TYPE_CAL_2X200G_NIC_INTERNET = 127,
+ BOARD_TYPE_CAL_1X100GR2_OCP = 129, /* 1X100G ETH Standard card */
+ BOARD_TYPE_CAL_2X200G_DPU_VL = 130,
BOARD_TYPE_CLD_2X100G_SDI5_1 = 170, /* 2X100G SDI 5.1 Card */
BOARD_TYPE_CLD_2X25G_SDI5_0_LITE = 171, /* 2x25G SDI5.0 Lite Card */
BOARD_TYPE_CLD_2X100G_SDI5_0 = 172, /* 2x100G SDI5.0 Card */
+ BOARD_TYPE_CLD_4X25G_SDI5_0_C = 175,
BOARD_TYPE_MAX_INDEX = 0xFF
};
@@ -49,23 +60,62 @@ static inline u32 spu_board_type_valid(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
- ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
}
static inline int board_type_is_sdi(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_1) ||
((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
- ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0);
+ ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C);
+}
+
+static inline int board_type_is_dpu_spu(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
}
static inline int board_type_is_dpu(u32 board_type)
{
- return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_6X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
+}
+
+/* 此接口判断是否是分布式存储的标卡以及计算的标卡(含ROCE特性),
+ * 仅用于LLDP TX功能冲突命令字处理的判断
+ */
+static inline int board_type_is_compute(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_75MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_40MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_NIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_COMSTORAGE) ||
+ ((board_type) == BOARD_TYPE_CAL_2X10G_LOW_POWER) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_NIC_INTERNET) ||
+ ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_4HOST) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_NIC_120MPPS);
+}
+
+/* 此接口判断服务器输入reboot网卡是否需要复位 */
+static inline int board_type_is_multi_socket(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP);
}
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
index 291e475..4d4d543 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
@@ -4,8 +4,95 @@
#ifndef MPU_CMD_BASE_DEFS_H
#define MPU_CMD_BASE_DEFS_H
-#include "mgmt_msg_base.h"
-#include "comm_defs.h"
+/** MPU CMD MODULE TYPE */
+enum hinic3_mod_type {
+ HINIC3_MOD_COMM = 0, /* HW communication module */
+ HINIC3_MOD_L2NIC = 1, /* L2NIC module */
+ HINIC3_MOD_ROCE = 2,
+ HINIC3_MOD_PLOG = 3,
+ HINIC3_MOD_TOE = 4,
+ HINIC3_MOD_FLR = 5,
+ HINIC3_MOD_VROCE = 6,
+ HINIC3_MOD_CFGM = 7, /* Configuration management */
+ HINIC3_MOD_CQM = 8,
+ HINIC3_MOD_VMSEC = 9,
+ COMM_MOD_FC = 10,
+ HINIC3_MOD_OVS = 11,
+ HINIC3_MOD_DSW = 12,
+ HINIC3_MOD_MIGRATE = 13,
+ HINIC3_MOD_HILINK = 14,
+ HINIC3_MOD_CRYPT = 15, /* secure crypto module */
+ HINIC3_MOD_VIO = 16,
+ HINIC3_MOD_IMU = 17,
+ HINIC3_MOD_DFX = 18, /* DFX */
+ HINIC3_MOD_HW_MAX = 19, /* hardware max module id */
+ /* Software module id, for PF/VF and multi-host */
+ HINIC3_MOD_SW_FUNC = 20,
+ HINIC3_MOD_MAX,
+};
+
+/* func reset的flag ,用于指示清理哪种资源 */
+enum func_reset_flag_e {
+ RES_TYPE_FLUSH_BIT = 0,
+ RES_TYPE_MQM,
+ RES_TYPE_SMF,
+ RES_TYPE_PF_BW_CFG,
+
+ RES_TYPE_COMM = 10,
+ RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_NIC,
+ RES_TYPE_OVS,
+ RES_TYPE_VBS,
+ RES_TYPE_ROCE,
+ RES_TYPE_FC,
+ RES_TYPE_TOE,
+ RES_TYPE_IPSEC,
+ RES_TYPE_MAX,
+};
+
+#define HINIC3_COMM_RES \
+ ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
+ (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
+ (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
+
+#define HINIC3_NIC_RES (1 << RES_TYPE_NIC)
+#define HINIC3_OVS_RES (1 << RES_TYPE_OVS)
+#define HINIC3_VBS_RES (1 << RES_TYPE_VBS)
+#define HINIC3_ROCE_RES (1 << RES_TYPE_ROCE)
+#define HINIC3_FC_RES (1 << RES_TYPE_FC)
+#define HINIC3_TOE_RES (1 << RES_TYPE_TOE)
+#define HINIC3_IPSEC_RES (1 << RES_TYPE_IPSEC)
+
+/* MODE OVS、NIC、UNKNOWN */
+#define HINIC3_WORK_MODE_OVS 0
+#define HINIC3_WORK_MODE_UNKNOWN 1
+#define HINIC3_WORK_MODE_NIC 2
+
+#define DEVICE_TYPE_L2NIC 0
+#define DEVICE_TYPE_NVME 1
+#define DEVICE_TYPE_VIRTIO_NET 2
+#define DEVICE_TYPE_VIRTIO_BLK 3
+#define DEVICE_TYPE_VIRTIO_VSOCK 4
+#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
+#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
+#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
+#define DEVICE_TYPE_VIRTIO_HPC 8
+#define DEVICE_TYPE_VIRTIO_FS 9
+
+#define IS_STORAGE_DEVICE_TYPE(dev_type) \
+ ((dev_type) == DEVICE_TYPE_VIRTIO_BLK || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_BLK_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_SCSI_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_FS)
+
+#define MGMT_MSG_CMD_OP_SET 1
+#define MGMT_MSG_CMD_OP_GET 0
+
+#define MGMT_MSG_CMD_OP_START 1
+#define MGMT_MSG_CMD_OP_STOP 0
+
+#define HOT_REPLACE_PARTITION_NUM 2
enum hinic3_svc_type {
SVC_T_COMM = 0,
@@ -23,4 +110,54 @@ enum hinic3_svc_type {
SVC_T_MAX,
};
+/**
+ * Common header control information of the COMM message interaction
+ * command word between the driver and PF
+ * struct mgmt_msg_head and struct comm_info_head are the same structure
+ */
+struct mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+/**
+ * Common header control information of the COMM message interaction
+ * command word between the driver and PF
+ */
+struct comm_info_head {
+ /** response status code, 0: success, others: error code */
+ u8 status;
+
+ /** firmware version for command */
+ u8 version;
+
+ /** response aeq number, unused for now */
+ u8 rep_aeq_num;
+ u8 rsvd[5];
+};
+
+static inline u32 get_function_partition(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM;
+}
+
+static inline u32 is_primary_function(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0;
+}
+
+static inline u32 mpu_nic_get_primary_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ function_id : (function_id - port_num);
+}
+
+// when func_id is in partition 0/1, it will get its another func_id in partition 1/0
+static inline u32 mpu_nic_get_backup_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ (function_id + port_num) : (function_id - port_num);
+}
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
index a8e2d63..3841bb5 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
@@ -91,6 +91,10 @@ enum hinic3_mgmt_cmd {
* @see comm_read_ucode_sm_resp
*/
COMM_MGMT_CMD_CLEAR_LOG, /**< clear log @see comm_cmd_clear_log_s */
+ COMM_MGMT_CMD_UCODE_SM_COUNTER_PER,
+ /**< get ucode sm counter @see struct comm_read_ucode_sm_per_req
+ * @see struct comm_read_ucode_sm_per_resp
+ */
COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140, /* check if switch workmode reserved
* @see comm_cmd_check_if_switch_workmode
@@ -103,6 +107,7 @@ enum hinic3_mgmt_cmd {
COMM_MGMT_CMD_CPI_TCAM_DBG, /* enable or disable the scheduled cpi tcam task,
* set task interval time @see comm_cmd_cpi_tcam_dbg_s
*/
+ COMM_MGMT_CMD_LLDP_TX_FUNC_SET,
COMM_MGMT_CMD_SECTION_RSVD_0 = 160, /**< rsvd0 section */
COMM_MGMT_CMD_SECTION_RSVD_1 = 170, /**< rsvd1 section */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
index 674603d..698730f 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
@@ -338,7 +338,8 @@ struct comm_cmd_get_fw_version {
struct mgmt_msg_head head;
u16 fw_type; /**< firmware type @see enum hinic3_fw_ver_type */
- u16 rsvd1;
+ u16 fw_dfx_vld : 1; /**< 0: release, 1: debug */
+ u16 rsvd1 : 15;
u8 ver[HINIC3_FW_VERSION_LEN]; /**< firmware version */
u8 time[HINIC3_FW_COMPILE_TIME_LEN]; /**< firmware compile time */
};
@@ -430,6 +431,22 @@ struct comm_cmd_bdf_info {
u8 rsvd2[5];
};
+struct mpu_pcie_pf_info {
+ u32 device_id; /**< device id */
+ u32 vendor_id; /**< vendor id */
+};
+
+struct mpu_pcie_device_info {
+ u8 status;
+ u8 version;
+ u8 rep_aeq_num;
+ u8 rsvd[5];
+
+ struct mpu_pcie_pf_info pf_info[32];
+ u32 bus_id; /**< bus id */
+ u32 pf_num; /**< pf index */
+};
+
#define TABLE_INDEX_MAX 129
struct sml_table_id_info {
u8 node_id;
@@ -446,6 +463,13 @@ struct comm_cmd_sdi_info {
u32 cfg_sdi_mode; /**< host mode, 0:normal 1:virtual machine 2:bare metal */
};
+struct comm_cmd_root_ctx_load_req {
+ struct comm_info_head head;
+ u32 func_id; /**< function id */
+ u32 smf_id; /**< smf id */
+ u32 queue_id; /**< queue id */
+};
+
#define HINIC_OVS_BOND_DEFAULT_ID 1
struct hinic3_hw_bond_infos {
u8 bond_id;
@@ -685,6 +709,28 @@ struct comm_read_ucode_sm_resp {
u64 val2;
};
+#define PER_REQ_MAX_DATA_LEN 0x600
+
+struct comm_read_ucode_sm_per_req {
+ struct mgmt_msg_head msg_head;
+
+ u32 tbl_type;
+ u32 count_id;
+};
+
+struct comm_read_ucode_sm_per_resp {
+ struct mgmt_msg_head msg_head;
+
+ u8 data[PER_REQ_MAX_DATA_LEN];
+};
+
+struct ucode_sm_counter_get_info {
+ u32 width_type;
+ u32 tbl_type;
+ unsigned int base_count;
+ unsigned int count_num;
+};
+
enum log_type {
MPU_LOG_CLEAR = 0,
SMU_LOG_CLEAR = 1,
@@ -693,6 +739,11 @@ enum log_type {
ALL_LOG_CLEAR = 4,
};
+struct comm_cmd_clear_log {
+ struct comm_info_head head;
+ u32 type; /**< log type @see enum log_type */
+};
+
#define ABLESWITCH 1
#define IMABLESWITCH 2
enum switch_workmode_op {
@@ -717,6 +768,14 @@ struct comm_cmd_check_if_switch_workmode {
u32 rsvd3[3];
};
+struct comm_cmd_switch_workmode {
+ struct mgmt_msg_head head;
+ u8 operation;
+ u8 work_mode;
+ u16 rsvd1[3];
+ u32 rsvd2[3];
+};
+
#define MIG_NOR_VM_ONE_MAX_SGE_MEM (64 * 8)
#define MIG_NOR_VM_ONE_MAX_MEM (MIG_NOR_VM_ONE_MAX_SGE_MEM + 16)
#define MIG_VM_MAX_SML_ENTRY_NUM 24
@@ -755,6 +814,15 @@ struct cmd_get_bdf_info_s {
#define CPI_TCAM_DBG_CMD_TYPE_SET 0
#define CPI_TCAM_DBG_CMD_TYPE_GET 1
+struct comm_cmd_cpi_tcam_dbg {
+ struct comm_info_head head;
+ u8 type;
+ u8 set_bitmap;
+ u8 enable;
+ u8 rsvd;
+ u32 time_interval;
+};
+
#define UDIE_ID_DATA_LEN 8
#define TDIE_ID_DATA_LEN 18
struct comm_cmd_get_die_id {
@@ -808,6 +876,12 @@ struct cmd_query_fw {
u32 len; /**< length */
};
+struct comm_cmd_get_cfg_info_t {
+ struct comm_info_head head;
+ u8 rsvd[8];
+ u8 info[64]; /**< flash config info */
+};
+
struct nic_cmd_get_uart_log_info {
struct comm_info_head head;
struct {
@@ -969,6 +1043,7 @@ enum comm_virtio_dev_type {
COMM_VIRTIO_NET_TYPE = 0,
COMM_VIRTIO_BLK_TYPE = 1,
COMM_VIRTIO_SCSI_TYPE = 4,
+ COMM_VIRTIO_FS_TYPE = 5,
};
struct comm_virtio_dev_cmd {
@@ -1030,6 +1105,13 @@ struct cmd_patch_sram_optimize {
u32 data[4]; /**< reserved */
};
+struct comm_cmd_con_sel_sta {
+ struct comm_info_head head;
+ u8 valid;
+ u8 host_id; /**< host id, range[0,3] */
+ u8 rsvd[2];
+};
+
/* ncsi counter */
struct nsci_counter_in_info_s {
struct comm_info_head head;
@@ -1082,7 +1164,9 @@ struct comm_cmd_ncsi_settings {
u8 lldp_over_ncsi_enable;
u8 lldp_over_mctp_enable;
u32 magicwd;
- u8 rsvd[8];
+ u8 lldp_tx_enable;
+ u8 rsvd[3];
+ u32 crc;
struct tag_ncsi_chan_info ncsi_chan_info;
};
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
index fde8617..1ee44a8 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
@@ -114,6 +114,14 @@ struct tag_ncsi_client_info {
#define AEN_CTRL_CONFIG_REQ_SHIFT 1
#define AEN_CTRL_DRV_CHANGE_SHIFT 2
+/* AEN Type */
+enum aen_type_e {
+ AEN_LINK_STATUS_CHANGE_TYPE = 0x0,
+ AEN_CONFIG_REQUIRED_TYPE = 0x1,
+ OEM_AEN_CONFIG_REQUEST_TYPE = 0x80,
+ AEN_TYPE_MAX = 0x100
+};
+
/* get link status 0x0A */
#define GET_LINK_STATUS_REQ_LEN 0
#define GET_LINK_STATUS_RSP_LEN 16
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
index 0bd168c..5b2bdc8 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
@@ -36,6 +36,7 @@ enum nic_rss_hash_type {
#define NIC_RX_MODE_BC 0x04
#define NIC_RX_MODE_MC_ALL 0x08
#define NIC_RX_MODE_PROMISC 0x10
+#define NIC_RX_DB_COS_MAX 0x4
/* IEEE 802.1Qaz std */
#define NIC_DCB_COS_MAX 0x8
@@ -52,4 +53,7 @@ enum nic_rss_hash_type {
#define NIC_DCB_PRIO_STRICT 0x1
#define NIC_DCB_MAX_PFC_NUM 0x4
+
+#define NIC_ETS_PERCENT_WEIGHT 100
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
index 801aeed..5476287 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
@@ -23,7 +23,11 @@
#define VRAM_CQM_BITMAP_BASE "B"
#define VRAM_NIC_DCB "DCB"
+#define VRAM_NIC_MHOST_MGMT "MHOST_MGMT"
#define VRAM_NIC_VRAM "NIC_VRAM"
+#define VRAM_NIC_IRQ_VRAM "NIC_IRQ"
+
+#define VRAM_NIC_MQM "NM"
#define VRAM_VBS_BASE_IOCB "BASE_IOCB"
#define VRAM_VBS_EX_IOCB "EX_IOCB"
@@ -32,6 +36,9 @@
#define VRAM_VBS_VOLQ_MTT "VOLQ_MTT"
#define VRAM_VBS_VOLQ_MTT_PAGE "MTT_PAGE"
+#define VRAM_OVS_PORT_CONF "OVS_PORT_CONF"
+#define VRAM_OVS_DFX_MGR "OVS_DFX_MGR"
+
#define VRAM_VROCE_ENTRY_POOL "VROCE_ENTRY"
#define VRAM_VROCE_GROUP_POOL "VROCE_GROUP"
#define VRAM_VROCE_UUID "VROCE_UUID"
@@ -42,6 +49,17 @@
#define VRAM_VROCE_DEV "VROCE_DEV"
#define VRAM_VROCE_RGROUP_HT_CNT "RGROUP_CNT"
#define VRAM_VROCE_RACL_HT_CNT "RACL_CNT"
+#define VRAM_VROCE_MQM_ENQC "VROCE_MQM_ENQC"
+
+#define VRAM_DTOE_NUMA_MEM "DTOE_NUMA"
+#define VRAM_DTOE_CARD_MEM "DTOE_CARD"
+#define VRAM_DTOE_CONN_MEM "DTOE_CONN"
+#define VRAM_DTOE_SUB_LEN 10
+
+#define VRAM_VROCE_MIG_ENTRY_POOL "VROCE_MIG_ENTRY"
+#define VRAM_VROCE_MIG_ENTRY_HT_CNT "MIG_ENTRY_CNT"
+
+#define VRAM_VBS_DEV_INDEX "VBS_INDEX"
#define VRAM_NAME_APPLY_LEN 64
@@ -55,11 +73,16 @@ enum KUP_HOOK_POINT {
PRE_FREEZE,
FREEZE_TO_KILL,
PRE_UPDATE_KERNEL,
- FLUSH_DURING_KUP,
POST_UPDATE_KERNEL,
UNFREEZE_TO_RUN,
POST_RUN,
KUP_HOOK_MAX,
};
+#define hi_vram_kalloc(name, size) 0
+#define hi_vram_kfree(vaddr, name, size)
+#define get_use_vram_flag(void) 0
+#define vram_get_kexec_flag(void) 0
+#define hi_vram_get_gfp_vram(void) 0
+
#endif /* VRAM_COMMON_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
similarity index 79%
rename from drivers/net/ethernet/huawei/hinic3/mag_cmd.h
rename to drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
index 9649503..c8533e5 100644
--- a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
@@ -9,6 +9,7 @@
/* serdes cmd struct define */
#define CMD_ARRAY_BUF_SIZE 64
#define SERDES_CMD_DATA_BUF_SIZE 512
+#define RATE_MBPS_TO_GBPS 1000
struct serdes_in_info {
u32 chip_id : 16;
u32 macro_id : 16;
@@ -127,6 +128,7 @@ enum mag_cmd_cnt_type {
MAG_RX_PCS_E_BLK_CNT = 5,
MAG_RX_PCS_DEC_ERR_BLK_CNT = 6,
MAG_RX_PCS_LANE_BIP_ERR_CNT = 7,
+ MAG_RX_RSFEC_ERR_CW_CNT = 8,
MAG_CNT_NUM
};
@@ -208,7 +210,9 @@ struct mag_cmd_get_port_info {
u32 supported_mode;
u32 advertised_mode;
- u8 rsvd2[8];
+ u32 supported_fec_mode;
+ u16 bond_speed;
+ u8 rsvd2[2];
};
#define MAG_CMD_OPCODE_GET 0
@@ -330,8 +334,8 @@ struct mag_cmd_cfg_fec_mode {
u8 port_id;
u8 opcode; /* 0:get fec mode 1:set fec mode */
- u8 fec;
- u8 rsvd0;
+ u8 advertised_fec;
+ u8 supported_fec;
};
/* speed */
@@ -641,7 +645,7 @@ struct mag_cmd_event_port_info {
u32 cable_length; /* 1/3/5m */
u8 cable_temp; /* temp */
u8 max_speed; /* Maximum rate of an optical module */
- u8 sfp_type; /* sfp/qsfp */
+ u8 sfp_type; /* sfp/qsfp/dsfp */
u8 rsvd1;
u32 power[4]; /* Optical Power */
@@ -678,6 +682,10 @@ struct mag_cmd_event_port_info {
u8 rsvd3[360];
};
+struct mag_cmd_rsfec_stats {
+ u32 rx_err_lane_phy;
+};
+
struct mag_cmd_port_stats {
u64 mac_tx_fragment_pkt_num;
u64 mac_tx_undersize_pkt_num;
@@ -913,10 +921,222 @@ struct mag_cmd_sfp_temp_in_info {
};
struct mag_cmd_sfp_temp_out_info {
- struct mgmt_msg_head head; /* 8B */
- s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
- s32 max_temp; /* Chip optical module threshold */
- s32 min_temp; /* Chip optical module threshold */
+ struct mgmt_msg_head head; /* 8B */
+ s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
+ s32 max_temp; /* Chip optical module threshold */
+ s32 min_temp; /* Chip optical module threshold */
+};
+
+#define XSFP_CMIS_PARSE_PAGE_NUM 6
+#define XSFP_CMIS_INFO_MAX_SIZE 1536
+#define QSFP_CMIS_PAGE_SIZE 128
+#define QSFP_CMIS_MAX_CHANNEL_NUM 0x8
+
+/* Lower: Control and Essentials, Upper: Administrative Information */
+#define QSFP_CMIS_PAGE_00H 0x00
+/* Advertising */
+#define QSFP_CMIS_PAGE_01H 0x01
+/* Module and lane Thresholds */
+#define QSFP_CMIS_PAGE_02H 0x02
+/* User EEPROM */
+#define QSFP_CMIS_PAGE_03H 0x03
+/* Laser Capabilities Advertising (Page 04h, Optional) */
+#define QSFP_CMIS_PAGE_04H 0x04
+#define QSFP_CMIS_PAGE_05H 0x05
+/* Lane and Data Path Control */
+#define QSFP_CMIS_PAGE_10H 0x10
+/* Lane Status */
+#define QSFP_CMIS_PAGE_11H 0x11
+#define QSFP_CMIS_PAGE_12H 0x12
+
+#define MGMT_TLV_U8_SIZE 1
+#define MGMT_TLV_U16_SIZE 2
+#define MGMT_TLV_U32_SIZE 4
+
+#define MGMT_TLV_GET_U8(addr) (*((u8 *)(void *)(addr)))
+#define MGMT_TLV_SET_U8(addr, value) \
+ ((*((u8 *)(void *)(addr))) = ((u8)(value)))
+
+#define MGMT_TLV_GET_U16(addr) (*((u16 *)(void *)(addr)))
+#define MGMT_TLV_SET_U16(addr, value) \
+ ((*((u16 *)(void *)(addr))) = ((u16)(value)))
+
+#define MGMT_TLV_GET_U32(addr) (*((u32 *)(void *)(addr)))
+#define MGMT_TLV_SET_U32(addr, value) \
+ ((*((u32 *)(void *)(addr))) = ((u32)(value)))
+
+#define MGMT_TLV_TYPE_END 0xFFFF
+
+enum mag_xsfp_type {
+ MAG_XSFP_TYPE_PAGE = 0x01,
+ MAG_XSFP_TYPE_WIRE_TYPE = 0x02,
+ MAG_XSFP_TYPE_END = MGMT_TLV_TYPE_END
+};
+
+struct qsfp_cmis_lower_page_00_s {
+ u8 resv0[14];
+ u8 temperature_msb;
+ u8 temperature_lsb;
+ u8 volt_supply[2];
+ u8 resv1[67];
+ u8 media_type;
+ u8 electrical_interface_id;
+ u8 media_interface_id;
+ u8 lane_count;
+ u8 resv2[39];
+};
+
+struct qsfp_cmis_upper_page_00_s {
+ u8 identifier;
+ u8 vendor_name[16];
+ u8 vendor_oui[3];
+ u8 vendor_pn[16];
+ u8 vendor_rev[2];
+ u8 vendor_sn[16];
+ u8 date_code[8];
+ u8 clei_code[10];
+ u8 power_character[2];
+ u8 cable_len;
+ u8 connector;
+ u8 copper_cable_attenuation[6];
+ u8 near_end_implementation;
+ u8 far_end_config;
+ u8 media_technology;
+ u8 resv0[43];
+};
+
+struct qsfp_cmis_upper_page_01_s {
+ u8 firmware_rev[2];
+ u8 hardware_rev[2];
+ u8 smf_len_km;
+ u8 om5_len;
+ u8 om4_len;
+ u8 om3_len;
+ u8 om2_len;
+ u8 resv0;
+ u8 wavelength[2];
+ u8 wavelength_tolerance[2];
+ u8 pages_implement;
+ u8 resv1[16];
+ u8 monitor_implement[2];
+ u8 resv2[95];
+};
+
+struct qsfp_cmis_upper_page_02_s {
+ u8 temperature_high_alarm[2];
+ u8 temperature_low_alarm[2];
+ u8 temperature_high_warn[2];
+ u8 temperature_low_warn[2];
+ u8 volt_high_alarm[2];
+ u8 volt_low_alarm[2];
+ u8 volt_high_warn[2];
+ u8 volt_low_warn[2];
+ u8 resv0[32];
+ u8 tx_power_high_alarm[2];
+ u8 tx_power_low_alarm[2];
+ u8 tx_power_high_warn[2];
+ u8 tx_power_low_warn[2];
+ u8 tx_bias_high_alarm[2];
+ u8 tx_bias_low_alarm[2];
+ u8 tx_bias_high_warn[2];
+ u8 tx_bias_low_warn[2];
+ u8 rx_power_high_alarm[2];
+ u8 rx_power_low_alarm[2];
+ u8 rx_power_high_warn[2];
+ u8 rx_power_low_warn[2];
+ u8 resv1[56];
+};
+
+struct qsfp_cmis_upper_page_03_s {
+ u8 resv0[QSFP_CMIS_PAGE_SIZE]; /* Reg 128-255: Upper Memory: Page 03H */
+};
+
+struct qsfp_cmis_upper_page_10_s {
+ u8 resv0[2]; /* Reg 128-129: Upper Memory: Page 10H */
+ u8 tx_disable; /* Reg 130: Tx disable, 0b=enabled, 1b=disabled */
+ u8 resv1[125]; /* Reg 131-255 */
+};
+
+struct qsfp_cmis_upper_page_11_s {
+ u8 resv0[7];
+ u8 tx_fault;
+ u8 tx_los;
+ u8 resv1[10];
+ u8 rx_los;
+ u8 resv2[6];
+ u8 tx_power[16];
+ u8 tx_bias[16];
+ u8 rx_power[16];
+ u8 resv3[54];
+};
+
+struct qsfp_cmis_info_s {
+ struct qsfp_cmis_lower_page_00_s lower_page_00;
+ struct qsfp_cmis_upper_page_00_s upper_page_00;
+ struct qsfp_cmis_upper_page_01_s upper_page_01;
+ struct qsfp_cmis_upper_page_02_s upper_page_02;
+ struct qsfp_cmis_upper_page_10_s upper_page_10;
+ struct qsfp_cmis_upper_page_11_s upper_page_11;
+};
+
+struct qsfp_cmis_comm_power_s {
+ u32 chl_power[QSFP_CMIS_MAX_CHANNEL_NUM];
+};
+
+struct qsfp_cmis_wire_info_s {
+ struct qsfp_cmis_comm_power_s rx_power;
+ u8 rx_los;
+ u8 resv0[3];
+};
+
+struct mgmt_tlv_info {
+ u16 type;
+ u16 length;
+ u8 value[];
+};
+
+struct mag_cmd_set_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 tlv_buf[];
+};
+
+struct mag_cmd_set_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+};
+
+struct tag_mag_cmd_get_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd;
+ u16 rsp_buf_len;
+};
+
+struct mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[];
+};
+
+struct parse_tlv_info {
+ u8 tlv_page_info[XSFP_CMIS_INFO_MAX_SIZE + 1];
+ u32 tlv_page_info_len;
+ u32 tlv_page_num[XSFP_CMIS_PARSE_PAGE_NUM];
+ u32 wire_type;
+ u8 id;
+};
+
+struct drv_tag_mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[XSFP_CMIS_INFO_MAX_SIZE];
};
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h b/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
deleted file mode 100644
index 257bf67..0000000
--- a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : mgmt_msg_base.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef MGMT_MSG_BASE_H
-#define MGMT_MSG_BASE_H
-
-#define MGMT_MSG_CMD_OP_SET 1
-#define MGMT_MSG_CMD_OP_GET 0
-
-#define MGMT_MSG_CMD_OP_START 1
-#define MGMT_MSG_CMD_OP_STOP 0
-
-struct mgmt_msg_head {
- u8 status;
- u8 version;
- u8 rsvd0[6];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
deleted file mode 100644
index abcfa27..0000000
--- a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2001-2021, Huawei Tech. Co., Ltd.
- * File Name : nic_cfg_comm.h
- * Version : Initial Draft
- * Description : nic config common header file
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef NIC_CFG_COMM_H
-#define NIC_CFG_COMM_H
-
-#include <linux/types.h>
-
-/* rss */
-#define HINIC3_RSS_TYPE_VALID_SHIFT 23
-#define HINIC3_RSS_TYPE_TCP_IPV6_EXT_SHIFT 24
-#define HINIC3_RSS_TYPE_IPV6_EXT_SHIFT 25
-#define HINIC3_RSS_TYPE_TCP_IPV6_SHIFT 26
-#define HINIC3_RSS_TYPE_IPV6_SHIFT 27
-#define HINIC3_RSS_TYPE_TCP_IPV4_SHIFT 28
-#define HINIC3_RSS_TYPE_IPV4_SHIFT 29
-#define HINIC3_RSS_TYPE_UDP_IPV6_SHIFT 30
-#define HINIC3_RSS_TYPE_UDP_IPV4_SHIFT 31
-
-#define HINIC3_RSS_TYPE_SET(val, member) (((u32)(val) & 0x1) << HINIC3_RSS_TYPE_##member##_SHIFT)
-#define HINIC3_RSS_TYPE_GET(val, member) (((u32)(val) >> HINIC3_RSS_TYPE_##member##_SHIFT) & 0x1)
-
-enum nic_rss_hash_type {
- NIC_RSS_HASH_TYPE_XOR = 0,
- NIC_RSS_HASH_TYPE_TOEP,
-
- NIC_RSS_HASH_TYPE_MAX /* MUST BE THE LAST ONE */
-};
-
-#define NIC_RSS_INDIR_SIZE 256
-#define NIC_RSS_KEY_SIZE 40
-
-/* *
- * Definition of the NIC receiving mode
- */
-#define NIC_RX_MODE_UC 0x01
-#define NIC_RX_MODE_MC 0x02
-#define NIC_RX_MODE_BC 0x04
-#define NIC_RX_MODE_MC_ALL 0x08
-#define NIC_RX_MODE_PROMISC 0x10
-
-/* IEEE 802.1Qaz std */
-#define NIC_DCB_COS_MAX 0x8
-#define NIC_DCB_UP_MAX 0x8
-#define NIC_DCB_TC_MAX 0x8
-#define NIC_DCB_PG_MAX 0x8
-#define NIC_DCB_TSA_SP 0x0
-#define NIC_DCB_TSA_CBS 0x1
-#define NIC_DCB_TSA_ETS 0x2
-#define NIC_DCB_DSCP_NUM 0x8
-#define NIC_DCB_IP_PRI_MAX 0x40
-
-#define NIC_DCB_PRIO_DWRR 0x0
-#define NIC_DCB_PRIO_STRICT 0x1
-
-#define NIC_DCB_MAX_PFC_NUM 0x4
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
similarity index 77%
rename from drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
rename to drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
index c35bc82..b0114a0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
- * File Name : hinic3_comm_cmd.h
+ * File Name : hinic3_nic_mpu_cmd.h
* Version : Initial Draft
* Created : 2019/4/25
* Last Modified :
@@ -33,10 +33,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_CFG_LOCAL_LRO_STATE,
HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
+ HINIC3_NIC_CMD_SET_FUNC_ER_FWD_ID,
HINIC3_NIC_CMD_SET_RQ_CI_CTX,
- /* MAC & VLAN CFG */
+ /* MAC & VLAN CFG & VXLAN CFG */
HINIC3_NIC_CMD_GET_MAC = 20,
HINIC3_NIC_CMD_SET_MAC,
HINIC3_NIC_CMD_DEL_MAC,
@@ -47,6 +48,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_VLAN_FILTER_EN,
HINIC3_NIC_CMD_SET_RX_VLAN_OFFLOAD,
HINIC3_NIC_CMD_SMAC_CHECK_STATE,
+ HINIC3_NIC_CMD_OUTBAND_SET_FUNC_VLAN,
+ HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+
+ HINIC3_NIC_CMD_RX_RATE_CFG,
+ HINIC3_NIC_CMD_WR_ORDERING_CFG,
/* SR-IOV */
HINIC3_NIC_CMD_CFG_VF_VLAN = 40,
@@ -63,6 +69,7 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC,
/* IP checksum error packets, enable rss quadruple hash */
HINIC3_NIC_CMD_IPCS_ERR_RSS_ENABLE_OP = 66,
+ HINIC3_NIC_CMD_GTP_INNER_PARSE_STATUS,
/* PPA/FDIR */
HINIC3_NIC_CMD_ADD_TC_FLOW = 80,
@@ -78,6 +85,10 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_CFG_PPA_FLUSH,
HINIC3_NIC_CMD_SET_FDIR_STATUS,
HINIC3_NIC_CMD_GET_PPA_COUNTER,
+ HINIC3_NIC_CMD_SET_FUNC_FLOW_BIFUR_ENABLE,
+ HINIC3_NIC_CMD_SET_BOND_MASK,
+ HINIC3_NIC_CMD_GET_BLOCK_TC_FLOWS,
+ HINIC3_NIC_CMD_GET_BOND_MASK,
/* PORT CFG */
HINIC3_NIC_CMD_SET_PORT_ENABLE = 100,
@@ -96,6 +107,8 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_QOS_PORT_CFG,
HINIC3_NIC_CMD_QOS_MAP_CFG,
HINIC3_NIC_CMD_FORCE_PKT_DROP,
+ HINIC3_NIC_CMD_CFG_TX_PROMISC_SKIP = 114,
+ HINIC3_NIC_CMD_SET_PORT_FLOW_BIFUR_ENABLE = 117,
HINIC3_NIC_CMD_TX_PAUSE_EXCP_NOTICE = 118,
HINIC3_NIC_CMD_INQUIRT_PAUSE_CFG = 119,
@@ -118,6 +131,10 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_UCAPTURE_OPT = 160, /* TODO: move to roce */
HINIC3_NIC_CMD_SET_VHD_CFG,
+ /* OUT OF BAND */
+ HINIC3_NIC_CMD_GET_OUTBAND_CFG = 170, /* Get outband vlan cfg info */
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE, /* Outband vlan cfg info report */
+
/* TODO: move to HILINK */
HINIC3_NIC_CMD_GET_PORT_STAT = 200,
HINIC3_NIC_CMD_CLEAN_PORT_STAT,
@@ -138,24 +155,23 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_LINK_ERR_EVENT,
HINIC3_NIC_CMD_SET_LED_STATUS,
- HINIC3_NIC_CMD_MAX = 256,
-};
+ /* mig */
+ HINIC3_NIC_CMD_MIG_SET_CEQ_CTRL = 230,
+ HINIC3_NIC_CMD_MIG_CFG_MSIX_INFO,
+ HINIC3_NIC_CMD_MIG_CFG_FUNC_VAT_TBL,
+ HINIC3_NIC_CMD_MIG_GET_VF_INFO,
+ HINIC3_NIC_CMD_MIG_CHK_MBX_EMPTY,
+ HINIC3_NIC_CMD_MIG_SET_VPORT_ENABLE,
+ HINIC3_NIC_CMD_MIG_CFG_SQ_CI,
+ HINIC3_NIC_CMD_MIG_CFG_RSS_TBL,
+ HINIC3_NIC_CMD_MIG_CFG_MAC_TBL,
+ HINIC3_NIC_CMD_MIG_TMP_SET_CMDQ_CTX,
-/* NIC CMDQ MODE */
-enum hinic3_ucode_cmd {
- HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
- HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
- HINIC3_UCODE_CMD_ARM_SQ,
- HINIC3_UCODE_CMD_ARM_RQ,
- HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_SET_IQ_ENABLE,
- HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
- HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
- HINIC3_UCODE_CMD_PPA_HASH_TABLE,
- HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_OSHR_CMD_ACTIVE_FUNCTION = 240,
+
+ HINIC3_NIC_CMD_GET_RQ_INFO = 241,
+
+ HINIC3_NIC_CMD_MAX = 256,
};
#endif /* HINIC3_NIC_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
new file mode 100644
index 0000000..5c28573
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
@@ -0,0 +1,1440 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+
+#ifndef NIC_MPU_CMD_DEFS_H
+#define NIC_MPU_CMD_DEFS_H
+
+#include "nic_cfg_comm.h"
+#include "mpu_cmd_base_defs.h"
+
+#ifndef ETH_ALEN
+#define ETH_ALEN 6
+#endif
+
+#define HINIC3_CMD_OP_SET 1
+#define HINIC3_CMD_OP_GET 0
+
+#define HINIC3_CMD_OP_ADD 1
+#define HINIC3_CMD_OP_DEL 0
+
+#define NIC_TCAM_BLOCK_LARGE_NUM 256
+#define NIC_TCAM_BLOCK_LARGE_SIZE 16
+
+#define TRAFFIC_BIFUR_MODEL_TYPE 2
+
+#define NIC_TCAM_FLOW_BIFUR_FLAG (1 << 0)
+
+#ifndef BIT
+#define BIT(n) (1UL << (n))
+#endif
+
+enum nic_feature_cap {
+ NIC_F_CSUM = BIT(0),
+ NIC_F_SCTP_CRC = BIT(1),
+ NIC_F_TSO = BIT(2),
+ NIC_F_LRO = BIT(3),
+ NIC_F_UFO = BIT(4),
+ NIC_F_RSS = BIT(5),
+ NIC_F_RX_VLAN_FILTER = BIT(6),
+ NIC_F_RX_VLAN_STRIP = BIT(7),
+ NIC_F_TX_VLAN_INSERT = BIT(8),
+ NIC_F_VXLAN_OFFLOAD = BIT(9),
+ NIC_F_IPSEC_OFFLOAD = BIT(10),
+ NIC_F_FDIR = BIT(11),
+ NIC_F_PROMISC = BIT(12),
+ NIC_F_ALLMULTI = BIT(13),
+ NIC_F_XSFP_REPORT = BIT(14),
+ NIC_F_VF_MAC = BIT(15),
+ NIC_F_RATE_LIMIT = BIT(16),
+ NIC_F_RXQ_RECOVERY = BIT(17),
+ NIC_F_TX_COMPACT_WQE_OL = BIT(19),
+ NIC_F_RX_COMPACT_CQE = BIT(20),
+ NIC_F_HTN_CMDQ = BIT(21),
+};
+
+#define NIC_F_ALL_MASK 0x7FBFFFF /* 使能所有属性 */
+
+struct hinic3_mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+#define NIC_MAX_FEATURE_QWORD 4
+struct hinic3_cmd_feature_nego {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 1: set, 0: get */
+ u8 rsvd;
+ u64 s_feature[NIC_MAX_FEATURE_QWORD];
+};
+
+struct hinic3_port_mac_set {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 rsvd1;
+ u8 mac[ETH_ALEN];
+};
+
+struct hinic3_port_mac_update {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 rsvd1;
+ u8 old_mac[ETH_ALEN];
+ u16 rsvd2;
+ u8 new_mac[ETH_ALEN];
+};
+
+struct hinic3_vport_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 state; /* 0--disable, 1--enable */
+ u8 rsvd2[3];
+};
+
+struct hinic3_port_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 state; /* 0--disable, 1--enable */
+ u8 rsvd2[3];
+};
+
+#define HINIC3_SET_PORT_CAR_PROFILE 0
+#define HINIC3_SET_PORT_CAR_STATE 1
+#define HINIC3_GET_PORT_CAR_LIMIT_SPEED 2
+
+struct hinic3_port_car_info {
+ u32 cir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
+ u32 xir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
+ u32 cbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
+ u32 xbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
+};
+
+struct hinic3_cmd_set_port_car {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode; /* 0--set car profile, 1--set car state */
+ u8 state; /* 0--disable, 1--enable */
+ u8 level;
+
+ struct hinic3_port_car_info car;
+};
+
+struct hinic3_cmd_clear_qp_resource {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_cmd_cache_out_qp_resource {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_port_stats_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_vport_stats {
+ u64 tx_unicast_pkts_vport;
+ u64 tx_unicast_bytes_vport;
+ u64 tx_multicast_pkts_vport;
+ u64 tx_multicast_bytes_vport;
+ u64 tx_broadcast_pkts_vport;
+ u64 tx_broadcast_bytes_vport;
+
+ u64 rx_unicast_pkts_vport;
+ u64 rx_unicast_bytes_vport;
+ u64 rx_multicast_pkts_vport;
+ u64 rx_multicast_bytes_vport;
+ u64 rx_broadcast_pkts_vport;
+ u64 rx_broadcast_bytes_vport;
+
+ u64 tx_discard_vport;
+ u64 rx_discard_vport;
+ u64 tx_err_vport;
+ u64 rx_err_vport;
+};
+
+struct hinic3_phy_fpga_port_stats {
+ u64 mac_rx_total_octs_port;
+ u64 mac_tx_total_octs_port;
+ u64 mac_rx_under_frame_pkts_port;
+ u64 mac_rx_frag_pkts_port;
+ u64 mac_rx_64_oct_pkts_port;
+ u64 mac_rx_127_oct_pkts_port;
+ u64 mac_rx_255_oct_pkts_port;
+ u64 mac_rx_511_oct_pkts_port;
+ u64 mac_rx_1023_oct_pkts_port;
+ u64 mac_rx_max_oct_pkts_port;
+ u64 mac_rx_over_oct_pkts_port;
+ u64 mac_tx_64_oct_pkts_port;
+ u64 mac_tx_127_oct_pkts_port;
+ u64 mac_tx_255_oct_pkts_port;
+ u64 mac_tx_511_oct_pkts_port;
+ u64 mac_tx_1023_oct_pkts_port;
+ u64 mac_tx_max_oct_pkts_port;
+ u64 mac_tx_over_oct_pkts_port;
+ u64 mac_rx_good_pkts_port;
+ u64 mac_rx_crc_error_pkts_port;
+ u64 mac_rx_broadcast_ok_port;
+ u64 mac_rx_multicast_ok_port;
+ u64 mac_rx_mac_frame_ok_port;
+ u64 mac_rx_length_err_pkts_port;
+ u64 mac_rx_vlan_pkts_port;
+ u64 mac_rx_pause_pkts_port;
+ u64 mac_rx_unknown_mac_frame_port;
+ u64 mac_tx_good_pkts_port;
+ u64 mac_tx_broadcast_ok_port;
+ u64 mac_tx_multicast_ok_port;
+ u64 mac_tx_underrun_pkts_port;
+ u64 mac_tx_mac_frame_ok_port;
+ u64 mac_tx_vlan_pkts_port;
+ u64 mac_tx_pause_pkts_port;
+};
+
+struct hinic3_port_stats {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ struct hinic3_phy_fpga_port_stats stats;
+};
+
+struct hinic3_cmd_vport_stats {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u32 stats_size;
+ u32 rsvd1;
+ struct hinic3_vport_stats stats;
+ u64 rsvd2[6];
+};
+
+struct hinic3_cmd_qpn {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 base_qpn;
+};
+
+enum hinic3_func_tbl_cfg_bitmap {
+ FUNC_CFG_INIT,
+ FUNC_CFG_RX_BUF_SIZE,
+ FUNC_CFG_MTU,
+};
+
+struct hinic3_func_tbl_cfg {
+ u16 rx_wqe_buf_size;
+ u16 mtu;
+ u32 rsvd[9];
+};
+
+struct hinic3_cmd_set_func_tbl {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd;
+
+ u32 cfg_bitmap;
+ struct hinic3_func_tbl_cfg tbl_cfg;
+};
+
+struct hinic3_cmd_cons_idx_attr {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_idx;
+ u8 dma_attr_off;
+ u8 pending_limit;
+ u8 coalescing_time;
+ u8 intr_en;
+ u16 intr_idx;
+ u32 l2nic_sqn;
+ u32 rsvd;
+ u64 ci_addr;
+};
+
+union sm_tbl_args {
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } mac_table_arg;
+ struct {
+ u32 er_id;
+ u32 vlan_id;
+ } vlan_elb_table_arg;
+ struct {
+ u32 func_id;
+ } vlan_filter_arg;
+ struct {
+ u32 mc_id;
+ } mc_elb_arg;
+ struct {
+ u32 func_id;
+ } func_tbl_arg;
+ struct {
+ u32 port_id;
+ } port_tbl_arg;
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } fdir_io_table_arg;
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } flexq_table_arg;
+ u32 args[4];
+};
+
+struct hinic3_rq_cqe_ctx {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 cqe_type;
+ u8 rq_id;
+ u8 threshold_cqe_num;
+ u8 rsvd1;
+
+ u16 msix_entry_idx;
+ u16 rsvd2;
+
+ u32 ci_addr_hi;
+ u32 ci_addr_lo;
+
+ u16 timer_loop;
+ u16 rsvd3;
+};
+
+#define DFX_SM_TBL_BUF_MAX (768)
+
+struct nic_cmd_dfx_sm_table {
+ struct hinic3_mgmt_msg_head msg_head;
+ u32 tbl_type;
+ union sm_tbl_args args;
+ u8 tbl_buf[DFX_SM_TBL_BUF_MAX];
+};
+
+struct hinic3_cmd_vlan_offload {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 vlan_offload;
+ u8 rsvd1[5];
+};
+
+/* ucode capture cfg info */
+struct nic_cmd_capture_info {
+ struct hinic3_mgmt_msg_head msg_head;
+ u32 op_type;
+ u32 func_port;
+ u32 is_en_trx;
+ u32 offset_cos;
+ u32 data_vlan;
+};
+
+struct hinic3_cmd_lro_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u8 lro_ipv4_en;
+ u8 lro_ipv6_en;
+ u8 lro_max_pkt_len; /* unit is 1K */
+ u8 resv2[13];
+};
+
+struct hinic3_cmd_lro_timer {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 opcode; /* 1: set timer value, 0: get timer value */
+ u8 rsvd1;
+ u16 rsvd2;
+ u32 timer;
+};
+
+struct hinic3_cmd_local_lro_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 state; /* 0: disable, 1: enable */
+};
+
+struct hinic3_cmd_gtp_inner_parse_status {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 status; /* 0: disable, 1: enable */
+};
+
+struct hinic3_cmd_vf_vlan_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u16 vlan_id;
+ u8 qos;
+ u8 rsvd2[5];
+};
+
+struct hinic3_cmd_spoofchk_set {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 state;
+ u8 rsvd1;
+};
+
+struct hinic3_cmd_tx_rate_cfg {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 rsvd1;
+ u8 direct;
+ u32 min_rate;
+ u32 max_rate;
+ u8 rsvd2[8];
+};
+
+struct hinic3_cmd_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+ u8 port_type;
+ u8 autoneg_cap;
+ u8 autoneg_state;
+ u8 duplex;
+ u8 speed;
+ u8 fec;
+ u16 rsvd2;
+ u32 rsvd3[4];
+};
+
+struct hinic3_cmd_register_vf {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 op_register; /* 0 - unregister, 1 - register */
+ u8 rsvd1[3];
+ u32 support_extra_feature;
+ u8 rsvd2[32];
+};
+
+struct hinic3_cmd_link_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 state;
+ u16 rsvd1;
+};
+
+struct hinic3_cmd_vlan_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 outband_defvid_flag;
+ u16 vlan_id;
+ u8 blacklist_flag;
+ u8 rsvd2;
+};
+
+#define VLAN_BLACKLIST_ENABLE 1
+#define VLAN_BLACKLIST_DISABLE 0
+
+struct hinic3_cmd_vxlan_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 cfg_mode;
+ u16 vxlan_port;
+ u16 rsvd2;
+};
+
+/* set vlan filter */
+struct hinic3_cmd_set_vlan_filter {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 resvd[2];
+ u32 vlan_filter_ctrl; /* bit0:vlan filter en; bit1:broadcast_filter_en */
+};
+
+struct hinic3_cmd_link_ksettings_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+
+ u32 valid_bitmap;
+ u8 speed; /* enum nic_speed_level */
+ u8 autoneg; /* 0 - off, 1 - on */
+ u8 fec; /* 0 - RSFEC, 1 - BASEFEC, 2 - NOFEC */
+ u8 rsvd2[21]; /* reserved for duplex, port, etc. */
+};
+
+struct mpu_lt_info {
+ u8 node;
+ u8 inst;
+ u8 entry_size;
+ u8 rsvd;
+ u32 lt_index;
+ u32 offset;
+ u32 len;
+};
+
+struct nic_mpu_lt_opera {
+ struct hinic3_mgmt_msg_head msg_head;
+ struct mpu_lt_info net_lt_cmd;
+ u8 data[100];
+};
+
+struct hinic3_force_pkt_drop {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port;
+ u8 rsvd1[3];
+};
+
+struct hinic3_rx_mode_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u32 rx_mode;
+};
+
+/* rss */
+struct hinic3_rss_context_table {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u32 context;
+};
+
+struct hinic3_cmd_rss_engine_type {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 hash_engine;
+ u8 rsvd1[4];
+};
+
+struct hinic3_cmd_rss_hash_key {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u8 key[NIC_RSS_KEY_SIZE];
+};
+
+struct hinic3_rss_indir_table {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 indir[NIC_RSS_INDIR_SIZE];
+};
+
+#define NIC_RSS_CMD_TEMP_ALLOC 0x01
+#define NIC_RSS_CMD_TEMP_FREE 0x02
+
+struct hinic3_rss_template_mgmt {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 cmd;
+ u8 template_id;
+ u8 rsvd1[4];
+};
+
+struct hinic3_cmd_rss_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 rss_en;
+ u8 rq_priority_number;
+ u8 prio_tc[NIC_DCB_COS_MAX];
+ u16 num_qps;
+ u16 rsvd1;
+};
+
+struct hinic3_dcb_state {
+ u8 dcb_on;
+ u8 default_cos;
+ u8 trust;
+ u8 rsvd1;
+ u8 pcp2cos[NIC_DCB_UP_MAX];
+ u8 dscp2cos[64];
+ u32 rsvd2[7];
+};
+
+struct hinic3_cmd_vf_dcb_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ struct hinic3_dcb_state state;
+};
+
+struct hinic3_up_ets_cfg { /* delet */
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+
+ u8 cos_tc[NIC_DCB_COS_MAX];
+ u8 tc_bw[NIC_DCB_TC_MAX];
+ u8 cos_prio[NIC_DCB_COS_MAX];
+ u8 cos_bw[NIC_DCB_COS_MAX];
+ u8 tc_prio[NIC_DCB_TC_MAX];
+};
+
+#define CMD_QOS_ETS_COS_TC BIT(0)
+#define CMD_QOS_ETS_TC_BW BIT(1)
+#define CMD_QOS_ETS_COS_PRIO BIT(2)
+#define CMD_QOS_ETS_COS_BW BIT(3)
+#define CMD_QOS_ETS_TC_PRIO BIT(4)
+#define CMD_QOS_ETS_TC_RATELIMIT BIT(5)
+struct hinic3_cmd_ets_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 1 - set, 0 - get */
+ /* bit0 - cos_tc, bit1 - tc_bw, bit2 - cos_prio, bit3 - cos_bw, bit4 - tc_prio */
+ u8 cfg_bitmap;
+ u8 rsvd;
+
+ u8 cos_tc[NIC_DCB_COS_MAX];
+ u8 tc_bw[NIC_DCB_TC_MAX];
+ u8 cos_prio[NIC_DCB_COS_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 cos_bw[NIC_DCB_COS_MAX];
+ u8 tc_prio[NIC_DCB_TC_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 rate_limit[NIC_DCB_TC_MAX];
+};
+
+struct hinic3_cmd_set_dcb_state {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 op_code; /* 0 - get dcb state, 1 - set dcb state */
+ u8 state; /* 0 - disable, 1 - enable dcb */
+ u8 port_state; /* 0 - disable, 1 - enable dcb */
+ u8 rsvd[7];
+};
+
+#define PFC_BIT_MAP_NUM 8
+struct hinic3_cmd_set_pfc {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 0:get 1: set pfc_en 2: set pfc_bitmap 3: set all */
+ u8 pfc_en; /* pfc_en 和 pfc_bitmap 必须同时设置 */
+ u8 pfc_bitmap;
+ u8 rsvd[4];
+};
+
+#define CMD_QOS_PORT_TRUST BIT(0)
+#define CMD_QOS_PORT_DFT_COS BIT(1)
+struct hinic3_cmd_qos_port_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 0 - get, 1 - set */
+ u8 cfg_bitmap; /* bit0 - trust, bit1 - dft_cos */
+ u8 rsvd0;
+
+ u8 trust;
+ u8 dft_cos;
+ u8 rsvd1[18];
+};
+
+#define MAP_COS_MAX_NUM 8
+#define CMD_QOS_MAP_PCP2COS BIT(0)
+#define CMD_QOS_MAP_DSCP2COS BIT(1)
+struct hinic3_cmd_qos_map_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 op_code;
+ u8 cfg_bitmap; /* bit0 - pcp2cos, bit1 - dscp2cos */
+ u16 rsvd0;
+
+ u8 pcp2cos[8]; /* 8 must be configured together */
+ /* If the dscp2cos parameter is set to 0xFF, the MPU ignores the DSCP priority,
+ * Multiple mappings between DSCP values and CoS values can be configured at a time.
+ */
+ u8 dscp2cos[64];
+ u32 rsvd1[4];
+};
+
+struct hinic3_cos_up_map {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 cos_valid_mask; /* every bit indicate index of map is valid 1 or not 0 */
+ u16 rsvd1;
+
+ /* user priority in cos(index:cos, value: up pri) */
+ u8 map[NIC_DCB_UP_MAX];
+};
+
+struct hinic3_cmd_pause_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode;
+ u16 rsvd1;
+ u8 auto_neg;
+ u8 rx_pause;
+ u8 tx_pause;
+ u8 rsvd2[5];
+};
+
+struct nic_cmd_pause_inquiry_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 valid;
+
+ u32 type; /* 1: set, 2: get */
+
+ u32 cos_id;
+
+ u32 rx_inquiry_pause_drop_pkts_en;
+ u32 rx_inquiry_pause_period_ms;
+ u32 rx_inquiry_pause_times;
+ /* rx pause Detection Threshold, Default PAUSE_FRAME_THD_10G/25G/40G/100 */
+ u32 rx_inquiry_pause_frame_thd;
+ u32 rx_inquiry_tx_total_pkts;
+
+ u32 tx_inquiry_pause_en; /* tx pause detect enable */
+ u32 tx_inquiry_pause_period_ms; /* tx pause Default Detection Period 200ms */
+ u32 tx_inquiry_pause_times; /* tx pause Default Times Period 5 */
+ u32 tx_inquiry_pause_frame_thd; /* tx pause Detection Threshold */
+ u32 tx_inquiry_rx_total_pkts;
+ u32 rsvd[3];
+};
+
+/* pfc/pause Storm TX exception reporting */
+struct nic_cmd_tx_pause_notice {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 tx_pause_except; /* 1: abnormality,0: normal */
+ u32 except_level;
+ u32 rsvd;
+};
+
+#define HINIC3_CMD_OP_FREE 0
+#define HINIC3_CMD_OP_ALLOC 1
+
+struct hinic3_cmd_cfg_qps {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 1: alloc qp, 0: free qp */
+ u8 rsvd1;
+ u16 num_qps;
+ u16 rsvd2;
+};
+
+struct hinic3_cmd_led_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port;
+ u8 type;
+ u8 mode;
+ u8 rsvd1;
+};
+
+struct hinic3_cmd_port_loopback {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode;
+ u8 mode;
+ u8 en;
+ u32 rsvd1[2];
+};
+
+struct hinic3_cmd_get_light_module_abs {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 abs_status; /* 0:present, 1:absent */
+ u8 rsv[2];
+};
+
+#define STD_SFP_INFO_MAX_SIZE 640
+struct hinic3_cmd_get_std_sfp_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 wire_type;
+ u16 eeprom_len;
+ u32 rsvd;
+ u8 sfp_info[STD_SFP_INFO_MAX_SIZE];
+};
+
+struct hinic3_cable_plug_event {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 plugged; /* 0: unplugged, 1: plugged */
+ u8 port_id;
+};
+
+struct nic_cmd_mac_info {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 valid_bitmap;
+ u16 rsvd;
+
+ u8 host_id[32];
+ u8 port_id[32];
+ u8 mac_addr[192];
+};
+
+struct nic_cmd_set_tcam_enable {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 tcam_enable;
+ u8 rsvd1;
+ u32 rsvd2;
+};
+
+struct nic_cmd_set_fdir_status {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 pkt_type_en;
+ u8 pkt_type;
+ u8 qid;
+ u8 rsvd2;
+};
+
+#define HINIC3_TCAM_BLOCK_ENABLE 1
+#define HINIC3_TCAM_BLOCK_DISABLE 0
+#define HINIC3_MAX_TCAM_RULES_NUM 4096
+
+/* tcam block type, according to tcam block size */
+enum {
+ NIC_TCAM_BLOCK_TYPE_LARGE = 0, /* block_size: 16 */
+ NIC_TCAM_BLOCK_TYPE_SMALL, /* block_size: 0 */
+ NIC_TCAM_BLOCK_TYPE_MAX
+};
+
+/* alloc tcam block input struct */
+struct nic_cmd_ctrl_tcam_block_in {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
+ /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
+ u8 tcam_type;
+ u16 tcam_block_index;
+ /* Size of the block that the driver wants to allocate
+ * Interface returned by the UP to the driver,
+ * indicating the size of the allocated TCAM block supported by the UP
+ */
+ u16 alloc_block_num;
+};
+
+/* alloc tcam block output struct */
+struct nic_cmd_ctrl_tcam_block_out {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
+ /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
+ u8 tcam_type;
+ u16 tcam_block_index;
+ /* Size of the block that the driver wants to allocate
+ * Interface returned by the UP to the driver,
+ * indicating the size of the allocated TCAM block supported by the UP
+ */
+ u16 mpu_alloc_block_size;
+};
+
+struct nic_cmd_flush_tcam_rules {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u16 rsvd;
+};
+
+struct nic_cmd_dfx_fdir_tcam_block_table {
+ struct hinic3_mgmt_msg_head head;
+ u8 tcam_type;
+ u8 valid;
+ u16 tcam_block_index;
+ u16 use_function_id;
+ u16 rsvd;
+};
+
+struct tcam_result {
+ u32 qid;
+ u32 rsvd;
+};
+
+#define TCAM_FLOW_KEY_SIZE (44)
+
+struct tcam_key_x_y {
+ u8 x[TCAM_FLOW_KEY_SIZE];
+ u8 y[TCAM_FLOW_KEY_SIZE];
+};
+
+struct nic_tcam_cfg_rule {
+ u32 index;
+ struct tcam_result data;
+ struct tcam_key_x_y key;
+};
+
+#define TCAM_RULE_FDIR_TYPE 0
+#define TCAM_RULE_PPA_TYPE 1
+
+struct nic_cmd_fdir_add_rule {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 type;
+ u8 fdir_ext; /* 0x1: flow bifur en bit */
+ struct nic_tcam_cfg_rule rule;
+};
+
+struct nic_cmd_fdir_del_rules {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 type;
+ u8 rsvd;
+ u32 index_start;
+ u32 index_num;
+};
+
+struct nic_cmd_fdir_get_rule {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 index;
+ u8 valid;
+ u8 type;
+ u16 rsvd;
+ struct tcam_key_x_y key;
+ struct tcam_result data;
+ u64 packet_count;
+ u64 byte_count;
+};
+
+struct nic_cmd_fdir_get_block_rules {
+ struct hinic3_mgmt_msg_head head;
+ u8 tcam_block_type; // only NIC_TCAM_BLOCK_TYPE_LARGE
+ u8 tcam_table_type; // TCAM_RULE_PPA_TYPE or TCAM_RULE_FDIR_TYPE
+ u16 tcam_block_index;
+ u8 valid[NIC_TCAM_BLOCK_LARGE_SIZE];
+ struct tcam_key_x_y key[NIC_TCAM_BLOCK_LARGE_SIZE];
+ struct tcam_result data[NIC_TCAM_BLOCK_LARGE_SIZE];
+};
+
+struct hinic3_tcam_key_ipv4_mem {
+ u32 rsvd1 : 1;
+ u32 bifur_flag : 2;
+ u32 model : 1;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+ u32 sipv4_h : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+ u32 dipv4_h : 16;
+ u32 sipv4_l : 16;
+ u32 vlan_id : 15;
+ u32 vlan_flag : 1;
+ u32 dipv4_l : 16;
+ u32 rsvd3;
+ u32 dport : 16;
+ u32 rsvd4 : 16;
+ u32 rsvd5 : 16;
+ u32 sport : 16;
+ u32 outer_sipv4_h : 16;
+ u32 rsvd6 : 16;
+ u32 outer_dipv4_h : 16;
+ u32 outer_sipv4_l : 16;
+ u32 vni_h : 16;
+ u32 outer_dipv4_l : 16;
+ u32 rsvd7 : 16;
+ u32 vni_l : 16;
+};
+
+union hinic3_tag_tcam_ext_info {
+ struct {
+ u32 id : 16; /* id */
+ u32 type : 4; /* type: 0-func, 1-vmdq, 2-port, 3-rsvd, 4-trunk, 5-dp, 6-mc */
+ u32 host_id : 3;
+ u32 rss_q_num : 8; /* rss queue num */
+ u32 ext : 1;
+ } bs;
+ u32 value;
+};
+
+struct hinic3_tcam_key_ipv6_mem {
+ u32 bifur_flag : 2;
+ u32 vlan_flag : 1;
+ u32 outer_ip_type : 1;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+ u32 sipv6_key0 : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+ u32 sipv6_key2 : 16;
+ u32 sipv6_key1 : 16;
+ u32 sipv6_key4 : 16;
+ u32 sipv6_key3 : 16;
+ u32 sipv6_key6 : 16;
+ u32 sipv6_key5 : 16;
+ u32 dport : 16;
+ u32 sipv6_key7 : 16;
+ u32 dipv6_key0 : 16;
+ u32 sport : 16;
+ u32 dipv6_key2 : 16;
+ u32 dipv6_key1 : 16;
+ u32 dipv6_key4 : 16;
+ u32 dipv6_key3 : 16;
+ u32 dipv6_key6 : 16;
+ u32 dipv6_key5 : 16;
+ u32 rsvd2 : 16;
+ u32 dipv6_key7 : 16;
+};
+
+struct hinic3_tcam_key_vxlan_ipv6_mem {
+ u32 rsvd1 : 4;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+
+ u32 dipv6_key0 : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+
+ u32 dipv6_key2 : 16;
+ u32 dipv6_key1 : 16;
+
+ u32 dipv6_key4 : 16;
+ u32 dipv6_key3 : 16;
+
+ u32 dipv6_key6 : 16;
+ u32 dipv6_key5 : 16;
+
+ u32 dport : 16;
+ u32 dipv6_key7 : 16;
+
+ u32 rsvd2 : 16;
+ u32 sport : 16;
+
+ u32 outer_sipv4_h : 16;
+ u32 rsvd3 : 16;
+
+ u32 outer_dipv4_h : 16;
+ u32 outer_sipv4_l : 16;
+
+ u32 vni_h : 16;
+ u32 outer_dipv4_l : 16;
+
+ u32 rsvd4 : 16;
+ u32 vni_l : 16;
+};
+
+struct tag_tcam_key {
+ union {
+ struct hinic3_tcam_key_ipv4_mem key_info;
+ struct hinic3_tcam_key_ipv6_mem key_info_ipv6;
+ struct hinic3_tcam_key_vxlan_ipv6_mem key_info_vxlan_ipv6;
+ };
+
+ union {
+ struct hinic3_tcam_key_ipv4_mem key_mask;
+ struct hinic3_tcam_key_ipv6_mem key_mask_ipv6;
+ struct hinic3_tcam_key_vxlan_ipv6_mem key_mask_vxlan_ipv6;
+ };
+};
+
+enum {
+ PPA_TABLE_ID_CLEAN_CMD = 0,
+ PPA_TABLE_ID_ADD_CMD,
+ PPA_TABLE_ID_DEL_CMD,
+ FDIR_TABLE_ID_ADD_CMD,
+ FDIR_TABLE_ID_DEL_CMD,
+ PPA_TABEL_ID_MAX
+};
+
+struct hinic3_ppa_cfg_table_id_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u16 cmd;
+ u16 table_id;
+ u16 rsvd1;
+};
+
+struct hinic3_ppa_cfg_ppa_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 ppa_en;
+ u8 ppa_miss_drop_en;
+};
+
+struct hinic3_func_flow_bifur_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 func_id;
+ u8 flow_bifur_en;
+ u8 rsvd[5];
+};
+
+struct hinic3_port_flow_bifur_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 port_id;
+ u8 flow_bifur_en;
+ u8 flow_bifur_type; /* 0->vf bifur, 2->traffic bifur */
+ u8 rsvd[4];
+};
+
+struct hinic3_bond_mask_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 func_id;
+ u8 bond_mask;
+ u8 bond_en;
+ u8 func_valid;
+ u8 rsvd[3];
+};
+
+struct hinic3_func_er_value_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 vf_id;
+ u16 er_fwd_id;
+};
+
+#define HINIC3_TX_SET_PROMISC_SKIP 0
+#define HINIC3_TX_GET_PROMISC_SKIP 1
+
+#define HINIC3_GET_TRAFFIC_BIFUR_STATE 0
+#define HINIC3_SET_TRAFFIC_BIFUR_STATE 1
+
+struct hinic3_tx_promisc_cfg {
+ struct hinic3_mgmt_msg_head msg_head;
+ u8 port_id;
+ u8 promisc_skip_en; /* 0: disable tx promisc replication, 1: enable */
+ u8 opcode; /* 0: set, 1: get */
+ u8 rsvd1;
+};
+
+struct hinic3_ppa_cfg_mode_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u8 ppa_mode;
+ u8 qpc_func_nums;
+ u16 base_qpc_func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_ppa_flush_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u8 flush_en; /* 0 flush done, 1 in flush operation */
+ u8 rsvd1;
+};
+
+struct hinic3_ppa_fdir_query_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u32 index;
+ u32 rsvd;
+ u64 pkt_nums;
+ u64 pkt_bytes;
+};
+
+/* BIOS CONF */
+enum {
+ NIC_NVM_DATA_SET = BIT(0), /* 1-save, 0-read */
+ NIC_NVM_DATA_PXE = BIT(1),
+ NIC_NVM_DATA_VLAN = BIT(2),
+ NIC_NVM_DATA_VLAN_PRI = BIT(3),
+ NIC_NVM_DATA_VLAN_ID = BIT(4),
+ NIC_NVM_DATA_WORK_MODE = BIT(5),
+ NIC_NVM_DATA_PF_TX_SPEED_LIMIT = BIT(6),
+ NIC_NVM_DATA_GE_MODE = BIT(7),
+ NIC_NVM_DATA_AUTO_NEG = BIT(8),
+ NIC_NVM_DATA_LINK_FEC = BIT(9),
+ NIC_NVM_DATA_PF_ADAPTIVE_LINK = BIT(10),
+ NIC_NVM_DATA_SRIOV_CONTROL = BIT(11),
+ NIC_NVM_DATA_EXTEND_MODE = BIT(12),
+ NIC_NVM_DATA_LEGACY_VLAN = BIT(13),
+ NIC_NVM_DATA_LEGACY_VLAN_PRI = BIT(14),
+ NIC_NVM_DATA_LEGACY_VLAN_ID = BIT(15),
+ NIC_NVM_DATA_RESET = BIT(31),
+};
+
+#define BIOS_CFG_SIGNATURE 0x1923E518
+#define BIOS_OP_CFG_ALL(op_code_val) \
+ ((((op_code_val) >> 1) & (0xFFFFFFFF)) != 0)
+#define BIOS_OP_CFG_WRITE(op_code_val) \
+ ((((op_code_val) & NIC_NVM_DATA_SET)) != 0)
+#define BIOS_OP_CFG_PXE_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PXE) != 0)
+#define BIOS_OP_CFG_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN) != 0)
+#define BIOS_OP_CFG_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_ID) != 0)
+#define BIOS_OP_CFG_WORK_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_WORK_MODE) != 0)
+#define BIOS_OP_CFG_PF_BW(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_TX_SPEED_LIMIT) != 0)
+#define BIOS_OP_CFG_GE_SPEED(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_GE_MODE) != 0)
+#define BIOS_OP_CFG_AUTO_NEG(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_AUTO_NEG) != 0)
+#define BIOS_OP_CFG_LINK_FEC(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LINK_FEC) != 0)
+#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_ADAPTIVE_LINK) != 0)
+#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_SRIOV_CONTROL) != 0)
+#define BIOS_OP_CFG_EXTEND_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_EXTEND_MODE) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_ID) != 0)
+#define BIOS_OP_CFG_RST_DEF_SET(op_code_val) \
+ (((op_code_val) & (u32)NIC_NVM_DATA_RESET) != 0)
+
+
+#define NIC_BIOS_CFG_MAX_PF_BW 100
+
+struct nic_legacy_vlan_cfg {
+ /* Legacy mode PXE VLAN enable: 0 - disable 1 - enable */
+ u8 pxe_vlan_en : 1;
+ /* Legacy mode PXE VLAN priority: 0-7 */
+ u8 pxe_vlan_pri : 3;
+ /* Legacy mode PXE VLAN ID 1-4094 */
+ u16 pxe_vlan_id : 12;
+};
+
+/* Note: This structure must be 4-byte aligned. */
+struct nic_bios_cfg {
+ u32 signature;
+ u8 pxe_en;
+ u8 extend_mode;
+ struct nic_legacy_vlan_cfg nlvc;
+ u8 pxe_vlan_en;
+ u8 pxe_vlan_pri;
+ u16 pxe_vlan_id;
+ u32 service_mode;
+ u32 pf_tx_bw;
+ u8 speed;
+ u8 auto_neg;
+ u8 lanes;
+ u8 fec;
+ u8 auto_adapt;
+ u8 func_valid;
+ u8 func_id;
+ u8 sriov_en;
+};
+
+struct nic_cmd_bios_cfg {
+ struct hinic3_mgmt_msg_head head;
+ u32 op_code; /* Operation Code: Bit0[0: read 1:write, BIT1-6: cfg_mask */
+ struct nic_bios_cfg bios_cfg;
+};
+
+struct nic_rx_rate_bios_cfg {
+ struct mgmt_msg_head msg_head;
+
+ u32 op_code; /* Operation Code:[0:read 1:write] */
+ u8 rx_rate_limit;
+ u8 func_id;
+};
+
+struct nic_cmd_vhd_config {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 vhd_type;
+ u8 virtio_small_enable; /* 0: mergeable mode, 1: small mode */
+};
+
+/* BOND */
+struct hinic3_create_bond_info {
+ u32 bond_id;
+ u32 master_slave_port_id;
+ u32 slave_bitmap; /* bond port id bitmap */
+ u32 poll_timeout; /* Bond device link check time */
+ u32 up_delay; /* Temporarily reserved */
+ u32 down_delay; /* Temporarily reserved */
+ u32 bond_mode; /* Temporarily reserved */
+ u32 active_pf; /* bond use active pf id */
+ u32 active_port_max_num; /* Maximum number of active bond member interfaces */
+ u32 active_port_min_num; /* Minimum number of active bond member interfaces */
+ u32 xmit_hash_policy;
+ u32 default_param_flag;
+ u32 rsvd;
+};
+
+struct hinic3_cmd_create_bond {
+ struct hinic3_mgmt_msg_head head;
+ struct hinic3_create_bond_info create_bond_info;
+};
+
+struct hinic3_cmd_delete_bond {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 rsvd[2];
+};
+
+struct hinic3_open_close_bond_info {
+ u32 bond_id;
+ u32 open_close_flag; /* Bond flag. 1: open; 0: close. */
+ u32 rsvd[2];
+};
+
+struct hinic3_cmd_open_close_bond {
+ struct hinic3_mgmt_msg_head head;
+ struct hinic3_open_close_bond_info open_close_bond_info;
+};
+
+struct lacp_port_params {
+ u16 port_number;
+ u16 port_priority;
+ u16 key;
+ u16 system_priority;
+ u8 system[ETH_ALEN];
+ u8 port_state;
+ u8 rsvd;
+};
+
+struct lacp_port_info {
+ u32 selected;
+ u32 aggregator_port_id;
+
+ struct lacp_port_params actor;
+ struct lacp_port_params partner;
+
+ u64 tx_lacp_pkts;
+ u64 rx_lacp_pkts;
+ u64 rx_8023ad_drop;
+ u64 tx_8023ad_drop;
+ u64 unknown_pkt_drop;
+ u64 rx_marker_pkts;
+ u64 tx_marker_pkts;
+};
+
+struct hinic3_bond_status_info {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 bon_mmi_status;
+ u32 active_bitmap;
+ u32 port_count;
+
+ struct lacp_port_info port_info[4];
+
+ u64 success_report_cnt[4];
+ u64 fail_report_cnt[4];
+
+ u64 poll_timeout;
+ u64 fast_periodic_timeout;
+ u64 slow_periodic_timeout;
+ u64 short_timeout;
+ u64 long_timeout;
+ u64 aggregate_wait_timeout;
+ u64 tx_period_timeout;
+ u64 rx_marker_timer;
+};
+
+struct hinic3_bond_active_report_info {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 bon_mmi_status;
+ u32 active_bitmap;
+
+ u8 rsvd[16];
+};
+
+/* IP checksum error packets, enable rss quadruple hash. */
+struct hinic3_ipcs_err_rss_enable_operation_s {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 en_tag;
+ u8 type; /* 1: set 0: get */
+ u8 rsvd[2];
+};
+
+struct hinic3_smac_check_state {
+ struct hinic3_mgmt_msg_head head;
+ u8 smac_check_en; /* 1: enable 0: disable */
+ u8 op_code; /* 1: set 0: get */
+ u8 flash_en; /* 1: enable 0: disable */
+ u8 rsvd;
+};
+
+struct hinic3_clear_log_state {
+ struct hinic3_mgmt_msg_head head;
+ u32 type;
+};
+
+struct hinic3_outband_cfg_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 outband_default_vid;
+ u16 func_id;
+};
+
+struct hinic3_wr_ordering {
+ struct hinic3_mgmt_msg_head head;
+ u8 op_code; /* 1: set 0: get */
+ u8 wr_pkt_so_ro;
+ u8 rd_pkt_so_ro;
+ u8 rsvd;
+};
+
+struct hinic3_function_active_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_rq_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rq_depth;
+ u16 rq_num;
+ u16 pf_num;
+ u16 port_num;
+};
+
+#endif /* HINIC_MGMT_INTERFACE_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
new file mode 100644
index 0000000..3e625fc
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
+ * File Name : nic_npu_cmd.h
+ * Version : Initial Draft
+ * Created : 2019/4/25
+ * Last Modified :
+ * Description : NIC Commands between Driver and NPU
+ * Function List :
+ */
+
+#ifndef NIC_NPU_CMD_H
+#define NIC_NPU_CMD_H
+
+/* NIC CMDQ MODE */
+enum hinic3_ucode_cmd {
+ HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
+ HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
+ HINIC3_UCODE_CMD_ARM_SQ, /**< Unused */
+ HINIC3_UCODE_CMD_ARM_RQ, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_IQ_ENABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
+ HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
+ HINIC3_UCODE_CMD_PPA_HASH_TABLE,
+ HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_UCODE_MIG_CFG_Q_CTX = 14,
+ HINIC3_UCODE_MIG_CHK_SQ_STOP,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ HINIC3_UCODE_MIG_CFG_BAT_INFO,
+};
+
+#endif /* NIC_NPU_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
index 78a8d7f..66f4305 100644
--- a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
+++ b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
@@ -5,6 +5,7 @@
#define OSSL_KNL_LINUX_H_
#include <net/ipv6.h>
+#include <net/devlink.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/device.h>
@@ -18,6 +19,12 @@
#include <linux/list.h>
#include <linux/bitmap.h>
#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/filter.h>
+#include <linux/aer.h>
+#include <linux/socket.h>
#ifndef NETIF_F_SCTP_CSUM
#define NETIF_F_SCTP_CSUM 0
@@ -173,12 +180,10 @@ static inline void *_hinic3_dma_zalloc_coherent(struct device *dev,
}
#endif
-#ifndef DT_KNL_EMU
struct timeval {
__kernel_old_time_t tv_sec; /* seconds */
__kernel_suseconds_t tv_usec; /* microseconds */
};
-#endif
#ifndef do_gettimeofday
#define do_gettimeofday(time) _kc_do_gettimeofday(time)
@@ -196,6 +201,10 @@ static inline void _kc_do_gettimeofday(struct timeval *tv)
#define ETH_GET_HEADLEN_NEED_DEV
#define HAVE_GENL_OPS_FIELD_VALIDATE
+#ifndef FIELD_SIZEOF
+#define FIELD_SIZEOF(t, f) (sizeof(((t *)0)->f))
+#endif
+
#define HAVE_DEVLINK_FLASH_UPDATE_PARAMS
#ifndef rtc_time_to_tm
@@ -253,12 +262,12 @@ static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size,
size, vaddr, dma_handle);
}
-#define HAVE_DEVLINK_FW_FILE_NAME_MEMBER
-
#define HAVE_ENCAPSULATION_TSO
#define HAVE_ENCAPSULATION_CSUM
+#define HAVE_UDP_TUNNEL_NIC_INFO
+
#ifndef eth_zero_addr
static inline void hinic3_eth_zero_addr(u8 *addr)
{
@@ -333,4 +342,15 @@ u64 ossl_get_real_time(void);
#define tasklet_state(tasklet) ((tasklet)->state)
+dma_addr_t pci_map_single(struct pci_dev *pdev,
+ void *ptr, size_t size, int direction);
+int pci_dma_mapping_error(struct pci_dev *pdev,
+ dma_addr_t dma_addr);
+void pci_unmap_single(struct pci_dev *pdev,
+ dma_addr_t dma_addr, size_t size, int direction);
+void *pci_alloc_consistent(struct pci_dev *pdev,
+ size_t size, dma_addr_t *dma_handle);
+void pci_free_consistent(struct pci_dev *pdev,
+ size_t size, void *vaddr, dma_addr_t dma_handle);
+
#endif
--
2.45.1.windows.1
2
1

09 May '25
From: fuguiming <fuguiming(a)huawei.com>
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IC5K0L?from=project-issue
CVE: NA
--------------------------------
Add optical module type adaptation.
Add ethtool fec function.
Add NIC XDP PASS function.
Add QoS persistence.
Add NIC out-of-band VLAN configuration function.
Fix NIC bifur bugs.
Fix performance test bugs.
Fix NIC RX bugs.
Fix NIC VF bugs.
Fix the bug of exiting when probing NIC.
Fix bond bugs.
Fix the bug of MAC address configuration failure in OS 6.6.
Fix the bug of reading NIC status incorrectly.
Fix and add some statistics.
Signed-off-by: fuguiming <fuguiming(a)huawei.com>
---
drivers/net/ethernet/huawei/hinic3/Makefile | 1 +
drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c | 3 +-
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c | 181 ++-
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h | 1 +
drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h | 212 ---
drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h | 239 ---
drivers/net/ethernet/huawei/hinic3/comm_defs.h | 100 --
drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h | 103 --
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c | 38 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h | 2 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c | 83 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c | 29 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c | 22 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h | 185 ---
drivers/net/ethernet/huawei/hinic3/hinic3_common.h | 118 --
drivers/net/ethernet/huawei/hinic3/hinic3_crm.h | 16 +-
drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c | 298 ++--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c | 262 +--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h | 7 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c | 247 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c | 459 +++---
drivers/net/ethernet/huawei/hinic3/hinic3_filter.c | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_hw.h | 19 +
drivers/net/ethernet/huawei/hinic3/hinic3_irq.c | 39 +-
drivers/net/ethernet/huawei/hinic3/hinic3_lld.h | 205 ---
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c | 833 +++++++++-
drivers/net/ethernet/huawei/hinic3/hinic3_main.c | 490 +++++-
drivers/net/ethernet/huawei/hinic3/hinic3_mt.h | 191 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c | 397 +++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic.h | 49 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c | 557 +++++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h | 54 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c | 186 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c | 10 +
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h | 112 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c | 105 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c | 50 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c | 15 +-
drivers/net/ethernet/huawei/hinic3/hinic3_profile.h | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rss.c | 137 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c | 41 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rx.c | 311 +++-
drivers/net/ethernet/huawei/hinic3/hinic3_rx.h | 41 +-
drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h | 7 +-
drivers/net/ethernet/huawei/hinic3/hinic3_tx.c | 79 +-
drivers/net/ethernet/huawei/hinic3/hinic3_wq.h | 4 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c | 11 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c | 6 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h | 5 -
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c | 1 -
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c | 213 ++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h | 18 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c | 3 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c | 14 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c | 42 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c | 79 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h | 7 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c | 155 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c | 115 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c | 85 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h | 31 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c | 40 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c | 1243 +++++++++++++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c | 3 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c | 4 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c | 41 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c | 122 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h | 4 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h | 31 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c | 64 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h | 14 +-
drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c | 1 +
drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h | 4 +
.../include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h | 11 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h | 42 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h | 2 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h | 70 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h | 141 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h | 5 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h | 88 +-
.../include/mpu/mpu_outband_ncsi_cmd_defs.h | 8 +
drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/vram_common.h | 25 +-
drivers/net/ethernet/huawei/hinic3/{mag_cmd.h => mag_mpu_cmd_defs.h} | 236 ++-
drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h | 27 -
drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h | 65 -
drivers/net/ethernet/huawei/hinic3/{hinic3_nic_cmd.h => nic_mpu_cmd.h} | 54 +-
drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h | 1440 +++++++++++++++++
drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h | 36 +
drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h | 28 +-
96 files changed, 8407 insertions(+), 2791 deletions(-)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_defs.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_common.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
rename drivers/net/ethernet/huawei/hinic3/{mag_cmd.h => mag_mpu_cmd_defs.h} (79%)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
rename drivers/net/ethernet/huawei/hinic3/{hinic3_nic_cmd.h => nic_mpu_cmd.h} (77%)
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
diff --git a/drivers/net/ethernet/huawei/hinic3/Makefile b/drivers/net/ethernet/huawei/hinic3/Makefile
index 6f9ed3f..457c920 100644
--- a/drivers/net/ethernet/huawei/hinic3/Makefile
+++ b/drivers/net/ethernet/huawei/hinic3/Makefile
@@ -11,6 +11,7 @@ ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/mpu/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/bond/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/vmsec/
+ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/bond/
obj-$(CONFIG_HINIC3) += hinic3.o
hinic3-objs := hw/hinic3_hwdev.o \
diff --git a/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c b/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c
index cc2e4b3..440fea6 100644
--- a/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_nic_cmdq.h"
#include "sw_cmdq_ops.h"
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
index e8c703b..dd0699b 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
@@ -9,6 +9,7 @@
#include <linux/net.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
+#include <linux/version.h>
#include "hinic3_lld.h"
#include "hinic3_srv_nic.h"
@@ -109,7 +110,8 @@ static struct hinic3_nic_dev *get_nic_dev_safe(struct net_device *ndev)
return netdev_priv(ndev);
}
-static u8 bond_get_slaves_bitmap(struct hinic3_bond_dev *bdev, struct bonding *bond)
+static u8 bond_get_slaves_bitmap(struct hinic3_bond_dev *bdev,
+ struct bonding *bond)
{
struct slave *slave = NULL;
struct list_head *iter = NULL;
@@ -203,7 +205,8 @@ static u8 bond_dev_track_port(struct hinic3_bond_dev *bdev,
bdev->tracker.netdev_state[port_id].tx_enabled = 0;
if (!bdev->ppf_hwdev)
bdev->ppf_hwdev = ppf_hwdev;
- pr_info("TRACK cnt: %d, slave_name(%s)\n", bdev->tracker.cnt, ndev->name);
+ pr_info("TRACK cnt: %d, slave_name(%s)\n",
+ bdev->tracker.cnt, ndev->name);
spin_unlock(&bdev->lock);
return port_id;
@@ -268,11 +271,16 @@ static void bond_master_event(struct hinic3_bond_dev *bdev,
queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
}
-static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
+static struct hinic3_bond_dev *bond_get_bdev(struct bonding *bond)
{
struct hinic3_bond_dev *bdev = NULL;
int bid;
+ if (!bond) {
+ pr_err("hinic3_bond: bond is NULL\n");
+ return NULL;
+ }
+
mutex_lock(&g_bond_mutex);
for (bid = BOND_FIRST_ID; bid <= BOND_MAX_ID; bid++) {
bdev = bond_mngr.bond_dev[bid];
@@ -283,38 +291,73 @@ static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
mutex_unlock(&g_bond_mutex);
return bdev;
}
+
+ if (strncmp(bond->dev->name,
+ bdev->name, BOND_NAME_MAX_LEN) == 0) {
+ bdev->bond = bond;
+ return bdev;
+ }
}
mutex_unlock(&g_bond_mutex);
return NULL;
}
-static void bond_handle_rtnl_event(struct net_device *ndev)
+static struct bonding *get_bonding_by_netdev(struct net_device *ndev)
{
- struct hinic3_bond_dev *bdev = NULL;
struct bonding *bond = NULL;
struct slave *slave = NULL;
if (netif_is_bond_master(ndev)) {
bond = netdev_priv(ndev);
- bdev = bond_get_bdev(bond);
} else if (netif_is_bond_slave(ndev)) {
- /*lint -e(160) */
slave = bond_slave_get_rtnl(ndev);
if (slave) {
bond = bond_get_bond_by_slave(slave);
- bdev = bond_get_bdev(bond);
}
}
- if (!bond || !bdev)
+ return bond;
+}
+
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+
+ if (!ndev) {
+ pr_err("hinic3_bond: netdev is NULL\n");
+ return false;
+ }
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
+ return false;
+
+ return bdev->status == BOND_DEV_STATUS_ACTIVATED;
+}
+EXPORT_SYMBOL(hinic3_is_bond_dev_status_actived);
+/*lint +e580 +e546*/
+
+static void bond_handle_rtnl_event(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+ struct slave *slave = NULL;
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
return;
bond_update_attr(bdev, bond);
- if (slave)
+ if (netif_is_bond_slave(ndev)) {
+ slave = bond_slave_get_rtnl(ndev);
bond_slave_event(bdev, slave);
- else
+ } else {
bond_master_event(bdev, bond);
+ }
}
static void bond_rtnl_data_ready(struct sock *sk)
@@ -368,7 +411,8 @@ static int bond_enable_netdev_event(void)
(*rtnl_sock)->sk->sk_data_ready = bond_rtnl_data_ready;
(*rtnl_sock)->sk->sk_allocation = GFP_KERNEL;
- err = kernel_bind(*rtnl_sock, (struct sockaddr *)(u8 *)&addr, sizeof(addr));
+ err = kernel_bind(*rtnl_sock, (struct sockaddr *)(u8 *)&addr,
+ sizeof(addr));
if (err) {
pr_err("hinic3_bond: Couldn't bind rtnl socket.\n");
sock_release(*rtnl_sock);
@@ -387,7 +431,7 @@ static void bond_disable_netdev_event(void)
static int bond_send_upcmd(struct hinic3_bond_dev *bdev, struct bond_attr *attr,
u8 cmd_type)
{
- int err, len;
+ int err, ret, len;
struct hinic3_bond_cmd cmd = {0};
u16 out_size = sizeof(cmd);
@@ -403,7 +447,9 @@ static int bond_send_upcmd(struct hinic3_bond_dev *bdev, struct bond_attr *attr,
len = sizeof(cmd.bond_name);
if (cmd_type == MPU_CMD_BOND_CREATE) {
- strscpy(cmd.bond_name, bdev->name, len);
+ ret = strscpy(cmd.bond_name, bdev->name, len);
+ if (ret < 0)
+ pr_err("strscpy bond name failed\n");
cmd.bond_name[sizeof(cmd.bond_name) - 1] = '\0';
}
@@ -478,7 +524,11 @@ static void bond_update_slave_info(struct hinic3_bond_dev *bdev,
continue;
}
+ if (!bdev->tracker.ndev[i])
+ continue;
+
bond_pf_bitmap_set(bdev, i);
+
if (!bdev->tracker.netdev_state[i].tx_enabled)
continue;
@@ -516,6 +566,7 @@ static int bond_upcmd_config(struct hinic3_bond_dev *bdev,
attr->active_slaves,
attr->lacp_collect_slaves);
pr_info("bond_pf_bitmap: 0x%x\n", attr->bond_pf_bitmap);
+ pr_info("bond user_bitmap 0x%x\n", attr->user_bitmap);
err = bond_send_upcmd(bdev, attr, MPU_CMD_BOND_SET_ATTR);
if (!err)
@@ -544,8 +595,10 @@ static int bond_upcmd_activate(struct hinic3_bond_dev *bdev,
return err;
}
-static void bond_call_service_func(struct hinic3_bond_dev *bdev, struct bond_attr *attr,
- enum bond_service_proc_pos pos, int bond_status)
+static void bond_call_service_func(struct hinic3_bond_dev *bdev,
+ struct bond_attr *attr,
+ enum bond_service_proc_pos pos,
+ int bond_status)
{
int i;
@@ -560,6 +613,18 @@ static void bond_call_service_func(struct hinic3_bond_dev *bdev, struct bond_att
mutex_unlock(&g_bond_service_func_mutex);
}
+static u32 bond_get_user_bitmap(struct hinic3_bond_dev *bdev)
+{
+ u32 user_bitmap = 0;
+ u8 user;
+
+ for (user = HINIC3_BOND_USER_OVS; user < HINIC3_BOND_USER_NUM; user++) {
+ if (bdev->slot_used[user] == 1)
+ BITMAP_SET(user_bitmap, user);
+ }
+ return user_bitmap;
+}
+
static void bond_do_work(struct hinic3_bond_dev *bdev)
{
bool is_bonded = 0;
@@ -570,7 +635,7 @@ static void bond_do_work(struct hinic3_bond_dev *bdev)
is_bonded = bdev->tracker.is_bonded;
attr = bdev->new_attr;
spin_unlock(&bdev->lock);
- attr.user_bitmap = 0;
+ attr.user_bitmap = bond_get_user_bitmap(bdev);
/* is_bonded indicates whether bond should be activated. */
if (is_bonded && !bond_dev_is_activated(bdev)) {
@@ -597,15 +662,22 @@ static void bond_try_do_work(struct work_struct *work)
struct delayed_work *delayed_work = to_delayed_work(work);
struct hinic3_bond_dev *bdev =
container_of(delayed_work, struct hinic3_bond_dev, bond_work);
+ int status;
- if (g_bond_service_func[HINIC3_BOND_USER_ROCE] && bdev->tracker.cnt < MIN_BOND_SLAVE_CNT)
+ status = mutex_trylock(&g_bond_mutex);
+ if (status == 0) {
+ /* Delay 1 sec and retry */
queue_delayed_work(bdev->wq, &bdev->bond_work, HZ);
- else
+ } else {
bond_do_work(bdev);
+ mutex_unlock(&g_bond_mutex);
+ }
}
static int bond_dev_init(struct hinic3_bond_dev *bdev, const char *name)
{
+ int err = 0;
+
bdev->wq = create_singlethread_workqueue("hinic3_bond_wq");
if (!bdev->wq) {
pr_err("hinic3_bond: Failed to create workqueue\n");
@@ -614,7 +686,13 @@ static int bond_dev_init(struct hinic3_bond_dev *bdev, const char *name)
INIT_DELAYED_WORK(&bdev->bond_work, bond_try_do_work);
bdev->status = BOND_DEV_STATUS_IDLE;
- strscpy(bdev->name, name, sizeof(bdev->name));
+ err = strscpy(bdev->name, name, strlen(name));
+ if (err < 0) {
+ pr_err("hinic3_bond: Failed to init bond dev\n");
+ cancel_delayed_work_sync(&bdev->bond_work);
+ destroy_workqueue(bdev->wq);
+ return err;
+ }
spin_lock_init(&bdev->lock);
@@ -630,6 +708,7 @@ static int bond_dev_release(struct hinic3_bond_dev *bdev)
err = bond_upcmd_deactivate(bdev);
if (err) {
pr_err("hinic3_bond: Failed to deactivate dev\n");
+ mutex_unlock(&g_bond_mutex);
return err;
}
@@ -637,7 +716,8 @@ static int bond_dev_release(struct hinic3_bond_dev *bdev)
if (bond_mngr.bond_dev[i] == bdev) {
bond_mngr.bond_dev[i] = NULL;
bond_mngr.cnt--;
- pr_info("hinic3_bond: Free bond, id: %u mngr_cnt:%u\n", i, bond_mngr.cnt);
+ pr_info("hinic3_bond: Free bond, id: %u mngr_cnt:%u\n",
+ i, bond_mngr.cnt);
break;
}
}
@@ -694,7 +774,8 @@ static struct hinic3_bond_dev *bond_dev_alloc(const char *name)
bdev->bond_attr.bond_id = i;
bond_mngr.bond_dev[i] = bdev;
bond_mngr.cnt++;
- pr_info("hinic3_bond: Create bond dev, id:%u cnt:%u\n", i, bond_mngr.cnt);
+ pr_info("hinic3_bond: Create bond dev, id:%u cnt:%u\n",
+ i, bond_mngr.cnt);
break;
}
}
@@ -764,20 +845,28 @@ static struct hinic3_bond_dev *bond_dev_by_name(const char *name)
static void bond_dev_user_attach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user)
{
+ u32 user_bitmap;
+
+ if (user < 0 || user >= HINIC3_BOND_USER_NUM)
+ return;
+
if (bdev->slot_used[user])
return;
bdev->slot_used[user] = 1;
- if (!kref_get_unless_zero(&bdev->ref))
+ if (!kref_get_unless_zero(&bdev->ref)) {
kref_init(&bdev->ref);
+ } else {
+ user_bitmap = bond_get_user_bitmap(bdev);
+ pr_info("hinic3_bond: user %u attach bond %s, user_bitmap %#x\n",
+ user, bdev->name, user_bitmap);
+ queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
+ }
}
static void bond_dev_user_detach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user, bool *freed)
{
- if (user < 0 || user >= HINIC3_BOND_USER_NUM)
- return;
-
if (bdev->slot_used[user]) {
bdev->slot_used[user] = 0;
if (kref_read(&bdev->ref) == 1)
@@ -790,16 +879,20 @@ static struct bonding *bond_get_knl_bonding(const char *name)
{
struct net_device *ndev_tmp = NULL;
+ rcu_read_lock();
for_each_netdev(&init_net, ndev_tmp) {
if (netif_is_bond_master(ndev_tmp) &&
- !strcmp(ndev_tmp->name, name))
+ !strcmp(ndev_tmp->name, name)) {
+ rcu_read_unlock();
return netdev_priv(ndev_tmp);
+ }
}
-
+ rcu_read_unlock();
return NULL;
}
-void hinic3_bond_set_user_bitmap(struct bond_attr *attr, enum hinic3_bond_user user)
+void hinic3_bond_set_user_bitmap(struct bond_attr *attr,
+ enum hinic3_bond_user user)
{
if (!BITMAP_JUDGE(attr->user_bitmap, user))
BITMAP_SET(attr->user_bitmap, user);
@@ -852,8 +945,9 @@ int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user)
int err = 0;
bool lock_freed = false;
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
- pr_warn("hinic3_bond: Invalid bond id:%u to delete\n", bond_id);
+ if (!BOND_ID_IS_VALID(bond_id) || user >= HINIC3_BOND_USER_NUM) {
+ pr_warn("hinic3_bond: Invalid bond id or user, bond_id: %u, user: %d\n",
+ bond_id, user);
return -EINVAL;
}
@@ -861,7 +955,8 @@ int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user)
if (!bond_mngr.bond_dev[bond_id])
err = -ENODEV;
else
- bond_dev_user_detach(bond_mngr.bond_dev[bond_id], user, &lock_freed);
+ bond_dev_user_detach(bond_mngr.bond_dev[bond_id],
+ user, &lock_freed);
if (!lock_freed)
mutex_unlock(&g_bond_mutex);
@@ -877,7 +972,8 @@ void hinic3_bond_clean_user(enum hinic3_bond_user user)
mutex_lock(&g_bond_mutex);
for (i = BOND_FIRST_ID; i <= BOND_MAX_ID; i++) {
if (bond_mngr.bond_dev[i]) {
- bond_dev_user_detach(bond_mngr.bond_dev[i], user, &lock_freed);
+ bond_dev_user_detach(bond_mngr.bond_dev[i],
+ user, &lock_freed);
if (lock_freed) {
mutex_lock(&g_bond_mutex);
lock_freed = false;
@@ -891,7 +987,7 @@ EXPORT_SYMBOL(hinic3_bond_clean_user);
int hinic3_bond_get_uplink_id(u16 bond_id, u32 *uplink_id)
{
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID || !uplink_id) {
+ if (!BOND_ID_IS_VALID(bond_id) || !uplink_id) {
pr_warn("hinic3_bond: Invalid args, id: %u, uplink: %d\n",
bond_id, !!uplink_id);
return -EINVAL;
@@ -941,7 +1037,7 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
int i;
int len;
- if (!info || bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
+ if (!info || !BOND_ID_IS_VALID(bond_id)) {
pr_warn("hinic3_bond: Invalid args, info: %d,id: %u\n",
!!info, bond_id);
return -EINVAL;
@@ -962,7 +1058,8 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
for (i = 0; i < BOND_PORT_MAX_NUM; i++) {
if (BITMAP_JUDGE(info->slaves, i) && tracker->ndev[i]) {
len = sizeof(info->slaves_name[0]);
- strscpy(info->slaves_name[info->cnt], tracker->ndev[i]->name, len);
+ strscpy(info->slaves_name[info->cnt],
+ tracker->ndev[i]->name, len);
info->cnt++;
}
}
@@ -972,7 +1069,8 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
}
EXPORT_SYMBOL(hinic3_bond_get_slaves);
-struct net_device *hinic3_bond_get_netdev_by_portid(const char *bond_name, u8 port_id)
+struct net_device *hinic3_bond_get_netdev_by_portid(const char *bond_name,
+ u8 port_id)
{
struct hinic3_bond_dev *bdev = NULL;
@@ -989,7 +1087,8 @@ struct net_device *hinic3_bond_get_netdev_by_portid(const char *bond_name, u8 po
}
EXPORT_SYMBOL(hinic3_bond_get_netdev_by_portid);
-int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos, u16 channel)
+int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos,
+ u16 channel)
{
struct comm_cmd_hw_bond_infos bond_infos;
u16 out_size = sizeof(bond_infos);
@@ -1002,7 +1101,8 @@ int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos, u1
bond_infos.infos.bond_id = infos->bond_id;
- err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_COMM, COMM_MGMT_CMD_GET_HW_BOND,
+ err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_COMM,
+ COMM_MGMT_CMD_GET_HW_BOND,
&bond_infos, sizeof(bond_infos),
&bond_infos, &out_size, 0, channel);
if (bond_infos.head.status || err || !out_size) {
@@ -1018,7 +1118,8 @@ int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos, u1
}
EXPORT_SYMBOL(hinic3_get_hw_bond_infos);
-int hinic3_get_bond_tracker_by_name(const char *name, struct bond_tracker *tracker)
+int hinic3_get_bond_tracker_by_name(const char *name,
+ struct bond_tracker *tracker)
{
struct hinic3_bond_dev *bdev = NULL;
int i;
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
index 024de95..5ab36f7 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
@@ -82,6 +82,7 @@ struct hinic3_bond_cmd {
char bond_name[16];
};
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev);
void hinic3_bond_set_user_bitmap(struct bond_attr *attr, enum hinic3_bond_user user);
int hinic3_bond_attach(const char *name, enum hinic3_bond_user user, u16 *bond_id);
int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user);
diff --git a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h b/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
deleted file mode 100644
index 557f326..0000000
--- a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2016-2022. All rights reserved.
- * File name: Cfg_mgt_comm_pub.h
- * Version No.: Draft
- * Generation date: 2016 year 05 month 07 day
- * Latest modification:
- * Function description: Header file for communication between the: Host and FW
- * Function list:
- * Modification history:
- * 1. Date: 2016 May 07
- * Modify content: Create a file.
- */
-#ifndef CFG_MGT_COMM_PUB_H
-#define CFG_MGT_COMM_PUB_H
-
-#include "mgmt_msg_base.h"
-
-enum servic_bit_define {
- SERVICE_BIT_NIC = 0,
- SERVICE_BIT_ROCE = 1,
- SERVICE_BIT_VBS = 2,
- SERVICE_BIT_TOE = 3,
- SERVICE_BIT_IPSEC = 4,
- SERVICE_BIT_FC = 5,
- SERVICE_BIT_VIRTIO = 6,
- SERVICE_BIT_OVS = 7,
- SERVICE_BIT_NVME = 8,
- SERVICE_BIT_ROCEAA = 9,
- SERVICE_BIT_CURRENET = 10,
- SERVICE_BIT_PPA = 11,
- SERVICE_BIT_MIGRATE = 12,
- SERVICE_BIT_MAX
-};
-
-#define CFG_SERVICE_MASK_NIC (0x1 << SERVICE_BIT_NIC)
-#define CFG_SERVICE_MASK_ROCE (0x1 << SERVICE_BIT_ROCE)
-#define CFG_SERVICE_MASK_VBS (0x1 << SERVICE_BIT_VBS)
-#define CFG_SERVICE_MASK_TOE (0x1 << SERVICE_BIT_TOE)
-#define CFG_SERVICE_MASK_IPSEC (0x1 << SERVICE_BIT_IPSEC)
-#define CFG_SERVICE_MASK_FC (0x1 << SERVICE_BIT_FC)
-#define CFG_SERVICE_MASK_VIRTIO (0x1 << SERVICE_BIT_VIRTIO)
-#define CFG_SERVICE_MASK_OVS (0x1 << SERVICE_BIT_OVS)
-#define CFG_SERVICE_MASK_NVME (0x1 << SERVICE_BIT_NVME)
-#define CFG_SERVICE_MASK_ROCEAA (0x1 << SERVICE_BIT_ROCEAA)
-#define CFG_SERVICE_MASK_CURRENET (0x1 << SERVICE_BIT_CURRENET)
-#define CFG_SERVICE_MASK_PPA (0x1 << SERVICE_BIT_PPA)
-#define CFG_SERVICE_MASK_MIGRATE (0x1 << SERVICE_BIT_MIGRATE)
-
-/* Definition of the scenario ID in the cfg_data, which is used for SML memory allocation. */
-enum scenes_id_define {
- SCENES_ID_FPGA_ETH = 0,
- SCENES_ID_FPGA_TIOE = 1, /* Discarded */
- SCENES_ID_STORAGE_ROCEAA_2x100 = 2,
- SCENES_ID_STORAGE_ROCEAA_4x25 = 3,
- SCENES_ID_CLOUD = 4,
- SCENES_ID_FC = 5,
- SCENES_ID_STORAGE_ROCE = 6,
- SCENES_ID_COMPUTE_ROCE = 7,
- SCENES_ID_STORAGE_TOE = 8,
- SCENES_ID_MAX
-};
-
-/* struct cfg_cmd_dev_cap.sf_svc_attr */
-enum {
- SF_SVC_FT_BIT = (1 << 0),
- SF_SVC_RDMA_BIT = (1 << 1),
-};
-
-enum cfg_cmd {
- CFG_CMD_GET_DEV_CAP = 0,
- CFG_CMD_GET_HOST_TIMER = 1,
-};
-
-struct cfg_cmd_host_timer {
- struct mgmt_msg_head head;
-
- u8 host_id;
- u8 rsvd1;
-
- u8 timer_pf_num;
- u8 timer_pf_id_start;
- u16 timer_vf_num;
- u16 timer_vf_id_start;
- u32 rsvd2[8];
-};
-
-struct cfg_cmd_dev_cap {
- struct mgmt_msg_head head;
-
- u16 func_id;
- u16 rsvd1;
-
- /* Public resources */
- u8 host_id;
- u8 ep_id;
- u8 er_id;
- u8 port_id;
-
- u16 host_total_func;
- u8 host_pf_num;
- u8 pf_id_start;
- u16 host_vf_num;
- u16 vf_id_start;
- u8 host_oq_id_mask_val;
- u8 timer_en;
- u8 host_valid_bitmap;
- u8 rsvd_host;
-
- u16 svc_cap_en;
- u16 max_vf;
- u8 flexq_en;
- u8 valid_cos_bitmap;
- /* Reserved for func_valid_cos_bitmap */
- u8 port_cos_valid_bitmap;
- u8 rsvd_func1;
- u32 rsvd_func2;
-
- u8 sf_svc_attr;
- u8 func_sf_en;
- u8 lb_mode;
- u8 smf_pg;
-
- u32 max_conn_num;
- u16 max_stick2cache_num;
- u16 max_bfilter_start_addr;
- u16 bfilter_len;
- u16 hash_bucket_num;
-
- /* shared resource */
- u8 host_sf_en;
- u8 master_host_id;
- u8 srv_multi_host_mode;
- u8 virtio_vq_size;
-
- u32 rsvd_func3[5];
-
- /* l2nic */
- u16 nic_max_sq_id;
- u16 nic_max_rq_id;
- u16 nic_default_num_queues;
- u16 rsvd1_nic;
- u32 rsvd2_nic[2];
-
- /* RoCE */
- u32 roce_max_qp;
- u32 roce_max_cq;
- u32 roce_max_srq;
- u32 roce_max_mpt;
- u32 roce_max_drc_qp;
-
- u32 roce_cmtt_cl_start;
- u32 roce_cmtt_cl_end;
- u32 roce_cmtt_cl_size;
-
- u32 roce_dmtt_cl_start;
- u32 roce_dmtt_cl_end;
- u32 roce_dmtt_cl_size;
-
- u32 roce_wqe_cl_start;
- u32 roce_wqe_cl_end;
- u32 roce_wqe_cl_size;
- u8 roce_srq_container_mode;
- u8 rsvd_roce1[3];
- u32 rsvd_roce2[5];
-
- /* IPsec */
- u32 ipsec_max_sactx;
- u16 ipsec_max_cq;
- u16 rsvd_ipsec1;
- u32 rsvd_ipsec[2];
-
- /* OVS */
- u32 ovs_max_qpc;
- u32 rsvd_ovs1[3];
-
- /* ToE */
- u32 toe_max_pctx;
- u32 toe_max_cq;
- u16 toe_max_srq;
- u16 toe_srq_id_start;
- u16 toe_max_mpt;
- u16 toe_max_cctxt;
- u32 rsvd_toe[2];
-
- /* FC */
- u32 fc_max_pctx;
- u32 fc_max_scq;
- u32 fc_max_srq;
-
- u32 fc_max_cctx;
- u32 fc_cctx_id_start;
-
- u8 fc_vp_id_start;
- u8 fc_vp_id_end;
- u8 rsvd_fc1[2];
- u32 rsvd_fc2[5];
-
- /* VBS */
- u16 vbs_max_volq;
- u16 rsvd0_vbs;
- u32 rsvd1_vbs[3];
-
- u16 fake_vf_start_id;
- u16 fake_vf_num;
- u32 fake_vf_max_pctx;
- u16 fake_vf_bfilter_start_addr;
- u16 fake_vf_bfilter_len;
- u32 rsvd_glb[8];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
deleted file mode 100644
index 59e20a1..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/******************************************************************************
- * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
- ******************************************************************************
- File Name : comm_cmdq_intf.h
- Version : Initial Draft
- Description : common command queue interface
- Function List :
- History :
- Modification: Created file
-
-******************************************************************************/
-
-#ifndef COMM_CMDQ_INTF_H
-#define COMM_CMDQ_INTF_H
-
-/* Cmdq ack type */
-enum hinic3_ack_type {
- HINIC3_ACK_TYPE_CMDQ,
- HINIC3_ACK_TYPE_SHARE_CQN,
- HINIC3_ACK_TYPE_APP_CQN,
-
- HINIC3_MOD_ACK_MAX = 15,
-};
-
-/* Defines the queue type of the set arm bit. */
-enum {
- SET_ARM_BIT_FOR_CMDQ = 0,
- SET_ARM_BIT_FOR_L2NIC_SQ,
- SET_ARM_BIT_FOR_L2NIC_RQ,
- SET_ARM_BIT_TYPE_NUM
-};
-
-/* Defines the type. Each function supports a maximum of eight CMDQ types. */
-enum {
- CMDQ_0 = 0,
- CMDQ_1 = 1, /* dedicated and non-blocking queues */
- CMDQ_NUM
-};
-
-/* *******************cmd common command data structure ************************ */
-// Func->ucode, which is used to set arm bit data,
-// The microcode needs to perform big-endian conversion.
-struct comm_info_ucode_set_arm_bit {
- u32 q_type;
- u32 q_id;
-};
-
-/* *******************WQE data structure ************************ */
-union cmdq_wqe_cs_dw0 {
- struct {
- u32 err_status : 29;
- u32 error_code : 2;
- u32 rsvd : 1;
- } bs;
- u32 val;
-};
-
-union cmdq_wqe_cs_dw1 {
- // This structure is used when the driver writes the wqe.
- struct {
- u32 token : 16; // [15:0]
- u32 cmd : 8; // [23:16]
- u32 mod : 5; // [28:24]
- u32 ack_type : 2; // [30:29]
- u32 obit : 1; // [31]
- } drv_wr;
-
- /* The uCode writes back the structure of the CS_DW1. */
- /* The driver reads and uses the structure. */
- struct {
- u32 mod : 5; // [4:0]
- u32 ack_type : 3; // [7:5]
- u32 cmd : 8; // [15:8]
- u32 arm : 1; // [16]
- u32 rsvd : 14; // [30:17]
- u32 obit : 1; // [31]
- } wb;
- u32 val;
-};
-
-/* CmdQ BD information or write back buffer information */
-struct cmdq_sge {
- u32 pa_h; // Upper 32 bits of the physical address
- u32 pa_l; // Upper 32 bits of the physical address
- u32 len; // Invalid bit[31].
- u32 resv;
-};
-
-/* Ctrls section definition of WQE */
-struct cmdq_wqe_ctrls {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
-};
-
-/* Complete section definition of WQE */
-struct cmdq_wqe_cs {
- union cmdq_wqe_cs_dw0 dw0;
- union cmdq_wqe_cs_dw1 dw1;
- union {
- struct cmdq_sge sge;
- u32 dw2_5[4];
- } ack;
-};
-
-/* Inline header in WQE inline, describing the length of inline data */
-union cmdq_wqe_inline_header {
- struct {
- u32 buf_len : 11; // [10:0] inline data len
- u32 rsv : 21; // [31:11]
- } bs;
- u32 val;
-};
-
-/* Definition of buffer descriptor section in WQE */
-union cmdq_wqe_bds {
- struct {
- struct cmdq_sge bds_sge;
- u32 rsvd[4]; /* Zwy is used to transfer the virtual address of the buffer. */
- } lcmd; /* Long command, non-inline, and SGE describe the buffer information. */
-};
-
-/* Definition of CMDQ WQE */
-/* (long cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(16B) |
- * | |
- * +----------------------------------------+
- * | driver section(16B) |
- * +----------------------------------------+
- *
- *
- * (middle cmd, 128B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(88B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- *
- *
- * (short cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(24B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- */
-struct cmdq_wqe {
- struct cmdq_wqe_ctrls ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds bds;
-};
-
-/* Definition of ctrls section in inline WQE */
-struct cmdq_wqe_ctrls_inline {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
- u64 db;
-};
-
-/* Buffer descriptor section definition of WQE */
-union cmdq_wqe_bds_inline {
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[80];
- } mcmd; /* Middle command, inline mode */
-
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[16];
- } scmd; /* Short command, inline mode */
-};
-
-struct cmdq_wqe_inline {
- struct cmdq_wqe_ctrls_inline ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds_inline bds;
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_defs.h b/drivers/net/ethernet/huawei/hinic3/comm_defs.h
deleted file mode 100644
index c5b1913..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_defs.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_defs.h
- * Version : Initial Draft
- * Description : common definitions
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef COMM_DEFS_H
-#define COMM_DEFS_H
-
-/* CMDQ MODULE_TYPE */
-enum hinic3_mod_type {
- HINIC3_MOD_COMM = 0, /* HW communication module */
- HINIC3_MOD_L2NIC = 1, /* L2NIC module */
- HINIC3_MOD_ROCE = 2,
- HINIC3_MOD_PLOG = 3,
- HINIC3_MOD_TOE = 4,
- HINIC3_MOD_FLR = 5,
- HINIC3_MOD_RSVD1 = 6,
- HINIC3_MOD_CFGM = 7, /* Configuration module */
- HINIC3_MOD_CQM = 8,
- HINIC3_MOD_VMSEC = 9,
- COMM_MOD_FC = 10,
- HINIC3_MOD_OVS = 11,
- HINIC3_MOD_DSW = 12,
- HINIC3_MOD_MIGRATE = 13,
- HINIC3_MOD_HILINK = 14,
- HINIC3_MOD_CRYPT = 15, /* secure crypto module */
- HINIC3_MOD_VIO = 16,
- HINIC3_MOD_IMU = 17,
- HINIC3_MOD_DFT = 18, /* DFT */
- HINIC3_MOD_HW_MAX = 19, /* hardware max module id */
- /* Software module id, for PF/VF and multi-host */
- HINIC3_MOD_SW_FUNC = 20,
- HINIC3_MOD_MAX,
-};
-
-/* func reset的flag ,用于指示清理哪种资源 */
-enum func_reset_flag {
- RES_TYPE_FLUSH_BIT = 0,
- RES_TYPE_MQM,
- RES_TYPE_SMF,
- RES_TYPE_PF_BW_CFG,
-
- RES_TYPE_COMM = 10,
- RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_NIC,
- RES_TYPE_OVS,
- RES_TYPE_VBS,
- RES_TYPE_ROCE,
- RES_TYPE_FC,
- RES_TYPE_TOE,
- RES_TYPE_IPSEC,
- RES_TYPE_MAX,
-};
-
-#define HINIC3_COMM_RES \
- ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
- (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
- (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
-
-#define HINIC3_NIC_RES BIT(RES_TYPE_NIC)
-#define HINIC3_OVS_RES BIT(RES_TYPE_OVS)
-#define HINIC3_VBS_RES BIT(RES_TYPE_VBS)
-#define HINIC3_ROCE_RES BIT(RES_TYPE_ROCE)
-#define HINIC3_FC_RES BIT(RES_TYPE_FC)
-#define HINIC3_TOE_RES BIT(RES_TYPE_TOE)
-#define HINIC3_IPSEC_RES BIT(RES_TYPE_IPSEC)
-
-/* MODE OVS、NIC、UNKNOWN */
-#define HINIC3_WORK_MODE_OVS 0
-#define HINIC3_WORK_MODE_UNKNOWN 1
-#define HINIC3_WORK_MODE_NIC 2
-
-#define DEVICE_TYPE_L2NIC 0
-#define DEVICE_TYPE_NVME 1
-#define DEVICE_TYPE_VIRTIO_NET 2
-#define DEVICE_TYPE_VIRTIO_BLK 3
-#define DEVICE_TYPE_VIRTIO_VSOCK 4
-#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
-#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
-#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
-#define DEVICE_TYPE_VIRTIO_HPC 8
-
-/* Common header control information of the COMM message
- * interaction command word between the driver and PF
- */
-struct comm_info_head {
- u8 status;
- u8 version;
- u8 rep_aeq_num;
- u8 rsvd[5];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
deleted file mode 100644
index ae998cf..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_msg_intf.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef COMM_MSG_INTF_H
-#define COMM_MSG_INTF_H
-
-#include "comm_defs.h"
-#include "mgmt_msg_base.h"
-#include "mpu_cmd_base_defs.h"
-#include "mpu_inband_cmd_defs.h"
-
-struct spu_cmd_freq_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: check */
- u8 rsvd[3];
- u32 freq;
-};
-
-struct spu_cmd_power_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: init */
- u8 slave_addr;
- u8 cmd_id;
- u8 size;
- u32 value;
-};
-
-struct spu_cmd_tsensor_operation {
- struct comm_info_head head;
-
- u8 op_code;
- u8 rsvd[3];
- s16 fabric_tsensor_temp_avg;
- s16 fabric_tsensor_temp;
- s16 sys_tsensor_temp_avg;
- s16 sys_tsensor_temp;
-};
-
-enum cfg_msix_operation {
- CFG_MSIX_OPERATION_FREE = 0,
- CFG_MSIX_OPERATION_ALLOC = 1,
-};
-
-struct comm_cmd_ffm_info {
- struct mgmt_msg_head head;
-
- u8 node_id;
- /* error level of the interrupt source */
- u8 err_level;
- /* Classification by interrupt source properties */
- u16 err_type;
- u32 err_csr_addr;
- u32 err_csr_value;
- u32 rsvd1;
-};
-
-struct hinic3_cmd_update_firmware {
- struct mgmt_msg_head msg_head;
-
- struct {
- u32 sl : 1;
- u32 sf : 1;
- u32 flag : 1;
- u32 bit_signed : 1;
- u32 reserved : 12;
- u32 fragment_len : 16;
- } ctl_info;
-
- struct {
- u32 section_crc;
- u32 section_type;
- } section_info;
-
- u32 total_len;
- u32 section_len;
- u32 section_version;
- u32 section_offset;
- u32 data[384];
-};
-
-struct hinic3_cmd_activate_firmware {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-struct hinic3_cmd_switch_config {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
index 8c95032..aad3a97 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
@@ -28,6 +28,8 @@
#include "cqm_npu_cmd.h"
#include "cqm_npu_cmd_defs.h"
+#include "vram_common.h"
+
static void cqm_bat_fill_cla_common_gpa(struct tag_cqm_handle *cqm_handle,
struct tag_cqm_cla_table *cla_table,
struct tag_cqm_bat_entry_standerd *bat_entry_standerd)
@@ -366,6 +368,13 @@ static s32 cqm_bat_update_cmd(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
struct hinic3_hwdev *handle = cqm_handle->ex_handle;
struct tag_cqm_cmdq_bat_update *bat_update_cmd = NULL;
s32 ret = CQM_FAIL;
+ int is_in_kexec;
+
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip updating the cqm_bat to chip during kexec!\n");
+ return CQM_SUCCESS;
+ }
bat_update_cmd = (struct tag_cqm_cmdq_bat_update *)(buf_in->buf);
bat_update_cmd->offset = 0;
@@ -768,8 +777,10 @@ static s32 cqm_cla_xyz_lvl1(struct tag_cqm_handle *cqm_handle,
/* Applying for CLA_Z_BUF Space */
cla_z_buf = &cla_table->cla_z_buf;
cla_z_buf->buf_size = trunk_size;
- cla_z_buf->buf_number = (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
- cla_z_buf->page_number = cla_z_buf->buf_number << cla_table->trunk_order;
+ cla_z_buf->buf_number =
+ (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
+ cla_z_buf->page_number = cla_z_buf->buf_number <<
+ cla_table->trunk_order;
/* All buffer space must be statically allocated. */
if (cla_table->alloc_static) {
@@ -840,6 +851,7 @@ static s32 cqm_cla_xyz_lvl2_xyz_apply(struct tag_cqm_handle *cqm_handle,
cla_x_buf->buf_size = trunk_size;
cla_x_buf->buf_number = 1;
cla_x_buf->page_number = cla_x_buf->buf_number << cla_table->trunk_order;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
ret = cqm_buf_alloc(cqm_handle, cla_x_buf, false);
if (ret != CQM_SUCCESS)
return CQM_FAIL;
@@ -869,14 +881,20 @@ static s32 cqm_cla_xyz_vram_name_init(struct tag_cqm_cla_table *cla_table,
cla_x_buf = &cla_table->cla_x_buf;
cla_z_buf = &cla_table->cla_z_buf;
cla_y_buf = &cla_table->cla_y_buf;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_x_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_X);
+ VRAM_NAME_MAX_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_X);
+ cla_y_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_y_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Y);
+ VRAM_NAME_MAX_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Y);
+ cla_z_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_z_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Z);
+ VRAM_NAME_MAX_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Z);
return CQM_SUCCESS;
}
@@ -1188,7 +1206,7 @@ static void cqm_cla_init_entry_extern(struct tag_cqm_handle *cqm_handle,
* exceed 128 x 4 KB. Otherwise, clearing the timer buffer of
* the function is complex.
*/
- cla_table->trunk_order = CQM_4K_PAGE_ORDER;
+ cla_table->trunk_order = CQM_8K_PAGE_ORDER;
cla_table->max_buffer_size = capability->timer_number *
capability->timer_basic_size;
cla_table->obj_size = capability->timer_basic_size;
@@ -1237,7 +1255,7 @@ static s32 cqm_cla_init_entry_condition(struct tag_cqm_handle *cqm_handle, u32 e
memcpy(cla_table_timer, cla_table, sizeof(struct tag_cqm_cla_table));
snprintf(cla_table_timer->name,
- VRAM_NAME_MAX_LEN - 1, "%s%s%01u", cla_table->name,
+ VRAM_NAME_MAX_LEN, "%s%s%01u", cla_table->name,
VRAM_CQM_CLA_SMF_BASE, i);
if (cqm_cla_xyz(cqm_handle, cla_table_timer) ==
@@ -1268,7 +1286,7 @@ static s32 cqm_cla_init_entry(struct tag_cqm_handle *cqm_handle,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
cla_table->type = bat_table->bat_entry_type[i];
- snprintf(cla_table->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(cla_table->name, VRAM_NAME_MAX_LEN,
"%s%s%s%02u", cqm_handle->name, VRAM_CQM_CLA_BASE,
VRAM_CQM_CLA_TYPE_BASE, cla_table->type);
@@ -1485,11 +1503,11 @@ static s32 cqm_cla_update(struct tag_cqm_handle *cqm_handle,
spu_en = 0;
pa = ((buf_node_parent->pa + (child_index * sizeof(dma_addr_t))) |
- (u32)spu_en);
+ spu_en);
cmd.gpa_h = CQM_ADDR_HI(pa);
cmd.gpa_l = CQM_ADDR_LW(pa);
- pa = (buf_node_child->pa | (u32)spu_en);
+ pa = (buf_node_child->pa | spu_en);
cmd.value_h = CQM_ADDR_HI(pa);
cmd.value_l = CQM_ADDR_LW(pa);
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
index dd0766e..a51c1dc 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
@@ -9,6 +9,7 @@
#include "cqm_bitmap_table.h"
#include "cqm_object.h"
+#include "vram_common.h"
/* When the connection check is enabled, the maximum number of connections
* supported by the chip is 1M - 63, which cannot reach 1M
@@ -19,6 +20,7 @@
#define CLA_TABLE_PAGE_ORDER 0
#define CQM_4K_PAGE_ORDER 0
#define CQM_4K_PAGE_SIZE 4096
+#define CQM_8K_PAGE_ORDER 1
#define CQM_BAT_ENTRY_MAX 16
#define CQM_BAT_ENTRY_SIZE 16
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
index d5fac94..61602e6 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
@@ -273,6 +273,11 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
return CQM_SUCCESS;
}
+static bool check_use_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ return buf->buf_info.use_vram ? true : false;
+}
+
static bool check_use_non_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
{
return buf->buf_info.use_vram ? false : true;
@@ -294,11 +299,46 @@ static bool check_for_nouse_node_alloc(struct hinic3_hwdev *handle, struct tag_c
return false;
}
+static s32 cqm_buf_vram_kalloc(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ void *vaddr = NULL;
+ int i;
+
+ vaddr = hi_vram_kalloc(buf->buf_info.buf_vram_name, (u64)buf->buf_size * buf->buf_number);
+ if (!vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
+ return CQM_FAIL;
+ }
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = (void *)((char *)vaddr + i * (u64)buf->buf_size);
+
+ return CQM_SUCCESS;
+}
+
+static void cqm_buf_vram_free(struct tag_cqm_buf *buf)
+{
+ s32 i;
+
+ if (!buf->buf_list)
+ return;
+
+ if (buf->buf_list[0].va)
+ hi_vram_kfree(buf->buf_list[0].va, buf->buf_info.buf_vram_name,
+ (u64)buf->buf_size * buf->buf_number);
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = NULL;
+}
+
static void cqm_buf_free_page_common(struct tag_cqm_buf *buf)
{
u32 order;
s32 i;
+ if (!buf->buf_list)
+ return;
+
order = (u32)get_order(buf->buf_size);
for (i = 0; i < (s32)buf->buf_number; i++) {
@@ -320,8 +360,10 @@ static s32 cqm_buf_use_node_alloc_page(struct hinic3_hwdev *handle, struct tag_c
node = dev_to_node(handle->dev_hdl);
for (i = 0; i < (s32)buf->buf_number; i++) {
newpage = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, order);
- if (!newpage)
+ if (!newpage) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
va = (void *)page_address(newpage);
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
@@ -349,8 +391,10 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
for (i = 0; i < (s32)buf->buf_number; i++) {
va = (void *)ossl_get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
- if (!va)
+ if (!va) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
* value must be 0.
@@ -367,21 +411,21 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
return CQM_SUCCESS;
}
-#define MALLOC_FUNCS_COUNT 2
-#define FREE_FUNCS_COUNT 1
-static const struct malloc_memory g_malloc_funcs[MALLOC_FUNCS_COUNT] = {
+static const struct malloc_memory g_malloc_funcs[] = {
+ {check_use_vram, cqm_buf_vram_kalloc},
{check_for_use_node_alloc, cqm_buf_use_node_alloc_page},
{check_for_nouse_node_alloc, cqm_buf_unused_node_alloc_page}
};
-static const struct free_memory g_free_funcs[FREE_FUNCS_COUNT] = {
+static const struct free_memory g_free_funcs[] = {
+ {check_use_vram, cqm_buf_vram_free},
{check_use_non_vram, cqm_buf_free_page_common}
};
static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *buf)
{
struct hinic3_hwdev *handle = cqm_handle->ex_handle;
- u32 malloc_funcs_num = MALLOC_FUNCS_COUNT;
+ u32 malloc_funcs_num = ARRAY_SIZE(g_malloc_funcs);
u32 i;
for (i = 0; i < malloc_funcs_num; i++) {
@@ -398,7 +442,7 @@ static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
static void cqm_buf_free_page(struct tag_cqm_buf *buf)
{
- u32 free_funcs_num = FREE_FUNCS_COUNT;
+ u32 free_funcs_num = ARRAY_SIZE(g_free_funcs);
u32 i;
for (i = 0; i < free_funcs_num; i++) {
@@ -447,8 +491,11 @@ static s32 cqm_buf_get_secure_mem_pages(struct tag_cqm_handle *cqm_handle, struc
cqm_get_secure_mem_pages(handle,
(u32)get_order(buf->buf_size),
&buf->buf_list[i].pa);
- if (!buf->buf_list[i].va)
+ if (!buf->buf_list[i].va) {
+ cqm_err(handle->dev_hdl,
+ CQM_ALLOC_FAIL(cqm_get_secure_mem_pages));
break;
+ }
}
if (i != buf->buf_number) {
@@ -777,7 +824,11 @@ static s32 cqm_single_bitmap_init(struct tag_cqm_bitmap *bitmap)
*/
bit_number = (ALIGN(bitmap->max_num, CQM_NUM_BIT_BYTE) >>
CQM_BYTE_BIT_SHIFT);
- bitmap->table = vmalloc(bit_number);
+ if (bitmap->bitmap_info.use_vram != 0)
+ bitmap->table = hi_vram_kalloc(bitmap->bitmap_info.buf_vram_name,
+ bit_number);
+ else
+ bitmap->table = vmalloc(bit_number);
if (!bitmap->table)
return CQM_FAIL;
memset(bitmap->table, 0, bit_number);
@@ -856,7 +907,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
}
bitmap = &cla_table->bitmap;
- snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_MAX_LEN,
"%s%s%02d", cla_table->name,
VRAM_CQM_BITMAP_BASE, cla_table->type);
@@ -866,6 +917,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
bitmap->reserved_top = capability->qpc_reserved;
bitmap->reserved_back = capability->qpc_reserved_back;
bitmap->last = capability->qpc_reserved;
+ bitmap->bitmap_info.use_vram = get_use_vram_flag();
cqm_info(handle->dev_hdl,
"Bitmap init: cla_table_type=%u, max_num=0x%x\n",
cla_table->type, bitmap->max_num);
@@ -945,7 +997,14 @@ void cqm_bitmap_uninit(struct tag_cqm_handle *cqm_handle)
if (cla_table->type != CQM_BAT_ENTRY_T_INVALID &&
bitmap->table) {
spin_lock_deinit(&bitmap->lock);
- vfree(bitmap->table);
+ if (bitmap->bitmap_info.use_vram != 0)
+ hi_vram_kfree(bitmap->table,
+ bitmap->bitmap_info.buf_vram_name,
+ ALIGN(bitmap->max_num,
+ CQM_NUM_BIT_BYTE) >>
+ CQM_BYTE_BIT_SHIFT);
+ else
+ vfree(bitmap->table);
bitmap->table = NULL;
}
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
index 7febf76..06b8661 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
@@ -9,6 +9,7 @@
#include <linux/spinlock.h>
#include "cqm_object.h"
+#include "vram_common.h"
struct tag_cqm_bitmap {
ulong *table;
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
index 9a13ae0..2a24e4a 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
@@ -196,6 +196,13 @@ void *cqm_get_db_addr(void *ex_handle, u32 service_type)
pr_err("[CQM]%s: ex_handle is null\n", __func__);
return NULL;
}
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return NULL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -218,6 +225,17 @@ s32 cqm_ring_hardware_db(void *ex_handle, u32 service_type, u8 db_count, u64 db)
struct tag_cqm_service *service = NULL;
struct hinic3_hwdev *handle = NULL;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -278,6 +296,17 @@ s32 cqm_ring_direct_wqe_db(void *ex_handle, u32 service_type, u8 db_count,
u64 *tmp = (u64 *)direct_wqe;
int i;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
index 19a8b56..1f1235c 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
@@ -23,6 +23,8 @@
#include "cqm_memsec.h"
#include "cqm_main.h"
+#include "vram_common.h"
+
static unsigned char roce_qpc_rsv_mode = CQM_QPC_ROCE_NORMAL;
module_param(roce_qpc_rsv_mode, byte, 0644);
MODULE_PARM_DESC(roce_qpc_rsv_mode,
@@ -98,10 +100,17 @@ static s32 cqm_set_timer_enable(void *ex_handle)
{
struct hinic3_hwdev *handle = (struct hinic3_hwdev *)ex_handle;
struct tag_cqm_handle *cqm_handle = NULL;
+ int is_in_kexec;
if (!ex_handle)
return CQM_FAIL;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip starting cqm timer during kexec\n");
+ return CQM_SUCCESS;
+ }
+
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
if (cqm_handle->func_capability.fake_func_type == CQM_FAKE_FUNC_PARENT &&
cqm_set_fake_vf_timer(cqm_handle) != CQM_SUCCESS)
@@ -473,7 +482,8 @@ static void cqm_service_capability_init_roce(struct tag_cqm_handle *cqm_handle,
func_cap->qpc_number += roce_own_cap->max_qps;
func_cap->qpc_basic_size = GET_MAX(roce_own_cap->qpc_entry_sz,
func_cap->qpc_basic_size);
- if (cqm_handle->func_attribute.func_type == CQM_PF && (IS_MASTER_HOST(handle))) {
+ if (cqm_handle->func_attribute.func_type == CQM_PF &&
+ (IS_MASTER_HOST(handle))) {
func_cap->hash_number = roce_own_cap->max_qps;
func_cap->hash_basic_size = CQM_HASH_BUCKET_SIZE_64;
}
@@ -1129,8 +1139,9 @@ static s32 cqm_fake_mem_init(struct tag_cqm_handle *cqm_handle)
for (i = 0; i < (u32)child_func_number; i++) {
fake_cqm_handle = cqm_handle->fake_cqm_handle[i];
- snprintf(fake_cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
- "%s%s%02u", cqm_handle->name, VRAM_CQM_FAKE_MEM_BASE, i);
+ snprintf(fake_cqm_handle->name, VRAM_NAME_MAX_LEN,
+ "%s%s%02u", cqm_handle->name,
+ VRAM_CQM_FAKE_MEM_BASE, i);
if (cqm_bat_init(fake_cqm_handle) != CQM_SUCCESS) {
cqm_err(handle->dev_hdl,
@@ -1174,8 +1185,9 @@ s32 cqm_mem_init(void *ex_handle)
struct tag_cqm_handle *cqm_handle = NULL;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
- snprintf(cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
- "%s%02u", VRAM_CQM_GLB_FUNC_BASE, hinic3_global_func_id(handle));
+ snprintf(cqm_handle->name, VRAM_NAME_MAX_LEN,
+ "%s%02u", VRAM_CQM_GLB_FUNC_BASE,
+ hinic3_global_func_id(handle));
if (cqm_fake_init(cqm_handle) != CQM_SUCCESS) {
cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_fake_init));
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
index 4f87bd1..8d1e481 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
@@ -362,6 +362,7 @@ s32 cqm_fake_vf_num_set(void *ex_handle, u16 fake_vf_num_cfg);
#define CQM_LOG_ID 0
#define CQM_PTR_NULL(x) "%s: " #x " is null\n", __func__
+#define CQM_ALLOC_FAIL(x) "%s: " #x " alloc fail\n", __func__
#define CQM_MAP_FAIL(x) "%s: " #x " map fail\n", __func__
#define CQM_FUNCTION_FAIL(x) "%s: " #x " return failure\n", __func__
#define CQM_WRONG_VALUE(x) "%s: " #x " %u is wrong\n", __func__, (u32)(x)
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
index 213803f..f5fce8f 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
@@ -378,7 +378,7 @@ static int hinic3_secure_mem_proc_node_remove(void *hwdev)
atomic_dec(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
@@ -401,7 +401,7 @@ static int hinic3_secure_mem_proc_node_add(void *hwdev)
atomic_inc(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
/* 0400 Read by owner */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h b/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
deleted file mode 100644
index ad732c3..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2019-2022. All rights reserved.
- * File Name : hinic3_comm_cmd.h
- * Version : Initial Draft
- * Created : 2019/4/25
- * Last Modified :
- * Description : COMM Commands between Driver and MPU
- * Function List :
- */
-
-#ifndef HINIC3_COMMON_CMD_H
-#define HINIC3_COMMON_CMD_H
-
-/* COMM Commands between Driver to MPU */
-enum hinic3_mgmt_cmd {
- /* flr及资源清理相关命令 */
- COMM_MGMT_CMD_FUNC_RESET = 0,
- COMM_MGMT_CMD_FEATURE_NEGO,
- COMM_MGMT_CMD_FLUSH_DOORBELL,
- COMM_MGMT_CMD_START_FLUSH,
- COMM_MGMT_CMD_SET_FUNC_FLR,
- COMM_MGMT_CMD_GET_GLOBAL_ATTR,
- COMM_MGMT_CMD_SET_PPF_FLR_TYPE,
- COMM_MGMT_CMD_SET_FUNC_SVC_USED_STATE,
-
- /* 分配msi-x中断资源 */
- COMM_MGMT_CMD_CFG_MSIX_NUM = 10,
-
- /* 驱动相关配置命令 */
- COMM_MGMT_CMD_SET_CMDQ_CTXT = 20,
- COMM_MGMT_CMD_SET_VAT,
- COMM_MGMT_CMD_CFG_PAGESIZE,
- COMM_MGMT_CMD_CFG_MSIX_CTRL_REG,
- COMM_MGMT_CMD_SET_CEQ_CTRL_REG,
- COMM_MGMT_CMD_SET_DMA_ATTR,
-
- /* INFRA配置相关命令字 */
- COMM_MGMT_CMD_GET_MQM_FIX_INFO = 40,
- COMM_MGMT_CMD_SET_MQM_CFG_INFO,
- COMM_MGMT_CMD_SET_MQM_SRCH_GPA,
- COMM_MGMT_CMD_SET_PPF_TMR,
- COMM_MGMT_CMD_SET_PPF_HT_GPA,
- COMM_MGMT_CMD_SET_FUNC_TMR_BITMAT,
- COMM_MGMT_CMD_SET_MBX_CRDT,
- COMM_MGMT_CMD_CFG_TEMPLATE,
- COMM_MGMT_CMD_SET_MQM_LIMIT,
-
- /* 信息获取相关命令字 */
- COMM_MGMT_CMD_GET_FW_VERSION = 60,
- COMM_MGMT_CMD_GET_BOARD_INFO,
- COMM_MGMT_CMD_SYNC_TIME,
- COMM_MGMT_CMD_GET_HW_PF_INFOS,
- COMM_MGMT_CMD_SEND_BDF_INFO,
- COMM_MGMT_CMD_GET_VIRTIO_BDF_INFO,
- COMM_MGMT_CMD_GET_SML_TABLE_INFO,
- COMM_MGMT_CMD_GET_SDI_INFO,
-
- /* 升级相关命令字 */
- COMM_MGMT_CMD_UPDATE_FW = 80,
- COMM_MGMT_CMD_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_DONE_NOTICE,
- COMM_MGMT_CMD_SWITCH_CFG,
- COMM_MGMT_CMD_CHECK_FLASH,
- COMM_MGMT_CMD_CHECK_FLASH_RW,
- COMM_MGMT_CMD_RESOURCE_CFG,
- COMM_MGMT_CMD_UPDATE_BIOS, /* TODO: merge to COMM_MGMT_CMD_UPDATE_FW */
- COMM_MGMT_CMD_MPU_GIT_CODE,
-
- /* chip reset相关 */
- COMM_MGMT_CMD_FAULT_REPORT = 100,
- COMM_MGMT_CMD_WATCHDOG_INFO,
- COMM_MGMT_CMD_MGMT_RESET,
- COMM_MGMT_CMD_FFM_SET, /* TODO: check if needed */
-
- /* chip info/log 相关 */
- COMM_MGMT_CMD_GET_LOG = 120,
- COMM_MGMT_CMD_TEMP_OP,
- COMM_MGMT_CMD_EN_AUTO_RST_CHIP,
- COMM_MGMT_CMD_CFG_REG,
- COMM_MGMT_CMD_GET_CHIP_ID,
- COMM_MGMT_CMD_SYSINFO_DFX,
- COMM_MGMT_CMD_PCIE_DFX_NTC,
- COMM_MGMT_CMD_DICT_LOG_STATUS, /* LOG STATUS 127 */
- COMM_MGMT_CMD_MSIX_INFO,
- COMM_MGMT_CMD_CHANNEL_DETECT,
- COMM_MGMT_CMD_DICT_COUNTER_STATUS,
-
- /* switch workmode 相关 */
- COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140,
- COMM_MGMT_CMD_SWITCH_WORKMODE,
-
- /* mpu 相关 */
- COMM_MGMT_CMD_MIGRATE_DFX_HPA = 150,
- COMM_MGMT_CMD_BDF_INFO,
- COMM_MGMT_CMD_NCSI_CFG_INFO_GET_PROC,
-
- /* rsvd0 section */
- COMM_MGMT_CMD_SECTION_RSVD_0 = 160,
-
- /* rsvd1 section */
- COMM_MGMT_CMD_SECTION_RSVD_1 = 170,
-
- /* rsvd2 section */
- COMM_MGMT_CMD_SECTION_RSVD_2 = 180,
-
- /* rsvd3 section */
- COMM_MGMT_CMD_SECTION_RSVD_3 = 190,
-
- /* TODO: move to DFT mode */
- COMM_MGMT_CMD_GET_DIE_ID = 200,
- COMM_MGMT_CMD_GET_EFUSE_TEST,
- COMM_MGMT_CMD_EFUSE_INFO_CFG,
- COMM_MGMT_CMD_GPIO_CTL,
- COMM_MGMT_CMD_HI30_SERLOOP_START, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_SERLOOP_STOP, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_SET_FLAG, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_GET_RESULT, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_ECC_TEST,
- COMM_MGMT_CMD_FUNC_BIST_TEST, /* 209 */
-
- COMM_MGMT_CMD_VPD_SET = 210,
- COMM_MGMT_CMD_VPD_GET,
-
- COMM_MGMT_CMD_ERASE_FLASH,
- COMM_MGMT_CMD_QUERY_FW_INFO,
- COMM_MGMT_CMD_GET_CFG_INFO,
- COMM_MGMT_CMD_GET_UART_LOG,
- COMM_MGMT_CMD_SET_UART_CMD,
- COMM_MGMT_CMD_SPI_TEST,
-
- /* TODO: ALL reg read/write merge to COMM_MGMT_CMD_CFG_REG */
- COMM_MGMT_CMD_UP_REG_GET,
- COMM_MGMT_CMD_UP_REG_SET, /* 219 */
-
- COMM_MGMT_CMD_REG_READ = 220,
- COMM_MGMT_CMD_REG_WRITE,
- COMM_MGMT_CMD_MAG_REG_WRITE,
- COMM_MGMT_CMD_ANLT_REG_WRITE,
-
- COMM_MGMT_CMD_HEART_EVENT, /* TODO: delete */
- COMM_MGMT_CMD_NCSI_OEM_GET_DRV_INFO, /* TODO: delete */
- COMM_MGMT_CMD_LASTWORD_GET,
- COMM_MGMT_CMD_READ_BIN_DATA, /* TODO: delete */
- /* COMM_MGMT_CMD_WWPN_GET, TODO: move to FC? */
- /* COMM_MGMT_CMD_WWPN_SET, TODO: move to FC? */ /* 229 */
-
- /* TODO: check if needed */
- COMM_MGMT_CMD_SET_VIRTIO_DEV = 230,
- COMM_MGMT_CMD_SET_MAC,
- /* MPU patch cmd */
- COMM_MGMT_CMD_LOAD_PATCH,
- COMM_MGMT_CMD_REMOVE_PATCH,
- COMM_MGMT_CMD_PATCH_ACTIVE,
- COMM_MGMT_CMD_PATCH_DEACTIVE,
- COMM_MGMT_CMD_PATCH_SRAM_OPTIMIZE,
- /* container host process */
- COMM_MGMT_CMD_CONTAINER_HOST_PROC,
- /* nsci counter */
- COMM_MGMT_CMD_NCSI_COUNTER_PROC,
- COMM_MGMT_CMD_CHANNEL_STATUS_CHECK, /* 239 */
-
- /* hot patch rsvd cmd */
- COMM_MGMT_CMD_RSVD_0 = 240,
- COMM_MGMT_CMD_RSVD_1,
- COMM_MGMT_CMD_RSVD_2,
- COMM_MGMT_CMD_RSVD_3,
- COMM_MGMT_CMD_RSVD_4,
- /* 无效字段,版本收编删除,编译使用 */
- COMM_MGMT_CMD_SEND_API_ACK_BY_UP,
-
- /* 注:添加cmd,不能修改已有命令字的值,请在前方rsvd
- * section中添加;原则上所有分支cmd表完全一致
- */
- COMM_MGMT_CMD_MAX = 255,
-};
-
-/* CmdQ Common subtype */
-enum comm_cmdq_cmd {
- COMM_CMD_UCODE_ARM_BIT_SET = 2,
- COMM_CMD_SEND_NPU_DFT_CMD,
-};
-
-#endif /* HINIC3_COMMON_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
deleted file mode 100644
index 9ce908e..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_COMMON_H
-#define HINIC3_COMMON_H
-
-#include <linux/types.h>
-
-struct hinic3_dma_addr_align {
- u32 real_size;
-
- void *ori_vaddr;
- dma_addr_t ori_paddr;
-
- void *align_vaddr;
- dma_addr_t align_paddr;
-};
-
-enum hinic3_wait_return {
- WAIT_PROCESS_CPL = 0,
- WAIT_PROCESS_WAITING = 1,
- WAIT_PROCESS_ERR = 2,
-};
-
-struct hinic3_sge {
- u32 hi_addr;
- u32 lo_addr;
- u32 len;
-};
-
-#ifdef static
-#undef static
-#define LLT_STATIC_DEF_SAVED
-#endif
-
-/* *
- * hinic_cpu_to_be32 - convert data to big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert, must be Multiple of 4B
- */
-static inline void hinic3_cpu_to_be32(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = cpu_to_be32(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_cpu_to_be32 - convert data from big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert
- */
-static inline void hinic3_be32_to_cpu(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = be32_to_cpu(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_set_sge - set dma area in scatter gather entry
- * @sge: scatter gather entry
- * @addr: dma address
- * @len: length of relevant data in the dma address
- */
-static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
- int len)
-{
- sge->hi_addr = upper_32_bits(addr);
- sge->lo_addr = lower_32_bits(addr);
- sge->len = len;
-}
-
-#define hinic3_hw_be32(val) (val)
-#define hinic3_hw_cpu32(val) (val)
-#define hinic3_hw_cpu16(val) (val)
-
-static inline void hinic3_hw_be32_len(void *data, int len)
-{
-}
-
-static inline void hinic3_hw_cpu32_len(void *data, int len)
-{
-}
-
-int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
- unsigned int flag,
- struct hinic3_dma_addr_align *mem_align);
-
-void hinic3_dma_free_coherent_align(void *dev_hdl,
- struct hinic3_dma_addr_align *mem_align);
-
-typedef enum hinic3_wait_return (*wait_cpl_handler)(void *priv_data);
-
-int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
- u32 wait_total_ms, u32 wait_once_us);
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
index 64139c4..4f5792f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
@@ -8,7 +8,7 @@
#include "mpu_cmd_base_defs.h"
-#define HINIC3_DRV_VERSION "15.17.1.2"
+#define HINIC3_DRV_VERSION "17.7.8.1"
#define HINIC3_DRV_DESC "Intelligent Network Interface Card Driver"
#define HIUDK_DRV_DESC "Intelligent Network Unified Driver"
@@ -45,6 +45,7 @@ enum hinic3_service_type {
SERVICE_T_CUSTOM,
SERVICE_T_VROCE,
SERVICE_T_CRYPT,
+ SERVICE_T_VSOCK,
SERVICE_T_BIFUR,
SERVICE_T_MAX,
@@ -64,6 +65,9 @@ struct nic_service_cap {
u16 max_sqs;
u16 max_rqs;
u16 default_num_queues;
+ u16 outband_vlan_cfg_en;
+ u8 lro_enable;
+ u8 rsvd1[3];
};
struct ppa_service_cap {
@@ -909,6 +913,13 @@ int hinic3_get_mgmt_version(void *hwdev, u8 *mgmt_ver, u8 version_size,
int hinic3_get_fw_version(void *hwdev, struct hinic3_fw_version *fw_ver,
u16 channel);
+/* *
+ * @brief hinic3_get_bond_create_mode - get bond create mode
+ * @param hwdev: device pointer to hwdev
+ * @retval global function id
+ */
+u8 hinic3_get_bond_create_mode(void *udkdev);
+
/* *
* @brief hinic3_global_func_id - get global function id
* @param hwdev: device pointer to hwdev
@@ -1263,4 +1274,7 @@ int hinic3_mbox_to_host_sync(void *hwdev, enum hinic3_mod_type mod,
int hinic3_get_func_vroce_enable(void *hwdev, u16 glb_func_idx, u8 *en);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type);
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
index 40ff473..1191653 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
@@ -18,9 +18,10 @@
#include "hinic3_tx.h"
#include "hinic3_dcb.h"
#include "hinic3_nic.h"
-#include "hinic3_mgmt_interface.h"
+#include "hinic3_bond.h"
+#include "nic_mpu_cmd_defs.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
typedef int (*nic_driv_module)(struct hinic3_nic_dev *nic_dev,
const void *buf_in, u32 in_size,
@@ -34,7 +35,6 @@ struct nic_drv_module_handle {
static int get_nic_drv_version(void *buf_out, const u32 *out_size)
{
struct drv_version_info *ver_info = buf_out;
- int err;
if (!buf_out) {
pr_err("Buf_out is NULL.\n");
@@ -47,10 +47,8 @@ static int get_nic_drv_version(void *buf_out, const u32 *out_size)
return -EINVAL;
}
- err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
- HINIC3_NIC_DRV_VERSION, "2023-05-17_19:56:38");
- if (err < 0)
- return -EINVAL;
+ snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
+ HINIC3_NIC_DRV_VERSION, "2025-05-08_00:00:08");
return 0;
}
@@ -126,7 +124,8 @@ static int get_tx_wqe_info(struct hinic3_nic_dev *nic_dev,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -178,7 +177,8 @@ static int get_rx_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
rq_info->delta = (u16)nic_dev->rxqs[q_id].delta;
- rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx & nic_dev->rxqs[q_id].q_mask);
+ rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx &
+ nic_dev->rxqs[q_id].q_mask);
rq_info->sw_pi = nic_dev->rxqs[q_id].next_to_update;
rq_info->msix_vector = nic_dev->rxqs[q_id].irq_id;
@@ -201,7 +201,8 @@ static int get_rx_wqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -230,7 +231,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EFAULT;
}
- if (!buf_in || !buf_out) {
+ if (!buf_in || !buf_out || !out_size) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Buf_in or buf_out is NULL.\n");
return -EINVAL;
@@ -243,7 +244,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EINVAL;
}
- if (!out_size || *out_size != sizeof(struct hinic3_rq_cqe)) {
+ if (*out_size != sizeof(struct hinic3_rq_cqe)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(struct hinic3_rq_cqe));
@@ -252,10 +253,12 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
q_id = (u16)info->q_id;
idx = (u16)info->wqe_id;
- if (q_id >= nic_dev->q_params.num_qps || idx >= nic_dev->rxqs[q_id].q_depth) {
+ if (q_id >= nic_dev->q_params.num_qps ||
+ idx >= nic_dev->rxqs[q_id].q_depth) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid q_id[%u] >= %u, or wqe idx[%u] >= %u.\n",
- q_id, nic_dev->q_params.num_qps, idx, nic_dev->rxqs[q_id].q_depth);
+ q_id, nic_dev->q_params.num_qps, idx,
+ nic_dev->rxqs[q_id].q_depth);
return -EFAULT;
}
@@ -338,7 +341,8 @@ static int set_loopback_mode(struct hinic3_nic_dev *nic_dev, const void *buf_in,
err = hinic3_set_loopback_mode(nic_dev->hwdev, (u8)mode->loop_mode,
(u8)mode->loop_ctrl);
if (err == 0)
- nicif_info(nic_dev, drv, nic_dev->netdev, "Set loopback mode %u en %u succeed\n",
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Set loopback mode %u en %u succeed\n",
mode->loop_mode, mode->loop_ctrl);
return err;
@@ -417,6 +421,59 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
{
u32 pf_bw_limit;
int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
+
+ if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To set VF bandwidth rate, please use ip link cmd\n");
+ return -EINVAL;
+ }
+
+ if (!buf_in || !buf_out || in_size != sizeof(u32) ||
+ !out_size || *out_size != sizeof(u8))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_TX;
+ pf_bw_limit = *((u32 *)buf_in);
+
+ err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
+ if (err) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %u%%\n",
+ pf_bw_limit);
+ if (err < 0)
+ return err;
+ }
+
+ *((u8 *)buf_out) = (u8)err;
+
+ return 0;
+}
+
+static int set_rx_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ u32 pf_bw_limit;
+ int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
nicif_err(nic_dev, drv, nic_dev->netdev, "To set VF bandwidth rate, please use ip link cmd\n");
@@ -426,11 +483,16 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || !buf_out || in_size != sizeof(u32) || !out_size || *out_size != sizeof(u8))
return -EINVAL;
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_RX;
pf_bw_limit = *((u32 *)buf_in);
err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %d%%\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to set pf bandwidth limit to %d%%\n",
pf_bw_limit);
if (err < 0)
return err;
@@ -445,19 +507,21 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
struct hinic3_nic_io *nic_io = NULL;
+ u32 *rate_limit = (u32 *)buf_out;
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "To get VF bandwidth rate, please use ip link cmd\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To get VF bandwidth rate, please use ip link cmd\n");
return -EINVAL;
}
if (!buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(u32)) {
+ if (*out_size != sizeof(u32) * 2) { // 2:Stored in an array, TX and RX, both length are u32
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user: %d, expect: %lu\n",
- *out_size, sizeof(u32));
+ *out_size, sizeof(u32) * 2);
return -EFAULT;
}
@@ -465,8 +529,12 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!nic_io)
return -EINVAL;
- *((u32 *)buf_out) = nic_io->nic_cfg.pf_bw_limit;
+ rate_limit[HINIC3_NIC_RX] = nic_io->nic_cfg.pf_bw_rx_limit;
+ rate_limit[HINIC3_NIC_TX] = nic_io->nic_cfg.pf_bw_tx_limit;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "read rate cfg success rx rate is: %u, tx rate is : %u\n",
+ rate_limit[HINIC3_NIC_RX], rate_limit[HINIC3_NIC_TX]);
return 0;
}
@@ -477,8 +545,8 @@ static int get_sset_count(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || in_size != sizeof(u32) || !out_size ||
*out_size != sizeof(u32) || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
@@ -504,16 +572,16 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
int err;
if (!buf_in || in_size != sizeof(u32) || !out_size || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
size = sizeof(u32);
err = get_sset_count(nic_dev, buf_in, in_size, &count, &size);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Get sset count failed, ret=%d\n",
- err);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Get sset count failed, ret=%d\n", err);
return -EINVAL;
}
if (count * sizeof(*items) != *out_size) {
@@ -527,12 +595,14 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
switch (sset) {
case HINIC3_SHOW_SSET_IO_STATS:
- hinic3_get_io_stats(nic_dev, items);
+ err = hinic3_get_io_stats(nic_dev, items);
+ if (err < 0)
+ return -EINVAL;
break;
default:
- nicif_err(nic_dev, drv, nic_dev->netdev, "Unknown %u to get stats\n",
- sset);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unknown %u to get stats\n", sset);
err = -EINVAL;
break;
}
@@ -544,15 +614,18 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int i;
u8 cos_num = 0, valid_cos_bitmap = 0;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_PCP2COS) {
for (i = 0; i < NIC_DCB_UP_MAX; i++) {
- if (!(nic_dev->func_dft_cos_bitmap & BIT(qos_in->pcp2cos[i]))) {
+ if (!(dcb->func_dft_cos_bitmap &
+ BIT(qos_in->pcp2cos[i]))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- qos_in->pcp2cos[i], nic_dev->func_dft_cos_bitmap);
+ qos_in->pcp2cos[i],
+ dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -562,7 +635,8 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
}
- memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos, sizeof(qos_in->pcp2cos));
+ memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos,
+ sizeof(qos_in->pcp2cos));
wanted_dcb_cfg->pcp_user_cos_num = cos_num;
wanted_dcb_cfg->pcp_valid_cos_map = valid_cos_bitmap;
}
@@ -572,12 +646,14 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = 0;
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++) {
u8 cos = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->wanted_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ dcb->wanted_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
- if (cos >= NIC_DCB_UP_MAX || !(nic_dev->func_dft_cos_bitmap & BIT(cos))) {
+ if (cos >= NIC_DCB_UP_MAX ||
+ !(dcb->func_dft_cos_bitmap & BIT(cos))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- cos, nic_dev->func_dft_cos_bitmap);
+ cos, dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -588,8 +664,10 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- wanted_dcb_cfg->dscp2cos[i] = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->hw_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ wanted_dcb_cfg->dscp2cos[i] =
+ qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
+ dcb->hw_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
wanted_dcb_cfg->dscp_user_cos_num = cos_num;
wanted_dcb_cfg->dscp_valid_cos_map = valid_cos_bitmap;
}
@@ -601,11 +679,12 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int ret;
u8 cos_num, valid_cos_bitmap;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_TRUST) {
- if (qos_in->trust > DCB_DSCP) {
+ if (qos_in->trust > HINIC3_DCB_DSCP) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid trust=%u\n", qos_in->trust);
return -EINVAL;
@@ -615,7 +694,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
}
if (qos_in->cfg_bitmap & CMD_QOS_DEV_DFT_COS) {
- if (!(BIT(qos_in->dft_cos) & nic_dev->func_dft_cos_bitmap)) {
+ if (!(BIT(qos_in->dft_cos) & dcb->func_dft_cos_bitmap)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid dft_cos=%u\n", qos_in->dft_cos);
return -EINVAL;
@@ -628,7 +707,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
if (ret)
return ret;
- if (wanted_dcb_cfg->trust == DCB_PCP) {
+ if (wanted_dcb_cfg->trust == HINIC3_DCB_PCP) {
cos_num = wanted_dcb_cfg->pcp_user_cos_num;
valid_cos_bitmap = wanted_dcb_cfg->pcp_valid_cos_map;
} else {
@@ -636,18 +715,11 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = wanted_dcb_cfg->dscp_valid_cos_map;
}
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "DCB is on, cos num should not more than channel num:%u\n",
- nic_dev->q_params.num_qps);
- return -EOPNOTSUPP;
- }
- }
-
if (!(BIT(wanted_dcb_cfg->default_cos) & valid_cos_bitmap)) {
- nicif_info(nic_dev, drv, nic_dev->netdev, "Current default_cos=%u, change to %u\n",
- wanted_dcb_cfg->default_cos, (u8)fls(valid_cos_bitmap) - 1);
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Current default_cos=%u, change to %u\n",
+ wanted_dcb_cfg->default_cos,
+ (u8)fls(valid_cos_bitmap) - 1);
wanted_dcb_cfg->default_cos = (u8)fls(valid_cos_bitmap) - 1;
}
@@ -657,6 +729,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_dev_cfg *qos_in = buf_in;
struct hinic3_mt_qos_dev_cfg *qos_out = buf_out;
u8 i;
@@ -675,9 +748,10 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(qos_out, qos_in, sizeof(*qos_in));
qos_out->head.status = 0;
if (qos_in->op_code & MT_DCB_OPCODE_WR) {
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg,
+ memcpy(&dcb->wanted_dcb_cfg, &dcb->hw_dcb_cfg,
sizeof(struct hinic3_dcb_config));
- err = update_wanted_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg, qos_in);
+ err = update_wanted_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg,
+ qos_in);
if (err) {
qos_out->head.status = MT_EINVAL;
return 0;
@@ -687,12 +761,12 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
qos_out->head.status = MT_EIO;
} else {
- qos_out->dft_cos = nic_dev->hw_dcb_cfg.default_cos;
- qos_out->trust = nic_dev->hw_dcb_cfg.trust;
+ qos_out->dft_cos = dcb->hw_dcb_cfg.default_cos;
+ qos_out->trust = dcb->hw_dcb_cfg.trust;
for (i = 0; i < NIC_DCB_UP_MAX; i++)
- qos_out->pcp2cos[i] = nic_dev->hw_dcb_cfg.pcp2cos[i];
+ qos_out->pcp2cos[i] = dcb->hw_dcb_cfg.pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- qos_out->dscp2cos[i] = nic_dev->hw_dcb_cfg.dscp2cos[i];
+ qos_out->dscp2cos[i] = dcb->hw_dcb_cfg.dscp2cos[i];
}
return 0;
@@ -721,27 +795,17 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(dcb_out, dcb_in, sizeof(*dcb_in));
dcb_out->head.status = 0;
if (dcb_in->op_code & MT_DCB_OPCODE_WR) {
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) == dcb_in->state)
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ==
+ dcb_in->state)
return 0;
- if (dcb_in->state) {
- if (user_cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "cos num %u should not more than channel num %u\n",
- user_cos_num,
- nic_dev->q_params.num_qps);
-
- return -EOPNOTSUPP;
- }
- }
-
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? user_cos_num : 0,
+ err = hinic3_setup_cos(nic_dev->netdev,
+ dcb_in->state ? user_cos_num : 0,
netif_run);
if (err)
goto setup_cos_fail;
@@ -751,7 +815,6 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
goto vport_up_fail;
}
- rtnl_unlock();
} else {
dcb_out->state = !!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
}
@@ -759,12 +822,12 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
vport_up_fail:
- hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num,
+ netif_run);
setup_cos_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
return err;
}
@@ -772,13 +835,15 @@ setup_cos_fail:
static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_cos_cfg *cos_cfg_in = buf_in;
struct hinic3_mt_qos_cos_cfg *cos_cfg_out = buf_out;
if (!buf_in || !buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(*cos_cfg_out) || in_size != sizeof(*cos_cfg_in)) {
+ if (*out_size != sizeof(*cos_cfg_out) ||
+ in_size != sizeof(*cos_cfg_in)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
in_size, *out_size, sizeof(*cos_cfg_in));
@@ -789,9 +854,9 @@ static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
cos_cfg_out->head.status = 0;
cos_cfg_out->port_id = hinic3_physical_port_id(nic_dev->hwdev);
- cos_cfg_out->func_cos_bitmap = (u8)nic_dev->func_dft_cos_bitmap;
- cos_cfg_out->port_cos_bitmap = (u8)nic_dev->port_dft_cos_bitmap;
- cos_cfg_out->func_max_cos_num = nic_dev->cos_config_num_max;
+ cos_cfg_out->func_cos_bitmap = (u8)dcb->func_dft_cos_bitmap;
+ cos_cfg_out->port_cos_bitmap = (u8)dcb->port_dft_cos_bitmap;
+ cos_cfg_out->func_max_cos_num = dcb->cos_config_num_max;
return 0;
}
@@ -803,7 +868,13 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
intr_num = hinic3_intr_num(nic_dev->hwdev);
- if (!buf_out || !out_size || *out_size != sizeof(u16)) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != sizeof(u16)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(u16));
@@ -817,7 +888,13 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
static int get_netdev_name(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- if (!buf_out || !out_size || *out_size != IFNAMSIZ) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != IFNAMSIZ) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %u\n",
*out_size, IFNAMSIZ);
@@ -829,8 +906,9 @@ static int get_netdev_name(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
}
-static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
int *tx_timeout = buf_out;
@@ -839,7 +917,8 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (*out_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, out_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, out_size: %u, expect: %lu\n",
*out_size, sizeof(int));
return -EINVAL;
}
@@ -849,8 +928,9 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return 0;
}
-static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
const int *tx_timeout = buf_in;
@@ -859,13 +939,15 @@ static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (in_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, in_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, in_size: %u, expect: %lu\n",
in_size, sizeof(int));
return -EINVAL;
}
net_dev->watchdog_timeo = *tx_timeout * HZ;
- nicif_info(nic_dev, drv, net_dev, "Set tx timeout check period to %ds\n", *tx_timeout);
+ nicif_info(nic_dev, drv, net_dev,
+ "Set tx timeout check period to %ds\n", *tx_timeout);
return 0;
}
@@ -891,6 +973,34 @@ static int get_xsfp_present(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
}
+static int get_xsfp_tlv_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info = buf_out;
+ const struct tag_mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req = buf_in;
+ int err;
+
+ if (!buf_in || !buf_out || !out_size)
+ return -EINVAL;
+
+ if (*out_size != sizeof(*sfp_tlv_info) ||
+ in_size != sizeof(*sfp_tlv_info_req)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
+ in_size, *out_size, sizeof(*sfp_tlv_info));
+ return -EINVAL;
+ }
+
+ err = hinic3_get_sfp_tlv_info(nic_dev->hwdev,
+ sfp_tlv_info, sfp_tlv_info_req);
+ if (err != 0) {
+ sfp_tlv_info->head.status = MT_EIO;
+ return 0;
+ }
+
+ return 0;
+}
+
static int get_xsfp_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
@@ -928,7 +1038,7 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{GET_LOOPBACK_MODE, get_loopback_mode},
{SET_LOOPBACK_MODE, set_loopback_mode},
{SET_LINK_MODE, set_link_mode},
- {SET_PF_BW_LIMIT, set_pf_bw_limit},
+ {SET_TX_PF_BW_LIMIT, set_pf_bw_limit},
{GET_PF_BW_LIMIT, get_pf_bw_limit},
{GET_SSET_COUNT, get_sset_count},
{GET_SSET_ITEMS, get_sset_stats},
@@ -940,17 +1050,22 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{SET_TX_TIMEOUT, set_netdev_tx_timeout},
{GET_XSFP_PRESENT, get_xsfp_present},
{GET_XSFP_INFO, get_xsfp_info},
+ {GET_XSFP_INFO_COMP_CMIS, get_xsfp_tlv_info},
+ {SET_RX_PF_BW_LIMIT, set_rx_pf_bw_limit}
};
static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
u32 cmd, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(nic_driv_module_cmd_handle) /
- sizeof(nic_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(nic_driv_module_cmd_handle) /
+ sizeof(nic_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type = (enum driver_cmd_type)cmd;
int err = 0;
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_lock();
+
mutex_lock(&nic_dev->nic_mutex);
for (index = 0; index < num_cmds; index++) {
if (cmd_type ==
@@ -963,6 +1078,9 @@ static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
}
mutex_unlock(&nic_dev->nic_mutex);
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_unlock();
+
if (index == num_cmds) {
pr_err("Can't find callback for %d\n", cmd_type);
return -EINVAL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
index a1fb4af..603a2ab 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
@@ -24,82 +24,80 @@
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_user_cos_num;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_user_cos_num;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_user_cos_num;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_user_cos_num;
return 0;
}
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_valid_cos_map;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_valid_cos_map;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_valid_cos_map;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_valid_cos_map;
return 0;
}
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
- u8 i, remainder, num_sq_per_cos, cur_cos_num = 0;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ struct hinic3_dcb_config *wanted_dcb_cfg =
+ &nic_dev->dcb->wanted_dcb_cfg;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
+ u8 cos_qp_num, cos_qp_offset = 0;
+ u8 i, remainder, num_qp_per_cos;
- if (num_cos == 0)
- return;
-
- num_sq_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
- if (num_sq_per_cos == 0)
+ if (num_cos == 0 || nic_dev->q_params.num_qps == 0)
return;
- remainder = nic_dev->q_params.num_qps % num_sq_per_cos;
+ num_qp_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
+ remainder = nic_dev->q_params.num_qps % num_cos;
- memset(dcb_cfg->cos_qp_offset, 0, sizeof(dcb_cfg->cos_qp_offset));
- memset(dcb_cfg->cos_qp_num, 0, sizeof(dcb_cfg->cos_qp_num));
+ memset(hw_dcb_cfg->cos_qp_offset, 0, sizeof(hw_dcb_cfg->cos_qp_offset));
+ memset(hw_dcb_cfg->cos_qp_num, 0, sizeof(hw_dcb_cfg->cos_qp_num));
for (i = 0; i < PCP_MAX_UP; i++) {
if (BIT(i) & valid_cos_map) {
- u8 cos_qp_num = num_sq_per_cos;
- u8 cos_qp_offset = (u8)(cur_cos_num * num_sq_per_cos);
-
- if (cur_cos_num < remainder) {
- cos_qp_num++;
- cos_qp_offset += cur_cos_num;
- } else {
- cos_qp_offset += remainder;
- }
-
- cur_cos_num++;
- valid_cos_map -= (u8)BIT(i);
+ cos_qp_num = num_qp_per_cos + ((remainder > 0) ?
+ (remainder--, 1) : 0);
- dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
- dcb_cfg->cos_qp_num[i] = cos_qp_num;
+ hw_dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
+ hw_dcb_cfg->cos_qp_num[i] = cos_qp_num;
hinic3_info(nic_dev, drv, "cos %u, cos_qp_offset=%u cos_qp_num=%u\n",
i, cos_qp_offset, cos_qp_num);
+
+ cos_qp_offset += cos_qp_num;
+ valid_cos_map -= (u8)BIT(i);
}
}
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_offset, dcb_cfg->cos_qp_offset,
- sizeof(dcb_cfg->cos_qp_offset));
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_num, dcb_cfg->cos_qp_num,
- sizeof(dcb_cfg->cos_qp_num));
+ memcpy(wanted_dcb_cfg->cos_qp_offset, hw_dcb_cfg->cos_qp_offset,
+ sizeof(hw_dcb_cfg->cos_qp_offset));
+ memcpy(wanted_dcb_cfg->cos_qp_num, hw_dcb_cfg->cos_qp_num,
+ sizeof(hw_dcb_cfg->cos_qp_num));
}
void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
u8 i;
u16 start_qid, q_num;
hinic3_set_txq_cos(nic_dev, 0, nic_dev->q_params.num_qps,
- nic_dev->hw_dcb_cfg.default_cos);
+ hw_dcb_cfg->default_cos);
if (!dcb_en)
return;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- q_num = (u16)nic_dev->hw_dcb_cfg.cos_qp_num[i];
+ q_num = (u16)hw_dcb_cfg->cos_qp_num[i];
if (q_num) {
- start_qid = (u16)nic_dev->hw_dcb_cfg.cos_qp_offset[i];
+ start_qid = (u16)hw_dcb_cfg->cos_qp_offset[i];
hinic3_set_txq_cos(nic_dev, start_qid, q_num, i);
hinic3_info(nic_dev, drv, "update tx db cos, start_qid %u, q_num=%u cos=%u\n",
@@ -110,30 +108,28 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ struct hinic3_dcb_config *hw_dcb_cfg = &dcb->hw_dcb_cfg;
struct hinic3_dcb_state dcb_state = {0};
u8 i;
int err;
-
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- /* VF does not support DCB, use the default cos */
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
-
- return 0;
- }
+ u32 pcp2cos_size = sizeof(dcb_state.pcp2cos);
+ u32 dscp2cos_size = sizeof(dcb_state.dscp2cos);
dcb_state.dcb_on = dcb_en;
- dcb_state.default_cos = dcb_cfg->default_cos;
- dcb_state.trust = dcb_cfg->trust;
+ dcb_state.default_cos = hw_dcb_cfg->default_cos;
+ dcb_state.trust = hw_dcb_cfg->trust;
if (dcb_en) {
for (i = 0; i < NIC_DCB_COS_MAX; i++)
- dcb_state.pcp2cos[i] = dcb_cfg->pcp2cos[i];
+ dcb_state.pcp2cos[i] = hw_dcb_cfg->pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- dcb_state.dscp2cos[i] = dcb_cfg->dscp2cos[i];
+ dcb_state.dscp2cos[i] = hw_dcb_cfg->dscp2cos[i];
} else {
- memset(dcb_state.pcp2cos, dcb_cfg->default_cos, sizeof(dcb_state.pcp2cos));
- memset(dcb_state.dscp2cos, dcb_cfg->default_cos, sizeof(dcb_state.dscp2cos));
+ memset(dcb_state.pcp2cos, hw_dcb_cfg->default_cos,
+ pcp2cos_size);
+ memset(dcb_state.dscp2cos, hw_dcb_cfg->default_cos,
+ dscp2cos_size);
}
err = hinic3_set_dcb_state(nic_dev->hwdev, &dcb_state);
@@ -143,7 +139,7 @@ static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
return err;
}
-static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
int err;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
@@ -169,11 +165,13 @@ static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
goto rx_configure_fail;
}
- if (dcb_en)
+ if (dcb_en) {
set_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
- else
+ set_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ } else {
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
-
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ }
return 0;
rx_configure_fail:
hinic3_set_tx_cos_state(nic_dev, dcb_en ? 0 : 1);
@@ -188,6 +186,7 @@ set_tx_cos_fail:
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err;
if (cos && test_bit(HINIC3_SAME_RXTX, &nic_dev->flags)) {
@@ -195,9 +194,10 @@ int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
return -EOPNOTSUPP;
}
- if (cos > nic_dev->cos_config_num_max) {
- nicif_err(nic_dev, drv, netdev, "Invalid num_tc: %u, max cos: %u\n",
- cos, nic_dev->cos_config_num_max);
+ if (cos > dcb->cos_config_num_max) {
+ nicif_err(nic_dev, drv, netdev,
+ "Invalid num_tc: %u, max cos: %u\n",
+ cos, dcb->cos_config_num_max);
return -EINVAL;
}
@@ -223,36 +223,48 @@ static u8 get_cos_num(u8 hw_valid_cos_bitmap)
static void hinic3_sync_dcb_cfg(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dcb_config *dcb_cfg)
{
- struct hinic3_dcb_config *hw_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
- memcpy(hw_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(hw_dcb_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
}
static int init_default_dcb_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *dcb_cfg)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 i, hw_dft_cos_map, port_cos_bitmap, dscp_ind;
int err;
+ int is_in_kexec;
- err = hinic3_cos_valid_bitmap(nic_dev->hwdev, &hw_dft_cos_map, &port_cos_bitmap);
+ err = hinic3_cos_valid_bitmap(nic_dev->hwdev,
+ &hw_dft_cos_map, &port_cos_bitmap);
if (err) {
hinic3_err(nic_dev, drv, "None cos supported\n");
return -EFAULT;
}
- nic_dev->func_dft_cos_bitmap = hw_dft_cos_map;
- nic_dev->port_dft_cos_bitmap = port_cos_bitmap;
- nic_dev->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+ is_in_kexec = vram_get_kexec_flag();
- dcb_cfg->trust = DCB_PCP;
- dcb_cfg->pcp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->dscp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
+ dcb->func_dft_cos_bitmap = hw_dft_cos_map;
+ dcb->port_dft_cos_bitmap = port_cos_bitmap;
+
+ dcb->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+
+ if (is_in_kexec == 0) {
+ dcb_cfg->trust = HINIC3_DCB_PCP;
+ dcb_cfg->default_cos = (u8)fls(dcb->func_dft_cos_bitmap) - 1;
+ } else {
+ dcb_cfg->trust = nic_dev->dcb->hw_dcb_cfg.trust;
+ dcb_cfg->default_cos = nic_dev->dcb->hw_dcb_cfg.default_cos;
+ }
+ dcb_cfg->pcp_user_cos_num = dcb->cos_config_num_max;
+ dcb_cfg->dscp_user_cos_num = dcb->cos_config_num_max;
dcb_cfg->pcp_valid_cos_map = hw_dft_cos_map;
dcb_cfg->dscp_valid_cos_map = hw_dft_cos_map;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i) ? i : dcb_cfg->default_cos;
+ dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i) ?
+ i : (u8)fls(dcb->func_dft_cos_bitmap) - 1;
for (dscp_ind = 0; dscp_ind < NIC_DCB_COS_MAX; dscp_ind++)
dcb_cfg->dscp2cos[i * NIC_DCB_DSCP_NUM + dscp_ind] = dcb_cfg->pcp2cos[i];
}
@@ -276,58 +288,115 @@ int hinic3_configure_dcb(struct net_device *netdev)
int err;
err = hinic3_sync_dcb_state(nic_dev->hwdev, 1,
- test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)
+ ? 1 : 0);
if (err) {
hinic3_err(nic_dev, drv, "Set dcb state failed\n");
return err;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ hinic3_sync_dcb_cfg(nic_dev, &nic_dev->dcb->wanted_dcb_cfg);
else
hinic3_dcb_reset_hw_config(nic_dev);
return 0;
}
+static int hinic3_dcb_alloc(struct hinic3_nic_dev *nic_dev)
+{
+ u16 func_id;
+ int is_use_vram;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(nic_dev->dcb_name, VRAM_NAME_MAX_LEN,
+ "%s%hu%s", VRAM_CQM_GLB_FUNC_BASE, func_id,
+ VRAM_NIC_DCB);
+
+ nic_dev->dcb = (struct hinic3_dcb *)hi_vram_kalloc(nic_dev->dcb_name,
+ sizeof(*nic_dev->dcb));
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to vram alloc dcb.\n");
+ return -EFAULT;
+ }
+ } else {
+ nic_dev->dcb = kzalloc(sizeof(*nic_dev->dcb), GFP_KERNEL);
+ if (!nic_dev->dcb)
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static void hinic3_dcb_free(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram)
+ hi_vram_kfree((void *)nic_dev->dcb, nic_dev->dcb_name,
+ sizeof(*nic_dev->dcb));
+ else
+ kfree(nic_dev->dcb);
+ nic_dev->dcb = NULL;
+}
+
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
+ hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+
+ hinic3_dcb_free(nic_dev);
+}
+
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = NULL;
int err;
u8 dcb_en = test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0;
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- return hinic3_set_tx_cos_state(nic_dev, dcb_en);
+ err = hinic3_dcb_alloc(nic_dev);
+ if (err != 0) {
+ hinic3_err(nic_dev, drv, "Dcb alloc failed.\n");
+ return err;
+ }
- err = init_default_dcb_cfg(nic_dev, dcb_cfg);
+ hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ err = init_default_dcb_cfg(nic_dev, hw_dcb_cfg);
if (err) {
- hinic3_err(nic_dev, drv, "Initialize dcb configuration failed\n");
+ hinic3_err(nic_dev, drv,
+ "Initialize dcb configuration failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&nic_dev->dcb->wanted_dcb_cfg, hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
hinic3_info(nic_dev, drv, "Support num cos %u, default cos %u\n",
- nic_dev->cos_config_num_max, dcb_cfg->default_cos);
+ nic_dev->dcb->cos_config_num_max, hw_dcb_cfg->default_cos);
err = hinic3_set_tx_cos_state(nic_dev, dcb_en);
if (err) {
hinic3_err(nic_dev, drv, "Set tx cos state failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- sema_init(&nic_dev->dcb_sem, 1);
-
return 0;
}
-static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dcb_config *dcb_cfg)
+static int change_qos_cfg(struct hinic3_nic_dev *nic_dev,
+ const struct hinic3_dcb_config *dcb_cfg)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err = 0;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags)) {
+ if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags)) {
nicif_warn(nic_dev, drv, netdev,
"Cos_up map setting in inprocess, please try again later\n");
return -EFAULT;
@@ -337,40 +406,44 @@ static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dc
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
- clear_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags);
+ clear_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags);
return err;
}
int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err, rollback_err;
u8 netif_run = 0;
struct hinic3_dcb_config old_dcb_cfg;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- memcpy(&old_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&old_dcb_cfg, &dcb->hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
- if (!memcmp(&nic_dev->wanted_dcb_cfg, &old_dcb_cfg, sizeof(struct hinic3_dcb_config))) {
+ if (!memcmp(&dcb->wanted_dcb_cfg, &old_dcb_cfg,
+ sizeof(struct hinic3_dcb_config))) {
nicif_info(nic_dev, drv, nic_dev->netdev,
"Same valid up bitmap, don't need to change anything\n");
return 0;
}
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = change_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ err = change_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Set cos_up map to hw failed\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Set cos_up map to hw failed\n");
goto change_qos_cfg_fail;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- err = hinic3_setup_cos(nic_dev->netdev, user_cos_num, netif_run);
+ err = hinic3_setup_cos(nic_dev->netdev,
+ user_cos_num, netif_run);
if (err)
goto set_err;
}
@@ -381,13 +454,12 @@ int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
goto vport_up_fail;
}
- rtnl_unlock();
-
return 0;
vport_up_fail:
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_setup_cos(nic_dev->netdev, user_cos_num ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, user_cos_num
+ ? 0 : user_cos_num, netif_run);
set_err:
rollback_err = change_qos_cfg(nic_dev, &old_dcb_cfg);
@@ -399,7 +471,5 @@ change_qos_cfg_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
-
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
index 7987f56..e0b35cb 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
@@ -24,11 +24,6 @@ struct hinic3_tc_cfg {
u16 rsvd;
};
-enum HINIC3_DCB_TRUST {
- DCB_PCP,
- DCB_DSCP,
-};
-
#define PCP_MAX_UP 8
#define DSCP_MAC_UP 64
#define DBG_DFLT_DSCP_VAL 0xFF
@@ -50,6 +45,7 @@ struct hinic3_dcb_config {
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev);
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev);
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev);
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev);
void hinic3_dcb_reset_hw_config(struct hinic3_nic_dev *nic_dev);
int hinic3_configure_dcb(struct net_device *netdev);
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run);
@@ -75,4 +71,5 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos);
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev);
int hinic3_vport_up(struct hinic3_nic_dev *nic_dev);
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
index 5a19959..e5e5578 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
@@ -56,9 +56,8 @@ static void hinic3_get_drvinfo(struct net_device *netdev,
return;
}
- err = snprintf(info->fw_version, sizeof(info->fw_version), "%s", mgmt_ver);
- if (err < 0)
- nicif_err(nic_dev, drv, netdev, "Failed to snprintf fw version\n");
+ snprintf(info->fw_version, sizeof(info->fw_version),
+ "%s", mgmt_ver);
}
static u32 hinic3_get_msglevel(struct net_device *netdev)
@@ -86,7 +85,8 @@ static int hinic3_nway_reset(struct net_device *netdev)
while (test_and_set_bit(HINIC3_AUTONEG_RESET, &nic_dev->flags))
msleep(100); /* sleep 100 ms, waiting for another autoneg restart progress done */
- err = hinic3_get_port_info(nic_dev->hwdev, &port_info, HINIC3_CHANNEL_NIC);
+ err = hinic3_get_port_info(nic_dev->hwdev, &port_info,
+ HINIC3_CHANNEL_NIC);
if (err) {
nicif_err(nic_dev, drv, netdev, "Get port info failed\n");
err = -EFAULT;
@@ -273,7 +273,7 @@ static int get_coalesce(struct net_device *netdev,
static int set_queue_coalesce(struct hinic3_nic_dev *nic_dev, u16 q_id,
struct hinic3_intr_coal_info *coal)
{
- struct hinic3_intr_coal_info *intr_coal;
+ struct hinic3_intr_coal_info *intr_coal = NULL;
struct interrupt_info info = {0};
struct net_device *netdev = nic_dev->netdev;
int err;
@@ -367,24 +367,11 @@ static int is_coalesce_exceed_limit(struct net_device *netdev,
return 0;
}
-static int is_coalesce_legal(struct net_device *netdev,
- const struct ethtool_coalesce *coal)
+static int is_coalesce_allowed_change(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct ethtool_coalesce tmp_coal = {0};
- int err;
-
- if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
- nicif_err(nic_dev, drv, netdev,
- "tx-usecs must be equal to rx-usecs\n");
- return -EINVAL;
- }
-
- if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
- nicif_err(nic_dev, drv, netdev,
- "tx-frames must be equal to rx-frames\n");
- return -EINVAL;
- }
tmp_coal.cmd = coal->cmd;
tmp_coal.rx_coalesce_usecs = coal->rx_coalesce_usecs;
@@ -409,6 +396,31 @@ static int is_coalesce_legal(struct net_device *netdev,
return -EOPNOTSUPP;
}
+ return 0;
+}
+
+static int is_coalesce_legal(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-usecs must be equal to rx-usecs\n");
+ return -EINVAL;
+ }
+
+ if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-frames must be equal to rx-frames\n");
+ return -EINVAL;
+ }
+
+ err = is_coalesce_allowed_change(netdev, coal);
+ if (err)
+ return err;
+
err = is_coalesce_exceed_limit(netdev, coal);
if (err)
return err;
@@ -444,8 +456,9 @@ static int is_coalesce_legal(struct net_device *netdev,
return 0;
}
-static inline void check_coalesce_align(struct hinic3_nic_dev *nic_dev, struct net_device *netdev,
- u32 item, u32 unit, char *str)
+static inline void check_coalesce_aligned(struct hinic3_nic_dev *nic_dev,
+ struct net_device *netdev,
+ u32 item, u32 unit, char *str)
{
if (item % unit)
nicif_warn(nic_dev, drv, netdev, "%s in %d units, change to %u\n",
@@ -453,10 +466,12 @@ static inline void check_coalesce_align(struct hinic3_nic_dev *nic_dev, struct n
}
#define CHECK_COALESCE_ALIGN(member, unit) \
- check_coalesce_align(nic_dev, netdev, member, unit, #member)
+ check_coalesce_aligned(nic_dev, netdev, member, unit, #member)
-static inline void check_coalesce_changed(struct hinic3_nic_dev *nic_dev, struct net_device *netdev,
- u32 item, u32 unit, u32 ori_val, char *obj_str, char *str)
+static inline void check_coalesce_changed(struct hinic3_nic_dev *nic_dev,
+ struct net_device *netdev,
+ u32 item, u32 unit, u32 ori_val,
+ char *obj_str, char *str)
{
if ((item / unit) != ori_val)
nicif_info(nic_dev, drv, netdev, "Change %s from %d to %u %s\n",
@@ -466,8 +481,10 @@ static inline void check_coalesce_changed(struct hinic3_nic_dev *nic_dev, struct
#define CHECK_COALESCE_CHANGED(member, unit, ori_val, obj_str) \
check_coalesce_changed(nic_dev, netdev, member, unit, ori_val, obj_str, #member)
-static inline void check_pkt_rate_changed(struct hinic3_nic_dev *nic_dev, struct net_device *netdev,
- u32 item, u32 ori_val, char *obj_str, char *str)
+static inline void check_pkt_rate_changed(struct hinic3_nic_dev *nic_dev,
+ struct net_device *netdev,
+ u32 item, u32 ori_val, char *obj_str,
+ char *str)
{
if (item != ori_val)
nicif_info(nic_dev, drv, netdev, "Change %s from %d to %u %s\n",
@@ -497,19 +514,10 @@ static int set_hw_coal_param(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static int set_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *coal, u16 queue)
+static void check_coalesce_align(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
- struct hinic3_intr_coal_info intr_coal = {0};
- struct hinic3_intr_coal_info *ori_intr_coal = NULL;
- u32 last_adaptive_rx;
- char obj_str[32] = {0};
- int err = 0;
-
- err = is_coalesce_legal(netdev, coal);
- if (err)
- return err;
CHECK_COALESCE_ALIGN(coal->rx_coalesce_usecs, COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal->rx_max_coalesced_frames,
@@ -522,6 +530,14 @@ static int set_coalesce(struct net_device *netdev,
COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal->rx_max_coalesced_frames_low,
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int check_coalesce_change(struct net_device *netdev,
+ u16 queue, struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info *ori_intr_coal = NULL;
+ char obj_str[32] = {0};
if (queue == COALESCE_ALL_QUEUE) {
ori_intr_coal = &nic_dev->intr_coalesce[0];
@@ -552,27 +568,54 @@ static int set_coalesce(struct net_device *netdev,
COALESCE_PENDING_LIMIT_UNIT,
ori_intr_coal->rx_pending_limt_low, obj_str);
- intr_coal.coalesce_timer_cfg =
+ return 0;
+}
+
+static void init_intr_coal_params(struct hinic3_intr_coal_info *intr_coal,
+ struct ethtool_coalesce *coal)
+{
+ intr_coal->coalesce_timer_cfg =
(u8)(coal->rx_coalesce_usecs / COALESCE_TIMER_CFG_UNIT);
- intr_coal.pending_limt = (u8)(coal->rx_max_coalesced_frames /
+ intr_coal->pending_limt = (u8)(coal->rx_max_coalesced_frames /
COALESCE_PENDING_LIMIT_UNIT);
- last_adaptive_rx = nic_dev->adaptive_rx_coal;
- nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
-
- intr_coal.pkt_rate_high = coal->pkt_rate_high;
- intr_coal.rx_usecs_high =
+ intr_coal->pkt_rate_high = coal->pkt_rate_high;
+ intr_coal->rx_usecs_high =
(u8)(coal->rx_coalesce_usecs_high / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_high =
+ intr_coal->rx_pending_limt_high =
(u8)(coal->rx_max_coalesced_frames_high /
COALESCE_PENDING_LIMIT_UNIT);
- intr_coal.pkt_rate_low = coal->pkt_rate_low;
- intr_coal.rx_usecs_low =
+ intr_coal->pkt_rate_low = coal->pkt_rate_low;
+ intr_coal->rx_usecs_low =
(u8)(coal->rx_coalesce_usecs_low / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_low =
+ intr_coal->rx_pending_limt_low =
(u8)(coal->rx_max_coalesced_frames_low /
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal, u16 queue)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info intr_coal = {0};
+ u32 last_adaptive_rx;
+ int err = 0;
+
+ err = is_coalesce_legal(netdev, coal);
+ if (err)
+ return err;
+
+ check_coalesce_align(netdev, coal);
+
+ err = check_coalesce_change(netdev, queue, coal);
+ if (err)
+ return err;
+
+ init_intr_coal_params(&intr_coal, coal);
+
+ last_adaptive_rx = nic_dev->adaptive_rx_coal;
+ nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
/* coalesce timer or pending set to zero will disable coalesce */
if (!nic_dev->adaptive_rx_coal &&
@@ -709,14 +752,16 @@ static int hinic3_set_pauseparam(struct net_device *netdev,
return -EFAULT;
}
- auto_neg = port_info.autoneg_state == PORT_CFG_AN_ON ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+ auto_neg = port_info.autoneg_state == PORT_CFG_AN_ON ?
+ AUTONEG_ENABLE : AUTONEG_DISABLE;
if (pause->autoneg != auto_neg) {
nicif_err(nic_dev, drv, netdev,
"To change autoneg please use: ethtool -s <dev> autoneg <on|off>\n");
return -EOPNOTSUPP;
}
- nic_pause.auto_neg = pause->autoneg == AUTONEG_ENABLE ? PORT_CFG_AN_ON : PORT_CFG_AN_OFF;
+ nic_pause.auto_neg = pause->autoneg == AUTONEG_ENABLE ?
+ PORT_CFG_AN_ON : PORT_CFG_AN_OFF;
nic_pause.rx_pause = (u8)pause->rx_pause;
nic_pause.tx_pause = (u8)pause->tx_pause;
@@ -768,6 +813,14 @@ static int hinic3_get_module_info(struct net_device *netdev,
modinfo->type = ETH_MODULE_SFF_8636;
modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
break;
+ case MODULE_TYPE_DSFP:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
+ case MODULE_TYPE_QSFP_CMIS:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
default:
nicif_warn(nic_dev, drv, netdev,
"Optical module unknown: 0x%x\n", sfp_type);
@@ -790,6 +843,11 @@ static int hinic3_get_module_eeprom(struct net_device *netdev,
memset(data, 0, ee->len);
err = hinic3_get_sfp_eeprom(nic_dev->hwdev, (u8 *)sfp_data, ee->len);
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(nic_dev->hwdev,
+ (u8 *)sfp_data,
+ sizeof(sfp_data));
+
if (err)
return err;
@@ -832,7 +890,8 @@ int hinic3_set_rxq_recovery_flag(struct net_device *netdev, u32 priv_flags)
if (test_and_set_bit(HINIC3_RXQ_RECOVERY, &nic_dev->flags))
return 0;
- queue_delayed_work(nic_dev->workq, &nic_dev->rxq_check_work, HZ);
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->rxq_check_work, HZ);
nicif_info(nic_dev, drv, netdev, "open rxq recovery\n");
} else {
if (!test_and_clear_bit(HINIC3_RXQ_RECOVERY, &nic_dev->flags))
@@ -888,7 +947,8 @@ static int hinic3_set_force_link_flag(struct net_device *netdev, u32 priv_flags)
nicif_info(nic_dev, link, netdev, "Set link up\n");
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, nic_dev->link_status);
+ hinic3_notify_all_vfs_link_changed(nic_dev->hwdev,
+ nic_dev->link_status);
} else {
if (!test_and_clear_bit(HINIC3_FORCE_LINK_UP, &nic_dev->flags))
return 0;
@@ -919,7 +979,8 @@ static int hinic3_set_force_link_flag(struct net_device *netdev, u32 priv_flags)
}
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, nic_dev->link_status);
+ hinic3_notify_all_vfs_link_changed(nic_dev->hwdev,
+ nic_dev->link_status);
}
return 0;
@@ -942,7 +1003,6 @@ static int hinic3_set_priv_flags(struct net_device *netdev, u32 priv_flags)
#define PORT_DOWN_ERR_IDX 0
#define LP_DEFAULT_TIME 5 /* seconds */
-#define LP_PKT_LEN 60
#define TEST_TIME_MULTIPLE 5
static int hinic3_run_lp_test(struct hinic3_nic_dev *nic_dev, u32 test_time)
@@ -1086,7 +1146,8 @@ static int do_lp_test(struct hinic3_nic_dev *nic_dev, u32 *flags, u32 test_time,
return err;
}
-static void hinic3_lp_test(struct net_device *netdev, struct ethtool_test *eth_test,
+static void hinic3_lp_test(struct net_device *netdev,
+ struct ethtool_test *eth_test,
u64 *data, u32 test_time)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
@@ -1109,7 +1170,8 @@ static void hinic3_lp_test(struct net_device *netdev, struct ethtool_test *eth_t
netif_carrier_off(netdev);
netif_tx_disable(netdev);
- err = do_lp_test(nic_dev, ð_test->flags, test_time_real, &test_index);
+ err = do_lp_test(nic_dev, ð_test->flags,
+ test_time_real, &test_index);
if (err) {
eth_test->flags |= ETH_TEST_FL_FAILED;
data[test_index] = 1;
@@ -1130,10 +1192,65 @@ static void hinic3_diag_test(struct net_device *netdev,
hinic3_lp_test(netdev, eth_test, data, 0);
}
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+static int hinic3_get_fecparam(struct net_device *netdev,
+ struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u8 advertised_fec = 0;
+ u8 supported_fec = 0;
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_GFECPARAM) {
+ nicif_err(nic_dev, drv, netdev,
+ "get fecparam cmd err.exp:0x%x,real:0x%x\n",
+ ETHTOOL_GFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = get_fecparam(nic_dev->hwdev, &advertised_fec, &supported_fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Get fec param failed\n");
+ return err;
+ }
+ fecparam->active_fec = (u32)advertised_fec;
+ fecparam->fec = (u32)supported_fec;
+
+ nicif_info(nic_dev, drv, netdev, "Get fec param success\n");
+ return 0;
+}
+
+static int hinic3_set_fecparam(struct net_device *netdev,
+ struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_SFECPARAM) {
+ nicif_err(nic_dev, drv, netdev,
+ "Set fecparam cmd err.exp:0x%x,real:0x%x\n",
+ ETHTOOL_SFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = set_fecparam(nic_dev->hwdev, (u8)fecparam->fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Set fec param failed\n");
+ return err;
+ }
+
+ nicif_info(nic_dev, drv, netdev, "Set fec param success\n");
+ return 0;
+}
+#endif
+
static const struct ethtool_ops hinic3_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1180,6 +1297,10 @@ static const struct ethtool_ops hinic3_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
@@ -1240,7 +1361,10 @@ static const struct ethtool_ops_ext hinic3_ethtool_ops_ext = {
static const struct ethtool_ops hinic3vf_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1267,6 +1391,11 @@ static const struct ethtool_ops hinic3vf_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
+
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
index b0e6aad..7f2537a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
@@ -24,11 +24,29 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
-#define FPGA_PORT_COUNTER 0
-#define EVB_PORT_COUNTER 1
-u16 mag_support_mode = EVB_PORT_COUNTER;
-module_param(mag_support_mode, ushort, 0444);
-MODULE_PARM_DESC(mag_support_mode, "Set mag port counter support mode, 0:FPGA 1:EVB, default is 1");
+#define HINIC_SET_LINK_STR_LEN 128
+#define HINIC_ETHTOOL_FEC_INFO_LEN 6
+#define HINIC_SUPPORTED_FEC_CMD 0
+#define HINIC_ADVERTISED_FEC_CMD 1
+
+struct hinic3_ethtool_fec {
+ u8 hinic_fec_offset;
+ u8 ethtool_bit_offset;
+};
+
+static struct hinic3_ethtool_fec
+ hinic3_ethtool_fec_info[HINIC_ETHTOOL_FEC_INFO_LEN] = {
+ /* The ethtool does not have the corresponding enumeration variable */
+ {PORT_FEC_NOT_SET, 0xFF},
+ {PORT_FEC_RSFEC, 0x32}, /* ETHTOOL_LINK_MODE_FEC_RS_BIT */
+ /* ETHTOOL_LINK_MODE_FEC_BASER_BIT */
+ {PORT_FEC_BASEFEC, 0x33},
+ {PORT_FEC_NOFEC, 0x31}, /* ETHTOOL_LINK_MODE_FEC_NONE_BIT */
+ /* ETHTOOL_LINK_MODE_FEC_LLRS_BIT: Available only in later versions */
+ {PORT_FEC_LLRSFEC, 0x4A},
+ /* The ethtool does not have the corresponding enumeration variable */
+ {PORT_FEC_AUTO, 0XFF}
+};
struct hinic3_stats {
char name[ETH_GSTRING_LEN];
@@ -36,9 +54,23 @@ struct hinic3_stats {
int offset;
};
+struct hinic3_netdev_link_count_str {
+ u64 link_down_events_phy;
+};
+
+#define HINIC3_NETDEV_LINK_COUNT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic3_netdev_link_count_str, _stat_item), \
+ .offset = offsetof(struct hinic3_netdev_link_count_str, _stat_item) \
+}
+
+static struct hinic3_stats hinic3_netdev_link_count[] = {
+ HINIC3_NETDEV_LINK_COUNT(link_down_events_phy),
+};
+
#define HINIC3_NETDEV_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct rtnl_link_stats64, _stat_item), \
+ .size = FIELD_SIZEOF(struct rtnl_link_stats64, _stat_item), \
.offset = offsetof(struct rtnl_link_stats64, _stat_item) \
}
@@ -67,7 +99,7 @@ static struct hinic3_stats hinic3_netdev_stats[] = {
#define HINIC3_NIC_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct hinic3_nic_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_nic_stats, _stat_item), \
.offset = offsetof(struct hinic3_nic_stats, _stat_item) \
}
@@ -84,17 +116,16 @@ static struct hinic3_stats hinic3_nic_dev_stats_extern[] = {
#define HINIC3_RXQ_STAT(_stat_item) { \
.name = "rxq%d_"#_stat_item, \
- .size = sizeof_field(struct hinic3_rxq_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_rxq_stats, _stat_item), \
.offset = offsetof(struct hinic3_rxq_stats, _stat_item) \
}
#define HINIC3_TXQ_STAT(_stat_item) { \
.name = "txq%d_"#_stat_item, \
- .size = sizeof_field(struct hinic3_txq_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_txq_stats, _stat_item), \
.offset = offsetof(struct hinic3_txq_stats, _stat_item) \
}
-/*lint -save -e786*/
static struct hinic3_stats hinic3_rx_queue_stats[] = {
HINIC3_RXQ_STAT(packets),
HINIC3_RXQ_STAT(bytes),
@@ -135,11 +166,9 @@ static struct hinic3_stats hinic3_tx_queue_stats_extern[] = {
HINIC3_TXQ_STAT(rsvd2),
};
-/*lint -restore*/
-
#define HINIC3_FUNC_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct hinic3_vport_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_vport_stats, _stat_item), \
.offset = offsetof(struct hinic3_vport_stats, _stat_item) \
}
@@ -166,7 +195,7 @@ static struct hinic3_stats hinic3_function_stats[] = {
#define HINIC3_PORT_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct mag_cmd_port_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct mag_cmd_port_stats, _stat_item), \
.offset = offsetof(struct mag_cmd_port_stats, _stat_item) \
}
@@ -260,49 +289,22 @@ static struct hinic3_stats hinic3_port_stats[] = {
HINIC3_PORT_STAT(mac_rx_unfilter_pkt_num),
};
-#define HINIC3_FGPA_PORT_STAT(_stat_item) { \
+#define HINIC3_RSFEC_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct hinic3_phy_fpga_port_stats, _stat_item), \
- .offset = offsetof(struct hinic3_phy_fpga_port_stats, _stat_item) \
+ .size = FIELD_SIZEOF(struct mag_cmd_rsfec_stats, _stat_item), \
+ .offset = offsetof(struct mag_cmd_rsfec_stats, _stat_item) \
}
-static struct hinic3_stats g_hinic3_fpga_port_stats[] = {
- HINIC3_FGPA_PORT_STAT(mac_rx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_under_frame_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_frag_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_crc_error_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_length_err_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_pause_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_unknown_mac_frame_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_underrun_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_pause_pkts_port),
+static struct hinic3_stats g_hinic3_rsfec_stats[] = {
+ HINIC3_RSFEC_STAT(rx_err_lane_phy),
};
+#define HINIC3_FGPA_PORT_STAT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic3_phy_fpga_port_stats, _stat_item), \
+ .offset = offsetof(struct hinic3_phy_fpga_port_stats, _stat_item) \
+}
+
static char g_hinic_priv_flags_strings[][ETH_GSTRING_LEN] = {
"Symmetric-RSS",
"Force-Link-up",
@@ -318,8 +320,7 @@ u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev)
(ARRAY_LEN(hinic3_tx_queue_stats) +
ARRAY_LEN(hinic3_tx_queue_stats_extern) +
ARRAY_LEN(hinic3_rx_queue_stats) +
- ARRAY_LEN(hinic3_rx_queue_stats_extern)) *
- nic_dev->max_qps;
+ ARRAY_LEN(hinic3_rx_queue_stats_extern)) * nic_dev->max_qps;
return count;
}
@@ -343,72 +344,89 @@ static int dev_stats_pack(struct hinic3_show_item *items, int len,
memcpy(items[item_idx].name, array[j].name,
HINIC3_SHOW_ITEM_LEN);
items[item_idx].hexadecimal = 0;
- items[item_idx].value = get_value_of_ptr(array[j].size,
- stats_ptr + array[j].offset);
+ items[item_idx].value =
+ get_value_of_ptr(array[j].size,
+ stats_ptr + array[j].offset);
item_idx++;
}
return item_idx;
}
-static int queue_stats_pack(struct hinic3_show_item *items, int len,
- struct hinic3_stats *array, void *stats_ptr,
- u16 qid)
+int hinic3_rx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat,
+ struct hinic3_rxq_stats *rxq_stats, u16 qid)
{
- int j;
- int item_idx = 0;
+ snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
- for (j = 0; j < len; j++) {
- memcpy(items[item_idx].name, array[j].name,
- HINIC3_SHOW_ITEM_LEN);
- snprintf(items[item_idx].name, HINIC3_SHOW_ITEM_LEN,
- array[j].name, qid);
- items[item_idx].hexadecimal = 0;
- items[item_idx].value = get_value_of_ptr(array[j].size,
- stats_ptr + array[j].offset);
- item_idx++;
- }
+ item->hexadecimal = 0;
+ item->value = get_value_of_ptr(stat->size, (char *)(rxq_stats) +
+ stat->offset);
- return item_idx;
+ return 0;
}
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
+int hinic3_tx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat,
+ struct hinic3_txq_stats *txq_stats, u16 qid)
+{
+ snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
+
+ item->hexadecimal = 0;
+ item->value = get_value_of_ptr(stat->size, (char *)(txq_stats) +
+ stat->offset);
+
+ return 0;
+}
+
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
{
struct hinic3_show_item *items = stats;
int item_idx = 0;
u16 qid;
+ int idx;
+ int ret;
- item_idx += dev_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_nic_dev_stats),
- hinic3_nic_dev_stats, &nic_dev->stats);
- item_idx += dev_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_nic_dev_stats_extern),
- hinic3_nic_dev_stats_extern,
- &nic_dev->stats);
+ dev_stats_pack(items, item_idx, hinic3_nic_dev_stats, &nic_dev->stats);
+ dev_stats_pack(items, item_idx, hinic3_nic_dev_stats_extern, &nic_dev->stats);
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_tx_queue_stats),
- hinic3_tx_queue_stats,
- &nic_dev->txqs[qid].txq_stats,
- qid);
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_tx_queue_stats_extern),
- hinic3_tx_queue_stats_extern,
- &nic_dev->txqs[qid].txq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++],
+ &hinic3_tx_queue_stats[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats_extern); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++],
+ &hinic3_tx_queue_stats_extern[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
}
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_rx_queue_stats),
- hinic3_rx_queue_stats,
- &nic_dev->rxqs[qid].rxq_stats,
- qid);
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_rx_queue_stats_extern),
- hinic3_rx_queue_stats_extern,
- &nic_dev->rxqs[qid].rxq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++],
+ &hinic3_rx_queue_stats[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats_extern); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++],
+ &hinic3_rx_queue_stats_extern[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
}
+
+ return 0;
}
static char g_hinic3_test_strings[][ETH_GSTRING_LEN] = {
@@ -428,16 +446,14 @@ int hinic3_get_sset_count(struct net_device *netdev, int sset)
q_num = nic_dev->q_params.num_qps;
count = ARRAY_LEN(hinic3_netdev_stats) +
ARRAY_LEN(hinic3_nic_dev_stats) +
+ ARRAY_LEN(hinic3_netdev_link_count) +
ARRAY_LEN(hinic3_function_stats) +
(ARRAY_LEN(hinic3_tx_queue_stats) +
- ARRAY_LEN(hinic3_rx_queue_stats)) *
- q_num;
+ ARRAY_LEN(hinic3_rx_queue_stats)) * q_num;
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER)
- count += ARRAY_LEN(g_hinic3_fpga_port_stats);
- else
- count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(g_hinic3_rsfec_stats);
}
return count;
@@ -486,9 +502,9 @@ static void get_drv_queue_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
}
}
-static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct hinic3_phy_fpga_port_stats *port_stats = NULL;
+ struct mag_cmd_port_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
@@ -496,19 +512,19 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
if (!port_stats) {
memset(&data[i], 0,
- ARRAY_LEN(g_hinic3_fpga_port_stats) * sizeof(*data));
- i += ARRAY_LEN(g_hinic3_fpga_port_stats);
+ ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
+ i += ARRAY_LEN(hinic3_port_stats);
return i;
}
- err = hinic3_get_fpga_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to get port stats from fw\n");
- for (j = 0; j < ARRAY_LEN(g_hinic3_fpga_port_stats); j++, i++) {
- p = (char *)(port_stats) + g_hinic3_fpga_port_stats[j].offset;
- data[i] = (g_hinic3_fpga_port_stats[j].size == sizeof(u64)) ?
+ for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
+ p = (char *)(port_stats) + hinic3_port_stats[j].offset;
+ data[i] = (hinic3_port_stats[j].size == sizeof(u64)) ?
*(u64 *)p :
*(u32 *)p;
}
@@ -518,34 +534,32 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
return i;
}
-static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_rsfec_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct mag_cmd_port_stats *port_stats = NULL;
+ struct mag_cmd_rsfec_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
- if (mag_support_mode == FPGA_PORT_COUNTER)
- return get_fpga_port_stats(nic_dev, data);
-
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
if (!port_stats) {
- memset(&data[i], 0,
- ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
- i += ARRAY_LEN(hinic3_port_stats);
- return i;
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to malloc port stats\n");
+ memset(&data[i], 0,
+ ARRAY_LEN(g_hinic3_rsfec_stats) * sizeof(*data));
+ i += ARRAY_LEN(g_hinic3_rsfec_stats);
+ return i;
}
- err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_rsfec_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to get port stats from fw\n");
+ "Failed to get rsfec stats from fw\n");
- for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
- p = (char *)(port_stats) + hinic3_port_stats[j].offset;
- data[i] = (hinic3_port_stats[j].size == sizeof(u64)) ?
- *(u64 *)p :
- *(u32 *)p;
+ for (j = 0; j < ARRAY_LEN(g_hinic3_rsfec_stats); j++, i++) {
+ p = (char *)(port_stats) + g_hinic3_rsfec_stats[j].offset;
+ data[i] = (g_hinic3_rsfec_stats[j].size ==
+ sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
kfree(port_stats);
@@ -569,6 +583,8 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
u16 i = 0, j = 0;
char *p = NULL;
int err;
+ int link_down_events_phy_tmp = 0;
+ struct hinic3_netdev_link_count_str link_count = {0};
#ifdef HAVE_NDO_GET_STATS64
net_stats = dev_get_stats(netdev, &temp);
@@ -586,6 +602,15 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = get_value_of_ptr(hinic3_nic_dev_stats[j].size, p);
}
+ err = hinic3_get_link_event_stats(nic_dev->hwdev,
+ &link_down_events_phy_tmp);
+
+ link_count.link_down_events_phy = (u64)link_down_events_phy_tmp;
+ for (j = 0; j < ARRAY_LEN(hinic3_netdev_link_count); j++, i++) {
+ p = (char *)(&link_count) + hinic3_netdev_link_count[j].offset;
+ data[i] = get_value_of_ptr(hinic3_netdev_link_count[j].size, p);
+ }
+
err = hinic3_get_vport_stats(nic_dev->hwdev,
hinic3_global_func_id(nic_dev->hwdev),
&vport_stats);
@@ -598,8 +623,10 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = get_value_of_ptr(hinic3_function_stats[j].size, p);
}
- if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
i += get_ethtool_port_stats(nic_dev, data + i);
+ i += get_ethtool_rsfec_stats(nic_dev, data + i);
+ }
get_drv_queue_stats(nic_dev, data + i);
}
@@ -620,6 +647,12 @@ static u16 get_drv_dev_strings(struct hinic3_nic_dev *nic_dev, char *p)
cnt++;
}
+ for (i = 0; i < ARRAY_LEN(hinic3_netdev_link_count); i++) {
+ memcpy(p, hinic3_netdev_link_count[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+
return cnt;
}
@@ -634,21 +667,16 @@ static u16 get_hw_stats_strings(struct hinic3_nic_dev *nic_dev, char *p)
}
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER) {
- for (i = 0; i < ARRAY_LEN(g_hinic3_fpga_port_stats);
- i++) {
- memcpy(p, g_hinic3_fpga_port_stats[i].name,
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
- } else {
- for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
- memcpy(p, hinic3_port_stats[i].name,
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
+ for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
+ memcpy(p, hinic3_port_stats[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+ for (i = 0; i < ARRAY_LEN(g_hinic3_rsfec_stats); i++) {
+ memcpy(p, g_hinic3_rsfec_stats[i].name,
+ ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
}
}
@@ -664,7 +692,8 @@ static u16 get_qp_stats_strings(const struct hinic3_nic_dev *nic_dev, char *p)
for (j = 0; j < ARRAY_LEN(hinic3_tx_queue_stats); j++) {
err = sprintf(p, hinic3_tx_queue_stats[j].name, i);
if (err < 0)
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to sprintf tx queue stats name, idx_qps: %u, idx_stats: %u\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to sprintf tx queue stats name, idx_qps: %u, idx_stats: %u\n",
i, j);
p += ETH_GSTRING_LEN;
cnt++;
@@ -675,7 +704,8 @@ static u16 get_qp_stats_strings(const struct hinic3_nic_dev *nic_dev, char *p)
for (j = 0; j < ARRAY_LEN(hinic3_rx_queue_stats); j++) {
err = sprintf(p, hinic3_rx_queue_stats[j].name, i);
if (err < 0)
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to sprintf rx queue stats name, idx_qps: %u, idx_stats: %u\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to sprintf rx queue stats name, idx_qps: %u, idx_stats: %u\n",
i, j);
p += ETH_GSTRING_LEN;
cnt++;
@@ -791,7 +821,6 @@ struct hw2ethtool_link_mode {
u32 speed;
};
-/*lint -save -e26 */
static const struct hw2ethtool_link_mode
hw2ethtool_link_mode_table[LINK_MODE_MAX_NUMBERS] = {
[LINK_MODE_GE] = {
@@ -851,8 +880,6 @@ static const struct hw2ethtool_link_mode
},
};
-/*lint -restore */
-
#define GET_SUPPORTED_MODE 0
#define GET_ADVERTISED_MODE 1
@@ -867,21 +894,35 @@ struct cmd_link_settings {
};
#define ETHTOOL_ADD_SUPPORTED_LINK_MODE(ecmd, mode) \
- set_bit(ETHTOOL_LINK_##mode##_BIT, (ecmd)->supported)
+ set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->supported)
#define ETHTOOL_ADD_ADVERTISED_LINK_MODE(ecmd, mode) \
- set_bit(ETHTOOL_LINK_##mode##_BIT, (ecmd)->advertising)
+ set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->advertising)
-static void ethtool_add_speed_link_mode(__ETHTOOL_DECLARE_LINK_MODE_MASK(bitmap), u32 mode)
+static void ethtool_add_supported_speed_link_mode(struct cmd_link_settings *link_settings,
+ u32 mode)
{
u32 i;
for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
- __ETHTOOL_LINK_MODE_MASK_NBITS)
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
continue;
+ set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
+ link_settings->supported);
+ }
+}
+static void ethtool_add_advertised_speed_link_mode(struct cmd_link_settings *link_settings,
+ u32 mode)
+{
+ u32 i;
+
+ for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
+ if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
+ continue;
set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
- bitmap);
+ link_settings->advertising);
}
}
@@ -912,9 +953,11 @@ hinic3_add_ethtool_link_mode(struct cmd_link_settings *link_settings,
for (link_mode = 0; link_mode < LINK_MODE_MAX_NUMBERS; link_mode++) {
if (hw_link_mode & BIT(link_mode)) {
if (name == GET_SUPPORTED_MODE)
- ethtool_add_speed_link_mode(link_settings->supported, link_mode);
+ ethtool_add_supported_speed_link_mode(link_settings,
+ link_mode);
else
- ethtool_add_speed_link_mode(link_settings->advertising, link_mode);
+ ethtool_add_advertised_speed_link_mode(
+ link_settings, link_mode);
}
}
}
@@ -937,10 +980,15 @@ static int hinic3_link_speed_set(struct hinic3_nic_dev *nic_dev,
err = hinic3_get_link_state(nic_dev->hwdev, &link_state);
if (!err && link_state) {
- link_settings->speed =
- port_info->speed < ARRAY_LEN(hw_to_ethtool_speed) ?
+ if (hinic3_get_bond_create_mode(nic_dev->hwdev)) {
+ link_settings->speed = port_info->bond_speed;
+ } else {
+ link_settings->speed =
+ port_info->speed <
+ ARRAY_LEN(hw_to_ethtool_speed) ?
hw_to_ethtool_speed[port_info->speed] :
(u32)SPEED_UNKNOWN;
+ }
link_settings->duplex = port_info->duplex;
} else {
@@ -956,28 +1004,28 @@ static void hinic3_link_port_type(struct cmd_link_settings *link_settings,
{
switch (port_type) {
case MAG_CMD_WIRE_TYPE_ELECTRIC:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_TP);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_TP);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, TP);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, TP);
link_settings->port = PORT_TP;
break;
case MAG_CMD_WIRE_TYPE_AOC:
case MAG_CMD_WIRE_TYPE_MM:
case MAG_CMD_WIRE_TYPE_SM:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_FIBRE);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_FIBRE);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, FIBRE);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, FIBRE);
link_settings->port = PORT_FIBRE;
break;
case MAG_CMD_WIRE_TYPE_COPPER:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_FIBRE);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_FIBRE);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, FIBRE);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, FIBRE);
link_settings->port = PORT_DA;
break;
case MAG_CMD_WIRE_TYPE_BACKPLANE:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_Backplane);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Backplane);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Backplane);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Backplane);
link_settings->port = PORT_NONE;
break;
@@ -1000,19 +1048,56 @@ static int get_link_pause_settings(struct hinic3_nic_dev *nic_dev,
return err;
}
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_Pause);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Pause);
if (nic_pause.rx_pause && nic_pause.tx_pause) {
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Pause);
} else if (nic_pause.tx_pause) {
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Asym_Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Asym_Pause);
} else if (nic_pause.rx_pause) {
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Pause);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Asym_Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Asym_Pause);
}
return 0;
}
+static bool is_bit_offset_defined(u8 bit_offset)
+{
+ if (bit_offset < __ETHTOOL_LINK_MODE_MASK_NBITS)
+ return true;
+ return false;
+}
+
+static void ethtool_add_supported_advertised_fec(struct cmd_link_settings *link_settings,
+ u32 fec, u8 cmd)
+{
+ u8 i;
+
+ for (i = 0; i < HINIC_ETHTOOL_FEC_INFO_LEN; i++) {
+ if ((fec & BIT(hinic3_ethtool_fec_info[i].hinic_fec_offset)) == 0)
+ continue;
+ if (is_bit_offset_defined(hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true &&
+ cmd == HINIC_ADVERTISED_FEC_CMD) {
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset,
+ link_settings->advertising);
+ return; /* There can be only one advertised fec mode. */
+ }
+ if (is_bit_offset_defined(hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true &&
+ cmd == HINIC_SUPPORTED_FEC_CMD)
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset,
+ link_settings->supported);
+ }
+}
+
+static void hinic3_link_fec_type(struct cmd_link_settings *link_settings,
+ u32 fec, u32 supported_fec)
+{
+ ethtool_add_supported_advertised_fec(link_settings, supported_fec,
+ HINIC_SUPPORTED_FEC_CMD);
+ ethtool_add_supported_advertised_fec(link_settings, fec,
+ HINIC_ADVERTISED_FEC_CMD);
+}
+
static int get_link_settings(struct net_device *netdev,
struct cmd_link_settings *link_settings)
{
@@ -1033,13 +1118,19 @@ static int get_link_settings(struct net_device *netdev,
hinic3_link_port_type(link_settings, port_info.port_type);
+ /* port_info.fec is bit offset, value is BIT(port_info.fec);
+ * but port_info.supported_fec_mode is bit value
+ */
+ hinic3_link_fec_type(link_settings, BIT(port_info.fec),
+ port_info.supported_fec_mode);
+
link_settings->autoneg = port_info.autoneg_state == PORT_CFG_AN_ON ?
AUTONEG_ENABLE :
AUTONEG_DISABLE;
if (port_info.autoneg_cap)
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_Autoneg);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Autoneg);
if (port_info.autoneg_state == PORT_CFG_AN_ON)
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Autoneg);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Autoneg);
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
err = get_link_pause_settings(nic_dev, link_settings);
@@ -1163,23 +1254,18 @@ static int hinic3_set_settings_to_hw(struct hinic3_nic_dev *nic_dev,
struct net_device *netdev = nic_dev->netdev;
struct hinic3_link_ksettings settings = { 0 };
int speed_level = 0;
- char set_link_str[128] = { 0 };
+ char set_link_str[HINIC_SET_LINK_STR_LEN] = {0};
+ char link_info[HINIC_SET_LINK_STR_LEN] = {0};
int err = 0;
- err = snprintf(set_link_str, sizeof(set_link_str) - 1, "%s",
- (bool)(set_settings & HILINK_LINK_SET_AUTONEG) ?
- ((bool)autoneg ? "autong enable " :
- "autong disable ") :
- "");
- if (err < 0)
- return -EINVAL;
+ snprintf(link_info, sizeof(link_info), "%s",
+ (bool)(set_settings & HILINK_LINK_SET_AUTONEG) ?
+ ((bool)autoneg ? "autong enable " : "autong disable ") : "");
if (set_settings & HILINK_LINK_SET_SPEED) {
speed_level = hinic3_ethtool_to_hw_speed_level(speed);
- err = snprintf(set_link_str, sizeof(set_link_str) - 1,
- "%sspeed %u ", set_link_str, speed);
- if (err < 0)
- return -EINVAL;
+ snprintf(set_link_str, sizeof(set_link_str),
+ "%sspeed %u ", link_info, speed);
}
settings.valid_bitmap = set_settings;
@@ -1218,7 +1304,8 @@ static int set_link_settings(struct net_device *netdev, u8 autoneg, u32 speed)
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
int hinic3_set_link_ksettings(struct net_device *netdev,
- const struct ethtool_link_ksettings *link_settings)
+ const
+ struct ethtool_link_ksettings *link_settings)
{
/* Only support to set autoneg and speed */
return set_link_settings(netdev, link_settings->base.autoneg,
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
index 70346d6..2daa7f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
@@ -82,7 +82,7 @@ static struct hinic3_mac_filter *hinic3_add_filter(struct hinic3_nic_dev *nic_de
struct list_head *mac_filter_list,
u8 *addr)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
@@ -117,7 +117,7 @@ static void hinic3_del_filter(struct hinic3_nic_dev *nic_dev,
static struct hinic3_mac_filter *hinic3_mac_filter_entry_clone(const struct hinic3_mac_filter *src)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
index ef8c62b..a3136ce 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
@@ -40,6 +40,7 @@ enum hinic3_channel_id {
HINIC3_CHANNEL_DSW,
HINIC3_CHANNEL_MIG,
HINIC3_CHANNEL_CRYPT,
+ HINIC3_CHANNEL_VROCE,
HINIC3_CHANNEL_MAX = 32,
};
@@ -397,6 +398,16 @@ void hinic3_free_cmd_buf(void *hwdev, struct hinic3_cmd_buf *cmd_buf);
**/
int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read clear
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+
/**
* @brief hinic3_sm_ctr_rd32 - small single 32 counter read
* @param hwdev: device pointer to hwdev
@@ -810,6 +821,13 @@ int hinic3_dbg_lt_wr_16byte_mask(void *hwdev, u8 dest, u8 instance,
*/
void hinic3_link_event_stats(void *dev, u8 link);
+/**
+ * @brief hinic3_get_link_event_stats - link event stats
+ * @param hwdev: device pointer to hwdev
+ * @param link: link status
+ */
+int hinic3_get_link_event_stats(void *dev, int *link_state);
+
/**
* @brief hinic3_get_hw_pf_infos - get pf infos
* @param hwdev: device pointer to hwdev
@@ -856,4 +874,5 @@ void hinic3_set_api_stop(void *hwdev);
int hinic3_activate_firmware(void *hwdev, u8 cfg_index);
int hinic3_switch_config(void *hwdev, u8 cfg_index);
+bool hinic3_is_optical_module_mode(void *hwdev);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
index 7e59c81..6525b76 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
@@ -47,12 +47,16 @@ static void qp_add_napi(struct hinic3_irq *irq_cfg)
netif_napi_add_weight(nic_dev->netdev, &irq_cfg->napi,
hinic3_poll, nic_dev->poll_weight);
napi_enable(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_IS_REGIN;
}
-static void qp_del_napi(struct hinic3_irq *irq_cfg)
+void qp_del_napi(struct hinic3_irq *irq_cfg)
{
- napi_disable(&irq_cfg->napi);
- netif_napi_del(&irq_cfg->napi);
+ if (irq_cfg->napi_reign == NAPI_IS_REGIN) {
+ napi_disable(&irq_cfg->napi);
+ netif_napi_del(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_NOT_REGIN;
+ }
}
static irqreturn_t qp_irq(int irq, void *data)
@@ -60,7 +64,8 @@ static irqreturn_t qp_irq(int irq, void *data)
struct hinic3_irq *irq_cfg = (struct hinic3_irq *)data;
struct hinic3_nic_dev *nic_dev = netdev_priv(irq_cfg->netdev);
- hinic3_misx_intr_clear_resend_bit(nic_dev->hwdev, irq_cfg->msix_entry_idx, 1);
+ hinic3_misx_intr_clear_resend_bit(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx, 1);
napi_schedule(&irq_cfg->napi);
@@ -95,7 +100,8 @@ static int hinic3_request_irq(struct hinic3_irq *irq_cfg, u16 q_id)
return err;
}
- err = request_irq(irq_cfg->irq_id, &qp_irq, 0, irq_cfg->irq_name, irq_cfg);
+ err = request_irq(irq_cfg->irq_id, &qp_irq, 0,
+ irq_cfg->irq_name, irq_cfg);
if (err) {
nicif_err(nic_dev, drv, irq_cfg->netdev, "Failed to request Rx irq\n");
qp_del_napi(irq_cfg);
@@ -138,12 +144,8 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev)
local_cpu = cpumask_local_spread(q_id, dev_to_node(&pdev->dev));
cpumask_set_cpu(local_cpu, &irq_cfg->affinity_mask);
- err = snprintf(irq_cfg->irq_name, sizeof(irq_cfg->irq_name),
- "%s_qp%u", nic_dev->netdev->name, q_id);
- if (err < 0) {
- err = -EINVAL;
- goto req_tx_irq_err;
- }
+ snprintf(irq_cfg->irq_name, sizeof(irq_cfg->irq_name),
+ "%s_qp%u", nic_dev->netdev->name, q_id);
err = hinic3_request_irq(irq_cfg, q_id);
if (err) {
@@ -151,20 +153,25 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev)
goto req_tx_irq_err;
}
- hinic3_set_msix_auto_mask_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ hinic3_set_msix_auto_mask_state(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx,
HINIC3_SET_MSIX_AUTO_MASK);
- hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx, HINIC3_MSIX_ENABLE);
+ hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ HINIC3_MSIX_ENABLE);
}
- INIT_DELAYED_WORK(&nic_dev->moderation_task, hinic3_auto_moderation_work);
+ INIT_DELAYED_WORK(&nic_dev->moderation_task,
+ hinic3_auto_moderation_work);
return 0;
req_tx_irq_err:
for (i = 0; i < q_id; i++) {
irq_cfg = &nic_dev->q_params.irq_cfg[i];
- hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx, HINIC3_MSIX_DISABLE);
- hinic3_set_msix_auto_mask_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ HINIC3_MSIX_DISABLE);
+ hinic3_set_msix_auto_mask_state(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx,
HINIC3_CLR_MSIX_AUTO_MASK);
hinic3_release_irq(irq_cfg);
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
deleted file mode 100644
index 2482c5f..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_LLD_H
-#define HINIC3_LLD_H
-
-#include "hinic3_crm.h"
-
-struct hinic3_lld_dev {
- struct pci_dev *pdev;
- void *hwdev;
-};
-
-struct hinic3_uld_info {
- /* When the function does not need to initialize the corresponding uld,
- * @probe needs to return 0 and uld_dev is set to NULL;
- * if uld_dev is NULL, @remove will not be called when uninstalling
- */
- int (*probe)(struct hinic3_lld_dev *lld_dev, void **uld_dev, char *uld_dev_name);
- void (*remove)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- int (*suspend)(struct hinic3_lld_dev *lld_dev, void *uld_dev, pm_message_t state);
- int (*resume)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- void (*event)(struct hinic3_lld_dev *lld_dev, void *uld_dev,
- struct hinic3_event_info *event);
- int (*ioctl)(void *uld_dev, u32 cmd, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size);
-};
-
-/* hinic3_register_uld - register an upper-layer driver
- * @type: uld service type
- * @uld_info: uld callback
- *
- * Registers an upper-layer driver.
- * Traverse existing devices and call @probe to initialize the uld device.
- */
-int hinic3_register_uld(enum hinic3_service_type type, struct hinic3_uld_info *uld_info);
-
-/**
- * hinic3_unregister_uld - unregister an upper-layer driver
- * @type: uld service type
- *
- * Traverse existing devices and call @remove to uninstall the uld device.
- * Unregisters an existing upper-layer driver.
- */
-void hinic3_unregister_uld(enum hinic3_service_type type);
-
-void lld_hold(void);
-void lld_put(void);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_name - get lld device by chip name
- * @param chip_name: chip name
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_name(const char *chip_name);
-
-/**
- * @brief lld_dev_hold - get reference to lld_dev
- * @param dev: lld device
- *
- * Hold reference to device to keep it from being freed
- **/
-void lld_dev_hold(struct hinic3_lld_dev *dev);
-
-/**
- * @brief lld_dev_put - release reference to lld_dev
- * @param dev: lld device
- *
- * Release reference to device to allow it to be freed
- **/
-void lld_dev_put(struct hinic3_lld_dev *dev);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name_unsafe - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * hinic3_get_lld_dev_by_dev_name_unsafe() is completely analogous to
- * hinic3_get_lld_dev_by_dev_name(), The only difference is that the reference
- * of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that lld_dev will not be freed during the remove process
- * when using lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name_unsafe(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_and_port - get lld device by chip name and port id
- * @param chip_name: chip name
- * @param port_id: port id
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name, u8 port_id);
-
-/**
- * @brief hinic3_get_ppf_lld_dev - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief hinic3_get_ppf_lld_dev_unsafe - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * hinic3_get_ppf_lld_dev_unsafe() is completely analogous to hinic3_get_ppf_lld_dev(),
- * The only difference is that the reference of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that ppf's lld_dev will not be freed during the remove process
- * when using ppf lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev_unsafe(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief uld_dev_hold - get reference to uld_dev
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * Hold reference to uld device to keep it from being freed
- **/
-void uld_dev_hold(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief uld_dev_put - release reference to lld_dev
- * @param dev: lld device
- * @param type: uld service type
- *
- * Release reference to uld device to allow it to be freed
- **/
-void uld_dev_put(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * The value of uld_dev reference increases when uld_dev is obtained. The caller needs
- * to release the reference by calling uld_dev_put.
- **/
-void *hinic3_get_uld_dev(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev_unsafe - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * hinic3_get_uld_dev_unsafe() is completely analogous to hinic3_get_uld_dev(),
- * The only difference is that the reference of uld_dev is not increased when uld_dev is obtained.
- *
- * The caller must ensure that uld_dev will not be freed during the remove process
- * when using uld_dev.
- **/
-void *hinic3_get_uld_dev_unsafe(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_chip_name - get chip name by lld device
- * @param lld_dev: lld device
- * @param chip_name: String for storing the chip name
- * @param max_len: Maximum number of characters to be copied for chip_name
- **/
-int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len);
-
-struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev);
-
-struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev);
-
-bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service);
-
-int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
- bool vf_srv_load);
-
-int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id,
- u16 service, bool en);
-
-bool hinic3_get_vf_load_state(struct pci_dev *pdev);
-
-int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state);
-
-int hinic3_attach_nic(struct hinic3_lld_dev *lld_dev);
-
-void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
-
-int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-const char **hinic3_get_uld_names(void);
-int hinic3_lld_init(void);
-void hinic3_lld_exit(void);
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
index 2fe808b..688bb7d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
@@ -17,11 +17,22 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_hw.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_common.h"
+#include "mag_mpu_cmd_defs.h"
+
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
+#define CAP_INFO_MAX_LEN 512
+#define DEVICE_VENDOR_MAX_LEN 17
+#define READ_RSFEC_REGISTER_DELAY_TIME_MS 500
+
+struct parse_tlv_info g_page_info = {0};
+struct drv_tag_mag_cmd_get_xsfp_tlv_rsp g_xsfp_tlv_info = {0};
static int mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
@@ -78,8 +89,10 @@ int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats)
return -ENOMEM;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
memset(&stats_info, 0, sizeof(stats_info));
stats_info.port_id = hinic3_physical_port_id(hwdev);
@@ -104,6 +117,64 @@ out:
}
EXPORT_SYMBOL(hinic3_get_phy_port_stats);
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats)
+{
+ struct mag_cmd_get_mag_cnt *port_stats = NULL;
+ struct mag_cmd_get_mag_cnt stats_info;
+ u16 out_size = sizeof(*port_stats);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !stats)
+ return -EINVAL;
+
+ port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
+ if (!port_stats)
+ return -ENOMEM;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ memset(&stats_info, 0, sizeof(stats_info));
+ stats_info.port_id = hinic3_physical_port_id(hwdev);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT,
+ &stats_info, sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+ /* 读2遍, 清除误码残留 */
+ msleep(READ_RSFEC_REGISTER_DELAY_TIME_MS);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT, &stats_info,
+ sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+
+ memcpy(stats, &port_stats->mag_csr[MAG_RX_RSFEC_ERR_CW_CNT],
+ sizeof(u32));
+
+out:
+ kfree(port_stats);
+
+ return err;
+}
+EXPORT_SYMBOL(hinic3_get_phy_rsfec_stats);
+
int hinic3_set_port_funcs_state(void *hwdev, bool enable)
{
return 0;
@@ -180,6 +251,8 @@ int hinic3_get_loopback_mode(void *hwdev, u8 *mode, u8 *enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_cfg_loopback_mode(nic_io, MGMT_MSG_CMD_OP_GET, mode,
enable);
@@ -195,6 +268,8 @@ int hinic3_set_loopback_mode(void *hwdev, u8 mode, u8 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) {
nic_err(nic_io->dev_hdl, "Invalid loopback mode %u to set\n",
@@ -218,6 +293,9 @@ int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&led_info, 0, sizeof(led_info));
led_info.function_id = hinic3_global_func_id(hwdev);
@@ -249,6 +327,8 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
memset(&port_msg, 0, sizeof(port_msg));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
port_msg.port_id = hinic3_physical_port_id(hwdev);
@@ -268,9 +348,12 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
port_info->port_type = port_msg.wire_type;
port_info->speed = port_msg.speed;
port_info->fec = port_msg.fec;
+ port_info->lanes = port_msg.lanes;
port_info->supported_mode = port_msg.supported_mode;
port_info->advertised_mode = port_msg.advertised_mode;
-
+ port_info->supported_fec_mode = port_msg.supported_fec_mode;
+ /* switch Gbps to Mbps */
+ port_info->bond_speed = (u32)port_msg.bond_speed * RATE_MBPS_TO_GBPS;
return 0;
}
@@ -306,6 +389,8 @@ int hinic3_set_link_settings(void *hwdev,
memset(&info, 0, sizeof(info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
info.port_id = hinic3_physical_port_id(hwdev);
info.config_bitmap = settings->valid_bitmap;
@@ -335,6 +420,8 @@ int hinic3_get_link_state(void *hwdev, u8 *link_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&get_link, 0, sizeof(get_link));
get_link.port_id = hinic3_physical_port_id(hwdev);
@@ -364,10 +451,11 @@ void hinic3_notify_vf_link_status(struct hinic3_nic_io *nic_io,
if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
link.status = link_status;
link.port_id = hinic3_physical_port_id(nic_io->hwdev);
- err = hinic3_mbox_to_vf(nic_io->hwdev, vf_id, HINIC3_MOD_HILINK,
- MAG_CMD_GET_LINK_STATUS, &link,
- sizeof(link), &link, &out_size, 0,
- HINIC3_CHANNEL_NIC);
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
+ MAG_CMD_GET_LINK_STATUS, &link,
+ sizeof(link), &link, &out_size,
+ HINIC3_CHANNEL_NIC);
if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
HW_VF_ID_TO_OS(vf_id));
@@ -387,6 +475,8 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
u16 i;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
nic_io->link_status = link_status;
for (i = 1; i <= nic_io->max_vfs; i++) {
if (!nic_io->vf_infos[HW_VF_ID_TO_OS(i)].link_forced)
@@ -394,6 +484,165 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
}
}
+static char *g_hw_to_char_fec[HILINK_FEC_MAX_TYPE] = {
+ "not set", "rsfec", "basefec",
+ "nofec", "llrsfec"};
+static char *g_hw_to_speed_info[PORT_SPEED_UNKNOWN] = {
+ "not set", "10MB", "100MB", "1GB", "10GB",
+ "25GB", "40GB", "50GB", "100GB", "200GB"};
+static char *g_hw_to_an_state_info[PORT_CFG_AN_OFF + 1] = {
+ "not set", "on", "off"};
+
+struct port_type_table {
+ u32 port_type;
+ char *port_type_name;
+};
+
+static const struct port_type_table port_optical_type_table_s[] = {
+ {LINK_PORT_UNKNOWN, "UNKNOWN"},
+ {LINK_PORT_OPTICAL_MM, "optical_sr"},
+ {LINK_PORT_OPTICAL_SM, "optical_lr"},
+ {LINK_PORT_PAS_COPPER, "copper"},
+ {LINK_PORT_ACC, "ACC"},
+ {LINK_PORT_BASET, "baset"},
+ {LINK_PORT_AOC, "AOC"},
+ {LINK_PORT_ELECTRIC, "electric"},
+ {LINK_PORT_BACKBOARD_INTERFACE, "interface"},
+};
+
+static char *get_port_type_name(u32 type)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(port_optical_type_table_s); i++) {
+ if (type == port_optical_type_table_s[i].port_type)
+ return port_optical_type_table_s[i].port_type_name;
+ }
+ return "UNKNOWN TYPE";
+}
+
+static void get_port_type(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ char **port_type)
+{
+ if (info->port_type <= LINK_PORT_BACKBOARD_INTERFACE)
+ *port_type = get_port_type_name(info->port_type);
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown port type: %u\n", info->port_type);
+}
+
+static int get_port_temperature_power(struct mag_cmd_event_port_info *info,
+ char *str)
+{
+ char cap_info[CAP_INFO_MAX_LEN];
+
+ memset(cap_info, 0, sizeof(cap_info));
+ snprintf(cap_info, CAP_INFO_MAX_LEN, "%s, %s, Temperature: %u", str,
+ info->sfp_type ? "QSFP" : "SFP", info->cable_temp);
+
+ if (info->sfp_type)
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuw %uuW %uuW %uuW",
+ cap_info, info->power[0x0], info->power[0x1],
+ info->power[0x2], info->power[0x3]);
+ else
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuW, tx power: %uuW",
+ cap_info, info->power[0x0], info->power[0x1]);
+
+ return 0;
+}
+
+static void print_cable_info(struct hinic3_nic_io *nic_io, struct mag_cmd_event_port_info *info)
+{
+ char tmp_str[CAP_INFO_MAX_LEN] = {0};
+ char tmp_vendor[DEVICE_VENDOR_MAX_LEN] = {0};
+ char *port_type = "Unknown port type";
+ int i;
+ int err = 0;
+
+ if (info->gpio_insert) {
+ sdk_info(nic_io->dev_hdl, "Cable unpresent\n");
+ return;
+ }
+
+ get_port_type(nic_io, info, &port_type);
+
+ for (i = sizeof(info->vendor_name) - 1; i >= 0; i--) {
+ if (info->vendor_name[i] == ' ')
+ info->vendor_name[i] = '\0';
+ else
+ break;
+ }
+
+ memcpy(tmp_vendor, info->vendor_name, sizeof(info->vendor_name));
+ snprintf(tmp_str, CAP_INFO_MAX_LEN, "Vendor: %s, %s, length: %um, max_speed: %uGbps",
+ tmp_vendor, port_type, info->cable_length, info->max_speed);
+
+ if (info->port_type == LINK_PORT_OPTICAL_MM ||
+ info->port_type == LINK_PORT_AOC) {
+ err = get_port_temperature_power(info, tmp_str);
+ if (err)
+ return;
+ }
+
+ sdk_info(nic_io->dev_hdl, "Cable information: %s\n", tmp_str);
+}
+
+static void print_link_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ enum hinic3_nic_event_type type)
+{
+ char *fec = "None";
+ char *speed = "None";
+ char *an_state = "None";
+
+ if (info->fec < HILINK_FEC_MAX_TYPE)
+ fec = g_hw_to_char_fec[info->fec];
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown fec type: %u\n", info->fec);
+
+ if (info->an_state > PORT_CFG_AN_OFF) {
+ sdk_info(nic_io->dev_hdl, "an_state %d is invalid",
+ info->an_state);
+ return;
+ }
+
+ an_state = g_hw_to_an_state_info[info->an_state];
+
+ if (info->speed >= PORT_SPEED_UNKNOWN) {
+ sdk_info(nic_io->dev_hdl, "speed %u is invalid", info->speed);
+ return;
+ }
+
+ speed = g_hw_to_speed_info[info->speed];
+ sdk_info(nic_io->dev_hdl, "Link information: speed %s, %s, autoneg %s",
+ speed, fec, an_state);
+}
+
+void print_port_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *port_info,
+ enum hinic3_nic_event_type type)
+{
+ print_cable_info(nic_io, port_info);
+
+ print_link_info(nic_io, port_info, type);
+
+ if (type == EVENT_NIC_LINK_UP)
+ return;
+
+ sdk_info(nic_io->dev_hdl, "PMA ctrl: %s, tx %s, rx %s, PMA fifo reg: 0x%x, PMA signal ok reg: 0x%x, RF/LF status reg: 0x%x\n",
+ port_info->pma_ctrl == 1 ? "off" : "on",
+ port_info->tx_enable ? "enable" : "disable",
+ port_info->rx_enable ? "enable" : "disable", port_info->pma_fifo_reg,
+ port_info->pma_signal_ok_reg, port_info->rf_lf);
+ sdk_info(nic_io->dev_hdl, "alos: %u, rx_los: %u, PCS 64 66b reg: 0x%x, PCS link: 0x%x, MAC link: 0x%x PCS_err_cnt: 0x%x\n",
+ port_info->alos, port_info->rx_los, port_info->pcs_64_66b_reg,
+ port_info->pcs_link, port_info->pcs_mac_link,
+ port_info->pcs_err_cnt);
+ sdk_info(nic_io->dev_hdl, "his_link_machine_state = 0x%08x, cur_link_machine_state = 0x%08x\n",
+ port_info->his_link_machine_state,
+ port_info->cur_link_machine_state);
+}
+
static int hinic3_get_vf_link_status_msg_handler(struct hinic3_nic_io *nic_io,
u16 vf_id, void *buf_in,
u16 in_size, void *buf_out,
@@ -433,6 +682,10 @@ static void get_port_info(void *hwdev,
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (hinic3_func_type(hwdev) != TYPE_VF && link_status->status) {
err = hinic3_get_port_info(hwdev, &port_info, HINIC3_CHANNEL_NIC);
if (err) {
@@ -457,8 +710,18 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
struct hinic3_event_info event_info = {0};
struct hinic3_event_link_info *link_info = (void *)event_info.event_data;
struct hinic3_nic_io *nic_io = NULL;
+#ifndef __UEFI__
+ struct pci_dev *pdev = NULL;
+#endif
+ /* Ignore link change event */
+ if (hinic3_is_bm_slave_host(hwdev))
+ return;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
link_status = buf_in;
sdk_info(nic_io->dev_hdl, "Link status report received, func_id: %u, status: %u\n",
@@ -475,6 +738,15 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
hinic3_event_callback(hwdev, &event_info);
+#ifndef __UEFI__
+ if (nic_io->pcidev_hdl) {
+ pdev = nic_io->pcidev_hdl;
+ if (pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID) {
+ return;
+ }
+ }
+#endif
+
if (hinic3_func_type(hwdev) != TYPE_VF) {
hinic3_notify_all_vfs_link_changed(hwdev, link_status->status);
ret_link_status = buf_out;
@@ -483,20 +755,142 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
}
}
+static void port_info_event_printf(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_event_port_info *port_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info;
+ enum hinic3_nic_event_type type;
+
+ if (!hwdev) {
+ pr_err("hwdev is NULL\n");
+ return;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ if (in_size != sizeof(*port_info)) {
+ sdk_info(nic_io->dev_hdl, "Invalid port info message size %d, should be %ld\n",
+ in_size, sizeof(*port_info));
+ return;
+ }
+
+ ((struct mag_cmd_event_port_info *)buf_out)->head.status = 0;
+
+ type = port_info->event_type;
+ if (type < EVENT_NIC_LINK_DOWN || type > EVENT_NIC_LINK_UP) {
+ sdk_info(nic_io->dev_hdl, "Invalid hilink info report, type: %d\n",
+ type);
+ return;
+ }
+
+ print_port_info(nic_io, port_info, type);
+
+ memset(&event_info, 0, sizeof(event_info));
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = type;
+
+ *out_size = sizeof(*port_info);
+
+ hinic3_event_callback(hwdev, &event_info);
+}
+
+void hinic3_notify_vf_bond_status(struct hinic3_nic_io *nic_io,
+ u16 vf_id, u8 bond_status)
+{
+ struct mag_cmd_get_bond_status bond;
+ struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ u16 out_size = sizeof(bond);
+ int err;
+
+ memset(&bond, 0, sizeof(bond));
+ if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
+ bond.status = bond_status;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
+ MAG_CMD_GET_BOND_STATUS, &bond,
+ sizeof(bond), &bond, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF %u not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return;
+ }
+ if (err || !out_size || bond.head.status)
+ nic_err(nic_io->dev_hdl,
+ "Send bond change event to VF %hu failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err, bond.head.status,
+ out_size);
+ }
+}
+
+void hinic3_notify_all_vfs_bond_changed(void *hwdev, u8 bond_status)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 i;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ nic_io->link_status = bond_status;
+ for (i = 1; i <= nic_io->max_vfs; i++)
+ hinic3_notify_vf_bond_status(nic_io, i, bond_status);
+}
+
+static void bond_status_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_get_bond_status *bond_status = NULL;
+ struct hinic3_event_info event_info = {};
+ struct hinic3_nic_io *nic_io = NULL;
+ struct mag_cmd_get_bond_status *ret_bond_status = NULL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+
+ bond_status = (struct mag_cmd_get_bond_status *)buf_in;
+ sdk_info(nic_io->dev_hdl, "bond status report received, func_id: %u, status: %u\n",
+ hinic3_global_func_id(hwdev), bond_status->status);
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = bond_status->status ?
+ EVENT_NIC_BOND_UP : EVENT_NIC_BOND_DOWN;
+
+ hinic3_event_callback(hwdev, &event_info);
+
+ if (hinic3_func_type(hwdev) != TYPE_VF) {
+ hinic3_notify_all_vfs_bond_changed(hwdev, bond_status->status);
+ ret_bond_status = buf_out;
+ ret_bond_status->head.status = 0;
+ *out_size = sizeof(*ret_bond_status);
+ }
+}
+
static void cable_plug_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct mag_cmd_wire_event *plug_event = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_event_info event_info;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
rt_cmd->mpu_send_sfp_abs = false;
rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
memset(&event_info, 0, sizeof(event_info));
@@ -518,9 +912,12 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
{
struct mag_cmd_get_xsfp_info *sfp_info = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_info)) {
sdk_err(nic_io->dev_hdl, "Invalid sfp info cmd, length: %u, should be %ld\n",
in_size, sizeof(*sfp_info));
@@ -528,10 +925,41 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
}
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
memcpy(&rt_cmd->std_sfp_info, sfp_info,
sizeof(struct mag_cmd_get_xsfp_info));
rt_cmd->mpu_send_sfp_info = true;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+}
+
+static void port_xsfp_tlv_info_event(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *xsfp_tlv_info = buf_in;
+ struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
+ size_t cpy_len = in_size - sizeof(struct mgmt_msg_head) -
+ XSFP_TLV_PRE_INFO_LEN;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
+
+ if (cpy_len > XSFP_CMIS_INFO_MAX_SIZE) {
+ sdk_err(nic_io->dev_hdl, "invalid cpy_len(%lu)\n", cpy_len);
+ return;
+ }
+ rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ rt_cmd_ext->std_xsfp_tlv_info.port_id = xsfp_tlv_info->port_id;
+ memcpy(&rt_cmd_ext->std_xsfp_tlv_info.tlv_buf[0],
+ &xsfp_tlv_info->tlv_buf[0], cpy_len);
+ rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = true;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
}
@@ -543,6 +971,8 @@ static void port_sfp_abs_event(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_abs)) {
sdk_err(nic_io->dev_hdl, "Invalid sfp absent cmd, length: %u, should be %ld\n",
in_size, sizeof(*sfp_abs));
@@ -564,9 +994,11 @@ bool hinic3_if_sfp_absent(void *hwdev)
u8 port_id = hinic3_physical_port_id(hwdev);
u16 out_size = sizeof(sfp_abs);
int err;
- bool sfp_abs_status;
+ bool sfp_abs_status = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return true;
memset(&sfp_abs, 0, sizeof(sfp_abs));
rt_cmd = &nic_io->nic_cfg.rt_cmd;
@@ -597,10 +1029,184 @@ bool hinic3_if_sfp_absent(void *hwdev)
return (sfp_abs.abs_status == 0 ? false : true);
}
+int hinic3_get_sfp_tlv_info(void *hwdev, struct drv_tag_mag_cmd_get_xsfp_tlv_rsp
+ *sfp_tlv_info,
+ const struct tag_mag_cmd_get_xsfp_tlv_req
+ *sfp_tlv_info_req)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ u16 out_size = sizeof(*sfp_tlv_info);
+ int err;
+
+ if (!hwdev || !sfp_tlv_info)
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ if (rt_cmd_ext->mpu_send_xsfp_tlv_info) {
+ if (rt_cmd_ext->std_xsfp_tlv_info.head.status != 0) {
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return -EIO;
+ }
+
+ memcpy(sfp_tlv_info, &rt_cmd_ext->std_xsfp_tlv_info,
+ sizeof(*sfp_tlv_info));
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_TLV_INFO,
+ (void *)sfp_tlv_info_req,
+ sizeof(*sfp_tlv_info_req),
+ sfp_tlv_info, &out_size);
+ if (sfp_tlv_info->head.status != 0 || err != 0 || out_size == 0) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get port%u tlv sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
+ hinic3_physical_port_id(hwdev), err,
+ sfp_tlv_info->head.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_get_page_pos(u32 page_id, u32 content_len, u32 *pos)
+{
+ if (page_id <= QSFP_CMIS_PAGE_03H) {
+ *pos = (page_id * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_11H) {
+ *pos = (QSFP_CMIS_PAGE_04H * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_12H) {
+ *pos = (QSFP_CMIS_PAGE_05H * content_len);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int hinic3_get_page_key_info(struct mgmt_tlv_info *tlv_info,
+ struct parse_tlv_info *page_info, u8 idx,
+ u32 *total_len)
+{
+ u8 *src_addr = NULL;
+ u8 *dst_addr = NULL;
+ u8 *tmp_addr = NULL;
+ u32 page_id = 0;
+ u32 content_len = 0;
+ u32 src_pos = 0;
+ int ret;
+
+ page_id = MGMT_TLV_GET_U32(tlv_info->value);
+ content_len = tlv_info->length - MGMT_TLV_U32_SIZE;
+ if (page_id == QSFP_CMIS_PAGE_00H) {
+ tmp_addr = (u8 *)(tlv_info + 1);
+ page_info->id = *(tmp_addr + MGMT_TLV_U32_SIZE);
+ }
+
+ ret = hinic3_trans_cmis_get_page_pos(page_id, content_len, &src_pos);
+ if (ret != 0)
+ return ret;
+
+ src_addr = page_info->tlv_page_info + src_pos;
+ tmp_addr = (u8 *)(tlv_info + 1);
+ dst_addr = tmp_addr + MGMT_TLV_U32_SIZE;
+ memcpy(src_addr, dst_addr, content_len);
+
+ if (idx < XSFP_CMIS_PARSE_PAGE_NUM)
+ page_info->tlv_page_num[idx] = page_id;
+
+ *total_len += content_len;
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_tlv_info_to_buf(u8 *sfp_tlv_info,
+ struct parse_tlv_info *page_info)
+{
+ struct mgmt_tlv_info *tlv_info = NULL;
+ u8 *tlv_buf = sfp_tlv_info;
+ u8 idx = 0;
+ u32 total_len = 0;
+ int ret = 0;
+ bool need_continue = true;
+
+ if (!sfp_tlv_info || !page_info)
+ return -EIO;
+
+ while (need_continue) {
+ tlv_info = (struct mgmt_tlv_info *)tlv_buf;
+ switch (tlv_info->type) {
+ case MAG_XSFP_TYPE_PAGE:
+ ret = hinic3_get_page_key_info(tlv_info, page_info,
+ idx, &total_len);
+ if (ret != 0) {
+ pr_err("lib_get_page_key_info fail,ret:0x%x.\n",
+ ret);
+ break;
+ }
+ idx++;
+ break;
+
+ case MAG_XSFP_TYPE_WIRE_TYPE:
+ page_info->wire_type = MGMT_TLV_GET_U32(&tlv_info->value);
+ break;
+
+ case MAG_XSFP_TYPE_END:
+ need_continue = false;
+ break;
+
+ default:
+ break;
+ }
+
+ tlv_buf += (sizeof(struct mgmt_tlv_info) + tlv_info->length);
+ }
+
+ page_info->tlv_page_info_len = total_len;
+
+ return 0;
+}
+
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len)
+{
+ int err = 0;
+ struct tag_mag_cmd_get_xsfp_tlv_req xsfp_tlv_info_req = {0};
+
+ xsfp_tlv_info_req.rsp_buf_len = XSFP_CMIS_INFO_MAX_SIZE;
+ xsfp_tlv_info_req.port_id = hinic3_physical_port_id(hwdev);
+ err = hinic3_get_sfp_tlv_info(hwdev, &g_xsfp_tlv_info,
+ &xsfp_tlv_info_req);
+ if (err != 0)
+ return err;
+
+ err = hinic3_trans_cmis_tlv_info_to_buf(g_xsfp_tlv_info.tlv_buf,
+ &g_page_info);
+ if (err)
+ return -ENOMEM;
+
+ memcpy(data, g_page_info.tlv_page_info, len);
+
+ return (err == 0) ? 0 : -ENOMEM;
+}
+
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
{
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ u8 sfp_info_status = 0;
u16 out_size = sizeof(*sfp_info);
int err;
@@ -608,13 +1214,17 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ sfp_info_status = rt_cmd->std_sfp_info.head.status;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (sfp_info_status != 0) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return -EIO;
+ return (sfp_info_status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ ? HINIC3_MGMT_CMD_UNSUPPORTED : -EIO;
}
memcpy(sfp_info, &rt_cmd->std_sfp_info, sizeof(*sfp_info));
@@ -626,7 +1236,12 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
sfp_info->port_id = hinic3_physical_port_id(hwdev);
err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_INFO, sfp_info,
sizeof(*sfp_info), sfp_info, &out_size);
- if (sfp_info->head.status || err || !out_size) {
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ return HINIC3_MGMT_CMD_UNSUPPORTED;
+
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ return -EOPNOTSUPP;
+ if (sfp_info->head.status != 0 || err != 0 || out_size == 0) {
nic_err(nic_io->dev_hdl,
"Failed to get port%u sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
hinic3_physical_port_id(hwdev), err,
@@ -642,7 +1257,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
struct mag_cmd_get_xsfp_info sfp_info;
int err;
- if (!hwdev || !data)
+ if (!hwdev || !data || len > PAGE_SIZE)
return -EINVAL;
if (hinic3_if_sfp_absent(hwdev))
@@ -654,7 +1269,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
if (err)
return err;
- memcpy(data, sfp_info.sfp_info, len);
+ memcpy(data, sfp_info.sfp_info, sizeof(sfp_info.sfp_info));
return 0;
}
@@ -664,7 +1279,7 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
- int err;
+ int err = 0;
if (!hwdev || !sfp_type || !sfp_type_ext)
return -EINVAL;
@@ -677,20 +1292,35 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (rt_cmd->std_sfp_info.head.status == 0) {
+ *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
+ *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ if (rt_cmd->std_sfp_info.head.status != HINIC3_MGMT_CMD_UNSUPPORTED) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
return -EIO;
}
- *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
- *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
- mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return 0;
+ err = HINIC3_MGMT_CMD_UNSUPPORTED; /* cmis */
}
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
- STD_SFP_INFO_MAX_SIZE);
+ if (err == 0) {
+ err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ } else {
+ /* mpu_send_sfp_info is false */
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ }
+
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+
if (err)
return err;
@@ -796,16 +1426,23 @@ int hinic3_set_pf_bw_limit(void *hwdev, u32 bw_limit)
return -EINVAL;
}
- old_bw_limit = nic_io->nic_cfg.pf_bw_limit;
- nic_io->nic_cfg.pf_bw_limit = bw_limit;
+ if (nic_io->direct == HINIC3_NIC_TX) {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_tx_limit;
+ nic_io->nic_cfg.pf_bw_tx_limit = bw_limit;
+ } else {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_rx_limit;
+ nic_io->nic_cfg.pf_bw_rx_limit = bw_limit;
+ }
err = hinic3_update_pf_bw(hwdev);
if (err) {
- nic_io->nic_cfg.pf_bw_limit = old_bw_limit;
- return err;
+ if (nic_io->direct == HINIC3_NIC_TX)
+ nic_io->nic_cfg.pf_bw_tx_limit = old_bw_limit;
+ else
+ nic_io->nic_cfg.pf_bw_rx_limit = old_bw_limit;
}
- return 0;
+ return err;
}
static const struct vf_msg_handler vf_mag_cmd_handler[] = {
@@ -828,6 +1465,9 @@ int hinic3_pf_mag_mbox_handler(void *hwdev, u16 vf_id,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
for (index = 0; index < cmd_size; index++) {
handler = &vf_mag_cmd_handler[index];
@@ -848,6 +1488,11 @@ static struct nic_event_handler mag_cmd_handler[] = {
.handler = link_status_event_handler,
},
+ {
+ .cmd = MAG_CMD_EVENT_PORT_INFO,
+ .handler = port_info_event_printf,
+ },
+
{
.cmd = MAG_CMD_WIRE_EVENT,
.handler = cable_plug_event,
@@ -862,6 +1507,16 @@ static struct nic_event_handler mag_cmd_handler[] = {
.cmd = MAG_CMD_GET_XSFP_PRESENT,
.handler = port_sfp_abs_event,
},
+
+ {
+ .cmd = MAG_CMD_GET_BOND_STATUS,
+ .handler = bond_status_event_handler,
+ },
+
+ {
+ .cmd = MAG_CMD_GET_XSFP_TLV_INFO,
+ .handler = port_xsfp_tlv_info_event,
+ },
};
static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
@@ -877,6 +1532,9 @@ static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
for (i = 0; i < size; i++) {
if (cmd == mag_cmd_handler[i].cmd) {
mag_cmd_handler[i].handler(hwdev, buf_in, in_size,
@@ -917,7 +1575,8 @@ static int _mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u32 i, cmd_cnt = ARRAY_LEN(vf_mag_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_mag_cmd_handler[i].cmd) {
cmd_to_pf = true;
@@ -949,3 +1608,123 @@ static int mag_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in,
return _mag_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out,
out_size, channel);
}
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+struct fecparam_value_map {
+ u8 hinic3_fec_offset;
+ u8 hinic3_fec_value;
+ u8 ethtool_fec_value;
+};
+
+static void fecparam_convert(u32 opcode, u8 in_fec_param, u8 *out_fec_param)
+{
+ u8 i;
+ u8 fec_value_table_lenth;
+ struct fecparam_value_map fec_value_table[] = {
+ {PORT_FEC_NOT_SET, BIT(PORT_FEC_NOT_SET), ETHTOOL_FEC_NONE},
+ {PORT_FEC_RSFEC, BIT(PORT_FEC_RSFEC), ETHTOOL_FEC_RS},
+ {PORT_FEC_BASEFEC, BIT(PORT_FEC_BASEFEC), ETHTOOL_FEC_BASER},
+ {PORT_FEC_NOFEC, BIT(PORT_FEC_NOFEC), ETHTOOL_FEC_OFF},
+#ifdef ETHTOOL_FEC_LLRS
+ {PORT_FEC_LLRSFEC, BIT(PORT_FEC_LLRSFEC), ETHTOOL_FEC_LLRS},
+#endif
+ {PORT_FEC_AUTO, BIT(PORT_FEC_AUTO), ETHTOOL_FEC_AUTO}
+ };
+
+ *out_fec_param = 0;
+ fec_value_table_lenth = (u8)(sizeof(fec_value_table) / sizeof(struct fecparam_value_map));
+
+ if (opcode == MAG_CMD_OPCODE_SET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].ethtool_fec_value) != 0)
+ /* The MPU uses the offset to determine the FEC mode. */
+ *out_fec_param =
+ fec_value_table[i].hinic3_fec_offset;
+ }
+ }
+
+ if (opcode == MAG_CMD_OPCODE_GET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].hinic3_fec_value) != 0)
+ *out_fec_param |=
+ fec_value_table[i].ethtool_fec_value;
+ }
+ }
+}
+
+/* When the ethtool is used to set the FEC mode */
+static bool check_fecparam_is_valid(u8 fec_param)
+{
+ if (fec_param == ETHTOOL_FEC_RS ||
+#ifdef ETHTOOL_FEC_LLRS
+ fec_param == ETHTOOL_FEC_LLRS ||
+#endif
+ fec_param == ETHTOOL_FEC_BASER ||
+ fec_param == ETHTOOL_FEC_OFF) {
+ return true;
+ }
+ return false;
+}
+
+int set_fecparam(void *hwdev, u8 fecparam)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ u8 advertised_fec = 0;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (check_fecparam_is_valid(fecparam) == false) {
+ nic_err(nic_io->dev_hdl, "fec param is invalid, failed to set fec param\n");
+ return -EINVAL;
+ }
+ fecparam_convert(MAG_CMD_OPCODE_SET, fecparam, &advertised_fec);
+ fec_msg.opcode = MAG_CMD_OPCODE_SET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ fec_msg.advertised_fec = advertised_fec;
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if (err != 0 || fec_msg.head.status != 0)
+ return -EINVAL;
+ return 0;
+}
+
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ fec_msg.opcode = MAG_CMD_OPCODE_GET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if (err != 0 || fec_msg.head.status != 0)
+ return -EINVAL;
+
+ /* fec_msg.advertised_fec: bit offset,
+ *value is BIT(fec_msg.advertised_fec); fec_msg.supported_fec: value
+ */
+ fecparam_convert(MAG_CMD_OPCODE_GET, BIT(fec_msg.advertised_fec),
+ advertised_fec);
+ fecparam_convert(MAG_CMD_OPCODE_GET, fec_msg.supported_fec,
+ supported_fec);
+ return 0;
+}
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
index 6f90c86..d240a53 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
@@ -20,6 +20,9 @@
#include <linux/debugfs.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#include "hinic3_hw.h"
#include "hinic3_crm.h"
#include "hinic3_mt.h"
@@ -35,8 +38,8 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
#include "hinic3_profile.h"
+#include "hinic3_bond.h"
-/*lint -e806*/
#define DEFAULT_POLL_WEIGHT 64
static unsigned int poll_weight = DEFAULT_POLL_WEIGHT;
module_param(poll_weight, uint, 0444);
@@ -68,7 +71,9 @@ static unsigned char set_link_status_follow = HINIC3_LINK_FOLLOW_STATUS_MAX;
module_param(set_link_status_follow, byte, 0444);
MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=default,1=follow,2=separate,3=unset");
-/*lint +e806*/
+static bool page_pool_enabled = true;
+module_param(page_pool_enabled, bool, 0444);
+MODULE_PARM_DESC(page_pool_enabled, "enable/disable page_pool feature for rxq page management (default enable)");
#define HINIC3_NIC_DEV_WQ_NAME "hinic3_nic_dev_wq"
@@ -80,6 +85,8 @@ MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=
#define HINIC3_SQ_DEPTH 1024
#define HINIC3_RQ_DEPTH 1024
+#define LRO_ENABLE 1
+
enum hinic3_rx_buff_len {
RX_BUFF_VALID_2KB = 2,
RX_BUFF_VALID_4KB = 4,
@@ -87,12 +94,15 @@ enum hinic3_rx_buff_len {
RX_BUFF_VALID_16KB = 16,
};
+#define NIC_MAX_PF_NUM 32
+
#define CONVERT_UNIT 1024
-#define BIFUR_RESOURCE_PF_SSID 0x5a1
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
-static int hinic3_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr);
+static int hinic3_netdev_event(struct notifier_block *notifier,
+ unsigned long event, void *ptr);
/* used for netdev notifier register/unregister */
static DEFINE_MUTEX(hinic3_netdev_notifiers_mutex);
@@ -101,6 +111,17 @@ static struct notifier_block hinic3_netdev_notifier = {
.notifier_call = hinic3_netdev_event,
};
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+static const struct udp_tunnel_nic_info hinic3_udp_tunnels = {
+ .set_port = hinic3_udp_tunnel_set_port,
+ .unset_port = hinic3_udp_tunnel_unset_port,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static void hinic3_register_notifier(struct hinic3_nic_dev *nic_dev)
{
int err;
@@ -134,7 +155,8 @@ static void hinic3_unregister_notifier(struct hinic3_nic_dev *nic_dev)
NETIF_F_SCTP_CRC | NETIF_F_RXCSUM | \
NETIF_F_ALL_TSO)
-static int hinic3_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr)
+static int hinic3_netdev_event(struct notifier_block *notifier,
+ unsigned long event, void *ptr)
{
struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
struct net_device *real_dev = NULL;
@@ -266,6 +288,11 @@ static void netdev_feature_init(struct net_device *netdev)
netdev->features |= dft_fts | cso_fts | tso_fts | vlan_fts;
netdev->vlan_features |= dft_fts | cso_fts | tso_fts;
+ if (nic_dev->nic_cap.lro_enable == LRO_ENABLE) {
+ netdev->features |= NETIF_F_LRO;
+ netdev->vlan_features |= NETIF_F_LRO;
+ }
+
#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT
hw_features |= get_netdev_hw_features(netdev);
#else
@@ -306,7 +333,8 @@ static void init_intr_coal_param(struct hinic3_nic_dev *nic_dev)
info->pending_limt = qp_pending_limit;
info->coalesce_timer_cfg = qp_coalesc_timer_cfg;
- info->resend_timer_cfg = HINIC3_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG;
+ info->resend_timer_cfg =
+ HINIC3_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG;
info->pkt_rate_high = HINIC3_RX_RATE_HIGH;
info->rx_usecs_high = HINIC3_RX_COAL_TIME_HIGH;
@@ -350,6 +378,7 @@ static int hinic3_init_intr_coalesce(struct hinic3_nic_dev *nic_dev)
static void hinic3_free_intr_coalesce(struct hinic3_nic_dev *nic_dev)
{
kfree(nic_dev->intr_coalesce);
+ nic_dev->intr_coalesce = NULL;
}
static int hinic3_alloc_txrxqs(struct hinic3_nic_dev *nic_dev)
@@ -396,15 +425,18 @@ static void hinic3_free_txrxqs(struct hinic3_nic_dev *nic_dev)
static void hinic3_tx_rx_ops_init(struct hinic3_nic_dev *nic_dev)
{
if (HINIC3_SUPPORT_TX_COMPACT_WQE_OL(nic_dev->hwdev)) {
- nic_dev->tx_rx_ops.tx_set_wqebb_cnt = hinic3_tx_set_compact_offload_wqebb_cnt;
- nic_dev->tx_rx_ops.tx_set_wqe_task = hinic3_tx_set_compact_offload_wqe_task;
+ nic_dev->tx_rx_ops.tx_set_wqebb_cnt =
+ hinic3_tx_set_compact_offload_wqebb_cnt;
+ nic_dev->tx_rx_ops.tx_set_wqe_task =
+ hinic3_tx_set_compact_offload_wqe_task;
} else {
nic_dev->tx_rx_ops.tx_set_wqebb_cnt = hinic3_tx_set_wqebb_cnt;
nic_dev->tx_rx_ops.tx_set_wqe_task = hinic3_tx_set_wqe_task;
}
if (HINIC3_SUPPORT_RX_COMPACT_CQE(nic_dev->hwdev))
- nic_dev->tx_rx_ops.rx_get_cqe_info = hinic3_rx_get_compact_cqe_info;
+ nic_dev->tx_rx_ops.rx_get_cqe_info =
+ hinic3_rx_get_compact_cqe_info;
else
nic_dev->tx_rx_ops.rx_get_cqe_info = hinic3_rx_get_cqe_info;
}
@@ -420,53 +452,47 @@ static void hinic3_sw_deinit(struct hinic3_nic_dev *nic_dev)
HINIC3_CHANNEL_NIC);
hinic3_clear_rss_config(nic_dev);
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+
+ hinic3_dcb_deinit(nic_dev);
}
-static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
+static void hinic3_netdev_mtu_init(struct net_device *netdev)
+{
+ /* MTU range: 384 - 9600 */
+#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
+ netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+
+#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
+ netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+}
+
+static int hinic3_set_default_mac(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
u8 mac_addr[ETH_ALEN];
- u64 nic_features;
int err = 0;
- nic_features = hinic3_get_feature_cap(nic_dev->hwdev);
- /* You can update the features supported by the driver according to the
- * scenario here
- */
- nic_features &= NIC_DRV_DEFAULT_FEATURE;
- hinic3_update_nic_feature(nic_dev->hwdev, nic_features);
-
- sema_init(&nic_dev->port_state_sem, 1);
-
- err = hinic3_dcb_init(nic_dev);
- if (err) {
- nic_err(&nic_dev->pdev->dev, "Failed to init dcb\n");
- return -EFAULT;
- }
-
- nic_dev->q_params.sq_depth = HINIC3_SQ_DEPTH;
- nic_dev->q_params.rq_depth = HINIC3_RQ_DEPTH;
-
- hinic3_try_to_enable_rss(nic_dev);
-
err = hinic3_get_default_mac(nic_dev->hwdev, mac_addr);
if (err) {
nic_err(&nic_dev->pdev->dev, "Failed to get MAC address\n");
- goto get_mac_err;
+ return err;
}
+
eth_hw_addr_set(netdev, mac_addr);
if (!is_valid_ether_addr(netdev->dev_addr)) {
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
nic_err(&nic_dev->pdev->dev, "Invalid MAC address %pM\n",
- netdev->dev_addr);
- err = -EIO;
- goto err_mac;
- }
+ netdev->dev_addr);
+ return -EIO;
+ }
- nic_info(&nic_dev->pdev->dev, "Invalid MAC address %pM, using random\n",
+ nic_info(&nic_dev->pdev->dev,
+ "Invalid MAC address %pM, using random\n",
netdev->dev_addr);
eth_hw_addr_random(netdev);
}
@@ -478,21 +504,62 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
* MAC, and we can't consider this condition is error status during
* driver probe procedure.
*/
- if (err && err != HINIC3_PF_SET_VF_ALREADY) {
+ if (err && err != HINIC3_PF_SET_VF_ALREADY)
nic_err(&nic_dev->pdev->dev, "Failed to set default MAC\n");
- goto set_mac_err;
+
+ if (err == HINIC3_PF_SET_VF_ALREADY)
+ return 0;
+
+ return err;
+}
+
+static void hinic3_outband_cfg_init(struct hinic3_nic_dev *nic_dev)
+{
+ u16 outband_default_vid = 0;
+ int err = 0;
+
+ if (!nic_dev->nic_cap.outband_vlan_cfg_en)
+ return;
+
+ err = hinic3_get_outband_vlan_cfg(nic_dev->hwdev, &outband_default_vid);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev,
+ "Failed to get_outband_cfg, err: %d\n", err);
+ return;
}
- /* MTU range: 384 - 9600 */
-#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
- netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
+ nic_dev->outband_cfg.outband_default_vid = outband_default_vid;
+}
-#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
- netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
+static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
+{
+ struct net_device *netdev = nic_dev->netdev;
+ u64 nic_features;
+ int err = 0;
+
+ nic_features = hinic3_get_feature_cap(nic_dev->hwdev);
+ /* You can update the features supported by the driver according to the
+ * scenario here
+ */
+ nic_features &= NIC_DRV_DEFAULT_FEATURE;
+ hinic3_update_nic_feature(nic_dev->hwdev, nic_features);
+
+ err = hinic3_dcb_init(nic_dev);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev, "Failed to init dcb\n");
+ return -EFAULT;
+ }
+
+ nic_dev->q_params.sq_depth = HINIC3_SQ_DEPTH;
+ nic_dev->q_params.rq_depth = HINIC3_RQ_DEPTH;
+
+ hinic3_try_to_enable_rss(nic_dev);
+
+ err = hinic3_set_default_mac(nic_dev);
+ if (err)
+ goto set_mac_err;
+
+ hinic3_netdev_mtu_init(netdev);
err = hinic3_alloc_txrxqs(nic_dev);
if (err) {
@@ -500,6 +567,8 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
goto alloc_qps_err;
}
+ hinic3_outband_cfg_init(nic_dev);
+
hinic3_tx_rx_ops_init(nic_dev);
return 0;
@@ -510,8 +579,6 @@ alloc_qps_err:
HINIC3_CHANNEL_NIC);
set_mac_err:
-err_mac:
-get_mac_err:
hinic3_clear_rss_config(nic_dev);
return err;
@@ -623,7 +690,8 @@ static void calc_coal_para(struct hinic3_nic_dev *nic_dev,
*pending_limt =
(u8)((rx_rate - q_coal->pkt_rate_low) *
- (q_coal->rx_pending_limt_high - q_coal->rx_pending_limt_low) /
+ (q_coal->rx_pending_limt_high -
+ q_coal->rx_pending_limt_low) /
(q_coal->pkt_rate_high - q_coal->pkt_rate_low) +
q_coal->rx_pending_limt_low);
}
@@ -637,8 +705,10 @@ static void update_queue_coal(struct hinic3_nic_dev *nic_dev, u16 qid,
q_coal = &nic_dev->intr_coalesce[qid];
- if (rx_rate > HINIC3_RX_RATE_THRESH && avg_pkt_size > HINIC3_AVG_PKT_SMALL) {
- calc_coal_para(nic_dev, q_coal, rx_rate, &coalesc_timer_cfg, &pending_limt);
+ if (rx_rate > HINIC3_RX_RATE_THRESH &&
+ avg_pkt_size > HINIC3_AVG_PKT_SMALL) {
+ calc_coal_para(nic_dev, q_coal, rx_rate,
+ &coalesc_timer_cfg, &pending_limt);
} else {
coalesc_timer_cfg = HINIC3_LOWEST_LATENCY;
pending_limt = q_coal->rx_pending_limt_low;
@@ -701,20 +771,55 @@ void hinic3_auto_moderation_work(struct work_struct *work)
static void hinic3_periodic_work_handler(struct work_struct *work)
{
struct delayed_work *delay = to_delayed_work(work);
- struct hinic3_nic_dev *nic_dev = container_of(delay, struct hinic3_nic_dev, periodic_work);
+ struct hinic3_nic_dev *nic_dev =
+ container_of(delay, struct hinic3_nic_dev, periodic_work);
if (test_and_clear_bit(EVENT_WORK_TX_TIMEOUT, &nic_dev->event_flag))
- hinic3_fault_event_report(nic_dev->hwdev, HINIC3_FAULT_SRC_TX_TIMEOUT,
+ hinic3_fault_event_report(nic_dev->hwdev,
+ HINIC3_FAULT_SRC_TX_TIMEOUT,
FAULT_LEVEL_SERIOUS_FLR);
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
}
+static void hinic3_vport_stats_work_handler(struct work_struct *work)
+{
+ int err;
+ struct hinic3_vport_stats vport_stats = {0};
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_nic_dev *nic_dev = container_of(delay,
+ struct hinic3_nic_dev,
+ vport_stats_work);
+ err = hinic3_get_vport_stats(nic_dev->hwdev,
+ hinic3_global_func_id(nic_dev->hwdev),
+ &vport_stats);
+ if (err)
+ nic_err(&nic_dev->pdev->dev, "Failed to get dropped stats from fw\n");
+ else
+ nic_dev->vport_stats.rx_discard_vport =
+ vport_stats.rx_discard_vport;
+ queue_delayed_work(nic_dev->workq, &nic_dev->vport_stats_work, HZ);
+}
+
+static void free_nic_dev_vram(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram = get_use_vram_flag();
+
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)nic_dev->nic_vram, nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ else
+ kfree(nic_dev->nic_vram);
+ nic_dev->nic_vram = NULL;
+}
+
static void free_nic_dev(struct hinic3_nic_dev *nic_dev)
{
hinic3_deinit_nic_prof_adapter(nic_dev);
destroy_workqueue(nic_dev->workq);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+ free_nic_dev_vram(nic_dev);
}
static int setup_nic_dev(struct net_device *netdev,
@@ -724,6 +829,10 @@ static int setup_nic_dev(struct net_device *netdev,
struct hinic3_nic_dev *nic_dev;
char *netdev_name_fmt;
u32 page_num;
+ u16 func_id;
+ int ret;
+ int is_in_kexec = vram_get_kexec_flag();
+ int is_use_vram = get_use_vram_flag();
nic_dev = (struct hinic3_nic_dev *)netdev_priv(netdev);
nic_dev->netdev = netdev;
@@ -738,22 +847,58 @@ static int setup_nic_dev(struct net_device *netdev,
nic_dev->dma_rx_buff_size = RX_BUFF_NUM_PER_PAGE * nic_dev->rx_buff_len;
page_num = nic_dev->dma_rx_buff_size / PAGE_SIZE;
nic_dev->page_order = page_num > 0 ? ilog2(page_num) : 0;
+ nic_dev->page_pool_enabled = page_pool_enabled;
+ nic_dev->outband_cfg.outband_default_vid = 0;
+
+ // value other than 0 indicates hot replace
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(nic_dev->nic_vram_name, VRAM_NAME_MAX_LEN,
+ "%s%hu", VRAM_NIC_VRAM, func_id);
+
+ nic_dev->nic_vram = (struct hinic3_vram *)hi_vram_kalloc(nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+
+ if (is_in_kexec == 0)
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ else
+ netdev->mtu = nic_dev->nic_vram->vram_mtu;
+ } else {
+ nic_dev->nic_vram = kzalloc(sizeof(*nic_dev->nic_vram),
+ GFP_KERNEL);
+ if (!nic_dev->nic_vram)
+ return -ENOMEM;
+
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ }
mutex_init(&nic_dev->nic_mutex);
nic_dev->vlan_bitmap = kzalloc(VLAN_BITMAP_SIZE(nic_dev), GFP_KERNEL);
- if (!nic_dev->vlan_bitmap)
- return -ENOMEM;
+ if (!nic_dev->vlan_bitmap) {
+ nic_err(&pdev->dev, "Failed to allocate vlan bitmap\n");
+ ret = -ENOMEM;
+ goto vlan_bitmap_error;
+ }
nic_dev->workq = create_singlethread_workqueue(HINIC3_NIC_DEV_WQ_NAME);
if (!nic_dev->workq) {
nic_err(&pdev->dev, "Failed to initialize nic workqueue\n");
- kfree(nic_dev->vlan_bitmap);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto create_workq_error;
}
- INIT_DELAYED_WORK(&nic_dev->periodic_work, hinic3_periodic_work_handler);
- INIT_DELAYED_WORK(&nic_dev->rxq_check_work, hinic3_rxq_check_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->periodic_work,
+ hinic3_periodic_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->rxq_check_work,
+ hinic3_rxq_check_work_handler);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ INIT_DELAYED_WORK(&nic_dev->vport_stats_work,
+ hinic3_vport_stats_work_handler);
INIT_LIST_HEAD(&nic_dev->uc_filter_list);
INIT_LIST_HEAD(&nic_dev->mc_filter_list);
@@ -766,10 +911,23 @@ static int setup_nic_dev(struct net_device *netdev,
hinic3_init_nic_prof_adapter(nic_dev);
netdev_name_fmt = hinic3_get_dft_netdev_name_fmt(nic_dev);
- if (netdev_name_fmt)
- strscpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (netdev_name_fmt) {
+ ret = strscpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (ret < 0)
+ goto get_netdev_name_error;
+ }
return 0;
+
+get_netdev_name_error:
+ hinic3_deinit_nic_prof_adapter(nic_dev);
+ destroy_workqueue(nic_dev->workq);
+create_workq_error:
+ kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+vlan_bitmap_error:
+ free_nic_dev_vram(nic_dev);
+ return ret;
}
static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
@@ -808,6 +966,31 @@ static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
return 0;
}
+static void hinic3_bond_init(struct hinic3_nic_dev *nic_dev)
+{
+ u32 bond_id = HINIC3_INVALID_BOND_ID;
+ int err = hinic3_create_bond(nic_dev->hwdev, &bond_id);
+
+ if (err != 0)
+ goto bond_init_failed;
+
+ /* bond id does not change, means this pf is not bond active pf, no log is generated */
+ if (bond_id == HINIC3_INVALID_BOND_ID)
+ return;
+
+ err = hinic3_open_close_bond(nic_dev->hwdev, true);
+ if (err != 0) {
+ hinic3_delete_bond(nic_dev->hwdev);
+ goto bond_init_failed;
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Bond %d init success\n", bond_id);
+ return;
+
+bond_init_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond init failed\n");
+}
+
static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
char *uld_dev_name)
{
@@ -838,6 +1021,12 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
goto err_out;
}
+ err = hinic3_get_dev_cap(lld_dev->hwdev);
+ if (err != 0) {
+ nic_err(&pdev->dev, "Failed to get dev cap\n");
+ goto err_out;
+ }
+
max_qps = hinic3_func_max_nic_qnum(lld_dev->hwdev);
netdev = alloc_etherdev_mq(sizeof(*nic_dev), max_qps);
if (!netdev) {
@@ -870,10 +1059,17 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
hinic3_assign_netdev_ops(nic_dev);
netdev_feature_init(netdev);
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+ netdev->udp_tunnel_nic_info = &hinic3_udp_tunnels;
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
err = hinic3_set_default_hw_feature(nic_dev);
if (err)
goto set_features_err;
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0)
+ hinic3_bond_init(nic_dev);
+
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
hinic3_register_notifier(nic_dev);
#endif
@@ -888,6 +1084,9 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
}
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->vport_stats_work, HZ);
netif_carrier_off(netdev);
*uld_dev = nic_dev;
@@ -920,6 +1119,25 @@ err_out:
return err;
}
+static void hinic3_bond_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ int ret = 0;
+
+ ret = hinic3_open_close_bond(nic_dev->hwdev, false);
+ if (ret != 0)
+ goto bond_deinit_failed;
+
+ ret = hinic3_delete_bond(nic_dev->hwdev);
+ if (ret != 0)
+ goto bond_deinit_failed;
+
+ nic_info(&nic_dev->pdev->dev, "Bond deinit success\n");
+ return;
+
+bond_deinit_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond deinit failed\n");
+}
+
static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
{
struct hinic3_nic_dev *nic_dev = adapter;
@@ -939,6 +1157,8 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_unregister_notifier(nic_dev);
#endif
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ cancel_delayed_work_sync(&nic_dev->vport_stats_work);
cancel_delayed_work_sync(&nic_dev->periodic_work);
cancel_delayed_work_sync(&nic_dev->rxq_check_work);
cancel_work_sync(&nic_dev->rx_mode_work);
@@ -946,6 +1166,9 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_flush_rx_flow_rule(nic_dev);
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0)
+ hinic3_bond_deinit(nic_dev);
+
hinic3_update_nic_feature(nic_dev->hwdev, 0);
hinic3_set_nic_feature_to_hw(nic_dev->hwdev);
@@ -955,6 +1178,7 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_deinit_nic_prof_adapter(nic_dev);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
free_netdev(netdev);
@@ -971,8 +1195,10 @@ static void sriov_state_change(struct hinic3_nic_dev *nic_dev,
static void hinic3_port_module_event_handler(struct hinic3_nic_dev *nic_dev,
struct hinic3_event_info *event)
{
- const char *g_hinic3_module_link_err[LINK_ERR_NUM] = { "Unrecognized module" };
- struct hinic3_port_module_event *module_event = (void *)event->event_data;
+ const char *g_hinic3_module_link_err[LINK_ERR_NUM] = {
+ "Unrecognized module" };
+ struct hinic3_port_module_event *module_event =
+ (void *)event->event_data;
enum port_module_event_type type = module_event->type;
enum link_err_type err_type = module_event->err_type;
@@ -1003,6 +1229,116 @@ static void hinic3_port_module_event_handler(struct hinic3_nic_dev *nic_dev,
}
}
+bool hinic3_need_proc_link_event(struct hinic3_lld_dev *lld_dev)
+{
+ int ret = 0;
+ u16 func_id;
+ u8 roce_enable = false;
+ bool is_slave_func = false;
+ struct hinic3_hw_bond_infos hw_bond_infos = {0};
+
+ if (!lld_dev)
+ return false;
+
+ /* 非slave设备需要处理link down事件 */
+ ret = hinic3_is_slave_func(lld_dev->hwdev, &is_slave_func);
+ if (ret != 0) {
+ nic_err(&lld_dev->pdev->dev, "NIC get info, lld_dev is null\n");
+ return true;
+ }
+
+ if (!is_slave_func)
+ return true;
+
+ /* 未使能了vroce功能,需处理link down事件 */
+ func_id = hinic3_global_func_id(lld_dev->hwdev);
+ ret = hinic3_get_func_vroce_enable(lld_dev->hwdev, func_id, &roce_enable);
+ if (ret != 0)
+ return true;
+
+ if (!roce_enable)
+ return true;
+
+ /* 未创建bond,需要处理link down事件 */
+ hw_bond_infos.bond_id = HINIC_OVS_BOND_DEFAULT_ID;
+
+ ret = hinic3_get_hw_bond_infos(lld_dev->hwdev, &hw_bond_infos, HINIC3_CHANNEL_COMM);
+ if (ret != 0) {
+ pr_err("[ROCE, ERR] Get chipf bond info failed (%d)\n", ret);
+ return true;
+ }
+
+ if (!hw_bond_infos.valid)
+ return true;
+
+ return false;
+}
+
+bool hinic3_need_proc_bond_event(struct hinic3_lld_dev *lld_dev)
+{
+ return !hinic3_need_proc_link_event(lld_dev);
+}
+
+static void hinic_porc_bond_state_change(struct hinic3_lld_dev *lld_dev, void *adapter,
+ struct hinic3_event_info *event)
+{
+ struct hinic3_nic_dev *nic_dev = adapter;
+
+ if (!nic_dev || !event || !hinic3_support_nic(lld_dev->hwdev, NULL))
+ return;
+
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond down\n");
+ hinic3_link_status_change(nic_dev, false);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond up\n");
+ hinic3_link_status_change(nic_dev, true);
+ break;
+ default:
+ break;
+ }
+}
+
+static void hinic3_outband_cfg_event_handler(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_outband_cfg_info *info)
+{
+ int err = 0;
+
+ if (!nic_dev || !info || !hinic3_support_nic(nic_dev->hwdev, NULL)) {
+ pr_err("Outband cfg event invalid param\n");
+ return;
+ }
+
+ if (hinic3_func_type(nic_dev->hwdev) != TYPE_VF &&
+ info->func_id >= NIC_MAX_PF_NUM) {
+ err = hinic3_notify_vf_outband_cfg(nic_dev->hwdev,
+ info->func_id,
+ info->outband_default_vid);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev,
+ "Outband cfg event notify vf err: %d, func_id: 0x%x, vid: 0x%x\n",
+ err, info->func_id, info->outband_default_vid);
+ return;
+ }
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Change outband default vid from %u to %u\n",
+ nic_dev->outband_cfg.outband_default_vid,
+ info->outband_default_vid);
+
+ nic_dev->outband_cfg.outband_default_vid = info->outband_default_vid;
+}
+
static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
struct hinic3_event_info *event)
{
@@ -1014,21 +1350,35 @@ static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_DOWN):
+ if (!hinic3_need_proc_link_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc link event\n");
+ return;
+ }
hinic3_link_status_change(nic_dev, false);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_UP):
hinic3_link_status_change(nic_dev, true);
break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ hinic_porc_bond_state_change(lld_dev, adapter, event);
+ break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_PORT_MODULE_EVENT):
hinic3_port_module_event_handler(nic_dev, event);
break;
- case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_SRIOV_STATE_CHANGE):
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_OUTBAND_CFG):
+ hinic3_outband_cfg_event_handler(nic_dev,
+ (void *)event->event_data);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM,
+ EVENT_COMM_SRIOV_STATE_CHANGE):
sriov_state_change(nic_dev, (void *)event->event_data);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_FAULT):
fault = (void *)event->event_data;
if (fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
- fault->event.chip.func_id == hinic3_global_func_id(lld_dev->hwdev))
+ fault->event.chip.func_id ==
+ hinic3_global_func_id(lld_dev->hwdev))
hinic3_link_status_change(nic_dev, false);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_PCIE_LINK_DOWN):
@@ -1081,7 +1431,7 @@ struct hinic3_uld_info g_nic_uld_info = {
.resume = NULL,
.event = nic_event,
.ioctl = nic_ioctl,
-}; /*lint -e766*/
+};
struct hinic3_uld_info *get_nic_uld_info(void)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
index 94e606e..5bd4c3d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
@@ -9,6 +9,7 @@
/* Interrupt at most records, interrupt will be recorded in the FFM */
#define NICTOOL_CMD_TYPE (0x18)
+#define HINIC3_CARD_NAME_MAX_LEN (128)
struct api_cmd_rd {
u32 pf_id;
@@ -110,7 +111,8 @@ enum dbgtool_cmd {
DBGTOOL_CMD_NUM
};
-#define PF_MAX_SIZE (16)
+#define HINIC_PF_MAX_SIZE (16)
+#define HINIC_VF_MAX_SIZE (4096)
#define BUSINFO_LEN (32)
enum module_name {
@@ -132,7 +134,8 @@ enum module_name {
SEND_TO_MIGRATE_DRIVER,
SEND_TO_PPA_DRIVER,
SEND_TO_CUSTOM_DRIVER = SEND_TO_SRV_DRV_BASE + 11,
- SEND_TO_BIFUR_DRIVER = SEND_TO_SRV_DRV_BASE + 15,
+ SEND_TO_VSOCK_DRIVER = SEND_TO_SRV_DRV_BASE + 14,
+ SEND_TO_BIFUR_DRIVER,
SEND_TO_DRIVER_MAX = SEND_TO_SRV_DRV_BASE + 16, /* reserved */
};
@@ -160,7 +163,7 @@ enum driver_cmd_type {
GET_CHIP_FAULT_STATS,
NIC_RSVD1,
NIC_RSVD2,
- NIC_RSVD3,
+ GET_OS_HOT_REPLACE_INFO,
GET_CHIP_ID,
GET_SINGLE_CARD_INFO,
GET_FIRMWARE_ACTIVE_STATUS,
@@ -171,7 +174,7 @@ enum driver_cmd_type {
GET_LOOPBACK_MODE = 32,
SET_LOOPBACK_MODE,
SET_LINK_MODE,
- SET_PF_BW_LIMIT,
+ SET_TX_PF_BW_LIMIT,
GET_PF_BW_LIMIT,
ROCE_CMD,
GET_POLL_WEIGHT,
@@ -189,6 +192,7 @@ enum driver_cmd_type {
GET_NIC_STATS_STRING,
GET_NIC_STATS_INFO,
GET_PF_ID,
+ GET_MBOX_CNT,
NIC_RSVD4,
NIC_RSVD5,
DCB_QOS_INFO,
@@ -205,6 +209,8 @@ enum driver_cmd_type {
RSS_INDIR,
PORT_ID,
+ SET_RX_PF_BW_LIMIT = 0x43,
+
GET_FUNC_CAP = 0x50,
GET_XSFP_PRESENT = 0x51,
GET_XSFP_INFO = 0x52,
@@ -216,6 +222,10 @@ enum driver_cmd_type {
WIN_CSR_WRITE = 0x62,
WIN_API_CMD_RD = 0x63,
+ GET_FUSION_Q = 0x64,
+
+ ROCE_CMD_BOND_HASH_TYPE_SET = 0xb2,
+
BIFUR_SET_ENABLE = 0xc0,
BIFUR_GET_ENABLE = 0xc1,
@@ -234,7 +244,8 @@ enum sm_cmd_type {
SM_CTR_RD64,
SM_CTR_RD32_CLEAR,
SM_CTR_RD64_PAIR_CLEAR,
- SM_CTR_RD64_CLEAR
+ SM_CTR_RD64_CLEAR,
+ SM_CTR_RD16_CLEAR,
};
struct cqm_stats {
@@ -321,10 +332,22 @@ struct pf_info {
};
struct card_info {
- struct pf_info pf[PF_MAX_SIZE];
+ struct pf_info pf[HINIC_PF_MAX_SIZE];
u32 pf_num;
};
+struct func_mbox_cnt_info {
+ char bus_info[BUSINFO_LEN];
+ u64 send_cnt;
+ u64 ack_cnt;
+};
+
+struct card_mbox_cnt_info {
+ struct func_mbox_cnt_info func_info[HINIC_PF_MAX_SIZE +
+ HINIC_VF_MAX_SIZE];
+ u32 func_num;
+};
+
struct hinic3_nic_loop_mode {
u32 loop_mode;
u32 loop_ctrl;
@@ -665,6 +688,162 @@ struct get_card_bond_msg_s {
struct bond_all_msg_s all_msg[MAX_BONDING_CNT_PER_CARD];
};
+#define MAX_FUSION_Q_STATS_STR_LEN 16
+#define MAX_FUSION_Q_NUM 256
+struct queue_status_s {
+ pid_t tgid;
+ char status[MAX_FUSION_Q_STATS_STR_LEN];
+};
+
+struct fusion_q_status_s {
+ u16 queue_num;
+ struct queue_status_s queue[MAX_FUSION_Q_NUM];
+};
+
+struct fusion_q_tx_hw_page {
+ u64 phy_addr;
+ u64 *map_addr;
+};
+
+struct fusion_sq_info {
+ u16 q_id;
+ u16 pi;
+ u16 ci; /* sw_ci */
+ u16 fi; /* hw_ci */
+ u32 q_depth;
+ u16 pi_reverse;
+ u16 wqebb_size;
+ u8 priority;
+ u16 *ci_addr;
+ u64 cla_addr;
+ void *slq_handle;
+ struct fusion_q_tx_hw_page direct_wqe;
+ struct fusion_q_tx_hw_page doorbell;
+ u32 page_idx;
+ u32 glb_sq_id;
+};
+
+struct fusion_q_tx_wqe {
+ u32 data[4];
+};
+
+struct fusion_rq_info {
+ u16 q_id;
+ u16 delta;
+ u16 hw_pi;
+ u16 ci; /* sw_ci */
+ u16 sw_pi;
+ u16 wqebb_size;
+ u16 q_depth;
+ u16 buf_len;
+
+ void *slq_handle;
+ u64 ci_wqe_page_addr;
+ u64 ci_cla_tbl_addr;
+
+ u8 coalesc_timer_cfg;
+ u8 pending_limt;
+ u16 msix_idx;
+ u32 msix_vector;
+};
+
+struct fusion_q_rx_wqe {
+ u32 data[8];
+};
+
+struct fusion_q_rx_cqe {
+ union {
+ struct {
+ unsigned int checksum_err : 16;
+ unsigned int lro_num : 8;
+ unsigned int rsvd1 : 7;
+ unsigned int rx_done : 1;
+ } bs;
+ unsigned int value;
+ } dw0;
+
+ union {
+ struct {
+ unsigned int vlan : 16;
+ unsigned int length : 16;
+ } bs;
+ unsigned int value;
+ } dw1;
+
+ union {
+ struct {
+ unsigned int pkt_types : 12;
+ unsigned int rsvd : 4;
+ unsigned int udp_0 : 1;
+ unsigned int ipv6_ex_add : 1;
+ unsigned int loopback : 1;
+ unsigned int umbcast : 2;
+ unsigned int vlan_offload_en : 1;
+ unsigned int tag_num : 2;
+ unsigned int rss_type : 8;
+ } bs;
+ unsigned int value;
+ } dw2;
+
+ union {
+ struct {
+ unsigned int rss_hash_value;
+ } bs;
+ unsigned int value;
+ } dw3;
+
+ union {
+ struct {
+ unsigned int tx_ts_seq : 16;
+ unsigned int message_1588_offset : 8;
+ unsigned int message_1588_type : 4;
+ unsigned int rsvd : 1;
+ unsigned int if_rx_ts : 1;
+ unsigned int if_tx_ts : 1;
+ unsigned int if_1588 : 1;
+ } bs;
+ unsigned int value;
+ } dw4;
+
+ union {
+ struct {
+ unsigned int ts;
+ } bs;
+ unsigned int value;
+ } dw5;
+
+ union {
+ struct {
+ unsigned int lro_ts;
+ } bs;
+ unsigned int value;
+ } dw6;
+
+ union {
+ struct {
+ unsigned int rsvd0;
+ } bs;
+ unsigned int value;
+ } dw7; /* 16Bytes Align */
+};
+
+struct os_hot_repalce_func_info {
+ char card_name[HINIC3_CARD_NAME_MAX_LEN];
+ u32 bus_num;
+ u32 valid;
+ u32 bdf;
+ int partition;
+ u16 backup_pf;
+ u16 pf_idx;
+ int port_id;
+};
+
+#define ALL_CARD_PF_NUM 2048 /* 64 card * 32 pf */
+struct os_hot_replace_info {
+ struct os_hot_repalce_func_info func_infos[ALL_CARD_PF_NUM];
+ u32 func_cnt;
+};
+
int alloc_buff_in(void *hwdev, struct msg_module *nt_msg, u32 in_size, void **buf_in);
int alloc_buff_out(void *hwdev, struct msg_module *nt_msg, u32 out_size, void **buf_out);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
index ea1d506..c4b3d5b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
@@ -15,6 +15,9 @@
#include <linux/ip.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#ifdef HAVE_XDP_SUPPORT
#include <linux/bpf.h>
#endif
@@ -28,6 +31,10 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
+#include "nic_npu_cmd.h"
+
+#include "vram_common.h"
+
#define HINIC3_DEFAULT_RX_CSUM_OFFLOAD 0xFFF
#define HINIC3_LRO_DEFAULT_COAL_PKT_SIZE 32
@@ -47,8 +54,62 @@ static void hinic3_nic_set_rx_mode(struct net_device *netdev)
queue_work(nic_dev->workq, &nic_dev->rx_mode_work);
}
+static void hinic3_free_irq_vram(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_dyna_txrxq_params *in_q_params)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ struct hinic3_dyna_txrxq_params q_params = nic_dev->q_params;
+
+ if (!q_params.irq_cfg)
+ return;
+
+ size = sizeof(struct hinic3_irq) * (q_params.num_qps);
+
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)q_params.irq_cfg, q_params.irq_cfg_vram_name, size);
+ q_params.irq_cfg = NULL;
+ } else {
+ kfree(in_q_params->irq_cfg);
+ in_q_params->irq_cfg = NULL;
+ }
+}
+
+static int hinic3_alloc_irq_vram(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_dyna_txrxq_params *q_params,
+ bool is_up_eth)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ u16 func_id;
+
+ size = sizeof(struct hinic3_irq) * q_params->num_qps;
+
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(q_params->irq_cfg_vram_name, VRAM_NAME_MAX_LEN,
+ "%s%hu", VRAM_NIC_IRQ_VRAM, func_id);
+ q_params->irq_cfg = (struct hinic3_irq *)hi_vram_kalloc(q_params->irq_cfg_vram_name,
+ size);
+ if (!q_params->irq_cfg) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq vram alloc failed.\n");
+ return -ENOMEM;
+ }
+ /* in order to clear napi stored in vram, irq need to init when eth up */
+ if (is_up_eth)
+ memset(q_params->irq_cfg, 0, size);
+ } else {
+ q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
+ if (!q_params->irq_cfg)
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_txrxq_params *q_params)
+ struct hinic3_dyna_txrxq_params *q_params,
+ bool is_up_eth)
{
u32 size;
int err;
@@ -70,12 +131,9 @@ static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
goto alloc_rxqs_res_arr_err;
}
- size = sizeof(*q_params->irq_cfg) * q_params->num_qps;
- q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
- if (!q_params->irq_cfg) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to alloc irq resource array\n");
- err = -ENOMEM;
+ err = hinic3_alloc_irq_vram(nic_dev, q_params, is_up_eth);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc irq resource array\n");
goto alloc_irq_cfg_err;
}
@@ -102,8 +160,7 @@ alloc_rxqs_res_err:
q_params->txqs_res);
alloc_txqs_res_err:
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ hinic3_free_irq_vram(nic_dev, q_params);
alloc_irq_cfg_err:
kfree(q_params->rxqs_res);
@@ -117,15 +174,17 @@ alloc_rxqs_res_arr_err:
}
static void hinic3_free_txrxq_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_txrxq_params *q_params)
+ struct hinic3_dyna_txrxq_params *q_params)
{
+ int is_in_kexec = vram_get_kexec_flag();
+
hinic3_free_rxqs_res(nic_dev, q_params->num_qps, q_params->rq_depth,
q_params->rxqs_res);
hinic3_free_txqs_res(nic_dev, q_params->num_qps, q_params->sq_depth,
q_params->txqs_res);
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ if (is_in_kexec == 0)
+ hinic3_free_irq_vram(nic_dev, q_params);
kfree(q_params->rxqs_res);
q_params->rxqs_res = NULL;
@@ -161,6 +220,7 @@ static int hinic3_configure_txrxqs(struct hinic3_nic_dev *nic_dev,
static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos;
if (!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
@@ -171,12 +231,13 @@ static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
num_cos = hinic3_get_dev_user_cos_num(nic_dev);
hinic3_update_qp_cos_cfg(nic_dev, num_cos);
/* For now, we don't support to change num_cos */
- if (num_cos > nic_dev->cos_config_num_max ||
+ if (num_cos > dcb->cos_config_num_max ||
nic_dev->q_params.num_qps < num_cos) {
nicif_err(nic_dev, drv, netdev, "Invalid num_cos: %u or num_qps: %u, disable DCB\n",
num_cos, nic_dev->q_params.num_qps);
nic_dev->q_params.num_cos = 0;
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
/* if we can't enable rss or get enough num_qps,
* need to sync default configure to hw
*/
@@ -190,17 +251,22 @@ static int hinic3_configure(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
- err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
- if (err) {
- nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
- return err;
+ if (is_in_kexec == 0) {
+ err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
+ return err;
+ }
}
config_dcb_qps_map(nic_dev);
/* rx rss init */
- err = hinic3_rx_configure(netdev, test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ err = hinic3_rx_configure(netdev,
+ test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)
+ ? 1 : 0);
if (err) {
nicif_err(nic_dev, drv, netdev, "Failed to configure rx\n");
return err;
@@ -256,10 +322,11 @@ static void config_dcb_num_qps(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dyna_txrxq_params *q_params,
u16 max_qps)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos = q_params->num_cos;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (!num_cos || num_cos > nic_dev->cos_config_num_max || num_cos > max_qps)
+ if (!num_cos || num_cos > dcb->cos_config_num_max || num_cos > max_qps)
return; /* will disable DCB in config_dcb_qps_map() */
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
@@ -332,57 +399,10 @@ static void hinic3_destroy_num_qps(struct hinic3_nic_dev *nic_dev)
kfree(nic_dev->qps_irq_info);
}
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev)
-{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- err = hinic3_set_port_enable(nic_dev->hwdev, false, HINIC3_CHANNEL_NIC);
- if (!err)
- nic_dev->force_port_disable = true;
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
-{
- int err = 0;
-
- down(&nic_dev->port_state_sem);
-
- nic_dev->force_port_disable = false;
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
- HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- /* Do nothing when force disable
- * Port will disable when call force port disable
- * and should not enable port when in force mode
- */
- if (nic_dev->force_port_disable) {
- up(&nic_dev->port_state_sem);
- return 0;
- }
-
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
- HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
+ return hinic3_set_port_enable(nic_dev->hwdev, enable,
+ HINIC3_CHANNEL_NIC);
}
static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
@@ -398,8 +418,8 @@ static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
}
static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+ struct hinic3_dyna_qp_params *qp_params,
+ struct hinic3_dyna_txrxq_params *trxq_params, bool is_up_eth)
{
int err;
@@ -414,7 +434,7 @@ static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
return err;
}
- err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params);
+ err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params, is_up_eth);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc txrxq resources\n");
hinic3_free_qps(nic_dev->hwdev, qp_params);
@@ -425,8 +445,8 @@ static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
}
static void hinic3_free_channel_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+ struct hinic3_dyna_qp_params *qp_params,
+ struct hinic3_dyna_txrxq_params *trxq_params)
{
mutex_lock(&nic_dev->nic_mutex);
hinic3_free_txrxq_resources(nic_dev, trxq_params);
@@ -521,7 +541,8 @@ int hinic3_vport_up(struct hinic3_nic_dev *nic_dev)
queue_delayed_work(nic_dev->workq, &nic_dev->moderation_task,
HINIC3_MODERATONE_DELAY);
if (test_bit(HINIC3_RXQ_RECOVERY, &nic_dev->flags))
- queue_delayed_work(nic_dev->workq, &nic_dev->rxq_check_work, HZ);
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->rxq_check_work, HZ);
hinic3_print_link_message(nic_dev, link_status);
@@ -542,9 +563,52 @@ vport_enable_err:
return err;
}
+static int hinic3_flush_rq_and_check(struct hinic3_nic_dev *nic_dev, u16 glb_func_id)
+{
+ struct hinic3_flush_rq *rq_flush_msg = NULL;
+ struct hinic3_cmd_buf *cmd_buf = NULL;
+ int out_buf_len = sizeof(struct hinic3_flush_rq);
+ u16 rq_id;
+ u64 out_param = 0;
+ int ret;
+
+ cmd_buf = hinic3_alloc_cmd_buf(nic_dev->hwdev);
+ if (!cmd_buf) {
+ nic_err(&nic_dev->pdev->dev, "Failed to allocate cmd buf\n");
+ return -ENOMEM;
+ }
+
+ cmd_buf->size = sizeof(struct hinic3_flush_rq);
+ rq_flush_msg = (struct hinic3_flush_rq *)cmd_buf->buf;
+ rq_flush_msg->dw.bs.func_id = glb_func_id;
+ for (rq_id = 0; rq_id < nic_dev->q_params.num_qps; rq_id++) {
+ rq_flush_msg->dw.bs.rq_id = rq_id;
+ hinic3_cpu_to_be32(rq_flush_msg, out_buf_len);
+ ret = hinic3_cmdq_direct_resp(nic_dev->hwdev, HINIC3_MOD_L2NIC,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ cmd_buf, &out_param, 0,
+ HINIC3_CHANNEL_NIC);
+ if (ret != 0 || out_param != 0) {
+ nic_err(&nic_dev->pdev->dev, "Failed to flush rq, ret:%d, func:%u, rq:%u\n",
+ ret, glb_func_id, rq_id);
+ goto err;
+ }
+ hinic3_be32_to_cpu(rq_flush_msg, out_buf_len);
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Func:%u rq_num:%u flush rq success\n",
+ glb_func_id, nic_dev->q_params.num_qps);
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return 0;
+err:
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return -1;
+}
+
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
{
u16 glb_func_id;
+ int is_in_kexec = vram_get_kexec_flag();
netif_carrier_off(nic_dev->netdev);
netif_tx_disable(nic_dev->netdev);
@@ -557,18 +621,21 @@ void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, 0);
- hinic3_maybe_set_port_state(nic_dev, false);
+ if (is_in_kexec != 0)
+ nicif_info(nic_dev, drv, nic_dev->netdev, "Skip changing mag status!\n");
+ else
+ hinic3_maybe_set_port_state(nic_dev, false);
glb_func_id = hinic3_global_func_id(nic_dev->hwdev);
hinic3_set_vport_enable(nic_dev->hwdev, glb_func_id, false,
HINIC3_CHANNEL_NIC);
hinic3_flush_txqs(nic_dev->netdev);
- /* After set vport disable 100ms,
- * no packets will be send to host
- * FPGA set 2000ms
- */
- msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+
+ if (is_in_kexec == 0)
+ msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+ else
+ (void)hinic3_flush_rq_and_check(nic_dev, glb_func_id);
hinic3_flush_qps_res(nic_dev->hwdev);
}
}
@@ -581,11 +648,12 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_qp_params new_qp_params = {0};
struct hinic3_dyna_qp_params cur_qp_params = {0};
int err;
+ bool is_free_resources = false;
hinic3_config_num_qps(nic_dev, trxq_params);
err = hinic3_alloc_channel_resources(nic_dev, &new_qp_params,
- trxq_params);
+ trxq_params, false);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc channel resources\n");
@@ -597,10 +665,19 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
hinic3_close_channel(nic_dev, &cur_qp_params);
hinic3_free_channel_resources(nic_dev, &cur_qp_params,
&nic_dev->q_params);
+ is_free_resources = true;
}
if (nic_dev->num_qp_irq > trxq_params->num_qps)
hinic3_qp_irq_change(nic_dev, trxq_params->num_qps);
+
+ if (is_free_resources) {
+ err = hinic3_alloc_irq_vram(nic_dev, trxq_params, false);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Change chl alloc irq failed\n");
+ goto alloc_irq_err;
+ }
+ }
nic_dev->q_params = *trxq_params;
if (reopen_handler)
@@ -621,7 +698,7 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
vport_up_err:
hinic3_close_channel(nic_dev, &new_qp_params);
-
+alloc_irq_err:
open_channel_err:
hinic3_free_channel_resources(nic_dev, &new_qp_params, trxq_params);
@@ -652,7 +729,7 @@ int hinic3_open(struct net_device *netdev)
}
err = hinic3_alloc_channel_resources(nic_dev, &qp_params,
- &nic_dev->q_params);
+ &nic_dev->q_params, true);
if (err)
goto alloc_channel_res_err;
@@ -691,12 +768,31 @@ setup_qps_err:
return err;
}
+static void hinic3_delete_napi(struct hinic3_nic_dev *nic_dev)
+{
+ u16 q_id;
+ int is_in_kexec = vram_get_kexec_flag();
+ struct hinic3_irq *irq_cfg = NULL;
+
+ if (is_in_kexec == 0 || !nic_dev->q_params.irq_cfg)
+ return;
+
+ for (q_id = 0; q_id < nic_dev->q_params.num_qps; q_id++) {
+ irq_cfg = &nic_dev->q_params.irq_cfg[q_id];
+ qp_del_napi(irq_cfg);
+ }
+
+ hinic3_free_irq_vram(nic_dev, &nic_dev->q_params);
+}
+
int hinic3_close(struct net_device *netdev)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic3_dyna_qp_params qp_params = {0};
if (!test_and_clear_bit(HINIC3_INTF_UP, &nic_dev->flags)) {
+ /* delete napi in os hotreplace rollback */
+ hinic3_delete_napi(nic_dev);
nicif_info(nic_dev, drv, netdev, "Netdev already close, do nothing\n");
return 0;
}
@@ -776,7 +872,8 @@ static u8 parse_ipv6_info(struct sk_buff *skb, u32 *rss_tunple,
return 0;
}
-static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb,
+static u16 select_queue_by_hash_func(struct net_device *dev,
+ struct sk_buff *skb,
unsigned int num_tx_queues)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(dev);
@@ -831,17 +928,20 @@ static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb
}
#define GET_DSCP_PRI_OFFSET 2
-static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev, struct sk_buff *skb)
+static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev,
+ struct sk_buff *skb)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int dscp_cp;
if (skb->protocol == htons(ETH_P_IP))
dscp_cp = ipv4_get_dsfield(ip_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
else if (skb->protocol == htons(ETH_P_IPV6))
- dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
+ dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >>
+ GET_DSCP_PRI_OFFSET;
else
- return nic_dev->hw_dcb_cfg.default_cos;
- return nic_dev->hw_dcb_cfg.dscp2cos[dscp_cp];
+ return dcb->hw_dcb_cfg.default_cos;
+ return dcb->hw_dcb_cfg.dscp2cos[dscp_cp];
}
#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY)
@@ -867,11 +967,13 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif /* end of HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK */
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u16 txq;
u8 cos, qp_num;
if (test_bit(HINIC3_SAME_RXTX, &nic_dev->flags))
- return select_queue_by_hash_func(netdev, skb, netdev->real_num_tx_queues);
+ return select_queue_by_hash_func(netdev, skb,
+ netdev->real_num_tx_queues);
txq =
#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY)
@@ -887,18 +989,19 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (nic_dev->hw_dcb_cfg.trust == DCB_PCP) {
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP) {
if (skb->vlan_tci)
- cos = nic_dev->hw_dcb_cfg.pcp2cos[skb->vlan_tci >> VLAN_PRIO_SHIFT];
+ cos = dcb->hw_dcb_cfg.pcp2cos[skb->vlan_tci >>
+ VLAN_PRIO_SHIFT];
else
- cos = nic_dev->hw_dcb_cfg.default_cos;
+ cos = dcb->hw_dcb_cfg.default_cos;
} else {
cos = hinic3_get_dscp_up(nic_dev, skb);
}
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cos] ?
- txq % nic_dev->hw_dcb_cfg.cos_qp_num[cos] : 0;
- txq = nic_dev->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
+ qp_num = dcb->hw_dcb_cfg.cos_qp_num[cos] ?
+ txq % dcb->hw_dcb_cfg.cos_qp_num[cos] : 0;
+ txq = dcb->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
}
return txq;
@@ -976,7 +1079,7 @@ static struct net_device_stats *hinic3_get_stats(struct net_device *netdev)
stats->rx_packets = packets;
stats->rx_bytes = bytes;
stats->rx_errors = errors;
- stats->rx_dropped = dropped;
+ stats->rx_dropped = dropped + nic_dev->vport_stats.rx_discard_vport;
#ifndef HAVE_VOID_NDO_GET_STATS64
return stats;
@@ -1023,10 +1126,18 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
u32 mtu = (u32)new_mtu;
int err = 0;
+ int is_in_kexec = vram_get_kexec_flag();
#ifdef HAVE_XDP_SUPPORT
u32 xdp_max_mtu;
+#endif
+
+ if (is_in_kexec != 0) {
+ nicif_info(nic_dev, drv, netdev, "Hotreplace skip change mtu\n");
+ return err;
+ }
+#ifdef HAVE_XDP_SUPPORT
if (hinic3_is_xdp_enable(nic_dev)) {
xdp_max_mtu = hinic3_xdp_max_mtu(nic_dev);
if (mtu > xdp_max_mtu) {
@@ -1045,6 +1156,7 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
nicif_info(nic_dev, drv, nic_dev->netdev, "Change mtu from %u to %d\n",
netdev->mtu, new_mtu);
netdev->mtu = mtu;
+ nic_dev->nic_vram->vram_mtu = mtu;
}
return err;
@@ -1078,6 +1190,76 @@ static int hinic3_set_mac_addr(struct net_device *netdev, void *addr)
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+static int hinic3_udp_tunnel_port_config(struct net_device *netdev,
+ struct udp_tunnel_info *ti,
+ u8 action)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u16 func_id = hinic3_global_func_id(nic_dev->hwdev);
+ u16 dst_port;
+ int ret = 0;
+
+ switch (ti->type) {
+ case UDP_TUNNEL_TYPE_VXLAN:
+ dst_port = ntohs(ti->port);
+ ret = hinic3_vlxan_port_config(nic_dev->hwdev,
+ func_id, dst_port, action);
+ if (ret != 0) {
+ nicif_warn(nic_dev, drv, netdev,
+ "Failed to set vxlan port %u to device\n",
+ dst_port);
+ break;
+ }
+ nicif_info(nic_dev, link, netdev, "Vxlan dst port set to %u\n",
+ action == HINIC3_CMD_OP_ADD ?
+ dst_port : ntohs(VXLAN_OFFLOAD_PORT_LE));
+ break;
+ default:
+ nicif_err(nic_dev, drv, netdev, "Failed to add port, only vxlan dst port is supported\n");
+ ret = -EINVAL;
+ }
+ return ret;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+static void hinic3_udp_tunnel_add(struct net_device *netdev,
+ struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+static void hinic3_udp_tunnel_del(struct net_device *netdev,
+ struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD */
+
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev,
+ __always_unused unsigned int table,
+ __always_unused unsigned int entry,
+ struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev,
+ __always_unused unsigned int table,
+ __always_unused unsigned int entry,
+ struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static int
hinic3_vlan_rx_add_vid(struct net_device *netdev,
__always_unused __be16 proto,
@@ -1124,7 +1306,7 @@ hinic3_vlan_rx_kill_vid(struct net_device *netdev,
int err = 0;
col = VID_COL(nic_dev, vid);
- line = VID_LINE(nic_dev, vid);
+ line = (int)VID_LINE(nic_dev, vid);
/* In the broadcast scenario, ucode finds the corresponding function
* based on VLAN 0 of vlan table. If we delete VLAN 0, the VLAN function
@@ -1163,14 +1345,12 @@ static int hinic3_vlan_restore(struct net_device *netdev)
return -EFAULT;
rcu_read_lock();
for (i = 0; i < VLAN_N_VID; i++) {
-/* lint -e778 */
#ifdef HAVE_VLAN_FIND_DEV_DEEP_RCU
vlandev =
__vlan_find_dev_deep_rcu(netdev, htons(ETH_P_8021Q), i);
#else
vlandev = __vlan_find_dev_deep(netdev, htons(ETH_P_8021Q), i);
#endif
-/* lint +e778 */
col = VID_COL(nic_dev, i);
line = VID_LINE(nic_dev, i);
if (!vlandev && (vlan_bitmap[line] & (1UL << col)) != 0) {
@@ -1328,12 +1508,17 @@ static int set_feature_vlan_filter(struct hinic3_nic_dev *nic_dev,
return 0;
#ifdef NEED_VLAN_RESTORE
- if (en)
+ if (en) {
err = hinic3_vlan_restore(nic_dev->netdev);
+ if (err) {
+ hinic3_err(nic_dev, drv, "vlan restore failed\n");
+ *failed_features |= vlan_filter_feature;
+ return err;
+ }
+ }
#endif
- if (err == 0)
- err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
+ err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
if (err) {
hinic3_err(nic_dev, drv, "%s rx vlan filter failed\n",
SET_FEATURES_OP_STR(en));
@@ -1427,8 +1612,8 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
struct hinic3_nic_dev *adapter = netdev_priv(netdev);
int err;
- if (is_multicast_ether_addr(mac) || /*lint !e574*/
- vf >= pci_num_vf(adapter->pdev)) /*lint !e574*/
+ if (is_multicast_ether_addr(mac) ||
+ vf >= pci_num_vf(adapter->pdev))
return -EINVAL;
err = hinic3_set_vf_mac(adapter->hwdev, OS_VF_ID_TO_HW(vf), mac);
@@ -1446,7 +1631,6 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
return 0;
}
-/*lint -save -e574 -e734*/
#ifdef IFLA_VF_MAX
static int set_hw_vf_vlan(void *hwdev, u16 cur_vlanprio, int vf,
u16 vlan, u8 qos)
@@ -1529,7 +1713,8 @@ static int hinic3_ndo_set_vf_spoofchk(struct net_device *netdev, int vf,
#endif
#ifdef HAVE_NDO_SET_VF_TRUST
-static int hinic3_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting)
+static int hinic3_ndo_set_vf_trust(struct net_device *netdev, int vf,
+ bool setting)
{
struct hinic3_nic_dev *adapter = netdev_priv(netdev);
int err;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
index 11c1731..d8c5419 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
@@ -10,6 +10,8 @@
#include "hinic3_common.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
/* ************************ array index define ********************* */
#define ARRAY_INDEX_0 0
@@ -21,6 +23,35 @@
#define ARRAY_INDEX_6 6
#define ARRAY_INDEX_7 7
+#define XSFP_TLV_PRE_INFO_LEN 4
+
+enum hinic3_link_port_type {
+ LINK_PORT_UNKNOWN,
+ LINK_PORT_OPTICAL_MM,
+ LINK_PORT_OPTICAL_SM,
+ LINK_PORT_PAS_COPPER,
+ LINK_PORT_ACC,
+ LINK_PORT_BASET,
+ LINK_PORT_AOC = 0x40,
+ LINK_PORT_ELECTRIC,
+ LINK_PORT_BACKBOARD_INTERFACE,
+};
+
+enum hilink_fibre_subtype {
+ FIBRE_SUBTYPE_SR = 1,
+ FIBRE_SUBTYPE_LR,
+ FIBRE_SUBTYPE_MAX,
+};
+
+enum hilink_fec_type {
+ HILINK_FEC_NOT_SET,
+ HILINK_FEC_RSFEC,
+ HILINK_FEC_BASEFEC,
+ HILINK_FEC_NOFEC,
+ HILINK_FEC_LLRSFE,
+ HILINK_FEC_MAX_TYPE,
+};
+
#define SQ_CI_ADDR_SHIFT 2
#define RQ_CI_ADDR_SHIFT 4
@@ -71,6 +102,12 @@ struct hinic3_port_routine_cmd {
struct mag_cmd_get_xsfp_present abs;
};
+struct hinic3_port_routine_cmd_extern {
+ bool mpu_send_xsfp_tlv_info;
+
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp std_xsfp_tlv_info;
+};
+
struct hinic3_nic_cfg {
struct semaphore cfg_lock;
@@ -84,11 +121,13 @@ struct hinic3_nic_cfg {
struct nic_port_info port_info;
/* percentage of pf link bandwidth */
- u32 pf_bw_limit;
- u32 rsvd2;
+ u32 pf_bw_tx_limit;
+ u32 pf_bw_rx_limit;
- struct hinic3_port_routine_cmd rt_cmd;
- struct mutex sfp_mutex; /* mutex used for copy sfp info */
+ struct hinic3_port_routine_cmd rt_cmd;
+ struct hinic3_port_routine_cmd_extern rt_cmd_ext;
+ /* mutex used for copy sfp info */
+ struct mutex sfp_mutex;
};
struct hinic3_nic_cmdq_ops;
@@ -98,7 +137,7 @@ struct hinic3_nic_io {
void *dev_hdl;
u8 link_status;
- u8 rsvd1;
+ u8 direct;
u32 rsvd2;
struct hinic3_io_queue *sq;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
index 747ac03..fc3c90a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
@@ -21,11 +21,133 @@
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_nic_cmdq.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_common.h"
#include "hinic3_nic_cfg.h"
-int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_sq_attr *attr)
+#include "vram_common.h"
+
+int hinic3_delete_bond(void *hwdev)
+{
+ struct hinic3_cmd_delete_bond cmd_delete_bond;
+ u16 out_size = sizeof(cmd_delete_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_delete_bond, 0, sizeof(cmd_delete_bond));
+ cmd_delete_bond.bond_id = HINIC3_INVALID_BOND_ID;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_DELETE,
+ &cmd_delete_bond, sizeof(cmd_delete_bond),
+ &cmd_delete_bond, &out_size);
+ if (err || !out_size || cmd_delete_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to delete bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_delete_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_delete_bond.bond_id != HINIC3_INVALID_BOND_ID)
+ nic_info(nic_io->dev_hdl, "Delete bond success\n");
+
+ return 0;
+}
+
+int hinic3_open_close_bond(void *hwdev, u32 bond_en)
+{
+ struct hinic3_cmd_open_close_bond cmd_open_close_bond;
+ u16 out_size = sizeof(cmd_open_close_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_open_close_bond, 0, sizeof(cmd_open_close_bond));
+ cmd_open_close_bond.open_close_bond_info.bond_id =
+ HINIC3_INVALID_BOND_ID;
+ cmd_open_close_bond.open_close_bond_info.open_close_flag = bond_en;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_OPEN_CLOSE,
+ &cmd_open_close_bond,
+ sizeof(cmd_open_close_bond),
+ &cmd_open_close_bond, &out_size);
+ if (err || !out_size || cmd_open_close_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to %s bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ bond_en ? "open" : "close", err,
+ cmd_open_close_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_open_close_bond.open_close_bond_info.bond_id !=
+ HINIC3_INVALID_BOND_ID) {
+ nic_info(nic_io->dev_hdl, "%s bond success\n",
+ bond_en ? "Open" : "Close");
+ }
+
+ return 0;
+}
+
+int hinic3_create_bond(void *hwdev, u32 *bond_id)
+{
+ struct hinic3_cmd_create_bond cmd_create_bond;
+ u16 out_size = sizeof(cmd_create_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_create_bond, 0, sizeof(cmd_create_bond));
+ cmd_create_bond.create_bond_info.default_param_flag = true;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_CREATE,
+ &cmd_create_bond, sizeof(cmd_create_bond),
+ &cmd_create_bond, &out_size);
+ if (err || !out_size || cmd_create_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to create default bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_create_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_create_bond.create_bond_info.bond_id !=
+ HINIC3_INVALID_BOND_ID) {
+ *bond_id = cmd_create_bond.create_bond_info.bond_id;
+ nic_info(nic_io->dev_hdl, "Create bond success\n");
+ }
+
+ return 0;
+}
+
+int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io,
+ struct hinic3_sq_attr *attr)
{
struct hinic3_cmd_cons_idx_attr cons_idx_attr;
u16 out_size = sizeof(cons_idx_attr);
@@ -48,7 +170,8 @@ int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_sq_attr *at
cons_idx_attr.l2nic_sqn = attr->l2nic_sqn;
cons_idx_attr.ci_addr = attr->ci_dma_base >> SQ_CI_ADDR_SHIFT;
- err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_SQ_CI_ATTR_SET,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC3_NIC_CMD_SQ_CI_ATTR_SET,
&cons_idx_attr, sizeof(cons_idx_attr),
&cons_idx_attr, &out_size);
if (err || !out_size || cons_idx_attr.msg_head.status) {
@@ -61,7 +184,8 @@ int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_sq_attr *at
return 0;
}
-int hinic3_set_rq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_rq_attr *attr)
+int hinic3_set_rq_ci_ctx(struct hinic3_nic_io *nic_io,
+ struct hinic3_rq_attr *attr)
{
struct hinic3_rq_cqe_ctx cons_idx_ctx;
u16 out_size = sizeof(cons_idx_ctx);
@@ -76,15 +200,19 @@ int hinic3_set_rq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_rq_attr *at
cons_idx_ctx.timer_loop = attr->coalescing_time;
cons_idx_ctx.threshold_cqe_num = attr->pending_limit;
cons_idx_ctx.msix_entry_idx = attr->intr_idx;
- cons_idx_ctx.ci_addr_hi = upper_32_bits(attr->ci_dma_base >> RQ_CI_ADDR_SHIFT);
- cons_idx_ctx.ci_addr_lo = lower_32_bits(attr->ci_dma_base >> RQ_CI_ADDR_SHIFT);
+ cons_idx_ctx.ci_addr_hi = upper_32_bits(attr->ci_dma_base >>
+ RQ_CI_ADDR_SHIFT);
+ cons_idx_ctx.ci_addr_lo = lower_32_bits(attr->ci_dma_base >>
+ RQ_CI_ADDR_SHIFT);
- err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_SET_RQ_CI_CTX,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC3_NIC_CMD_SET_RQ_CI_CTX,
&cons_idx_ctx, sizeof(cons_idx_ctx),
&cons_idx_ctx, &out_size);
if (err || !out_size || cons_idx_ctx.msg_head.status) {
nic_err(nic_io->dev_hdl, "Set rq cqe ctx fail, qid: %d, err: %d, status: 0x%x, out_size: 0x%x",
- attr->l2nic_rqn, err, cons_idx_ctx.msg_head.status, out_size);
+ attr->l2nic_rqn, err,
+ cons_idx_ctx.msg_head.status, out_size);
return -EFAULT;
}
@@ -142,8 +270,8 @@ int hinic3_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
&mac_info, sizeof(mac_info),
&mac_info, &out_size, channel);
if (err || !out_size ||
- hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
- mac_info.vlan_id)) {
+ (hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
+ mac_info.vlan_id) != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, mac_info.msg_head.status, out_size, channel);
@@ -178,6 +306,8 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -193,7 +323,8 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
&mac_info, sizeof(mac_info), &mac_info,
&out_size, channel);
if (err || !out_size ||
- (mac_info.msg_head.status && !PF_SET_VF_MAC(hwdev, mac_info.msg_head.status))) {
+ (mac_info.msg_head.status &&
+ !PF_SET_VF_MAC(hwdev, mac_info.msg_head.status))) {
nic_err(nic_io->dev_hdl,
"Failed to delete MAC, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, mac_info.msg_head.status, out_size, channel);
@@ -223,6 +354,8 @@ int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -239,8 +372,8 @@ int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
&mac_info, sizeof(mac_info),
&mac_info, &out_size);
if (err || !out_size ||
- hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
- mac_info.vlan_id)) {
+ (hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
+ mac_info.vlan_id) != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x\n",
err, mac_info.msg_head.status, out_size);
@@ -273,6 +406,8 @@ int hinic3_get_default_mac(void *hwdev, u8 *mac_addr)
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
mac_info.func_id = hinic3_global_func_id(hwdev);
@@ -318,6 +453,45 @@ static int hinic3_config_vlan(struct hinic3_nic_io *nic_io, u8 opcode,
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action)
+{
+ struct hinic3_cmd_vxlan_port_info vxlan_port_info;
+ u16 out_size = sizeof(vxlan_port_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ memset(&vxlan_port_info, 0, sizeof(vxlan_port_info));
+ vxlan_port_info.opcode = action;
+ vxlan_port_info.cfg_mode = 0; // other tool set
+ vxlan_port_info.func_id = func_id;
+ vxlan_port_info.vxlan_port = port;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+ &vxlan_port_info, sizeof(vxlan_port_info),
+ &vxlan_port_info, &out_size);
+ if (err || !out_size || vxlan_port_info.msg_head.status) {
+ if (vxlan_port_info.msg_head.status == 0x2) // other tool set failed
+ nic_warn(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port because it has already been set by hinicadm\n",
+ action == HINIC3_CMD_OP_ADD
+ ? "add" : "delete");
+ else
+ nic_err(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port, err: %d, status: 0x%x, out size: 0x%x\n",
+ action == HINIC3_CMD_OP_ADD ? "add" : "delete",
+ err, vxlan_port_info.msg_head.status, out_size);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
{
struct hinic3_nic_io *nic_io = NULL;
@@ -326,6 +500,8 @@ int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan_id, func_id);
}
@@ -337,6 +513,8 @@ int hinic3_del_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_DEL, vlan_id, func_id);
}
@@ -380,6 +558,8 @@ int hinic3_set_dcb_state(void *hwdev, struct hinic3_dcb_state *dcb_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (!memcmp(&nic_io->dcb_state, dcb_state, sizeof(nic_io->dcb_state)))
return 0;
@@ -423,7 +603,8 @@ int hinic3_get_cos_by_pri(void *hwdev, u8 pri, u8 *cos)
if (pri >= NIC_DCB_UP_MAX && nic_io->dcb_state.trust == HINIC3_DCB_PCP)
return -EINVAL;
- if (pri >= NIC_DCB_IP_PRI_MAX && nic_io->dcb_state.trust == HINIC3_DCB_DSCP)
+ if (pri >= NIC_DCB_IP_PRI_MAX &&
+ nic_io->dcb_state.trust == HINIC3_DCB_DSCP)
return -EINVAL;
/*lint -e662*/
@@ -541,13 +722,15 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_cfg = &nic_io->nic_cfg;
down(&nic_cfg->cfg_lock);
err = hinic3_cfg_hw_pause(nic_io, HINIC3_CMD_OP_SET, &nic_pause);
- if (err) {
+ if (err != 0) {
up(&nic_cfg->cfg_lock);
return err;
}
@@ -566,7 +749,6 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
{
- struct hinic3_nic_cfg *nic_cfg = NULL;
struct hinic3_nic_io *nic_io = NULL;
int err = 0;
@@ -574,17 +756,13 @@ int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- nic_cfg = &nic_io->nic_cfg;
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_hw_pause(nic_io, HINIC3_CMD_OP_GET, nic_pause);
- if (err)
+ if (err != 0)
return err;
- if (nic_cfg->pause_set || !nic_pause->auto_neg) {
- nic_pause->rx_pause = nic_cfg->nic_pause.rx_pause;
- nic_pause->tx_pause = nic_cfg->nic_pause.tx_pause;
- }
-
return 0;
}
@@ -599,6 +777,8 @@ int hinic3_sync_dcb_state(void *hwdev, u8 op_code, u8 state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&dcb_state, 0, sizeof(dcb_state));
@@ -607,7 +787,8 @@ int hinic3_sync_dcb_state(void *hwdev, u8 op_code, u8 state)
dcb_state.func_id = hinic3_global_func_id(hwdev);
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_QOS_DCB_STATE,
- &dcb_state, sizeof(dcb_state), &dcb_state, &out_size);
+ &dcb_state, sizeof(dcb_state),
+ &dcb_state, &out_size);
if (err || dcb_state.head.status || !out_size) {
nic_err(nic_io->dev_hdl,
"Failed to set dcb state, err: %d, status: 0x%x, out size: 0x%x\n",
@@ -675,7 +856,8 @@ int hinic3_cache_out_qps_res(void *hwdev)
qp_res.func_id = hinic3_global_func_id(hwdev);
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
- &qp_res, sizeof(qp_res), &qp_res, &out_size);
+ &qp_res, sizeof(qp_res),
+ &qp_res, &out_size);
if (err || !out_size || qp_res.msg_head.status) {
nic_err(nic_io->dev_hdl, "Failed to cache out qp resources, err: %d, status: 0x%x, out size: 0x%x\n",
err, qp_res.msg_head.status, out_size);
@@ -685,45 +867,8 @@ int hinic3_cache_out_qps_res(void *hwdev)
return 0;
}
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats)
-{
- struct hinic3_port_stats *port_stats = NULL;
- struct hinic3_port_stats_info stats_info;
- u16 out_size = sizeof(*port_stats);
- struct hinic3_nic_io *nic_io = NULL;
- int err;
-
- port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
- if (!port_stats)
- return -ENOMEM;
-
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
-
- memset(&stats_info, 0, sizeof(stats_info));
-
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_PORT_STAT,
- &stats_info, sizeof(stats_info),
- port_stats, &out_size);
- if (err || !out_size || port_stats->msg_head.status) {
- nic_err(nic_io->dev_hdl,
- "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
- err, port_stats->msg_head.status, out_size);
- err = -EIO;
- goto out;
- }
-
- memcpy(stats, &port_stats->stats, sizeof(*stats));
-
-out:
- kfree(port_stats);
-
- return err;
-}
-EXPORT_SYMBOL(hinic3_get_fpga_phy_port_stats);
-
-int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *stats)
+int hinic3_get_vport_stats(void *hwdev, u16 func_id,
+ struct hinic3_vport_stats *stats)
{
struct hinic3_port_stats_info stats_info;
struct hinic3_cmd_vport_stats vport_stats;
@@ -738,6 +883,8 @@ int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *
memset(&vport_stats, 0, sizeof(vport_stats));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
stats_info.func_id = func_id;
@@ -756,7 +903,8 @@ int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *
return 0;
}
-static int hinic3_set_function_table(struct hinic3_nic_io *nic_io, u32 cfg_bitmap,
+static int hinic3_set_function_table(struct hinic3_nic_io *nic_io,
+ u32 cfg_bitmap,
const struct hinic3_func_tbl_cfg *cfg)
{
struct hinic3_cmd_set_func_tbl cmd_func_tbl;
@@ -804,6 +952,8 @@ int hinic3_set_port_mtu(void *hwdev, u16 new_mtu)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (new_mtu < HINIC3_MIN_MTU_SIZE) {
nic_err(nic_io->dev_hdl,
@@ -834,6 +984,8 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&feature_nego, 0, sizeof(feature_nego));
feature_nego.func_id = hinic3_global_func_id(hwdev);
feature_nego.opcode = opcode;
@@ -855,29 +1007,24 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return 0;
}
-static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
+static int hinic3_get_bios_pf_bw_tx_limit(void *hwdev,
+ struct hinic3_nic_io *nic_io,
+ u16 func_id, u32 *pf_rate)
{
- struct hinic3_nic_io *nic_io = NULL;
+ int err = 0; // default success
struct nic_cmd_bios_cfg cfg = {{0}};
u16 out_size = sizeof(cfg);
- int err;
-
- if (!hwdev || !pf_bw_limit)
- return -EINVAL;
-
- if (hinic3_func_type(hwdev) == TYPE_VF || !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
- return 0;
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- cfg.bios_cfg.func_id = (u8)hinic3_global_func_id(hwdev);
+ cfg.bios_cfg.func_id = (u8)func_id;
cfg.bios_cfg.func_valid = 1;
- cfg.op_code = 0 | NIC_NVM_DATA_PF_SPEED_LIMIT;
+ cfg.op_code = 0 | NIC_NVM_DATA_PF_TX_SPEED_LIMIT;
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BIOS_CFG, &cfg, sizeof(cfg),
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BIOS_CFG,
+ &cfg, sizeof(cfg),
&cfg, &out_size);
if (err || !out_size || cfg.head.status) {
nic_err(nic_io->dev_hdl,
- "Failed to get bios pf bandwidth limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ "Failed to get bios pf bandwidth tx limit, err: %d, status: 0x%x, out size: 0x%x\n",
err, cfg.head.status, out_size);
return -EIO;
}
@@ -887,13 +1034,86 @@ static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
nic_warn(nic_io->dev_hdl, "Invalid bios configuration data, signature: 0x%x\n",
cfg.bios_cfg.signature);
- if (cfg.bios_cfg.pf_bw > MAX_LIMIT_BW) {
+ if (cfg.bios_cfg.pf_tx_bw > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
+ cfg.bios_cfg.pf_tx_bw);
+ return -EINVAL;
+ }
+
+ (*pf_rate) = cfg.bios_cfg.pf_tx_bw;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_rx_limit(void *hwdev,
+ struct hinic3_nic_io *nic_io,
+ u16 func_id, u32 *pf_rate)
+{
+ int err = 0; // default success
+ struct nic_rx_rate_bios_cfg rx_bios_conf = {{0}};
+ u16 out_size = sizeof(rx_bios_conf);
+
+ rx_bios_conf.func_id = (u8)func_id;
+ rx_bios_conf.op_code = 0; /* 1-save, 0-read */
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_RX_RATE_CFG,
+ &rx_bios_conf, sizeof(rx_bios_conf),
+ &rx_bios_conf, &out_size);
+ if (rx_bios_conf.msg_head.status == HINIC3_MGMT_CMD_UNSUPPORTED &&
+ err == 0) { // Compatible older firmware
+ nic_warn(nic_io->dev_hdl, "Not support get bios pf bandwidth rx limit\n");
+ return 0;
+ } else if (err || !out_size || rx_bios_conf.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get bios pf bandwidth rx limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, rx_bios_conf.msg_head.status, out_size);
+ return -EIO;
+ }
+ if (rx_bios_conf.rx_rate_limit > MAX_LIMIT_BW) {
nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
- cfg.bios_cfg.pf_bw);
+ rx_bios_conf.rx_rate_limit);
return -EINVAL;
}
- *pf_bw_limit = cfg.bios_cfg.pf_bw;
+ (*pf_rate) = rx_bios_conf.rx_rate_limit;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit, u8 direct)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u32 pf_rate = 0;
+ int err = 0;
+ u16 func_id;
+
+ func_id = hinic3_global_func_id(hwdev);
+
+ if (!hwdev || !pf_bw_limit)
+ return -EINVAL;
+
+ if (hinic3_func_type(hwdev) == TYPE_VF ||
+ !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
+ return 0;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (direct == HINIC3_NIC_TX)
+ err = hinic3_get_bios_pf_bw_tx_limit(hwdev, nic_io,
+ func_id, &pf_rate);
+ else if (direct == HINIC3_NIC_RX)
+ err = hinic3_get_bios_pf_bw_rx_limit(hwdev, nic_io,
+ func_id, &pf_rate);
+
+ if (err != 0)
+ return err;
+
+ if (pf_rate > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl,
+ "Invalid bios cfg pf bandwidth limit: %u\n", pf_rate);
+ return -EINVAL;
+ }
+
+ *pf_bw_limit = pf_rate;
return 0;
}
@@ -902,8 +1122,9 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
{
struct hinic3_cmd_tx_rate_cfg rate_cfg = {{0}};
struct hinic3_nic_io *nic_io = NULL;
+ u32 rate_limit;
u16 out_size = sizeof(rate_cfg);
- u32 pf_rate;
+ u32 pf_rate = 0;
int err;
u32 speed_convert[PORT_SPEED_UNKNOWN] = {
0, 10, 100, 1000, 10000, 25000, 40000, 50000, 100000, 200000
@@ -914,15 +1135,16 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
return -EINVAL;
if (speed_level >= PORT_SPEED_UNKNOWN) {
- nic_err(nic_io->dev_hdl, "Invalid speed level: %u\n", speed_level);
+ nic_err(nic_io->dev_hdl,
+ "Invalid speed level: %u\n", speed_level);
return -EINVAL;
}
- if (nic_io->nic_cfg.pf_bw_limit == MAX_LIMIT_BW) {
- pf_rate = 0;
- } else {
+ rate_limit = (nic_io->direct == HINIC3_NIC_TX) ?
+ nic_io->nic_cfg.pf_bw_tx_limit : nic_io->nic_cfg.pf_bw_rx_limit;
+ if (rate_limit != MAX_LIMIT_BW) {
/* divided by 100 to convert to percentage */
- pf_rate = (speed_convert[speed_level] / 100) * nic_io->nic_cfg.pf_bw_limit;
+ pf_rate = (speed_convert[speed_level] / 100) * rate_limit;
/* bandwidth limit is very small but not unlimit in this case */
if (pf_rate == 0 && speed_level != PORT_SPEED_NOT_SET)
pf_rate = 1;
@@ -931,13 +1153,16 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
rate_cfg.func_id = hinic3_global_func_id(hwdev);
rate_cfg.min_rate = 0;
rate_cfg.max_rate = pf_rate;
+ rate_cfg.direct = nic_io->direct;
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_MAX_MIN_RATE, &rate_cfg,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
+ &rate_cfg,
sizeof(rate_cfg), &rate_cfg, &out_size);
if (err || !out_size || rate_cfg.msg_head.status) {
nic_err(nic_io->dev_hdl, "Failed to set rate(%u), err: %d, status: 0x%x, out size: 0x%x\n",
pf_rate, err, rate_cfg.msg_head.status, out_size);
- return rate_cfg.msg_head.status ? rate_cfg.msg_head.status : -EIO;
+ return rate_cfg.msg_head.status
+ ? rate_cfg.msg_head.status : -EIO;
}
return 0;
@@ -954,7 +1179,8 @@ int hinic3_set_nic_feature_to_hw(void *hwdev)
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- return nic_feature_nego(hwdev, HINIC3_CMD_OP_SET, &nic_io->feature_cap, 1);
+ return nic_feature_nego(hwdev, HINIC3_CMD_OP_SET,
+ &nic_io->feature_cap, 1);
}
u64 hinic3_get_feature_cap(void *hwdev)
@@ -962,6 +1188,8 @@ u64 hinic3_get_feature_cap(void *hwdev)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
return nic_io->feature_cap;
}
@@ -971,12 +1199,17 @@ void hinic3_update_nic_feature(void *hwdev, u64 s_feature)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
nic_io->feature_cap = s_feature;
- nic_info(nic_io->dev_hdl, "Update nic feature to 0x%llx\n", nic_io->feature_cap);
+ nic_info(nic_io->dev_hdl,
+ "Update nic feature to 0x%llx\n",
+ nic_io->feature_cap);
}
-static inline int init_nic_hwdev_param_valid(const void *hwdev, const void *pcidev_hdl,
+static inline int init_nic_hwdev_param_valid(const void *hwdev,
+ const void *pcidev_hdl,
const void *dev_hdl)
{
if (!hwdev || !pcidev_hdl || !dev_hdl)
@@ -1004,6 +1237,7 @@ static int hinic3_init_nic_io(void *hwdev, void *pcidev_hdl, void *dev_hdl,
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_abs = false;
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_info = false;
+ (*nic_io)->nic_cfg.rt_cmd_ext.mpu_send_xsfp_tlv_info = false;
return 0;
}
@@ -1020,27 +1254,34 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
{
struct hinic3_nic_io *nic_io = NULL;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
err = hinic3_init_nic_io(hwdev, pcidev_hdl, dev_hdl, &nic_io);
- if (err)
+ if (err != 0)
return err;
+ nic_io->rx_buff_len = rx_buff_len;
+
err = hinic3_register_service_adapter(hwdev, nic_io, SERVICE_T_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to register service adapter\n");
goto register_sa_err;
}
- err = hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 1, HINIC3_CHANNEL_NIC);
- if (err) {
+ err = hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC,
+ 1, HINIC3_CHANNEL_NIC);
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set function svc used state\n");
goto set_used_state_err;
}
- err = hinic3_init_function_table(nic_io);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to init function table\n");
- goto err_out;
+ if (is_in_kexec == 0) {
+ err = hinic3_init_function_table(nic_io);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to init function table\n");
+ goto err_out;
+ }
}
err = hinic3_get_nic_feature_from_hw(hwdev, &nic_io->feature_cap, 1);
@@ -1052,24 +1293,35 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
sdk_info(dev_hdl, "nic features: 0x%llx\n", nic_io->feature_cap);
hinic3_nic_cmdq_adapt_init(nic_io);
- err = hinic3_get_bios_pf_bw_limit(hwdev, &nic_io->nic_cfg.pf_bw_limit);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to get pf bandwidth limit\n");
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_tx_limit,
+ HINIC3_NIC_TX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf tx bandwidth limit\n");
+ goto err_out;
+ }
+
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_rx_limit,
+ HINIC3_NIC_RX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf rx bandwidth limit\n");
goto err_out;
}
err = hinic3_vf_func_init(nic_io);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to init vf info\n");
goto err_out;
}
- nic_io->rx_buff_len = rx_buff_len;
-
return 0;
err_out:
- hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 0, HINIC3_CHANNEL_NIC);
+ if (hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC,
+ 0, HINIC3_CHANNEL_NIC) != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to set function svc used state\n");
+ }
set_used_state_err:
hinic3_unregister_service_adapter(hwdev, SERVICE_T_NIC);
@@ -1119,6 +1371,8 @@ int hinic3_force_drop_tx_pkt(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&pkt_drop, 0, sizeof(pkt_drop));
pkt_drop.port = hinic3_physical_port_id(hwdev);
@@ -1147,6 +1401,8 @@ int hinic3_set_rx_mode(void *hwdev, u32 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&rx_mode_cfg, 0, sizeof(rx_mode_cfg));
rx_mode_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1175,6 +1431,8 @@ int hinic3_set_rx_vlan_offload(void *hwdev, u8 en)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_cfg, 0, sizeof(vlan_cfg));
vlan_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1192,7 +1450,8 @@ int hinic3_set_rx_vlan_offload(void *hwdev, u8 en)
return 0;
}
-int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
+int hinic3_update_mac_vlan(void *hwdev, const u16 old_vlan,
+ u16 new_vlan, int vf_id)
{
struct vf_data_storage *vf_info = NULL;
struct hinic3_nic_io *nic_io = NULL;
@@ -1203,6 +1462,8 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
if (!nic_io->vf_infos || is_zero_ether_addr(vf_info->drv_mac_addr))
return 0;
@@ -1211,7 +1472,7 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
err = hinic3_del_mac(nic_io->hwdev, vf_info->drv_mac_addr,
old_vlan, func_id, HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to delete VF %d MAC %pM vlan %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->drv_mac_addr, old_vlan);
return err;
@@ -1219,7 +1480,7 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
err = hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
new_vlan, func_id, HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to add VF %d MAC %pM vlan %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->drv_mac_addr, new_vlan);
hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
@@ -1242,6 +1503,8 @@ static int hinic3_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en,
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_cfg, 0, sizeof(lro_cfg));
lro_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1273,6 +1536,8 @@ static int hinic3_set_rx_lro_timer(void *hwdev, u32 timer_value)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_timer, 0, sizeof(lro_timer));
lro_timer.opcode = HINIC3_CMD_OP_SET;
@@ -1305,12 +1570,14 @@ int hinic3_set_rx_lro_state(void *hwdev, u8 lro_en, u32 lro_timer,
ipv6_en = lro_en ? 1 : 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_info(nic_io->dev_hdl, "Set LRO max coalesce packet size to %uK\n",
lro_max_pkt_len);
err = hinic3_set_rx_lro(hwdev, ipv4_en, ipv6_en, (u8)lro_max_pkt_len);
- if (err)
+ if (err != 0)
return err;
/* we don't set LRO timer for VF */
@@ -1333,6 +1600,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_filter, 0, sizeof(vlan_filter));
vlan_filter.func_id = hinic3_global_func_id(hwdev);
@@ -1352,7 +1621,6 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
{
- // struct hinic_hwdev *dev = hwdev;
struct nic_cmd_capture_info cap_info = {{0}};
u16 out_size = sizeof(cap_info);
int err;
@@ -1361,7 +1629,6 @@ int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
return -EINVAL;
/* 2 function capture types */
- // cap_info.op_type = UP_UCAPTURE_OP_TYPE_FUNC;
cap_info.is_en_trx = cap_en;
cap_info.func_port = func_id;
@@ -1386,6 +1653,8 @@ int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (tcam_rule->index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to add is invalid\n");
return -EINVAL;
@@ -1421,6 +1690,8 @@ int hinic3_del_tcam_rule(void *hwdev, u32 index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to del is invalid\n");
return -EINVAL;
@@ -1470,6 +1741,8 @@ static int hinic3_mgmt_tcam_block(void *hwdev, u8 alloc_en, u16 *index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&tcam_block_info, 0,
sizeof(struct nic_cmd_ctrl_tcam_block_out));
@@ -1515,6 +1788,8 @@ int hinic3_set_fdir_tcam_rule_filter(void *hwdev, bool enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
port_tcam_cmd.func_id = hinic3_global_func_id(hwdev);
port_tcam_cmd.tcam_enable = (u8)enable;
@@ -1543,6 +1818,8 @@ int hinic3_flush_tcam_rule(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&tcam_flush, 0, sizeof(struct nic_cmd_flush_tcam_rules));
tcam_flush.func_id = hinic3_global_func_id(hwdev);
@@ -1560,7 +1837,8 @@ int hinic3_flush_tcam_rule(void *hwdev)
return 0;
}
-int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type)
+int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info,
+ u16 num_qps, u16 wqe_type)
{
struct hinic3_cmd_buf *cmd_buf = NULL;
struct hinic3_nic_io *nic_io = NULL;
@@ -1573,6 +1851,8 @@ int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -1587,9 +1867,11 @@ int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
cmd_buf->size = sizeof(struct hinic3_rxq_hw);
- err = hinic3_cmdq_detail_resp(hwdev, HINIC3_MOD_L2NIC, HINIC3_UCODE_CMD_RXQ_INFO_GET,
- cmd_buf, cmd_buf, NULL, 0, HINIC3_CHANNEL_NIC);
- if (err)
+ err = hinic3_cmdq_detail_resp(hwdev, HINIC3_MOD_L2NIC,
+ HINIC3_UCODE_CMD_RXQ_INFO_GET,
+ cmd_buf, cmd_buf, NULL, 0,
+ HINIC3_CHANNEL_NIC);
+ if (err != 0)
goto get_rxq_info_failed;
rxq_info_out = cmd_buf->buf;
@@ -1604,7 +1886,8 @@ get_rxq_info_failed:
return err;
}
-int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_state)
+int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced,
+ bool link_state)
{
struct hinic3_nic_io *nic_io = NULL;
struct vf_data_storage *vf_infos = NULL;
@@ -1615,8 +1898,10 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return -EINVAL;
}
- if (hinic3_func_type(hwdev) == TYPE_VF)
+ if (hinic3_func_type(hwdev) == TYPE_VF) {
+ pr_err("VF are not supported to set link state.\n");
return -EINVAL;
+ }
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
if (!nic_io) {
@@ -1633,3 +1918,35 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return 0;
}
EXPORT_SYMBOL(hinic3_pf_set_vf_link_state);
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid)
+{
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ u16 out_size = sizeof(outband_cfg_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !outband_default_vid)
+ return -EINVAL;
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_OUTBAND_CFG,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size);
+ if (err || !out_size || outband_cfg_info.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get outband cfg, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, outband_cfg_info.msg_head.status, out_size);
+ return -EINVAL;
+ }
+
+ *outband_default_vid = outband_cfg_info.outband_default_vid;
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
index dd2c2fd..60caf68 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
@@ -7,9 +7,10 @@
#include <linux/types.h>
#include <linux/netdevice.h>
-#include "hinic3_mgmt_interface.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
+#include "nic_cfg_comm.h"
+#include "nic_mpu_cmd_defs.h"
#define OS_VF_ID_TO_HW(os_vf_id) ((os_vf_id) + 1)
#define HW_VF_ID_TO_OS(hw_vf_id) ((hw_vf_id) - 1)
@@ -54,6 +55,8 @@
#define MAX_LIMIT_BW 100
+#define HINIC3_INVALID_BOND_ID 0xffffffff
+
enum hinic3_valid_link_settings {
HILINK_LINK_SET_SPEED = 0x1,
HILINK_LINK_SET_AUTONEG = 0x2,
@@ -67,6 +70,11 @@ enum hinic3_link_follow_status {
HINIC3_LINK_FOLLOW_STATUS_MAX,
};
+enum hinic3_nic_pf_direct {
+ HINIC3_NIC_RX = 0,
+ HINIC3_NIC_TX,
+};
+
struct hinic3_link_ksettings {
u32 valid_bitmap;
u8 speed; /* enum nic_speed_level */
@@ -152,8 +160,12 @@ struct nic_port_info {
u8 duplex;
u8 speed;
u8 fec;
+ u8 lanes;
+ u8 rsvd;
u32 supported_mode;
u32 advertised_mode;
+ u32 supported_fec_mode;
+ u32 bond_speed;
};
struct nic_pause_config {
@@ -178,11 +190,17 @@ struct hinic3_rxq_hw {
#define MODULE_TYPE_QSFP28 0x11
#define MODULE_TYPE_QSFP 0x0C
#define MODULE_TYPE_QSFP_PLUS 0x0D
+#define MODULE_TYPE_DSFP 0x1B
+#define MODULE_TYPE_QSFP_CMIS 0x1E
#define TCAM_IP_TYPE_MASK 0x1
#define TCAM_TUNNEL_TYPE_MASK 0xF
#define TCAM_FUNC_ID_MASK 0x7FFF
+int hinic3_delete_bond(void *hwdev);
+int hinic3_open_close_bond(void *hwdev, u32 bond_en);
+int hinic3_create_bond(void *hwdev, u32 *bond_id);
+
int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule);
int hinic3_del_tcam_rule(void *hwdev, u32 index);
@@ -335,7 +353,7 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr);
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr);
/* *
* @brief hinic3_vf_info_vlanprio - get vf vlan priority
@@ -510,7 +528,14 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table);
*/
int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats);
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats);
+/* *
+ * @brief hinic3_get_phy_rsfec_stats - get rsfec stats
+ * @param hwdev: device pointer to hwdev
+ * @param stats: rsfec(Reed-Solomon Forward Error Correction) stats
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats);
int hinic3_set_port_funcs_state(void *hwdev, bool enable);
@@ -546,6 +571,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl);
void hinic3_clear_vfs_info(void *hwdev);
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id);
+
int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id);
int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
@@ -565,9 +592,13 @@ int hinic3_set_autoneg(void *hwdev, bool enable);
int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext);
int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len);
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len);
bool hinic3_if_sfp_absent(void *hwdev);
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info);
+int hinic3_get_sfp_tlv_info(void *hwdev,
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info,
+ const struct tag_mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req);
/* *
* @brief hinic3_set_nic_feature_to_hw - sync nic feature to hardware
@@ -620,4 +651,19 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level);
int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type);
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+/* *
+ * @brief hinic3_vlxan_port_config - add/del vxlan dst port
+ * @param hwdev: device pointer to hwdev
+ * @param func_id: function id
+ * @param port: vxlan dst port
+ * @param action: add or del, del will set to default value (0x12B5)
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action);
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
index 15d081b..c0e0a61 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
@@ -22,7 +22,8 @@
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_nic_cmdq.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
/*lint -e806*/
static unsigned char set_vf_link_state;
@@ -59,7 +60,8 @@ static int hinic3_set_vlan_ctx(struct hinic3_nic_io *nic_io, u16 func_id,
vlan_tag, q_id, vlan_mode);
err = hinic3_cmdq_direct_resp(nic_io->hwdev, HINIC3_MOD_L2NIC,
- cmd, cmd_buf, &out_param, 0, HINIC3_CHANNEL_NIC);
+ cmd, cmd_buf, &out_param,
+ 0, HINIC3_CHANNEL_NIC);
hinic3_free_cmd_buf(nic_io->hwdev, cmd_buf);
@@ -108,7 +110,7 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
err = hinic3_set_vlan_ctx(nic_io, glb_func_id, vlan_tag,
NIC_CONFIG_ALL_QUEUE_VLAN_CTX,
opcode == HINIC3_CMD_OP_ADD);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d vlan ctx, err: %d\n",
HW_VF_ID_TO_OS(vf_id), err);
@@ -129,12 +131,15 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
/* this function just be called by hinic3_ndo_set_vf_mac,
* others are not permitted.
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr)
{
- struct vf_data_storage *vf_info;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_info = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
#ifndef __VMWARE__
/* duplicate request, so just return success */
@@ -152,13 +157,15 @@ int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan, qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan = vlan;
@@ -172,17 +179,19 @@ int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
vf_infos = nic_io->vf_infos;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_DEL,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_info(nic_io->dev_hdl, "Remove VLAN %u on VF %d\n",
@@ -197,11 +206,13 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
u16 hinic3_vf_info_vlanprio(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
u16 pf_vlan, vlanprio;
u8 pf_qos;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
pf_vlan = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan;
pf_qos = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos;
@@ -214,9 +225,14 @@ int hinic3_set_vf_link_state(void *hwdev, u16 vf_id, int link)
{
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ struct vf_data_storage *vf_infos = NULL;
u8 link_status = 0;
+ if (!nic_io)
+ return -EINVAL;
+
+ vf_infos = nic_io->vf_infos;
+
switch (link) {
case HINIC3_IFLA_VF_LINK_STATE_AUTO:
vf_infos[HW_VF_ID_TO_OS(vf_id)].link_forced = false;
@@ -256,6 +272,8 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
vf_infos = nic_io->vf_infos;
memset(&spoofchk_cfg, 0, sizeof(spoofchk_cfg));
@@ -280,9 +298,11 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
bool hinic3_vf_info_spoofchk(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].spoofchk;
}
@@ -296,7 +316,7 @@ int hinic3_set_vf_trust(void *hwdev, u16 vf_id, bool trust)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
+ if (!nic_io || vf_id > nic_io->max_vfs)
return -EINVAL;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust = trust;
@@ -309,11 +329,11 @@ bool hinic3_get_vf_trust(void *hwdev, int vf_id)
struct hinic3_nic_io *nic_io = NULL;
if (!hwdev)
- return -EINVAL;
+ return false;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
- return -EINVAL;
+ if (!nic_io || vf_id > nic_io->max_vfs)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust;
}
@@ -331,6 +351,7 @@ static int hinic3_set_vf_tx_rate_max_min(struct hinic3_nic_io *nic_io,
rate_cfg.func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf_id;
rate_cfg.max_rate = max_rate;
rate_cfg.min_rate = min_rate;
+ rate_cfg.direct = HINIC3_NIC_TX;
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
&rate_cfg, sizeof(rate_cfg), &rate_cfg,
@@ -351,13 +372,15 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (!HINIC3_SUPPORT_RATE_LIMIT(hwdev)) {
nic_err(nic_io->dev_hdl, "Current function doesn't support to set vf rate limit\n");
return -EOPNOTSUPP;
}
err = hinic3_set_vf_tx_rate_max_min(nic_io, vf_id, max_rate, min_rate);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].max_rate = max_rate;
@@ -368,12 +391,16 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
void hinic3_get_vf_config(void *hwdev, u16 vf_id, struct ifla_vf_info *ivi)
{
- struct vf_data_storage *vfinfo;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vfinfo = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
vfinfo = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vfinfo)
+ return;
ivi->vf = HW_VF_ID_TO_OS(vf_id);
ether_addr_copy(ivi->mac, vfinfo->user_mac_addr);
@@ -446,13 +473,15 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
int err;
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
- nic_io->hwdev, hinic3_vf_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_vf_event_handler);
+ if (err != 0)
return err;
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
- nic_io->hwdev, hinic3_vf_mag_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_vf_mag_event_handler);
+ if (err != 0)
goto reg_hilink_err;
memset(®ister_info, 0, sizeof(register_info));
@@ -464,6 +493,11 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
®ister_info, &out_size, 0,
HINIC3_CHANNEL_NIC);
if (err || !out_size || register_info.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev)) {
+ nic_warn(nic_io->dev_hdl, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, register_info.msg_head.status, out_size);
+ return 0;
+ }
nic_err(nic_io->dev_hdl, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
err, register_info.msg_head.status, out_size);
err = -EIO;
@@ -498,18 +532,20 @@ static int pf_init_vf_infos(struct hinic3_nic_io *nic_io)
for (i = 0; i < nic_io->max_vfs; i++) {
err = hinic3_init_vf_infos(nic_io, i);
- if (err)
+ if (err != 0)
goto init_vf_infos_err;
}
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
- nic_io->hwdev, hinic3_pf_mbox_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_mbox_handler);
+ if (err != 0)
goto register_pf_mbox_cb_err;
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
- nic_io->hwdev, hinic3_pf_mag_mbox_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_mag_mbox_handler);
+ if (err != 0)
goto register_pf_mag_mbox_cb_err;
return 0;
@@ -531,17 +567,19 @@ int hinic3_vf_func_init(struct hinic3_nic_io *nic_io)
return vf_func_register(nic_io);
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
- nic_io->hwdev, hinic3_pf_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_event_handler);
+ if (err != 0)
return err;
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
- nic_io->hwdev, hinic3_pf_mag_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_mag_event_handler);
+ if (err != 0)
goto register_mgmt_msg_cb_err;
err = pf_init_vf_infos(nic_io);
- if (err)
+ if (err != 0)
goto pf_init_vf_infos_err;
return 0;
@@ -568,17 +606,24 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
&unregister, sizeof(unregister),
&unregister, &out_size, 0,
HINIC3_CHANNEL_NIC);
- if (err || !out_size || unregister.msg_head.status)
- nic_err(nic_io->dev_hdl, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
- err, unregister.msg_head.status, out_size);
-
+ if (err || !out_size || unregister.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev)) {
+ nic_info(nic_io->dev_hdl, "vRoCE VF notify PF unsuccessful is allowed");
+ } else {
+ nic_err(nic_io->dev_hdl, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, unregister.msg_head.status, out_size);
+ }
+ }
hinic3_unregister_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
} else {
if (nic_io->vf_infos) {
- hinic3_unregister_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK);
- hinic3_unregister_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
+ hinic3_unregister_pf_mbox_cb(nic_io->hwdev,
+ HINIC3_MOD_HILINK);
+ hinic3_unregister_pf_mbox_cb(nic_io->hwdev,
+ HINIC3_MOD_L2NIC);
hinic3_clear_vfs_info(nic_io->hwdev);
kfree(nic_io->vf_infos);
+ nic_io->vf_infos = NULL;
}
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
@@ -587,11 +632,15 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
static void clear_vf_infos(void *hwdev, u16 vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
u16 func_id;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
func_id = hinic3_glb_pf_vf_offset(hwdev) + vf_id;
vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
@@ -620,10 +669,59 @@ static void clear_vf_infos(void *hwdev, u16 vf_id)
void hinic3_clear_vfs_info(void *hwdev)
{
+ u16 i;
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- u16 i;
+
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
for (i = 0; i < nic_io->max_vfs; i++)
clear_vf_infos(hwdev, OS_VF_ID_TO_HW(i));
}
+
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id)
+{
+ int err = 0;
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ struct vf_data_storage *vf_infos = NULL;
+ u16 out_size = sizeof(outband_cfg_info);
+ u16 vf_id;
+ struct hinic3_nic_io *nic_io =
+ hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return 0;
+ }
+
+ vf_id = func_id - hinic3_glb_pf_vf_offset(nic_io->hwdev);
+ vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+ if (vf_infos->registered) {
+ outband_cfg_info.func_id = func_id;
+ outband_cfg_info.outband_default_vid = vlan_id;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_L2NIC,
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return 0;
+ }
+ if (err || !out_size || outband_cfg_info.msg_head.status)
+ nic_err(nic_io->dev_hdl,
+ "outband cfg event to VF %d failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err,
+ outband_cfg_info.msg_head.status, out_size);
+ }
+
+ return err;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
index 0ec4b32..b45c875 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
@@ -30,6 +30,8 @@ int hinic3_dbg_get_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (q_id >= nic_io->num_qps) {
pr_err("q_id[%u] > num_qps_cfg[%u].\n", q_id, nic_io->num_qps);
return -EINVAL;
@@ -69,6 +71,8 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -82,6 +86,8 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
sq = &nic_io->sq[q_id];
+ if (!sq)
+ return -EINVAL;
sq_info->q_id = q_id;
sq_info->pi = hinic3_get_sq_local_pi(sq);
@@ -112,6 +118,8 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -125,6 +133,8 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
rq = &nic_io->rq[q_id];
+ if (!rq)
+ return -EINVAL;
rq_info->q_id = q_id;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
index e76a66b..c219452 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
@@ -15,9 +15,10 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
#include "hinic3_dcb.h"
+#include "vram_common.h"
#define HINIC3_NIC_DRV_NAME "hinic3"
-#define HINIC3_NIC_DRV_VERSION HINIC3_DRV_VERSION
+#define HINIC3_NIC_DRV_VERSION "17.7.8.1"
#define HINIC3_FUNC_IS_VF(hwdev) (hinic3_func_type(hwdev) == TYPE_VF)
@@ -25,6 +26,10 @@
#define HINIC3_MODERATONE_DELAY HZ
#define LP_PKT_CNT 64
+#define LP_PKT_LEN 60
+
+#define NAPI_IS_REGIN 1
+#define NAPI_NOT_REGIN 0
enum hinic3_flags {
HINIC3_INTF_UP,
@@ -91,6 +96,8 @@ struct hinic3_irq {
u16 rsvd1;
u32 irq_id; /* The IRQ number from OS */
+ u32 napi_reign;
+
char irq_name[IFNAMSIZ + 16];
struct napi_struct napi;
cpumask_t affinity_mask;
@@ -123,6 +130,41 @@ struct hinic3_dyna_txrxq_params {
struct hinic3_dyna_txq_res *txqs_res;
struct hinic3_dyna_rxq_res *rxqs_res;
struct hinic3_irq *irq_cfg;
+ char irq_cfg_vram_name[VRAM_NAME_MAX_LEN];
+};
+
+struct hinic3_flush_rq {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 lb_proc : 1;
+ u32 rsvd : 10;
+ u32 rq_id : 8;
+ u32 func_id : 13;
+#else
+ u32 func_id : 13;
+ u32 rq_id : 8;
+ u32 rsvd : 10;
+ u32 lb_proc : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd2 : 2;
+ u32 src_chnl : 12;
+ u32 pkt_len : 18;
+#else
+ u32 pkt_len : 18;
+ u32 src_chnl : 12;
+ u32 rsvd2 : 2;
+#endif
+ } bs;
+ u32 value;
+ } lb_info0; /* loop back information, used by uCode */
};
#define HINIC3_NIC_STATS_INC(nic_dev, field) \
@@ -147,6 +189,10 @@ struct hinic3_nic_stats {
#endif
};
+struct hinic3_nic_vport_stats {
+ u64 rx_discard_vport;
+};
+
#define HINIC3_TCAM_DYNAMIC_BLOCK_SIZE 16
#define HINIC3_MAX_TCAM_FILTERS 512
@@ -185,6 +231,28 @@ struct hinic3_tcam_info {
struct hinic3_tcam_dynamic_block_info tcam_dynamic_info;
};
+struct hinic3_dcb {
+ u8 cos_config_num_max;
+ u8 func_dft_cos_bitmap;
+ /* used to tool validity check */
+ u16 port_dft_cos_bitmap;
+
+ struct hinic3_dcb_config hw_dcb_cfg;
+ struct hinic3_dcb_config wanted_dcb_cfg;
+ unsigned long dcb_flags;
+};
+
+struct hinic3_vram {
+ u32 vram_mtu;
+ u16 vram_num_qps;
+ unsigned long flags;
+};
+
+struct hinic3_outband_cfg {
+ u16 outband_default_vid;
+ u16 rsvd;
+};
+
struct hinic3_nic_dev {
struct pci_dev *pdev;
struct net_device *netdev;
@@ -204,6 +272,7 @@ struct hinic3_nic_dev {
u32 dma_rx_buff_size;
u16 rx_buff_len;
u32 page_order;
+ bool page_pool_enabled;
/* Rss related varibles */
u8 rss_hash_engine;
@@ -213,17 +282,13 @@ struct hinic3_nic_dev {
u32 *rss_hkey_be;
u32 *rss_indir;
- u8 cos_config_num_max;
- u8 func_dft_cos_bitmap;
- u16 port_dft_cos_bitmap; /* used to tool validity check */
+ struct hinic3_dcb *dcb;
+ char dcb_name[VRAM_NAME_MAX_LEN];
+
+ struct hinic3_vram *nic_vram;
+ char nic_vram_name[VRAM_NAME_MAX_LEN];
- struct hinic3_dcb_config hw_dcb_cfg;
- struct hinic3_dcb_config wanted_dcb_cfg;
- struct hinic3_dcb_config dcb_cfg;
- unsigned long dcb_flags;
int disable_port_cnt;
- /* lock for disable or enable traffic flow */
- struct semaphore dcb_sem;
struct hinic3_intr_coal_info *intr_coalesce;
unsigned long last_moder_jiffies;
@@ -235,11 +300,10 @@ struct hinic3_nic_dev {
#endif
struct hinic3_nic_stats stats;
+ struct hinic3_nic_vport_stats vport_stats;
/* lock for nic resource */
struct mutex nic_mutex;
- bool force_port_disable;
- struct semaphore port_state_sem;
u8 link_status;
struct nic_service_cap nic_cap;
@@ -281,9 +345,10 @@ struct hinic3_nic_dev {
struct hinic3_nic_prof_attr *prof_attr;
struct hinic3_prof_adapter *prof_adap;
u64 rsvd8[7];
- u32 rsvd9;
+ struct hinic3_outband_cfg outband_cfg;
u32 rxq_get_err_times;
struct delayed_work rxq_check_work;
+ struct delayed_work vport_stats_work;
struct hinic3_tx_rx_ops tx_rx_ops;
};
@@ -312,7 +377,7 @@ struct hinic3_uld_info *get_nic_uld_info(void);
u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev);
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
int hinic3_open(struct net_device *netdev);
@@ -331,6 +396,8 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev);
void hinic3_qps_irq_deinit(struct hinic3_nic_dev *nic_dev);
+void qp_del_napi(struct hinic3_irq *irq_cfg);
+
void hinic3_set_netdev_ops(struct hinic3_nic_dev *nic_dev);
bool hinic3_is_netdev_ops_match(const struct net_device *netdev);
@@ -348,10 +415,6 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
int hinic3_get_sset_count(struct net_device *netdev, int sset);
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev);
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
#ifdef ETHTOOL_GLINKSETTINGS
@@ -386,5 +449,18 @@ bool hinic3_is_xdp_enable(struct hinic3_nic_dev *nic_dev);
int hinic3_xdp_max_mtu(struct hinic3_nic_dev *nic_dev);
#endif
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry,
+ struct udp_tunnel_info *ti);
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+int set_fecparam(void *hwdev, u8 fecparam);
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec);
+#endif
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
index 57cf07c..87b5aa6 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
@@ -21,11 +21,12 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
{
- struct vf_data_storage *vf_info;
+ struct vf_data_storage *vf_info = NULL;
u16 func_id;
int err = 0;
@@ -38,7 +39,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
vf_info->pf_vlan, func_id,
HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d MAC\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -51,7 +52,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD,
vf_info->pf_vlan, vf_info->pf_qos,
vf_id);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to add VF %d VLAN_QOS\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -62,7 +63,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_vf_tx_rate(nic_io->hwdev, vf_id,
vf_info->max_rate,
vf_info->min_rate);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d max rate %u, min rate %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->max_rate,
vf_info->min_rate);
@@ -84,7 +85,7 @@ static int register_vf_msg_handler(struct hinic3_nic_io *nic_io, u16 vf_id)
}
err = hinic3_init_vf_config(nic_io, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].registered = true;
@@ -137,6 +138,9 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
int err;
+ if (!vf_info)
+ return -EINVAL;
+
if (register_vf->op_register) {
vf_info->support_extra_feature = register_vf->support_extra_feature;
err = register_vf_msg_handler(nic_io, vf_id);
@@ -145,7 +149,7 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
vf_info->support_extra_feature = 0;
}
- if (err)
+ if (err != 0)
register_info->msg_head.status = EFAULT;
*out_size = sizeof(*register_info);
@@ -157,6 +161,8 @@ void hinic3_unregister_vf(struct hinic3_nic_io *nic_io, u16 vf_id)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vf_info)
+ return;
unregister_vf_msg_handler(nic_io, vf_id);
vf_info->support_extra_feature = 0;
}
@@ -181,14 +187,21 @@ static int hinic3_get_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
void *buf_out, u16 *out_size)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf);
+ struct hinic3_port_mac_set *mac_in =
+ (struct hinic3_port_mac_set *)buf_in;
struct hinic3_port_mac_set *mac_info = buf_out;
int err;
+ if (!mac_info || !vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (HINIC3_SUPPORT_VF_MAC(nic_io->hwdev)) {
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_GET_MAC, buf_in,
in_size, buf_out, out_size);
- if (!err) {
+ if (err == 0) {
if (is_zero_ether_addr(mac_info->mac))
ether_addr_copy(mac_info->mac, vf_info->drv_mac_addr);
}
@@ -211,6 +224,11 @@ static int hinic3_set_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -247,6 +265,10 @@ static int hinic3_del_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -283,10 +305,13 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
struct hinic3_port_mac_update *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
if (!is_valid_ether_addr(mac_in->new_mac)) {
nic_err(nic_io->dev_hdl, "Update VF MAC is invalid.\n");
return -EINVAL;
}
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
#ifndef __VMWARE__
if (vf_info->use_specified_mac && !vf_info->trust) {
@@ -301,7 +326,7 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
HW_VF_ID_TO_OS(vf),
HINIC_CFG_VF_MAC_CHANGED,
(void *)mac_in->new_mac);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to config VF %d MAC request, err: %d\n",
HW_VF_ID_TO_OS(vf), err);
return err;
@@ -359,10 +384,11 @@ static int _l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u16 in_size, void *buf_out, u16 *out_size,
u16 channel)
{
- u32 i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
+ int i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_cmd_handler[i].cmd)
cmd_to_pf = true;
@@ -397,13 +423,15 @@ int hinic3_pf_mbox_handler(void *hwdev,
u16 vf_id, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- u32 index, cmd_size = ARRAY_LEN(vf_cmd_handler);
+ int index, cmd_size = ARRAY_LEN(vf_cmd_handler);
struct hinic3_nic_io *nic_io = NULL;
if (!hwdev)
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (index = 0; index < cmd_size; index++) {
if (cmd == vf_cmd_handler[index].cmd)
@@ -460,10 +488,14 @@ void hinic3_notify_dcb_state_event(struct hinic3_nic_io *nic_io,
static void dcb_state_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- struct hinic3_cmd_vf_dcb_state *vf_dcb;
- struct hinic3_nic_io *nic_io;
+ struct hinic3_cmd_vf_dcb_state *vf_dcb = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
vf_dcb = buf_in;
if (!vf_dcb)
@@ -479,6 +511,10 @@ static void tx_pause_excp_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*excp_info)) {
nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
@@ -501,6 +537,10 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_event_info event_info = {0};
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*active_info)) {
nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
@@ -515,6 +555,36 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
hinic3_event_callback(nic_io->hwdev, &event_info);
}
+static void outband_vlan_cfg_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out,
+ u16 *out_size)
+{
+ struct hinic3_outband_cfg_info *outband_cfg_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info = {0};
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ nic_info(nic_io->dev_hdl, "outband vlan cfg event received\n");
+
+ if (in_size != sizeof(*outband_cfg_info)) {
+ nic_err(nic_io->dev_hdl, "outband cfg info invalid in_size: %u, should be %lu\n",
+ in_size, sizeof(*outband_cfg_info));
+ return;
+ }
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = EVENT_NIC_OUTBAND_CFG;
+ memcpy((void *)event_info.event_data,
+ outband_cfg_info, sizeof(*outband_cfg_info));
+
+ hinic3_event_callback(nic_io->hwdev, &event_info);
+}
+
static const struct nic_event_handler nic_cmd_handler[] = {
{
.cmd = HINIC3_NIC_CMD_VF_COS,
@@ -529,6 +599,11 @@ static const struct nic_event_handler nic_cmd_handler[] = {
.cmd = HINIC3_NIC_CMD_BOND_ACTIVE_NOTICE,
.handler = bond_active_event_handler,
},
+
+ {
+ .cmd = HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ .handler = outband_vlan_cfg_event_handler,
+ },
};
static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
@@ -543,6 +618,8 @@ static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (i = 0; i < size; i++) {
if (cmd == nic_cmd_handler[i].cmd) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
index a827f44..f3bb4c5 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
@@ -16,9 +16,10 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
-#include "hinic3_nic_io.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_nic_cmdq.h"
+#include "hinic3_nic_io.h"
#define HINIC3_DEAULT_TX_CI_PENDING_LIMIT 1
#define HINIC3_DEAULT_TX_CI_COALESCING_TIME 1
@@ -35,7 +36,7 @@ MODULE_PARM_DESC(tx_coalescing_time, "TX CI coalescing parameter coalescing_time
static unsigned char rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
module_param(rq_wqe_type, byte, 0444);
-MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 0-8Bytes, 1-16Bytes, 2-32Bytes (default=1)");
+MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 1-16Bytes, 2-32Bytes (default=2)");
/*lint +e806*/
static u32 tx_drop_thd_on = HINIC3_DEAULT_DROP_THD_ON;
@@ -46,7 +47,7 @@ static u32 tx_drop_thd_off = HINIC3_DEAULT_DROP_THD_OFF;
module_param(tx_drop_thd_off, uint, 0644);
MODULE_PARM_DESC(tx_drop_thd_off, "TX parameter drop_thd_off (default=0)");
/* performance: ci addr RTE_CACHE_SIZE(64B) alignment */
-#define HINIC3_CI_Q_ADDR_SIZE (64)
+#define HINIC3_CI_Q_ADDR_SIZE (64U)
#define CI_TABLE_SIZE(num_qps, pg_sz) \
(ALIGN((num_qps) * HINIC3_CI_Q_ADDR_SIZE, pg_sz))
@@ -255,7 +256,7 @@ static int hinic3_create_sq(struct hinic3_nic_io *nic_io, struct hinic3_io_queue
err = hinic3_wq_create(nic_io->hwdev, &sq->wq, sq_depth,
(u16)BIT(HINIC3_SQ_WQEBB_SHIFT));
- if (err) {
+ if (err != 0) {
sdk_err(nic_io->dev_hdl, "Failed to create tx queue(%u) wq\n",
q_id);
return err;
@@ -291,13 +292,22 @@ static int hinic3_create_rq(struct hinic3_nic_io *nic_io, struct hinic3_io_queue
{
int err;
- rq->wqe_type = (u8)(hinic3_get_rq_wqe_type(nic_io->hwdev));
+ /* rq_wqe_type Only support type 1-16Bytes, 2-32Bytes */
+ if (rq_wqe_type != HINIC3_NORMAL_RQ_WQE &&
+ rq_wqe_type != HINIC3_EXTEND_RQ_WQE) {
+ sdk_warn(nic_io->dev_hdl, "Module Parameter rq_wqe_type value %d is out of range: [%d, %d].",
+ rq_wqe_type, HINIC3_NORMAL_RQ_WQE,
+ HINIC3_EXTEND_RQ_WQE);
+ rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
+ }
+
+ rq->wqe_type = rq_wqe_type;
rq->q_id = q_id;
rq->msix_entry_idx = rq_msix_idx;
err = hinic3_wq_create(nic_io->hwdev, &rq->wq, rq_depth,
(u16)BIT(HINIC3_RQ_WQEBB_SHIFT + rq->wqe_type));
- if (err) {
+ if (err != 0) {
sdk_err(nic_io->dev_hdl, "Failed to create rx queue(%u) wq\n",
q_id);
return err;
@@ -318,14 +328,14 @@ static int create_qp(struct hinic3_nic_io *nic_io, struct hinic3_io_queue *sq,
int err;
err = hinic3_create_sq(nic_io, sq, q_id, sq_depth, qp_msix_idx);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to create sq, qid: %u\n",
q_id);
return err;
}
err = hinic3_create_rq(nic_io, rq, q_id, rq_depth, qp_msix_idx);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to create rq, qid: %u\n",
q_id);
goto create_rq_err;
@@ -364,14 +374,14 @@ int hinic3_init_nicio_res(void *hwdev)
nic_io->max_qps = hinic3_func_max_qnum(hwdev);
err = hinic3_alloc_db_addr(hwdev, &db_base, NULL);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to allocate doorbell for sqs\n");
goto alloc_sq_db_fail;
}
nic_io->sqs_db_addr = (u8 *)db_base;
err = hinic3_alloc_db_addr(hwdev, &db_base, NULL);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to allocate doorbell for rqs\n");
goto alloc_rq_db_fail;
}
@@ -474,7 +484,7 @@ int hinic3_alloc_qps(void *hwdev, struct irq_info *qps_msix_arry,
for (q_id = 0; q_id < num_qps; q_id++) {
err = create_qp(nic_io, &sqs[q_id], &rqs[q_id], q_id, qp_params->sq_depth,
qp_params->rq_depth, qps_msix_arry[q_id].msix_entry_idx);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to allocate qp %u, err: %d\n", q_id, err);
goto create_qp_err;
}
@@ -599,14 +609,14 @@ int hinic3_create_qps(void *hwdev, u16 num_qp, u32 sq_depth, u32 rq_depth,
}
err = hinic3_init_nicio_res(hwdev);
- if (err)
+ if (err != 0)
return err;
qp_params.num_qps = num_qp;
qp_params.sq_depth = sq_depth;
qp_params.rq_depth = rq_depth;
err = hinic3_alloc_qps(hwdev, qps_msix_arry, &qp_params);
- if (err) {
+ if (err != 0) {
hinic3_deinit_nicio_res(hwdev);
nic_err(nic_io->dev_hdl,
"Failed to allocate qps, err: %d\n", err);
@@ -906,11 +916,11 @@ static int init_qp_ctxts(struct hinic3_nic_io *nic_io)
int err;
err = init_sq_ctxts(nic_io);
- if (err)
+ if (err != 0)
return err;
err = init_rq_ctxts(nic_io);
- if (err)
+ if (err != 0)
return err;
return 0;
@@ -1026,14 +1036,14 @@ int hinic3_init_qp_ctxts(void *hwdev)
return -EFAULT;
err = init_qp_ctxts(nic_io);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to init QP ctxts\n");
return err;
}
/* clean LRO/TSO context space */
err = clean_qp_offload_ctxt(nic_io);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to clean qp offload ctxts\n");
return err;
}
@@ -1042,13 +1052,13 @@ int hinic3_init_qp_ctxts(void *hwdev)
err = hinic3_set_root_ctxt(hwdev, rq_depth, nic_io->sq[0].wq.q_depth,
nic_io->rx_buff_len, HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set root context\n");
return err;
}
err = init_sq_ci_ctxts(nic_io);
- if (err)
+ if (err != 0)
goto clean_root_ctxt;
if (HINIC3_SUPPORT_RX_COMPACT_CQE(hwdev)) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
index 37f923d..c5e02ad 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
@@ -317,7 +317,7 @@ static inline void hinic3_write_db(struct hinic3_io_queue *queue, int cos,
wmb(); /* Write all before the doorbell */
- writeq(*((u64 *)&db), DB_ADDR(queue, pi));
+ writeq(*((u64 *)(u8 *)&db), DB_ADDR(queue, pi));
}
struct hinic3_dyna_qp_params {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
index 78d943d..9ea93a0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
@@ -32,7 +32,7 @@ struct hinic3_prof_adapter nic_prof_adap_objs[] = {
void hinic3_init_nic_prof_adapter(struct hinic3_nic_dev *nic_dev)
{
- u16 num_adap = ARRAY_SIZE(nic_prof_adap_objs);
+ int num_adap = ARRAY_LEN(nic_prof_adap_objs);
nic_dev->prof_adap = hinic3_prof_init(nic_dev, nic_prof_adap_objs, num_adap,
(void *)&nic_dev->prof_attr);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
index 6302fb8..dc4bb9e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
@@ -430,7 +430,8 @@ hinic3_dynamic_lookup_tcam_filter(struct hinic3_nic_dev *nic_dev,
list_for_each_entry(tmp,
&tcam_info->tcam_dynamic_info.tcam_dynamic_list,
block_list)
- if (tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)
+ if (tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE ||
+ !tmp)
break;
if (!tmp || tmp->dynamic_index_cnt >= HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) {
@@ -512,7 +513,7 @@ static int hinic3_add_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, queue: %d, tcam_rule_nums: %d succeed\n",
+ "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, queue: %u, tcam_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev),
tcam_filter->dynamic_block_id, index, fdir_tcam_rule->index,
fdir_tcam_rule->data.qid, tcam_info->tcam_rule_nums + 1);
@@ -579,7 +580,7 @@ static int hinic3_del_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, local_rules_nums: %d, global_rule_nums: %d succeed\n",
+ "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, local_rules_nums: %u, global_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev), dynamic_block_id,
tcam_filter->index, index, tmp->dynamic_index_cnt - 1,
tcam_info->tcam_rule_nums - 1);
@@ -605,7 +606,7 @@ static inline struct hinic3_tcam_filter *
hinic3_tcam_filter_lookup(const struct list_head *filter_list,
struct tag_tcam_key *key)
{
- struct hinic3_tcam_filter *iter;
+ struct hinic3_tcam_filter *iter = NULL;
list_for_each_entry(iter, filter_list, tcam_filter_list) {
if (memcmp(key, &iter->tcam_key,
@@ -630,7 +631,7 @@ static int hinic3_remove_one_rule(struct hinic3_nic_dev *nic_dev,
struct hinic3_ethtool_rx_flow_rule *eth_rule)
{
struct hinic3_tcam_info *tcam_info = &nic_dev->tcam;
- struct hinic3_tcam_filter *tcam_filter;
+ struct hinic3_tcam_filter *tcam_filter = NULL;
struct nic_tcam_cfg_rule fdir_tcam_rule;
struct tag_tcam_key tcam_key;
int err;
@@ -751,7 +752,7 @@ static int validate_flow(struct hinic3_nic_dev *nic_dev,
{
if (fs->location >= MAX_NUM_OF_ETHTOOL_NTUPLE_RULES) {
nicif_err(nic_dev, drv, nic_dev->netdev, "loc exceed limit[0,%lu]\n",
- MAX_NUM_OF_ETHTOOL_NTUPLE_RULES);
+ MAX_NUM_OF_ETHTOOL_NTUPLE_RULES - 1);
return -EINVAL;
}
@@ -872,7 +873,7 @@ int hinic3_ethtool_get_flow(const struct hinic3_nic_dev *nic_dev,
int hinic3_ethtool_get_all_flows(const struct hinic3_nic_dev *nic_dev,
struct ethtool_rxnfc *info, u32 *rule_locs)
{
- int idx = 0;
+ u32 idx = 0;
struct hinic3_ethtool_rx_flow_rule *eth_rule = NULL;
if (!HINIC3_SUPPORT_FDIR(nic_dev->hwdev)) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h b/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
index a93f3b6..9202218 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
@@ -38,13 +38,12 @@ struct hinic3_prof_adapter {
#define LLT_STATIC_DEF_SAVED
#endif
-/*lint -save -e661 */
static inline struct hinic3_prof_adapter *
hinic3_prof_init(void *device, struct hinic3_prof_adapter *adap_objs, int num_adap,
void **prof_attr)
{
struct hinic3_prof_adapter *prof_obj = NULL;
- u16 i;
+ int i;
for (i = 0; i < num_adap; i++) {
prof_obj = &adap_objs[i];
@@ -68,7 +67,6 @@ static inline void hinic3_prof_deinit(struct hinic3_prof_adapter *prof_obj, void
prof_obj->deinit(prof_attr);
}
-/*lint -restore*/
/* module-level interface */
#ifdef CONFIG_MODULE_PROF
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
index e4705c2..dcd79ee 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/dcbnl.h>
+#include <linux/init.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -23,7 +24,6 @@
#include "hinic3_hw.h"
#include "hinic3_rss.h"
-/*lint -e806*/
static u16 num_qps;
module_param(num_qps, ushort, 0444);
MODULE_PARM_DESC(num_qps, "Number of Queue Pairs (default=0)");
@@ -104,88 +104,83 @@ static int hinic3_get_rq2iq_map(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev, u8 num_cos, u32 *indir)
+static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev,
+ u8 group_num, u32 *indir)
{
- u16 k, group_size, start_qid = 0, qp_num = 0;
- int i = 0;
- u8 j, cur_cos = 0, default_cos;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ u16 k, group_size, start_qid = 0, cur_cos_qnum = 0;
+ u32 i = 0;
+ u8 j, cur_cos = 0, group = 0;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
- if (num_cos == 0) {
+ if (group_num == 0) {
for (i = 0; i < NIC_RSS_INDIR_SIZE; i++)
indir[i] = i % nic_dev->q_params.num_qps;
} else {
- group_size = NIC_RSS_INDIR_SIZE / num_cos;
-
- for (j = 0; j < num_cos; j++) {
- while (cur_cos < NIC_DCB_COS_MAX &&
- nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos] == 0)
- cur_cos++;
-
- if (cur_cos >= NIC_DCB_COS_MAX) {
- if (BIT(nic_dev->hw_dcb_cfg.default_cos) & valid_cos_map)
- default_cos = nic_dev->hw_dcb_cfg.default_cos;
- else
- default_cos = (u8)fls(valid_cos_map) - 1;
+ group_size = NIC_RSS_INDIR_SIZE / group_num;
+
+ for (group = 0; group < group_num; group++) {
+ cur_cos = dcb->hw_dcb_cfg.default_cos;
+ for (j = 0; j < NIC_DCB_COS_MAX; j++) {
+ if ((BIT(j) & valid_cos_map) != 0) {
+ cur_cos = j;
+ valid_cos_map -= (u8)BIT(j);
+ break;
+ }
+ }
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[default_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[default_cos];
+ cur_cos_qnum = dcb->hw_dcb_cfg.cos_qp_num[cur_cos];
+ if (cur_cos_qnum > 0) {
+ start_qid =
+ dcb->hw_dcb_cfg.cos_qp_offset[cur_cos];
} else {
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[cur_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos];
+ start_qid = cur_cos % nic_dev->q_params.num_qps;
+ /* Ensure that the offset of start_id is 0. */
+ cur_cos_qnum = 1;
}
for (k = 0; k < group_size; k++)
- indir[i++] = start_qid + k % qp_num;
-
- cur_cos++;
+ indir[i++] = start_qid + k % cur_cos_qnum;
}
}
}
-/*lint -e528*/
int hinic3_rss_init(struct hinic3_nic_dev *nic_dev, u8 *rq2iq_map, u32 map_size, u8 dcb_en)
{
struct net_device *netdev = nic_dev->netdev;
- u8 i, cos_num;
- u8 cos_map[NIC_DCB_UP_MAX] = {0};
- u8 cfg_map[NIC_DCB_UP_MAX] = {0};
+ u8 i, group_num, cos_bitmap, group = 0;
+ u8 cos_group[NIC_DCB_UP_MAX] = {0};
int err;
- if (dcb_en) {
- cos_num = hinic3_get_dev_user_cos_num(nic_dev);
-
- if (nic_dev->hw_dcb_cfg.trust == 0) {
- memcpy(cfg_map, nic_dev->hw_dcb_cfg.pcp2cos, sizeof(cfg_map));
- } else if (nic_dev->hw_dcb_cfg.trust == 1) {
- for (i = 0; i < NIC_DCB_UP_MAX; i++)
- cfg_map[i] = nic_dev->hw_dcb_cfg.dscp2cos[i * NIC_DCB_DSCP_NUM];
- }
-#define COS_CHANGE_OFFSET 4
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[COS_CHANGE_OFFSET + i] = cfg_map[i];
+ if (dcb_en != 0) {
+ group_num = (u8)roundup_pow_of_two(hinic3_get_dev_user_cos_num(nic_dev));
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[i] = cfg_map[NIC_DCB_UP_MAX - (i + 1)];
+ cos_bitmap = hinic3_get_dev_valid_cos_map(nic_dev);
- while (cos_num & (cos_num - 1))
- cos_num++;
+ for (i = 0; i < NIC_DCB_UP_MAX; i++) {
+ if ((BIT(i) & cos_bitmap) != 0)
+ cos_group[NIC_DCB_UP_MAX - i - 1] = group++;
+ else
+ cos_group[NIC_DCB_UP_MAX - i - 1] =
+ group_num - 1;
+ }
} else {
- cos_num = 0;
+ group_num = 0;
}
- err = hinic3_set_hw_rss_parameters(netdev, 1, cos_num, cos_map, dcb_en);
+ err = hinic3_set_hw_rss_parameters(netdev, 1, group_num,
+ cos_group, dcb_en);
if (err)
return err;
- err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps, cos_num, cos_map,
- NIC_DCB_UP_MAX, nic_dev->rss_indir, rq2iq_map, map_size);
+ err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps,
+ group_num, cos_group, NIC_DCB_UP_MAX,
+ nic_dev->rss_indir, rq2iq_map, map_size);
if (err)
nicif_err(nic_dev, drv, netdev, "Failed to get rq map\n");
return err;
}
-/*lint -e528*/
void hinic3_rss_deinit(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -246,11 +241,29 @@ discard_user_rss_indir:
hinic3_set_default_rss_indir(netdev);
}
+#ifdef HAVE_HOT_REPLACE_FUNC
+bool partition_slave_doing_hotupgrade(void)
+{
+ return get_partition_role() && partition_doing_hotupgrade();
+}
+#endif
+
static void decide_num_qps(struct hinic3_nic_dev *nic_dev)
{
u16 tmp_num_qps = nic_dev->max_qps;
u16 num_cpus = 0;
+ u16 max_num_cpus;
int i, node;
+ int is_in_kexec = vram_get_kexec_flag();
+
+ if (is_in_kexec != 0) {
+ nic_dev->q_params.num_qps = nic_dev->nic_vram->vram_num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Os hotreplace use vram to init num qps 1:%u 2:%u\n",
+ nic_dev->q_params.num_qps,
+ nic_dev->nic_vram->vram_num_qps);
+ return;
+ }
if (nic_dev->nic_cap.default_num_queues != 0 &&
nic_dev->nic_cap.default_num_queues < nic_dev->max_qps)
@@ -258,16 +271,29 @@ static void decide_num_qps(struct hinic3_nic_dev *nic_dev)
MOD_PARA_VALIDATE_NUM_QPS(nic_dev, num_qps, tmp_num_qps);
- for (i = 0; i < (int)num_online_cpus(); i++) {
+#ifdef HAVE_HOT_REPLACE_FUNC
+ if (partition_slave_doing_hotupgrade())
+ max_num_cpus = (u16)num_present_cpus();
+ else
+ max_num_cpus = (u16)num_online_cpus();
+#else
+ max_num_cpus = (u16)num_online_cpus();
+#endif
+
+ for (i = 0; i < max_num_cpus; i++) {
node = (int)cpu_to_node(i);
if (node == dev_to_node(&nic_dev->pdev->dev))
num_cpus++;
}
if (!num_cpus)
- num_cpus = (u16)num_online_cpus();
+ num_cpus = max_num_cpus;
nic_dev->q_params.num_qps = (u16)min_t(u16, tmp_num_qps, num_cpus);
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "init num qps 1:%u 2:%u\n",
+ nic_dev->q_params.num_qps, nic_dev->nic_vram->vram_num_qps);
}
static void copy_value_to_rss_hkey(struct hinic3_nic_dev *nic_dev,
@@ -322,7 +348,6 @@ static int alloc_rss_resource(struct hinic3_nic_dev *nic_dev)
return 0;
}
-/*lint -e528*/
void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -361,6 +386,7 @@ void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
set_q_params:
clear_bit(HINIC3_RSS_ENABLE, &nic_dev->flags);
nic_dev->q_params.num_qps = nic_dev->max_qps;
+ nic_dev->nic_vram->vram_num_qps = nic_dev->max_qps;
}
static int hinic3_config_rss_hw_resource(struct hinic3_nic_dev *nic_dev,
@@ -754,6 +780,7 @@ int hinic3_set_channels(struct net_device *netdev,
nic_dev->q_params.num_qps = (u16)count;
}
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
return 0;
}
@@ -814,7 +841,7 @@ int hinic3_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
int err = 0;
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
@@ -921,7 +948,7 @@ int hinic3_get_rxfh_indir(struct net_device *netdev, u32 *indir)
indir = indir1->ring_index;
#endif
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
index 071418d..4f4b18c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
@@ -15,14 +15,15 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_nic_cfg.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_hw.h"
#include "hinic3_nic.h"
#include "hinic3_nic_cmdq.h"
#include "hinic3_common.h"
static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
- u8 *key)
+ u8 *key, u16 key_size)
{
struct hinic3_cmd_rss_hash_key hash_key;
u16 out_size = sizeof(hash_key);
@@ -33,7 +34,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
hash_key.opcode = opcode;
if (opcode == HINIC3_CMD_OP_SET)
- memcpy(hash_key.key, key, NIC_RSS_KEY_SIZE);
+ memcpy(hash_key.key, key, key_size);
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_CFG_RSS_HASH_KEY,
@@ -47,7 +48,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
}
if (opcode == HINIC3_CMD_OP_GET)
- memcpy(key, hash_key.key, NIC_RSS_KEY_SIZE);
+ memcpy(key, hash_key.key, key_size);
return 0;
}
@@ -61,8 +62,12 @@ int hinic3_rss_set_hash_key(void *hwdev, const u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memcpy(hash_key, key, NIC_RSS_KEY_SIZE);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET, hash_key);
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET,
+ hash_key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
@@ -73,7 +78,11 @@ int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET, key);
+ if (!nic_io)
+ return -EINVAL;
+
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET,
+ key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
@@ -89,6 +98,7 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
if (nic_io == NULL)
return -EINVAL;
+
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (cmd_buf == NULL) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -159,6 +169,8 @@ static int hinic3_cmdq_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
@@ -210,6 +222,9 @@ static int hinic3_mgmt_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&ctx_tbl, 0, sizeof(ctx_tbl));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
ctx |= HINIC3_RSS_TYPE_SET(1, VALID) |
@@ -259,6 +274,8 @@ int hinic3_get_rss_type(void *hwdev, struct nic_rss_type *rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&ctx_tbl, 0, sizeof(struct hinic3_rss_context_table));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
@@ -292,6 +309,9 @@ static int hinic3_rss_cfg_hash_engine(struct hinic3_nic_io *nic_io, u8 opcode,
u16 out_size = sizeof(hash_type);
int err;
+ if (!nic_io)
+ return -EINVAL;
+
memset(&hash_type, 0, sizeof(struct hinic3_cmd_rss_engine_type));
hash_type.func_id = hinic3_global_func_id(nic_io->hwdev);
@@ -325,6 +345,9 @@ int hinic3_rss_set_hash_engine(void *hwdev, u8 type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_SET, &type);
}
@@ -336,6 +359,9 @@ int hinic3_rss_get_hash_engine(void *hwdev, u8 *type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_GET, type);
}
@@ -351,6 +377,9 @@ int hinic3_rss_cfg(void *hwdev, u8 rss_en, u8 cos_num, u8 *prio_tc, u16 num_qps)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&rss_cfg, 0, sizeof(struct hinic3_cmd_rss_config));
rss_cfg.func_id = hinic3_global_func_id(hwdev);
rss_cfg.rss_en = rss_en;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
index f8a866d..936258c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
@@ -21,6 +21,7 @@
#include <linux/ipv6.h>
#include <linux/module.h>
#include <linux/compiler.h>
+#include <linux/filter.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -63,19 +64,31 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
struct pci_dev *pdev = nic_dev->pdev;
struct page *page = rx_info->page;
dma_addr_t dma = rx_info->buf_dma_addr;
+ u32 page_offset = 0;
if (likely(dma))
return true;
/* alloc new page for storage */
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page = page_pool_alloc_frag(rx_info->page_pool, &page_offset,
+ nic_dev->rx_buff_len,
+ GFP_ATOMIC | __GFP_COLD | __GFP_COMP);
+ if (unlikely(!page))
+ return false;
+ dma = page_pool_get_dma_addr(page);
+ goto set_rx_info;
+ }
+#endif
page = alloc_pages_node(NUMA_NO_NODE, GFP_ATOMIC | __GFP_COLD |
__GFP_COMP, nic_dev->page_order);
if (unlikely(!page))
return false;
/* map page for use */
- dma = dma_map_page(&pdev->dev, page, 0, nic_dev->dma_rx_buff_size,
- DMA_FROM_DEVICE);
+ dma = dma_map_page(&pdev->dev, page, page_offset,
+ nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
/* if mapping failed free memory back to system since
* there isn't much point in holding memory we can't use
*/
@@ -83,10 +96,12 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
__free_pages(page, nic_dev->page_order);
return false;
}
+ goto set_rx_info;
+set_rx_info:
rx_info->page = page;
rx_info->buf_dma_addr = dma;
- rx_info->page_offset = 0;
+ rx_info->page_offset = page_offset;
return true;
}
@@ -108,7 +123,7 @@ static u32 hinic3_rx_fill_wqe(struct hinic3_rxq *rxq)
/* unit of cqe length is 16B */
hinic3_set_sge(&rq_wqe->extend_wqe.cqe_sect.sge,
rx_info->cqe_dma,
- (sizeof(struct hinic3_rq_cqe) >>
+ (HINIC3_CQE_LEN >>
HINIC3_CQE_SIZE_SHIFT));
/* use fixed len */
rq_wqe->extend_wqe.buf_desc.sge.len =
@@ -169,7 +184,7 @@ static u32 hinic3_rx_fill_buffers(struct hinic3_rxq *rxq)
if (likely(i)) {
hinic3_write_db(rxq->rq,
- rxq->q_id & 3,
+ rxq->q_id & (NIC_RX_DB_COS_MAX - 1),
RQ_CFLAG_DP,
(u16)((u32)rxq->next_to_update <<
rxq->rq->wqe_type));
@@ -206,6 +221,18 @@ static void hinic3_rx_free_buffers(struct hinic3_nic_dev *nic_dev, u32 q_depth,
for (i = 0; i < q_depth; i++) {
rx_info = &rx_info_arr[i];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ if (rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool,
+ rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ }
+ continue;
+ }
+#endif
+
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev,
rx_info->buf_dma_addr,
@@ -265,8 +292,15 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
DMA_FROM_DEVICE);
if (size <= HINIC3_RX_HDR_SIZE && !skb_is_nonlinear(skb)) {
- memcpy(__skb_put(skb, size), va + offset,
- ALIGN(size, sizeof(long))); /*lint !e666*/
+ __skb_put_data(skb, va + offset, size);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool,
+ page, false);
+ return false;
+ }
+#endif
/* page is not reserved, we can reuse buffer as-is */
if (likely(page_to_nid(page) == numa_node_id()))
@@ -274,25 +308,38 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
/* this page cannot be reused so discard it */
put_page(page);
- return false;
+ goto discard_page;
}
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
- (int)(rx_info->page_offset + offset), (int)size, rxq->buf_len);
+ (int)(rx_info->page_offset + offset), (int)size,
+ rxq->buf_len);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
/* avoid re-using remote pages */
if (unlikely(page_to_nid(page) != numa_node_id()))
- return false;
+ goto discard_page;
/* if we are only owner of page we can reuse it */
if (unlikely(page_count(page) != 1))
- return false;
+ goto discard_page;
/* flip page offset to other buffer */
rx_info->page_offset ^= rxq->buf_len;
get_page(page);
return true;
+
+discard_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
}
static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
@@ -338,10 +385,6 @@ static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
if (likely(hinic3_add_rx_frag(rxq, rx_info, skb, frag_size, tmp_pkt_offset))) {
hinic3_reuse_rx_page(rxq, rx_info);
- } else {
- /* we are not reusing the buffer so unmap it */
- dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
- rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
}
/* clear contents of buffer_info */
rx_info->buf_dma_addr = 0;
@@ -486,9 +529,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
protocol = hdr.eth->h_proto;
/* L2 header */
- /*lint -save -e778*/
if (protocol == htons(ETH_P_8021_AD) ||
- protocol == htons(ETH_P_8021_Q)) { /*lint -restore*/
+ protocol == htons(ETH_P_8021_Q)) {
if (unlikely(max_len < ETH_HLEN + VLAN_HLEN))
return max_len;
@@ -500,9 +542,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
}
/* L3 header */
- /*lint -save -e778*/
switch (protocol) {
- case htons(ETH_P_IP): /*lint -restore*/
+ case htons(ETH_P_IP):
if ((int)(hdr.data - data) >
(int)(max_len - sizeof(struct iphdr)))
return max_len;
@@ -713,7 +754,10 @@ static inline void hinic3_lro_set_gso_params(struct sk_buff *skb, u16 num_lro)
}
#ifdef HAVE_XDP_SUPPORT
-enum hinic3_xdp_pkt {
+enum hinic3_xdp_status {
+ // bpf_prog status
+ HINIC3_XDP_PROG_EMPTY,
+ // pkt action
HINIC3_XDP_PKT_PASS,
HINIC3_XDP_PKT_DROP,
};
@@ -724,9 +768,15 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
while (weqbb_num) {
rx_info = &rxq->rx_info[rxq->cons_idx & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool)
+ goto discard_direct;
+#endif
if (likely(page_to_nid(rx_info->page) == numa_node_id()))
hinic3_reuse_rx_page(rxq, rx_info);
+ goto discard_direct;
+discard_direct:
rx_info->buf_dma_addr = 0;
rx_info->page = NULL;
rxq->cons_idx++;
@@ -736,11 +786,11 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
}
}
-int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
+int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len, struct xdp_buff *xdp)
{
struct bpf_prog *xdp_prog = NULL;
struct hinic3_rx_info *rx_info = NULL;
- struct xdp_buff xdp;
+ struct net_device *netdev = rxq->netdev;
int result = HINIC3_XDP_PKT_PASS;
u16 weqbb_num = 1; /* xdp can only use one rx_buff */
u8 *va = NULL;
@@ -748,13 +798,14 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
rcu_read_lock();
xdp_prog = READ_ONCE(rxq->xdp_prog);
- if (!xdp_prog)
+ if (!xdp_prog) {
+ result = HINIC3_XDP_PROG_EMPTY;
goto unlock_rcu;
+ }
if (unlikely(pkt_len > rxq->buf_len)) {
RXQ_STATS_INC(rxq, xdp_large_pkt);
- weqbb_num = (u16)(pkt_len >> rxq->rx_buff_shift) +
- ((pkt_len & (rxq->buf_len - 1)) ? 1 : 0);
+ weqbb_num = HINIC3_GET_SGE_NUM(pkt_len, rxq);
result = HINIC3_XDP_PKT_DROP;
goto xdp_out;
}
@@ -765,26 +816,27 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
dma_sync_single_range_for_cpu(rxq->dev, rx_info->buf_dma_addr,
rx_info->page_offset,
rxq->buf_len, DMA_FROM_DEVICE);
- xdp.data = va;
- xdp.data_hard_start = xdp.data;
- xdp.data_end = xdp.data + pkt_len;
+ xdp->data = va;
+ xdp->data_hard_start = xdp->data;
+ xdp->data_end = xdp->data + pkt_len;
#ifdef HAVE_XDP_FRAME_SZ
- xdp.frame_sz = rxq->buf_len;
+ xdp->frame_sz = rxq->buf_len;
#endif
#ifdef HAVE_XDP_DATA_META
- xdp_set_data_meta_invalid(&xdp);
+ xdp_set_data_meta_invalid(xdp);
#endif
- prefetchw(xdp.data_hard_start);
- act = bpf_prog_run_xdp(xdp_prog, &xdp);
+ prefetchw(xdp->data_hard_start);
+ act = bpf_prog_run_xdp(xdp_prog, xdp);
switch (act) {
case XDP_PASS:
+ result = HINIC3_XDP_PKT_PASS;
break;
case XDP_DROP:
result = HINIC3_XDP_PKT_DROP;
break;
default:
result = HINIC3_XDP_PKT_DROP;
- bpf_warn_invalid_xdp_action(rxq->netdev, xdp_prog, act);
+ bpf_warn_invalid_xdp_action(netdev, xdp_prog, act);
}
xdp_out:
@@ -798,9 +850,86 @@ unlock_rcu:
return result;
}
+
+static bool hinic3_add_rx_frag_with_xdp(struct hinic3_rxq *rxq, u32 pkt_len,
+ struct hinic3_rx_info *rx_info,
+ struct sk_buff *skb, struct xdp_buff *xdp)
+{
+ struct page *page = rx_info->page;
+
+ if (pkt_len <= HINIC3_RX_HDR_SIZE) {
+ __skb_put_data(skb, xdp->data, pkt_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool, page, false);
+ return false;
+ }
+#endif
+ if (likely(page_to_nid(page) == numa_node_id()))
+ return true;
+
+ put_page(page);
+ goto umap_page;
+ }
+
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
+ (int)(rx_info->page_offset +
+ (xdp->data - xdp->data_hard_start)),
+ (int)pkt_len, rxq->buf_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
+ if (unlikely(page_to_nid(page) != numa_node_id()))
+ goto umap_page;
+ if (unlikely(page_count(page) != 1))
+ goto umap_page;
+
+ rx_info->page_offset ^= rxq->buf_len;
+ get_page(page);
+
+ return true;
+umap_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
+}
+
+static struct sk_buff *hinic3_fetch_rx_buffer_xdp(struct hinic3_rxq *rxq,
+ u32 pkt_len,
+ struct xdp_buff *xdp)
+{
+ struct sk_buff *skb;
+ struct hinic3_rx_info *rx_info;
+ u32 sw_ci;
+ bool reuse;
+
+ sw_ci = rxq->cons_idx & rxq->q_mask;
+ rx_info = &rxq->rx_info[sw_ci];
+
+ skb = netdev_alloc_skb_ip_align(rxq->netdev, HINIC3_RX_HDR_SIZE);
+ if (unlikely(!skb))
+ return NULL;
+
+ reuse = hinic3_add_rx_frag_with_xdp(rxq, pkt_len, rx_info, skb, xdp);
+ if (likely(reuse))
+ hinic3_reuse_rx_page(rxq, rx_info);
+
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+
+ rxq->cons_idx += 1;
+ rxq->delta += 1;
+
+ return skb;
+}
+
#endif
-static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_cqe_info *cqe_info)
+static int recv_one_pkt(struct hinic3_rxq *rxq,
+ struct hinic3_cqe_info *cqe_info)
{
struct sk_buff *skb = NULL;
struct net_device *netdev = rxq->netdev;
@@ -808,13 +937,25 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_cqe_info *cqe_info
#ifdef HAVE_XDP_SUPPORT
u32 xdp_status;
+ struct xdp_buff xdp = { 0 };
- xdp_status = (u32)(hinic3_run_xdp(rxq, cqe_info->pkt_len));
+ xdp_status = (u32)(hinic3_run_xdp(rxq, cqe_info->pkt_len, &xdp));
if (xdp_status == HINIC3_XDP_PKT_DROP)
return 0;
-#endif
+ // build skb
+ if (xdp_status != HINIC3_XDP_PROG_EMPTY) {
+ // xdp_prog configured, build skb with xdp
+ skb = hinic3_fetch_rx_buffer_xdp(rxq, cqe_info->pkt_len, &xdp);
+ } else {
+ // xdp_prog not configured, build skb
+ skb = hinic3_fetch_rx_buffer(rxq, cqe_info);
+ }
+#else
+
+ // xdp is not supported
skb = hinic3_fetch_rx_buffer(rxq, cqe_info);
+#endif
if (unlikely(!skb)) {
RXQ_STATS_INC(rxq, alloc_skb_err);
return -ENOMEM;
@@ -842,7 +983,7 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_cqe_info *cqe_info
if (unlikely(test_bit(HINIC3_LP_TEST, &nic_dev->flags)))
hinic3_copy_lp_data(nic_dev, skb);
- if (cqe_info->lro_num)
+ if (cqe_info->lro_num > 1)
hinic3_lro_set_gso_params(skb, cqe_info->lro_num);
skb_record_rx_queue(skb, rxq->q_id);
@@ -1021,12 +1162,39 @@ int hinic3_rx_poll(struct hinic3_rxq *rxq, int budget)
return pkts;
}
+#ifdef HAVE_PAGE_POOL_SUPPORT
+static struct page_pool *hinic3_create_page_pool(struct hinic3_nic_dev *nic_dev,
+ u32 rq_depth,
+ struct hinic3_rx_info *rx_info_arr)
+{
+ struct page_pool_params pp_params = {
+ .flags = PP_FLAG_DMA_MAP | PP_FLAG_PAGE_FRAG | PP_FLAG_DMA_SYNC_DEV,
+ .order = nic_dev->page_order,
+ .pool_size = rq_depth * nic_dev->rx_buff_len /
+ (PAGE_SIZE << nic_dev->page_order),
+ .nid = dev_to_node(&nic_dev->pdev->dev),
+ .dev = &nic_dev->pdev->dev,
+ .dma_dir = DMA_FROM_DEVICE,
+ .offset = 0,
+ .max_len = PAGE_SIZE << nic_dev->page_order,
+ };
+ struct page_pool *page_pool;
+ int i;
+
+ page_pool = nic_dev->page_pool_enabled ?
+ page_pool_create(&pp_params) : NULL;
+ for (i = 0; i < rq_depth; i++)
+ rx_info_arr[i].page_pool = page_pool;
+ return page_pool;
+}
+#endif
+
int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
u32 rq_depth, struct hinic3_dyna_rxq_res *rxqs_res)
{
struct hinic3_dyna_rxq_res *rqres = NULL;
u64 cqe_mem_size = sizeof(struct hinic3_rq_cqe) * rq_depth;
- int idx, i;
+ int idx;
u32 pkts;
u64 size;
@@ -1045,51 +1213,53 @@ int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
if (!rqres->rx_info) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx info\n", idx);
- goto err_out;
+ goto err_alloc_rx_info;
}
-
if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
rqres->cqe_start_vaddr =
- dma_zalloc_coherent(&nic_dev->pdev->dev, cqe_mem_size,
+ dma_zalloc_coherent(&nic_dev->pdev->dev,
+ cqe_mem_size,
&rqres->cqe_start_paddr,
GFP_KERNEL);
if (!rqres->cqe_start_vaddr) {
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d cqe\n", idx);
- goto err_out;
+ goto err_alloc_cqe;
}
}
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ rqres->page_pool = hinic3_create_page_pool(nic_dev, rq_depth,
+ rqres->rx_info);
+ if (nic_dev->page_pool_enabled && !rqres->page_pool) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to create rxq%d page pool\n", idx);
+ goto err_create_page_pool;
+ }
+#endif
pkts = hinic3_rx_alloc_buffers(nic_dev, rq_depth,
rqres->rx_info);
if (!pkts) {
- if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- }
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx buffers\n", idx);
- goto err_out;
+ goto err_alloc_buffers;
}
rqres->next_to_alloc = (u16)pkts;
}
return 0;
-err_out:
- for (i = 0; i < idx; i++) {
- rqres = &rxqs_res[i];
-
- hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
- if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- }
- kfree(rqres->rx_info);
- }
-
+err_alloc_buffers:
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ page_pool_destroy(rqres->page_pool);
+err_create_page_pool:
+#endif
+ dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
+ rqres->cqe_start_vaddr,
+ rqres->cqe_start_paddr);
+err_alloc_cqe:
+ kfree(rqres->rx_info);
+err_alloc_rx_info:
+ hinic3_free_rxqs_res(nic_dev, idx, rq_depth, rxqs_res);
return -ENOMEM;
}
@@ -1104,6 +1274,10 @@ void hinic3_free_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
rqres = &rxqs_res[idx];
hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rqres->page_pool)
+ page_pool_destroy(rqres->page_pool);
+#endif
if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
rqres->cqe_start_vaddr,
@@ -1191,6 +1365,7 @@ void hinic3_free_rxqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->rxqs);
+ nic_dev->rxqs = NULL;
}
int hinic3_alloc_rxqs(struct net_device *netdev)
@@ -1312,6 +1487,14 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
nic_info(&nic_dev->pdev->dev, "rxq %u restore_buf_num:%u\n", q_id, rxq->restore_buf_num);
rx_info = &rxq->rx_info[(hw_ci + rxq->q_depth - 1) & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool && rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool, rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ goto reset_rxq;
+ }
+#endif
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev, rx_info->buf_dma_addr,
nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
@@ -1322,7 +1505,9 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
__free_pages(rx_info->page, nic_dev->page_order);
rx_info->page = NULL;
}
+ goto reset_rxq;
+reset_rxq:
rxq->delta = 1;
rxq->next_to_update = (u16)((hw_ci + rxq->q_depth - 1) & rxq->q_mask);
rxq->cons_idx = (u16)((rxq->next_to_update + 1) & rxq->q_mask);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
index 586a221..480f787 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
@@ -4,6 +4,10 @@
#ifndef HINIC3_RX_H
#define HINIC3_RX_H
+#ifdef HAVE_PAGE_POOL_SUPPORT
+#include <net/page_pool/helpers.h>
+#endif
+
#include <linux/types.h>
#include <linux/device.h>
#include <linux/mm_types.h>
@@ -27,6 +31,7 @@
#define HINIC3_RX_CSUM_IPSU_OTHER_ERR BIT(8)
#define HINIC3_HEADER_DATA_UNIT 2
+#define HINIC3_CQE_LEN 32
#define HINIC3_COMPACT_CQE_8B 8
#define HINIC3_COMPACT_CQE_16B 16
@@ -35,20 +40,20 @@
#define HINIC3_RQ_CQE_INTEGRATE 1
struct hinic3_rxq_stats {
- u64 packets;
- u64 bytes;
- u64 errors;
- u64 csum_errors;
- u64 other_errors;
- u64 dropped;
- u64 xdp_dropped;
- u64 rx_buf_empty;
-
- u64 alloc_skb_err;
- u64 alloc_rx_buf_err;
- u64 xdp_large_pkt;
- u64 restore_drop_sge;
- u64 rsvd2;
+ u64 packets;
+ u64 bytes;
+ u64 errors;
+ u64 csum_errors;
+ u64 other_errors;
+ u64 dropped;
+ u64 xdp_dropped;
+ u64 rx_buf_empty;
+
+ u64 alloc_skb_err;
+ u64 alloc_rx_buf_err;
+ u64 xdp_large_pkt;
+ u64 restore_drop_sge;
+ u64 rsvd2;
#ifdef HAVE_NDO_GET_STATS64
struct u64_stats_sync syncp;
#else
@@ -62,6 +67,9 @@ struct hinic3_rx_info {
struct hinic3_rq_cqe *cqe;
dma_addr_t cqe_dma;
struct page *page;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
u32 page_offset;
u32 rsvd1;
struct hinic3_rq_wqe *rq_wqe;
@@ -102,7 +110,7 @@ struct hinic3_rxq {
u16 next_to_update;
struct device *dev; /* device for DMA mapping */
- unsigned long status;
+ u64 status;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
@@ -130,6 +138,9 @@ struct hinic3_dyna_rxq_res {
struct hinic3_rx_info *rx_info;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
};
int hinic3_alloc_rxqs(struct net_device *netdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
index bdd5a8e..d816609 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
@@ -11,10 +11,12 @@
#ifndef HINIC3_SRV_NIC_H
#define HINIC3_SRV_NIC_H
-#include "hinic3_mgmt_interface.h"
+#include <linux/netdevice.h>
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_lld.h"
+#include "nic_cfg_comm.h"
+#include "nic_mpu_cmd_defs.h"
enum hinic3_queue_type {
HINIC3_SQ,
@@ -64,6 +66,7 @@ enum hinic3_nic_event_type {
EVENT_NIC_DCB_STATE_CHANGE,
EVENT_NIC_BOND_DOWN,
EVENT_NIC_BOND_UP,
+ EVENT_NIC_OUTBAND_CFG,
};
/* *
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
index bc1a8ef..99264c7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
@@ -223,24 +223,72 @@ static void get_inner_l3_l4_type(struct sk_buff *skb, union hinic3_ip *ip,
enum sq_l3_type *l3_type, u8 *l4_proto)
{
unsigned char *exthdr = NULL;
- __be16 frag_off = 0;
if (ip->v4->version == IP4_VERSION) {
*l3_type = IPV4_PKT_WITH_CHKSUM_OFFLOAD;
*l4_proto = ip->v4->protocol;
+
+#ifdef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
+ /* inner_transport_header is wrong in centos7.0 and suse12.1 */
+ l4->hdr = ip->hdr + ((u8)ip->v4->ihl << IP_HDR_IHL_UNIT_SHIFT);
+#endif
} else if (ip->v4->version == IP6_VERSION) {
*l3_type = IPV6_PKT;
exthdr = ip->hdr + sizeof(*ip->v6);
*l4_proto = ip->v6->nexthdr;
- if (exthdr != l4->hdr)
+ if (exthdr != l4->hdr) {
+ __be16 frag_off = 0;
+#ifndef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
ipv6_skip_exthdr(skb, (int)(exthdr - skb->data),
- l4_proto, &frag_off);
+ l4_proto, &frag_off);
+#else
+ int pld_off = 0;
+
+ pld_off = ipv6_skip_exthdr(skb,
+ (int)(exthdr - skb->data),
+ l4_proto, &frag_off);
+ l4->hdr = skb->data + pld_off;
+#endif
+ }
} else {
*l3_type = UNKNOWN_L3TYPE;
*l4_proto = 0;
}
}
+static u8 hinic3_get_inner_l4_type(struct sk_buff *skb)
+{
+ enum sq_l3_type l3_type;
+ u8 l4_proto;
+ union hinic3_ip ip;
+ union hinic3_l4 l4;
+
+ ip.hdr = skb_inner_network_header(skb);
+ l4.hdr = skb_inner_transport_header(skb);
+
+ get_inner_l3_l4_type(skb, &ip, &l4, &l3_type, &l4_proto);
+
+ return l4_proto;
+}
+
+static void hinic3_set_unknown_tunnel_csum(struct sk_buff *skb)
+{
+ int csum_offset;
+ __sum16 skb_csum;
+ u8 l4_proto;
+
+ l4_proto = hinic3_get_inner_l4_type(skb);
+ /* Unsupport tunnel packet, disable csum offload */
+ skb_checksum_help(skb);
+ /* The value of csum is changed from 0xffff to 0 according to RFC1624. */
+ if (skb->ip_summed == CHECKSUM_NONE && l4_proto != IPPROTO_UDP) {
+ csum_offset = skb_checksum_start_offset(skb) + skb->csum_offset;
+ skb_csum = *(__sum16 *)(skb->data + csum_offset);
+ if (skb_csum == 0xffff)
+ *(__sum16 *)(skb->data + csum_offset) = 0;
+ }
+}
+
static int hinic3_tx_csum(struct hinic3_txq *txq, struct sk_buff *skb,
struct hinic3_offload_info *offload_info,
struct hinic3_queue_info *queue_info)
@@ -276,10 +324,9 @@ static int hinic3_tx_csum(struct hinic3_txq *txq, struct sk_buff *skb,
if (l4_proto == IPPROTO_UDP)
queue_info->udp_dp_en = 1;
- if (l4_proto != IPPROTO_UDP ||
- ((struct udphdr *)skb_transport_header(skb))->dest != VXLAN_OFFLOAD_PORT_LE) {
+ if (l4_proto != IPPROTO_UDP) {
TXQ_STATS_INC(txq, unknown_tunnel_pkt);
- skb_checksum_help(skb);
+ hinic3_set_unknown_tunnel_csum(skb);
return 0;
}
}
@@ -682,6 +729,14 @@ static netdev_tx_t hinic3_send_one_skb(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
+ /* l2nic outband vlan cfg enable */
+ if (!skb_vlan_tag_present(skb) &&
+ nic_dev->nic_cap.outband_vlan_cfg_en == 1 &&
+ nic_dev->outband_cfg.outband_default_vid != 0) {
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+ (u16)nic_dev->outband_cfg.outband_default_vid);
+ }
+
offload = hinic3_tx_offload(skb, &offload_info, &queue_info, txq);
if (unlikely(offload == TX_OFFLOAD_INVALID)) {
TXQ_STATS_INC(txq, offload_cow_skb_err);
@@ -880,6 +935,7 @@ int hinic3_alloc_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
tqres->bds = kzalloc(size, GFP_KERNEL);
if (!tqres->bds) {
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc txq%d bds info\n", idx);
goto err_out;
@@ -893,7 +949,9 @@ err_out:
tqres = &txqs_res[i];
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
return -ENOMEM;
@@ -910,7 +968,9 @@ void hinic3_free_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
free_all_tx_skbs(nic_dev, sq_depth, tqres->tx_info);
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
}
@@ -982,6 +1042,7 @@ void hinic3_free_txqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->txqs);
+ nic_dev->txqs = NULL;
}
static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
@@ -998,7 +1059,7 @@ static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
static int hinic3_stop_sq(struct hinic3_txq *txq)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(txq->netdev);
- unsigned long timeout;
+ u64 timeout;
int err;
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -1007,7 +1068,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
return 0;
usleep_range(900, 1000); /* sleep 900 us ~ 1000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* force hardware to drop packets */
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -1020,7 +1081,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
break;
usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* Avoid msleep takes too long and get a fake result */
if (is_hw_complete_sq_process(txq->sq))
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
index 1b9e509..7ae029b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
@@ -29,7 +29,7 @@ struct hinic3_wq {
#define WQ_MASK_IDX(wq, idx) ((idx) & (wq)->idx_mask)
#define WQ_MASK_PAGE(wq, pg_idx) \
- ((pg_idx) < (wq)->num_wq_pages ? (pg_idx) : 0)
+ (((pg_idx) < ((wq)->num_wq_pages)) ? (pg_idx) : 0)
#define WQ_PAGE_IDX(wq, idx) ((idx) >> (wq)->wqebbs_per_page_shift)
#define WQ_OFFSET_IN_PAGE(wq, idx) ((idx) & (wq)->wqebbs_per_page_mask)
#define WQ_GET_WQEBB_ADDR(wq, pg_idx, idx_in_pg) \
@@ -75,7 +75,7 @@ static inline void *hinic3_wq_get_multi_wqebbs(struct hinic3_wq *wq,
pg_idx = WQ_PAGE_IDX(wq, *prod_idx);
off_in_page = WQ_OFFSET_IN_PAGE(wq, *prod_idx);
- if (off_in_page + num_wqebbs > wq->wqebbs_per_page) {
+ if ((off_in_page + num_wqebbs) > wq->wqebbs_per_page) {
/* wqe across wq page boundary */
*second_part_wqebbs_addr =
WQ_GET_WQEBB_ADDR(wq, WQ_MASK_PAGE(wq, pg_idx + 1), 0);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
index 597d3fe..468351f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
@@ -400,12 +400,15 @@ static int wait_for_status_poll(struct hinic3_api_cmd_chain *chain)
API_CMD_STATUS_TIMEOUT, 100); /* wait 100 us once */
}
-static void copy_resp_data(struct hinic3_api_cmd_cell_ctxt *ctxt, void *ack,
+static void copy_resp_data(struct hinic3_api_cmd_chain *chain,
+ struct hinic3_api_cmd_cell_ctxt *ctxt, void *ack,
u16 ack_size)
{
struct hinic3_api_cmd_resp_fmt *resp = ctxt->resp;
+ int rsp_size_align = chain->rsp_size_align - 0x8;
+ int rsp_size = (ack_size > rsp_size_align) ? rsp_size_align : ack_size;
- memcpy(ack, &resp->resp_data, ack_size);
+ memcpy(ack, &resp->resp_data, rsp_size);
ctxt->status = 0;
}
@@ -464,7 +467,7 @@ static int wait_for_api_cmd_completion(struct hinic3_api_cmd_chain *chain,
case HINIC3_API_CMD_POLL_READ:
err = wait_for_resp_polling(ctxt);
if (err == 0)
- copy_resp_data(ctxt, ack, ack_size);
+ copy_resp_data(chain, ctxt, ack, ack_size);
else
sdk_err(dev, "API CMD poll response timeout\n");
break;
@@ -1054,13 +1057,11 @@ alloc_cells_buf_err:
alloc_wb_status_err:
kfree(chain->cell_ctxt);
-/*lint -save -e548*/
alloc_cell_ctxt_err:
if (chain->chain_type == HINIC3_API_CMD_WRITE_ASYNC_TO_MGMT_CPU)
spin_lock_deinit(&chain->async_lock);
else
sema_deinit(&chain->sem);
-/*lint -restore*/
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
index 38474ba..9f10131 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
@@ -801,7 +801,7 @@ static int cmdq_sync_cmd(struct hinic3_cmdq *cmdq, u8 mod, u8 cmd,
hinic3_cmdq_fill_completion_info(cmd_info, &cmpt_code, &done, &errcode, out_param);
cmdq_set_cmd_buf(cmd_info, cmdq->hwdev, buf_in, buf_out);
- memcpy(&saved_cmd_info, cmd_info, sizeof(*cmd_info));
+ memcpy(&saved_cmd_info, cmd_info, sizeof(struct hinic3_cmdq_cmd_info));
cmdq_sync_wqe_prepare(cmdq, mod, cmd, buf_in, buf_out, curr_wqe, curr_pi, nic_cmd_type);
@@ -1075,6 +1075,7 @@ int hinic3_cmdq_async(void *hwdev, u8 mod, u8 cmd, struct hinic3_cmd_buf *buf_in
return cmdq_async_cmd(&cmdqs->cmdq[HINIC3_CMDQ_SYNC], mod,
cmd, buf_in, channel);
}
+EXPORT_SYMBOL(hinic3_cmdq_async);
int hinic3_cmdq_async_cos(void *hwdev, u8 mod, u8 cmd,
u8 cos_id, struct hinic3_cmd_buf *buf_in, u16 channel)
@@ -1320,6 +1321,7 @@ cmd_infos_err:
static void free_cmdq(struct hinic3_cmdq *cmdq)
{
kfree(cmdq->cmd_infos);
+ cmdq->cmd_infos = NULL;
spin_lock_deinit(&cmdq->cmdq_lock);
}
@@ -1530,7 +1532,7 @@ static int create_cmdq_wq(struct hinic3_cmdqs *cmdqs)
type = HINIC3_CMDQ_SYNC;
for (; type < cmdqs->cmdq_num; type++)
memcpy((u8 *)cmdqs->wq_block_vaddr +
- CMDQ_WQ_CLA_SIZE * type,
+ ((u64)type * CMDQ_WQ_CLA_SIZE),
cmdqs->cmdq[type].wq.wq_block_vaddr,
cmdqs->cmdq[type].wq.num_wq_pages * sizeof(u64));
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
index b9b884f..4f4639d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
@@ -15,11 +15,6 @@
#include "hinic3_common.h"
#include "hinic3_hwdev.h"
-struct dma_pool {
- unsigned int size;
- void *dev_hdl;
-};
-
#define HINIC3_SCMD_DATA_LEN 16
#define HINIC3_CMDQ_DEPTH 4096
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c
index c212bcc..d7e4985 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c
@@ -16,7 +16,6 @@
#include "ossl_knl.h"
#include "npu_cmdq_base_defs.h"
-#include "comm_defs.h"
#include "hinic3_crm.h"
#include "hinic3_hw.h"
#include "hinic3_hwdev.h"
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
index 5e0139a..0981d94 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
@@ -22,11 +22,15 @@
#include "hinic3_sriov.h"
#include "hinic3_nictool.h"
#include "hinic3_pci_id_tbl.h"
+#include "hinic3_hwdev.h"
+#include "cfg_mgmt_mpu_cmd_defs.h"
+#include "mpu_cmd_base_defs.h"
#include "hinic3_dev_mgmt.h"
#define HINIC3_WAIT_TOOL_CNT_TIMEOUT 10000
#define HINIC3_WAIT_TOOL_MIN_USLEEP_TIME 9900
#define HINIC3_WAIT_TOOL_MAX_USLEEP_TIME 10000
+#define HIGHT_BDF 8
static unsigned long card_bit_map;
@@ -60,14 +64,24 @@ void lld_dev_cnt_init(struct hinic3_pcidev *pci_adapter)
void lld_dev_hold(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_inc(&pci_adapter->ref_cnt);
}
void lld_dev_put(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_dec(&pci_adapter->ref_cnt);
}
@@ -236,6 +250,40 @@ void hinic3_get_all_chip_id(void *id_info)
card_id->num = (u32)i;
}
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+ u64 bar1_phy_addr = 0;
+ u64 bar3_phy_addr = 0;
+ u64 bar1_size = 0;
+ u64 bar3_size = 0;
+
+ lld_hold();
+
+ /* get PF bar1 or bar3 physical address to verify */
+ list_for_each_entry(chip_node, &g_hinic3_chip_list, node) {
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (hinic3_func_type(dev->hwdev) == TYPE_VF)
+ continue;
+
+ bar1_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+ bar1_size = pci_resource_len(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+
+ bar3_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ bar3_size = pci_resource_len(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ if ((phy_addr == bar1_phy_addr && vmsize <= bar1_size) ||
+ (phy_addr == bar3_phy_addr && vmsize <= bar3_size)) {
+ lld_put();
+ return 0;
+ }
+ }
+ }
+
+ lld_put();
+ return -EINVAL;
+}
+
void hinic3_get_card_func_info_by_card_name(const char *chip_name,
struct hinic3_card_func_info *card_func)
{
@@ -422,6 +470,29 @@ struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name
return NULL;
}
+void *hinic3_get_ppf_dev(void)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct list_head *chip_list = NULL;
+
+ lld_hold();
+ chip_list = get_hinic3_chip_list();
+
+ list_for_each_entry(chip_node, chip_list, node)
+ list_for_each_entry(pci_adapter, &chip_node->func_list, node)
+ if (hinic3_func_type(pci_adapter->hwdev) == TYPE_PPF) {
+ pr_info("Get ppf_func_id:%u",
+ hinic3_global_func_id(pci_adapter->hwdev));
+ lld_put();
+ return pci_adapter->lld_dev.hwdev;
+ }
+
+ lld_put();
+ return NULL;
+}
+EXPORT_SYMBOL(hinic3_get_ppf_dev);
+
struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
enum hinic3_service_type type)
{
@@ -518,6 +589,7 @@ EXPORT_SYMBOL(hinic3_get_ppf_lld_dev_unsafe);
int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len)
{
struct hinic3_pcidev *pci_adapter = NULL;
+ int ret = 0;
if (!lld_dev || !chip_name || !max_len)
return -EINVAL;
@@ -527,12 +599,18 @@ int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 ma
return -EFAULT;
lld_hold();
- strscpy(chip_name, pci_adapter->chip_node->chip_name, max_len);
+ if (strscpy(chip_name, pci_adapter->chip_node->chip_name, max_len) < 0)
+ goto RELEASE;
chip_name[max_len - 1] = '\0';
lld_put();
return 0;
+
+RELEASE:
+ lld_put();
+
+ return ret;
}
EXPORT_SYMBOL(hinic3_get_chip_name);
@@ -541,6 +619,87 @@ struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev)
return lld_dev->hwdev;
}
+void hinic3_write_oshr_info(struct os_hot_replace_info *out_oshr_info,
+ struct hw_pf_info *info,
+ struct hinic3_board_info *board_info,
+ struct card_node *chip_node, u32 serivce_enable,
+ u32 func_info_idx)
+{
+ out_oshr_info->func_infos[func_info_idx].pf_idx = info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].backup_pf =
+ (((info->glb_func_idx) / (board_info->port_num)) %
+ HOT_REPLACE_PARTITION_NUM == 0) ?
+ ((info->glb_func_idx) + (board_info->port_num)) :
+ ((info->glb_func_idx) - (board_info->port_num));
+ out_oshr_info->func_infos[func_info_idx].partition =
+ ((info->glb_func_idx) / (board_info->port_num)) %
+ HOT_REPLACE_PARTITION_NUM;
+ out_oshr_info->func_infos[func_info_idx].port_id = info->port_id;
+ out_oshr_info->func_infos[func_info_idx].bdf =
+ (info->bus_num << HIGHT_BDF) + info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].bus_num = chip_node->bus_num;
+ out_oshr_info->func_infos[func_info_idx].valid = serivce_enable;
+ memcpy(out_oshr_info->func_infos[func_info_idx].card_name,
+ chip_node->chip_name, IFNAMSIZ);
+}
+
+void hinic3_get_os_hot_replace_info(void *oshr_info)
+{
+ struct os_hot_replace_info *out_oshr_info =
+ (struct os_hot_replace_info *)oshr_info;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dst_dev = NULL;
+ struct hinic3_board_info *board_info = NULL;
+ struct hw_pf_info *infos = NULL;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ struct hinic3_hwdev *hwdev = NULL;
+ u32 func_info_idx = 0, func_id = 0, func_num, serivce_enable = 0;
+ struct list_head *hinic3_chip_list = get_hinic3_chip_list();
+ int err;
+
+ lld_hold();
+ pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ pr_err("kzalloc pf_infos fail\n");
+ lld_put();
+ return;
+ }
+ list_for_each_entry(chip_node, hinic3_chip_list, node) {
+ list_for_each_entry(dst_dev, &chip_node->func_list, node) {
+ err = hinic3_get_hw_pf_infos(dst_dev->hwdev,
+ pf_infos,
+ HINIC3_CHANNEL_COMM);
+ if (err != 0) {
+ pr_err("get pf info failed\n");
+ break;
+ }
+ hwdev = (struct hinic3_hwdev *)dst_dev->hwdev;
+ serivce_enable = 0;
+ infos = pf_infos->infos;
+ board_info = &hwdev->board_info;
+ if (hwdev->hot_replace_mode == HOT_REPLACE_ENABLE)
+ serivce_enable = 1;
+ break;
+ }
+
+ func_num = pf_infos->num_pfs;
+ if (func_num <= 0) {
+ pr_err("get pf num failed\n");
+ break;
+ }
+
+ for (func_id = 0; func_id < func_num; func_id++) {
+ hinic3_write_oshr_info(out_oshr_info, &infos[func_id],
+ board_info, chip_node,
+ serivce_enable, func_info_idx);
+ func_info_idx++;
+ }
+ }
+ out_oshr_info->func_cnt = func_info_idx;
+ kfree(pf_infos);
+ lld_put();
+}
+
struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(lld_dev->pdev);
@@ -608,21 +767,24 @@ void hinic3_get_card_info(const void *hwdev, void *bufin)
if (hinic3_support_nic(fun_hwdev, NULL)) {
if (dev->uld_dev[SERVICE_T_NIC]) {
info->pf[i].pf_type |= (u32)BIT(SERVICE_T_NIC);
- get_dynamic_uld_dev_name(dev, SERVICE_T_NIC, info->pf[i].name);
+ get_dynamic_uld_dev_name(dev, SERVICE_T_NIC,
+ info->pf[i].name);
}
}
if (hinic3_support_ppa(fun_hwdev, NULL)) {
if (dev->uld_dev[SERVICE_T_PPA]) {
info->pf[i].pf_type |= (u32)BIT(SERVICE_T_PPA);
- get_dynamic_uld_dev_name(dev, SERVICE_T_PPA, info->pf[i].name);
+ get_dynamic_uld_dev_name(dev, SERVICE_T_PPA,
+ info->pf[i].name);
}
}
if (hinic3_func_for_mgmt(fun_hwdev))
strscpy(info->pf[i].name, "FOR_MGMT", IFNAMSIZ);
- if (dev->lld_dev.pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID)
+ if (dev->lld_dev.pdev->subsystem_device ==
+ BIFUR_RESOURCE_PF_SSID)
strscpy(info->pf[i].name, "bifur", IFNAMSIZ);
strscpy(info->pf[i].bus_info, pci_name(dev->pcidev),
@@ -721,6 +883,7 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
struct card_node *chip_node = NULL;
unsigned char i;
unsigned char bus_number = 0;
+ int err;
if (chip_node_is_exist(pci_adapter, &bus_number))
return 0;
@@ -746,7 +909,10 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
/* bus number */
chip_node->bus_num = bus_number;
- if (snprintf(chip_node->chip_name, IFNAMSIZ, "%s%u", HINIC3_CHIP_NAME, i) < 0) {
+ snprintf(chip_node->chip_name, IFNAMSIZ, "%s%u", HINIC3_CHIP_NAME, i);
+
+ err = sscanf(chip_node->chip_name, HINIC3_CHIP_NAME "%d", &chip_node->chip_id);
+ if (err <= 0) {
clear_bit(i, &card_bit_map);
kfree(chip_node);
return -EINVAL;
@@ -803,3 +969,36 @@ int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *
return 0;
}
+
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin)
+{
+ struct card_node *chip_node = NULL;
+ struct card_mbox_cnt_info *info = (struct card_mbox_cnt_info *)bufin;
+ struct hinic3_pcidev *dev = NULL;
+ struct hinic3_hwdev *func_hwdev = NULL;
+ u32 i = 0;
+
+ info->func_num = 0;
+ chip_node = hinic3_get_chip_node_by_hwdev(hwdev);
+ if (!chip_node)
+ return;
+
+ lld_hold();
+
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ func_hwdev = (struct hinic3_hwdev *)dev->hwdev;
+ strscpy(info->func_info[i].bus_info, pci_name(dev->pcidev),
+ sizeof(info->func_info[i].bus_info));
+
+ info->func_info[i].send_cnt = func_hwdev->mbox_send_cnt;
+ info->func_info[i].ack_cnt = func_hwdev->mbox_ack_cnt;
+ info->func_num++;
+ i = info->func_num;
+ if (i >= ARRAY_SIZE(info->func_info)) {
+ sdk_err(&dev->pcidev->dev, "chip_node->func_list bigger than pf_max + vf_max\n");
+ break;
+ }
+ }
+
+ lld_put();
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
index 5c7c7cd..9815082 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
@@ -22,8 +22,13 @@
#define BIFUR_RESOURCE_PF_SSID 0x05a1
-#define HINIC3_IS_VF_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_VF)
-#define HINIC3_IS_SPU_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_SPU)
+#define HINIC3_IS_VF_DEV(pdev) \
+ ((pdev)->device == HINIC3_DEV_ID_VF || \
+ (pdev)->device == HINIC3_DEV_SDI_5_1_ID_VF)
+#define HINIC3_IS_SPU_DEV(pdev) \
+ (((pdev)->device == HINIC3_DEV_ID_SPU) || \
+ ((pdev)->device == HINIC3_DEV_ID_SDI_5_0_PF) || \
+ (((pdev)->device == HINIC3_DEV_ID_DPU_PF)))
enum {
HINIC3_NOT_PROBE = 1,
@@ -79,6 +84,13 @@ struct hinic3_pcidev {
u16 probe_fault_level;
u16 rsvd2;
u64 rsvd4;
+
+ struct workqueue_struct *multi_host_mgmt_workq;
+ struct work_struct slave_nic_work;
+ struct work_struct slave_vroce_work;
+
+ struct workqueue_struct *migration_probe_workq;
+ struct delayed_work migration_probe_dwork;
};
struct hinic_chip_info {
@@ -104,4 +116,6 @@ void wait_lld_dev_unused(struct hinic3_pcidev *pci_adapter);
void *hinic3_get_hwdev_by_pcidev(struct pci_dev *pdev);
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
index 11561a0..59ff722 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
@@ -101,7 +101,8 @@ static bool check_image_device_type(struct hinic3_hwdev *hwdev, u32 device_type)
static void encapsulate_update_cmd(struct hinic3_cmd_update_firmware *msg,
struct firmware_section *section_info,
- int *remain_len, u32 *send_len, u32 *send_pos)
+ const int *remain_len, u32 *send_len,
+ u32 *send_pos)
{
memset(msg->data, 0, sizeof(msg->data));
msg->ctl_info.sf = (*remain_len == section_info->section_len) ? true : false;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
index 937d699..be7c82b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
@@ -26,6 +26,8 @@
#include "hinic3_prof_adap.h"
#include "hinic3_eqs.h"
+#include "vram_common.h"
+
#define HINIC3_EQS_WQ_NAME "hinic3_eqs"
#define AEQ_CTRL_0_INTR_IDX_SHIFT 0
@@ -66,7 +68,6 @@
#define HINIC3_TASK_PROCESS_EQE_LIMIT 1024
#define HINIC3_EQ_UPDATE_CI_STEP 64
-/*lint -e806*/
static uint g_aeq_len = HINIC3_DEFAULT_AEQ_LEN;
module_param(g_aeq_len, uint, 0444);
MODULE_PARM_DESC(g_aeq_len,
@@ -83,7 +84,6 @@ static uint g_num_ceqe_in_tasklet = HINIC3_TASK_PROCESS_EQE_LIMIT;
module_param(g_num_ceqe_in_tasklet, uint, 0444);
MODULE_PARM_DESC(g_num_ceqe_in_tasklet,
"The max number of ceqe can be processed in tasklet, default = 1024");
-/*lint +e806*/
#define CEQ_CTRL_0_INTR_IDX_SHIFT 0
#define CEQ_CTRL_0_DMA_ATTR_SHIFT 12
@@ -819,18 +819,22 @@ static int alloc_eq_pages(struct hinic3_eq *eq)
u32 reg, init_val;
u16 pg_idx, i;
int err;
+ gfp_t gfp_vram;
eq->eq_pages = kcalloc(eq->num_pages, sizeof(*eq->eq_pages),
GFP_KERNEL);
if (!eq->eq_pages)
return -ENOMEM;
+ gfp_vram = hi_vram_get_gfp_vram();
+
for (pg_idx = 0; pg_idx < eq->num_pages; pg_idx++) {
eq_page = &eq->eq_pages[pg_idx];
err = hinic3_dma_zalloc_coherent_align(eq->hwdev->dev_hdl,
eq->page_size,
HINIC3_MIN_EQ_PAGE_SIZE,
- GFP_KERNEL, eq_page);
+ GFP_KERNEL | gfp_vram,
+ eq_page);
if (err) {
sdk_err(eq->hwdev->dev_hdl, "Failed to alloc eq page, page index: %u\n",
pg_idx);
@@ -881,6 +885,7 @@ static void free_eq_pages(struct hinic3_eq *eq)
&eq->eq_pages[pg_idx]);
kfree(eq->eq_pages);
+ eq->eq_pages = NULL;
}
static inline u32 get_page_size(const struct hinic3_eq *eq)
@@ -1120,7 +1125,8 @@ int hinic3_aeqs_init(struct hinic3_hwdev *hwdev, u16 num_aeqs,
hwdev->aeqs = aeqs;
aeqs->hwdev = hwdev;
aeqs->num_aeqs = num_aeqs;
- aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME, WQ_MEM_RECLAIM,
+ aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME,
+ WQ_MEM_RECLAIM | WQ_HIGHPRI,
HINIC3_MAX_AEQS);
if (!aeqs->workq) {
sdk_err(hwdev->dev_hdl, "Failed to initialize aeq workqueue\n");
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
index a4cbac8..6b96b87 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
@@ -82,6 +82,48 @@ int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id,
return 0;
}
+/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read and clear to zero
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
+ u16 *value)
+{
+ struct chipif_sml_ctr_rd_req req;
+ union ctr_rd_rsp rsp;
+ int ret;
+
+ if (!hwdev || !value)
+ return -EFAULT;
+
+ if (!COMM_SUPPORT_API_CHAIN((struct hinic3_hwdev *)hwdev))
+ return -EPERM;
+
+ memset(&req, 0, sizeof(req));
+
+ hinic3_sml_ctr_read_build_req(&req, instance,
+ CHIPIF_SM_CTR_OP_READ_CLEAR,
+ CHIPIF_ACK, ctr_id, 0);
+
+ ret = hinic3_api_cmd_read_ack(hwdev, node, (u8 *)&req,
+ (unsigned short)sizeof(req),
+ (void *)&rsp,
+ (unsigned short)sizeof(rsp));
+ if (ret) {
+ sdk_err(((struct hinic3_hwdev *)hwdev)->dev_hdl,
+ "Sm 16bit counter clear fail, err(%d)\n", ret);
+ return ret;
+ }
+ sml_ctr_htonl_n((u32 *)&rsp, sizeof(rsp) / sizeof(u32));
+ *value = rsp.bs_ss16_rsp.value1;
+
+ return 0;
+}
+
/**
* hinic3_sm_ctr_rd32 - small single 32 counter read
* @hwdev: the hardware device
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
index 030ef6d..41c439a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
@@ -34,13 +34,18 @@ static void parse_pub_res_cap_dfx(struct hinic3_hwdev *hwdev,
cap->max_vf);
sdk_info(hwdev->dev_hdl, "Host_pf_num: 0x%x, pf_id_start: 0x%x, host_vf_num: 0x%x, vf_id_start: 0x%x\n",
cap->pf_num, cap->pf_id_start, cap->vf_num, cap->vf_id_start);
- sdk_info(hwdev->dev_hdl, "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x\n",
- cap->host_valid_bitmap, cap->master_host_id, cap->srv_multi_host_mode);
sdk_info(hwdev->dev_hdl,
- "fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
- cap->fake_vf_start_id, cap->fake_vf_num, cap->fake_vf_max_pctx);
- sdk_info(hwdev->dev_hdl, "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x\n",
- cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len);
+ "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x, hot_plug_disable: 0x%x\n",
+ cap->host_valid_bitmap, cap->master_host_id,
+ cap->srv_multi_host_mode, cap->hot_plug_disable);
+ sdk_info(hwdev->dev_hdl,
+ "os_hot_replace: 0x%x, fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
+ cap->os_hot_replace, cap->fake_vf_start_id,
+ cap->fake_vf_num, cap->fake_vf_max_pctx);
+ sdk_info(hwdev->dev_hdl,
+ "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x, bond_create_mode: 0x%x\n",
+ cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len,
+ cap->bond_create_mode);
}
static void parse_cqm_res_cap(struct hinic3_hwdev *hwdev, struct service_cap *cap,
@@ -109,6 +114,9 @@ static void parse_pub_res_cap(struct hinic3_hwdev *hwdev,
cap->host_valid_bitmap = dev_cap->host_valid_bitmap;
cap->master_host_id = dev_cap->master_host_id;
cap->srv_multi_host_mode = dev_cap->srv_multi_host_mode;
+ cap->hot_plug_disable = dev_cap->hot_plug_disable;
+ cap->bond_create_mode = dev_cap->bond_create_mode;
+ cap->os_hot_replace = dev_cap->os_hot_replace;
cap->fake_vf_en = dev_cap->fake_vf_en;
cap->fake_vf_start_bit = dev_cap->fake_vf_start_bit;
cap->fake_vf_end_bit = dev_cap->fake_vf_end_bit;
@@ -148,18 +156,27 @@ static void parse_l2nic_res_cap(struct hinic3_hwdev *hwdev,
nic_cap->max_sqs = dev_cap->nic_max_sq_id + 1;
nic_cap->max_rqs = dev_cap->nic_max_rq_id + 1;
nic_cap->default_num_queues = dev_cap->nic_default_num_queues;
+ nic_cap->outband_vlan_cfg_en = dev_cap->outband_vlan_cfg_en;
+ nic_cap->lro_enable = dev_cap->lro_enable;
sdk_info(hwdev->dev_hdl, "L2nic resource capbility, max_sqs: 0x%x, max_rqs: 0x%x\n",
nic_cap->max_sqs, nic_cap->max_rqs);
/* Check parameters from firmware */
- if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP ||
- nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
- sdk_info(hwdev->dev_hdl, "Number of qp exceed limit[1-%d]: sq: %u, rq: %u\n",
- HINIC3_CFG_MAX_QP, nic_cap->max_sqs, nic_cap->max_rqs);
+ if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of sq exceed limit[1-%d]: sq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_sqs);
nic_cap->max_sqs = HINIC3_CFG_MAX_QP;
+ }
+
+ if (nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of rq exceed limit[1-%d]: rq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_rqs);
nic_cap->max_rqs = HINIC3_CFG_MAX_QP;
}
+
+ if (nic_cap->outband_vlan_cfg_en)
+ sdk_info(hwdev->dev_hdl, "L2nic outband vlan cfg enabled\n");
}
static void parse_fc_res_cap(struct hinic3_hwdev *hwdev,
@@ -333,6 +350,28 @@ static void parse_ipsec_res_cap(struct hinic3_hwdev *hwdev,
dev_cap->ipsec_max_sactx, dev_cap->ipsec_max_cq);
}
+static void parse_vbs_res_cap(struct hinic3_hwdev *hwdev,
+ struct service_cap *cap,
+ struct cfg_cmd_dev_cap *dev_cap,
+ enum func_type type)
+{
+ struct vbs_service_cap *vbs_cap = &cap->vbs_cap;
+
+ vbs_cap->vbs_max_volq = dev_cap->vbs_max_volq;
+ vbs_cap->vbs_main_pf_enable = dev_cap->vbs_main_pf_enable;
+ vbs_cap->vbs_vsock_pf_enable = dev_cap->vbs_vsock_pf_enable;
+ vbs_cap->vbs_fushion_queue_pf_enable = dev_cap->vbs_fushion_queue_pf_enable;
+
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS resource capbility, vbs_max_volq: 0x%x\n",
+ dev_cap->vbs_max_volq);
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS pf info, vbs_main_pf_enable: 0x%x, vbs_vsock_pf_enable: 0x%x, vbs_fushion_queue_pf_enable: 0x%x\n",
+ dev_cap->vbs_main_pf_enable,
+ dev_cap->vbs_vsock_pf_enable,
+ dev_cap->vbs_fushion_queue_pf_enable);
+}
+
static void parse_dev_cap(struct hinic3_hwdev *dev,
struct cfg_cmd_dev_cap *dev_cap, enum func_type type)
{
@@ -375,6 +414,9 @@ static void parse_dev_cap(struct hinic3_hwdev *dev,
if (IS_PPA_TYPE(dev))
parse_ppa_res_cap(dev, cap, dev_cap, type);
+
+ if (IS_VBS_TYPE(dev))
+ parse_vbs_res_cap(dev, cap, dev_cap, type);
}
static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
@@ -404,6 +446,23 @@ static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
return 0;
}
+u8 hinic3_get_bond_create_mode(void *dev)
+{
+ struct hinic3_hwdev *hwdev = NULL;
+ struct service_cap *cap = NULL;
+
+ if (!dev) {
+ pr_err("pointer dev is NULL\n");
+ return -EINVAL;
+ }
+
+ hwdev = (struct hinic3_hwdev *)dev;
+ cap = &hwdev->cfg_mgmt->svc_cap;
+
+ return cap->bond_create_mode;
+}
+EXPORT_SYMBOL(hinic3_get_bond_create_mode);
+
int hinic3_get_dev_cap(void *dev)
{
enum func_type type;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
index 671eed6..2f2310a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
@@ -166,6 +166,11 @@ struct service_cap {
u8 srv_multi_host_mode;
u16 virtio_vq_size;
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 os_hot_replace;
+ u8 rsvd1;
+
u8 timer_pf_num;
u8 timer_pf_id_start;
u16 timer_vf_num;
@@ -335,5 +340,7 @@ void free_capability(struct hinic3_hwdev *dev);
int hinic3_init_vf_dev_cap(void *hwdev);
+u8 hinic3_get_bond_create_mode(void *dev);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
index 8a87d25..8659e0b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
@@ -21,6 +21,7 @@
#include "hinic3_hw_cfg.h"
#include "hinic3_cmdq.h"
#include "mpu_inband_cmd_defs.h"
+#include "vram_common.h"
#include "hinic3_hw_comm.h"
#define HINIC3_MSIX_CNT_LLI_TIMER_SHIFT 0
@@ -242,12 +243,19 @@ int hinic3_func_reset(void *dev, u16 func_id, u64 reset_flag, u16 channel)
struct hinic3_hwdev *hwdev = dev;
u16 out_size = sizeof(func_reset);
int err = 0;
+ int is_in_kexec;
if (!dev) {
pr_err("Invalid para: dev is null.\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ sdk_info(hwdev->dev_hdl, "Skip function reset!\n");
+ return 0;
+ }
+
sdk_info(hwdev->dev_hdl, "Function is reset, flag: 0x%llx, channel:0x%x\n",
reset_flag, channel);
@@ -554,7 +562,7 @@ EXPORT_SYMBOL(hinic3_set_ppf_flr_type);
int hinic3_set_ppf_tbl_hotreplace_flag(void *hwdev, u8 flag)
{
- struct comm_cmd_ppf_tbl_htrp_config htr_info = {0};
+ struct comm_cmd_ppf_tbl_htrp_config htr_info = {};
u16 out_size = sizeof(struct comm_cmd_ppf_tbl_htrp_config);
struct hinic3_hwdev *dev = hwdev;
int ret;
@@ -899,11 +907,19 @@ static int set_ppf_tmr_status(struct hinic3_hwdev *hwdev,
int hinic3_ppf_tmr_start(void *hwdev)
{
+ int is_in_kexec;
+
if (!hwdev) {
pr_err("Hwdev pointer is NULL for starting ppf timer\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ pr_info("Skip starting ppt timer during kexec");
+ return 0;
+ }
+
return set_ppf_tmr_status(hwdev, HINIC_PPF_TMR_FLAG_START);
}
EXPORT_SYMBOL(hinic3_ppf_tmr_start);
@@ -919,18 +935,114 @@ int hinic3_ppf_tmr_stop(void *hwdev)
}
EXPORT_SYMBOL(hinic3_ppf_tmr_stop);
+static int hi_vram_kalloc_align(struct hinic3_hwdev *hwdev, char *name,
+ u32 page_size, u32 page_num,
+ struct hinic3_dma_addr_align *mem_align)
+{
+ void *vaddr = NULL, *align_vaddr = NULL;
+ dma_addr_t paddr, align_paddr;
+ u64 real_size = page_size;
+ u64 align = page_size;
+
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (!vaddr) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ /* align */
+ if (align_paddr == paddr) {
+ align_vaddr = vaddr;
+ goto out;
+ }
+
+ hi_vram_kfree((void *)vaddr, name, real_size);
+
+ /* realloc memory for align */
+ real_size = page_size + align;
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (!vaddr) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc align failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ align_vaddr = (void *)((u64)vaddr + (align_paddr - paddr));
+
+out:
+ mem_align->real_size = (u32)real_size;
+ mem_align->ori_vaddr = vaddr;
+ mem_align->ori_paddr = paddr;
+ mem_align->align_vaddr = align_vaddr;
+ mem_align->align_paddr = align_paddr;
+
+ return 0;
+}
+
+static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
+{
+ u32 i;
+ struct hinic3_dma_addr_align *page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = hwdev->mqm_eqm_vram_name;
+
+ page_addr = hwdev->mqm_att.brm_srch_page_addr;
+
+ for (i = 0; i < hwdev->mqm_att.page_num; i++) {
+ if (is_use_vram != 0) {
+ hi_vram_kfree(page_addr->ori_vaddr,
+ mqm_eqm_vram_name[i].vram_name,
+ page_addr->real_size);
+ } else {
+ hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
+ }
+ page_addr->ori_vaddr = NULL;
+ page_addr++;
+ }
+
+ kfree(mqm_eqm_vram_name);
+ hwdev->mqm_eqm_vram_name = NULL;
+}
+
static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
u32 page_num)
{
struct hinic3_dma_addr_align *page_addr = hwdev->mqm_att.brm_srch_page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = NULL;
u32 valid_num = 0;
u32 flag = 1;
u32 i = 0;
int err;
+ u16 func_id;
+
+ mqm_eqm_vram_name = kcalloc(page_num, sizeof(struct mqm_eqm_vram_name_s), GFP_KERNEL);
+ if (!mqm_eqm_vram_name)
+ return -ENOMEM;
+
+ hwdev->mqm_eqm_vram_name = mqm_eqm_vram_name;
+ func_id = hinic3_global_func_id(hwdev);
for (i = 0; i < page_num; i++) {
- err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl, page_size,
- page_size, GFP_KERNEL, page_addr);
+ if (is_use_vram != 0) {
+ snprintf(mqm_eqm_vram_name[i].vram_name,
+ VRAM_NAME_MAX_LEN, "%s%hu%s%u",
+ VRAM_CQM_GLB_FUNC_BASE, func_id,
+ VRAM_NIC_MQM, i);
+ err = hi_vram_kalloc_align(hwdev,
+ mqm_eqm_vram_name[i].vram_name,
+ page_size, page_num,
+ page_addr);
+ } else {
+ err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl,
+ page_size,
+ page_size,
+ GFP_KERNEL,
+ page_addr);
+ }
if (err) {
flag = 0;
break;
@@ -939,15 +1051,12 @@ static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
page_addr++;
}
+ hwdev->mqm_att.page_num = valid_num;
+
if (flag == 1) {
hwdev->mqm_att.page_size = page_size;
- hwdev->mqm_att.page_num = page_num;
} else {
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
- for (i = 0; i < valid_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
+ mqm_eqm_free_page_mem(hwdev);
return -EFAULT;
}
@@ -986,19 +1095,6 @@ static int mqm_eqm_alloc_page_mem(struct hinic3_hwdev *hwdev)
return ret;
}
-static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
-{
- u32 i;
- struct hinic3_dma_addr_align *page_addr;
-
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
-
- for (i = 0; i < hwdev->mqm_att.page_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
-}
-
static int mqm_eqm_set_cfg_2_hw(struct hinic3_hwdev *hwdev, u8 valid)
{
struct comm_cmd_eqm_cfg info_eqm_cfg;
@@ -1129,6 +1225,7 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
{
struct comm_cmd_get_eqm_num info_eqm_fix;
int ret;
+ int is_in_kexec;
if (hwdev->hwif->attr.func_type != TYPE_PPF)
return 0;
@@ -1158,10 +1255,16 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
goto err_page;
}
- ret = mqm_eqm_set_page_2_hw(hwdev);
- if (ret) {
- sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
- goto err_ecmd;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ ret = mqm_eqm_set_page_2_hw(hwdev);
+ if (ret) {
+ sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
+ goto err_ecmd;
+ }
+ } else {
+ sdk_info(hwdev->dev_hdl,
+ "Mqm db don't set to chip when os hot replace.\r\n");
}
ret = mqm_eqm_set_cfg_2_hw(hwdev, 1);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
index e8aa7ef..722fecd 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
@@ -252,97 +252,6 @@ static u32 get_up_timeout_val(enum hinic3_mod_type mod, u16 cmd)
return 0; /* use default mbox/apichain timeout time */
}
-static int api_csr_read(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
-{
- struct up_log_msg_st *up_log_msg = (struct up_log_msg_st *)buf_in;
- u8 *buf_out_tmp = (u8 *)buf_out;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
-
- if (!buf_in || !buf_out || in_size != sizeof(*up_log_msg) ||
- *out_size != up_log_msg->rd_len || up_log_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = up_log_msg->rd_len;
- rd_addr = up_log_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_rd32(hwdev, node_id,
- rd_addr + offset,
- (u32 *)(buf_out_tmp + offset));
- if (ret) {
- pr_err("Csr rd fail, err: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, node_id, rd_addr + offset);
- return ret;
- }
- offset += DW_WIDTH;
- }
- *out_size = rd_len;
-
- return ret;
-}
-
-static int api_csr_write(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out,
- u32 *out_size)
-{
- struct csr_write_st *csr_write_msg = (struct csr_write_st *)buf_in;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
- u8 *data = NULL;
-
- if (!buf_in || in_size != sizeof(*csr_write_msg) || csr_write_msg->rd_len == 0 ||
- csr_write_msg->rd_len > API_CSR_MAX_RD_LEN || csr_write_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = csr_write_msg->rd_len;
- rd_addr = csr_write_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- data = kzalloc(rd_len, GFP_KERNEL);
- if (!data)
- return -EFAULT;
-
- if (copy_from_user(data, (void *)csr_write_msg->data, rd_len)) {
- pr_err("Copy information from user failed\n");
- kfree(data);
- return -EFAULT;
- }
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_wr32(hwdev, node_id,
- rd_addr + offset,
- *((u32 *)(data + offset)));
- if (ret) {
- pr_err("Csr wr fail, ret: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, rd_addr + offset, node_id);
- kfree(data);
- return ret;
- }
- offset += DW_WIDTH;
- }
-
- *out_size = 0;
- kfree(data);
- return ret;
-}
-
int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
@@ -369,10 +278,8 @@ int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
return ret;
}
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_BYPASS) {
- if (nt_msg->mpu_cmd.cmd == API_CSR_WRITE)
- return api_csr_write(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
-
- ret = api_csr_read(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
+ pr_err("Unsupported api_type %u\n", nt_msg->mpu_cmd.api_type);
+ return -EINVAL;
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_TO_MPU) {
timeout = get_up_timeout_val(mod, cmd);
if (hinic3_pcie_itf_id(hwdev) != SPU_HOST_ID)
@@ -439,6 +346,23 @@ static int sm_rd16(void *hwdev, u32 id, u8 instance,
return ret;
}
+static int sm_rd16_clear(void *hwdev, u32 id, u8 instance,
+ u8 node, struct sm_out_st *buf_out)
+{
+ u16 val1;
+ int ret;
+
+ ret = hinic3_sm_ctr_rd16_clear(hwdev, node, instance, id, &val1);
+ if (ret != 0) {
+ pr_err("Get sm ctr clear information (16 bits)failed!\n");
+ val1 = 0xffff;
+ }
+
+ buf_out->val1 = val1;
+
+ return ret;
+}
+
static int sm_rd32(void *hwdev, u32 id, u8 instance,
u8 node, struct sm_out_st *buf_out)
{
@@ -558,6 +482,7 @@ const struct sm_module_handle sm_module_cmd_handle[] = {
{SM_CTR_RD32, sm_rd32},
{SM_CTR_RD64_PAIR, sm_rd64_pair},
{SM_CTR_RD64, sm_rd64},
+ {SM_CTR_RD16_CLEAR, sm_rd16_clear},
{SM_CTR_RD32_CLEAR, sm_rd32_clear},
{SM_CTR_RD64_PAIR_CLEAR, sm_rd64_pair_clear},
{SM_CTR_RD64_CLEAR, sm_rd64_clear}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
index 83e7b63..c317f4a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
@@ -101,6 +101,12 @@ enum hinic3_pcie_tph {
#define SLAVE_HOST_STATUS_SET(host_id, enable) (((u8)(enable) & 1U) << (host_id))
#define SLAVE_HOST_STATUS_GET(host_id, val) (!!((val) & (1U << (host_id))))
+#ifdef HAVE_HOT_REPLACE_FUNC
+ extern int get_partition_id(void);
+#else
+ static int get_partition_id(void) {return 0; }
+#endif
+
void set_slave_host_enable(void *hwdev, u8 host_id, bool enable)
{
u32 reg_val;
@@ -207,6 +213,27 @@ static void hinic3_init_host_mode_pre(struct hinic3_hwdev *hwdev)
}
}
+static void hinic3_init_hot_plug_status(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->hot_plug_disable)
+ hwdev->hot_plug_mode = HOT_PLUG_DISABLE;
+ else
+ hwdev->hot_plug_mode = HOT_PLUG_ENABLE;
+}
+
+static void hinic3_init_os_hot_replace(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->os_hot_replace) {
+ hwdev->hot_replace_mode = HOT_REPLACE_ENABLE;
+ } else {
+ hwdev->hot_replace_mode = HOT_REPLACE_DISABLE;
+ }
+}
+
static u8 hinic3_nic_sw_aeqe_handler(void *hwdev, u8 event, u8 *data)
{
struct hinic3_hwdev *dev = hwdev;
@@ -270,14 +297,20 @@ static void chip_fault_show(struct hinic3_hwdev *hwdev,
"fatal", "reset", "host", "flr", "general", "suggestion"};
char level_str[FAULT_SHOW_STR_LEN + 1];
u8 level;
+ int ret;
memset(level_str, 0, FAULT_SHOW_STR_LEN + 1);
level = event->event.chip.err_level;
- if (level < FAULT_LEVEL_MAX)
- strscpy(level_str, fault_level[level],
- FAULT_SHOW_STR_LEN);
- else
- strscpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (level < FAULT_LEVEL_MAX) {
+ ret = strscpy(level_str, fault_level[level],
+ FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ } else {
+ ret = strscpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ }
if (level == FAULT_LEVEL_SERIOUS_FLR)
dev_err(hwdev->dev_hdl, "err_level: %u [%s], flr func_id: %u\n",
@@ -299,6 +332,7 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
"reg rd timeout", "reg wr timeout", "phy fault", "tsensor fault"};
char type_str[FAULT_SHOW_STR_LEN + 1] = {0};
struct fault_event_stats *fault = NULL;
+ int ret;
sdk_err(hwdev->dev_hdl, "Fault event report received, func_id: %u\n",
hinic3_global_func_id(hwdev));
@@ -306,10 +340,14 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
fault = &hwdev->hw_stats.fault_event_stats;
if (event->type < FAULT_TYPE_MAX) {
- strscpy(type_str, fault_type[event->type], sizeof(type_str));
+ ret = strscpy(type_str, fault_type[event->type], sizeof(type_str));
+ if (ret < 0)
+ return;
atomic_inc(&fault->fault_type_stat[event->type]);
} else {
- strscpy(type_str, "Unknown", sizeof(type_str));
+ ret = strscpy(type_str, "Unknown", sizeof(type_str));
+ if (ret < 0)
+ return;
}
sdk_err(hwdev->dev_hdl, "Fault type: %u [%s]\n", event->type, type_str);
@@ -1536,15 +1574,29 @@ int hinic3_init_hwdev(struct hinic3_init_para *para)
hinic3_init_host_mode_pre(hwdev);
+ hinic3_init_hot_plug_status(hwdev);
+
+ hinic3_init_os_hot_replace(hwdev);
+
err = hinic3_multi_host_mgmt_init(hwdev);
if (err != 0) {
sdk_err(hwdev->dev_hdl, "Failed to init function mode\n");
goto init_multi_host_fail;
}
- err = hinic3_init_ppf_work(hwdev);
- if (err != 0)
- goto init_ppf_work_fail;
+ // hot_replace_mode is enable, run ppf function only when partition_id is 0
+ // or run ppf function directly
+ if (hwdev->hot_replace_mode == HOT_REPLACE_ENABLE) {
+ if (get_partition_id() == 0) {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0)
+ goto init_ppf_work_fail;
+ }
+ } else {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0)
+ goto init_ppf_work_fail;
+ }
err = hinic3_set_comm_features(hwdev, hwdev->features, COMM_MAX_FEATURE_QWORD);
if (err != 0) {
@@ -1948,6 +2000,19 @@ void hinic3_link_event_stats(void *dev, u8 link)
}
EXPORT_SYMBOL(hinic3_link_event_stats);
+int hinic3_get_link_event_stats(void *dev, int *link_state)
+{
+ struct hinic3_hwdev *hwdev = dev;
+
+ if (!hwdev || !link_state)
+ return -EINVAL;
+
+ *link_state = hwdev->hw_stats.link_event_stats.link_down_stats.counter;
+
+ return 0;
+}
+EXPORT_SYMBOL(hinic3_get_link_event_stats);
+
u8 hinic3_max_pf_num(void *hwdev)
{
if (!hwdev)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
index b8a3356..0ca639f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
@@ -10,6 +10,7 @@
#include "hinic3_hw.h"
#include "mpu_inband_cmd_defs.h"
#include "hinic3_profile.h"
+#include "vram_common.h"
struct cfg_mgmt_info;
@@ -82,6 +83,22 @@ enum hinic3_host_mode_e {
HINIC3_SDI_MODE_MAX,
};
+enum hinic3_hot_plug_mode {
+ HOT_PLUG_ENABLE,
+ HOT_PLUG_DISABLE,
+};
+
+enum hinic3_os_hot_replace_mode {
+ HOT_REPLACE_DISABLE,
+ HOT_REPLACE_ENABLE,
+};
+
+#define UNSUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_DISABLE)
+
+#define SUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_ENABLE)
+
#define MULTI_HOST_CHIP_MODE_SHIFT 0
#define MULTI_HOST_MASTER_MBX_STS_SHIFT 17
#define MULTI_HOST_PRIV_DATA_SHIFT 0x8
@@ -100,6 +117,10 @@ enum hinic3_host_mode_e {
((val) & (~(MULTI_HOST_##member##_MASK \
<< MULTI_HOST_##member##_SHIFT)))
+struct mqm_eqm_vram_name_s {
+ char vram_name[VRAM_NAME_MAX_LEN];
+};
+
struct hinic3_hwdev {
void *adapter_hdl; /* pointer to hinic3_pcidev or NDIS_Adapter */
void *pcidev_hdl; /* pointer to pcidev or Handler */
@@ -138,6 +159,9 @@ struct hinic3_hwdev {
u32 rsvd2;
struct hinic3_multi_host_mgmt *mhost_mgmt;
+ char mhost_mgmt_name[VRAM_NAME_MAX_LEN];
+
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name;
struct mutex stateful_mutex; /* protect cqm init and deinit */
@@ -170,6 +194,8 @@ struct hinic3_hwdev {
struct hinic3_devlink *devlink_dev;
enum hinic3_func_mode func_mode;
+ enum hinic3_hot_plug_mode hot_plug_mode;
+ enum hinic3_os_hot_replace_mode hot_replace_mode;
u32 rsvd3;
DECLARE_BITMAP(func_probe_in_host, MAX_FUNCTION_NUM);
@@ -179,7 +205,10 @@ struct hinic3_hwdev {
u64 last_recv_aeq_cnt;
u16 aeq_busy_cnt;
- u64 rsvd4[8];
+ u64 mbox_send_cnt;
+ u64 mbox_ack_cnt;
+
+ u64 rsvd4[5];
u8 cmdq_mode;
};
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
index 33f1210..8590f70 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
@@ -544,6 +544,7 @@ static void free_db_area(struct hinic3_free_db_area *free_db_area)
{
spin_lock_deinit(&free_db_area->idx_lock);
kfree(free_db_area->db_bitmap_array);
+ free_db_area->db_bitmap_array = NULL;
}
static int get_db_idx(struct hinic3_hwif *hwif, u32 *idx)
@@ -841,6 +842,7 @@ void hinic3_free_hwif(struct hinic3_hwdev *hwdev)
free_db_area(&hwdev->hwif->free_db_area);
enable_all_msix(hwdev);
kfree(hwdev->hwif);
+ hwdev->hwif = NULL;
}
u16 hinic3_global_func_id(void *hwdev)
@@ -856,6 +858,44 @@ u16 hinic3_global_func_id(void *hwdev)
}
EXPORT_SYMBOL(hinic3_global_func_id);
+/**
+ * get function id from register,used by sriov hot migration process
+ * @hwdev: the pointer to hw device
+ */
+u16 hinic3_global_func_id_hw(void *hwdev)
+{
+ u32 addr, attr0;
+ struct hinic3_hwdev *dev;
+
+ dev = (struct hinic3_hwdev *)hwdev;
+ addr = HINIC3_CSR_FUNC_ATTR0_ADDR;
+ attr0 = hinic3_hwif_read_reg(dev->hwif, addr);
+
+ return HINIC3_AF0_GET(attr0, FUNC_GLOBAL_IDX);
+}
+
+/**
+ * get function id, used by sriov hot migratition process.
+ * @hwdev: the pointer to hw device
+ * @func_id: function id
+ */
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id)
+{
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)hwdev;
+
+ if (!hwdev || !func_id)
+ return -EINVAL;
+
+ /* only vf get func_id from chip reg for sriov migrate */
+ if (!HINIC3_IS_VF(dev)) {
+ *func_id = hinic3_global_func_id(hwdev);
+ return 0;
+ }
+
+ *func_id = hinic3_global_func_id_hw(dev);
+ return 0;
+}
+
u16 hinic3_intr_num(void *hwdev)
{
struct hinic3_hwif *hwif = NULL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
index 6ab1b92..0b02176 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
@@ -16,6 +16,7 @@
#include <linux/rtc.h>
#include <linux/aer.h>
#include <linux/debugfs.h>
+#include <linux/notifier.h>
#include "ossl_knl.h"
#include "hinic3_mt.h"
@@ -26,13 +27,38 @@
#include "hinic3_dev_mgmt.h"
#include "hinic3_nictool.h"
#include "hinic3_hw.h"
+#include "hinic3_multi_host_mgmt.h"
+#include "hinic3_hw_cfg.h"
#include "hinic3_lld.h"
#include "hinic3_profile.h"
#include "hinic3_hwdev.h"
#include "hinic3_prof_adap.h"
-#include "comm_msg_intf.h"
+#include "hinic3_devlink.h"
+#include "vram_common.h"
+
+enum partition_dev_type {
+ PARTITION_DEV_NONE = 0,
+ PARTITION_DEV_SHARED,
+ PARTITION_DEV_EXCLUSIVE,
+ PARTITION_DEV_BACKUP,
+};
+
+#ifdef HAVE_HOT_REPLACE_FUNC
+static int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type,
+ unsigned int partition_id);
+static int get_partition_id(void);
+#else
+static int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type,
+ unsigned int partition_id)
+{
+ return 0;
+}
+static int get_partition_id(void) { return 0; }
+#endif
+
+static bool g_is_pf_migrated;
static bool disable_vf_load;
module_param(disable_vf_load, bool, 0444);
MODULE_PARM_DESC(disable_vf_load,
@@ -44,10 +70,12 @@ MODULE_PARM_DESC(disable_attach, "disable_attach or not - default is false");
#define HINIC3_WAIT_SRIOV_CFG_TIMEOUT 15000
-MODULE_AUTHOR("Huawei Technologies CO., Ltd");
-MODULE_DESCRIPTION(HINIC3_DRV_DESC);
-MODULE_VERSION(HINIC3_DRV_VERSION);
-MODULE_LICENSE("GPL");
+#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
+static DEVICE_ATTR_RW(sriov_numvfs, 0644,
+ sriov_numvfs_show, sriov_numvfs_store);
+static DEVICE_ATTR_RO(sriov_totalvfs, 0444,
+ sriov_totalvfs_show, NULL);
+#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
static struct attribute *hinic3_attributes[] = {
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
@@ -64,7 +92,18 @@ static const struct attribute_group hinic3_attr_group = {
struct hinic3_uld_info g_uld_info[SERVICE_T_MAX] = { {0} };
#define HINIC3_EVENT_PROCESS_TIMEOUT 10000
+#define HINIC3_WAIT_EVENT_PROCESS_TIMEOUT 100
struct mutex g_uld_mutex; /* g_uld_info lock */
+#define BUS_MAX_DEV_NUM 256
+#define HINIC3_SLAVE_WORK_MAX_NUM 20
+
+struct vf_offset_info {
+ u8 valid;
+ u16 vf_offset_from_pf[CMD_MAX_MAX_PF_NUM];
+};
+
+static struct vf_offset_info g_vf_offset;
+DEFINE_MUTEX(g_vf_offset_lock);
void hinic3_uld_lock_init(void)
{
@@ -73,13 +112,23 @@ void hinic3_uld_lock_init(void)
static const char *s_uld_name[SERVICE_T_MAX] = {
"nic", "ovs", "roce", "toe", "ioe",
- "fc", "vbs", "ipsec", "virtio", "migrate", "ppa", "bifur", "custom"};
+ "fc", "vbs", "ipsec", "virtio", "migrate",
+ "ppa", "custom", "vroce", "crypt", "vsock", "bifur"};
const char **hinic3_get_uld_names(void)
{
return s_uld_name;
}
+#ifdef CONFIG_PCI_IOV
+static int hinic3_get_pf_device_id(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_dev = pci_physfn(pdev);
+
+ return pf_dev->device;
+}
+#endif
+
static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
const struct hinic3_uld_info *uld_info)
{
@@ -98,6 +147,10 @@ static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
atomic_set(&dev->uld_ref_cnt[type], 0);
+ if (!uld_info->probe) {
+ err = 0;
+ goto out_unlock;
+ }
err = uld_info->probe(&dev->lld_dev, &uld_dev, dev->uld_dev_name[type]);
if (err) {
sdk_err(&dev->pcidev->dev,
@@ -166,6 +219,10 @@ static void detach_uld(struct hinic3_pcidev *dev,
wait_uld_unused(dev, type);
+ if (!uld_info->remove) {
+ mutex_unlock(&dev->pdev_mutex);
+ return;
+ }
uld_info->remove(&dev->lld_dev, dev->uld_dev[type]);
dev->uld_dev[type] = NULL;
@@ -182,11 +239,14 @@ static void attach_ulds(struct hinic3_pcidev *dev)
{
enum hinic3_service_type type;
struct pci_dev *pdev = dev->pcidev;
+ int is_in_kexec = vram_get_kexec_flag();
+
+ if (is_in_kexec == 0)
+ lld_hold();
- lld_hold();
mutex_lock(&g_uld_mutex);
- for (type = SERVICE_T_NIC; type < SERVICE_T_MAX; type++) {
+ for (type = SERVICE_T_OVS; type < SERVICE_T_MAX; type++) {
if (g_uld_info[type].probe) {
if (pdev->is_virtfn &&
(!hinic3_get_vf_service_load(pdev, (u16)type))) {
@@ -198,7 +258,9 @@ static void attach_ulds(struct hinic3_pcidev *dev)
}
}
mutex_unlock(&g_uld_mutex);
- lld_put();
+
+ if (is_in_kexec == 0)
+ lld_put();
}
static void detach_ulds(struct hinic3_pcidev *dev)
@@ -305,7 +367,7 @@ void hinic3_unregister_uld(enum hinic3_service_type type)
}
uld_info = &g_uld_info[type];
- memset(uld_info, 0, sizeof(*uld_info));
+ memset(uld_info, 0, sizeof(struct hinic3_uld_info));
mutex_unlock(&g_uld_mutex);
lld_put();
}
@@ -359,6 +421,26 @@ void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_ser
}
EXPORT_SYMBOL(hinic3_detach_service);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ __module_get(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_get);
+
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ module_put(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_put);
+
static void hinic3_sync_time_to_fmw(struct hinic3_pcidev *pdev_pri)
{
struct timeval tv = {0};
@@ -441,23 +523,445 @@ static void send_event_to_all_pf(struct hinic3_pcidev *dev,
lld_put();
}
+u32 hinic3_pdev_is_virtfn(struct pci_dev *pdev)
+{
+#ifdef CONFIG_PCI_IOV
+ return pdev->is_virtfn;
+#else
+ return 0;
+#endif
+}
+
+static int hinic3_get_function_enable(struct pci_dev *pdev, bool *en)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+ int err;
+
+ /* PF in host os or function in guest os, probe sdk in default */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev) {
+ *en = true;
+ return 0;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev) {
+ /* vf in host and pf sdk not probed */
+ return -EFAULT;
+ }
+ pf_hwdev = pci_adapter->hwdev;
+
+ err = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (err) {
+ sdk_err(&pci_adapter->pcidev->dev,
+ "Func hinic3_get_vfid_by_vfpci fail %d\n", err);
+ return err;
+ }
+
+ err = hinic3_get_func_nic_enable(pf_hwdev, global_func_id, en);
+ if (!!err) {
+ sdk_info(&pdev->dev, "Failed to get function nic status, err %d.\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+int hinic3_set_func_probe_in_host(void *hwdev, u16 func_id, bool probe)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (hinic3_func_type(hwdev) != TYPE_PPF)
+ return -EINVAL;
+
+ if (probe)
+ set_bit(func_id, dev->func_probe_in_host);
+ else
+ clear_bit(func_id, dev->func_probe_in_host);
+
+ return 0;
+}
+
+bool hinic3_get_func_probe_in_host(void *hwdev, u16 func_id)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+ bool probed = false;
+
+ if (!hwdev)
+ return false;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return false;
+ }
+
+ probed = !!test_bit(func_id, ppf_dev->func_probe_in_host);
+ up(&dev->ppf_sem);
+
+ return probed;
+}
+
+void *hinic3_get_ppf_hwdev_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ chip_node = pci_adapter->chip_node;
+ lld_dev_hold(&pci_adapter->lld_dev);
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (dev->lld_state == HINIC3_IN_REMOVE)
+ continue;
+
+ if (dev->hwdev && hinic3_func_type(dev->hwdev) == TYPE_PPF) {
+ lld_dev_put(&pci_adapter->lld_dev);
+ return dev->hwdev;
+ }
+ }
+ lld_dev_put(&pci_adapter->lld_dev);
+
+ return NULL;
+}
+
+static int hinic3_set_vf_nic_used_state(void *hwdev, u16 func_id, bool opened)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+
+ if (!dev || func_id >= MAX_FUNCTION_NUM)
+ return -EINVAL;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return -EINVAL;
+ }
+
+ if (opened)
+ set_bit(func_id, ppf_dev->netdev_setup_state);
+ else
+ clear_bit(func_id, ppf_dev->netdev_setup_state);
+
+ up(&dev->ppf_sem);
+
+ return 0;
+}
+
+static void set_vf_func_in_use(struct pci_dev *pdev, bool in_use)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+
+ /* only need to be set when VF is on the host */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev)
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev)
+ return;
+
+ pf_hwdev = pci_adapter->hwdev;
+
+ global_func_id = (u16)pdev->devfn + hinic3_glb_pf_vf_offset(pf_hwdev);
+ (void)hinic3_set_vf_nic_used_state(pf_hwdev, global_func_id, in_use);
+}
+
+static int hinic3_pf_get_vf_offset_info(struct hinic3_pcidev *des_dev, u16 *vf_offset)
+{
+ int err, i;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ u16 pf_func_id;
+ struct hinic3_pcidev *pf_pci_adapter = NULL;
+
+ pf_pci_adapter = (hinic3_pdev_is_virtfn(des_dev->pcidev)) ?
+ pci_get_drvdata(des_dev->pcidev->physfn) : des_dev;
+ pf_func_id = hinic3_global_func_id(pf_pci_adapter->hwdev);
+ if (pf_func_id >= CMD_MAX_MAX_PF_NUM || !vf_offset)
+ return -EINVAL;
+
+ mutex_lock(&g_vf_offset_lock);
+ if (g_vf_offset.valid == 0) {
+ pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ err = -ENOMEM;
+ goto err_malloc;
+ }
+
+ err = hinic3_get_hw_pf_infos(pf_pci_adapter->hwdev,
+ pf_infos, HINIC3_CHANNEL_COMM);
+ if (err) {
+ sdk_warn(&pf_pci_adapter->pcidev->dev,
+ "Hinic3_get_hw_pf_infos fail err %d\n", err);
+ err = -EFAULT;
+ goto err_out;
+ }
+
+ g_vf_offset.valid = 1;
+ for (i = 0; i < CMD_MAX_MAX_PF_NUM; i++)
+ g_vf_offset.vf_offset_from_pf[i] = pf_infos->infos[i].vf_offset;
+
+ kfree(pf_infos);
+ }
+
+ *vf_offset = g_vf_offset.vf_offset_from_pf[pf_func_id];
+
+ mutex_unlock(&g_vf_offset_lock);
+
+ return 0;
+
+err_out:
+ kfree(pf_infos);
+err_malloc:
+ mutex_unlock(&g_vf_offset_lock);
+ return err;
+}
+
+static struct pci_dev *get_vf_pdev_by_pf(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ int err;
+ u16 bus_num;
+ u16 vf_start, vf_end;
+ u16 des_fn, pf_func_id, vf_offset;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ pf_func_id = hinic3_global_func_id(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end || pf_func_id >= CMD_MAX_MAX_PF_NUM)
+ return NULL;
+
+ err = hinic3_pf_get_vf_offset_info(des_dev, &vf_offset);
+ if (err) {
+ sdk_warn(&des_dev->pcidev->dev, "Hinic3_pf_get_vf_offset_info fail\n");
+ return NULL;
+ }
+
+ des_fn = ((func_id - vf_start) - 1) + pf_func_id + vf_offset;
+ bus_num = des_dev->pcidev->bus->number + des_fn / BUS_MAX_DEV_NUM;
+
+ return pci_get_domain_bus_and_slot(0, bus_num, (des_fn % BUS_MAX_DEV_NUM));
+}
+
+static struct hinic3_pcidev *get_des_pci_adapter(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ struct pci_dev *des_pdev = NULL;
+ u16 vf_start, vf_end;
+ bool probe_in_host = false;
+
+ if (hinic3_global_func_id(des_dev->hwdev) == func_id)
+ return des_dev;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end)
+ return NULL;
+
+ des_pdev = get_vf_pdev_by_pf(des_dev, func_id);
+ if (!des_pdev)
+ return NULL;
+
+ pci_dev_put(des_pdev);
+
+ probe_in_host = hinic3_get_func_probe_in_host(des_dev->hwdev, func_id);
+ if (!probe_in_host)
+ return NULL;
+
+ return pci_get_drvdata(des_pdev);
+}
+
+int __set_vroce_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ u8 enable_vroce = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_vroce_enable(pci_adapter->hwdev,
+ func_id, &enable_vroce);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Failed to get vroce state.\n");
+ return err;
+ }
+
+ mutex_lock(&g_uld_mutex);
+
+ if (!!enable_vroce) {
+ if (!g_uld_info[SERVICE_T_ROCE].probe) {
+ sdk_info(&pdev->dev, "Uld(roce_info) has not been registered!\n");
+ mutex_unlock(&g_uld_mutex);
+ return 0;
+ }
+
+ err = attach_uld(pci_adapter, SERVICE_T_ROCE,
+ &g_uld_info[SERVICE_T_ROCE]);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Failed to initialize VROCE.\n");
+ mutex_unlock(&g_uld_mutex);
+ return err;
+ }
+ } else {
+ sdk_info(&pdev->dev, "Func %u vroce state: disable.\n", func_id);
+ if (g_uld_info[SERVICE_T_ROCE].remove)
+ detach_uld(pci_adapter, SERVICE_T_ROCE);
+ }
+
+ mutex_unlock(&g_uld_mutex);
+
+ return 0;
+}
+
+void slave_host_mgmt_vroce_work(struct work_struct *work)
+{
+#ifndef __HIFC__
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_vroce_work);
+
+ __set_vroce_func_state(pci_adapter);
+#endif
+}
+
+void *hinic3_get_roce_uld_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ return pci_adapter->uld_dev[SERVICE_T_ROCE];
+}
+
+static int func_service_state_process(struct hinic3_pcidev *event_dev,
+ struct hinic3_pcidev *des_dev,
+ struct hinic3_mhost_nic_func_state *state,
+ u16 cmd)
+{
+ int err = 0;
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)event_dev->hwdev;
+
+ switch (cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ state->enable = hinic3_get_roce_uld_by_pdev(des_dev->pcidev) ? 1 : 0;
+ break;
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive nic[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ if (event_dev->multi_host_mgmt_workq) {
+ queue_work(event_dev->multi_host_mgmt_workq,
+ &des_dev->slave_nic_work);
+ } else {
+ sdk_err(&des_dev->pcidev->dev, "Can not schedule slave nic work\n");
+ err = -EFAULT;
+ }
+ break;
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive vroce[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ queue_work_on(hisdk3_get_work_cpu_affinity(dev, WORK_TYPE_MBOX),
+ event_dev->multi_host_mgmt_workq,
+ &des_dev->slave_vroce_work);
+ break;
+ default:
+ sdk_warn(&des_dev->pcidev->dev,
+ "Service state process with unknown cmd: %u\n", cmd);
+ err = -EFAULT;
+ break;
+ }
+
+ return err;
+}
+
+static void multi_host_mgmt(struct hinic3_pcidev *dev,
+ struct hinic3_multi_host_mgmt_event *mhost_mgmt)
+{
+ struct hinic3_pcidev *cur_dev = NULL;
+ struct hinic3_pcidev *des_dev = NULL;
+ struct hinic3_mhost_nic_func_state *nic_state = NULL;
+ u16 sub_cmd = mhost_mgmt->sub_cmd;
+
+ switch (sub_cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ nic_state = mhost_mgmt->data;
+ nic_state->status = 0;
+ if (!dev->hwdev)
+ return;
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)dev->hwdev))
+ return;
+
+ /* find func_idx pci_adapter and disable or enable nic */
+ lld_dev_hold(&dev->lld_dev);
+ list_for_each_entry(cur_dev, &dev->chip_node->func_list, node) {
+ if (cur_dev->lld_state == HINIC3_IN_REMOVE ||
+ hinic3_pdev_is_virtfn(cur_dev->pcidev))
+ continue;
+
+ des_dev = get_des_pci_adapter(cur_dev, nic_state->func_idx);
+ if (!des_dev)
+ continue;
+
+ if (func_service_state_process(dev, des_dev, nic_state, sub_cmd))
+ nic_state->status = 1;
+ break;
+ }
+ lld_dev_put(&dev->lld_dev);
+ break;
+ default:
+ sdk_warn(&dev->pcidev->dev, "Received unknown multi-host mgmt event: %u\n",
+ mhost_mgmt->sub_cmd);
+ break;
+ }
+}
+
static void hinic3_event_process(void *adapter, struct hinic3_event_info *event)
{
struct hinic3_pcidev *dev = adapter;
struct hinic3_fault_event *fault = (void *)event->event_data;
+ struct hinic3_multi_host_mgmt_event *mhost_event =
+ (void *)event->event_data;
u16 func_id;
- if ((event->service == EVENT_SRV_COMM && event->type == EVENT_COMM_FAULT) &&
- fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
- fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
- func_id = fault->event.chip.func_id;
- return send_event_to_dst_pf(adapter, func_id, event);
- }
-
- if (event->type == EVENT_COMM_MGMT_WATCHDOG)
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MULTI_HOST_MGMT):
+ multi_host_mgmt(dev, mhost_event);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_FAULT):
+ if (fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
+ fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
+ func_id = fault->event.chip.func_id;
+ return send_event_to_dst_pf(adapter, func_id, event);
+ }
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MGMT_WATCHDOG):
send_event_to_all_pf(adapter, event);
- else
+ break;
+ default:
send_uld_dev_event(adapter, event);
+ break;
+ }
}
static void uld_def_init(struct hinic3_pcidev *pci_adapter)
@@ -605,31 +1109,70 @@ static void hinic3_pci_deinit(struct pci_dev *pdev)
kfree(pci_adapter);
}
-#ifdef CONFIG_X86
-/**
- * cfg_order_reg - when cpu model is haswell or broadwell, should configure dma
- * order register to zero
- * @pci_adapter: pci_adapter
- **/
-/*lint -save -e40 */
-static void cfg_order_reg(struct hinic3_pcidev *pci_adapter)
+static void set_vf_load_state(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
{
- u8 cpu_model[] = {0x3c, 0x3f, 0x45, 0x46, 0x3d, 0x47, 0x4f, 0x56};
- struct cpuinfo_x86 *cpuinfo = NULL;
- u32 i;
+ /* In bm mode, slave host will load vfs in default */
+ if (IS_BMGW_SLAVE_HOST(((struct hinic3_hwdev *)pci_adapter->hwdev)) &&
+ hinic3_func_type(pci_adapter->hwdev) != TYPE_VF)
+ hinic3_set_vf_load_state(pdev, false);
- if (hinic3_func_type(pci_adapter->hwdev) == TYPE_VF)
- return;
+ if (!disable_attach) {
+ if ((hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) &&
+ hinic3_is_bm_slave_host(pci_adapter->hwdev)) {
+ if (hinic3_func_max_vf(pci_adapter->hwdev) == 0) {
+ sdk_warn(&pdev->dev, "The sriov enabling process is skipped, vfs_num: 0.\n");
+ return;
+ }
+ hinic3_pci_sriov_enable(pdev,
+ hinic3_func_max_vf(pci_adapter->hwdev));
+ }
+ }
+}
- cpuinfo = &cpu_data(0);
- for (i = 0; i < sizeof(cpu_model); i++) {
- if (cpu_model[i] == cpuinfo->x86_model)
- hinic3_set_pcie_order_cfg(pci_adapter->hwdev);
+static void hinic3_init_ppf_hwdev(struct hinic3_hwdev *hwdev)
+{
+ if (!hwdev) {
+ pr_err("[%s:%d] null hwdev pointer\n", __FILE__, __LINE__);
+ return;
}
+
+ hwdev->ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(hwdev->pcidev_hdl);
}
-/*lint -restore*/
-#endif
+static int set_nic_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ bool enable_nic = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_nic_enable(pci_adapter->hwdev, func_id, &enable_nic);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Failed to get nic state.\n");
+ return err;
+ }
+
+ if (!enable_nic) {
+ sdk_info(&pdev->dev, "Func %u nic state: disable.\n", func_id);
+ detach_uld(pci_adapter, SERVICE_T_NIC);
+ return 0;
+ }
+
+ if (IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ (void)hinic3_init_vf_dev_cap(pci_adapter->hwdev);
+
+ if (g_uld_info[SERVICE_T_NIC].probe) {
+ err = attach_uld(pci_adapter, SERVICE_T_NIC, &g_uld_info[SERVICE_T_NIC]);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Initialize NIC failed\n");
+ return err;
+ }
+ }
+
+ return 0;
+}
static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
{
@@ -689,7 +1232,16 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
list_add_tail(&pci_adapter->node, &pci_adapter->chip_node->func_list);
lld_unlock_chip_node();
+ hinic3_init_ppf_hwdev((struct hinic3_hwdev *)pci_adapter->hwdev);
+
+ set_vf_load_state(pdev, pci_adapter);
+
if (!disable_attach) {
+ /* NIC is base driver, probe firstly */
+ err = set_nic_func_state(pci_adapter);
+ if (err)
+ goto set_nic_func_state_err;
+
attach_ulds(pci_adapter);
if (hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) {
@@ -700,10 +1252,6 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
goto create_sysfs_err;
}
}
-
-#ifdef CONFIG_X86
- cfg_order_reg(pci_adapter);
-#endif
}
return 0;
@@ -711,6 +1259,7 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
create_sysfs_err:
detach_ulds(pci_adapter);
+set_nic_func_state_err:
lld_lock_chip_node();
list_del(&pci_adapter->node);
lld_unlock_chip_node();
@@ -759,6 +1308,7 @@ static void hinic3_func_deinit(struct pci_dev *pdev)
hinic3_free_stateful(pci_adapter->hwdev);
hinic3_free_hwdev(pci_adapter->hwdev);
+ pci_adapter->hwdev = NULL;
}
static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
@@ -766,18 +1316,61 @@ static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
struct hinic3_sriov_info *sriov_info;
unsigned long end;
- sriov_info = &pci_adapter->sriov_info;
- clear_bit(HINIC3_FUNC_PERSENT, &sriov_info->state);
- usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
+ sriov_info = &pci_adapter->sriov_info;
+ clear_bit(HINIC3_FUNC_PERSENT, &sriov_info->state);
+ usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
+
+ end = jiffies + msecs_to_jiffies(HINIC3_WAIT_SRIOV_CFG_TIMEOUT);
+ do {
+ if (!test_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state) &&
+ !test_bit(HINIC3_SRIOV_DISABLE, &sriov_info->state))
+ return;
+
+ usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
+ } while (time_before(jiffies, end));
+}
+
+static bool hinic3_get_vf_nic_en_status(struct pci_dev *pdev)
+{
+ bool nic_en = false;
+ u16 global_func_id;
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev) {
+ pr_err("pdev is null.\n");
+ return false;
+ }
+
+ if (pdev->is_virtfn)
+ pf_pdev = pdev->physfn;
+ else
+ return false;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return false;
+ }
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ return false;
+
+ if (hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id)) {
+ sdk_err(&pdev->dev, "Get vf id by vfpci failed\n");
+ return false;
+ }
+
+ if (hinic3_get_mhost_func_nic_enable(pci_adapter->hwdev,
+ global_func_id, &nic_en)) {
+ sdk_err(&pdev->dev, "Get function nic status failed\n");
+ return false;
+ }
- end = jiffies + msecs_to_jiffies(HINIC3_WAIT_SRIOV_CFG_TIMEOUT);
- do {
- if (!test_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state) &&
- !test_bit(HINIC3_SRIOV_DISABLE, &sriov_info->state))
- return;
+ sdk_info(&pdev->dev, "Func %hu %s default probe in host\n",
+ global_func_id, (nic_en) ? "enable" : "disable");
- usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- } while (time_before(jiffies, end));
+ return nic_en;
}
bool hinic3_get_vf_load_state(struct pci_dev *pdev)
@@ -897,6 +1490,32 @@ int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
}
EXPORT_SYMBOL(hinic3_set_vf_service_load);
+static bool hinic3_is_host_vmsec_enable(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct pci_dev *pf_pdev = NULL;
+
+ if (pdev->is_virtfn)
+ pf_pdev = pdev->physfn;
+ else
+ pf_pdev = pdev;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ pr_err("Pci_adapter is null.\n");
+ return false;
+ }
+
+ /* pf/vf used in host */
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ (hinic3_func_type(pci_adapter->hwdev) == TYPE_PF) &&
+ IS_RDMA_TYPE((struct hinic3_hwdev *)pci_adapter->hwdev)) {
+ return true;
+ }
+
+ return false;
+}
+
static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
@@ -910,6 +1529,13 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
pci_adapter->lld_state = HINIC3_IN_REMOVE;
mutex_unlock(&pci_adapter->pdev_mutex);
+ if (!(pdev->is_virtfn) && (hinic3_is_host_vmsec_enable(pdev) == true) &&
+ (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF)) {
+ cancel_delayed_work_sync(&pci_adapter->migration_probe_dwork);
+ flush_workqueue(pci_adapter->migration_probe_workq);
+ destroy_workqueue(pci_adapter->migration_probe_workq);
+ }
+
hinic3_detect_hw_present(pci_adapter->hwdev);
hisdk3_remove_pre_process(pci_adapter->hwdev);
@@ -934,23 +1560,127 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
sdk_info(&pdev->dev, "Pcie device removed function\n");
+ set_vf_func_in_use(pdev, false);
+
+ return 0;
+}
+
+int hinic3_get_vfid_by_vfpci(void *hwdev, struct pci_dev *pdev, u16 *global_func_id)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ u16 pf_bus, vf_bus, vf_offset;
+ int err;
+
+ if (!pdev || !global_func_id || !hinic3_pdev_is_virtfn(pdev))
+ return -EINVAL;
+ (void)hwdev;
+ pf_pdev = pdev->physfn;
+
+ vf_bus = pdev->bus->number;
+ pf_bus = pf_pdev->bus->number;
+
+ if (pdev->vendor == HINIC3_VIRTIO_VNEDER_ID)
+ return -EPERM;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return -EINVAL;
+ }
+
+ err = hinic3_pf_get_vf_offset_info(pci_adapter, &vf_offset);
+ if (err) {
+ sdk_err(&pdev->dev, "Func hinic3_pf_get_vf_offset_info fail\n");
+ return -EFAULT;
+ }
+
+ *global_func_id = (u16)((vf_bus - pf_bus) * BUS_MAX_DEV_NUM) + (u16)pdev->devfn +
+ (u16)(CMD_MAX_MAX_PF_NUM - g_vf_offset.vf_offset_from_pf[0]);
+
return 0;
}
+EXPORT_SYMBOL(hinic3_get_vfid_by_vfpci);
+
+static void hinic3_set_vf_status_in_host(struct pci_dev *pdev, bool status)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ void *ppf_hwdev = NULL;
+ u16 global_func_id;
+ int ret;
+
+ if (!pf_pdev)
+ return;
+
+ if (!hinic3_pdev_is_virtfn(pdev))
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ pf_hwdev = pci_adapter->hwdev;
+ ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(pf_pdev);
+ if (!pf_hwdev || !ppf_hwdev)
+ return;
+
+ ret = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (ret) {
+ sdk_err(&pci_adapter->pcidev->dev,
+ "Func hinic3_get_vfid_by_vfpci fail %d\n", ret);
+ return;
+ }
+
+ ret = hinic3_set_func_probe_in_host(ppf_hwdev, global_func_id, status);
+ if (ret)
+ sdk_err(&pci_adapter->pcidev->dev,
+ "Set the function probe status in host failed\n");
+}
+
+#ifdef CONFIG_PCI_IOV
+/* Check whether pdev is a VF and whether it belongs to the PF of the SDI card */
+static bool check_pdev_type_and_state(struct pci_dev *pdev)
+{
+ if (!(pdev->is_virtfn))
+ return false;
+
+ if ((hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_1_PF) &&
+ (hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_0_PF)) {
+ return false;
+ }
+
+ if (!hinic3_get_vf_load_state(pdev))
+ return false;
+
+ return true;
+}
+#endif
static void hinic3_remove(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
+ sdk_info(&pdev->dev, "Pcie device remove begin\n");
+
if (!pci_adapter)
- return;
+ goto out;
- sdk_info(&pdev->dev, "Pcie device remove begin\n");
+#ifdef CONFIG_PCI_IOV
+ if (check_pdev_type_and_state(pdev))
+ goto out;
+#endif
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
hinic3_remove_func(pci_adapter);
+ if (!pci_adapter->pcidev->is_virtfn &&
+ pci_adapter->multi_host_mgmt_workq)
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
hinic3_pci_deinit(pdev);
hinic3_probe_pre_unprocess(pdev);
+out:
+ hinic3_set_vf_status_in_host(pdev, false);
sdk_info(&pdev->dev, "Pcie device removed\n");
}
@@ -969,7 +1699,7 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
if (pci_adapter->lld_state >= HINIC3_PROBE_START) {
sdk_warn(&pdev->dev, "Don not probe repeat\n");
mutex_unlock(&pci_adapter->pdev_mutex);
- return 0;
+ return -EEXIST;
}
pci_adapter->lld_state = HINIC3_PROBE_START;
mutex_unlock(&pci_adapter->pdev_mutex);
@@ -977,15 +1707,28 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
return 0;
}
+static void hinic3_probe_success_process(struct hinic3_pcidev *pci_adapter)
+{
+ hinic3_probe_success(pci_adapter->hwdev);
+
+ mutex_lock(&pci_adapter->pdev_mutex);
+ pci_adapter->lld_state = HINIC3_PROBE_OK;
+ mutex_unlock(&pci_adapter->pdev_mutex);
+}
+
static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
int err;
err = probe_func_param_init(pci_adapter);
- if (err)
+ if (err == -EEXIST)
+ return 0;
+ else if (err)
return err;
+ set_vf_func_in_use(pdev, true);
+
err = mapping_bar(pdev, pci_adapter);
if (err) {
sdk_err(&pdev->dev, "Failed to map bar\n");
@@ -1017,11 +1760,7 @@ static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
}
}
- hinic3_probe_success(pci_adapter->hwdev);
-
- mutex_lock(&pci_adapter->pdev_mutex);
- pci_adapter->lld_state = HINIC3_PROBE_OK;
- mutex_unlock(&pci_adapter->pdev_mutex);
+ hinic3_probe_success_process(pci_adapter);
return 0;
@@ -1037,18 +1776,300 @@ alloc_chip_node_fail:
unmapping_bar(pci_adapter);
map_bar_failed:
+ set_vf_func_in_use(pdev, false);
sdk_err(&pdev->dev, "Pcie device probe function failed\n");
return err;
}
+void hinic3_set_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int err;
+ bool enable_func = false;
+
+ err = hinic3_get_function_enable(pdev, &enable_func);
+ if (err) {
+ sdk_info(&pdev->dev, "Get function enable failed\n");
+ return;
+ }
+
+ sdk_info(&pdev->dev, "%s function resource start\n",
+ enable_func ? "Initialize" : "Free");
+ if (enable_func) {
+ err = hinic3_probe_func(pci_adapter);
+ if (err)
+ sdk_info(&pdev->dev, "Function probe failed\n");
+ } else {
+ hinic3_remove_func(pci_adapter);
+ }
+ if (err == 0)
+ sdk_info(&pdev->dev, "%s function resource end\n",
+ enable_func ? "Initialize" : "Free");
+}
+
+void slave_host_mgmt_work(struct work_struct *work)
+{
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_nic_work);
+
+ if (hinic3_pdev_is_virtfn(pci_adapter->pcidev))
+ hinic3_set_func_state(pci_adapter);
+ else
+ set_nic_func_state(pci_adapter);
+}
+
+static int pci_adapter_assign_val(struct hinic3_pcidev **ppci_adapter,
+ struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ *ppci_adapter = pci_get_drvdata(pdev);
+ (*ppci_adapter)->disable_vf_load = disable_vf_load;
+ (*ppci_adapter)->id = *id;
+ (*ppci_adapter)->lld_state = HINIC3_NOT_PROBE;
+ (*ppci_adapter)->probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ lld_dev_cnt_init(*ppci_adapter);
+
+ (*ppci_adapter)->multi_host_mgmt_workq = alloc_workqueue("hinic_mhost_mgmt",
+ WQ_UNBOUND,
+ HINIC3_SLAVE_WORK_MAX_NUM);
+ if (!(*ppci_adapter)->multi_host_mgmt_workq) {
+ hinic3_pci_deinit(pdev);
+ sdk_err(&pdev->dev, "Alloc multi host mgmt workqueue failed\n");
+ return -ENOMEM;
+ }
+
+ INIT_WORK(&(*ppci_adapter)->slave_nic_work, slave_host_mgmt_work);
+ INIT_WORK(&(*ppci_adapter)->slave_vroce_work,
+ slave_host_mgmt_vroce_work);
+
+ return 0;
+}
+
+static void slave_host_vfio_probe_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_pcidev *pci_adapter = container_of(delay, struct hinic3_pcidev,
+ migration_probe_dwork);
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int (*dev_migration_probe)(struct pci_dev *pdev);
+ int rc;
+
+ if (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) != TYPE_PF)
+ return;
+
+ dev_migration_probe = __symbol_get("migration_dev_migration_probe");
+ if (!(dev_migration_probe)) {
+ sdk_err(&pdev->dev,
+ "Failed to find: migration_dev_migration_probe");
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork,
+ WAIT_TIME * HZ);
+ } else {
+ rc = dev_migration_probe(pdev);
+ __symbol_put("migration_dev_migration_probe");
+ if (rc) {
+ sdk_err(&pdev->dev,
+ "Failed to __dev_migration_probe, rc:0x%x, pf migrated(%d).\n",
+ rc, g_is_pf_migrated);
+ } else {
+ g_is_pf_migrated = true;
+ sdk_info(&pdev->dev,
+ "Succeeded in __dev_migration_probe, pf migrated(%d).\n",
+ g_is_pf_migrated);
+ }
+ }
+}
+
+struct vf_add_delaywork {
+ struct pci_dev *vf_pdev;
+ struct delayed_work migration_vf_add_dwork;
+};
+
+static void slave_host_migration_vf_add_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct vf_add_delaywork *vf_add = container_of(delay, struct vf_add_delaywork,
+ migration_vf_add_dwork);
+ struct pci_dev *vf_pdev = vf_add->vf_pdev;
+ struct pci_dev *pf_pdev = NULL;
+ int (*migration_dev_add_vf)(struct pci_dev *vf_pdev);
+ int ret;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!vf_pdev) {
+ pr_err("vf pdev is null.\n");
+ goto err1;
+ }
+ if (!vf_pdev->is_virtfn) {
+ sdk_err(&vf_pdev->dev, "Pdev is not virtfn.\n");
+ goto err1;
+ }
+
+ pf_pdev = vf_pdev->physfn;
+ if (!pf_pdev) {
+ sdk_err(&vf_pdev->dev, "pf_pdev is null.\n");
+ goto err1;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&vf_pdev->dev, "Pci_adapter is null.\n");
+ goto err1;
+ }
+
+ if (!g_is_pf_migrated) {
+ sdk_info(&vf_pdev->dev, "pf is not migrated yet, so vf continues to try again.\n");
+ goto delay_work;
+ }
+
+ migration_dev_add_vf = __symbol_get("migration_dev_add_vf");
+ if (migration_dev_add_vf) {
+ ret = migration_dev_add_vf(vf_pdev);
+ __symbol_put("migration_dev_add_vf");
+ if (ret)
+ sdk_err(&vf_pdev->dev, "vf get migration symbol succeeded, but dev add vf failed, ret:%d.\n",
+ ret);
+ else
+ sdk_info(&vf_pdev->dev, "vf get migration symbol succeeded, and dev add vf success.\n");
+ goto err1;
+ }
+ sdk_info(&vf_pdev->dev, "pf is migrated, but vf get migration symbol failed.\n");
+
+delay_work:
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork, WAIT_TIME * HZ);
+ return;
+
+err1:
+ kfree(vf_add);
+}
+
+static void hinic3_probe_vf_add_dwork(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct vf_add_delaywork *vf_add = NULL;
+
+ if (!hinic3_is_host_vmsec_enable(pdev))
+ return;
+
+#if defined(CONFIG_SP_VID_DID)
+ if (pdev->vendor == PCI_VENDOR_ID_SPNIC && pdev->device == HINIC3_DEV_SDI_5_1_ID_VF) {
+#elif defined(CONFIG_NF_VID_DID)
+ if (pdev->vendor == PCI_VENDOR_ID_NF && pdev->device == NFNIC_DEV_ID_VF) {
+#else
+ if (pdev->vendor == PCI_VENDOR_ID_HUAWEI && pdev->device == HINIC3_DEV_SDI_5_0_ID_VF) {
+#endif
+ vf_add = kmalloc(sizeof(*vf_add), GFP_ATOMIC);
+
+ if (!vf_add) {
+ sdk_info(&pdev->dev, "vf_add is null.\n");
+ return;
+ }
+ vf_add->vf_pdev = pdev;
+
+ pf_pdev = pdev->physfn;
+
+ if (!pf_pdev) {
+ sdk_info(&pdev->dev, "Vf-pf_pdev is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_info(&pdev->dev, "Pci_adapter is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ INIT_DELAYED_WORK(&vf_add->migration_vf_add_dwork,
+ slave_host_migration_vf_add_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork,
+ WAIT_TIME * HZ);
+ }
+}
+
+static int hinic3_probe_migration_dwork(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+{
+ if (!hinic3_is_host_vmsec_enable(pdev)) {
+ sdk_info(&pdev->dev, "Probe_migration : hinic3_is_host_vmsec_enable is (0).\n");
+ return 0;
+ }
+
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF) {
+ pci_adapter->migration_probe_workq =
+ create_singlethread_workqueue("hinic3_migration_probe_delay");
+ if (!pci_adapter->migration_probe_workq) {
+ sdk_err(&pdev->dev, "Failed to create work queue:%s\n",
+ "hinic3_migration_probe_delay");
+ return -EINVAL;
+ }
+
+ INIT_DELAYED_WORK(&pci_adapter->migration_probe_dwork,
+ slave_host_vfio_probe_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork,
+ WAIT_TIME * HZ);
+ }
+
+ return 0;
+}
+
+static bool hinic3_os_hot_replace_allow(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_hwdev *hwdev = (struct hinic3_hwdev *)pci_adapter->hwdev;
+ // check service enable and dev is not VF
+ if (hinic3_func_type(hwdev) == TYPE_VF || hwdev->hot_replace_mode == HOT_REPLACE_DISABLE)
+ return false;
+
+ return true;
+}
+
+static bool hinic3_os_hot_replace_process(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_board_info *board_info;
+ u16 cur_pf_id = hinic3_global_func_id(pci_adapter->hwdev);
+ u8 cur_partion_id;
+
+ board_info = &((struct hinic3_hwdev *)(pci_adapter->hwdev))->board_info;
+ // probe to os
+ vpci_set_partition_attrs(pci_adapter->pcidev, PARTITION_DEV_EXCLUSIVE,
+ get_function_partition(cur_pf_id,
+ board_info->port_num));
+
+ // check pf_id is in the right partition_id
+ cur_partion_id = get_partition_id();
+ if (get_function_partition(cur_pf_id, board_info->port_num) ==
+ cur_partion_id)
+ return true;
+
+ pci_adapter->probe_fault_level = FAULT_LEVEL_SUGGESTION;
+ return false;
+}
+
static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct hinic3_pcidev *pci_adapter = NULL;
u16 probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ u32 device_id, function_id;
int err;
sdk_info(&pdev->dev, "Pcie device probe begin\n");
+#ifdef CONFIG_PCI_IOV
+ hinic3_set_vf_status_in_host(pdev, true);
+ if (check_pdev_type_and_state(pdev)) {
+ sdk_info(&pdev->dev, "VFs are not binded to hinic\n");
+ hinic3_probe_vf_add_dwork(pdev);
+ return -EINVAL;
+ }
+#endif
+
err = hinic3_probe_pre_process(pdev);
if (err != 0 && err != HINIC3_NOT_PROBE)
goto out;
@@ -1060,26 +2081,48 @@ static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (err)
goto pci_init_err;
- pci_adapter = pci_get_drvdata(pdev);
- pci_adapter->disable_vf_load = disable_vf_load;
- pci_adapter->id = *id;
- pci_adapter->lld_state = HINIC3_NOT_PROBE;
- pci_adapter->probe_fault_level = probe_fault_level;
- lld_dev_cnt_init(pci_adapter);
+ err = pci_adapter_assign_val(&pci_adapter, pdev, id);
+ if (err)
+ goto allco_queue_err;
- if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev))) {
+ if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev)) &&
+ (!hinic3_get_vf_nic_en_status(pdev))) {
sdk_info(&pdev->dev, "VF device disable load in host\n");
return 0;
}
- err = hinic3_probe_func(pci_adapter);
- if (err)
+ if (hinic3_probe_func(pci_adapter))
+ goto hinic3_probe_func_fail;
+
+ if (hinic3_os_hot_replace_allow(pci_adapter)) {
+ if (!hinic3_os_hot_replace_process(pci_adapter)) {
+ device_id = PCI_SLOT(pdev->devfn);
+ function_id = PCI_FUNC(pdev->devfn);
+ sdk_info(&pdev->dev,
+ "os hot replace: skip function %d:%d for partition %d",
+ device_id, function_id, get_partition_id());
+ goto os_hot_repalce_not_allow;
+ }
+ }
+
+ if (hinic3_probe_migration_dwork(pdev, pci_adapter))
goto hinic3_probe_func_fail;
sdk_info(&pdev->dev, "Pcie device probed\n");
return 0;
+os_hot_repalce_not_allow:
+ hinic3_func_deinit(pdev);
+ lld_lock_chip_node();
+ free_chip_node(pci_adapter);
+ lld_unlock_chip_node();
+ unmapping_bar(pci_adapter);
+ set_vf_func_in_use(pdev, false);
hinic3_probe_func_fail:
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
+allco_queue_err:
probe_fault_level = pci_adapter->probe_fault_level;
hinic3_pci_deinit(pdev);
@@ -1105,6 +2148,11 @@ static int hinic3_get_pf_info(struct pci_dev *pdev, u16 service,
}
*pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (*pf_infos == NULL) {
+ sdk_err(&pdev->dev, "pf_infos kzalloc failed\n");
+ return -EFAULT;
+ }
+
err = hinic3_get_hw_pf_infos(dev->hwdev, *pf_infos, HINIC3_CHANNEL_COMM);
if (err) {
kfree(*pf_infos);
@@ -1120,6 +2168,7 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
{
int err;
+ mutex_lock(&dst_dev->pdev_mutex);
/* unload invalid vf func id */
if (!en && vf_func_id != hinic3_global_func_id(dst_dev->hwdev) &&
!strcmp(des_pdev->driver->name, HINIC3_DRV_NAME)) {
@@ -1137,6 +2186,8 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
err = hinic3_probe_func(dst_dev);
if (err)
return -EFAULT;
+ } else {
+ mutex_unlock(&dst_dev->pdev_mutex);
}
return 0;
@@ -1161,7 +2212,6 @@ static int get_vf_service_state_param(struct pci_dev *pdev, struct hinic3_pcidev
return 0;
}
-#define BUS_MAX_DEV_NUM 256
static int hinic3_dst_pdev_valid(struct hinic3_pcidev *dst_dev, struct pci_dev **des_pdev_ptr,
u16 vf_devfn, bool en)
{
@@ -1243,7 +2293,6 @@ int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id, u16 servic
if (en)
pci_dev_put(des_pdev);
- mutex_lock(&dst_dev->pdev_mutex);
find_dst_dev = true;
break;
}
@@ -1263,19 +2312,30 @@ free_pf_info:
}
EXPORT_SYMBOL(hinic3_set_vf_service_state);
-/*lint -save -e133 -e10*/
static const struct pci_device_id hinic3_pci_table[] = {
+#if defined(CONFIG_SP_VID_DID)
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_STANDARD), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_SDI_5_1_PF), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_SDI_5_0_PF), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_SPN120), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_VF), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_SDI_5_1_ID_VF), 0},
+#elif defined(CONFIG_NF_VID_DID)
+ {PCI_VDEVICE(NF, NFNIC_DEV_ID_STANDARD), 0},
+ {PCI_VDEVICE(NF, NFNIC_DEV_ID_VF), 0},
+#else
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SPU), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_STANDARD), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_1_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_SDI_5_1_ID_VF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_VF), 0},
+#endif
{0, 0}
};
-/*lint -restore*/
-
MODULE_DEVICE_TABLE(pci, hinic3_pci_table);
/**
@@ -1307,14 +2367,27 @@ static pci_ers_result_t hinic3_io_error_detected(struct pci_dev *pdev,
return PCI_ERS_RESULT_CAN_RECOVER;
}
+static void hinic3_timer_disable(void *hwdev)
+{
+ if (!hwdev)
+ return;
+
+ if (hinic3_get_stateful_enable(hwdev) && hinic3_get_timer_enable(hwdev))
+ (void)hinic3_func_tmr_bitmap_set(hwdev,
+ hinic3_global_func_id(hwdev),
+ false);
+}
+
static void hinic3_shutdown(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
sdk_info(&pdev->dev, "Shutdown device\n");
- if (pci_adapter)
+ if (pci_adapter) {
+ hinic3_timer_disable(pci_adapter->hwdev);
hinic3_shutdown_hwdev(pci_adapter->hwdev);
+ }
pci_disable_device(pdev);
@@ -1341,6 +2414,9 @@ static struct pci_driver hinic3_driver = {
.probe = hinic3_probe,
.remove = hinic3_remove,
.shutdown = hinic3_shutdown,
+#ifdef CONFIG_PARTITION_DEVICE
+ .driver.probe_concurrency = true,
+#endif
#if defined(HAVE_SRIOV_CONFIGURE)
.sriov_configure = hinic3_pci_sriov_configure,
#elif defined(HAVE_RHEL6_SRIOV_CONFIGURE)
@@ -1362,16 +2438,21 @@ int hinic3_lld_init(void)
err = hinic3_module_pre_init();
if (err) {
pr_err("Init custom failed\n");
- return err;
+ goto module_pre_init_err;
}
err = pci_register_driver(&hinic3_driver);
if (err) {
- hinic3_module_post_exit();
- return err;
+ pr_err("sdk3 pci register driver failed\n");
+ goto register_pci_driver_err;
}
return 0;
+
+register_pci_driver_err:
+ hinic3_module_post_exit();
+module_pre_init_err:
+ return err;
}
void hinic3_lld_exit(void)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
index b2851c6..3626262 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
@@ -584,6 +584,7 @@ static void free_recv_mbox(struct hinic3_recv_mbox *recv_msg)
kfree(recv_msg->resp_buff);
kfree(recv_msg->msg);
kfree(recv_msg);
+ recv_msg = NULL;
}
static void recv_func_mbox_work_handler(struct work_struct *work)
@@ -1232,6 +1233,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
set_mbox_to_func_event(func_to_func, EVENT_FAIL);
goto send_err;
}
+ func_to_func->hwdev->mbox_send_cnt++;
if (wait_mbox_msg_completion(func_to_func, timeout) != 0) {
sdk_err(func_to_func->hwdev->dev_hdl,
@@ -1240,6 +1242,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
err = -ETIMEDOUT;
goto send_err;
}
+ func_to_func->hwdev->mbox_ack_cnt++;
if (mod != msg_desc->mod || cmd != msg_desc->cmd) {
sdk_err(func_to_func->hwdev->dev_hdl,
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
index 2bd63f1..4718458 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
@@ -861,6 +861,7 @@ static int alloc_recv_msg(struct hinic3_recv_msg *recv_msg)
static void free_recv_msg(struct hinic3_recv_msg *recv_msg)
{
kfree(recv_msg->msg);
+ recv_msg->msg = NULL;
}
/**
@@ -932,6 +933,9 @@ static void free_msg_buf(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt)
free_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
+ pf_to_mgmt->mgmt_ack_buf = NULL;
+ pf_to_mgmt->sync_msg_buf = NULL;
+ pf_to_mgmt->async_msg_buf = NULL;
}
/**
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
index 3548410..a0f5e73 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
@@ -676,6 +676,9 @@ static int hinic3_register_slave_ppf(struct hinic3_hwdev *hwdev, bool registered
if (!IS_SLAVE_HOST(hwdev))
return -EINVAL;
+ if (UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev))
+ return 0;
+
host_info = kcalloc(1, sizeof(struct register_slave_host), GFP_KERNEL);
if (!host_info)
return -ENOMEM;
@@ -1075,7 +1078,8 @@ int hinic3_get_func_nic_enable(void *hwdev, u16 glb_func_idx, bool *en)
return -EINVAL;
/* if single host, return true. */
- if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev)) {
+ if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev) ||
+ UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev)) {
*en = true;
return 0;
}
@@ -1145,11 +1149,21 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
{
int err;
struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+ int is_use_vram, is_in_kexec;
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
- hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0) {
+ snprintf(hwdev->mhost_mgmt_name, VRAM_NAME_MAX_LEN, "%s",
+ VRAM_NIC_MHOST_MGMT);
+ hwdev->mhost_mgmt = hi_vram_kalloc(hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ } else {
+ hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ }
+
if (!hwdev->mhost_mgmt)
return -ENOMEM;
@@ -1165,8 +1179,11 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK, hwdev, hilink_ppf_mbox_handler);
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC, hwdev, sw_func_ppf_mbox_handler);
- bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
- bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ }
/* Slave host:
* register slave host ppf functions
@@ -1179,7 +1196,11 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
return 0;
out_free_mhost_mgmt:
- kfree(hwdev->mhost_mgmt);
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)hwdev->mhost_mgmt, hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ else
+ kfree(hwdev->mhost_mgmt);
hwdev->mhost_mgmt = NULL;
return err;
@@ -1187,6 +1208,8 @@ out_free_mhost_mgmt:
int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
{
+ int is_use_vram;
+
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
@@ -1203,7 +1226,13 @@ int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC);
- kfree(hwdev->mhost_mgmt);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)hwdev->mhost_mgmt, hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ else
+ kfree(hwdev->mhost_mgmt);
+
hwdev->mhost_mgmt = NULL;
return 0;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
index 5e4804a..5a5ea53 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
@@ -17,14 +17,13 @@
#include "hinic3_hwdev.h"
#include "hinic3_lld.h"
#include "hinic3_hw_mt.h"
+#include "hinic3_dev_mgmt.h"
#include "hinic3_nictool.h"
static int g_nictool_ref_cnt;
static dev_t g_dev_id = {0};
-/*lint -save -e104 -e808*/
static struct class *g_nictool_class;
-/*lint -restore*/
static struct cdev g_nictool_cdev;
#define HINIC3_MAX_BUF_SIZE (2048 * 1024)
@@ -92,6 +91,23 @@ static int get_all_chip_id_cmd(struct hinic3_lld_dev *lld_dev, const void *buf_i
return 0;
}
+#ifndef __HIFC__
+static int get_os_hot_replace_info(struct hinic3_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ if (*out_size != sizeof(struct os_hot_replace_info) || !buf_out) {
+ pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
+ *out_size, sizeof(struct os_hot_replace_info));
+ return -EFAULT;
+ }
+
+ hinic3_get_os_hot_replace_info(buf_out);
+
+ return 0;
+}
+#endif
+
static int get_card_usr_api_chain_mem(int card_idx)
{
unsigned char *tmp = NULL;
@@ -166,7 +182,7 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
if (!buf_out || *out_size != sizeof(struct pf_dev_info) * PF_DEV_INFO_NUM) {
pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
- *out_size, sizeof(dev_info) * PF_DEV_INFO_NUM);
+ *out_size, sizeof(*dev_info) * PF_DEV_INFO_NUM);
return -EFAULT;
}
@@ -193,13 +209,18 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
return 0;
}
-static long dbgtool_knl_free_mem(int id)
+static void dbgtool_knl_free_mem(int id)
{
unsigned char *tmp = NULL;
int i;
+ if (id < 0 || id >= MAX_CARD_NUM) {
+ pr_err("Invalid card id\n");
+ return;
+ }
+
if (!g_card_vir_addr[id])
- return 0;
+ return;
tmp = g_card_vir_addr[id];
for (i = 0; i < (1 << DBGTOOL_PAGE_ORDER); i++) {
@@ -211,7 +232,6 @@ static long dbgtool_knl_free_mem(int id)
g_card_vir_addr[id] = NULL;
g_card_phy_addr[id] = 0;
- return 0;
}
static int free_knl_mem(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_size,
@@ -337,7 +357,6 @@ static int get_hw_drv_version(struct hinic3_lld_dev *lld_dev, const void *buf_in
void *buf_out, u32 *out_size)
{
struct drv_version_info *ver_info = buf_out;
- int err;
if (!buf_out) {
pr_err("Buf_out is NULL.\n");
@@ -350,10 +369,8 @@ static int get_hw_drv_version(struct hinic3_lld_dev *lld_dev, const void *buf_in
return -EINVAL;
}
- err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s", HINIC3_DRV_VERSION,
- "2023-05-17_19:56:38");
- if (err < 0)
- return -EINVAL;
+ snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s", HINIC3_DRV_VERSION,
+ "2025-05-08_00:00:08");
return 0;
}
@@ -386,6 +403,22 @@ static int get_pf_id(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_
return 0;
}
+#ifndef __HIFC__
+/* not support fc yet */
+static int get_mbox_cnt(struct hinic3_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ if (!buf_out || *out_size != sizeof(struct card_mbox_cnt_info)) {
+ pr_err("buf_out is NULL, or out_size != %lu\n", sizeof(struct card_info));
+ return -EINVAL;
+ }
+
+ hinic3_get_mbox_cnt(hinic3_get_sdk_hwdev_by_lld(lld_dev), buf_out);
+
+ return 0;
+}
+#endif
+
struct hw_drv_module_handle hw_driv_module_cmd_handle[] = {
{FUNC_TYPE, get_func_type},
{GET_FUNC_IDX, get_func_id},
@@ -402,6 +435,10 @@ struct hw_drv_module_handle hw_driv_module_cmd_handle[] = {
{GET_FUNC_CAP, get_pf_cap_info},
{GET_DRV_VERSION, get_hw_drv_version},
{GET_PF_ID, get_pf_id},
+#ifndef __HIFC__
+ {GET_OS_HOT_REPLACE_INFO, get_os_hot_replace_info},
+ {GET_MBOX_CNT, (hw_driv_module)get_mbox_cnt},
+#endif
};
static int alloc_tmp_buf(void *hwdev, struct msg_module *nt_msg, u32 in_size,
@@ -439,8 +476,8 @@ static void free_tmp_buf(void *hwdev, struct msg_module *nt_msg,
static int send_to_hw_driver(struct hinic3_lld_dev *lld_dev, struct msg_module *nt_msg,
const void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(hw_driv_module_cmd_handle) /
- sizeof(hw_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(hw_driv_module_cmd_handle) /
+ sizeof(hw_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type =
(enum driver_cmd_type)(nt_msg->msg_formate);
int err = 0;
@@ -482,8 +519,8 @@ static int send_to_service_driver(struct hinic3_lld_dev *lld_dev, struct msg_mod
if (nt_msg->msg_formate == GET_DRV_VERSION)
return 0;
- pr_err("Can not get the uld dev correctly: %s, %s driver may be not register\n",
- nt_msg->device_name, service_name[type]);
+ pr_err("Can not get the uld dev correctly: %s driver may be not register\n",
+ service_name[type]);
return -EINVAL;
}
@@ -597,8 +634,10 @@ static long hinicadm_k_unlocked_ioctl(struct file *pfile, unsigned long arg)
return -ENODEV;
}
- if (nt_msg.msg_formate == DEV_NAME_TEST)
+ if (nt_msg.msg_formate == DEV_NAME_TEST) {
+ lld_dev_put(lld_dev);
return 0;
+ }
ret = alloc_tmp_buf(hinic3_get_sdk_hwdev_by_lld(lld_dev), &nt_msg,
in_size, &buf_in, out_size_expect, &buf_out);
@@ -642,6 +681,9 @@ out_free_lock:
static long dbgtool_knl_ffm_info_rd(struct dbgtool_param *para,
struct dbgtool_k_glb_info *dbgtool_info)
{
+ if (!para->param.ffm_rd || !dbgtool_info->ffm)
+ return -EINVAL;
+
/* Copy the ffm_info to user mode */
if (copy_to_user(para->param.ffm_rd, dbgtool_info->ffm,
(unsigned int)sizeof(struct ffm_record_info))) {
@@ -674,13 +716,14 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
card_info = (struct card_node *)g_card_node_array[i];
if (!card_info)
continue;
- if (!strncmp(param.chip_name, card_info->chip_name, IFNAMSIZ))
+ if (memcmp(param.chip_name, card_info->chip_name,
+ strlen(card_info->chip_name) + 1) == 0)
break;
}
if (i == MAX_CARD_NUM || !card_info) {
lld_put();
- pr_err("Can't find this card %s\n", param.chip_name);
+ pr_err("Can't find this card.\n");
return -EFAULT;
}
@@ -697,10 +740,10 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
pr_err("Not suppose to use this cmd(0x%x).\n", real_cmd);
ret = 0;
break;
-
default:
pr_err("Dbgtool cmd(0x%x) not support now\n", real_cmd);
ret = -EFAULT;
+ break;
}
up(&dbgtool_info->dbgtool_sem);
@@ -746,9 +789,11 @@ static long nictool_k_unlocked_ioctl(struct file *pfile,
static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
{
+ pgprot_t vm_page_prot;
unsigned long vmsize = vma->vm_end - vma->vm_start;
phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
phys_addr_t phy_addr;
+ int err = 0;
if (vmsize > (PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER))) {
pr_err("Map size = %lu is bigger than alloc\n", vmsize);
@@ -758,13 +803,18 @@ static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
/* old version of tool set vma->vm_pgoff to 0 */
phy_addr = offset ? offset : g_card_phy_addr[card_id];
- if (!phy_addr) {
- pr_err("Card_id = %d physical address is 0\n", card_id);
- return -EAGAIN;
+ /* check phy_addr valid */
+ if (phy_addr != g_card_phy_addr[card_id]) {
+ err = hinic3_bar_mmap_param_valid(phy_addr, vmsize);
+ if (err != 0) {
+ pr_err("mmap param invalid, err: %d\n", err);
+ return err;
+ }
}
/* Disable cache and write buffer in the mapping area */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_page_prot = vm_page_prot;
if (remap_pfn_range(vma, vma->vm_start, (phy_addr >> PAGE_SHIFT),
vmsize, vma->vm_page_prot)) {
pr_err("Remap pfn range failed.\n");
@@ -787,7 +837,6 @@ static const struct file_operations fifo_operations = {
static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
{
struct dbgtool_k_glb_info *dbgtool_info = NULL;
- int err, id;
if (hinic3_func_type(hwdev) != TYPE_VF)
chip_info->func_handle_array[hinic3_global_func_id(hwdev)] = NULL;
@@ -795,23 +844,22 @@ static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
if (--chip_info->func_num)
return;
- err = sscanf(chip_info->chip_name, HINIC3_CHIP_NAME "%d", &id);
- if (err < 0)
- pr_err("Failed to get card id\n");
-
- if (id < MAX_CARD_NUM)
- g_card_node_array[id] = NULL;
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ g_card_node_array[chip_info->chip_id] = NULL;
dbgtool_info = chip_info->dbgtool_info;
/* FFM deinit */
- kfree(dbgtool_info->ffm);
- dbgtool_info->ffm = NULL;
+ if (dbgtool_info && dbgtool_info->ffm) {
+ kfree(dbgtool_info->ffm);
+ dbgtool_info->ffm = NULL;
+ }
kfree(dbgtool_info);
+
chip_info->dbgtool_info = NULL;
- if (id < MAX_CARD_NUM)
- (void)dbgtool_knl_free_mem(id);
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ dbgtool_knl_free_mem(chip_info->chip_id);
}
static int alloc_dbgtool_info(void *hwdev, struct card_node *chip_info)
@@ -872,7 +920,7 @@ dbgtool_info_fail:
* nictool_k_init - initialize the hw interface
**/
/* temp for dbgtool_info */
-/*lint -e438*/
+
int nictool_k_init(void *hwdev, void *chip_node)
{
struct card_node *chip_info = (struct card_node *)chip_node;
@@ -895,9 +943,7 @@ int nictool_k_init(void *hwdev, void *chip_node)
}
/* Create equipment */
- /*lint -save -e160*/
g_nictool_class = class_create(HIADM3_DEV_CLASS);
- /*lint -restore*/
if (IS_ERR(g_nictool_class)) {
pr_err("Create nictool_class fail\n");
err = -EFAULT;
@@ -944,7 +990,7 @@ alloc_chdev_fail:
free_dbgtool_info(hwdev, chip_info);
return err;
-} /*lint +e438*/
+}
void nictool_k_uninit(void *hwdev, void *chip_node)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
index f368133..c943dfc 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
@@ -18,6 +18,8 @@
int nictool_k_init(void *hwdev, void *chip_node);
void nictool_k_uninit(void *hwdev, void *chip_node);
+void hinic3_get_os_hot_replace_info(void *oshr_info);
+
void hinic3_get_all_chip_id(void *id_info);
void hinic3_get_card_func_info_by_card_name
@@ -29,6 +31,8 @@ bool hinic3_is_in_host(void);
int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *isvalid);
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin);
+
extern struct hinic3_uld_info g_uld_info[SERVICE_T_MAX];
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
index 2d5423e..e961ef7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
@@ -19,6 +19,20 @@
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
+#elif defined(CONFIG_NF_VID_DID)
+#define PCI_VENDOR_ID_NF 0x2036
+#define NFNIC_DEV_ID_STANDARD 0x1618
+#define NFNIC_DEV_ID_SDI_5_1_PF 0x0226
+#define NFNIC_DEV_ID_SDI_5_0_PF 0x0225
+#define NFNIC_DEV_ID_DPU_PF 0x0224
+#define NFNIC_DEV_ID_VF 0x1619
+#define NFNIC_DEV_ID_VF_HV 0x379F
+#define NFNIC_DEV_SDI_5_1_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_0_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_1_ID_VF_HV 0x379F
+#define NFNIC_DEV_ID_SPU 0xAC00
+#define NFNIC_DEV_SDI_5_1_SSDID_VF 0x1000
+#define NFNIC_DEV_SDI_V100_SSDID_MASK (3 << 12)
#else
#define PCI_VENDOR_ID_HUAWEI 0x19e5
#define HINIC3_DEV_ID_STANDARD 0x0222
@@ -28,16 +42,33 @@
#define HINIC3_DEV_ID_VF 0x375F
#define HINIC3_DEV_ID_VF_HV 0x379F
#define HINIC3_DEV_SDI_5_1_ID_VF 0x375F
+#define HINIC3_DEV_SDI_5_0_ID_VF 0x375F
#define HINIC3_DEV_SDI_5_1_ID_VF_HV 0x379F
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
#endif
+#define NFNIC_DEV_SSID_2X25G_NF 0x0860
+#define NFNIC_DEV_SSID_4X25G_NF 0x0861
+#define NFNIC_DEV_SSID_2x100G_NF 0x0862
+#define NFNIC_DEV_SSID_2x200G_NF 0x0863
+
+#define HINIC3_DEV_SSID_2X10G 0x0035
#define HINIC3_DEV_SSID_2X25G 0x0051
#define HINIC3_DEV_SSID_4X25G 0x0052
+#define HINIC3_DEV_SSID_4X25G_BD 0x0252
+#define HINIC3_DEV_SSID_4X25G_SMARTNIC 0x0152
+#define HINIC3_DEV_SSID_6X25G_VL 0x0356
#define HINIC3_DEV_SSID_2X100G 0x00A1
+#define HINIC3_DEV_SSID_2X100G_SMARTNIC 0x01A1
+#define HINIC3_DEV_SSID_2X200G 0x04B1
#define HINIC3_DEV_SSID_2X100G_VF 0x1000
+#define HINIC3_DEV_SSID_HPC_4_HOST_NIC 0x005A
+#define HINIC3_DEV_SSID_2X200G_VL 0x00B1
+#define HINIC3_DEV_SSID_1X100G 0x02A4
+
+#define BIFUR_RESOURCE_PF_SSID 0x05a1
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
index b23b69f..461272e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
@@ -52,26 +52,25 @@ static int hinic3_deinit_vf_hw(void *hwdev, u16 start_vf_id, u16 end_vf_id)
}
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
-ssize_t hinic3_sriov_totalvfs_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ssize_t sriov_totalvfs_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
return sprintf(buf, "%d\n", pci_sriov_get_totalvfs(pdev));
}
-ssize_t hinic3_sriov_numvfs_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ssize_t sriov_numvfs_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
return sprintf(buf, "%d\n", pci_num_vf(pdev));
}
-/*lint -save -e713*/
-ssize_t hinic3_sriov_numvfs_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+ssize_t sriov_numvfs_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct pci_dev *pdev = to_pci_dev(dev);
int ret;
@@ -116,7 +115,6 @@ ssize_t hinic3_sriov_numvfs_store(struct device *dev,
return count;
}
-/*lint -restore*/
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
int hinic3_pci_sriov_disable(struct pci_dev *dev)
@@ -174,24 +172,15 @@ int hinic3_pci_sriov_disable(struct pci_dev *dev)
return 0;
}
-int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
-{
#ifdef CONFIG_PCI_IOV
- struct hinic3_sriov_info *sriov_info = NULL;
- struct hinic3_event_info event = {0};
- void *hwdev = NULL;
- int pre_existing_vfs = 0;
- int err = 0;
-
- sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
- hwdev = hinic3_get_hwdev_by_pcidev(dev);
- if (!hwdev) {
- sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
- return -EPERM;
- }
+int hinic3_pci_sriov_check(struct hinic3_sriov_info *sriov_info, struct pci_dev *dev, int num_vfs)
+{
+ int pre_existing_vfs;
+ int err;
if (test_and_set_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state)) {
- sdk_err(&dev->dev, "SR-IOV enable in process, please wait, num_vfs %d\n",
+ sdk_err(&dev->dev,
+ "SR-IOV enable in process, please wait, num_vfs %d\n",
num_vfs);
return -EPERM;
}
@@ -202,6 +191,7 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
clear_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state);
return -ERANGE;
}
+
if (pre_existing_vfs && pre_existing_vfs != num_vfs) {
err = hinic3_pci_sriov_disable(dev);
if (err) {
@@ -213,6 +203,29 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
return num_vfs;
}
+ return 0;
+}
+#endif
+
+int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
+{
+#ifdef CONFIG_PCI_IOV
+ struct hinic3_sriov_info *sriov_info = NULL;
+ struct hinic3_event_info event = {0};
+ void *hwdev = NULL;
+ int err = 0;
+
+ sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
+ hwdev = hinic3_get_hwdev_by_pcidev(dev);
+ if (!hwdev) {
+ sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
+ return -EPERM;
+ }
+
+ err = hinic3_pci_sriov_check(sriov_info, dev, num_vfs);
+ if (err != 0)
+ return err;
+
err = hinic3_init_vf_hw(hwdev, 1, (u16)num_vfs);
if (err) {
sdk_err(&dev->dev, "Failed to init vf in hardware before enable sriov, error %d\n",
@@ -262,6 +275,3 @@ int hinic3_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
else
return hinic3_pci_sriov_enable(dev, num_vfs);
}
-
-/*lint -restore*/
-
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h
index 4a640ad..becb5c7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h
@@ -7,13 +7,13 @@
#include <linux/pci.h>
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
-ssize_t hinic3_sriov_totalvfs_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-ssize_t hinic3_sriov_numvfs_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-ssize_t hinic3_sriov_numvfs_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count);
+ssize_t sriov_totalvfs_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+ssize_t sriov_numvfs_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+ssize_t sriov_numvfs_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
enum hinic3_sriov_state {
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c b/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c
index f8aea696..be83022 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c
@@ -117,3 +117,4 @@ u64 ossl_get_real_time(void)
tv_msec = (u64)tv.tv_sec * MSEC_PER_SEC + (u64)tv.tv_usec / USEC_PER_MSEC;
return tv_msec;
}
+
diff --git a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
index 9e8fc75..01ab739 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
@@ -10,6 +10,10 @@
#define OVS_PORT_NUM_MAX BOND_PORT_MAX_NUM
#define DEFAULT_ROCE_BOND_FUNC 0xFFFFFFFF
+#define BOND_ID_IS_VALID(_id) \
+ (((_id) >= BOND_FIRST_ID) && ((_id) <= BOND_MAX_ID))
+#define BOND_ID_IS_INVALID(_id) (!(BOND_ID_IS_VALID(_id)))
+
enum bond_group_id {
BOND_FIRST_ID = 1,
BOND_MAX_ID = 4,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
index e7e16fc..f9737ea 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
@@ -52,6 +52,8 @@ enum scenes_id_define {
SCENES_ID_STORAGE_ROCE = 6,
SCENES_ID_COMPUTE_ROCE = 7,
SCENES_ID_STORAGE_TOE = 8,
+ SCENES_ID_COMPUTE_DPU = 100,
+ SCENES_ID_COMPUTE_SMART_NIC = 101,
SCENES_ID_MAX
};
@@ -122,13 +124,18 @@ struct cfg_cmd_dev_cap {
u8 srv_multi_host_mode;
u8 virtio_vq_size;
- u32 rsvd_func3[5];
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 lro_enable;
+ u8 os_hot_replace;
+
+ u32 rsvd_func3[4];
/* l2nic */
u16 nic_max_sq_id;
u16 nic_max_rq_id;
u16 nic_default_num_queues;
- u16 rsvd1_nic;
+ u16 outband_vlan_cfg_en;
u32 rsvd2_nic[2];
/* RoCE */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
index d9f67e2..6c5b995 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
@@ -37,7 +37,7 @@ static inline void hinic3_cpu_to_be32(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -59,7 +59,7 @@ static inline void hinic3_be32_to_cpu(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -86,52 +86,16 @@ static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
sge->len = (u32)len;
}
-#ifdef HW_CONVERT_ENDIAN
#define hinic3_hw_be32(val) (val)
#define hinic3_hw_cpu32(val) (val)
#define hinic3_hw_cpu16(val) (val)
-#else
-#define hinic3_hw_be32(val) cpu_to_be32(val)
-#define hinic3_hw_cpu32(val) be32_to_cpu(val)
-#define hinic3_hw_cpu16(val) be16_to_cpu(val)
-#endif
static inline void hinic3_hw_be32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_be32(*mem);
- mem++;
- }
-#endif
}
static inline void hinic3_hw_cpu32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_cpu32(*mem);
- mem++;
- }
-#endif
}
int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
@@ -149,6 +113,8 @@ int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
/* func_attr.glb_func_idx, global function index */
u16 hinic3_global_func_id(void *hwdev);
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id);
+
/* func_attr.p2p_idx, belongs to which pf */
u8 hinic3_pf_id_of_vf(void *hwdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
index 9a9bfe2..e36ba1d 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
@@ -219,5 +219,7 @@ void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
const char **hinic3_get_uld_names(void);
+int hinic3_lld_init(void);
+void hinic3_lld_exit(void);
#endif
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
index 97d34f0..4cd6f94 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
@@ -43,6 +43,10 @@ enum mag_cmd {
MAG_CMD_GET_XSFP_PRESENT = 62, /* get xsfp present status @see mag_cmd_get_xsfp_present */
MAG_CMD_SET_XSFP_RW = 63, /* sfp/qsfp single byte read/write, @see mag_cmd_set_xsfp_rw */
MAG_CMD_CFG_XSFP_TEMPERATURE = 64, /* get xsfp temp @see mag_cmd_sfp_temp_out_info */
+ /**< set xsfp tlv info @see struct mag_cmd_set_xsfp_tlv_req */
+ MAG_CMD_SET_XSFP_TLV_INFO = 65,
+ /**< get xsfp tlv info @see struct drv_tag_mag_cmd_get_xsfp_tlv_rsp */
+ MAG_CMD_GET_XSFP_TLV_INFO = 66,
/* Event reported 100-149 */
MAG_CMD_WIRE_EVENT = 100,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
index caaba5d..d33b9f4 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
@@ -31,17 +31,28 @@ enum board_type_define_e {
BOARD_TYPE_STRG_2X100G_ROCE_AA = 42, /* 2X100G SmartIO ROCE_AA Card */
BOARD_TYPE_CAL_2X25G_NIC_75MPPS = 100, /* 2X25G ETH Standard card 75MPPS */
BOARD_TYPE_CAL_2X25G_NIC_40MPPS = 101, /* 2X25G ETH Standard card 40MPPS */
- BOARD_TYPE_CAL_2X100G_DPU = 102, /* 2x100G DPU Card */
+ BOARD_TYPE_CAL_2X100G_DPU_VL = 102, /* 2x100G DPU Card */
BOARD_TYPE_CAL_4X25G_NIC_120MPPS = 105, /* 4X25G ETH Standard card 120MPPS */
BOARD_TYPE_CAL_4X25G_COMSTORAGE = 106, /* 4X25GE compute storage Onboard Card */
BOARD_TYPE_CAL_2X32G_FC_HBA = 110, /* 2X32G FC HBA card */
BOARD_TYPE_CAL_2X16G_FC_HBA = 111, /* 2X16G FC HBA card */
BOARD_TYPE_CAL_2X100G_NIC_120MPPS = 115, /* 2X100G ETH Standard card 120MPPS */
- BOARD_TYPE_CAL_2X25G_DPU = 116, /* 2x25G DPU Card */
- BOARD_TYPE_CAL_4X25G_DPU = 118, /* 4x25G DPU Card */
+ BOARD_TYPE_CAL_2X25G_DPU_BD = 116, /* 2x25G DPU Card */
+ BOARD_TYPE_CAL_2X100G_TCE_BACKPLANE = 117,
+ BOARD_TYPE_CAL_4X25G_DPU_VL = 118, /* 4x25G DPU Card */
+ BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS = 119,
+ BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS = 120,
+ BOARD_TYPE_CAL_6X25G_DPU_VL = 121, /* 6x25G DPU Card */
+ BOARD_TYPE_CAL_4X25G_DPU_BD = 122,
+ BOARD_TYPE_CAL_2X25G_NIC_4HOST = 123,
+ BOARD_TYPE_CAL_2X10G_LOW_POWER = 125,
+ BOARD_TYPE_CAL_2X200G_NIC_INTERNET = 127,
+ BOARD_TYPE_CAL_1X100GR2_OCP = 129, /* 1X100G ETH Standard card */
+ BOARD_TYPE_CAL_2X200G_DPU_VL = 130,
BOARD_TYPE_CLD_2X100G_SDI5_1 = 170, /* 2X100G SDI 5.1 Card */
BOARD_TYPE_CLD_2X25G_SDI5_0_LITE = 171, /* 2x25G SDI5.0 Lite Card */
BOARD_TYPE_CLD_2X100G_SDI5_0 = 172, /* 2x100G SDI5.0 Card */
+ BOARD_TYPE_CLD_4X25G_SDI5_0_C = 175,
BOARD_TYPE_MAX_INDEX = 0xFF
};
@@ -49,23 +60,62 @@ static inline u32 spu_board_type_valid(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
- ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
}
static inline int board_type_is_sdi(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_1) ||
((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
- ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0);
+ ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C);
+}
+
+static inline int board_type_is_dpu_spu(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
}
static inline int board_type_is_dpu(u32 board_type)
{
- return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_6X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
+}
+
+/* 此接口判断是否是分布式存储的标卡以及计算的标卡(含ROCE特性),
+ * 仅用于LLDP TX功能冲突命令字处理的判断
+ */
+static inline int board_type_is_compute(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_75MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_40MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_NIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_COMSTORAGE) ||
+ ((board_type) == BOARD_TYPE_CAL_2X10G_LOW_POWER) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_NIC_INTERNET) ||
+ ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_4HOST) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_NIC_120MPPS);
+}
+
+/* 此接口判断服务器输入reboot网卡是否需要复位 */
+static inline int board_type_is_multi_socket(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP);
}
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
index 291e475..4d4d543 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
@@ -4,8 +4,95 @@
#ifndef MPU_CMD_BASE_DEFS_H
#define MPU_CMD_BASE_DEFS_H
-#include "mgmt_msg_base.h"
-#include "comm_defs.h"
+/** MPU CMD MODULE TYPE */
+enum hinic3_mod_type {
+ HINIC3_MOD_COMM = 0, /* HW communication module */
+ HINIC3_MOD_L2NIC = 1, /* L2NIC module */
+ HINIC3_MOD_ROCE = 2,
+ HINIC3_MOD_PLOG = 3,
+ HINIC3_MOD_TOE = 4,
+ HINIC3_MOD_FLR = 5,
+ HINIC3_MOD_VROCE = 6,
+ HINIC3_MOD_CFGM = 7, /* Configuration management */
+ HINIC3_MOD_CQM = 8,
+ HINIC3_MOD_VMSEC = 9,
+ COMM_MOD_FC = 10,
+ HINIC3_MOD_OVS = 11,
+ HINIC3_MOD_DSW = 12,
+ HINIC3_MOD_MIGRATE = 13,
+ HINIC3_MOD_HILINK = 14,
+ HINIC3_MOD_CRYPT = 15, /* secure crypto module */
+ HINIC3_MOD_VIO = 16,
+ HINIC3_MOD_IMU = 17,
+ HINIC3_MOD_DFX = 18, /* DFX */
+ HINIC3_MOD_HW_MAX = 19, /* hardware max module id */
+ /* Software module id, for PF/VF and multi-host */
+ HINIC3_MOD_SW_FUNC = 20,
+ HINIC3_MOD_MAX,
+};
+
+/* func reset的flag ,用于指示清理哪种资源 */
+enum func_reset_flag_e {
+ RES_TYPE_FLUSH_BIT = 0,
+ RES_TYPE_MQM,
+ RES_TYPE_SMF,
+ RES_TYPE_PF_BW_CFG,
+
+ RES_TYPE_COMM = 10,
+ RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_NIC,
+ RES_TYPE_OVS,
+ RES_TYPE_VBS,
+ RES_TYPE_ROCE,
+ RES_TYPE_FC,
+ RES_TYPE_TOE,
+ RES_TYPE_IPSEC,
+ RES_TYPE_MAX,
+};
+
+#define HINIC3_COMM_RES \
+ ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
+ (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
+ (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
+
+#define HINIC3_NIC_RES (1 << RES_TYPE_NIC)
+#define HINIC3_OVS_RES (1 << RES_TYPE_OVS)
+#define HINIC3_VBS_RES (1 << RES_TYPE_VBS)
+#define HINIC3_ROCE_RES (1 << RES_TYPE_ROCE)
+#define HINIC3_FC_RES (1 << RES_TYPE_FC)
+#define HINIC3_TOE_RES (1 << RES_TYPE_TOE)
+#define HINIC3_IPSEC_RES (1 << RES_TYPE_IPSEC)
+
+/* MODE OVS、NIC、UNKNOWN */
+#define HINIC3_WORK_MODE_OVS 0
+#define HINIC3_WORK_MODE_UNKNOWN 1
+#define HINIC3_WORK_MODE_NIC 2
+
+#define DEVICE_TYPE_L2NIC 0
+#define DEVICE_TYPE_NVME 1
+#define DEVICE_TYPE_VIRTIO_NET 2
+#define DEVICE_TYPE_VIRTIO_BLK 3
+#define DEVICE_TYPE_VIRTIO_VSOCK 4
+#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
+#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
+#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
+#define DEVICE_TYPE_VIRTIO_HPC 8
+#define DEVICE_TYPE_VIRTIO_FS 9
+
+#define IS_STORAGE_DEVICE_TYPE(dev_type) \
+ ((dev_type) == DEVICE_TYPE_VIRTIO_BLK || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_BLK_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_SCSI_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_FS)
+
+#define MGMT_MSG_CMD_OP_SET 1
+#define MGMT_MSG_CMD_OP_GET 0
+
+#define MGMT_MSG_CMD_OP_START 1
+#define MGMT_MSG_CMD_OP_STOP 0
+
+#define HOT_REPLACE_PARTITION_NUM 2
enum hinic3_svc_type {
SVC_T_COMM = 0,
@@ -23,4 +110,54 @@ enum hinic3_svc_type {
SVC_T_MAX,
};
+/**
+ * Common header control information of the COMM message interaction
+ * command word between the driver and PF
+ * struct mgmt_msg_head and struct comm_info_head are the same structure
+ */
+struct mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+/**
+ * Common header control information of the COMM message interaction
+ * command word between the driver and PF
+ */
+struct comm_info_head {
+ /** response status code, 0: success, others: error code */
+ u8 status;
+
+ /** firmware version for command */
+ u8 version;
+
+ /** response aeq number, unused for now */
+ u8 rep_aeq_num;
+ u8 rsvd[5];
+};
+
+static inline u32 get_function_partition(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM;
+}
+
+static inline u32 is_primary_function(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0;
+}
+
+static inline u32 mpu_nic_get_primary_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ function_id : (function_id - port_num);
+}
+
+// when func_id is in partition 0/1, it will get its another func_id in partition 1/0
+static inline u32 mpu_nic_get_backup_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ (function_id + port_num) : (function_id - port_num);
+}
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
index a8e2d63..3841bb5 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
@@ -91,6 +91,10 @@ enum hinic3_mgmt_cmd {
* @see comm_read_ucode_sm_resp
*/
COMM_MGMT_CMD_CLEAR_LOG, /**< clear log @see comm_cmd_clear_log_s */
+ COMM_MGMT_CMD_UCODE_SM_COUNTER_PER,
+ /**< get ucode sm counter @see struct comm_read_ucode_sm_per_req
+ * @see struct comm_read_ucode_sm_per_resp
+ */
COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140, /* check if switch workmode reserved
* @see comm_cmd_check_if_switch_workmode
@@ -103,6 +107,7 @@ enum hinic3_mgmt_cmd {
COMM_MGMT_CMD_CPI_TCAM_DBG, /* enable or disable the scheduled cpi tcam task,
* set task interval time @see comm_cmd_cpi_tcam_dbg_s
*/
+ COMM_MGMT_CMD_LLDP_TX_FUNC_SET,
COMM_MGMT_CMD_SECTION_RSVD_0 = 160, /**< rsvd0 section */
COMM_MGMT_CMD_SECTION_RSVD_1 = 170, /**< rsvd1 section */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
index 674603d..698730f 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
@@ -338,7 +338,8 @@ struct comm_cmd_get_fw_version {
struct mgmt_msg_head head;
u16 fw_type; /**< firmware type @see enum hinic3_fw_ver_type */
- u16 rsvd1;
+ u16 fw_dfx_vld : 1; /**< 0: release, 1: debug */
+ u16 rsvd1 : 15;
u8 ver[HINIC3_FW_VERSION_LEN]; /**< firmware version */
u8 time[HINIC3_FW_COMPILE_TIME_LEN]; /**< firmware compile time */
};
@@ -430,6 +431,22 @@ struct comm_cmd_bdf_info {
u8 rsvd2[5];
};
+struct mpu_pcie_pf_info {
+ u32 device_id; /**< device id */
+ u32 vendor_id; /**< vendor id */
+};
+
+struct mpu_pcie_device_info {
+ u8 status;
+ u8 version;
+ u8 rep_aeq_num;
+ u8 rsvd[5];
+
+ struct mpu_pcie_pf_info pf_info[32];
+ u32 bus_id; /**< bus id */
+ u32 pf_num; /**< pf index */
+};
+
#define TABLE_INDEX_MAX 129
struct sml_table_id_info {
u8 node_id;
@@ -446,6 +463,13 @@ struct comm_cmd_sdi_info {
u32 cfg_sdi_mode; /**< host mode, 0:normal 1:virtual machine 2:bare metal */
};
+struct comm_cmd_root_ctx_load_req {
+ struct comm_info_head head;
+ u32 func_id; /**< function id */
+ u32 smf_id; /**< smf id */
+ u32 queue_id; /**< queue id */
+};
+
#define HINIC_OVS_BOND_DEFAULT_ID 1
struct hinic3_hw_bond_infos {
u8 bond_id;
@@ -685,6 +709,28 @@ struct comm_read_ucode_sm_resp {
u64 val2;
};
+#define PER_REQ_MAX_DATA_LEN 0x600
+
+struct comm_read_ucode_sm_per_req {
+ struct mgmt_msg_head msg_head;
+
+ u32 tbl_type;
+ u32 count_id;
+};
+
+struct comm_read_ucode_sm_per_resp {
+ struct mgmt_msg_head msg_head;
+
+ u8 data[PER_REQ_MAX_DATA_LEN];
+};
+
+struct ucode_sm_counter_get_info {
+ u32 width_type;
+ u32 tbl_type;
+ unsigned int base_count;
+ unsigned int count_num;
+};
+
enum log_type {
MPU_LOG_CLEAR = 0,
SMU_LOG_CLEAR = 1,
@@ -693,6 +739,11 @@ enum log_type {
ALL_LOG_CLEAR = 4,
};
+struct comm_cmd_clear_log {
+ struct comm_info_head head;
+ u32 type; /**< log type @see enum log_type */
+};
+
#define ABLESWITCH 1
#define IMABLESWITCH 2
enum switch_workmode_op {
@@ -717,6 +768,14 @@ struct comm_cmd_check_if_switch_workmode {
u32 rsvd3[3];
};
+struct comm_cmd_switch_workmode {
+ struct mgmt_msg_head head;
+ u8 operation;
+ u8 work_mode;
+ u16 rsvd1[3];
+ u32 rsvd2[3];
+};
+
#define MIG_NOR_VM_ONE_MAX_SGE_MEM (64 * 8)
#define MIG_NOR_VM_ONE_MAX_MEM (MIG_NOR_VM_ONE_MAX_SGE_MEM + 16)
#define MIG_VM_MAX_SML_ENTRY_NUM 24
@@ -755,6 +814,15 @@ struct cmd_get_bdf_info_s {
#define CPI_TCAM_DBG_CMD_TYPE_SET 0
#define CPI_TCAM_DBG_CMD_TYPE_GET 1
+struct comm_cmd_cpi_tcam_dbg {
+ struct comm_info_head head;
+ u8 type;
+ u8 set_bitmap;
+ u8 enable;
+ u8 rsvd;
+ u32 time_interval;
+};
+
#define UDIE_ID_DATA_LEN 8
#define TDIE_ID_DATA_LEN 18
struct comm_cmd_get_die_id {
@@ -808,6 +876,12 @@ struct cmd_query_fw {
u32 len; /**< length */
};
+struct comm_cmd_get_cfg_info_t {
+ struct comm_info_head head;
+ u8 rsvd[8];
+ u8 info[64]; /**< flash config info */
+};
+
struct nic_cmd_get_uart_log_info {
struct comm_info_head head;
struct {
@@ -969,6 +1043,7 @@ enum comm_virtio_dev_type {
COMM_VIRTIO_NET_TYPE = 0,
COMM_VIRTIO_BLK_TYPE = 1,
COMM_VIRTIO_SCSI_TYPE = 4,
+ COMM_VIRTIO_FS_TYPE = 5,
};
struct comm_virtio_dev_cmd {
@@ -1030,6 +1105,13 @@ struct cmd_patch_sram_optimize {
u32 data[4]; /**< reserved */
};
+struct comm_cmd_con_sel_sta {
+ struct comm_info_head head;
+ u8 valid;
+ u8 host_id; /**< host id, range[0,3] */
+ u8 rsvd[2];
+};
+
/* ncsi counter */
struct nsci_counter_in_info_s {
struct comm_info_head head;
@@ -1082,7 +1164,9 @@ struct comm_cmd_ncsi_settings {
u8 lldp_over_ncsi_enable;
u8 lldp_over_mctp_enable;
u32 magicwd;
- u8 rsvd[8];
+ u8 lldp_tx_enable;
+ u8 rsvd[3];
+ u32 crc;
struct tag_ncsi_chan_info ncsi_chan_info;
};
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
index fde8617..1ee44a8 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
@@ -114,6 +114,14 @@ struct tag_ncsi_client_info {
#define AEN_CTRL_CONFIG_REQ_SHIFT 1
#define AEN_CTRL_DRV_CHANGE_SHIFT 2
+/* AEN Type */
+enum aen_type_e {
+ AEN_LINK_STATUS_CHANGE_TYPE = 0x0,
+ AEN_CONFIG_REQUIRED_TYPE = 0x1,
+ OEM_AEN_CONFIG_REQUEST_TYPE = 0x80,
+ AEN_TYPE_MAX = 0x100
+};
+
/* get link status 0x0A */
#define GET_LINK_STATUS_REQ_LEN 0
#define GET_LINK_STATUS_RSP_LEN 16
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
index 0bd168c..5b2bdc8 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
@@ -36,6 +36,7 @@ enum nic_rss_hash_type {
#define NIC_RX_MODE_BC 0x04
#define NIC_RX_MODE_MC_ALL 0x08
#define NIC_RX_MODE_PROMISC 0x10
+#define NIC_RX_DB_COS_MAX 0x4
/* IEEE 802.1Qaz std */
#define NIC_DCB_COS_MAX 0x8
@@ -52,4 +53,7 @@ enum nic_rss_hash_type {
#define NIC_DCB_PRIO_STRICT 0x1
#define NIC_DCB_MAX_PFC_NUM 0x4
+
+#define NIC_ETS_PERCENT_WEIGHT 100
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
index 801aeed..5476287 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
@@ -23,7 +23,11 @@
#define VRAM_CQM_BITMAP_BASE "B"
#define VRAM_NIC_DCB "DCB"
+#define VRAM_NIC_MHOST_MGMT "MHOST_MGMT"
#define VRAM_NIC_VRAM "NIC_VRAM"
+#define VRAM_NIC_IRQ_VRAM "NIC_IRQ"
+
+#define VRAM_NIC_MQM "NM"
#define VRAM_VBS_BASE_IOCB "BASE_IOCB"
#define VRAM_VBS_EX_IOCB "EX_IOCB"
@@ -32,6 +36,9 @@
#define VRAM_VBS_VOLQ_MTT "VOLQ_MTT"
#define VRAM_VBS_VOLQ_MTT_PAGE "MTT_PAGE"
+#define VRAM_OVS_PORT_CONF "OVS_PORT_CONF"
+#define VRAM_OVS_DFX_MGR "OVS_DFX_MGR"
+
#define VRAM_VROCE_ENTRY_POOL "VROCE_ENTRY"
#define VRAM_VROCE_GROUP_POOL "VROCE_GROUP"
#define VRAM_VROCE_UUID "VROCE_UUID"
@@ -42,6 +49,17 @@
#define VRAM_VROCE_DEV "VROCE_DEV"
#define VRAM_VROCE_RGROUP_HT_CNT "RGROUP_CNT"
#define VRAM_VROCE_RACL_HT_CNT "RACL_CNT"
+#define VRAM_VROCE_MQM_ENQC "VROCE_MQM_ENQC"
+
+#define VRAM_DTOE_NUMA_MEM "DTOE_NUMA"
+#define VRAM_DTOE_CARD_MEM "DTOE_CARD"
+#define VRAM_DTOE_CONN_MEM "DTOE_CONN"
+#define VRAM_DTOE_SUB_LEN 10
+
+#define VRAM_VROCE_MIG_ENTRY_POOL "VROCE_MIG_ENTRY"
+#define VRAM_VROCE_MIG_ENTRY_HT_CNT "MIG_ENTRY_CNT"
+
+#define VRAM_VBS_DEV_INDEX "VBS_INDEX"
#define VRAM_NAME_APPLY_LEN 64
@@ -55,11 +73,16 @@ enum KUP_HOOK_POINT {
PRE_FREEZE,
FREEZE_TO_KILL,
PRE_UPDATE_KERNEL,
- FLUSH_DURING_KUP,
POST_UPDATE_KERNEL,
UNFREEZE_TO_RUN,
POST_RUN,
KUP_HOOK_MAX,
};
+#define hi_vram_kalloc(name, size) 0
+#define hi_vram_kfree(vaddr, name, size)
+#define get_use_vram_flag(void) 0
+#define vram_get_kexec_flag(void) 0
+#define hi_vram_get_gfp_vram(void) 0
+
#endif /* VRAM_COMMON_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
similarity index 79%
rename from drivers/net/ethernet/huawei/hinic3/mag_cmd.h
rename to drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
index 9649503..c8533e5 100644
--- a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
@@ -9,6 +9,7 @@
/* serdes cmd struct define */
#define CMD_ARRAY_BUF_SIZE 64
#define SERDES_CMD_DATA_BUF_SIZE 512
+#define RATE_MBPS_TO_GBPS 1000
struct serdes_in_info {
u32 chip_id : 16;
u32 macro_id : 16;
@@ -127,6 +128,7 @@ enum mag_cmd_cnt_type {
MAG_RX_PCS_E_BLK_CNT = 5,
MAG_RX_PCS_DEC_ERR_BLK_CNT = 6,
MAG_RX_PCS_LANE_BIP_ERR_CNT = 7,
+ MAG_RX_RSFEC_ERR_CW_CNT = 8,
MAG_CNT_NUM
};
@@ -208,7 +210,9 @@ struct mag_cmd_get_port_info {
u32 supported_mode;
u32 advertised_mode;
- u8 rsvd2[8];
+ u32 supported_fec_mode;
+ u16 bond_speed;
+ u8 rsvd2[2];
};
#define MAG_CMD_OPCODE_GET 0
@@ -330,8 +334,8 @@ struct mag_cmd_cfg_fec_mode {
u8 port_id;
u8 opcode; /* 0:get fec mode 1:set fec mode */
- u8 fec;
- u8 rsvd0;
+ u8 advertised_fec;
+ u8 supported_fec;
};
/* speed */
@@ -641,7 +645,7 @@ struct mag_cmd_event_port_info {
u32 cable_length; /* 1/3/5m */
u8 cable_temp; /* temp */
u8 max_speed; /* Maximum rate of an optical module */
- u8 sfp_type; /* sfp/qsfp */
+ u8 sfp_type; /* sfp/qsfp/dsfp */
u8 rsvd1;
u32 power[4]; /* Optical Power */
@@ -678,6 +682,10 @@ struct mag_cmd_event_port_info {
u8 rsvd3[360];
};
+struct mag_cmd_rsfec_stats {
+ u32 rx_err_lane_phy;
+};
+
struct mag_cmd_port_stats {
u64 mac_tx_fragment_pkt_num;
u64 mac_tx_undersize_pkt_num;
@@ -913,10 +921,222 @@ struct mag_cmd_sfp_temp_in_info {
};
struct mag_cmd_sfp_temp_out_info {
- struct mgmt_msg_head head; /* 8B */
- s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
- s32 max_temp; /* Chip optical module threshold */
- s32 min_temp; /* Chip optical module threshold */
+ struct mgmt_msg_head head; /* 8B */
+ s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
+ s32 max_temp; /* Chip optical module threshold */
+ s32 min_temp; /* Chip optical module threshold */
+};
+
+#define XSFP_CMIS_PARSE_PAGE_NUM 6
+#define XSFP_CMIS_INFO_MAX_SIZE 1536
+#define QSFP_CMIS_PAGE_SIZE 128
+#define QSFP_CMIS_MAX_CHANNEL_NUM 0x8
+
+/* Lower: Control and Essentials, Upper: Administrative Information */
+#define QSFP_CMIS_PAGE_00H 0x00
+/* Advertising */
+#define QSFP_CMIS_PAGE_01H 0x01
+/* Module and lane Thresholds */
+#define QSFP_CMIS_PAGE_02H 0x02
+/* User EEPROM */
+#define QSFP_CMIS_PAGE_03H 0x03
+/* Laser Capabilities Advertising (Page 04h, Optional) */
+#define QSFP_CMIS_PAGE_04H 0x04
+#define QSFP_CMIS_PAGE_05H 0x05
+/* Lane and Data Path Control */
+#define QSFP_CMIS_PAGE_10H 0x10
+/* Lane Status */
+#define QSFP_CMIS_PAGE_11H 0x11
+#define QSFP_CMIS_PAGE_12H 0x12
+
+#define MGMT_TLV_U8_SIZE 1
+#define MGMT_TLV_U16_SIZE 2
+#define MGMT_TLV_U32_SIZE 4
+
+#define MGMT_TLV_GET_U8(addr) (*((u8 *)(void *)(addr)))
+#define MGMT_TLV_SET_U8(addr, value) \
+ ((*((u8 *)(void *)(addr))) = ((u8)(value)))
+
+#define MGMT_TLV_GET_U16(addr) (*((u16 *)(void *)(addr)))
+#define MGMT_TLV_SET_U16(addr, value) \
+ ((*((u16 *)(void *)(addr))) = ((u16)(value)))
+
+#define MGMT_TLV_GET_U32(addr) (*((u32 *)(void *)(addr)))
+#define MGMT_TLV_SET_U32(addr, value) \
+ ((*((u32 *)(void *)(addr))) = ((u32)(value)))
+
+#define MGMT_TLV_TYPE_END 0xFFFF
+
+enum mag_xsfp_type {
+ MAG_XSFP_TYPE_PAGE = 0x01,
+ MAG_XSFP_TYPE_WIRE_TYPE = 0x02,
+ MAG_XSFP_TYPE_END = MGMT_TLV_TYPE_END
+};
+
+struct qsfp_cmis_lower_page_00_s {
+ u8 resv0[14];
+ u8 temperature_msb;
+ u8 temperature_lsb;
+ u8 volt_supply[2];
+ u8 resv1[67];
+ u8 media_type;
+ u8 electrical_interface_id;
+ u8 media_interface_id;
+ u8 lane_count;
+ u8 resv2[39];
+};
+
+struct qsfp_cmis_upper_page_00_s {
+ u8 identifier;
+ u8 vendor_name[16];
+ u8 vendor_oui[3];
+ u8 vendor_pn[16];
+ u8 vendor_rev[2];
+ u8 vendor_sn[16];
+ u8 date_code[8];
+ u8 clei_code[10];
+ u8 power_character[2];
+ u8 cable_len;
+ u8 connector;
+ u8 copper_cable_attenuation[6];
+ u8 near_end_implementation;
+ u8 far_end_config;
+ u8 media_technology;
+ u8 resv0[43];
+};
+
+struct qsfp_cmis_upper_page_01_s {
+ u8 firmware_rev[2];
+ u8 hardware_rev[2];
+ u8 smf_len_km;
+ u8 om5_len;
+ u8 om4_len;
+ u8 om3_len;
+ u8 om2_len;
+ u8 resv0;
+ u8 wavelength[2];
+ u8 wavelength_tolerance[2];
+ u8 pages_implement;
+ u8 resv1[16];
+ u8 monitor_implement[2];
+ u8 resv2[95];
+};
+
+struct qsfp_cmis_upper_page_02_s {
+ u8 temperature_high_alarm[2];
+ u8 temperature_low_alarm[2];
+ u8 temperature_high_warn[2];
+ u8 temperature_low_warn[2];
+ u8 volt_high_alarm[2];
+ u8 volt_low_alarm[2];
+ u8 volt_high_warn[2];
+ u8 volt_low_warn[2];
+ u8 resv0[32];
+ u8 tx_power_high_alarm[2];
+ u8 tx_power_low_alarm[2];
+ u8 tx_power_high_warn[2];
+ u8 tx_power_low_warn[2];
+ u8 tx_bias_high_alarm[2];
+ u8 tx_bias_low_alarm[2];
+ u8 tx_bias_high_warn[2];
+ u8 tx_bias_low_warn[2];
+ u8 rx_power_high_alarm[2];
+ u8 rx_power_low_alarm[2];
+ u8 rx_power_high_warn[2];
+ u8 rx_power_low_warn[2];
+ u8 resv1[56];
+};
+
+struct qsfp_cmis_upper_page_03_s {
+ u8 resv0[QSFP_CMIS_PAGE_SIZE]; /* Reg 128-255: Upper Memory: Page 03H */
+};
+
+struct qsfp_cmis_upper_page_10_s {
+ u8 resv0[2]; /* Reg 128-129: Upper Memory: Page 10H */
+ u8 tx_disable; /* Reg 130: Tx disable, 0b=enabled, 1b=disabled */
+ u8 resv1[125]; /* Reg 131-255 */
+};
+
+struct qsfp_cmis_upper_page_11_s {
+ u8 resv0[7];
+ u8 tx_fault;
+ u8 tx_los;
+ u8 resv1[10];
+ u8 rx_los;
+ u8 resv2[6];
+ u8 tx_power[16];
+ u8 tx_bias[16];
+ u8 rx_power[16];
+ u8 resv3[54];
+};
+
+struct qsfp_cmis_info_s {
+ struct qsfp_cmis_lower_page_00_s lower_page_00;
+ struct qsfp_cmis_upper_page_00_s upper_page_00;
+ struct qsfp_cmis_upper_page_01_s upper_page_01;
+ struct qsfp_cmis_upper_page_02_s upper_page_02;
+ struct qsfp_cmis_upper_page_10_s upper_page_10;
+ struct qsfp_cmis_upper_page_11_s upper_page_11;
+};
+
+struct qsfp_cmis_comm_power_s {
+ u32 chl_power[QSFP_CMIS_MAX_CHANNEL_NUM];
+};
+
+struct qsfp_cmis_wire_info_s {
+ struct qsfp_cmis_comm_power_s rx_power;
+ u8 rx_los;
+ u8 resv0[3];
+};
+
+struct mgmt_tlv_info {
+ u16 type;
+ u16 length;
+ u8 value[];
+};
+
+struct mag_cmd_set_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 tlv_buf[];
+};
+
+struct mag_cmd_set_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+};
+
+struct tag_mag_cmd_get_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd;
+ u16 rsp_buf_len;
+};
+
+struct mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[];
+};
+
+struct parse_tlv_info {
+ u8 tlv_page_info[XSFP_CMIS_INFO_MAX_SIZE + 1];
+ u32 tlv_page_info_len;
+ u32 tlv_page_num[XSFP_CMIS_PARSE_PAGE_NUM];
+ u32 wire_type;
+ u8 id;
+};
+
+struct drv_tag_mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[XSFP_CMIS_INFO_MAX_SIZE];
};
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h b/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
deleted file mode 100644
index 257bf67..0000000
--- a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : mgmt_msg_base.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef MGMT_MSG_BASE_H
-#define MGMT_MSG_BASE_H
-
-#define MGMT_MSG_CMD_OP_SET 1
-#define MGMT_MSG_CMD_OP_GET 0
-
-#define MGMT_MSG_CMD_OP_START 1
-#define MGMT_MSG_CMD_OP_STOP 0
-
-struct mgmt_msg_head {
- u8 status;
- u8 version;
- u8 rsvd0[6];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
deleted file mode 100644
index abcfa27..0000000
--- a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2001-2021, Huawei Tech. Co., Ltd.
- * File Name : nic_cfg_comm.h
- * Version : Initial Draft
- * Description : nic config common header file
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef NIC_CFG_COMM_H
-#define NIC_CFG_COMM_H
-
-#include <linux/types.h>
-
-/* rss */
-#define HINIC3_RSS_TYPE_VALID_SHIFT 23
-#define HINIC3_RSS_TYPE_TCP_IPV6_EXT_SHIFT 24
-#define HINIC3_RSS_TYPE_IPV6_EXT_SHIFT 25
-#define HINIC3_RSS_TYPE_TCP_IPV6_SHIFT 26
-#define HINIC3_RSS_TYPE_IPV6_SHIFT 27
-#define HINIC3_RSS_TYPE_TCP_IPV4_SHIFT 28
-#define HINIC3_RSS_TYPE_IPV4_SHIFT 29
-#define HINIC3_RSS_TYPE_UDP_IPV6_SHIFT 30
-#define HINIC3_RSS_TYPE_UDP_IPV4_SHIFT 31
-
-#define HINIC3_RSS_TYPE_SET(val, member) (((u32)(val) & 0x1) << HINIC3_RSS_TYPE_##member##_SHIFT)
-#define HINIC3_RSS_TYPE_GET(val, member) (((u32)(val) >> HINIC3_RSS_TYPE_##member##_SHIFT) & 0x1)
-
-enum nic_rss_hash_type {
- NIC_RSS_HASH_TYPE_XOR = 0,
- NIC_RSS_HASH_TYPE_TOEP,
-
- NIC_RSS_HASH_TYPE_MAX /* MUST BE THE LAST ONE */
-};
-
-#define NIC_RSS_INDIR_SIZE 256
-#define NIC_RSS_KEY_SIZE 40
-
-/* *
- * Definition of the NIC receiving mode
- */
-#define NIC_RX_MODE_UC 0x01
-#define NIC_RX_MODE_MC 0x02
-#define NIC_RX_MODE_BC 0x04
-#define NIC_RX_MODE_MC_ALL 0x08
-#define NIC_RX_MODE_PROMISC 0x10
-
-/* IEEE 802.1Qaz std */
-#define NIC_DCB_COS_MAX 0x8
-#define NIC_DCB_UP_MAX 0x8
-#define NIC_DCB_TC_MAX 0x8
-#define NIC_DCB_PG_MAX 0x8
-#define NIC_DCB_TSA_SP 0x0
-#define NIC_DCB_TSA_CBS 0x1
-#define NIC_DCB_TSA_ETS 0x2
-#define NIC_DCB_DSCP_NUM 0x8
-#define NIC_DCB_IP_PRI_MAX 0x40
-
-#define NIC_DCB_PRIO_DWRR 0x0
-#define NIC_DCB_PRIO_STRICT 0x1
-
-#define NIC_DCB_MAX_PFC_NUM 0x4
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
similarity index 77%
rename from drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
rename to drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
index c35bc82..b0114a0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
- * File Name : hinic3_comm_cmd.h
+ * File Name : hinic3_nic_mpu_cmd.h
* Version : Initial Draft
* Created : 2019/4/25
* Last Modified :
@@ -33,10 +33,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_CFG_LOCAL_LRO_STATE,
HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
+ HINIC3_NIC_CMD_SET_FUNC_ER_FWD_ID,
HINIC3_NIC_CMD_SET_RQ_CI_CTX,
- /* MAC & VLAN CFG */
+ /* MAC & VLAN CFG & VXLAN CFG */
HINIC3_NIC_CMD_GET_MAC = 20,
HINIC3_NIC_CMD_SET_MAC,
HINIC3_NIC_CMD_DEL_MAC,
@@ -47,6 +48,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_VLAN_FILTER_EN,
HINIC3_NIC_CMD_SET_RX_VLAN_OFFLOAD,
HINIC3_NIC_CMD_SMAC_CHECK_STATE,
+ HINIC3_NIC_CMD_OUTBAND_SET_FUNC_VLAN,
+ HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+
+ HINIC3_NIC_CMD_RX_RATE_CFG,
+ HINIC3_NIC_CMD_WR_ORDERING_CFG,
/* SR-IOV */
HINIC3_NIC_CMD_CFG_VF_VLAN = 40,
@@ -63,6 +69,7 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC,
/* IP checksum error packets, enable rss quadruple hash */
HINIC3_NIC_CMD_IPCS_ERR_RSS_ENABLE_OP = 66,
+ HINIC3_NIC_CMD_GTP_INNER_PARSE_STATUS,
/* PPA/FDIR */
HINIC3_NIC_CMD_ADD_TC_FLOW = 80,
@@ -78,6 +85,10 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_CFG_PPA_FLUSH,
HINIC3_NIC_CMD_SET_FDIR_STATUS,
HINIC3_NIC_CMD_GET_PPA_COUNTER,
+ HINIC3_NIC_CMD_SET_FUNC_FLOW_BIFUR_ENABLE,
+ HINIC3_NIC_CMD_SET_BOND_MASK,
+ HINIC3_NIC_CMD_GET_BLOCK_TC_FLOWS,
+ HINIC3_NIC_CMD_GET_BOND_MASK,
/* PORT CFG */
HINIC3_NIC_CMD_SET_PORT_ENABLE = 100,
@@ -96,6 +107,8 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_QOS_PORT_CFG,
HINIC3_NIC_CMD_QOS_MAP_CFG,
HINIC3_NIC_CMD_FORCE_PKT_DROP,
+ HINIC3_NIC_CMD_CFG_TX_PROMISC_SKIP = 114,
+ HINIC3_NIC_CMD_SET_PORT_FLOW_BIFUR_ENABLE = 117,
HINIC3_NIC_CMD_TX_PAUSE_EXCP_NOTICE = 118,
HINIC3_NIC_CMD_INQUIRT_PAUSE_CFG = 119,
@@ -118,6 +131,10 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_UCAPTURE_OPT = 160, /* TODO: move to roce */
HINIC3_NIC_CMD_SET_VHD_CFG,
+ /* OUT OF BAND */
+ HINIC3_NIC_CMD_GET_OUTBAND_CFG = 170, /* Get outband vlan cfg info */
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE, /* Outband vlan cfg info report */
+
/* TODO: move to HILINK */
HINIC3_NIC_CMD_GET_PORT_STAT = 200,
HINIC3_NIC_CMD_CLEAN_PORT_STAT,
@@ -138,24 +155,23 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_LINK_ERR_EVENT,
HINIC3_NIC_CMD_SET_LED_STATUS,
- HINIC3_NIC_CMD_MAX = 256,
-};
+ /* mig */
+ HINIC3_NIC_CMD_MIG_SET_CEQ_CTRL = 230,
+ HINIC3_NIC_CMD_MIG_CFG_MSIX_INFO,
+ HINIC3_NIC_CMD_MIG_CFG_FUNC_VAT_TBL,
+ HINIC3_NIC_CMD_MIG_GET_VF_INFO,
+ HINIC3_NIC_CMD_MIG_CHK_MBX_EMPTY,
+ HINIC3_NIC_CMD_MIG_SET_VPORT_ENABLE,
+ HINIC3_NIC_CMD_MIG_CFG_SQ_CI,
+ HINIC3_NIC_CMD_MIG_CFG_RSS_TBL,
+ HINIC3_NIC_CMD_MIG_CFG_MAC_TBL,
+ HINIC3_NIC_CMD_MIG_TMP_SET_CMDQ_CTX,
-/* NIC CMDQ MODE */
-enum hinic3_ucode_cmd {
- HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
- HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
- HINIC3_UCODE_CMD_ARM_SQ,
- HINIC3_UCODE_CMD_ARM_RQ,
- HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_SET_IQ_ENABLE,
- HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
- HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
- HINIC3_UCODE_CMD_PPA_HASH_TABLE,
- HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_OSHR_CMD_ACTIVE_FUNCTION = 240,
+
+ HINIC3_NIC_CMD_GET_RQ_INFO = 241,
+
+ HINIC3_NIC_CMD_MAX = 256,
};
#endif /* HINIC3_NIC_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
new file mode 100644
index 0000000..5c28573
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
@@ -0,0 +1,1440 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+
+#ifndef NIC_MPU_CMD_DEFS_H
+#define NIC_MPU_CMD_DEFS_H
+
+#include "nic_cfg_comm.h"
+#include "mpu_cmd_base_defs.h"
+
+#ifndef ETH_ALEN
+#define ETH_ALEN 6
+#endif
+
+#define HINIC3_CMD_OP_SET 1
+#define HINIC3_CMD_OP_GET 0
+
+#define HINIC3_CMD_OP_ADD 1
+#define HINIC3_CMD_OP_DEL 0
+
+#define NIC_TCAM_BLOCK_LARGE_NUM 256
+#define NIC_TCAM_BLOCK_LARGE_SIZE 16
+
+#define TRAFFIC_BIFUR_MODEL_TYPE 2
+
+#define NIC_TCAM_FLOW_BIFUR_FLAG (1 << 0)
+
+#ifndef BIT
+#define BIT(n) (1UL << (n))
+#endif
+
+enum nic_feature_cap {
+ NIC_F_CSUM = BIT(0),
+ NIC_F_SCTP_CRC = BIT(1),
+ NIC_F_TSO = BIT(2),
+ NIC_F_LRO = BIT(3),
+ NIC_F_UFO = BIT(4),
+ NIC_F_RSS = BIT(5),
+ NIC_F_RX_VLAN_FILTER = BIT(6),
+ NIC_F_RX_VLAN_STRIP = BIT(7),
+ NIC_F_TX_VLAN_INSERT = BIT(8),
+ NIC_F_VXLAN_OFFLOAD = BIT(9),
+ NIC_F_IPSEC_OFFLOAD = BIT(10),
+ NIC_F_FDIR = BIT(11),
+ NIC_F_PROMISC = BIT(12),
+ NIC_F_ALLMULTI = BIT(13),
+ NIC_F_XSFP_REPORT = BIT(14),
+ NIC_F_VF_MAC = BIT(15),
+ NIC_F_RATE_LIMIT = BIT(16),
+ NIC_F_RXQ_RECOVERY = BIT(17),
+ NIC_F_TX_COMPACT_WQE_OL = BIT(19),
+ NIC_F_RX_COMPACT_CQE = BIT(20),
+ NIC_F_HTN_CMDQ = BIT(21),
+};
+
+#define NIC_F_ALL_MASK 0x7FBFFFF /* 使能所有属性 */
+
+struct hinic3_mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+#define NIC_MAX_FEATURE_QWORD 4
+struct hinic3_cmd_feature_nego {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 1: set, 0: get */
+ u8 rsvd;
+ u64 s_feature[NIC_MAX_FEATURE_QWORD];
+};
+
+struct hinic3_port_mac_set {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 rsvd1;
+ u8 mac[ETH_ALEN];
+};
+
+struct hinic3_port_mac_update {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 rsvd1;
+ u8 old_mac[ETH_ALEN];
+ u16 rsvd2;
+ u8 new_mac[ETH_ALEN];
+};
+
+struct hinic3_vport_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 state; /* 0--disable, 1--enable */
+ u8 rsvd2[3];
+};
+
+struct hinic3_port_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 state; /* 0--disable, 1--enable */
+ u8 rsvd2[3];
+};
+
+#define HINIC3_SET_PORT_CAR_PROFILE 0
+#define HINIC3_SET_PORT_CAR_STATE 1
+#define HINIC3_GET_PORT_CAR_LIMIT_SPEED 2
+
+struct hinic3_port_car_info {
+ u32 cir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
+ u32 xir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
+ u32 cbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
+ u32 xbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
+};
+
+struct hinic3_cmd_set_port_car {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode; /* 0--set car profile, 1--set car state */
+ u8 state; /* 0--disable, 1--enable */
+ u8 level;
+
+ struct hinic3_port_car_info car;
+};
+
+struct hinic3_cmd_clear_qp_resource {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_cmd_cache_out_qp_resource {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_port_stats_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_vport_stats {
+ u64 tx_unicast_pkts_vport;
+ u64 tx_unicast_bytes_vport;
+ u64 tx_multicast_pkts_vport;
+ u64 tx_multicast_bytes_vport;
+ u64 tx_broadcast_pkts_vport;
+ u64 tx_broadcast_bytes_vport;
+
+ u64 rx_unicast_pkts_vport;
+ u64 rx_unicast_bytes_vport;
+ u64 rx_multicast_pkts_vport;
+ u64 rx_multicast_bytes_vport;
+ u64 rx_broadcast_pkts_vport;
+ u64 rx_broadcast_bytes_vport;
+
+ u64 tx_discard_vport;
+ u64 rx_discard_vport;
+ u64 tx_err_vport;
+ u64 rx_err_vport;
+};
+
+struct hinic3_phy_fpga_port_stats {
+ u64 mac_rx_total_octs_port;
+ u64 mac_tx_total_octs_port;
+ u64 mac_rx_under_frame_pkts_port;
+ u64 mac_rx_frag_pkts_port;
+ u64 mac_rx_64_oct_pkts_port;
+ u64 mac_rx_127_oct_pkts_port;
+ u64 mac_rx_255_oct_pkts_port;
+ u64 mac_rx_511_oct_pkts_port;
+ u64 mac_rx_1023_oct_pkts_port;
+ u64 mac_rx_max_oct_pkts_port;
+ u64 mac_rx_over_oct_pkts_port;
+ u64 mac_tx_64_oct_pkts_port;
+ u64 mac_tx_127_oct_pkts_port;
+ u64 mac_tx_255_oct_pkts_port;
+ u64 mac_tx_511_oct_pkts_port;
+ u64 mac_tx_1023_oct_pkts_port;
+ u64 mac_tx_max_oct_pkts_port;
+ u64 mac_tx_over_oct_pkts_port;
+ u64 mac_rx_good_pkts_port;
+ u64 mac_rx_crc_error_pkts_port;
+ u64 mac_rx_broadcast_ok_port;
+ u64 mac_rx_multicast_ok_port;
+ u64 mac_rx_mac_frame_ok_port;
+ u64 mac_rx_length_err_pkts_port;
+ u64 mac_rx_vlan_pkts_port;
+ u64 mac_rx_pause_pkts_port;
+ u64 mac_rx_unknown_mac_frame_port;
+ u64 mac_tx_good_pkts_port;
+ u64 mac_tx_broadcast_ok_port;
+ u64 mac_tx_multicast_ok_port;
+ u64 mac_tx_underrun_pkts_port;
+ u64 mac_tx_mac_frame_ok_port;
+ u64 mac_tx_vlan_pkts_port;
+ u64 mac_tx_pause_pkts_port;
+};
+
+struct hinic3_port_stats {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ struct hinic3_phy_fpga_port_stats stats;
+};
+
+struct hinic3_cmd_vport_stats {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u32 stats_size;
+ u32 rsvd1;
+ struct hinic3_vport_stats stats;
+ u64 rsvd2[6];
+};
+
+struct hinic3_cmd_qpn {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 base_qpn;
+};
+
+enum hinic3_func_tbl_cfg_bitmap {
+ FUNC_CFG_INIT,
+ FUNC_CFG_RX_BUF_SIZE,
+ FUNC_CFG_MTU,
+};
+
+struct hinic3_func_tbl_cfg {
+ u16 rx_wqe_buf_size;
+ u16 mtu;
+ u32 rsvd[9];
+};
+
+struct hinic3_cmd_set_func_tbl {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd;
+
+ u32 cfg_bitmap;
+ struct hinic3_func_tbl_cfg tbl_cfg;
+};
+
+struct hinic3_cmd_cons_idx_attr {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_idx;
+ u8 dma_attr_off;
+ u8 pending_limit;
+ u8 coalescing_time;
+ u8 intr_en;
+ u16 intr_idx;
+ u32 l2nic_sqn;
+ u32 rsvd;
+ u64 ci_addr;
+};
+
+union sm_tbl_args {
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } mac_table_arg;
+ struct {
+ u32 er_id;
+ u32 vlan_id;
+ } vlan_elb_table_arg;
+ struct {
+ u32 func_id;
+ } vlan_filter_arg;
+ struct {
+ u32 mc_id;
+ } mc_elb_arg;
+ struct {
+ u32 func_id;
+ } func_tbl_arg;
+ struct {
+ u32 port_id;
+ } port_tbl_arg;
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } fdir_io_table_arg;
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } flexq_table_arg;
+ u32 args[4];
+};
+
+struct hinic3_rq_cqe_ctx {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 cqe_type;
+ u8 rq_id;
+ u8 threshold_cqe_num;
+ u8 rsvd1;
+
+ u16 msix_entry_idx;
+ u16 rsvd2;
+
+ u32 ci_addr_hi;
+ u32 ci_addr_lo;
+
+ u16 timer_loop;
+ u16 rsvd3;
+};
+
+#define DFX_SM_TBL_BUF_MAX (768)
+
+struct nic_cmd_dfx_sm_table {
+ struct hinic3_mgmt_msg_head msg_head;
+ u32 tbl_type;
+ union sm_tbl_args args;
+ u8 tbl_buf[DFX_SM_TBL_BUF_MAX];
+};
+
+struct hinic3_cmd_vlan_offload {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 vlan_offload;
+ u8 rsvd1[5];
+};
+
+/* ucode capture cfg info */
+struct nic_cmd_capture_info {
+ struct hinic3_mgmt_msg_head msg_head;
+ u32 op_type;
+ u32 func_port;
+ u32 is_en_trx;
+ u32 offset_cos;
+ u32 data_vlan;
+};
+
+struct hinic3_cmd_lro_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u8 lro_ipv4_en;
+ u8 lro_ipv6_en;
+ u8 lro_max_pkt_len; /* unit is 1K */
+ u8 resv2[13];
+};
+
+struct hinic3_cmd_lro_timer {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 opcode; /* 1: set timer value, 0: get timer value */
+ u8 rsvd1;
+ u16 rsvd2;
+ u32 timer;
+};
+
+struct hinic3_cmd_local_lro_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 state; /* 0: disable, 1: enable */
+};
+
+struct hinic3_cmd_gtp_inner_parse_status {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 status; /* 0: disable, 1: enable */
+};
+
+struct hinic3_cmd_vf_vlan_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u16 vlan_id;
+ u8 qos;
+ u8 rsvd2[5];
+};
+
+struct hinic3_cmd_spoofchk_set {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 state;
+ u8 rsvd1;
+};
+
+struct hinic3_cmd_tx_rate_cfg {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 rsvd1;
+ u8 direct;
+ u32 min_rate;
+ u32 max_rate;
+ u8 rsvd2[8];
+};
+
+struct hinic3_cmd_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+ u8 port_type;
+ u8 autoneg_cap;
+ u8 autoneg_state;
+ u8 duplex;
+ u8 speed;
+ u8 fec;
+ u16 rsvd2;
+ u32 rsvd3[4];
+};
+
+struct hinic3_cmd_register_vf {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 op_register; /* 0 - unregister, 1 - register */
+ u8 rsvd1[3];
+ u32 support_extra_feature;
+ u8 rsvd2[32];
+};
+
+struct hinic3_cmd_link_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 state;
+ u16 rsvd1;
+};
+
+struct hinic3_cmd_vlan_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 outband_defvid_flag;
+ u16 vlan_id;
+ u8 blacklist_flag;
+ u8 rsvd2;
+};
+
+#define VLAN_BLACKLIST_ENABLE 1
+#define VLAN_BLACKLIST_DISABLE 0
+
+struct hinic3_cmd_vxlan_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 cfg_mode;
+ u16 vxlan_port;
+ u16 rsvd2;
+};
+
+/* set vlan filter */
+struct hinic3_cmd_set_vlan_filter {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 resvd[2];
+ u32 vlan_filter_ctrl; /* bit0:vlan filter en; bit1:broadcast_filter_en */
+};
+
+struct hinic3_cmd_link_ksettings_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+
+ u32 valid_bitmap;
+ u8 speed; /* enum nic_speed_level */
+ u8 autoneg; /* 0 - off, 1 - on */
+ u8 fec; /* 0 - RSFEC, 1 - BASEFEC, 2 - NOFEC */
+ u8 rsvd2[21]; /* reserved for duplex, port, etc. */
+};
+
+struct mpu_lt_info {
+ u8 node;
+ u8 inst;
+ u8 entry_size;
+ u8 rsvd;
+ u32 lt_index;
+ u32 offset;
+ u32 len;
+};
+
+struct nic_mpu_lt_opera {
+ struct hinic3_mgmt_msg_head msg_head;
+ struct mpu_lt_info net_lt_cmd;
+ u8 data[100];
+};
+
+struct hinic3_force_pkt_drop {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port;
+ u8 rsvd1[3];
+};
+
+struct hinic3_rx_mode_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u32 rx_mode;
+};
+
+/* rss */
+struct hinic3_rss_context_table {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u32 context;
+};
+
+struct hinic3_cmd_rss_engine_type {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 hash_engine;
+ u8 rsvd1[4];
+};
+
+struct hinic3_cmd_rss_hash_key {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u8 key[NIC_RSS_KEY_SIZE];
+};
+
+struct hinic3_rss_indir_table {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 indir[NIC_RSS_INDIR_SIZE];
+};
+
+#define NIC_RSS_CMD_TEMP_ALLOC 0x01
+#define NIC_RSS_CMD_TEMP_FREE 0x02
+
+struct hinic3_rss_template_mgmt {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 cmd;
+ u8 template_id;
+ u8 rsvd1[4];
+};
+
+struct hinic3_cmd_rss_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 rss_en;
+ u8 rq_priority_number;
+ u8 prio_tc[NIC_DCB_COS_MAX];
+ u16 num_qps;
+ u16 rsvd1;
+};
+
+struct hinic3_dcb_state {
+ u8 dcb_on;
+ u8 default_cos;
+ u8 trust;
+ u8 rsvd1;
+ u8 pcp2cos[NIC_DCB_UP_MAX];
+ u8 dscp2cos[64];
+ u32 rsvd2[7];
+};
+
+struct hinic3_cmd_vf_dcb_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ struct hinic3_dcb_state state;
+};
+
+struct hinic3_up_ets_cfg { /* delet */
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+
+ u8 cos_tc[NIC_DCB_COS_MAX];
+ u8 tc_bw[NIC_DCB_TC_MAX];
+ u8 cos_prio[NIC_DCB_COS_MAX];
+ u8 cos_bw[NIC_DCB_COS_MAX];
+ u8 tc_prio[NIC_DCB_TC_MAX];
+};
+
+#define CMD_QOS_ETS_COS_TC BIT(0)
+#define CMD_QOS_ETS_TC_BW BIT(1)
+#define CMD_QOS_ETS_COS_PRIO BIT(2)
+#define CMD_QOS_ETS_COS_BW BIT(3)
+#define CMD_QOS_ETS_TC_PRIO BIT(4)
+#define CMD_QOS_ETS_TC_RATELIMIT BIT(5)
+struct hinic3_cmd_ets_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 1 - set, 0 - get */
+ /* bit0 - cos_tc, bit1 - tc_bw, bit2 - cos_prio, bit3 - cos_bw, bit4 - tc_prio */
+ u8 cfg_bitmap;
+ u8 rsvd;
+
+ u8 cos_tc[NIC_DCB_COS_MAX];
+ u8 tc_bw[NIC_DCB_TC_MAX];
+ u8 cos_prio[NIC_DCB_COS_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 cos_bw[NIC_DCB_COS_MAX];
+ u8 tc_prio[NIC_DCB_TC_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 rate_limit[NIC_DCB_TC_MAX];
+};
+
+struct hinic3_cmd_set_dcb_state {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 op_code; /* 0 - get dcb state, 1 - set dcb state */
+ u8 state; /* 0 - disable, 1 - enable dcb */
+ u8 port_state; /* 0 - disable, 1 - enable dcb */
+ u8 rsvd[7];
+};
+
+#define PFC_BIT_MAP_NUM 8
+struct hinic3_cmd_set_pfc {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 0:get 1: set pfc_en 2: set pfc_bitmap 3: set all */
+ u8 pfc_en; /* pfc_en 和 pfc_bitmap 必须同时设置 */
+ u8 pfc_bitmap;
+ u8 rsvd[4];
+};
+
+#define CMD_QOS_PORT_TRUST BIT(0)
+#define CMD_QOS_PORT_DFT_COS BIT(1)
+struct hinic3_cmd_qos_port_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 0 - get, 1 - set */
+ u8 cfg_bitmap; /* bit0 - trust, bit1 - dft_cos */
+ u8 rsvd0;
+
+ u8 trust;
+ u8 dft_cos;
+ u8 rsvd1[18];
+};
+
+#define MAP_COS_MAX_NUM 8
+#define CMD_QOS_MAP_PCP2COS BIT(0)
+#define CMD_QOS_MAP_DSCP2COS BIT(1)
+struct hinic3_cmd_qos_map_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 op_code;
+ u8 cfg_bitmap; /* bit0 - pcp2cos, bit1 - dscp2cos */
+ u16 rsvd0;
+
+ u8 pcp2cos[8]; /* 8 must be configured together */
+ /* If the dscp2cos parameter is set to 0xFF, the MPU ignores the DSCP priority,
+ * Multiple mappings between DSCP values and CoS values can be configured at a time.
+ */
+ u8 dscp2cos[64];
+ u32 rsvd1[4];
+};
+
+struct hinic3_cos_up_map {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 cos_valid_mask; /* every bit indicate index of map is valid 1 or not 0 */
+ u16 rsvd1;
+
+ /* user priority in cos(index:cos, value: up pri) */
+ u8 map[NIC_DCB_UP_MAX];
+};
+
+struct hinic3_cmd_pause_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode;
+ u16 rsvd1;
+ u8 auto_neg;
+ u8 rx_pause;
+ u8 tx_pause;
+ u8 rsvd2[5];
+};
+
+struct nic_cmd_pause_inquiry_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 valid;
+
+ u32 type; /* 1: set, 2: get */
+
+ u32 cos_id;
+
+ u32 rx_inquiry_pause_drop_pkts_en;
+ u32 rx_inquiry_pause_period_ms;
+ u32 rx_inquiry_pause_times;
+ /* rx pause Detection Threshold, Default PAUSE_FRAME_THD_10G/25G/40G/100 */
+ u32 rx_inquiry_pause_frame_thd;
+ u32 rx_inquiry_tx_total_pkts;
+
+ u32 tx_inquiry_pause_en; /* tx pause detect enable */
+ u32 tx_inquiry_pause_period_ms; /* tx pause Default Detection Period 200ms */
+ u32 tx_inquiry_pause_times; /* tx pause Default Times Period 5 */
+ u32 tx_inquiry_pause_frame_thd; /* tx pause Detection Threshold */
+ u32 tx_inquiry_rx_total_pkts;
+ u32 rsvd[3];
+};
+
+/* pfc/pause Storm TX exception reporting */
+struct nic_cmd_tx_pause_notice {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 tx_pause_except; /* 1: abnormality,0: normal */
+ u32 except_level;
+ u32 rsvd;
+};
+
+#define HINIC3_CMD_OP_FREE 0
+#define HINIC3_CMD_OP_ALLOC 1
+
+struct hinic3_cmd_cfg_qps {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 1: alloc qp, 0: free qp */
+ u8 rsvd1;
+ u16 num_qps;
+ u16 rsvd2;
+};
+
+struct hinic3_cmd_led_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port;
+ u8 type;
+ u8 mode;
+ u8 rsvd1;
+};
+
+struct hinic3_cmd_port_loopback {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode;
+ u8 mode;
+ u8 en;
+ u32 rsvd1[2];
+};
+
+struct hinic3_cmd_get_light_module_abs {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 abs_status; /* 0:present, 1:absent */
+ u8 rsv[2];
+};
+
+#define STD_SFP_INFO_MAX_SIZE 640
+struct hinic3_cmd_get_std_sfp_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 wire_type;
+ u16 eeprom_len;
+ u32 rsvd;
+ u8 sfp_info[STD_SFP_INFO_MAX_SIZE];
+};
+
+struct hinic3_cable_plug_event {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 plugged; /* 0: unplugged, 1: plugged */
+ u8 port_id;
+};
+
+struct nic_cmd_mac_info {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 valid_bitmap;
+ u16 rsvd;
+
+ u8 host_id[32];
+ u8 port_id[32];
+ u8 mac_addr[192];
+};
+
+struct nic_cmd_set_tcam_enable {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 tcam_enable;
+ u8 rsvd1;
+ u32 rsvd2;
+};
+
+struct nic_cmd_set_fdir_status {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 pkt_type_en;
+ u8 pkt_type;
+ u8 qid;
+ u8 rsvd2;
+};
+
+#define HINIC3_TCAM_BLOCK_ENABLE 1
+#define HINIC3_TCAM_BLOCK_DISABLE 0
+#define HINIC3_MAX_TCAM_RULES_NUM 4096
+
+/* tcam block type, according to tcam block size */
+enum {
+ NIC_TCAM_BLOCK_TYPE_LARGE = 0, /* block_size: 16 */
+ NIC_TCAM_BLOCK_TYPE_SMALL, /* block_size: 0 */
+ NIC_TCAM_BLOCK_TYPE_MAX
+};
+
+/* alloc tcam block input struct */
+struct nic_cmd_ctrl_tcam_block_in {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
+ /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
+ u8 tcam_type;
+ u16 tcam_block_index;
+ /* Size of the block that the driver wants to allocate
+ * Interface returned by the UP to the driver,
+ * indicating the size of the allocated TCAM block supported by the UP
+ */
+ u16 alloc_block_num;
+};
+
+/* alloc tcam block output struct */
+struct nic_cmd_ctrl_tcam_block_out {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
+ /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
+ u8 tcam_type;
+ u16 tcam_block_index;
+ /* Size of the block that the driver wants to allocate
+ * Interface returned by the UP to the driver,
+ * indicating the size of the allocated TCAM block supported by the UP
+ */
+ u16 mpu_alloc_block_size;
+};
+
+struct nic_cmd_flush_tcam_rules {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u16 rsvd;
+};
+
+struct nic_cmd_dfx_fdir_tcam_block_table {
+ struct hinic3_mgmt_msg_head head;
+ u8 tcam_type;
+ u8 valid;
+ u16 tcam_block_index;
+ u16 use_function_id;
+ u16 rsvd;
+};
+
+struct tcam_result {
+ u32 qid;
+ u32 rsvd;
+};
+
+#define TCAM_FLOW_KEY_SIZE (44)
+
+struct tcam_key_x_y {
+ u8 x[TCAM_FLOW_KEY_SIZE];
+ u8 y[TCAM_FLOW_KEY_SIZE];
+};
+
+struct nic_tcam_cfg_rule {
+ u32 index;
+ struct tcam_result data;
+ struct tcam_key_x_y key;
+};
+
+#define TCAM_RULE_FDIR_TYPE 0
+#define TCAM_RULE_PPA_TYPE 1
+
+struct nic_cmd_fdir_add_rule {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 type;
+ u8 fdir_ext; /* 0x1: flow bifur en bit */
+ struct nic_tcam_cfg_rule rule;
+};
+
+struct nic_cmd_fdir_del_rules {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 type;
+ u8 rsvd;
+ u32 index_start;
+ u32 index_num;
+};
+
+struct nic_cmd_fdir_get_rule {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 index;
+ u8 valid;
+ u8 type;
+ u16 rsvd;
+ struct tcam_key_x_y key;
+ struct tcam_result data;
+ u64 packet_count;
+ u64 byte_count;
+};
+
+struct nic_cmd_fdir_get_block_rules {
+ struct hinic3_mgmt_msg_head head;
+ u8 tcam_block_type; // only NIC_TCAM_BLOCK_TYPE_LARGE
+ u8 tcam_table_type; // TCAM_RULE_PPA_TYPE or TCAM_RULE_FDIR_TYPE
+ u16 tcam_block_index;
+ u8 valid[NIC_TCAM_BLOCK_LARGE_SIZE];
+ struct tcam_key_x_y key[NIC_TCAM_BLOCK_LARGE_SIZE];
+ struct tcam_result data[NIC_TCAM_BLOCK_LARGE_SIZE];
+};
+
+struct hinic3_tcam_key_ipv4_mem {
+ u32 rsvd1 : 1;
+ u32 bifur_flag : 2;
+ u32 model : 1;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+ u32 sipv4_h : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+ u32 dipv4_h : 16;
+ u32 sipv4_l : 16;
+ u32 vlan_id : 15;
+ u32 vlan_flag : 1;
+ u32 dipv4_l : 16;
+ u32 rsvd3;
+ u32 dport : 16;
+ u32 rsvd4 : 16;
+ u32 rsvd5 : 16;
+ u32 sport : 16;
+ u32 outer_sipv4_h : 16;
+ u32 rsvd6 : 16;
+ u32 outer_dipv4_h : 16;
+ u32 outer_sipv4_l : 16;
+ u32 vni_h : 16;
+ u32 outer_dipv4_l : 16;
+ u32 rsvd7 : 16;
+ u32 vni_l : 16;
+};
+
+union hinic3_tag_tcam_ext_info {
+ struct {
+ u32 id : 16; /* id */
+ u32 type : 4; /* type: 0-func, 1-vmdq, 2-port, 3-rsvd, 4-trunk, 5-dp, 6-mc */
+ u32 host_id : 3;
+ u32 rss_q_num : 8; /* rss queue num */
+ u32 ext : 1;
+ } bs;
+ u32 value;
+};
+
+struct hinic3_tcam_key_ipv6_mem {
+ u32 bifur_flag : 2;
+ u32 vlan_flag : 1;
+ u32 outer_ip_type : 1;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+ u32 sipv6_key0 : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+ u32 sipv6_key2 : 16;
+ u32 sipv6_key1 : 16;
+ u32 sipv6_key4 : 16;
+ u32 sipv6_key3 : 16;
+ u32 sipv6_key6 : 16;
+ u32 sipv6_key5 : 16;
+ u32 dport : 16;
+ u32 sipv6_key7 : 16;
+ u32 dipv6_key0 : 16;
+ u32 sport : 16;
+ u32 dipv6_key2 : 16;
+ u32 dipv6_key1 : 16;
+ u32 dipv6_key4 : 16;
+ u32 dipv6_key3 : 16;
+ u32 dipv6_key6 : 16;
+ u32 dipv6_key5 : 16;
+ u32 rsvd2 : 16;
+ u32 dipv6_key7 : 16;
+};
+
+struct hinic3_tcam_key_vxlan_ipv6_mem {
+ u32 rsvd1 : 4;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+
+ u32 dipv6_key0 : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+
+ u32 dipv6_key2 : 16;
+ u32 dipv6_key1 : 16;
+
+ u32 dipv6_key4 : 16;
+ u32 dipv6_key3 : 16;
+
+ u32 dipv6_key6 : 16;
+ u32 dipv6_key5 : 16;
+
+ u32 dport : 16;
+ u32 dipv6_key7 : 16;
+
+ u32 rsvd2 : 16;
+ u32 sport : 16;
+
+ u32 outer_sipv4_h : 16;
+ u32 rsvd3 : 16;
+
+ u32 outer_dipv4_h : 16;
+ u32 outer_sipv4_l : 16;
+
+ u32 vni_h : 16;
+ u32 outer_dipv4_l : 16;
+
+ u32 rsvd4 : 16;
+ u32 vni_l : 16;
+};
+
+struct tag_tcam_key {
+ union {
+ struct hinic3_tcam_key_ipv4_mem key_info;
+ struct hinic3_tcam_key_ipv6_mem key_info_ipv6;
+ struct hinic3_tcam_key_vxlan_ipv6_mem key_info_vxlan_ipv6;
+ };
+
+ union {
+ struct hinic3_tcam_key_ipv4_mem key_mask;
+ struct hinic3_tcam_key_ipv6_mem key_mask_ipv6;
+ struct hinic3_tcam_key_vxlan_ipv6_mem key_mask_vxlan_ipv6;
+ };
+};
+
+enum {
+ PPA_TABLE_ID_CLEAN_CMD = 0,
+ PPA_TABLE_ID_ADD_CMD,
+ PPA_TABLE_ID_DEL_CMD,
+ FDIR_TABLE_ID_ADD_CMD,
+ FDIR_TABLE_ID_DEL_CMD,
+ PPA_TABEL_ID_MAX
+};
+
+struct hinic3_ppa_cfg_table_id_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u16 cmd;
+ u16 table_id;
+ u16 rsvd1;
+};
+
+struct hinic3_ppa_cfg_ppa_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 ppa_en;
+ u8 ppa_miss_drop_en;
+};
+
+struct hinic3_func_flow_bifur_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 func_id;
+ u8 flow_bifur_en;
+ u8 rsvd[5];
+};
+
+struct hinic3_port_flow_bifur_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 port_id;
+ u8 flow_bifur_en;
+ u8 flow_bifur_type; /* 0->vf bifur, 2->traffic bifur */
+ u8 rsvd[4];
+};
+
+struct hinic3_bond_mask_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 func_id;
+ u8 bond_mask;
+ u8 bond_en;
+ u8 func_valid;
+ u8 rsvd[3];
+};
+
+struct hinic3_func_er_value_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 vf_id;
+ u16 er_fwd_id;
+};
+
+#define HINIC3_TX_SET_PROMISC_SKIP 0
+#define HINIC3_TX_GET_PROMISC_SKIP 1
+
+#define HINIC3_GET_TRAFFIC_BIFUR_STATE 0
+#define HINIC3_SET_TRAFFIC_BIFUR_STATE 1
+
+struct hinic3_tx_promisc_cfg {
+ struct hinic3_mgmt_msg_head msg_head;
+ u8 port_id;
+ u8 promisc_skip_en; /* 0: disable tx promisc replication, 1: enable */
+ u8 opcode; /* 0: set, 1: get */
+ u8 rsvd1;
+};
+
+struct hinic3_ppa_cfg_mode_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u8 ppa_mode;
+ u8 qpc_func_nums;
+ u16 base_qpc_func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_ppa_flush_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u8 flush_en; /* 0 flush done, 1 in flush operation */
+ u8 rsvd1;
+};
+
+struct hinic3_ppa_fdir_query_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u32 index;
+ u32 rsvd;
+ u64 pkt_nums;
+ u64 pkt_bytes;
+};
+
+/* BIOS CONF */
+enum {
+ NIC_NVM_DATA_SET = BIT(0), /* 1-save, 0-read */
+ NIC_NVM_DATA_PXE = BIT(1),
+ NIC_NVM_DATA_VLAN = BIT(2),
+ NIC_NVM_DATA_VLAN_PRI = BIT(3),
+ NIC_NVM_DATA_VLAN_ID = BIT(4),
+ NIC_NVM_DATA_WORK_MODE = BIT(5),
+ NIC_NVM_DATA_PF_TX_SPEED_LIMIT = BIT(6),
+ NIC_NVM_DATA_GE_MODE = BIT(7),
+ NIC_NVM_DATA_AUTO_NEG = BIT(8),
+ NIC_NVM_DATA_LINK_FEC = BIT(9),
+ NIC_NVM_DATA_PF_ADAPTIVE_LINK = BIT(10),
+ NIC_NVM_DATA_SRIOV_CONTROL = BIT(11),
+ NIC_NVM_DATA_EXTEND_MODE = BIT(12),
+ NIC_NVM_DATA_LEGACY_VLAN = BIT(13),
+ NIC_NVM_DATA_LEGACY_VLAN_PRI = BIT(14),
+ NIC_NVM_DATA_LEGACY_VLAN_ID = BIT(15),
+ NIC_NVM_DATA_RESET = BIT(31),
+};
+
+#define BIOS_CFG_SIGNATURE 0x1923E518
+#define BIOS_OP_CFG_ALL(op_code_val) \
+ ((((op_code_val) >> 1) & (0xFFFFFFFF)) != 0)
+#define BIOS_OP_CFG_WRITE(op_code_val) \
+ ((((op_code_val) & NIC_NVM_DATA_SET)) != 0)
+#define BIOS_OP_CFG_PXE_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PXE) != 0)
+#define BIOS_OP_CFG_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN) != 0)
+#define BIOS_OP_CFG_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_ID) != 0)
+#define BIOS_OP_CFG_WORK_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_WORK_MODE) != 0)
+#define BIOS_OP_CFG_PF_BW(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_TX_SPEED_LIMIT) != 0)
+#define BIOS_OP_CFG_GE_SPEED(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_GE_MODE) != 0)
+#define BIOS_OP_CFG_AUTO_NEG(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_AUTO_NEG) != 0)
+#define BIOS_OP_CFG_LINK_FEC(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LINK_FEC) != 0)
+#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_ADAPTIVE_LINK) != 0)
+#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_SRIOV_CONTROL) != 0)
+#define BIOS_OP_CFG_EXTEND_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_EXTEND_MODE) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_ID) != 0)
+#define BIOS_OP_CFG_RST_DEF_SET(op_code_val) \
+ (((op_code_val) & (u32)NIC_NVM_DATA_RESET) != 0)
+
+
+#define NIC_BIOS_CFG_MAX_PF_BW 100
+
+struct nic_legacy_vlan_cfg {
+ /* Legacy mode PXE VLAN enable: 0 - disable 1 - enable */
+ u8 pxe_vlan_en : 1;
+ /* Legacy mode PXE VLAN priority: 0-7 */
+ u8 pxe_vlan_pri : 3;
+ /* Legacy mode PXE VLAN ID 1-4094 */
+ u16 pxe_vlan_id : 12;
+};
+
+/* Note: This structure must be 4-byte aligned. */
+struct nic_bios_cfg {
+ u32 signature;
+ u8 pxe_en;
+ u8 extend_mode;
+ struct nic_legacy_vlan_cfg nlvc;
+ u8 pxe_vlan_en;
+ u8 pxe_vlan_pri;
+ u16 pxe_vlan_id;
+ u32 service_mode;
+ u32 pf_tx_bw;
+ u8 speed;
+ u8 auto_neg;
+ u8 lanes;
+ u8 fec;
+ u8 auto_adapt;
+ u8 func_valid;
+ u8 func_id;
+ u8 sriov_en;
+};
+
+struct nic_cmd_bios_cfg {
+ struct hinic3_mgmt_msg_head head;
+ u32 op_code; /* Operation Code: Bit0[0: read 1:write, BIT1-6: cfg_mask */
+ struct nic_bios_cfg bios_cfg;
+};
+
+struct nic_rx_rate_bios_cfg {
+ struct mgmt_msg_head msg_head;
+
+ u32 op_code; /* Operation Code:[0:read 1:write] */
+ u8 rx_rate_limit;
+ u8 func_id;
+};
+
+struct nic_cmd_vhd_config {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 vhd_type;
+ u8 virtio_small_enable; /* 0: mergeable mode, 1: small mode */
+};
+
+/* BOND */
+struct hinic3_create_bond_info {
+ u32 bond_id;
+ u32 master_slave_port_id;
+ u32 slave_bitmap; /* bond port id bitmap */
+ u32 poll_timeout; /* Bond device link check time */
+ u32 up_delay; /* Temporarily reserved */
+ u32 down_delay; /* Temporarily reserved */
+ u32 bond_mode; /* Temporarily reserved */
+ u32 active_pf; /* bond use active pf id */
+ u32 active_port_max_num; /* Maximum number of active bond member interfaces */
+ u32 active_port_min_num; /* Minimum number of active bond member interfaces */
+ u32 xmit_hash_policy;
+ u32 default_param_flag;
+ u32 rsvd;
+};
+
+struct hinic3_cmd_create_bond {
+ struct hinic3_mgmt_msg_head head;
+ struct hinic3_create_bond_info create_bond_info;
+};
+
+struct hinic3_cmd_delete_bond {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 rsvd[2];
+};
+
+struct hinic3_open_close_bond_info {
+ u32 bond_id;
+ u32 open_close_flag; /* Bond flag. 1: open; 0: close. */
+ u32 rsvd[2];
+};
+
+struct hinic3_cmd_open_close_bond {
+ struct hinic3_mgmt_msg_head head;
+ struct hinic3_open_close_bond_info open_close_bond_info;
+};
+
+struct lacp_port_params {
+ u16 port_number;
+ u16 port_priority;
+ u16 key;
+ u16 system_priority;
+ u8 system[ETH_ALEN];
+ u8 port_state;
+ u8 rsvd;
+};
+
+struct lacp_port_info {
+ u32 selected;
+ u32 aggregator_port_id;
+
+ struct lacp_port_params actor;
+ struct lacp_port_params partner;
+
+ u64 tx_lacp_pkts;
+ u64 rx_lacp_pkts;
+ u64 rx_8023ad_drop;
+ u64 tx_8023ad_drop;
+ u64 unknown_pkt_drop;
+ u64 rx_marker_pkts;
+ u64 tx_marker_pkts;
+};
+
+struct hinic3_bond_status_info {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 bon_mmi_status;
+ u32 active_bitmap;
+ u32 port_count;
+
+ struct lacp_port_info port_info[4];
+
+ u64 success_report_cnt[4];
+ u64 fail_report_cnt[4];
+
+ u64 poll_timeout;
+ u64 fast_periodic_timeout;
+ u64 slow_periodic_timeout;
+ u64 short_timeout;
+ u64 long_timeout;
+ u64 aggregate_wait_timeout;
+ u64 tx_period_timeout;
+ u64 rx_marker_timer;
+};
+
+struct hinic3_bond_active_report_info {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 bon_mmi_status;
+ u32 active_bitmap;
+
+ u8 rsvd[16];
+};
+
+/* IP checksum error packets, enable rss quadruple hash. */
+struct hinic3_ipcs_err_rss_enable_operation_s {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 en_tag;
+ u8 type; /* 1: set 0: get */
+ u8 rsvd[2];
+};
+
+struct hinic3_smac_check_state {
+ struct hinic3_mgmt_msg_head head;
+ u8 smac_check_en; /* 1: enable 0: disable */
+ u8 op_code; /* 1: set 0: get */
+ u8 flash_en; /* 1: enable 0: disable */
+ u8 rsvd;
+};
+
+struct hinic3_clear_log_state {
+ struct hinic3_mgmt_msg_head head;
+ u32 type;
+};
+
+struct hinic3_outband_cfg_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 outband_default_vid;
+ u16 func_id;
+};
+
+struct hinic3_wr_ordering {
+ struct hinic3_mgmt_msg_head head;
+ u8 op_code; /* 1: set 0: get */
+ u8 wr_pkt_so_ro;
+ u8 rd_pkt_so_ro;
+ u8 rsvd;
+};
+
+struct hinic3_function_active_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_rq_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rq_depth;
+ u16 rq_num;
+ u16 pf_num;
+ u16 port_num;
+};
+
+#endif /* HINIC_MGMT_INTERFACE_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
new file mode 100644
index 0000000..3e625fc
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
+ * File Name : nic_npu_cmd.h
+ * Version : Initial Draft
+ * Created : 2019/4/25
+ * Last Modified :
+ * Description : NIC Commands between Driver and NPU
+ * Function List :
+ */
+
+#ifndef NIC_NPU_CMD_H
+#define NIC_NPU_CMD_H
+
+/* NIC CMDQ MODE */
+enum hinic3_ucode_cmd {
+ HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
+ HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
+ HINIC3_UCODE_CMD_ARM_SQ, /**< Unused */
+ HINIC3_UCODE_CMD_ARM_RQ, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_IQ_ENABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
+ HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
+ HINIC3_UCODE_CMD_PPA_HASH_TABLE,
+ HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_UCODE_MIG_CFG_Q_CTX = 14,
+ HINIC3_UCODE_MIG_CHK_SQ_STOP,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ HINIC3_UCODE_MIG_CFG_BAT_INFO,
+};
+
+#endif /* NIC_NPU_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
index 78a8d7f..66f4305 100644
--- a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
+++ b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
@@ -5,6 +5,7 @@
#define OSSL_KNL_LINUX_H_
#include <net/ipv6.h>
+#include <net/devlink.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/device.h>
@@ -18,6 +19,12 @@
#include <linux/list.h>
#include <linux/bitmap.h>
#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/filter.h>
+#include <linux/aer.h>
+#include <linux/socket.h>
#ifndef NETIF_F_SCTP_CSUM
#define NETIF_F_SCTP_CSUM 0
@@ -173,12 +180,10 @@ static inline void *_hinic3_dma_zalloc_coherent(struct device *dev,
}
#endif
-#ifndef DT_KNL_EMU
struct timeval {
__kernel_old_time_t tv_sec; /* seconds */
__kernel_suseconds_t tv_usec; /* microseconds */
};
-#endif
#ifndef do_gettimeofday
#define do_gettimeofday(time) _kc_do_gettimeofday(time)
@@ -196,6 +201,10 @@ static inline void _kc_do_gettimeofday(struct timeval *tv)
#define ETH_GET_HEADLEN_NEED_DEV
#define HAVE_GENL_OPS_FIELD_VALIDATE
+#ifndef FIELD_SIZEOF
+#define FIELD_SIZEOF(t, f) (sizeof(((t *)0)->f))
+#endif
+
#define HAVE_DEVLINK_FLASH_UPDATE_PARAMS
#ifndef rtc_time_to_tm
@@ -253,12 +262,12 @@ static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size,
size, vaddr, dma_handle);
}
-#define HAVE_DEVLINK_FW_FILE_NAME_MEMBER
-
#define HAVE_ENCAPSULATION_TSO
#define HAVE_ENCAPSULATION_CSUM
+#define HAVE_UDP_TUNNEL_NIC_INFO
+
#ifndef eth_zero_addr
static inline void hinic3_eth_zero_addr(u8 *addr)
{
@@ -333,4 +342,15 @@ u64 ossl_get_real_time(void);
#define tasklet_state(tasklet) ((tasklet)->state)
+dma_addr_t pci_map_single(struct pci_dev *pdev,
+ void *ptr, size_t size, int direction);
+int pci_dma_mapping_error(struct pci_dev *pdev,
+ dma_addr_t dma_addr);
+void pci_unmap_single(struct pci_dev *pdev,
+ dma_addr_t dma_addr, size_t size, int direction);
+void *pci_alloc_consistent(struct pci_dev *pdev,
+ size_t size, dma_addr_t *dma_handle);
+void pci_free_consistent(struct pci_dev *pdev,
+ size_t size, void *vaddr, dma_addr_t dma_handle);
+
#endif
--
2.45.1.windows.1
2
1

09 May '25
From: Chenyuan Yang <chenyuan0y(a)gmail.com>
stable inclusion
from stable-v6.6.88
commit c17ef974bfcf1a50818168b47c4606b425a957c4
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC5BKW
CVE: CVE-2025-37755
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 7f1ff1b38a7c8b872382b796023419d87d78c47e ]
page_pool_dev_alloc_pages could return NULL. There was a WARN_ON(!page)
but it would still proceed to use the NULL pointer and then crash.
This is similar to commit 001ba0902046
("net: fec: handle page_pool_dev_alloc_pages error").
This is found by our static analysis tool KNighter.
Signed-off-by: Chenyuan Yang <chenyuan0y(a)gmail.com>
Fixes: 3c47e8ae113a ("net: libwx: Support to receive packets in NAPI")
Reviewed-by: Joe Damato <jdamato(a)fastly.com>
Link: https://patch.msgid.link/20250407184952.2111299-1-chenyuan0y@gmail.com
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Yuntao Liu <liuyuntao12(a)huawei.com>
---
drivers/net/ethernet/wangxun/libwx/wx_lib.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_lib.c b/drivers/net/ethernet/wangxun/libwx/wx_lib.c
index 3b120d078793..c0ae843fed54 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_lib.c
+++ b/drivers/net/ethernet/wangxun/libwx/wx_lib.c
@@ -311,7 +311,8 @@ static bool wx_alloc_mapped_page(struct wx_ring *rx_ring,
return true;
page = page_pool_dev_alloc_pages(rx_ring->page_pool);
- WARN_ON(!page);
+ if (unlikely(!page))
+ return false;
dma = page_pool_get_dma_addr(page);
bi->page_dma = dma;
--
2.34.1
2
1

[openeuler:OLK-5.10 2891/2891] versioncheck: ./drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c: 682: need linux/version.h
by kernel test robot 09 May '25
by kernel test robot 09 May '25
09 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-5.10
head: 2e5032bf08eca1f3b062773540ff27c51788390d
commit: 79871cd2cd720225eb582c9ed49fb4a96a270b3b [2891/2891] net/hinic3: Synchronize new NIC features and bug fixes
reproduce: (https://download.01.org/0day-ci/archive/20250509/202505091231.o5lexadJ-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505091231.o5lexadJ-lkp@intel.com/
versioncheck warnings: (new ones prefixed by >>)
INFO PATH=/opt/cross/rustc-1.58.0-bindgen-0.56.0/cargo/bin:/opt/cross/clang-20/bin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
/usr/bin/timeout -k 100 3h /usr/bin/make KCFLAGS= -Wno-error=return-type -Wreturn-type -funsigned-char -Wundef W=1 --keep-going LLVM=1 -j32 ARCH=x86_64 versioncheck
find ./* \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc -o -name .hg -o -name .git \) -prune -o \
-name '*.[hcS]' -type f -print | sort \
| xargs perl -w ./scripts/checkversion.pl
./arch/csky/include/asm/atomic.h: 6 linux/version.h not needed.
./arch/csky/include/asm/io.h: 9 linux/version.h not needed.
./arch/csky/include/asm/thread_info.h: 9 linux/version.h not needed.
./arch/csky/include/asm/uaccess.h: 15 linux/version.h not needed.
./arch/csky/kernel/process.c: 5 linux/version.h not needed.
./arch/csky/mm/dma-mapping.c: 12 linux/version.h not needed.
./arch/csky/mm/fault.c: 16 linux/version.h not needed.
./arch/s390/include/asm/setup.h: 183: need linux/version.h
./arch/um/drivers/vector_kern.c: 11 linux/version.h not needed.
./drivers/block/rsxx/rsxx_priv.h: 14 linux/version.h not needed.
./drivers/char/ipmi/ipmi_si_ls2k500.c: 19 linux/version.h not needed.
./drivers/crypto/cavium/cpt/cptpf_main.c: 13 linux/version.h not needed.
./drivers/crypto/cavium/zip/common.h: 59 linux/version.h not needed.
./drivers/crypto/ccree/cc_driver.h: 26 linux/version.h not needed.
./drivers/crypto/montage/tsse/tsse_vuart.c: 21 linux/version.h not needed.
./drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c: 62 linux/version.h not needed.
./drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c: 28 linux/version.h not needed.
./drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c: 26 linux/version.h not needed.
./drivers/gpu/drm/inspur/inspur_drm_de.c: 513: need linux/version.h
./drivers/gpu/drm/inspur/inspur_drm_drv.c: 456: need linux/version.h
./drivers/gpu/drm/pl111/pl111_display.c: 14 linux/version.h not needed.
./drivers/gpu/drm/pl111/pl111_drv.c: 47 linux/version.h not needed.
./drivers/gpu/drm/tve200/tve200_display.c: 14 linux/version.h not needed.
./drivers/gpu/drm/tve200/tve200_drv.c: 38 linux/version.h not needed.
./drivers/hv/hv.c: 16 linux/version.h not needed.
./drivers/i2c/busses/i2c-brcmstb.c: 25 linux/version.h not needed.
./drivers/i2c/busses/i2c-xgene-slimpro.c: 22 linux/version.h not needed.
./drivers/media/pci/cx25821/cx25821.h: 31 linux/version.h not needed.
./drivers/media/platform/s3c-camif/camif-core.c: 26 linux/version.h not needed.
./drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.h: 16 linux/version.h not needed.
./drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c: 31 linux/version.h not needed.
./drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.c: 14 linux/version.h not needed.
./drivers/media/usb/uvc/uvc_driver.c: 18 linux/version.h not needed.
./drivers/net/ethernet/3snic/sssnic/include/kernel/sss_linux_kernel.h: 12 linux/version.h not needed.
./drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c: 21 linux/version.h not needed.
./drivers/net/ethernet/huawei/bma/edma_drv/bma_include.h: 32 linux/version.h not needed.
./drivers/net/ethernet/huawei/bma/edma_drv/bma_pci.c: 17 linux/version.h not needed.
./drivers/net/ethernet/huawei/bma/kbox_drv/kbox_include.h: 20 linux/version.h not needed.
./drivers/net/ethernet/huawei/bma/kbox_drv/kbox_main.c: 22 linux/version.h not needed.
./drivers/net/ethernet/huawei/bma/kbox_drv/kbox_mce.c: 16 linux/version.h not needed.
./drivers/net/ethernet/huawei/bma/kbox_drv/kbox_ram_op.c: 16 linux/version.h not needed.
./drivers/net/ethernet/huawei/hinic/ossl_knl.h: 22 linux/version.h not needed.
./drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c: 12 linux/version.h not needed.
>> ./drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c: 682: need linux/version.h
./drivers/net/ethernet/linkdata/sxe/base/compat/sxe_compat.h: 16 linux/version.h not needed.
./drivers/net/ethernet/linkdata/sxevf/base/compat/sxe_compat.h: 16 linux/version.h not needed.
./drivers/net/ethernet/mucse/rnpm/rnpm_common.h: 7 linux/version.h not needed.
./drivers/net/ethernet/nebula-matrix/m1600/common.h: 12 linux/version.h not needed.
./drivers/net/ethernet/nebula-matrix/m1600/txrx.c: 9 linux/version.h not needed.
./drivers/net/ethernet/qlogic/qede/qede.h: 10 linux/version.h not needed.
./drivers/net/ethernet/qlogic/qede/qede_ethtool.c: 7 linux/version.h not needed.
./drivers/net/ethernet/qlogic/qede/qede_main.c: 10 linux/version.h not needed.
./drivers/net/ethernet/yunsilicon/xsc/common/xsc_core.h: 26 linux/version.h not needed.
./drivers/net/usb/lan78xx.c: 5 linux/version.h not needed.
./drivers/net/wireless/rsi/rsi_91x_ps.c: 19 linux/version.h not needed.
./drivers/scsi/cxgbi/libcxgbi.h: 27 linux/version.h not needed.
./drivers/scsi/hisi_raid/hiraid_main.c: 9 linux/version.h not needed.
./drivers/scsi/huawei/hifc/hifc_knl_adp.h: 23 linux/version.h not needed.
./drivers/scsi/linkdata/ps3stor/linux/ps3_base.c: 12 linux/version.h not needed.
./drivers/scsi/linkdata/ps3stor/linux/ps3_cli.c: 15 linux/version.h not needed.
./drivers/scsi/linkdata/ps3stor/linux/ps3_driver_log.c: 4 linux/version.h not needed.
./drivers/scsi/linkdata/ps3stor/ps3_device_manager.h: 10 linux/version.h not needed.
./drivers/scsi/linkdata/ps3stor/ps3_device_manager_sas.h: 7 linux/version.h not needed.
./drivers/scsi/linkdata/ps3stor/ps3_qos.c: 7 linux/version.h not needed.
./drivers/scsi/linkdata/ps3stor/ps3_rb_tree.h: 8 linux/version.h not needed.
./drivers/scsi/linkdata/ps3stor/ps3_sas_transport.h: 10 linux/version.h not needed.
./drivers/scsi/linkdata/ps3stor/ps3_scsi_cmd_err.c: 10 linux/version.h not needed.
./drivers/scsi/qedf/qedf.h: 15 linux/version.h not needed.
./drivers/scsi/qedf/qedf_dbg.h: 13 linux/version.h not needed.
./drivers/scsi/qedi/qedi_dbg.h: 14 linux/version.h not needed.
./drivers/scsi/sssraid/sssraid_fw.c: 6 linux/version.h not needed.
./drivers/scsi/sssraid/sssraid_os.c: 6 linux/version.h not needed.
./drivers/soc/tegra/powergate-bpmp.c: 10 linux/version.h not needed.
./drivers/staging/media/atomisp/include/linux/atomisp.h: 23 linux/version.h not needed.
./drivers/staging/rtl8723bs/include/drv_types.h: 17 linux/version.h not needed.
./drivers/staging/rtl8723bs/include/ioctl_cfg80211.h: 10 linux/version.h not needed.
./drivers/ub/urma/ubcore/ubcore_cdev_file.c: 23 linux/version.h not needed.
./drivers/ub/urma/ubcore/ubcore_device.c: 33 linux/version.h not needed.
./drivers/ub/urma/ubcore/ubcore_genl.c: 26 linux/version.h not needed.
./drivers/ub/urma/ubcore/ubcore_genl_admin.c: 20 linux/version.h not needed.
./drivers/ub/urma/ubcore/ubcore_main.c: 28 linux/version.h not needed.
./drivers/ub/urma/ubcore/ubcore_tp.c: 26 linux/version.h not needed.
./drivers/ub/urma/ubcore/ubcore_umem.c: 26 linux/version.h not needed.
./drivers/ub/urma/uburma/uburma_main.c: 29 linux/version.h not needed.
./drivers/ub/urma/uburma/uburma_mmap.c: 21 linux/version.h not needed.
./drivers/watchdog/ziirave_wdt.c: 21 linux/version.h not needed.
./fs/eulerfs/euler.h: 20 linux/version.h not needed.
./fs/eulerfs/euler_common.h: 25 linux/version.h not needed.
./fs/proc/etmem_scan.c: 13 linux/version.h not needed.
./include/linux/qed/qed_ll2_if.h: 15 linux/version.h not needed.
./kernel/bpf/syscall.c: 20 linux/version.h not needed.
./samples/bpf/sampleip_kern.c: 7 linux/version.h not needed.
./samples/bpf/trace_event_kern.c: 8 linux/version.h not needed.
./sound/soc/codecs/cs35l35.c: 12 linux/version.h not needed.
./sound/soc/codecs/cs42l42.c: 14 linux/version.h not needed.
./tools/lib/bpf/libbpf_sched.h: 21 linux/version.h not needed.
./tools/perf/include/bpf/bpf.h: 70: need linux/version.h
./tools/perf/tests/bpf-script-example.c: 49: need linux/version.h
./tools/perf/tests/bpf-script-test-kbuild.c: 21: need linux/version.h
./tools/perf/tests/bpf-script-test-prologue.c: 47: need linux/version.h
./tools/perf/tests/bpf-script-test-relocation.c: 51: need linux/version.h
./tools/testing/selftests/bpf/progs/test_map_lock.c: 4 linux/version.h not needed.
./tools/testing/selftests/bpf/progs/test_send_signal_kern.c: 4 linux/version.h not needed.
./tools/testing/selftests/bpf/progs/test_spin_lock.c: 4 linux/version.h not needed.
./tools/testing/selftests/bpf/progs/test_tcp_estats.c: 37 linux/version.h not needed.
./tools/testing/selftests/wireguard/qemu/init.c: 25 linux/version.h not needed.
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0
Support fuse fastpath by using the newly added fast_ipc module.
chenrenhui (2):
ipc: add fast_ipc module to enable fast process switching
fuse: support fastpath via fast_ipc
Kconfig | 2 +
arch/arm64/configs/openeuler_defconfig | 2 +
arch/x86/configs/openeuler_defconfig | 2 +
fs/fuse/Kconfig | 9 +
fs/fuse/dev.c | 744 +++++++++++++++++++++++++
fs/fuse/dir.c | 87 ++-
fs/fuse/file.c | 235 +++++++-
fs/fuse/fuse_i.h | 55 ++
fs/fuse/inode.c | 112 ++++
fs/fuse/readdir.c | 8 +
include/linux/fast_ipc.h | 48 ++
include/uapi/linux/fuse.h | 15 +-
ipc/Kconfig | 5 +
ipc/Makefile | 2 +-
ipc/fast_ipc.c | 299 ++++++++++
15 files changed, 1597 insertions(+), 28 deletions(-)
create mode 100644 include/linux/fast_ipc.h
create mode 100644 ipc/Kconfig
create mode 100644 ipc/fast_ipc.c
--
2.33.0
2
3

[PATCH OLK-6.6] jfs: Fix uninit-value access of imap allocated in the diMount() function
by Yifan Qiao 09 May '25
by Yifan Qiao 09 May '25
09 May '25
From: Zhongqiu Han <quic_zhonhan(a)quicinc.com>
mainline inclusion
from mainline-v6.15-rc1
commit 9629d7d66c621671d9a47afe27ca9336bfc8a9ea
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC5BHS
CVE: CVE-2025-37742
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
syzbot reports that hex_dump_to_buffer is using uninit-value:
=====================================================
BUG: KMSAN: uninit-value in hex_dump_to_buffer+0x888/0x1100 lib/hexdump.c:171
hex_dump_to_buffer+0x888/0x1100 lib/hexdump.c:171
print_hex_dump+0x13d/0x3e0 lib/hexdump.c:276
diFree+0x5ba/0x4350 fs/jfs/jfs_imap.c:876
jfs_evict_inode+0x510/0x550 fs/jfs/inode.c:156
evict+0x723/0xd10 fs/inode.c:796
iput_final fs/inode.c:1946 [inline]
iput+0x97b/0xdb0 fs/inode.c:1972
txUpdateMap+0xf3e/0x1150 fs/jfs/jfs_txnmgr.c:2367
txLazyCommit fs/jfs/jfs_txnmgr.c:2664 [inline]
jfs_lazycommit+0x627/0x11d0 fs/jfs/jfs_txnmgr.c:2733
kthread+0x6b9/0xef0 kernel/kthread.c:464
ret_from_fork+0x6d/0x90 arch/x86/kernel/process.c:148
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
Uninit was created at:
slab_post_alloc_hook mm/slub.c:4121 [inline]
slab_alloc_node mm/slub.c:4164 [inline]
__kmalloc_cache_noprof+0x8e3/0xdf0 mm/slub.c:4320
kmalloc_noprof include/linux/slab.h:901 [inline]
diMount+0x61/0x7f0 fs/jfs/jfs_imap.c:105
jfs_mount+0xa8e/0x11d0 fs/jfs/jfs_mount.c:176
jfs_fill_super+0xa47/0x17c0 fs/jfs/super.c:523
get_tree_bdev_flags+0x6ec/0x910 fs/super.c:1636
get_tree_bdev+0x37/0x50 fs/super.c:1659
jfs_get_tree+0x34/0x40 fs/jfs/super.c:635
vfs_get_tree+0xb1/0x5a0 fs/super.c:1814
do_new_mount+0x71f/0x15e0 fs/namespace.c:3560
path_mount+0x742/0x1f10 fs/namespace.c:3887
do_mount fs/namespace.c:3900 [inline]
__do_sys_mount fs/namespace.c:4111 [inline]
__se_sys_mount+0x71f/0x800 fs/namespace.c:4088
__x64_sys_mount+0xe4/0x150 fs/namespace.c:4088
x64_sys_call+0x39bf/0x3c30 arch/x86/include/generated/asm/syscalls_64.h:166
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
=====================================================
The reason is that imap is not properly initialized after memory
allocation. It will cause the snprintf() function to write uninitialized
data into linebuf within hex_dump_to_buffer().
Fix this by using kzalloc instead of kmalloc to clear its content at the
beginning in diMount().
Signed-off-by: Zhongqiu Han <quic_zhonhan(a)quicinc.com>
Reported-by: syzbot+df6cdcb35904203d2b6d(a)syzkaller.appspotmail.com
Closes: https://lore.kernel.org/lkml/67b5d07e.050a0220.14d86d.00e6.GAE@google.com/
Signed-off-by: Dave Kleikamp <dave.kleikamp(a)oracle.com>
Signed-off-by: Yifan Qiao <qiaoyifan4(a)huawei.com>
---
fs/jfs/jfs_imap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index b30e4cf2f579..8b876e2db8c6 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -102,7 +102,7 @@ int diMount(struct inode *ipimap)
* allocate/initialize the in-memory inode map control structure
*/
/* allocate the in-memory inode map control structure. */
- imap = kmalloc(sizeof(struct inomap), GFP_KERNEL);
+ imap = kzalloc(sizeof(struct inomap), GFP_KERNEL);
if (imap == NULL)
return -ENOMEM;
--
2.39.2
2
1

[PATCH openEuler-1.0-LTS] nvmet: avoid potential UAF in nvmet_req_complete()
by Yifan Qiao 09 May '25
by Yifan Qiao 09 May '25
09 May '25
From: Damien Le Moal <damien.lemoal(a)opensource.wdc.com>
stable inclusion
from stable-v4.19.279
commit fafcb4b26393870c45462f9af6a48e581dbbcf7e
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC5DE1
CVE: CVE-2023-53116
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 6173a77b7e9d3e202bdb9897b23f2a8afe7bf286 ]
An nvme target ->queue_response() operation implementation may free the
request passed as argument. Such implementation potentially could result
in a use after free of the request pointer when percpu_ref_put() is
called in nvmet_req_complete().
Avoid such problem by using a local variable to save the sq pointer
before calling __nvmet_req_complete(), thus avoiding dereferencing the
req pointer after that function call.
Fixes: a07b4970f464 ("nvmet: add a generic NVMe target")
Signed-off-by: Damien Le Moal <damien.lemoal(a)opensource.wdc.com>
Reviewed-by: Chaitanya Kulkarni <kch(a)nvidia.com>
Signed-off-by: Christoph Hellwig <hch(a)lst.de>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Yifan Qiao <qiaoyifan4(a)huawei.com>
---
drivers/nvme/target/core.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 4a2ab093811e..1d5f266aee49 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -522,8 +522,10 @@ static void __nvmet_req_complete(struct nvmet_req *req, u16 status)
void nvmet_req_complete(struct nvmet_req *req, u16 status)
{
+ struct nvmet_sq *sq = req->sq;
+
__nvmet_req_complete(req, status);
- percpu_ref_put(&req->sq->ref);
+ percpu_ref_put(&sq->ref);
}
EXPORT_SYMBOL_GPL(nvmet_req_complete);
--
2.39.2
2
1

[PATCH openEuler-1.0-LTS] ata: libata-transport: fix double ata_host_put() in ata_tport_add()
by Yifan Qiao 09 May '25
by Yifan Qiao 09 May '25
09 May '25
From: Yang Yingliang <yangyingliang(a)huawei.com>
stable inclusion
from stable-v4.19.267
commit 30e12e2be27ac6c4be2af4163c70db381364706f
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC5BRR
CVE: CVE-2022-49826
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 8c76310740807ade5ecdab5888f70ecb6d35732e ]
In the error path in ata_tport_add(), when calling put_device(),
ata_tport_release() is called, it will put the refcount of 'ap->host'.
And then ata_host_put() is called again, the refcount is decreased
to 0, ata_host_release() is called, all ports are freed and set to
null.
When unbinding the device after failure, ata_host_stop() is called
to release the resources, it leads a null-ptr-deref(), because all
the ports all freed and null.
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008
CPU: 7 PID: 18671 Comm: modprobe Kdump: loaded Tainted: G E 6.1.0-rc3+ #8
pstate: 80400009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : ata_host_stop+0x3c/0x84 [libata]
lr : release_nodes+0x64/0xd0
Call trace:
ata_host_stop+0x3c/0x84 [libata]
release_nodes+0x64/0xd0
devres_release_all+0xbc/0x1b0
device_unbind_cleanup+0x20/0x70
really_probe+0x158/0x320
__driver_probe_device+0x84/0x120
driver_probe_device+0x44/0x120
__driver_attach+0xb4/0x220
bus_for_each_dev+0x78/0xdc
driver_attach+0x2c/0x40
bus_add_driver+0x184/0x240
driver_register+0x80/0x13c
__pci_register_driver+0x4c/0x60
ahci_pci_driver_init+0x30/0x1000 [ahci]
Fix this by removing redundant ata_host_put() in the error path.
Fixes: 2623c7a5f279 ("libata: add refcounting to ata_host")
Signed-off-by: Yang Yingliang <yangyingliang(a)huawei.com>
Signed-off-by: Damien Le Moal <damien.lemoal(a)opensource.wdc.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Yifan Qiao <qiaoyifan4(a)huawei.com>
---
drivers/ata/libata-transport.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
index c3f446fc24c4..34f6c6f730b8 100644
--- a/drivers/ata/libata-transport.c
+++ b/drivers/ata/libata-transport.c
@@ -317,7 +317,6 @@ int ata_tport_add(struct device *parent,
tport_err:
transport_destroy_device(dev);
put_device(dev);
- ata_host_put(ap->host);
return error;
}
--
2.39.2
2
1

08 May '25
From: fuguiming <fuguiming(a)huawei.com>
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IC5K0L?from=project-issue
CVE: NA
--------------------------------
Add optical module type adaptation.
Add ethtool fec function.
Add NIC XDP PASS function.
Add QoS persistence.
Add NIC out-of-band VLAN configuration function.
Fix NIC bifur bugs.
Fix performance test bugs.
Fix NIC RX bugs.
Fix NIC VF bugs.
Fix the bug of exiting when probing NIC.
Fix bond bugs.
Fix the bug of MAC address configuration failure in OS 6.6.
Fix the bug of reading NIC status incorrectly.
Fix and add some statistics.
Signed-off-by: fuguiming <fuguiming(a)huawei.com>
---
drivers/net/ethernet/huawei/hinic3/Makefile | 1 +
drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c | 3 +-
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c | 181 ++-
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h | 1 +
drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h | 212 ---
drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h | 239 ---
drivers/net/ethernet/huawei/hinic3/comm_defs.h | 100 --
drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h | 103 --
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c | 40 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h | 2 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c | 88 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c | 29 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c | 22 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h | 185 ---
drivers/net/ethernet/huawei/hinic3/hinic3_common.h | 118 --
drivers/net/ethernet/huawei/hinic3/hinic3_crm.h | 16 +-
drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c | 298 ++--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c | 264 +--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h | 7 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c | 252 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c | 456 +++---
drivers/net/ethernet/huawei/hinic3/hinic3_filter.c | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_hw.h | 19 +
drivers/net/ethernet/huawei/hinic3/hinic3_irq.c | 39 +-
drivers/net/ethernet/huawei/hinic3/hinic3_lld.h | 205 ---
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c | 831 +++++++++-
drivers/net/ethernet/huawei/hinic3/hinic3_main.c | 492 +++++-
drivers/net/ethernet/huawei/hinic3/hinic3_mt.h | 190 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c | 402 +++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic.h | 50 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c | 557 +++++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h | 54 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c | 186 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c | 10 +
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h | 114 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c | 105 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c | 50 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c | 15 +-
drivers/net/ethernet/huawei/hinic3/hinic3_profile.h | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rss.c | 139 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c | 41 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rx.c | 311 +++-
drivers/net/ethernet/huawei/hinic3/hinic3_rx.h | 41 +-
drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h | 7 +-
drivers/net/ethernet/huawei/hinic3/hinic3_tx.c | 79 +-
drivers/net/ethernet/huawei/hinic3/hinic3_wq.h | 4 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c | 11 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c | 6 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h | 5 -
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c | 1 -
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c | 213 ++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h | 18 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c | 3 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c | 14 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c | 42 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c | 79 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h | 7 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c | 155 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c | 115 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c | 85 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h | 31 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c | 40 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c | 1243 +++++++++++++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c | 3 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c | 4 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c | 41 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c | 126 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h | 4 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h | 31 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c | 56 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h | 6 +-
drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c | 1 +
drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h | 4 +
.../include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h | 11 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h | 42 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h | 2 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h | 70 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h | 141 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h | 5 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h | 88 +-
.../include/mpu/mpu_outband_ncsi_cmd_defs.h | 8 +
drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/vram_common.h | 25 +-
drivers/net/ethernet/huawei/hinic3/{mag_cmd.h => mag_mpu_cmd_defs.h} | 237 ++-
drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h | 27 -
drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h | 65 -
drivers/net/ethernet/huawei/hinic3/{hinic3_nic_cmd.h => nic_mpu_cmd.h} | 55 +-
drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h | 1440 +++++++++++++++++
drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h | 36 +
drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h | 29 +-
96 files changed, 8427 insertions(+), 2782 deletions(-)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_defs.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_common.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
rename drivers/net/ethernet/huawei/hinic3/{mag_cmd.h => mag_mpu_cmd_defs.h} (79%)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
rename drivers/net/ethernet/huawei/hinic3/{hinic3_nic_cmd.h => nic_mpu_cmd.h} (77%)
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
diff --git a/drivers/net/ethernet/huawei/hinic3/Makefile b/drivers/net/ethernet/huawei/hinic3/Makefile
index 6f9ed3f..457c920 100644
--- a/drivers/net/ethernet/huawei/hinic3/Makefile
+++ b/drivers/net/ethernet/huawei/hinic3/Makefile
@@ -11,6 +11,7 @@ ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/mpu/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/bond/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/vmsec/
+ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/bond/
obj-$(CONFIG_HINIC3) += hinic3.o
hinic3-objs := hw/hinic3_hwdev.o \
diff --git a/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c b/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c
index cc2e4b3..440fea6 100644
--- a/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_nic_cmdq.h"
#include "sw_cmdq_ops.h"
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
index e8c703b..cd6ea8e 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
@@ -9,6 +9,7 @@
#include <linux/net.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
+#include <linux/version.h>
#include "hinic3_lld.h"
#include "hinic3_srv_nic.h"
@@ -81,7 +82,7 @@ static u32 bond_gen_uplink_id(struct hinic3_bond_dev *bdev)
spin_lock(&bdev->lock);
for (i = 0; i < BOND_PORT_MAX_NUM; i++) {
if (BITMAP_JUDGE(bdev->bond_attr.slaves, i)) {
- if (!bdev->tracker.ndev[i])
+ if (bdev->tracker.ndev[i] == NULL)
continue;
nic_dev = netdev_priv(bdev->tracker.ndev[i]);
pdev = nic_dev->pdev;
@@ -109,7 +110,8 @@ static struct hinic3_nic_dev *get_nic_dev_safe(struct net_device *ndev)
return netdev_priv(ndev);
}
-static u8 bond_get_slaves_bitmap(struct hinic3_bond_dev *bdev, struct bonding *bond)
+static u8 bond_get_slaves_bitmap(struct hinic3_bond_dev *bdev,
+ struct bonding *bond)
{
struct slave *slave = NULL;
struct list_head *iter = NULL;
@@ -203,7 +205,8 @@ static u8 bond_dev_track_port(struct hinic3_bond_dev *bdev,
bdev->tracker.netdev_state[port_id].tx_enabled = 0;
if (!bdev->ppf_hwdev)
bdev->ppf_hwdev = ppf_hwdev;
- pr_info("TRACK cnt: %d, slave_name(%s)\n", bdev->tracker.cnt, ndev->name);
+ pr_info("TRACK cnt: %d, slave_name(%s)\n",
+ bdev->tracker.cnt, ndev->name);
spin_unlock(&bdev->lock);
return port_id;
@@ -268,11 +271,16 @@ static void bond_master_event(struct hinic3_bond_dev *bdev,
queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
}
-static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
+static struct hinic3_bond_dev *bond_get_bdev(struct bonding *bond)
{
struct hinic3_bond_dev *bdev = NULL;
int bid;
+ if (bond == NULL) {
+ pr_err("hinic3_bond: bond is NULL\n");
+ return NULL;
+ }
+
mutex_lock(&g_bond_mutex);
for (bid = BOND_FIRST_ID; bid <= BOND_MAX_ID; bid++) {
bdev = bond_mngr.bond_dev[bid];
@@ -283,38 +291,73 @@ static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
mutex_unlock(&g_bond_mutex);
return bdev;
}
+
+ if (strncmp(bond->dev->name,
+ bdev->name, BOND_NAME_MAX_LEN) == 0) {
+ bdev->bond = bond;
+ return bdev;
+ }
}
mutex_unlock(&g_bond_mutex);
return NULL;
}
-static void bond_handle_rtnl_event(struct net_device *ndev)
+static struct bonding *get_bonding_by_netdev(struct net_device *ndev)
{
- struct hinic3_bond_dev *bdev = NULL;
struct bonding *bond = NULL;
struct slave *slave = NULL;
if (netif_is_bond_master(ndev)) {
bond = netdev_priv(ndev);
- bdev = bond_get_bdev(bond);
} else if (netif_is_bond_slave(ndev)) {
- /*lint -e(160) */
slave = bond_slave_get_rtnl(ndev);
if (slave) {
bond = bond_get_bond_by_slave(slave);
- bdev = bond_get_bdev(bond);
}
}
- if (!bond || !bdev)
+ return bond;
+}
+/*lint -e580 -e546*/
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+
+ if (!ndev) {
+ pr_err("hinic3_bond: netdev is NULL\n");
+ return false;
+ }
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
+ return false;
+
+ return bdev->status == BOND_DEV_STATUS_ACTIVATED;
+}
+EXPORT_SYMBOL(hinic3_is_bond_dev_status_actived);
+/*lint +e580 +e546*/
+
+static void bond_handle_rtnl_event(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+ struct slave *slave = NULL;
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
return;
bond_update_attr(bdev, bond);
- if (slave)
+ if (netif_is_bond_slave(ndev)) {
+ slave = bond_slave_get_rtnl(ndev);
bond_slave_event(bdev, slave);
- else
+ } else {
bond_master_event(bdev, bond);
+ }
}
static void bond_rtnl_data_ready(struct sock *sk)
@@ -368,7 +411,8 @@ static int bond_enable_netdev_event(void)
(*rtnl_sock)->sk->sk_data_ready = bond_rtnl_data_ready;
(*rtnl_sock)->sk->sk_allocation = GFP_KERNEL;
- err = kernel_bind(*rtnl_sock, (struct sockaddr *)(u8 *)&addr, sizeof(addr));
+ err = kernel_bind(*rtnl_sock, (struct sockaddr *)(u8 *)&addr,
+ sizeof(addr));
if (err) {
pr_err("hinic3_bond: Couldn't bind rtnl socket.\n");
sock_release(*rtnl_sock);
@@ -387,7 +431,7 @@ static void bond_disable_netdev_event(void)
static int bond_send_upcmd(struct hinic3_bond_dev *bdev, struct bond_attr *attr,
u8 cmd_type)
{
- int err, len;
+ int err, ret, len;
struct hinic3_bond_cmd cmd = {0};
u16 out_size = sizeof(cmd);
@@ -403,7 +447,9 @@ static int bond_send_upcmd(struct hinic3_bond_dev *bdev, struct bond_attr *attr,
len = sizeof(cmd.bond_name);
if (cmd_type == MPU_CMD_BOND_CREATE) {
- strscpy(cmd.bond_name, bdev->name, len);
+ ret = strscpy(cmd.bond_name, bdev->name, len);
+ if (ret < 0)
+ pr_err("strscpy bond name failed\n");
cmd.bond_name[sizeof(cmd.bond_name) - 1] = '\0';
}
@@ -478,7 +524,11 @@ static void bond_update_slave_info(struct hinic3_bond_dev *bdev,
continue;
}
+ if (!bdev->tracker.ndev[i])
+ continue;
+
bond_pf_bitmap_set(bdev, i);
+
if (!bdev->tracker.netdev_state[i].tx_enabled)
continue;
@@ -516,6 +566,7 @@ static int bond_upcmd_config(struct hinic3_bond_dev *bdev,
attr->active_slaves,
attr->lacp_collect_slaves);
pr_info("bond_pf_bitmap: 0x%x\n", attr->bond_pf_bitmap);
+ pr_info("bond user_bitmap 0x%x\n", attr->user_bitmap);
err = bond_send_upcmd(bdev, attr, MPU_CMD_BOND_SET_ATTR);
if (!err)
@@ -544,8 +595,10 @@ static int bond_upcmd_activate(struct hinic3_bond_dev *bdev,
return err;
}
-static void bond_call_service_func(struct hinic3_bond_dev *bdev, struct bond_attr *attr,
- enum bond_service_proc_pos pos, int bond_status)
+static void bond_call_service_func(struct hinic3_bond_dev *bdev,
+ struct bond_attr *attr,
+ enum bond_service_proc_pos pos,
+ int bond_status)
{
int i;
@@ -560,6 +613,18 @@ static void bond_call_service_func(struct hinic3_bond_dev *bdev, struct bond_att
mutex_unlock(&g_bond_service_func_mutex);
}
+static u32 bond_get_user_bitmap(struct hinic3_bond_dev *bdev)
+{
+ u32 user_bitmap = 0;
+ u8 user;
+
+ for (user = HINIC3_BOND_USER_OVS; user < HINIC3_BOND_USER_NUM; user++) {
+ if (bdev->slot_used[user] == 1)
+ BITMAP_SET(user_bitmap, user);
+ }
+ return user_bitmap;
+}
+
static void bond_do_work(struct hinic3_bond_dev *bdev)
{
bool is_bonded = 0;
@@ -570,7 +635,7 @@ static void bond_do_work(struct hinic3_bond_dev *bdev)
is_bonded = bdev->tracker.is_bonded;
attr = bdev->new_attr;
spin_unlock(&bdev->lock);
- attr.user_bitmap = 0;
+ attr.user_bitmap = bond_get_user_bitmap(bdev);
/* is_bonded indicates whether bond should be activated. */
if (is_bonded && !bond_dev_is_activated(bdev)) {
@@ -597,15 +662,22 @@ static void bond_try_do_work(struct work_struct *work)
struct delayed_work *delayed_work = to_delayed_work(work);
struct hinic3_bond_dev *bdev =
container_of(delayed_work, struct hinic3_bond_dev, bond_work);
+ int status;
- if (g_bond_service_func[HINIC3_BOND_USER_ROCE] && bdev->tracker.cnt < MIN_BOND_SLAVE_CNT)
+ status = mutex_trylock(&g_bond_mutex);
+ if (status == 0) {
+ /* Delay 1 sec and retry */
queue_delayed_work(bdev->wq, &bdev->bond_work, HZ);
- else
+ } else {
bond_do_work(bdev);
+ mutex_unlock(&g_bond_mutex);
+ }
}
static int bond_dev_init(struct hinic3_bond_dev *bdev, const char *name)
{
+ int err = 0;
+
bdev->wq = create_singlethread_workqueue("hinic3_bond_wq");
if (!bdev->wq) {
pr_err("hinic3_bond: Failed to create workqueue\n");
@@ -614,7 +686,13 @@ static int bond_dev_init(struct hinic3_bond_dev *bdev, const char *name)
INIT_DELAYED_WORK(&bdev->bond_work, bond_try_do_work);
bdev->status = BOND_DEV_STATUS_IDLE;
- strscpy(bdev->name, name, sizeof(bdev->name));
+ err = strscpy(bdev->name, name, strlen(name));
+ if (err < 0) {
+ pr_err("hinic3_bond: Failed to init bond dev\n");
+ cancel_delayed_work_sync(&bdev->bond_work);
+ destroy_workqueue(bdev->wq);
+ return err;
+ }
spin_lock_init(&bdev->lock);
@@ -630,6 +708,7 @@ static int bond_dev_release(struct hinic3_bond_dev *bdev)
err = bond_upcmd_deactivate(bdev);
if (err) {
pr_err("hinic3_bond: Failed to deactivate dev\n");
+ mutex_unlock(&g_bond_mutex);
return err;
}
@@ -637,7 +716,8 @@ static int bond_dev_release(struct hinic3_bond_dev *bdev)
if (bond_mngr.bond_dev[i] == bdev) {
bond_mngr.bond_dev[i] = NULL;
bond_mngr.cnt--;
- pr_info("hinic3_bond: Free bond, id: %u mngr_cnt:%u\n", i, bond_mngr.cnt);
+ pr_info("hinic3_bond: Free bond, id: %u mngr_cnt:%u\n",
+ i, bond_mngr.cnt);
break;
}
}
@@ -694,7 +774,8 @@ static struct hinic3_bond_dev *bond_dev_alloc(const char *name)
bdev->bond_attr.bond_id = i;
bond_mngr.bond_dev[i] = bdev;
bond_mngr.cnt++;
- pr_info("hinic3_bond: Create bond dev, id:%u cnt:%u\n", i, bond_mngr.cnt);
+ pr_info("hinic3_bond: Create bond dev, id:%u cnt:%u\n",
+ i, bond_mngr.cnt);
break;
}
}
@@ -764,20 +845,28 @@ static struct hinic3_bond_dev *bond_dev_by_name(const char *name)
static void bond_dev_user_attach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user)
{
+ u32 user_bitmap;
+
+ if (user < 0 || user >= HINIC3_BOND_USER_NUM)
+ return;
+
if (bdev->slot_used[user])
return;
bdev->slot_used[user] = 1;
if (!kref_get_unless_zero(&bdev->ref))
kref_init(&bdev->ref);
+ else {
+ user_bitmap = bond_get_user_bitmap(bdev);
+ pr_info("hinic3_bond: user %u attach bond %s, user_bitmap %#x\n",
+ user, bdev->name, user_bitmap);
+ queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
+ }
}
static void bond_dev_user_detach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user, bool *freed)
{
- if (user < 0 || user >= HINIC3_BOND_USER_NUM)
- return;
-
if (bdev->slot_used[user]) {
bdev->slot_used[user] = 0;
if (kref_read(&bdev->ref) == 1)
@@ -790,16 +879,20 @@ static struct bonding *bond_get_knl_bonding(const char *name)
{
struct net_device *ndev_tmp = NULL;
+ rcu_read_lock();
for_each_netdev(&init_net, ndev_tmp) {
if (netif_is_bond_master(ndev_tmp) &&
- !strcmp(ndev_tmp->name, name))
+ !strcmp(ndev_tmp->name, name)) {
+ rcu_read_unlock();
return netdev_priv(ndev_tmp);
+ }
}
-
+ rcu_read_unlock();
return NULL;
}
-void hinic3_bond_set_user_bitmap(struct bond_attr *attr, enum hinic3_bond_user user)
+void hinic3_bond_set_user_bitmap(struct bond_attr *attr,
+ enum hinic3_bond_user user)
{
if (!BITMAP_JUDGE(attr->user_bitmap, user))
BITMAP_SET(attr->user_bitmap, user);
@@ -852,8 +945,9 @@ int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user)
int err = 0;
bool lock_freed = false;
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
- pr_warn("hinic3_bond: Invalid bond id:%u to delete\n", bond_id);
+ if (!BOND_ID_IS_VALID(bond_id) || user >= HINIC3_BOND_USER_NUM) {
+ pr_warn("hinic3_bond: Invalid bond id or user, bond_id: %u, user: %d\n",
+ bond_id, user);
return -EINVAL;
}
@@ -861,7 +955,8 @@ int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user)
if (!bond_mngr.bond_dev[bond_id])
err = -ENODEV;
else
- bond_dev_user_detach(bond_mngr.bond_dev[bond_id], user, &lock_freed);
+ bond_dev_user_detach(bond_mngr.bond_dev[bond_id],
+ user, &lock_freed);
if (!lock_freed)
mutex_unlock(&g_bond_mutex);
@@ -877,7 +972,8 @@ void hinic3_bond_clean_user(enum hinic3_bond_user user)
mutex_lock(&g_bond_mutex);
for (i = BOND_FIRST_ID; i <= BOND_MAX_ID; i++) {
if (bond_mngr.bond_dev[i]) {
- bond_dev_user_detach(bond_mngr.bond_dev[i], user, &lock_freed);
+ bond_dev_user_detach(bond_mngr.bond_dev[i],
+ user, &lock_freed);
if (lock_freed) {
mutex_lock(&g_bond_mutex);
lock_freed = false;
@@ -891,7 +987,7 @@ EXPORT_SYMBOL(hinic3_bond_clean_user);
int hinic3_bond_get_uplink_id(u16 bond_id, u32 *uplink_id)
{
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID || !uplink_id) {
+ if (!BOND_ID_IS_VALID(bond_id) || !uplink_id) {
pr_warn("hinic3_bond: Invalid args, id: %u, uplink: %d\n",
bond_id, !!uplink_id);
return -EINVAL;
@@ -941,7 +1037,7 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
int i;
int len;
- if (!info || bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
+ if (!info || !BOND_ID_IS_VALID(bond_id)) {
pr_warn("hinic3_bond: Invalid args, info: %d,id: %u\n",
!!info, bond_id);
return -EINVAL;
@@ -962,7 +1058,8 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
for (i = 0; i < BOND_PORT_MAX_NUM; i++) {
if (BITMAP_JUDGE(info->slaves, i) && tracker->ndev[i]) {
len = sizeof(info->slaves_name[0]);
- strscpy(info->slaves_name[info->cnt], tracker->ndev[i]->name, len);
+ strscpy(info->slaves_name[info->cnt],
+ tracker->ndev[i]->name, len);
info->cnt++;
}
}
@@ -972,7 +1069,8 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
}
EXPORT_SYMBOL(hinic3_bond_get_slaves);
-struct net_device *hinic3_bond_get_netdev_by_portid(const char *bond_name, u8 port_id)
+struct net_device *hinic3_bond_get_netdev_by_portid(const char *bond_name,
+ u8 port_id)
{
struct hinic3_bond_dev *bdev = NULL;
@@ -989,7 +1087,8 @@ struct net_device *hinic3_bond_get_netdev_by_portid(const char *bond_name, u8 po
}
EXPORT_SYMBOL(hinic3_bond_get_netdev_by_portid);
-int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos, u16 channel)
+int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos,
+ u16 channel)
{
struct comm_cmd_hw_bond_infos bond_infos;
u16 out_size = sizeof(bond_infos);
@@ -1002,7 +1101,8 @@ int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos, u1
bond_infos.infos.bond_id = infos->bond_id;
- err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_COMM, COMM_MGMT_CMD_GET_HW_BOND,
+ err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_COMM,
+ COMM_MGMT_CMD_GET_HW_BOND,
&bond_infos, sizeof(bond_infos),
&bond_infos, &out_size, 0, channel);
if (bond_infos.head.status || err || !out_size) {
@@ -1018,7 +1118,8 @@ int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos, u1
}
EXPORT_SYMBOL(hinic3_get_hw_bond_infos);
-int hinic3_get_bond_tracker_by_name(const char *name, struct bond_tracker *tracker)
+int hinic3_get_bond_tracker_by_name(const char *name,
+ struct bond_tracker *tracker)
{
struct hinic3_bond_dev *bdev = NULL;
int i;
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
index 024de95..5ab36f7 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
@@ -82,6 +82,7 @@ struct hinic3_bond_cmd {
char bond_name[16];
};
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev);
void hinic3_bond_set_user_bitmap(struct bond_attr *attr, enum hinic3_bond_user user);
int hinic3_bond_attach(const char *name, enum hinic3_bond_user user, u16 *bond_id);
int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user);
diff --git a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h b/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
deleted file mode 100644
index 557f326..0000000
--- a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2016-2022. All rights reserved.
- * File name: Cfg_mgt_comm_pub.h
- * Version No.: Draft
- * Generation date: 2016 year 05 month 07 day
- * Latest modification:
- * Function description: Header file for communication between the: Host and FW
- * Function list:
- * Modification history:
- * 1. Date: 2016 May 07
- * Modify content: Create a file.
- */
-#ifndef CFG_MGT_COMM_PUB_H
-#define CFG_MGT_COMM_PUB_H
-
-#include "mgmt_msg_base.h"
-
-enum servic_bit_define {
- SERVICE_BIT_NIC = 0,
- SERVICE_BIT_ROCE = 1,
- SERVICE_BIT_VBS = 2,
- SERVICE_BIT_TOE = 3,
- SERVICE_BIT_IPSEC = 4,
- SERVICE_BIT_FC = 5,
- SERVICE_BIT_VIRTIO = 6,
- SERVICE_BIT_OVS = 7,
- SERVICE_BIT_NVME = 8,
- SERVICE_BIT_ROCEAA = 9,
- SERVICE_BIT_CURRENET = 10,
- SERVICE_BIT_PPA = 11,
- SERVICE_BIT_MIGRATE = 12,
- SERVICE_BIT_MAX
-};
-
-#define CFG_SERVICE_MASK_NIC (0x1 << SERVICE_BIT_NIC)
-#define CFG_SERVICE_MASK_ROCE (0x1 << SERVICE_BIT_ROCE)
-#define CFG_SERVICE_MASK_VBS (0x1 << SERVICE_BIT_VBS)
-#define CFG_SERVICE_MASK_TOE (0x1 << SERVICE_BIT_TOE)
-#define CFG_SERVICE_MASK_IPSEC (0x1 << SERVICE_BIT_IPSEC)
-#define CFG_SERVICE_MASK_FC (0x1 << SERVICE_BIT_FC)
-#define CFG_SERVICE_MASK_VIRTIO (0x1 << SERVICE_BIT_VIRTIO)
-#define CFG_SERVICE_MASK_OVS (0x1 << SERVICE_BIT_OVS)
-#define CFG_SERVICE_MASK_NVME (0x1 << SERVICE_BIT_NVME)
-#define CFG_SERVICE_MASK_ROCEAA (0x1 << SERVICE_BIT_ROCEAA)
-#define CFG_SERVICE_MASK_CURRENET (0x1 << SERVICE_BIT_CURRENET)
-#define CFG_SERVICE_MASK_PPA (0x1 << SERVICE_BIT_PPA)
-#define CFG_SERVICE_MASK_MIGRATE (0x1 << SERVICE_BIT_MIGRATE)
-
-/* Definition of the scenario ID in the cfg_data, which is used for SML memory allocation. */
-enum scenes_id_define {
- SCENES_ID_FPGA_ETH = 0,
- SCENES_ID_FPGA_TIOE = 1, /* Discarded */
- SCENES_ID_STORAGE_ROCEAA_2x100 = 2,
- SCENES_ID_STORAGE_ROCEAA_4x25 = 3,
- SCENES_ID_CLOUD = 4,
- SCENES_ID_FC = 5,
- SCENES_ID_STORAGE_ROCE = 6,
- SCENES_ID_COMPUTE_ROCE = 7,
- SCENES_ID_STORAGE_TOE = 8,
- SCENES_ID_MAX
-};
-
-/* struct cfg_cmd_dev_cap.sf_svc_attr */
-enum {
- SF_SVC_FT_BIT = (1 << 0),
- SF_SVC_RDMA_BIT = (1 << 1),
-};
-
-enum cfg_cmd {
- CFG_CMD_GET_DEV_CAP = 0,
- CFG_CMD_GET_HOST_TIMER = 1,
-};
-
-struct cfg_cmd_host_timer {
- struct mgmt_msg_head head;
-
- u8 host_id;
- u8 rsvd1;
-
- u8 timer_pf_num;
- u8 timer_pf_id_start;
- u16 timer_vf_num;
- u16 timer_vf_id_start;
- u32 rsvd2[8];
-};
-
-struct cfg_cmd_dev_cap {
- struct mgmt_msg_head head;
-
- u16 func_id;
- u16 rsvd1;
-
- /* Public resources */
- u8 host_id;
- u8 ep_id;
- u8 er_id;
- u8 port_id;
-
- u16 host_total_func;
- u8 host_pf_num;
- u8 pf_id_start;
- u16 host_vf_num;
- u16 vf_id_start;
- u8 host_oq_id_mask_val;
- u8 timer_en;
- u8 host_valid_bitmap;
- u8 rsvd_host;
-
- u16 svc_cap_en;
- u16 max_vf;
- u8 flexq_en;
- u8 valid_cos_bitmap;
- /* Reserved for func_valid_cos_bitmap */
- u8 port_cos_valid_bitmap;
- u8 rsvd_func1;
- u32 rsvd_func2;
-
- u8 sf_svc_attr;
- u8 func_sf_en;
- u8 lb_mode;
- u8 smf_pg;
-
- u32 max_conn_num;
- u16 max_stick2cache_num;
- u16 max_bfilter_start_addr;
- u16 bfilter_len;
- u16 hash_bucket_num;
-
- /* shared resource */
- u8 host_sf_en;
- u8 master_host_id;
- u8 srv_multi_host_mode;
- u8 virtio_vq_size;
-
- u32 rsvd_func3[5];
-
- /* l2nic */
- u16 nic_max_sq_id;
- u16 nic_max_rq_id;
- u16 nic_default_num_queues;
- u16 rsvd1_nic;
- u32 rsvd2_nic[2];
-
- /* RoCE */
- u32 roce_max_qp;
- u32 roce_max_cq;
- u32 roce_max_srq;
- u32 roce_max_mpt;
- u32 roce_max_drc_qp;
-
- u32 roce_cmtt_cl_start;
- u32 roce_cmtt_cl_end;
- u32 roce_cmtt_cl_size;
-
- u32 roce_dmtt_cl_start;
- u32 roce_dmtt_cl_end;
- u32 roce_dmtt_cl_size;
-
- u32 roce_wqe_cl_start;
- u32 roce_wqe_cl_end;
- u32 roce_wqe_cl_size;
- u8 roce_srq_container_mode;
- u8 rsvd_roce1[3];
- u32 rsvd_roce2[5];
-
- /* IPsec */
- u32 ipsec_max_sactx;
- u16 ipsec_max_cq;
- u16 rsvd_ipsec1;
- u32 rsvd_ipsec[2];
-
- /* OVS */
- u32 ovs_max_qpc;
- u32 rsvd_ovs1[3];
-
- /* ToE */
- u32 toe_max_pctx;
- u32 toe_max_cq;
- u16 toe_max_srq;
- u16 toe_srq_id_start;
- u16 toe_max_mpt;
- u16 toe_max_cctxt;
- u32 rsvd_toe[2];
-
- /* FC */
- u32 fc_max_pctx;
- u32 fc_max_scq;
- u32 fc_max_srq;
-
- u32 fc_max_cctx;
- u32 fc_cctx_id_start;
-
- u8 fc_vp_id_start;
- u8 fc_vp_id_end;
- u8 rsvd_fc1[2];
- u32 rsvd_fc2[5];
-
- /* VBS */
- u16 vbs_max_volq;
- u16 rsvd0_vbs;
- u32 rsvd1_vbs[3];
-
- u16 fake_vf_start_id;
- u16 fake_vf_num;
- u32 fake_vf_max_pctx;
- u16 fake_vf_bfilter_start_addr;
- u16 fake_vf_bfilter_len;
- u32 rsvd_glb[8];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
deleted file mode 100644
index 59e20a1..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/******************************************************************************
- * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
- ******************************************************************************
- File Name : comm_cmdq_intf.h
- Version : Initial Draft
- Description : common command queue interface
- Function List :
- History :
- Modification: Created file
-
-******************************************************************************/
-
-#ifndef COMM_CMDQ_INTF_H
-#define COMM_CMDQ_INTF_H
-
-/* Cmdq ack type */
-enum hinic3_ack_type {
- HINIC3_ACK_TYPE_CMDQ,
- HINIC3_ACK_TYPE_SHARE_CQN,
- HINIC3_ACK_TYPE_APP_CQN,
-
- HINIC3_MOD_ACK_MAX = 15,
-};
-
-/* Defines the queue type of the set arm bit. */
-enum {
- SET_ARM_BIT_FOR_CMDQ = 0,
- SET_ARM_BIT_FOR_L2NIC_SQ,
- SET_ARM_BIT_FOR_L2NIC_RQ,
- SET_ARM_BIT_TYPE_NUM
-};
-
-/* Defines the type. Each function supports a maximum of eight CMDQ types. */
-enum {
- CMDQ_0 = 0,
- CMDQ_1 = 1, /* dedicated and non-blocking queues */
- CMDQ_NUM
-};
-
-/* *******************cmd common command data structure ************************ */
-// Func->ucode, which is used to set arm bit data,
-// The microcode needs to perform big-endian conversion.
-struct comm_info_ucode_set_arm_bit {
- u32 q_type;
- u32 q_id;
-};
-
-/* *******************WQE data structure ************************ */
-union cmdq_wqe_cs_dw0 {
- struct {
- u32 err_status : 29;
- u32 error_code : 2;
- u32 rsvd : 1;
- } bs;
- u32 val;
-};
-
-union cmdq_wqe_cs_dw1 {
- // This structure is used when the driver writes the wqe.
- struct {
- u32 token : 16; // [15:0]
- u32 cmd : 8; // [23:16]
- u32 mod : 5; // [28:24]
- u32 ack_type : 2; // [30:29]
- u32 obit : 1; // [31]
- } drv_wr;
-
- /* The uCode writes back the structure of the CS_DW1. */
- /* The driver reads and uses the structure. */
- struct {
- u32 mod : 5; // [4:0]
- u32 ack_type : 3; // [7:5]
- u32 cmd : 8; // [15:8]
- u32 arm : 1; // [16]
- u32 rsvd : 14; // [30:17]
- u32 obit : 1; // [31]
- } wb;
- u32 val;
-};
-
-/* CmdQ BD information or write back buffer information */
-struct cmdq_sge {
- u32 pa_h; // Upper 32 bits of the physical address
- u32 pa_l; // Upper 32 bits of the physical address
- u32 len; // Invalid bit[31].
- u32 resv;
-};
-
-/* Ctrls section definition of WQE */
-struct cmdq_wqe_ctrls {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
-};
-
-/* Complete section definition of WQE */
-struct cmdq_wqe_cs {
- union cmdq_wqe_cs_dw0 dw0;
- union cmdq_wqe_cs_dw1 dw1;
- union {
- struct cmdq_sge sge;
- u32 dw2_5[4];
- } ack;
-};
-
-/* Inline header in WQE inline, describing the length of inline data */
-union cmdq_wqe_inline_header {
- struct {
- u32 buf_len : 11; // [10:0] inline data len
- u32 rsv : 21; // [31:11]
- } bs;
- u32 val;
-};
-
-/* Definition of buffer descriptor section in WQE */
-union cmdq_wqe_bds {
- struct {
- struct cmdq_sge bds_sge;
- u32 rsvd[4]; /* Zwy is used to transfer the virtual address of the buffer. */
- } lcmd; /* Long command, non-inline, and SGE describe the buffer information. */
-};
-
-/* Definition of CMDQ WQE */
-/* (long cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(16B) |
- * | |
- * +----------------------------------------+
- * | driver section(16B) |
- * +----------------------------------------+
- *
- *
- * (middle cmd, 128B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(88B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- *
- *
- * (short cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(24B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- */
-struct cmdq_wqe {
- struct cmdq_wqe_ctrls ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds bds;
-};
-
-/* Definition of ctrls section in inline WQE */
-struct cmdq_wqe_ctrls_inline {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
- u64 db;
-};
-
-/* Buffer descriptor section definition of WQE */
-union cmdq_wqe_bds_inline {
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[80];
- } mcmd; /* Middle command, inline mode */
-
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[16];
- } scmd; /* Short command, inline mode */
-};
-
-struct cmdq_wqe_inline {
- struct cmdq_wqe_ctrls_inline ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds_inline bds;
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_defs.h b/drivers/net/ethernet/huawei/hinic3/comm_defs.h
deleted file mode 100644
index c5b1913..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_defs.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_defs.h
- * Version : Initial Draft
- * Description : common definitions
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef COMM_DEFS_H
-#define COMM_DEFS_H
-
-/* CMDQ MODULE_TYPE */
-enum hinic3_mod_type {
- HINIC3_MOD_COMM = 0, /* HW communication module */
- HINIC3_MOD_L2NIC = 1, /* L2NIC module */
- HINIC3_MOD_ROCE = 2,
- HINIC3_MOD_PLOG = 3,
- HINIC3_MOD_TOE = 4,
- HINIC3_MOD_FLR = 5,
- HINIC3_MOD_RSVD1 = 6,
- HINIC3_MOD_CFGM = 7, /* Configuration module */
- HINIC3_MOD_CQM = 8,
- HINIC3_MOD_VMSEC = 9,
- COMM_MOD_FC = 10,
- HINIC3_MOD_OVS = 11,
- HINIC3_MOD_DSW = 12,
- HINIC3_MOD_MIGRATE = 13,
- HINIC3_MOD_HILINK = 14,
- HINIC3_MOD_CRYPT = 15, /* secure crypto module */
- HINIC3_MOD_VIO = 16,
- HINIC3_MOD_IMU = 17,
- HINIC3_MOD_DFT = 18, /* DFT */
- HINIC3_MOD_HW_MAX = 19, /* hardware max module id */
- /* Software module id, for PF/VF and multi-host */
- HINIC3_MOD_SW_FUNC = 20,
- HINIC3_MOD_MAX,
-};
-
-/* func reset的flag ,用于指示清理哪种资源 */
-enum func_reset_flag {
- RES_TYPE_FLUSH_BIT = 0,
- RES_TYPE_MQM,
- RES_TYPE_SMF,
- RES_TYPE_PF_BW_CFG,
-
- RES_TYPE_COMM = 10,
- RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_NIC,
- RES_TYPE_OVS,
- RES_TYPE_VBS,
- RES_TYPE_ROCE,
- RES_TYPE_FC,
- RES_TYPE_TOE,
- RES_TYPE_IPSEC,
- RES_TYPE_MAX,
-};
-
-#define HINIC3_COMM_RES \
- ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
- (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
- (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
-
-#define HINIC3_NIC_RES BIT(RES_TYPE_NIC)
-#define HINIC3_OVS_RES BIT(RES_TYPE_OVS)
-#define HINIC3_VBS_RES BIT(RES_TYPE_VBS)
-#define HINIC3_ROCE_RES BIT(RES_TYPE_ROCE)
-#define HINIC3_FC_RES BIT(RES_TYPE_FC)
-#define HINIC3_TOE_RES BIT(RES_TYPE_TOE)
-#define HINIC3_IPSEC_RES BIT(RES_TYPE_IPSEC)
-
-/* MODE OVS、NIC、UNKNOWN */
-#define HINIC3_WORK_MODE_OVS 0
-#define HINIC3_WORK_MODE_UNKNOWN 1
-#define HINIC3_WORK_MODE_NIC 2
-
-#define DEVICE_TYPE_L2NIC 0
-#define DEVICE_TYPE_NVME 1
-#define DEVICE_TYPE_VIRTIO_NET 2
-#define DEVICE_TYPE_VIRTIO_BLK 3
-#define DEVICE_TYPE_VIRTIO_VSOCK 4
-#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
-#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
-#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
-#define DEVICE_TYPE_VIRTIO_HPC 8
-
-/* Common header control information of the COMM message
- * interaction command word between the driver and PF
- */
-struct comm_info_head {
- u8 status;
- u8 version;
- u8 rep_aeq_num;
- u8 rsvd[5];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
deleted file mode 100644
index ae998cf..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_msg_intf.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef COMM_MSG_INTF_H
-#define COMM_MSG_INTF_H
-
-#include "comm_defs.h"
-#include "mgmt_msg_base.h"
-#include "mpu_cmd_base_defs.h"
-#include "mpu_inband_cmd_defs.h"
-
-struct spu_cmd_freq_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: check */
- u8 rsvd[3];
- u32 freq;
-};
-
-struct spu_cmd_power_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: init */
- u8 slave_addr;
- u8 cmd_id;
- u8 size;
- u32 value;
-};
-
-struct spu_cmd_tsensor_operation {
- struct comm_info_head head;
-
- u8 op_code;
- u8 rsvd[3];
- s16 fabric_tsensor_temp_avg;
- s16 fabric_tsensor_temp;
- s16 sys_tsensor_temp_avg;
- s16 sys_tsensor_temp;
-};
-
-enum cfg_msix_operation {
- CFG_MSIX_OPERATION_FREE = 0,
- CFG_MSIX_OPERATION_ALLOC = 1,
-};
-
-struct comm_cmd_ffm_info {
- struct mgmt_msg_head head;
-
- u8 node_id;
- /* error level of the interrupt source */
- u8 err_level;
- /* Classification by interrupt source properties */
- u16 err_type;
- u32 err_csr_addr;
- u32 err_csr_value;
- u32 rsvd1;
-};
-
-struct hinic3_cmd_update_firmware {
- struct mgmt_msg_head msg_head;
-
- struct {
- u32 sl : 1;
- u32 sf : 1;
- u32 flag : 1;
- u32 bit_signed : 1;
- u32 reserved : 12;
- u32 fragment_len : 16;
- } ctl_info;
-
- struct {
- u32 section_crc;
- u32 section_type;
- } section_info;
-
- u32 total_len;
- u32 section_len;
- u32 section_version;
- u32 section_offset;
- u32 data[384];
-};
-
-struct hinic3_cmd_activate_firmware {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-struct hinic3_cmd_switch_config {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
index 8c95032..8c9f849 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
@@ -28,6 +28,8 @@
#include "cqm_npu_cmd.h"
#include "cqm_npu_cmd_defs.h"
+#include "vram_common.h"
+
static void cqm_bat_fill_cla_common_gpa(struct tag_cqm_handle *cqm_handle,
struct tag_cqm_cla_table *cla_table,
struct tag_cqm_bat_entry_standerd *bat_entry_standerd)
@@ -366,6 +368,13 @@ static s32 cqm_bat_update_cmd(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
struct hinic3_hwdev *handle = cqm_handle->ex_handle;
struct tag_cqm_cmdq_bat_update *bat_update_cmd = NULL;
s32 ret = CQM_FAIL;
+ int is_in_kexec;
+
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip updating the cqm_bat to chip during kexec!\n");
+ return CQM_SUCCESS;
+ }
bat_update_cmd = (struct tag_cqm_cmdq_bat_update *)(buf_in->buf);
bat_update_cmd->offset = 0;
@@ -768,8 +777,10 @@ static s32 cqm_cla_xyz_lvl1(struct tag_cqm_handle *cqm_handle,
/* Applying for CLA_Z_BUF Space */
cla_z_buf = &cla_table->cla_z_buf;
cla_z_buf->buf_size = trunk_size;
- cla_z_buf->buf_number = (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
- cla_z_buf->page_number = cla_z_buf->buf_number << cla_table->trunk_order;
+ cla_z_buf->buf_number =
+ (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
+ cla_z_buf->page_number = cla_z_buf->buf_number <<
+ cla_table->trunk_order;
/* All buffer space must be statically allocated. */
if (cla_table->alloc_static) {
@@ -840,6 +851,7 @@ static s32 cqm_cla_xyz_lvl2_xyz_apply(struct tag_cqm_handle *cqm_handle,
cla_x_buf->buf_size = trunk_size;
cla_x_buf->buf_number = 1;
cla_x_buf->page_number = cla_x_buf->buf_number << cla_table->trunk_order;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
ret = cqm_buf_alloc(cqm_handle, cla_x_buf, false);
if (ret != CQM_SUCCESS)
return CQM_FAIL;
@@ -869,14 +881,20 @@ static s32 cqm_cla_xyz_vram_name_init(struct tag_cqm_cla_table *cla_table,
cla_x_buf = &cla_table->cla_x_buf;
cla_z_buf = &cla_table->cla_z_buf;
cla_y_buf = &cla_table->cla_y_buf;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_x_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_X);
+ VRAM_NAME_MAX_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_X);
+ cla_y_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_y_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Y);
+ VRAM_NAME_MAX_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Y);
+ cla_z_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_z_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Z);
+ VRAM_NAME_MAX_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Z);
return CQM_SUCCESS;
}
@@ -1188,7 +1206,7 @@ static void cqm_cla_init_entry_extern(struct tag_cqm_handle *cqm_handle,
* exceed 128 x 4 KB. Otherwise, clearing the timer buffer of
* the function is complex.
*/
- cla_table->trunk_order = CQM_4K_PAGE_ORDER;
+ cla_table->trunk_order = CQM_8K_PAGE_ORDER;
cla_table->max_buffer_size = capability->timer_number *
capability->timer_basic_size;
cla_table->obj_size = capability->timer_basic_size;
@@ -1237,7 +1255,7 @@ static s32 cqm_cla_init_entry_condition(struct tag_cqm_handle *cqm_handle, u32 e
memcpy(cla_table_timer, cla_table, sizeof(struct tag_cqm_cla_table));
snprintf(cla_table_timer->name,
- VRAM_NAME_MAX_LEN - 1, "%s%s%01u", cla_table->name,
+ VRAM_NAME_MAX_LEN, "%s%s%01u", cla_table->name,
VRAM_CQM_CLA_SMF_BASE, i);
if (cqm_cla_xyz(cqm_handle, cla_table_timer) ==
@@ -1268,7 +1286,7 @@ static s32 cqm_cla_init_entry(struct tag_cqm_handle *cqm_handle,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
cla_table->type = bat_table->bat_entry_type[i];
- snprintf(cla_table->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(cla_table->name, VRAM_NAME_MAX_LEN,
"%s%s%s%02u", cqm_handle->name, VRAM_CQM_CLA_BASE,
VRAM_CQM_CLA_TYPE_BASE, cla_table->type);
@@ -1485,11 +1503,11 @@ static s32 cqm_cla_update(struct tag_cqm_handle *cqm_handle,
spu_en = 0;
pa = ((buf_node_parent->pa + (child_index * sizeof(dma_addr_t))) |
- (u32)spu_en);
+ spu_en);
cmd.gpa_h = CQM_ADDR_HI(pa);
cmd.gpa_l = CQM_ADDR_LW(pa);
- pa = (buf_node_child->pa | (u32)spu_en);
+ pa = (buf_node_child->pa | spu_en);
cmd.value_h = CQM_ADDR_HI(pa);
cmd.value_l = CQM_ADDR_LW(pa);
@@ -1979,7 +1997,7 @@ struct tag_cqm_cla_table *cqm_cla_table_get(struct tag_cqm_bat_table *bat_table,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
- if (cla_table && entry_type == cla_table->type)
+ if ((cla_table != NULL) && (entry_type == cla_table->type))
return cla_table;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
index dd0766e..a51c1dc 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
@@ -9,6 +9,7 @@
#include "cqm_bitmap_table.h"
#include "cqm_object.h"
+#include "vram_common.h"
/* When the connection check is enabled, the maximum number of connections
* supported by the chip is 1M - 63, which cannot reach 1M
@@ -19,6 +20,7 @@
#define CLA_TABLE_PAGE_ORDER 0
#define CQM_4K_PAGE_ORDER 0
#define CQM_4K_PAGE_SIZE 4096
+#define CQM_8K_PAGE_ORDER 1
#define CQM_BAT_ENTRY_MAX 16
#define CQM_BAT_ENTRY_SIZE 16
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
index d5fac94..5f095c8 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
@@ -254,8 +254,10 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
}
pages = vmalloc(sizeof(struct page *) * buf->page_number);
- if (!pages)
+ if (!pages) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(pages));
return CQM_FAIL;
+ }
for (i = 0; i < buf->buf_number; i++) {
for (j = 0; j < ((u32)1 << order); j++)
@@ -273,6 +275,11 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
return CQM_SUCCESS;
}
+static bool check_use_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ return buf->buf_info.use_vram ? true : false;
+}
+
static bool check_use_non_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
{
return buf->buf_info.use_vram ? false : true;
@@ -294,11 +301,46 @@ static bool check_for_nouse_node_alloc(struct hinic3_hwdev *handle, struct tag_c
return false;
}
+static s32 cqm_buf_vram_kalloc(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ void *vaddr = NULL;
+ int i;
+
+ vaddr = hi_vram_kalloc(buf->buf_info.buf_vram_name, (u64)buf->buf_size * buf->buf_number);
+ if (!vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
+ return CQM_FAIL;
+ }
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = (void *)((char *)vaddr + i * (u64)buf->buf_size);
+
+ return CQM_SUCCESS;
+}
+
+static void cqm_buf_vram_free(struct tag_cqm_buf *buf)
+{
+ s32 i;
+
+ if (buf->buf_list == NULL)
+ return;
+
+ if (buf->buf_list[0].va)
+ hi_vram_kfree(buf->buf_list[0].va, buf->buf_info.buf_vram_name,
+ (u64)buf->buf_size * buf->buf_number);
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = NULL;
+}
+
static void cqm_buf_free_page_common(struct tag_cqm_buf *buf)
{
u32 order;
s32 i;
+ if (buf->buf_list == NULL)
+ return;
+
order = (u32)get_order(buf->buf_size);
for (i = 0; i < (s32)buf->buf_number; i++) {
@@ -320,8 +362,10 @@ static s32 cqm_buf_use_node_alloc_page(struct hinic3_hwdev *handle, struct tag_c
node = dev_to_node(handle->dev_hdl);
for (i = 0; i < (s32)buf->buf_number; i++) {
newpage = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, order);
- if (!newpage)
+ if (!newpage) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
va = (void *)page_address(newpage);
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
@@ -349,8 +393,10 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
for (i = 0; i < (s32)buf->buf_number; i++) {
va = (void *)ossl_get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
- if (!va)
+ if (!va) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
* value must be 0.
@@ -367,21 +413,21 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
return CQM_SUCCESS;
}
-#define MALLOC_FUNCS_COUNT 2
-#define FREE_FUNCS_COUNT 1
-static const struct malloc_memory g_malloc_funcs[MALLOC_FUNCS_COUNT] = {
+static const struct malloc_memory g_malloc_funcs[] = {
+ {check_use_vram, cqm_buf_vram_kalloc},
{check_for_use_node_alloc, cqm_buf_use_node_alloc_page},
{check_for_nouse_node_alloc, cqm_buf_unused_node_alloc_page}
};
-static const struct free_memory g_free_funcs[FREE_FUNCS_COUNT] = {
+static const struct free_memory g_free_funcs[] = {
+ {check_use_vram, cqm_buf_vram_free},
{check_use_non_vram, cqm_buf_free_page_common}
};
static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *buf)
{
struct hinic3_hwdev *handle = cqm_handle->ex_handle;
- u32 malloc_funcs_num = MALLOC_FUNCS_COUNT;
+ u32 malloc_funcs_num = ARRAY_SIZE(g_malloc_funcs);
u32 i;
for (i = 0; i < malloc_funcs_num; i++) {
@@ -398,7 +444,7 @@ static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
static void cqm_buf_free_page(struct tag_cqm_buf *buf)
{
- u32 free_funcs_num = FREE_FUNCS_COUNT;
+ u32 free_funcs_num = ARRAY_SIZE(g_free_funcs);
u32 i;
for (i = 0; i < free_funcs_num; i++) {
@@ -447,8 +493,11 @@ static s32 cqm_buf_get_secure_mem_pages(struct tag_cqm_handle *cqm_handle, struc
cqm_get_secure_mem_pages(handle,
(u32)get_order(buf->buf_size),
&buf->buf_list[i].pa);
- if (!buf->buf_list[i].va)
+ if (!buf->buf_list[i].va) {
+ cqm_err(handle->dev_hdl,
+ CQM_ALLOC_FAIL(cqm_get_secure_mem_pages));
break;
+ }
}
if (i != buf->buf_number) {
@@ -777,7 +826,12 @@ static s32 cqm_single_bitmap_init(struct tag_cqm_bitmap *bitmap)
*/
bit_number = (ALIGN(bitmap->max_num, CQM_NUM_BIT_BYTE) >>
CQM_BYTE_BIT_SHIFT);
- bitmap->table = vmalloc(bit_number);
+ if (bitmap->bitmap_info.use_vram != 0)
+ bitmap->table = hi_vram_kalloc(
+ bitmap->bitmap_info.buf_vram_name,
+ bit_number);
+ else
+ bitmap->table = vmalloc(bit_number);
if (!bitmap->table)
return CQM_FAIL;
memset(bitmap->table, 0, bit_number);
@@ -856,7 +910,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
}
bitmap = &cla_table->bitmap;
- snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_MAX_LEN,
"%s%s%02d", cla_table->name,
VRAM_CQM_BITMAP_BASE, cla_table->type);
@@ -866,6 +920,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
bitmap->reserved_top = capability->qpc_reserved;
bitmap->reserved_back = capability->qpc_reserved_back;
bitmap->last = capability->qpc_reserved;
+ bitmap->bitmap_info.use_vram = get_use_vram_flag();
cqm_info(handle->dev_hdl,
"Bitmap init: cla_table_type=%u, max_num=0x%x\n",
cla_table->type, bitmap->max_num);
@@ -945,7 +1000,14 @@ void cqm_bitmap_uninit(struct tag_cqm_handle *cqm_handle)
if (cla_table->type != CQM_BAT_ENTRY_T_INVALID &&
bitmap->table) {
spin_lock_deinit(&bitmap->lock);
- vfree(bitmap->table);
+ if (bitmap->bitmap_info.use_vram != 0)
+ hi_vram_kfree(bitmap->table,
+ bitmap->bitmap_info.buf_vram_name,
+ ALIGN(bitmap->max_num,
+ CQM_NUM_BIT_BYTE) >>
+ CQM_BYTE_BIT_SHIFT);
+ else
+ vfree(bitmap->table);
bitmap->table = NULL;
}
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
index 7febf76..06b8661 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
@@ -9,6 +9,7 @@
#include <linux/spinlock.h>
#include "cqm_object.h"
+#include "vram_common.h"
struct tag_cqm_bitmap {
ulong *table;
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
index 9a13ae0..2a24e4a 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
@@ -196,6 +196,13 @@ void *cqm_get_db_addr(void *ex_handle, u32 service_type)
pr_err("[CQM]%s: ex_handle is null\n", __func__);
return NULL;
}
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return NULL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -218,6 +225,17 @@ s32 cqm_ring_hardware_db(void *ex_handle, u32 service_type, u8 db_count, u64 db)
struct tag_cqm_service *service = NULL;
struct hinic3_hwdev *handle = NULL;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -278,6 +296,17 @@ s32 cqm_ring_direct_wqe_db(void *ex_handle, u32 service_type, u8 db_count,
u64 *tmp = (u64 *)direct_wqe;
int i;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
index 19a8b56..1f1235c 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
@@ -23,6 +23,8 @@
#include "cqm_memsec.h"
#include "cqm_main.h"
+#include "vram_common.h"
+
static unsigned char roce_qpc_rsv_mode = CQM_QPC_ROCE_NORMAL;
module_param(roce_qpc_rsv_mode, byte, 0644);
MODULE_PARM_DESC(roce_qpc_rsv_mode,
@@ -98,10 +100,17 @@ static s32 cqm_set_timer_enable(void *ex_handle)
{
struct hinic3_hwdev *handle = (struct hinic3_hwdev *)ex_handle;
struct tag_cqm_handle *cqm_handle = NULL;
+ int is_in_kexec;
if (!ex_handle)
return CQM_FAIL;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip starting cqm timer during kexec\n");
+ return CQM_SUCCESS;
+ }
+
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
if (cqm_handle->func_capability.fake_func_type == CQM_FAKE_FUNC_PARENT &&
cqm_set_fake_vf_timer(cqm_handle) != CQM_SUCCESS)
@@ -473,7 +482,8 @@ static void cqm_service_capability_init_roce(struct tag_cqm_handle *cqm_handle,
func_cap->qpc_number += roce_own_cap->max_qps;
func_cap->qpc_basic_size = GET_MAX(roce_own_cap->qpc_entry_sz,
func_cap->qpc_basic_size);
- if (cqm_handle->func_attribute.func_type == CQM_PF && (IS_MASTER_HOST(handle))) {
+ if (cqm_handle->func_attribute.func_type == CQM_PF &&
+ (IS_MASTER_HOST(handle))) {
func_cap->hash_number = roce_own_cap->max_qps;
func_cap->hash_basic_size = CQM_HASH_BUCKET_SIZE_64;
}
@@ -1129,8 +1139,9 @@ static s32 cqm_fake_mem_init(struct tag_cqm_handle *cqm_handle)
for (i = 0; i < (u32)child_func_number; i++) {
fake_cqm_handle = cqm_handle->fake_cqm_handle[i];
- snprintf(fake_cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
- "%s%s%02u", cqm_handle->name, VRAM_CQM_FAKE_MEM_BASE, i);
+ snprintf(fake_cqm_handle->name, VRAM_NAME_MAX_LEN,
+ "%s%s%02u", cqm_handle->name,
+ VRAM_CQM_FAKE_MEM_BASE, i);
if (cqm_bat_init(fake_cqm_handle) != CQM_SUCCESS) {
cqm_err(handle->dev_hdl,
@@ -1174,8 +1185,9 @@ s32 cqm_mem_init(void *ex_handle)
struct tag_cqm_handle *cqm_handle = NULL;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
- snprintf(cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
- "%s%02u", VRAM_CQM_GLB_FUNC_BASE, hinic3_global_func_id(handle));
+ snprintf(cqm_handle->name, VRAM_NAME_MAX_LEN,
+ "%s%02u", VRAM_CQM_GLB_FUNC_BASE,
+ hinic3_global_func_id(handle));
if (cqm_fake_init(cqm_handle) != CQM_SUCCESS) {
cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_fake_init));
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
index 4f87bd1..8d1e481 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
@@ -362,6 +362,7 @@ s32 cqm_fake_vf_num_set(void *ex_handle, u16 fake_vf_num_cfg);
#define CQM_LOG_ID 0
#define CQM_PTR_NULL(x) "%s: " #x " is null\n", __func__
+#define CQM_ALLOC_FAIL(x) "%s: " #x " alloc fail\n", __func__
#define CQM_MAP_FAIL(x) "%s: " #x " map fail\n", __func__
#define CQM_FUNCTION_FAIL(x) "%s: " #x " return failure\n", __func__
#define CQM_WRONG_VALUE(x) "%s: " #x " %u is wrong\n", __func__, (u32)(x)
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
index 213803f..f5fce8f 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
@@ -378,7 +378,7 @@ static int hinic3_secure_mem_proc_node_remove(void *hwdev)
atomic_dec(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
@@ -401,7 +401,7 @@ static int hinic3_secure_mem_proc_node_add(void *hwdev)
atomic_inc(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
/* 0400 Read by owner */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h b/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
deleted file mode 100644
index ad732c3..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2019-2022. All rights reserved.
- * File Name : hinic3_comm_cmd.h
- * Version : Initial Draft
- * Created : 2019/4/25
- * Last Modified :
- * Description : COMM Commands between Driver and MPU
- * Function List :
- */
-
-#ifndef HINIC3_COMMON_CMD_H
-#define HINIC3_COMMON_CMD_H
-
-/* COMM Commands between Driver to MPU */
-enum hinic3_mgmt_cmd {
- /* flr及资源清理相关命令 */
- COMM_MGMT_CMD_FUNC_RESET = 0,
- COMM_MGMT_CMD_FEATURE_NEGO,
- COMM_MGMT_CMD_FLUSH_DOORBELL,
- COMM_MGMT_CMD_START_FLUSH,
- COMM_MGMT_CMD_SET_FUNC_FLR,
- COMM_MGMT_CMD_GET_GLOBAL_ATTR,
- COMM_MGMT_CMD_SET_PPF_FLR_TYPE,
- COMM_MGMT_CMD_SET_FUNC_SVC_USED_STATE,
-
- /* 分配msi-x中断资源 */
- COMM_MGMT_CMD_CFG_MSIX_NUM = 10,
-
- /* 驱动相关配置命令 */
- COMM_MGMT_CMD_SET_CMDQ_CTXT = 20,
- COMM_MGMT_CMD_SET_VAT,
- COMM_MGMT_CMD_CFG_PAGESIZE,
- COMM_MGMT_CMD_CFG_MSIX_CTRL_REG,
- COMM_MGMT_CMD_SET_CEQ_CTRL_REG,
- COMM_MGMT_CMD_SET_DMA_ATTR,
-
- /* INFRA配置相关命令字 */
- COMM_MGMT_CMD_GET_MQM_FIX_INFO = 40,
- COMM_MGMT_CMD_SET_MQM_CFG_INFO,
- COMM_MGMT_CMD_SET_MQM_SRCH_GPA,
- COMM_MGMT_CMD_SET_PPF_TMR,
- COMM_MGMT_CMD_SET_PPF_HT_GPA,
- COMM_MGMT_CMD_SET_FUNC_TMR_BITMAT,
- COMM_MGMT_CMD_SET_MBX_CRDT,
- COMM_MGMT_CMD_CFG_TEMPLATE,
- COMM_MGMT_CMD_SET_MQM_LIMIT,
-
- /* 信息获取相关命令字 */
- COMM_MGMT_CMD_GET_FW_VERSION = 60,
- COMM_MGMT_CMD_GET_BOARD_INFO,
- COMM_MGMT_CMD_SYNC_TIME,
- COMM_MGMT_CMD_GET_HW_PF_INFOS,
- COMM_MGMT_CMD_SEND_BDF_INFO,
- COMM_MGMT_CMD_GET_VIRTIO_BDF_INFO,
- COMM_MGMT_CMD_GET_SML_TABLE_INFO,
- COMM_MGMT_CMD_GET_SDI_INFO,
-
- /* 升级相关命令字 */
- COMM_MGMT_CMD_UPDATE_FW = 80,
- COMM_MGMT_CMD_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_DONE_NOTICE,
- COMM_MGMT_CMD_SWITCH_CFG,
- COMM_MGMT_CMD_CHECK_FLASH,
- COMM_MGMT_CMD_CHECK_FLASH_RW,
- COMM_MGMT_CMD_RESOURCE_CFG,
- COMM_MGMT_CMD_UPDATE_BIOS, /* TODO: merge to COMM_MGMT_CMD_UPDATE_FW */
- COMM_MGMT_CMD_MPU_GIT_CODE,
-
- /* chip reset相关 */
- COMM_MGMT_CMD_FAULT_REPORT = 100,
- COMM_MGMT_CMD_WATCHDOG_INFO,
- COMM_MGMT_CMD_MGMT_RESET,
- COMM_MGMT_CMD_FFM_SET, /* TODO: check if needed */
-
- /* chip info/log 相关 */
- COMM_MGMT_CMD_GET_LOG = 120,
- COMM_MGMT_CMD_TEMP_OP,
- COMM_MGMT_CMD_EN_AUTO_RST_CHIP,
- COMM_MGMT_CMD_CFG_REG,
- COMM_MGMT_CMD_GET_CHIP_ID,
- COMM_MGMT_CMD_SYSINFO_DFX,
- COMM_MGMT_CMD_PCIE_DFX_NTC,
- COMM_MGMT_CMD_DICT_LOG_STATUS, /* LOG STATUS 127 */
- COMM_MGMT_CMD_MSIX_INFO,
- COMM_MGMT_CMD_CHANNEL_DETECT,
- COMM_MGMT_CMD_DICT_COUNTER_STATUS,
-
- /* switch workmode 相关 */
- COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140,
- COMM_MGMT_CMD_SWITCH_WORKMODE,
-
- /* mpu 相关 */
- COMM_MGMT_CMD_MIGRATE_DFX_HPA = 150,
- COMM_MGMT_CMD_BDF_INFO,
- COMM_MGMT_CMD_NCSI_CFG_INFO_GET_PROC,
-
- /* rsvd0 section */
- COMM_MGMT_CMD_SECTION_RSVD_0 = 160,
-
- /* rsvd1 section */
- COMM_MGMT_CMD_SECTION_RSVD_1 = 170,
-
- /* rsvd2 section */
- COMM_MGMT_CMD_SECTION_RSVD_2 = 180,
-
- /* rsvd3 section */
- COMM_MGMT_CMD_SECTION_RSVD_3 = 190,
-
- /* TODO: move to DFT mode */
- COMM_MGMT_CMD_GET_DIE_ID = 200,
- COMM_MGMT_CMD_GET_EFUSE_TEST,
- COMM_MGMT_CMD_EFUSE_INFO_CFG,
- COMM_MGMT_CMD_GPIO_CTL,
- COMM_MGMT_CMD_HI30_SERLOOP_START, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_SERLOOP_STOP, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_SET_FLAG, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_GET_RESULT, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_ECC_TEST,
- COMM_MGMT_CMD_FUNC_BIST_TEST, /* 209 */
-
- COMM_MGMT_CMD_VPD_SET = 210,
- COMM_MGMT_CMD_VPD_GET,
-
- COMM_MGMT_CMD_ERASE_FLASH,
- COMM_MGMT_CMD_QUERY_FW_INFO,
- COMM_MGMT_CMD_GET_CFG_INFO,
- COMM_MGMT_CMD_GET_UART_LOG,
- COMM_MGMT_CMD_SET_UART_CMD,
- COMM_MGMT_CMD_SPI_TEST,
-
- /* TODO: ALL reg read/write merge to COMM_MGMT_CMD_CFG_REG */
- COMM_MGMT_CMD_UP_REG_GET,
- COMM_MGMT_CMD_UP_REG_SET, /* 219 */
-
- COMM_MGMT_CMD_REG_READ = 220,
- COMM_MGMT_CMD_REG_WRITE,
- COMM_MGMT_CMD_MAG_REG_WRITE,
- COMM_MGMT_CMD_ANLT_REG_WRITE,
-
- COMM_MGMT_CMD_HEART_EVENT, /* TODO: delete */
- COMM_MGMT_CMD_NCSI_OEM_GET_DRV_INFO, /* TODO: delete */
- COMM_MGMT_CMD_LASTWORD_GET,
- COMM_MGMT_CMD_READ_BIN_DATA, /* TODO: delete */
- /* COMM_MGMT_CMD_WWPN_GET, TODO: move to FC? */
- /* COMM_MGMT_CMD_WWPN_SET, TODO: move to FC? */ /* 229 */
-
- /* TODO: check if needed */
- COMM_MGMT_CMD_SET_VIRTIO_DEV = 230,
- COMM_MGMT_CMD_SET_MAC,
- /* MPU patch cmd */
- COMM_MGMT_CMD_LOAD_PATCH,
- COMM_MGMT_CMD_REMOVE_PATCH,
- COMM_MGMT_CMD_PATCH_ACTIVE,
- COMM_MGMT_CMD_PATCH_DEACTIVE,
- COMM_MGMT_CMD_PATCH_SRAM_OPTIMIZE,
- /* container host process */
- COMM_MGMT_CMD_CONTAINER_HOST_PROC,
- /* nsci counter */
- COMM_MGMT_CMD_NCSI_COUNTER_PROC,
- COMM_MGMT_CMD_CHANNEL_STATUS_CHECK, /* 239 */
-
- /* hot patch rsvd cmd */
- COMM_MGMT_CMD_RSVD_0 = 240,
- COMM_MGMT_CMD_RSVD_1,
- COMM_MGMT_CMD_RSVD_2,
- COMM_MGMT_CMD_RSVD_3,
- COMM_MGMT_CMD_RSVD_4,
- /* 无效字段,版本收编删除,编译使用 */
- COMM_MGMT_CMD_SEND_API_ACK_BY_UP,
-
- /* 注:添加cmd,不能修改已有命令字的值,请在前方rsvd
- * section中添加;原则上所有分支cmd表完全一致
- */
- COMM_MGMT_CMD_MAX = 255,
-};
-
-/* CmdQ Common subtype */
-enum comm_cmdq_cmd {
- COMM_CMD_UCODE_ARM_BIT_SET = 2,
- COMM_CMD_SEND_NPU_DFT_CMD,
-};
-
-#endif /* HINIC3_COMMON_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
deleted file mode 100644
index 9ce908e..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_COMMON_H
-#define HINIC3_COMMON_H
-
-#include <linux/types.h>
-
-struct hinic3_dma_addr_align {
- u32 real_size;
-
- void *ori_vaddr;
- dma_addr_t ori_paddr;
-
- void *align_vaddr;
- dma_addr_t align_paddr;
-};
-
-enum hinic3_wait_return {
- WAIT_PROCESS_CPL = 0,
- WAIT_PROCESS_WAITING = 1,
- WAIT_PROCESS_ERR = 2,
-};
-
-struct hinic3_sge {
- u32 hi_addr;
- u32 lo_addr;
- u32 len;
-};
-
-#ifdef static
-#undef static
-#define LLT_STATIC_DEF_SAVED
-#endif
-
-/* *
- * hinic_cpu_to_be32 - convert data to big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert, must be Multiple of 4B
- */
-static inline void hinic3_cpu_to_be32(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = cpu_to_be32(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_cpu_to_be32 - convert data from big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert
- */
-static inline void hinic3_be32_to_cpu(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = be32_to_cpu(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_set_sge - set dma area in scatter gather entry
- * @sge: scatter gather entry
- * @addr: dma address
- * @len: length of relevant data in the dma address
- */
-static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
- int len)
-{
- sge->hi_addr = upper_32_bits(addr);
- sge->lo_addr = lower_32_bits(addr);
- sge->len = len;
-}
-
-#define hinic3_hw_be32(val) (val)
-#define hinic3_hw_cpu32(val) (val)
-#define hinic3_hw_cpu16(val) (val)
-
-static inline void hinic3_hw_be32_len(void *data, int len)
-{
-}
-
-static inline void hinic3_hw_cpu32_len(void *data, int len)
-{
-}
-
-int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
- unsigned int flag,
- struct hinic3_dma_addr_align *mem_align);
-
-void hinic3_dma_free_coherent_align(void *dev_hdl,
- struct hinic3_dma_addr_align *mem_align);
-
-typedef enum hinic3_wait_return (*wait_cpl_handler)(void *priv_data);
-
-int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
- u32 wait_total_ms, u32 wait_once_us);
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
index 64139c4..4f5792f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
@@ -8,7 +8,7 @@
#include "mpu_cmd_base_defs.h"
-#define HINIC3_DRV_VERSION "15.17.1.2"
+#define HINIC3_DRV_VERSION "17.7.8.1"
#define HINIC3_DRV_DESC "Intelligent Network Interface Card Driver"
#define HIUDK_DRV_DESC "Intelligent Network Unified Driver"
@@ -45,6 +45,7 @@ enum hinic3_service_type {
SERVICE_T_CUSTOM,
SERVICE_T_VROCE,
SERVICE_T_CRYPT,
+ SERVICE_T_VSOCK,
SERVICE_T_BIFUR,
SERVICE_T_MAX,
@@ -64,6 +65,9 @@ struct nic_service_cap {
u16 max_sqs;
u16 max_rqs;
u16 default_num_queues;
+ u16 outband_vlan_cfg_en;
+ u8 lro_enable;
+ u8 rsvd1[3];
};
struct ppa_service_cap {
@@ -909,6 +913,13 @@ int hinic3_get_mgmt_version(void *hwdev, u8 *mgmt_ver, u8 version_size,
int hinic3_get_fw_version(void *hwdev, struct hinic3_fw_version *fw_ver,
u16 channel);
+/* *
+ * @brief hinic3_get_bond_create_mode - get bond create mode
+ * @param hwdev: device pointer to hwdev
+ * @retval global function id
+ */
+u8 hinic3_get_bond_create_mode(void *udkdev);
+
/* *
* @brief hinic3_global_func_id - get global function id
* @param hwdev: device pointer to hwdev
@@ -1263,4 +1274,7 @@ int hinic3_mbox_to_host_sync(void *hwdev, enum hinic3_mod_type mod,
int hinic3_get_func_vroce_enable(void *hwdev, u16 glb_func_idx, u8 *en);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type);
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
index 40ff473..8f5bb32 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
@@ -18,9 +18,10 @@
#include "hinic3_tx.h"
#include "hinic3_dcb.h"
#include "hinic3_nic.h"
-#include "hinic3_mgmt_interface.h"
+#include "hinic3_bond.h"
+#include "nic_mpu_cmd_defs.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
typedef int (*nic_driv_module)(struct hinic3_nic_dev *nic_dev,
const void *buf_in, u32 in_size,
@@ -34,7 +35,6 @@ struct nic_drv_module_handle {
static int get_nic_drv_version(void *buf_out, const u32 *out_size)
{
struct drv_version_info *ver_info = buf_out;
- int err;
if (!buf_out) {
pr_err("Buf_out is NULL.\n");
@@ -47,10 +47,8 @@ static int get_nic_drv_version(void *buf_out, const u32 *out_size)
return -EINVAL;
}
- err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
- HINIC3_NIC_DRV_VERSION, "2023-05-17_19:56:38");
- if (err < 0)
- return -EINVAL;
+ snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
+ HINIC3_NIC_DRV_VERSION, "2025-05-08_00:00:08");
return 0;
}
@@ -126,7 +124,8 @@ static int get_tx_wqe_info(struct hinic3_nic_dev *nic_dev,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -178,7 +177,8 @@ static int get_rx_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
rq_info->delta = (u16)nic_dev->rxqs[q_id].delta;
- rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx & nic_dev->rxqs[q_id].q_mask);
+ rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx &
+ nic_dev->rxqs[q_id].q_mask);
rq_info->sw_pi = nic_dev->rxqs[q_id].next_to_update;
rq_info->msix_vector = nic_dev->rxqs[q_id].irq_id;
@@ -201,7 +201,8 @@ static int get_rx_wqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -230,7 +231,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EFAULT;
}
- if (!buf_in || !buf_out) {
+ if (!buf_in || !buf_out || !out_size) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Buf_in or buf_out is NULL.\n");
return -EINVAL;
@@ -243,7 +244,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EINVAL;
}
- if (!out_size || *out_size != sizeof(struct hinic3_rq_cqe)) {
+ if (*out_size != sizeof(struct hinic3_rq_cqe)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(struct hinic3_rq_cqe));
@@ -252,10 +253,12 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
q_id = (u16)info->q_id;
idx = (u16)info->wqe_id;
- if (q_id >= nic_dev->q_params.num_qps || idx >= nic_dev->rxqs[q_id].q_depth) {
+ if (q_id >= nic_dev->q_params.num_qps ||
+ idx >= nic_dev->rxqs[q_id].q_depth) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid q_id[%u] >= %u, or wqe idx[%u] >= %u.\n",
- q_id, nic_dev->q_params.num_qps, idx, nic_dev->rxqs[q_id].q_depth);
+ q_id, nic_dev->q_params.num_qps, idx,
+ nic_dev->rxqs[q_id].q_depth);
return -EFAULT;
}
@@ -338,7 +341,8 @@ static int set_loopback_mode(struct hinic3_nic_dev *nic_dev, const void *buf_in,
err = hinic3_set_loopback_mode(nic_dev->hwdev, (u8)mode->loop_mode,
(u8)mode->loop_ctrl);
if (err == 0)
- nicif_info(nic_dev, drv, nic_dev->netdev, "Set loopback mode %u en %u succeed\n",
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Set loopback mode %u en %u succeed\n",
mode->loop_mode, mode->loop_ctrl);
return err;
@@ -417,6 +421,59 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
{
u32 pf_bw_limit;
int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
+
+ if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To set VF bandwidth rate, please use ip link cmd\n");
+ return -EINVAL;
+ }
+
+ if (!buf_in || !buf_out || in_size != sizeof(u32) ||
+ !out_size || *out_size != sizeof(u8))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_TX;
+ pf_bw_limit = *((u32 *)buf_in);
+
+ err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
+ if (err) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %u%%\n",
+ pf_bw_limit);
+ if (err < 0)
+ return err;
+ }
+
+ *((u8 *)buf_out) = (u8)err;
+
+ return 0;
+}
+
+static int set_rx_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ u32 pf_bw_limit;
+ int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
nicif_err(nic_dev, drv, nic_dev->netdev, "To set VF bandwidth rate, please use ip link cmd\n");
@@ -426,11 +483,16 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || !buf_out || in_size != sizeof(u32) || !out_size || *out_size != sizeof(u8))
return -EINVAL;
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_RX;
pf_bw_limit = *((u32 *)buf_in);
err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %d%%\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to set pf bandwidth limit to %d%%\n",
pf_bw_limit);
if (err < 0)
return err;
@@ -445,19 +507,21 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
struct hinic3_nic_io *nic_io = NULL;
+ u32 *rate_limit = (u32 *)buf_out;
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "To get VF bandwidth rate, please use ip link cmd\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To get VF bandwidth rate, please use ip link cmd\n");
return -EINVAL;
}
if (!buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(u32)) {
+ if (*out_size != sizeof(u32) * 2) { // 2:Stored in an array, TX and RX, both length are u32
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user: %d, expect: %lu\n",
- *out_size, sizeof(u32));
+ *out_size, sizeof(u32) * 2);
return -EFAULT;
}
@@ -465,8 +529,12 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!nic_io)
return -EINVAL;
- *((u32 *)buf_out) = nic_io->nic_cfg.pf_bw_limit;
+ rate_limit[HINIC3_NIC_RX] = nic_io->nic_cfg.pf_bw_rx_limit;
+ rate_limit[HINIC3_NIC_TX] = nic_io->nic_cfg.pf_bw_tx_limit;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "read rate cfg success rx rate is: %u, tx rate is : %u\n",
+ rate_limit[HINIC3_NIC_RX], rate_limit[HINIC3_NIC_TX]);
return 0;
}
@@ -477,8 +545,8 @@ static int get_sset_count(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || in_size != sizeof(u32) || !out_size ||
*out_size != sizeof(u32) || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
@@ -504,16 +572,16 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
int err;
if (!buf_in || in_size != sizeof(u32) || !out_size || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
size = sizeof(u32);
err = get_sset_count(nic_dev, buf_in, in_size, &count, &size);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Get sset count failed, ret=%d\n",
- err);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Get sset count failed, ret=%d\n", err);
return -EINVAL;
}
if (count * sizeof(*items) != *out_size) {
@@ -527,12 +595,14 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
switch (sset) {
case HINIC3_SHOW_SSET_IO_STATS:
- hinic3_get_io_stats(nic_dev, items);
+ err = hinic3_get_io_stats(nic_dev, items);
+ if (err < 0)
+ return -EINVAL;
break;
default:
- nicif_err(nic_dev, drv, nic_dev->netdev, "Unknown %u to get stats\n",
- sset);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unknown %u to get stats\n", sset);
err = -EINVAL;
break;
}
@@ -544,15 +614,18 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int i;
u8 cos_num = 0, valid_cos_bitmap = 0;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_PCP2COS) {
for (i = 0; i < NIC_DCB_UP_MAX; i++) {
- if (!(nic_dev->func_dft_cos_bitmap & BIT(qos_in->pcp2cos[i]))) {
+ if (!(dcb->func_dft_cos_bitmap &
+ BIT(qos_in->pcp2cos[i]))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- qos_in->pcp2cos[i], nic_dev->func_dft_cos_bitmap);
+ qos_in->pcp2cos[i],
+ dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -562,7 +635,8 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
}
- memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos, sizeof(qos_in->pcp2cos));
+ memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos,
+ sizeof(qos_in->pcp2cos));
wanted_dcb_cfg->pcp_user_cos_num = cos_num;
wanted_dcb_cfg->pcp_valid_cos_map = valid_cos_bitmap;
}
@@ -572,12 +646,14 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = 0;
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++) {
u8 cos = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->wanted_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ dcb->wanted_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
- if (cos >= NIC_DCB_UP_MAX || !(nic_dev->func_dft_cos_bitmap & BIT(cos))) {
+ if (cos >= NIC_DCB_UP_MAX ||
+ !(dcb->func_dft_cos_bitmap & BIT(cos))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- cos, nic_dev->func_dft_cos_bitmap);
+ cos, dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -588,8 +664,10 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- wanted_dcb_cfg->dscp2cos[i] = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->hw_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ wanted_dcb_cfg->dscp2cos[i] =
+ qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
+ dcb->hw_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
wanted_dcb_cfg->dscp_user_cos_num = cos_num;
wanted_dcb_cfg->dscp_valid_cos_map = valid_cos_bitmap;
}
@@ -601,11 +679,12 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int ret;
u8 cos_num, valid_cos_bitmap;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_TRUST) {
- if (qos_in->trust > DCB_DSCP) {
+ if (qos_in->trust > HINIC3_DCB_DSCP) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid trust=%u\n", qos_in->trust);
return -EINVAL;
@@ -615,7 +694,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
}
if (qos_in->cfg_bitmap & CMD_QOS_DEV_DFT_COS) {
- if (!(BIT(qos_in->dft_cos) & nic_dev->func_dft_cos_bitmap)) {
+ if (!(BIT(qos_in->dft_cos) & dcb->func_dft_cos_bitmap)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid dft_cos=%u\n", qos_in->dft_cos);
return -EINVAL;
@@ -628,7 +707,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
if (ret)
return ret;
- if (wanted_dcb_cfg->trust == DCB_PCP) {
+ if (wanted_dcb_cfg->trust == HINIC3_DCB_PCP) {
cos_num = wanted_dcb_cfg->pcp_user_cos_num;
valid_cos_bitmap = wanted_dcb_cfg->pcp_valid_cos_map;
} else {
@@ -636,18 +715,11 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = wanted_dcb_cfg->dscp_valid_cos_map;
}
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "DCB is on, cos num should not more than channel num:%u\n",
- nic_dev->q_params.num_qps);
- return -EOPNOTSUPP;
- }
- }
-
if (!(BIT(wanted_dcb_cfg->default_cos) & valid_cos_bitmap)) {
- nicif_info(nic_dev, drv, nic_dev->netdev, "Current default_cos=%u, change to %u\n",
- wanted_dcb_cfg->default_cos, (u8)fls(valid_cos_bitmap) - 1);
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Current default_cos=%u, change to %u\n",
+ wanted_dcb_cfg->default_cos,
+ (u8)fls(valid_cos_bitmap) - 1);
wanted_dcb_cfg->default_cos = (u8)fls(valid_cos_bitmap) - 1;
}
@@ -657,6 +729,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_dev_cfg *qos_in = buf_in;
struct hinic3_mt_qos_dev_cfg *qos_out = buf_out;
u8 i;
@@ -675,9 +748,10 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(qos_out, qos_in, sizeof(*qos_in));
qos_out->head.status = 0;
if (qos_in->op_code & MT_DCB_OPCODE_WR) {
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg,
+ memcpy(&dcb->wanted_dcb_cfg, &dcb->hw_dcb_cfg,
sizeof(struct hinic3_dcb_config));
- err = update_wanted_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg, qos_in);
+ err = update_wanted_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg,
+ qos_in);
if (err) {
qos_out->head.status = MT_EINVAL;
return 0;
@@ -687,12 +761,12 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
qos_out->head.status = MT_EIO;
} else {
- qos_out->dft_cos = nic_dev->hw_dcb_cfg.default_cos;
- qos_out->trust = nic_dev->hw_dcb_cfg.trust;
+ qos_out->dft_cos = dcb->hw_dcb_cfg.default_cos;
+ qos_out->trust = dcb->hw_dcb_cfg.trust;
for (i = 0; i < NIC_DCB_UP_MAX; i++)
- qos_out->pcp2cos[i] = nic_dev->hw_dcb_cfg.pcp2cos[i];
+ qos_out->pcp2cos[i] = dcb->hw_dcb_cfg.pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- qos_out->dscp2cos[i] = nic_dev->hw_dcb_cfg.dscp2cos[i];
+ qos_out->dscp2cos[i] = dcb->hw_dcb_cfg.dscp2cos[i];
}
return 0;
@@ -721,27 +795,17 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(dcb_out, dcb_in, sizeof(*dcb_in));
dcb_out->head.status = 0;
if (dcb_in->op_code & MT_DCB_OPCODE_WR) {
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) == dcb_in->state)
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ==
+ dcb_in->state)
return 0;
- if (dcb_in->state) {
- if (user_cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "cos num %u should not more than channel num %u\n",
- user_cos_num,
- nic_dev->q_params.num_qps);
-
- return -EOPNOTSUPP;
- }
- }
-
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? user_cos_num : 0,
+ err = hinic3_setup_cos(nic_dev->netdev,
+ dcb_in->state ? user_cos_num : 0,
netif_run);
if (err)
goto setup_cos_fail;
@@ -751,7 +815,6 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
goto vport_up_fail;
}
- rtnl_unlock();
} else {
dcb_out->state = !!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
}
@@ -759,12 +822,12 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
vport_up_fail:
- hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num,
+ netif_run);
setup_cos_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
return err;
}
@@ -772,13 +835,15 @@ setup_cos_fail:
static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_cos_cfg *cos_cfg_in = buf_in;
struct hinic3_mt_qos_cos_cfg *cos_cfg_out = buf_out;
if (!buf_in || !buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(*cos_cfg_out) || in_size != sizeof(*cos_cfg_in)) {
+ if (*out_size != sizeof(*cos_cfg_out) ||
+ in_size != sizeof(*cos_cfg_in)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
in_size, *out_size, sizeof(*cos_cfg_in));
@@ -789,9 +854,9 @@ static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
cos_cfg_out->head.status = 0;
cos_cfg_out->port_id = hinic3_physical_port_id(nic_dev->hwdev);
- cos_cfg_out->func_cos_bitmap = (u8)nic_dev->func_dft_cos_bitmap;
- cos_cfg_out->port_cos_bitmap = (u8)nic_dev->port_dft_cos_bitmap;
- cos_cfg_out->func_max_cos_num = nic_dev->cos_config_num_max;
+ cos_cfg_out->func_cos_bitmap = (u8)dcb->func_dft_cos_bitmap;
+ cos_cfg_out->port_cos_bitmap = (u8)dcb->port_dft_cos_bitmap;
+ cos_cfg_out->func_max_cos_num = dcb->cos_config_num_max;
return 0;
}
@@ -803,7 +868,13 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
intr_num = hinic3_intr_num(nic_dev->hwdev);
- if (!buf_out || !out_size || *out_size != sizeof(u16)) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != sizeof(u16)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(u16));
@@ -817,7 +888,13 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
static int get_netdev_name(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- if (!buf_out || !out_size || *out_size != IFNAMSIZ) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != IFNAMSIZ) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %u\n",
*out_size, IFNAMSIZ);
@@ -829,8 +906,9 @@ static int get_netdev_name(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
}
-static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
int *tx_timeout = buf_out;
@@ -839,7 +917,8 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (*out_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, out_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, out_size: %u, expect: %lu\n",
*out_size, sizeof(int));
return -EINVAL;
}
@@ -849,8 +928,9 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return 0;
}
-static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
const int *tx_timeout = buf_in;
@@ -859,13 +939,15 @@ static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (in_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, in_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, in_size: %u, expect: %lu\n",
in_size, sizeof(int));
return -EINVAL;
}
net_dev->watchdog_timeo = *tx_timeout * HZ;
- nicif_info(nic_dev, drv, net_dev, "Set tx timeout check period to %ds\n", *tx_timeout);
+ nicif_info(nic_dev, drv, net_dev,
+ "Set tx timeout check period to %ds\n", *tx_timeout);
return 0;
}
@@ -891,6 +973,34 @@ static int get_xsfp_present(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
}
+static int get_xsfp_tlv_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info = buf_out;
+ const struct tag_mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req = buf_in;
+ int err;
+
+ if ((buf_in == NULL) || (buf_out == NULL) || (out_size == NULL))
+ return -EINVAL;
+
+ if (*out_size != sizeof(*sfp_tlv_info) ||
+ in_size != sizeof(*sfp_tlv_info_req)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
+ in_size, *out_size, sizeof(*sfp_tlv_info));
+ return -EINVAL;
+ }
+
+ err = hinic3_get_sfp_tlv_info(nic_dev->hwdev,
+ sfp_tlv_info, sfp_tlv_info_req);
+ if (err != 0) {
+ sfp_tlv_info->head.status = MT_EIO;
+ return 0;
+ }
+
+ return 0;
+}
+
static int get_xsfp_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
@@ -928,7 +1038,7 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{GET_LOOPBACK_MODE, get_loopback_mode},
{SET_LOOPBACK_MODE, set_loopback_mode},
{SET_LINK_MODE, set_link_mode},
- {SET_PF_BW_LIMIT, set_pf_bw_limit},
+ {SET_TX_PF_BW_LIMIT, set_pf_bw_limit},
{GET_PF_BW_LIMIT, get_pf_bw_limit},
{GET_SSET_COUNT, get_sset_count},
{GET_SSET_ITEMS, get_sset_stats},
@@ -940,17 +1050,22 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{SET_TX_TIMEOUT, set_netdev_tx_timeout},
{GET_XSFP_PRESENT, get_xsfp_present},
{GET_XSFP_INFO, get_xsfp_info},
+ {GET_XSFP_INFO_COMP_CMIS, get_xsfp_tlv_info},
+ {SET_RX_PF_BW_LIMIT, set_rx_pf_bw_limit}
};
static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
u32 cmd, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(nic_driv_module_cmd_handle) /
- sizeof(nic_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(nic_driv_module_cmd_handle) /
+ sizeof(nic_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type = (enum driver_cmd_type)cmd;
int err = 0;
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_lock();
+
mutex_lock(&nic_dev->nic_mutex);
for (index = 0; index < num_cmds; index++) {
if (cmd_type ==
@@ -963,6 +1078,9 @@ static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
}
mutex_unlock(&nic_dev->nic_mutex);
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_unlock();
+
if (index == num_cmds) {
pr_err("Can't find callback for %d\n", cmd_type);
return -EINVAL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
index a1fb4af..ba4ec4d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
@@ -24,82 +24,80 @@
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_user_cos_num;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_user_cos_num;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_user_cos_num;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_user_cos_num;
return 0;
}
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_valid_cos_map;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_valid_cos_map;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_valid_cos_map;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_valid_cos_map;
return 0;
}
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
- u8 i, remainder, num_sq_per_cos, cur_cos_num = 0;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ struct hinic3_dcb_config *wanted_dcb_cfg =
+ &nic_dev->dcb->wanted_dcb_cfg;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
+ u8 cos_qp_num, cos_qp_offset = 0;
+ u8 i, remainder, num_qp_per_cos;
- if (num_cos == 0)
- return;
-
- num_sq_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
- if (num_sq_per_cos == 0)
+ if (num_cos == 0 || nic_dev->q_params.num_qps == 0)
return;
- remainder = nic_dev->q_params.num_qps % num_sq_per_cos;
+ num_qp_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
+ remainder = nic_dev->q_params.num_qps % num_cos;
- memset(dcb_cfg->cos_qp_offset, 0, sizeof(dcb_cfg->cos_qp_offset));
- memset(dcb_cfg->cos_qp_num, 0, sizeof(dcb_cfg->cos_qp_num));
+ memset(hw_dcb_cfg->cos_qp_offset, 0, sizeof(hw_dcb_cfg->cos_qp_offset));
+ memset(hw_dcb_cfg->cos_qp_num, 0, sizeof(hw_dcb_cfg->cos_qp_num));
for (i = 0; i < PCP_MAX_UP; i++) {
if (BIT(i) & valid_cos_map) {
- u8 cos_qp_num = num_sq_per_cos;
- u8 cos_qp_offset = (u8)(cur_cos_num * num_sq_per_cos);
-
- if (cur_cos_num < remainder) {
- cos_qp_num++;
- cos_qp_offset += cur_cos_num;
- } else {
- cos_qp_offset += remainder;
- }
-
- cur_cos_num++;
- valid_cos_map -= (u8)BIT(i);
+ cos_qp_num = num_qp_per_cos + ((remainder > 0) ?
+ (remainder--, 1) : 0);
- dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
- dcb_cfg->cos_qp_num[i] = cos_qp_num;
+ hw_dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
+ hw_dcb_cfg->cos_qp_num[i] = cos_qp_num;
hinic3_info(nic_dev, drv, "cos %u, cos_qp_offset=%u cos_qp_num=%u\n",
i, cos_qp_offset, cos_qp_num);
+
+ cos_qp_offset += cos_qp_num;
+ valid_cos_map -= (u8)BIT(i);
}
}
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_offset, dcb_cfg->cos_qp_offset,
- sizeof(dcb_cfg->cos_qp_offset));
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_num, dcb_cfg->cos_qp_num,
- sizeof(dcb_cfg->cos_qp_num));
+ memcpy(wanted_dcb_cfg->cos_qp_offset, hw_dcb_cfg->cos_qp_offset,
+ sizeof(hw_dcb_cfg->cos_qp_offset));
+ memcpy(wanted_dcb_cfg->cos_qp_num, hw_dcb_cfg->cos_qp_num,
+ sizeof(hw_dcb_cfg->cos_qp_num));
}
void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
u8 i;
u16 start_qid, q_num;
hinic3_set_txq_cos(nic_dev, 0, nic_dev->q_params.num_qps,
- nic_dev->hw_dcb_cfg.default_cos);
+ hw_dcb_cfg->default_cos);
if (!dcb_en)
return;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- q_num = (u16)nic_dev->hw_dcb_cfg.cos_qp_num[i];
+ q_num = (u16)hw_dcb_cfg->cos_qp_num[i];
if (q_num) {
- start_qid = (u16)nic_dev->hw_dcb_cfg.cos_qp_offset[i];
+ start_qid = (u16)hw_dcb_cfg->cos_qp_offset[i];
hinic3_set_txq_cos(nic_dev, start_qid, q_num, i);
hinic3_info(nic_dev, drv, "update tx db cos, start_qid %u, q_num=%u cos=%u\n",
@@ -110,30 +108,28 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ struct hinic3_dcb_config *hw_dcb_cfg = &dcb->hw_dcb_cfg;
struct hinic3_dcb_state dcb_state = {0};
u8 i;
int err;
-
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- /* VF does not support DCB, use the default cos */
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
-
- return 0;
- }
+ u32 pcp2cos_size = sizeof(dcb_state.pcp2cos);
+ u32 dscp2cos_size = sizeof(dcb_state.dscp2cos);
dcb_state.dcb_on = dcb_en;
- dcb_state.default_cos = dcb_cfg->default_cos;
- dcb_state.trust = dcb_cfg->trust;
+ dcb_state.default_cos = hw_dcb_cfg->default_cos;
+ dcb_state.trust = hw_dcb_cfg->trust;
if (dcb_en) {
for (i = 0; i < NIC_DCB_COS_MAX; i++)
- dcb_state.pcp2cos[i] = dcb_cfg->pcp2cos[i];
+ dcb_state.pcp2cos[i] = hw_dcb_cfg->pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- dcb_state.dscp2cos[i] = dcb_cfg->dscp2cos[i];
+ dcb_state.dscp2cos[i] = hw_dcb_cfg->dscp2cos[i];
} else {
- memset(dcb_state.pcp2cos, dcb_cfg->default_cos, sizeof(dcb_state.pcp2cos));
- memset(dcb_state.dscp2cos, dcb_cfg->default_cos, sizeof(dcb_state.dscp2cos));
+ memset(dcb_state.pcp2cos, hw_dcb_cfg->default_cos,
+ pcp2cos_size);
+ memset(dcb_state.dscp2cos, hw_dcb_cfg->default_cos,
+ dscp2cos_size);
}
err = hinic3_set_dcb_state(nic_dev->hwdev, &dcb_state);
@@ -143,7 +139,7 @@ static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
return err;
}
-static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
int err;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
@@ -169,11 +165,13 @@ static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
goto rx_configure_fail;
}
- if (dcb_en)
+ if (dcb_en) {
set_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
- else
+ set_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ } else {
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
-
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ }
return 0;
rx_configure_fail:
hinic3_set_tx_cos_state(nic_dev, dcb_en ? 0 : 1);
@@ -188,6 +186,7 @@ set_tx_cos_fail:
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err;
if (cos && test_bit(HINIC3_SAME_RXTX, &nic_dev->flags)) {
@@ -195,9 +194,10 @@ int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
return -EOPNOTSUPP;
}
- if (cos > nic_dev->cos_config_num_max) {
- nicif_err(nic_dev, drv, netdev, "Invalid num_tc: %u, max cos: %u\n",
- cos, nic_dev->cos_config_num_max);
+ if (cos > dcb->cos_config_num_max) {
+ nicif_err(nic_dev, drv, netdev,
+ "Invalid num_tc: %u, max cos: %u\n",
+ cos, dcb->cos_config_num_max);
return -EINVAL;
}
@@ -223,36 +223,48 @@ static u8 get_cos_num(u8 hw_valid_cos_bitmap)
static void hinic3_sync_dcb_cfg(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dcb_config *dcb_cfg)
{
- struct hinic3_dcb_config *hw_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
- memcpy(hw_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(hw_dcb_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
}
static int init_default_dcb_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *dcb_cfg)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 i, hw_dft_cos_map, port_cos_bitmap, dscp_ind;
int err;
+ int is_in_kexec;
- err = hinic3_cos_valid_bitmap(nic_dev->hwdev, &hw_dft_cos_map, &port_cos_bitmap);
+ err = hinic3_cos_valid_bitmap(nic_dev->hwdev,
+ &hw_dft_cos_map, &port_cos_bitmap);
if (err) {
hinic3_err(nic_dev, drv, "None cos supported\n");
return -EFAULT;
}
- nic_dev->func_dft_cos_bitmap = hw_dft_cos_map;
- nic_dev->port_dft_cos_bitmap = port_cos_bitmap;
- nic_dev->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+ is_in_kexec = vram_get_kexec_flag();
- dcb_cfg->trust = DCB_PCP;
- dcb_cfg->pcp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->dscp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
+ dcb->func_dft_cos_bitmap = hw_dft_cos_map;
+ dcb->port_dft_cos_bitmap = port_cos_bitmap;
+
+ dcb->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+
+ if (is_in_kexec == 0) {
+ dcb_cfg->trust = HINIC3_DCB_PCP;
+ dcb_cfg->default_cos = (u8)fls(dcb->func_dft_cos_bitmap) - 1;
+ } else {
+ dcb_cfg->trust = nic_dev->dcb->hw_dcb_cfg.trust;
+ dcb_cfg->default_cos = nic_dev->dcb->hw_dcb_cfg.default_cos;
+ }
+ dcb_cfg->pcp_user_cos_num = dcb->cos_config_num_max;
+ dcb_cfg->dscp_user_cos_num = dcb->cos_config_num_max;
dcb_cfg->pcp_valid_cos_map = hw_dft_cos_map;
dcb_cfg->dscp_valid_cos_map = hw_dft_cos_map;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i) ? i : dcb_cfg->default_cos;
+ dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i) ?
+ i : (u8)fls(dcb->func_dft_cos_bitmap) - 1;
for (dscp_ind = 0; dscp_ind < NIC_DCB_COS_MAX; dscp_ind++)
dcb_cfg->dscp2cos[i * NIC_DCB_DSCP_NUM + dscp_ind] = dcb_cfg->pcp2cos[i];
}
@@ -276,58 +288,117 @@ int hinic3_configure_dcb(struct net_device *netdev)
int err;
err = hinic3_sync_dcb_state(nic_dev->hwdev, 1,
- test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)
+ ? 1 : 0);
if (err) {
hinic3_err(nic_dev, drv, "Set dcb state failed\n");
return err;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ hinic3_sync_dcb_cfg(nic_dev, &nic_dev->dcb->wanted_dcb_cfg);
else
hinic3_dcb_reset_hw_config(nic_dev);
return 0;
}
+static int hinic3_dcb_alloc(struct hinic3_nic_dev *nic_dev)
+{
+ u16 func_id;
+ int is_use_vram;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(nic_dev->dcb_name, VRAM_NAME_MAX_LEN,
+ "%s%hu%s", VRAM_CQM_GLB_FUNC_BASE, func_id,
+ VRAM_NIC_DCB);
+
+ nic_dev->dcb = (struct hinic3_dcb *)hi_vram_kalloc(nic_dev->dcb_name,
+ sizeof(*nic_dev->dcb));
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to vram alloc dcb.\n");
+ return -EFAULT;
+ }
+ } else {
+ nic_dev->dcb = kzalloc(sizeof(*nic_dev->dcb), GFP_KERNEL);
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to create dcb.\n");
+ return -EFAULT;
+ }
+ }
+
+ return 0;
+}
+
+static void hinic3_dcb_free(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram)
+ hi_vram_kfree((void *)nic_dev->dcb, nic_dev->dcb_name,
+ sizeof(*nic_dev->dcb));
+ else
+ kfree(nic_dev->dcb);
+ nic_dev->dcb = NULL;
+}
+
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
+ hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+
+ hinic3_dcb_free(nic_dev);
+}
+
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = NULL;
int err;
u8 dcb_en = test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0;
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- return hinic3_set_tx_cos_state(nic_dev, dcb_en);
+ err = hinic3_dcb_alloc(nic_dev);
+ if (err != 0) {
+ hinic3_err(nic_dev, drv, "Dcb alloc failed.\n");
+ return err;
+ }
- err = init_default_dcb_cfg(nic_dev, dcb_cfg);
+ hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ err = init_default_dcb_cfg(nic_dev, hw_dcb_cfg);
if (err) {
- hinic3_err(nic_dev, drv, "Initialize dcb configuration failed\n");
+ hinic3_err(nic_dev, drv,
+ "Initialize dcb configuration failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&nic_dev->dcb->wanted_dcb_cfg, hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
hinic3_info(nic_dev, drv, "Support num cos %u, default cos %u\n",
- nic_dev->cos_config_num_max, dcb_cfg->default_cos);
+ nic_dev->dcb->cos_config_num_max, hw_dcb_cfg->default_cos);
err = hinic3_set_tx_cos_state(nic_dev, dcb_en);
if (err) {
hinic3_err(nic_dev, drv, "Set tx cos state failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- sema_init(&nic_dev->dcb_sem, 1);
-
return 0;
}
-static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dcb_config *dcb_cfg)
+static int change_qos_cfg(struct hinic3_nic_dev *nic_dev,
+ const struct hinic3_dcb_config *dcb_cfg)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err = 0;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags)) {
+ if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags)) {
nicif_warn(nic_dev, drv, netdev,
"Cos_up map setting in inprocess, please try again later\n");
return -EFAULT;
@@ -337,40 +408,44 @@ static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dc
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
- clear_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags);
+ clear_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags);
return err;
}
int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err, rollback_err;
u8 netif_run = 0;
struct hinic3_dcb_config old_dcb_cfg;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- memcpy(&old_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&old_dcb_cfg, &dcb->hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
- if (!memcmp(&nic_dev->wanted_dcb_cfg, &old_dcb_cfg, sizeof(struct hinic3_dcb_config))) {
+ if (!memcmp(&dcb->wanted_dcb_cfg, &old_dcb_cfg,
+ sizeof(struct hinic3_dcb_config))) {
nicif_info(nic_dev, drv, nic_dev->netdev,
"Same valid up bitmap, don't need to change anything\n");
return 0;
}
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = change_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ err = change_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Set cos_up map to hw failed\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Set cos_up map to hw failed\n");
goto change_qos_cfg_fail;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- err = hinic3_setup_cos(nic_dev->netdev, user_cos_num, netif_run);
+ err = hinic3_setup_cos(nic_dev->netdev,
+ user_cos_num, netif_run);
if (err)
goto set_err;
}
@@ -381,13 +456,12 @@ int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
goto vport_up_fail;
}
- rtnl_unlock();
-
return 0;
vport_up_fail:
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_setup_cos(nic_dev->netdev, user_cos_num ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, user_cos_num
+ ? 0 : user_cos_num, netif_run);
set_err:
rollback_err = change_qos_cfg(nic_dev, &old_dcb_cfg);
@@ -399,7 +473,5 @@ change_qos_cfg_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
-
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
index 7987f56..e0b35cb 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
@@ -24,11 +24,6 @@ struct hinic3_tc_cfg {
u16 rsvd;
};
-enum HINIC3_DCB_TRUST {
- DCB_PCP,
- DCB_DSCP,
-};
-
#define PCP_MAX_UP 8
#define DSCP_MAC_UP 64
#define DBG_DFLT_DSCP_VAL 0xFF
@@ -50,6 +45,7 @@ struct hinic3_dcb_config {
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev);
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev);
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev);
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev);
void hinic3_dcb_reset_hw_config(struct hinic3_nic_dev *nic_dev);
int hinic3_configure_dcb(struct net_device *netdev);
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run);
@@ -75,4 +71,5 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos);
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev);
int hinic3_vport_up(struct hinic3_nic_dev *nic_dev);
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
index 5a19959..ae41819 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
@@ -56,9 +56,8 @@ static void hinic3_get_drvinfo(struct net_device *netdev,
return;
}
- err = snprintf(info->fw_version, sizeof(info->fw_version), "%s", mgmt_ver);
- if (err < 0)
- nicif_err(nic_dev, drv, netdev, "Failed to snprintf fw version\n");
+ snprintf(info->fw_version, sizeof(info->fw_version),
+ "%s", mgmt_ver);
}
static u32 hinic3_get_msglevel(struct net_device *netdev)
@@ -86,7 +85,8 @@ static int hinic3_nway_reset(struct net_device *netdev)
while (test_and_set_bit(HINIC3_AUTONEG_RESET, &nic_dev->flags))
msleep(100); /* sleep 100 ms, waiting for another autoneg restart progress done */
- err = hinic3_get_port_info(nic_dev->hwdev, &port_info, HINIC3_CHANNEL_NIC);
+ err = hinic3_get_port_info(nic_dev->hwdev, &port_info,
+ HINIC3_CHANNEL_NIC);
if (err) {
nicif_err(nic_dev, drv, netdev, "Get port info failed\n");
err = -EFAULT;
@@ -273,7 +273,7 @@ static int get_coalesce(struct net_device *netdev,
static int set_queue_coalesce(struct hinic3_nic_dev *nic_dev, u16 q_id,
struct hinic3_intr_coal_info *coal)
{
- struct hinic3_intr_coal_info *intr_coal;
+ struct hinic3_intr_coal_info *intr_coal = NULL;
struct interrupt_info info = {0};
struct net_device *netdev = nic_dev->netdev;
int err;
@@ -367,24 +367,11 @@ static int is_coalesce_exceed_limit(struct net_device *netdev,
return 0;
}
-static int is_coalesce_legal(struct net_device *netdev,
- const struct ethtool_coalesce *coal)
+static int is_coalesce_allowed_change(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct ethtool_coalesce tmp_coal = {0};
- int err;
-
- if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
- nicif_err(nic_dev, drv, netdev,
- "tx-usecs must be equal to rx-usecs\n");
- return -EINVAL;
- }
-
- if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
- nicif_err(nic_dev, drv, netdev,
- "tx-frames must be equal to rx-frames\n");
- return -EINVAL;
- }
tmp_coal.cmd = coal->cmd;
tmp_coal.rx_coalesce_usecs = coal->rx_coalesce_usecs;
@@ -409,6 +396,31 @@ static int is_coalesce_legal(struct net_device *netdev,
return -EOPNOTSUPP;
}
+ return 0;
+}
+
+static int is_coalesce_legal(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-usecs must be equal to rx-usecs\n");
+ return -EINVAL;
+ }
+
+ if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-frames must be equal to rx-frames\n");
+ return -EINVAL;
+ }
+
+ err = is_coalesce_allowed_change(netdev, coal);
+ if (err)
+ return err;
+
err = is_coalesce_exceed_limit(netdev, coal);
if (err)
return err;
@@ -444,7 +456,8 @@ static int is_coalesce_legal(struct net_device *netdev,
return 0;
}
-static inline void check_coalesce_align(struct hinic3_nic_dev *nic_dev, struct net_device *netdev,
+static inline void check_coalesce_aligned(struct hinic3_nic_dev *nic_dev,
+ struct net_device *netdev,
u32 item, u32 unit, char *str)
{
if (item % unit)
@@ -453,10 +466,12 @@ static inline void check_coalesce_align(struct hinic3_nic_dev *nic_dev, struct n
}
#define CHECK_COALESCE_ALIGN(member, unit) \
- check_coalesce_align(nic_dev, netdev, member, unit, #member)
+ check_coalesce_aligned(nic_dev, netdev, member, unit, #member)
-static inline void check_coalesce_changed(struct hinic3_nic_dev *nic_dev, struct net_device *netdev,
- u32 item, u32 unit, u32 ori_val, char *obj_str, char *str)
+static inline void check_coalesce_changed(struct hinic3_nic_dev *nic_dev,
+ struct net_device *netdev,
+ u32 item, u32 unit, u32 ori_val,
+ char *obj_str, char *str)
{
if ((item / unit) != ori_val)
nicif_info(nic_dev, drv, netdev, "Change %s from %d to %u %s\n",
@@ -466,8 +481,10 @@ static inline void check_coalesce_changed(struct hinic3_nic_dev *nic_dev, struct
#define CHECK_COALESCE_CHANGED(member, unit, ori_val, obj_str) \
check_coalesce_changed(nic_dev, netdev, member, unit, ori_val, obj_str, #member)
-static inline void check_pkt_rate_changed(struct hinic3_nic_dev *nic_dev, struct net_device *netdev,
- u32 item, u32 ori_val, char *obj_str, char *str)
+static inline void check_pkt_rate_changed(struct hinic3_nic_dev *nic_dev,
+ struct net_device *netdev,
+ u32 item, u32 ori_val, char *obj_str,
+ char *str)
{
if (item != ori_val)
nicif_info(nic_dev, drv, netdev, "Change %s from %d to %u %s\n",
@@ -497,19 +514,10 @@ static int set_hw_coal_param(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static int set_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *coal, u16 queue)
+static void check_coalesce_align(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
- struct hinic3_intr_coal_info intr_coal = {0};
- struct hinic3_intr_coal_info *ori_intr_coal = NULL;
- u32 last_adaptive_rx;
- char obj_str[32] = {0};
- int err = 0;
-
- err = is_coalesce_legal(netdev, coal);
- if (err)
- return err;
CHECK_COALESCE_ALIGN(coal->rx_coalesce_usecs, COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal->rx_max_coalesced_frames,
@@ -522,6 +530,14 @@ static int set_coalesce(struct net_device *netdev,
COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal->rx_max_coalesced_frames_low,
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int check_coalesce_change(struct net_device *netdev,
+ u16 queue, struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info *ori_intr_coal = NULL;
+ char obj_str[32] = {0};
if (queue == COALESCE_ALL_QUEUE) {
ori_intr_coal = &nic_dev->intr_coalesce[0];
@@ -552,27 +568,54 @@ static int set_coalesce(struct net_device *netdev,
COALESCE_PENDING_LIMIT_UNIT,
ori_intr_coal->rx_pending_limt_low, obj_str);
- intr_coal.coalesce_timer_cfg =
+ return 0;
+}
+
+static void init_intr_coal_params(struct hinic3_intr_coal_info *intr_coal,
+ struct ethtool_coalesce *coal)
+{
+ intr_coal->coalesce_timer_cfg =
(u8)(coal->rx_coalesce_usecs / COALESCE_TIMER_CFG_UNIT);
- intr_coal.pending_limt = (u8)(coal->rx_max_coalesced_frames /
+ intr_coal->pending_limt = (u8)(coal->rx_max_coalesced_frames /
COALESCE_PENDING_LIMIT_UNIT);
- last_adaptive_rx = nic_dev->adaptive_rx_coal;
- nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
-
- intr_coal.pkt_rate_high = coal->pkt_rate_high;
- intr_coal.rx_usecs_high =
+ intr_coal->pkt_rate_high = coal->pkt_rate_high;
+ intr_coal->rx_usecs_high =
(u8)(coal->rx_coalesce_usecs_high / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_high =
+ intr_coal->rx_pending_limt_high =
(u8)(coal->rx_max_coalesced_frames_high /
COALESCE_PENDING_LIMIT_UNIT);
- intr_coal.pkt_rate_low = coal->pkt_rate_low;
- intr_coal.rx_usecs_low =
+ intr_coal->pkt_rate_low = coal->pkt_rate_low;
+ intr_coal->rx_usecs_low =
(u8)(coal->rx_coalesce_usecs_low / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_low =
+ intr_coal->rx_pending_limt_low =
(u8)(coal->rx_max_coalesced_frames_low /
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal, u16 queue)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info intr_coal = {0};
+ u32 last_adaptive_rx;
+ int err = 0;
+
+ err = is_coalesce_legal(netdev, coal);
+ if (err)
+ return err;
+
+ check_coalesce_align(netdev, coal);
+
+ err = check_coalesce_change(netdev, queue, coal);
+ if (err)
+ return err;
+
+ init_intr_coal_params(&intr_coal, coal);
+
+ last_adaptive_rx = nic_dev->adaptive_rx_coal;
+ nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
/* coalesce timer or pending set to zero will disable coalesce */
if (!nic_dev->adaptive_rx_coal &&
@@ -709,14 +752,16 @@ static int hinic3_set_pauseparam(struct net_device *netdev,
return -EFAULT;
}
- auto_neg = port_info.autoneg_state == PORT_CFG_AN_ON ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+ auto_neg = port_info.autoneg_state == PORT_CFG_AN_ON ?
+ AUTONEG_ENABLE : AUTONEG_DISABLE;
if (pause->autoneg != auto_neg) {
nicif_err(nic_dev, drv, netdev,
"To change autoneg please use: ethtool -s <dev> autoneg <on|off>\n");
return -EOPNOTSUPP;
}
- nic_pause.auto_neg = pause->autoneg == AUTONEG_ENABLE ? PORT_CFG_AN_ON : PORT_CFG_AN_OFF;
+ nic_pause.auto_neg = pause->autoneg == AUTONEG_ENABLE ?
+ PORT_CFG_AN_ON : PORT_CFG_AN_OFF;
nic_pause.rx_pause = (u8)pause->rx_pause;
nic_pause.tx_pause = (u8)pause->tx_pause;
@@ -768,6 +813,14 @@ static int hinic3_get_module_info(struct net_device *netdev,
modinfo->type = ETH_MODULE_SFF_8636;
modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
break;
+ case MODULE_TYPE_DSFP:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
+ case MODULE_TYPE_QSFP_CMIS:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
default:
nicif_warn(nic_dev, drv, netdev,
"Optical module unknown: 0x%x\n", sfp_type);
@@ -790,6 +843,11 @@ static int hinic3_get_module_eeprom(struct net_device *netdev,
memset(data, 0, ee->len);
err = hinic3_get_sfp_eeprom(nic_dev->hwdev, (u8 *)sfp_data, ee->len);
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(nic_dev->hwdev,
+ (u8 *)sfp_data,
+ sizeof(sfp_data));
+
if (err)
return err;
@@ -832,7 +890,8 @@ int hinic3_set_rxq_recovery_flag(struct net_device *netdev, u32 priv_flags)
if (test_and_set_bit(HINIC3_RXQ_RECOVERY, &nic_dev->flags))
return 0;
- queue_delayed_work(nic_dev->workq, &nic_dev->rxq_check_work, HZ);
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->rxq_check_work, HZ);
nicif_info(nic_dev, drv, netdev, "open rxq recovery\n");
} else {
if (!test_and_clear_bit(HINIC3_RXQ_RECOVERY, &nic_dev->flags))
@@ -888,7 +947,8 @@ static int hinic3_set_force_link_flag(struct net_device *netdev, u32 priv_flags)
nicif_info(nic_dev, link, netdev, "Set link up\n");
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, nic_dev->link_status);
+ hinic3_notify_all_vfs_link_changed(
+ nic_dev->hwdev, nic_dev->link_status);
} else {
if (!test_and_clear_bit(HINIC3_FORCE_LINK_UP, &nic_dev->flags))
return 0;
@@ -919,7 +979,8 @@ static int hinic3_set_force_link_flag(struct net_device *netdev, u32 priv_flags)
}
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, nic_dev->link_status);
+ hinic3_notify_all_vfs_link_changed(
+ nic_dev->hwdev, nic_dev->link_status);
}
return 0;
@@ -942,7 +1003,6 @@ static int hinic3_set_priv_flags(struct net_device *netdev, u32 priv_flags)
#define PORT_DOWN_ERR_IDX 0
#define LP_DEFAULT_TIME 5 /* seconds */
-#define LP_PKT_LEN 60
#define TEST_TIME_MULTIPLE 5
static int hinic3_run_lp_test(struct hinic3_nic_dev *nic_dev, u32 test_time)
@@ -958,8 +1018,11 @@ static int hinic3_run_lp_test(struct hinic3_nic_dev *nic_dev, u32 test_time)
u8 j;
skb_tmp = alloc_skb(LP_PKT_LEN, GFP_ATOMIC);
- if (!skb_tmp)
+ if (!skb_tmp) {
+ nicif_err(nic_dev, drv, netdev,
+ "Alloc xmit skb template failed for loopback test\n");
return -ENOMEM;
+ }
eth_hdr = __skb_put(skb_tmp, ETH_HLEN);
eth_hdr->h_proto = htons(ETH_P_ARP);
@@ -1057,6 +1120,8 @@ static int do_lp_test(struct hinic3_nic_dev *nic_dev, u32 *flags, u32 test_time,
lb_test_rx_buf = vmalloc(LP_PKT_CNT * LP_PKT_LEN);
if (!lb_test_rx_buf) {
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to alloc RX buffer for loopback test\n");
err = -ENOMEM;
} else {
nic_dev->lb_test_rx_buf = lb_test_rx_buf;
@@ -1086,7 +1151,8 @@ static int do_lp_test(struct hinic3_nic_dev *nic_dev, u32 *flags, u32 test_time,
return err;
}
-static void hinic3_lp_test(struct net_device *netdev, struct ethtool_test *eth_test,
+static void hinic3_lp_test(struct net_device *netdev,
+ struct ethtool_test *eth_test,
u64 *data, u32 test_time)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
@@ -1109,7 +1175,8 @@ static void hinic3_lp_test(struct net_device *netdev, struct ethtool_test *eth_t
netif_carrier_off(netdev);
netif_tx_disable(netdev);
- err = do_lp_test(nic_dev, ð_test->flags, test_time_real, &test_index);
+ err = do_lp_test(nic_dev, ð_test->flags,
+ test_time_real, &test_index);
if (err) {
eth_test->flags |= ETH_TEST_FL_FAILED;
data[test_index] = 1;
@@ -1130,10 +1197,65 @@ static void hinic3_diag_test(struct net_device *netdev,
hinic3_lp_test(netdev, eth_test, data, 0);
}
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+static int hinic3_get_fecparam(struct net_device *netdev,
+ struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u8 advertised_fec = 0;
+ u8 supported_fec = 0;
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_GFECPARAM) {
+ nicif_err(nic_dev, drv, netdev,
+ "get fecparam cmd err.exp:0x%x,real:0x%x\n",
+ ETHTOOL_GFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = get_fecparam(nic_dev->hwdev, &advertised_fec, &supported_fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Get fec param failed\n");
+ return err;
+ }
+ fecparam->active_fec = (u32)advertised_fec;
+ fecparam->fec = (u32)supported_fec;
+
+ nicif_info(nic_dev, drv, netdev, "Get fec param success\n");
+ return 0;
+}
+
+static int hinic3_set_fecparam(struct net_device *netdev,
+ struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_SFECPARAM) {
+ nicif_err(nic_dev, drv, netdev,
+ "Set fecparam cmd err.exp:0x%x,real:0x%x\n",
+ ETHTOOL_SFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = set_fecparam(nic_dev->hwdev, (u8)fecparam->fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Set fec param failed\n");
+ return err;
+ }
+
+ nicif_info(nic_dev, drv, netdev, "Set fec param success\n");
+ return 0;
+}
+#endif
+
static const struct ethtool_ops hinic3_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1180,6 +1302,10 @@ static const struct ethtool_ops hinic3_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
@@ -1240,7 +1366,10 @@ static const struct ethtool_ops_ext hinic3_ethtool_ops_ext = {
static const struct ethtool_ops hinic3vf_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1267,6 +1396,11 @@ static const struct ethtool_ops hinic3vf_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
+
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
index b0e6aad..938cf2c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
@@ -24,11 +24,29 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
-#define FPGA_PORT_COUNTER 0
-#define EVB_PORT_COUNTER 1
-u16 mag_support_mode = EVB_PORT_COUNTER;
-module_param(mag_support_mode, ushort, 0444);
-MODULE_PARM_DESC(mag_support_mode, "Set mag port counter support mode, 0:FPGA 1:EVB, default is 1");
+#define HINIC_SET_LINK_STR_LEN 128
+#define HINIC_ETHTOOL_FEC_INFO_LEN 6
+#define HINIC_SUPPORTED_FEC_CMD 0
+#define HINIC_ADVERTISED_FEC_CMD 1
+
+struct hinic3_ethtool_fec {
+ u8 hinic_fec_offset;
+ u8 ethtool_bit_offset;
+};
+
+static struct hinic3_ethtool_fec
+ hinic3_ethtool_fec_info[HINIC_ETHTOOL_FEC_INFO_LEN] = {
+ /* The ethtool does not have the corresponding enumeration variable */
+ {PORT_FEC_NOT_SET, 0xFF},
+ {PORT_FEC_RSFEC, 0x32}, /* ETHTOOL_LINK_MODE_FEC_RS_BIT */
+ /* ETHTOOL_LINK_MODE_FEC_BASER_BIT */
+ {PORT_FEC_BASEFEC, 0x33},
+ {PORT_FEC_NOFEC, 0x31}, /* ETHTOOL_LINK_MODE_FEC_NONE_BIT */
+ /* ETHTOOL_LINK_MODE_FEC_LLRS_BIT: Available only in later versions */
+ {PORT_FEC_LLRSFEC, 0x4A},
+ /* The ethtool does not have the corresponding enumeration variable */
+ {PORT_FEC_AUTO, 0XFF}
+};
struct hinic3_stats {
char name[ETH_GSTRING_LEN];
@@ -36,9 +54,23 @@ struct hinic3_stats {
int offset;
};
+struct hinic3_netdev_link_count_str {
+ u64 link_down_events_phy;
+};
+
+#define HINIC3_NETDEV_LINK_COUNT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic3_netdev_link_count_str, _stat_item), \
+ .offset = offsetof(struct hinic3_netdev_link_count_str, _stat_item) \
+}
+
+static struct hinic3_stats hinic3_netdev_link_count[] = {
+ HINIC3_NETDEV_LINK_COUNT(link_down_events_phy),
+};
+
#define HINIC3_NETDEV_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct rtnl_link_stats64, _stat_item), \
+ .size = FIELD_SIZEOF(struct rtnl_link_stats64, _stat_item), \
.offset = offsetof(struct rtnl_link_stats64, _stat_item) \
}
@@ -67,7 +99,7 @@ static struct hinic3_stats hinic3_netdev_stats[] = {
#define HINIC3_NIC_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct hinic3_nic_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_nic_stats, _stat_item), \
.offset = offsetof(struct hinic3_nic_stats, _stat_item) \
}
@@ -84,17 +116,16 @@ static struct hinic3_stats hinic3_nic_dev_stats_extern[] = {
#define HINIC3_RXQ_STAT(_stat_item) { \
.name = "rxq%d_"#_stat_item, \
- .size = sizeof_field(struct hinic3_rxq_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_rxq_stats, _stat_item), \
.offset = offsetof(struct hinic3_rxq_stats, _stat_item) \
}
#define HINIC3_TXQ_STAT(_stat_item) { \
.name = "txq%d_"#_stat_item, \
- .size = sizeof_field(struct hinic3_txq_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_txq_stats, _stat_item), \
.offset = offsetof(struct hinic3_txq_stats, _stat_item) \
}
-/*lint -save -e786*/
static struct hinic3_stats hinic3_rx_queue_stats[] = {
HINIC3_RXQ_STAT(packets),
HINIC3_RXQ_STAT(bytes),
@@ -135,11 +166,9 @@ static struct hinic3_stats hinic3_tx_queue_stats_extern[] = {
HINIC3_TXQ_STAT(rsvd2),
};
-/*lint -restore*/
-
#define HINIC3_FUNC_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct hinic3_vport_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_vport_stats, _stat_item), \
.offset = offsetof(struct hinic3_vport_stats, _stat_item) \
}
@@ -166,7 +195,7 @@ static struct hinic3_stats hinic3_function_stats[] = {
#define HINIC3_PORT_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct mag_cmd_port_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct mag_cmd_port_stats, _stat_item), \
.offset = offsetof(struct mag_cmd_port_stats, _stat_item) \
}
@@ -260,49 +289,22 @@ static struct hinic3_stats hinic3_port_stats[] = {
HINIC3_PORT_STAT(mac_rx_unfilter_pkt_num),
};
-#define HINIC3_FGPA_PORT_STAT(_stat_item) { \
+#define HINIC3_RSFEC_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct hinic3_phy_fpga_port_stats, _stat_item), \
- .offset = offsetof(struct hinic3_phy_fpga_port_stats, _stat_item) \
+ .size = FIELD_SIZEOF(struct mag_cmd_rsfec_stats, _stat_item), \
+ .offset = offsetof(struct mag_cmd_rsfec_stats, _stat_item) \
}
-static struct hinic3_stats g_hinic3_fpga_port_stats[] = {
- HINIC3_FGPA_PORT_STAT(mac_rx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_under_frame_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_frag_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_crc_error_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_length_err_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_pause_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_unknown_mac_frame_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_underrun_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_pause_pkts_port),
+static struct hinic3_stats g_hinic3_rsfec_stats[] = {
+ HINIC3_RSFEC_STAT(rx_err_lane_phy),
};
+#define HINIC3_FGPA_PORT_STAT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic3_phy_fpga_port_stats, _stat_item), \
+ .offset = offsetof(struct hinic3_phy_fpga_port_stats, _stat_item) \
+}
+
static char g_hinic_priv_flags_strings[][ETH_GSTRING_LEN] = {
"Symmetric-RSS",
"Force-Link-up",
@@ -318,8 +320,7 @@ u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev)
(ARRAY_LEN(hinic3_tx_queue_stats) +
ARRAY_LEN(hinic3_tx_queue_stats_extern) +
ARRAY_LEN(hinic3_rx_queue_stats) +
- ARRAY_LEN(hinic3_rx_queue_stats_extern)) *
- nic_dev->max_qps;
+ ARRAY_LEN(hinic3_rx_queue_stats_extern)) * nic_dev->max_qps;
return count;
}
@@ -343,72 +344,87 @@ static int dev_stats_pack(struct hinic3_show_item *items, int len,
memcpy(items[item_idx].name, array[j].name,
HINIC3_SHOW_ITEM_LEN);
items[item_idx].hexadecimal = 0;
- items[item_idx].value = get_value_of_ptr(array[j].size,
- stats_ptr + array[j].offset);
+ items[item_idx].value =
+ get_value_of_ptr(array[j].size,
+ stats_ptr + array[j].offset);
item_idx++;
}
return item_idx;
}
-static int queue_stats_pack(struct hinic3_show_item *items, int len,
- struct hinic3_stats *array, void *stats_ptr,
- u16 qid)
+int hinic3_rx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat, struct hinic3_rxq_stats *rxq_stats, u16 qid)
{
- int j;
- int item_idx = 0;
+ snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
- for (j = 0; j < len; j++) {
- memcpy(items[item_idx].name, array[j].name,
- HINIC3_SHOW_ITEM_LEN);
- snprintf(items[item_idx].name, HINIC3_SHOW_ITEM_LEN,
- array[j].name, qid);
- items[item_idx].hexadecimal = 0;
- items[item_idx].value = get_value_of_ptr(array[j].size,
- stats_ptr + array[j].offset);
- item_idx++;
- }
+ item->hexadecimal = 0;
+ item->value = get_value_of_ptr(stat->size, (char *)(rxq_stats) +
+ stat->offset);
- return item_idx;
+ return 0;
+}
+
+int hinic3_tx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat, struct hinic3_txq_stats *txq_stats, u16 qid)
+{
+ snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
+
+ item->hexadecimal = 0;
+ item->value = get_value_of_ptr(stat->size, (char *)(txq_stats) +
+ stat->offset);
+
+ return 0;
}
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
{
struct hinic3_show_item *items = stats;
int item_idx = 0;
u16 qid;
+ int idx;
+ int ret;
- item_idx += dev_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_nic_dev_stats),
- hinic3_nic_dev_stats, &nic_dev->stats);
- item_idx += dev_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_nic_dev_stats_extern),
- hinic3_nic_dev_stats_extern,
- &nic_dev->stats);
+ dev_stats_pack(items, item_idx, hinic3_nic_dev_stats, &nic_dev->stats);
+ dev_stats_pack(items, item_idx, hinic3_nic_dev_stats_extern, &nic_dev->stats);
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_tx_queue_stats),
- hinic3_tx_queue_stats,
- &nic_dev->txqs[qid].txq_stats,
- qid);
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_tx_queue_stats_extern),
- hinic3_tx_queue_stats_extern,
- &nic_dev->txqs[qid].txq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++],
+ &hinic3_tx_queue_stats[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats_extern); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++],
+ &hinic3_tx_queue_stats_extern[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
}
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_rx_queue_stats),
- hinic3_rx_queue_stats,
- &nic_dev->rxqs[qid].rxq_stats,
- qid);
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_rx_queue_stats_extern),
- hinic3_rx_queue_stats_extern,
- &nic_dev->rxqs[qid].rxq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++],
+ &hinic3_rx_queue_stats[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats_extern); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++],
+ &hinic3_rx_queue_stats_extern[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
}
+
+ return 0;
}
static char g_hinic3_test_strings[][ETH_GSTRING_LEN] = {
@@ -428,16 +444,14 @@ int hinic3_get_sset_count(struct net_device *netdev, int sset)
q_num = nic_dev->q_params.num_qps;
count = ARRAY_LEN(hinic3_netdev_stats) +
ARRAY_LEN(hinic3_nic_dev_stats) +
+ ARRAY_LEN(hinic3_netdev_link_count) +
ARRAY_LEN(hinic3_function_stats) +
(ARRAY_LEN(hinic3_tx_queue_stats) +
- ARRAY_LEN(hinic3_rx_queue_stats)) *
- q_num;
+ ARRAY_LEN(hinic3_rx_queue_stats)) * q_num;
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER)
- count += ARRAY_LEN(g_hinic3_fpga_port_stats);
- else
- count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(g_hinic3_rsfec_stats);
}
return count;
@@ -486,9 +500,9 @@ static void get_drv_queue_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
}
}
-static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct hinic3_phy_fpga_port_stats *port_stats = NULL;
+ struct mag_cmd_port_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
@@ -496,19 +510,19 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
if (!port_stats) {
memset(&data[i], 0,
- ARRAY_LEN(g_hinic3_fpga_port_stats) * sizeof(*data));
- i += ARRAY_LEN(g_hinic3_fpga_port_stats);
+ ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
+ i += ARRAY_LEN(hinic3_port_stats);
return i;
}
- err = hinic3_get_fpga_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to get port stats from fw\n");
- for (j = 0; j < ARRAY_LEN(g_hinic3_fpga_port_stats); j++, i++) {
- p = (char *)(port_stats) + g_hinic3_fpga_port_stats[j].offset;
- data[i] = (g_hinic3_fpga_port_stats[j].size == sizeof(u64)) ?
+ for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
+ p = (char *)(port_stats) + hinic3_port_stats[j].offset;
+ data[i] = (hinic3_port_stats[j].size == sizeof(u64)) ?
*(u64 *)p :
*(u32 *)p;
}
@@ -518,34 +532,32 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
return i;
}
-static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_rsfec_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct mag_cmd_port_stats *port_stats = NULL;
+ struct mag_cmd_rsfec_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
- if (mag_support_mode == FPGA_PORT_COUNTER)
- return get_fpga_port_stats(nic_dev, data);
-
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
if (!port_stats) {
- memset(&data[i], 0,
- ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
- i += ARRAY_LEN(hinic3_port_stats);
- return i;
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to malloc port stats\n");
+ memset(&data[i], 0,
+ ARRAY_LEN(g_hinic3_rsfec_stats) * sizeof(*data));
+ i += ARRAY_LEN(g_hinic3_rsfec_stats);
+ return i;
}
- err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_rsfec_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to get port stats from fw\n");
+ "Failed to get rsfec stats from fw\n");
- for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
- p = (char *)(port_stats) + hinic3_port_stats[j].offset;
- data[i] = (hinic3_port_stats[j].size == sizeof(u64)) ?
- *(u64 *)p :
- *(u32 *)p;
+ for (j = 0; j < ARRAY_LEN(g_hinic3_rsfec_stats); j++, i++) {
+ p = (char *)(port_stats) + g_hinic3_rsfec_stats[j].offset;
+ data[i] = (g_hinic3_rsfec_stats[j].size ==
+ sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
kfree(port_stats);
@@ -569,6 +581,8 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
u16 i = 0, j = 0;
char *p = NULL;
int err;
+ int link_down_events_phy_tmp = 0;
+ struct hinic3_netdev_link_count_str link_count = {0};
#ifdef HAVE_NDO_GET_STATS64
net_stats = dev_get_stats(netdev, &temp);
@@ -586,6 +600,15 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = get_value_of_ptr(hinic3_nic_dev_stats[j].size, p);
}
+ err = hinic3_get_link_event_stats(nic_dev->hwdev,
+ &link_down_events_phy_tmp);
+
+ link_count.link_down_events_phy = (u64)link_down_events_phy_tmp;
+ for (j = 0; j < ARRAY_LEN(hinic3_netdev_link_count); j++, i++) {
+ p = (char *)(&link_count) + hinic3_netdev_link_count[j].offset;
+ data[i] = get_value_of_ptr(hinic3_netdev_link_count[j].size, p);
+ }
+
err = hinic3_get_vport_stats(nic_dev->hwdev,
hinic3_global_func_id(nic_dev->hwdev),
&vport_stats);
@@ -598,8 +621,10 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = get_value_of_ptr(hinic3_function_stats[j].size, p);
}
- if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
i += get_ethtool_port_stats(nic_dev, data + i);
+ i += get_ethtool_rsfec_stats(nic_dev, data + i);
+ }
get_drv_queue_stats(nic_dev, data + i);
}
@@ -620,6 +645,12 @@ static u16 get_drv_dev_strings(struct hinic3_nic_dev *nic_dev, char *p)
cnt++;
}
+ for (i = 0; i < ARRAY_LEN(hinic3_netdev_link_count); i++) {
+ memcpy(p, hinic3_netdev_link_count[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+
return cnt;
}
@@ -634,21 +665,16 @@ static u16 get_hw_stats_strings(struct hinic3_nic_dev *nic_dev, char *p)
}
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER) {
- for (i = 0; i < ARRAY_LEN(g_hinic3_fpga_port_stats);
- i++) {
- memcpy(p, g_hinic3_fpga_port_stats[i].name,
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
- } else {
- for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
- memcpy(p, hinic3_port_stats[i].name,
+ for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
+ memcpy(p, hinic3_port_stats[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+ for (i = 0; i < ARRAY_LEN(g_hinic3_rsfec_stats); i++) {
+ memcpy(p, g_hinic3_rsfec_stats[i].name,
ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
+ p += ETH_GSTRING_LEN;
+ cnt++;
}
}
@@ -664,7 +690,8 @@ static u16 get_qp_stats_strings(const struct hinic3_nic_dev *nic_dev, char *p)
for (j = 0; j < ARRAY_LEN(hinic3_tx_queue_stats); j++) {
err = sprintf(p, hinic3_tx_queue_stats[j].name, i);
if (err < 0)
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to sprintf tx queue stats name, idx_qps: %u, idx_stats: %u\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to sprintf tx queue stats name, idx_qps: %u, idx_stats: %u\n",
i, j);
p += ETH_GSTRING_LEN;
cnt++;
@@ -675,7 +702,8 @@ static u16 get_qp_stats_strings(const struct hinic3_nic_dev *nic_dev, char *p)
for (j = 0; j < ARRAY_LEN(hinic3_rx_queue_stats); j++) {
err = sprintf(p, hinic3_rx_queue_stats[j].name, i);
if (err < 0)
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to sprintf rx queue stats name, idx_qps: %u, idx_stats: %u\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to sprintf rx queue stats name, idx_qps: %u, idx_stats: %u\n",
i, j);
p += ETH_GSTRING_LEN;
cnt++;
@@ -791,7 +819,6 @@ struct hw2ethtool_link_mode {
u32 speed;
};
-/*lint -save -e26 */
static const struct hw2ethtool_link_mode
hw2ethtool_link_mode_table[LINK_MODE_MAX_NUMBERS] = {
[LINK_MODE_GE] = {
@@ -851,8 +878,6 @@ static const struct hw2ethtool_link_mode
},
};
-/*lint -restore */
-
#define GET_SUPPORTED_MODE 0
#define GET_ADVERTISED_MODE 1
@@ -867,21 +892,37 @@ struct cmd_link_settings {
};
#define ETHTOOL_ADD_SUPPORTED_LINK_MODE(ecmd, mode) \
- set_bit(ETHTOOL_LINK_##mode##_BIT, (ecmd)->supported)
+ set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->supported)
#define ETHTOOL_ADD_ADVERTISED_LINK_MODE(ecmd, mode) \
- set_bit(ETHTOOL_LINK_##mode##_BIT, (ecmd)->advertising)
+ set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->advertising)
-static void ethtool_add_speed_link_mode(__ETHTOOL_DECLARE_LINK_MODE_MASK(bitmap), u32 mode)
+static void ethtool_add_supported_speed_link_mode(
+ struct cmd_link_settings *link_settings,
+ u32 mode)
{
u32 i;
for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
- __ETHTOOL_LINK_MODE_MASK_NBITS)
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
continue;
+ set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
+ link_settings->supported);
+ }
+}
+static void ethtool_add_advertised_speed_link_mode(
+ struct cmd_link_settings *link_settings,
+ u32 mode)
+{
+ u32 i;
+
+ for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
+ if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
+ continue;
set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
- bitmap);
+ link_settings->advertising);
}
}
@@ -912,9 +953,11 @@ hinic3_add_ethtool_link_mode(struct cmd_link_settings *link_settings,
for (link_mode = 0; link_mode < LINK_MODE_MAX_NUMBERS; link_mode++) {
if (hw_link_mode & BIT(link_mode)) {
if (name == GET_SUPPORTED_MODE)
- ethtool_add_speed_link_mode(link_settings->supported, link_mode);
+ ethtool_add_supported_speed_link_mode(
+ link_settings, link_mode);
else
- ethtool_add_speed_link_mode(link_settings->advertising, link_mode);
+ ethtool_add_advertised_speed_link_mode(
+ link_settings, link_mode);
}
}
}
@@ -937,10 +980,15 @@ static int hinic3_link_speed_set(struct hinic3_nic_dev *nic_dev,
err = hinic3_get_link_state(nic_dev->hwdev, &link_state);
if (!err && link_state) {
- link_settings->speed =
- port_info->speed < ARRAY_LEN(hw_to_ethtool_speed) ?
+ if (hinic3_get_bond_create_mode(nic_dev->hwdev)) {
+ link_settings->speed = port_info->bond_speed;
+ } else {
+ link_settings->speed =
+ port_info->speed <
+ ARRAY_LEN(hw_to_ethtool_speed) ?
hw_to_ethtool_speed[port_info->speed] :
(u32)SPEED_UNKNOWN;
+ }
link_settings->duplex = port_info->duplex;
} else {
@@ -956,28 +1004,28 @@ static void hinic3_link_port_type(struct cmd_link_settings *link_settings,
{
switch (port_type) {
case MAG_CMD_WIRE_TYPE_ELECTRIC:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_TP);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_TP);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, TP);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, TP);
link_settings->port = PORT_TP;
break;
case MAG_CMD_WIRE_TYPE_AOC:
case MAG_CMD_WIRE_TYPE_MM:
case MAG_CMD_WIRE_TYPE_SM:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_FIBRE);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_FIBRE);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, FIBRE);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, FIBRE);
link_settings->port = PORT_FIBRE;
break;
case MAG_CMD_WIRE_TYPE_COPPER:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_FIBRE);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_FIBRE);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, FIBRE);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, FIBRE);
link_settings->port = PORT_DA;
break;
case MAG_CMD_WIRE_TYPE_BACKPLANE:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_Backplane);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Backplane);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Backplane);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Backplane);
link_settings->port = PORT_NONE;
break;
@@ -1000,19 +1048,58 @@ static int get_link_pause_settings(struct hinic3_nic_dev *nic_dev,
return err;
}
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_Pause);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Pause);
if (nic_pause.rx_pause && nic_pause.tx_pause) {
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Pause);
} else if (nic_pause.tx_pause) {
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Asym_Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Asym_Pause);
} else if (nic_pause.rx_pause) {
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Pause);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Asym_Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Asym_Pause);
}
return 0;
}
+static bool is_bit_offset_defined(u8 bit_offset)
+{
+ if (bit_offset < __ETHTOOL_LINK_MODE_MASK_NBITS)
+ return true;
+ return false;
+}
+
+static void ethtool_add_supported_advertised_fec(
+ struct cmd_link_settings *link_settings, u32 fec, u8 cmd)
+{
+ u8 i;
+
+ for (i = 0; i < HINIC_ETHTOOL_FEC_INFO_LEN; i++) {
+ if ((fec & BIT(hinic3_ethtool_fec_info[i].hinic_fec_offset)) == 0)
+ continue;
+ if ((is_bit_offset_defined(
+ hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true) &&
+ (cmd == HINIC_ADVERTISED_FEC_CMD)) {
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset,
+ link_settings->advertising);
+ return; /* There can be only one advertised fec mode. */
+ }
+ if ((is_bit_offset_defined(
+ hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true) &&
+ (cmd == HINIC_SUPPORTED_FEC_CMD))
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset,
+ link_settings->supported);
+ }
+}
+
+static void hinic3_link_fec_type(struct cmd_link_settings *link_settings,
+ u32 fec, u32 supported_fec)
+{
+ ethtool_add_supported_advertised_fec(link_settings, supported_fec,
+ HINIC_SUPPORTED_FEC_CMD);
+ ethtool_add_supported_advertised_fec(link_settings, fec,
+ HINIC_ADVERTISED_FEC_CMD);
+}
+
static int get_link_settings(struct net_device *netdev,
struct cmd_link_settings *link_settings)
{
@@ -1033,13 +1120,19 @@ static int get_link_settings(struct net_device *netdev,
hinic3_link_port_type(link_settings, port_info.port_type);
+ /* port_info.fec is bit offset, value is BIT(port_info.fec);
+ * but port_info.supported_fec_mode is bit value
+ */
+ hinic3_link_fec_type(link_settings, BIT(port_info.fec),
+ port_info.supported_fec_mode);
+
link_settings->autoneg = port_info.autoneg_state == PORT_CFG_AN_ON ?
AUTONEG_ENABLE :
AUTONEG_DISABLE;
if (port_info.autoneg_cap)
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_Autoneg);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Autoneg);
if (port_info.autoneg_state == PORT_CFG_AN_ON)
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Autoneg);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Autoneg);
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
err = get_link_pause_settings(nic_dev, link_settings);
@@ -1163,23 +1256,19 @@ static int hinic3_set_settings_to_hw(struct hinic3_nic_dev *nic_dev,
struct net_device *netdev = nic_dev->netdev;
struct hinic3_link_ksettings settings = { 0 };
int speed_level = 0;
- char set_link_str[128] = { 0 };
+ char set_link_str[HINIC_SET_LINK_STR_LEN] = {0};
+ char link_info[HINIC_SET_LINK_STR_LEN] = {0};
int err = 0;
- err = snprintf(set_link_str, sizeof(set_link_str) - 1, "%s",
+ snprintf(link_info, sizeof(link_info), "%s",
(bool)(set_settings & HILINK_LINK_SET_AUTONEG) ?
((bool)autoneg ? "autong enable " :
- "autong disable ") :
- "");
- if (err < 0)
- return -EINVAL;
+ "autong disable ") : "");
if (set_settings & HILINK_LINK_SET_SPEED) {
speed_level = hinic3_ethtool_to_hw_speed_level(speed);
- err = snprintf(set_link_str, sizeof(set_link_str) - 1,
- "%sspeed %u ", set_link_str, speed);
- if (err < 0)
- return -EINVAL;
+ snprintf(set_link_str, sizeof(set_link_str),
+ "%sspeed %u ", link_info, speed);
}
settings.valid_bitmap = set_settings;
@@ -1218,7 +1307,8 @@ static int set_link_settings(struct net_device *netdev, u8 autoneg, u32 speed)
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
int hinic3_set_link_ksettings(struct net_device *netdev,
- const struct ethtool_link_ksettings *link_settings)
+ const
+ struct ethtool_link_ksettings *link_settings)
{
/* Only support to set autoneg and speed */
return set_link_settings(netdev, link_settings->base.autoneg,
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
index 70346d6..2daa7f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
@@ -82,7 +82,7 @@ static struct hinic3_mac_filter *hinic3_add_filter(struct hinic3_nic_dev *nic_de
struct list_head *mac_filter_list,
u8 *addr)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
@@ -117,7 +117,7 @@ static void hinic3_del_filter(struct hinic3_nic_dev *nic_dev,
static struct hinic3_mac_filter *hinic3_mac_filter_entry_clone(const struct hinic3_mac_filter *src)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
index ef8c62b..a3136ce 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
@@ -40,6 +40,7 @@ enum hinic3_channel_id {
HINIC3_CHANNEL_DSW,
HINIC3_CHANNEL_MIG,
HINIC3_CHANNEL_CRYPT,
+ HINIC3_CHANNEL_VROCE,
HINIC3_CHANNEL_MAX = 32,
};
@@ -397,6 +398,16 @@ void hinic3_free_cmd_buf(void *hwdev, struct hinic3_cmd_buf *cmd_buf);
**/
int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read clear
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+
/**
* @brief hinic3_sm_ctr_rd32 - small single 32 counter read
* @param hwdev: device pointer to hwdev
@@ -810,6 +821,13 @@ int hinic3_dbg_lt_wr_16byte_mask(void *hwdev, u8 dest, u8 instance,
*/
void hinic3_link_event_stats(void *dev, u8 link);
+/**
+ * @brief hinic3_get_link_event_stats - link event stats
+ * @param hwdev: device pointer to hwdev
+ * @param link: link status
+ */
+int hinic3_get_link_event_stats(void *dev, int *link_state);
+
/**
* @brief hinic3_get_hw_pf_infos - get pf infos
* @param hwdev: device pointer to hwdev
@@ -856,4 +874,5 @@ void hinic3_set_api_stop(void *hwdev);
int hinic3_activate_firmware(void *hwdev, u8 cfg_index);
int hinic3_switch_config(void *hwdev, u8 cfg_index);
+bool hinic3_is_optical_module_mode(void *hwdev);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
index 7e59c81..6525b76 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
@@ -47,12 +47,16 @@ static void qp_add_napi(struct hinic3_irq *irq_cfg)
netif_napi_add_weight(nic_dev->netdev, &irq_cfg->napi,
hinic3_poll, nic_dev->poll_weight);
napi_enable(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_IS_REGIN;
}
-static void qp_del_napi(struct hinic3_irq *irq_cfg)
+void qp_del_napi(struct hinic3_irq *irq_cfg)
{
- napi_disable(&irq_cfg->napi);
- netif_napi_del(&irq_cfg->napi);
+ if (irq_cfg->napi_reign == NAPI_IS_REGIN) {
+ napi_disable(&irq_cfg->napi);
+ netif_napi_del(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_NOT_REGIN;
+ }
}
static irqreturn_t qp_irq(int irq, void *data)
@@ -60,7 +64,8 @@ static irqreturn_t qp_irq(int irq, void *data)
struct hinic3_irq *irq_cfg = (struct hinic3_irq *)data;
struct hinic3_nic_dev *nic_dev = netdev_priv(irq_cfg->netdev);
- hinic3_misx_intr_clear_resend_bit(nic_dev->hwdev, irq_cfg->msix_entry_idx, 1);
+ hinic3_misx_intr_clear_resend_bit(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx, 1);
napi_schedule(&irq_cfg->napi);
@@ -95,7 +100,8 @@ static int hinic3_request_irq(struct hinic3_irq *irq_cfg, u16 q_id)
return err;
}
- err = request_irq(irq_cfg->irq_id, &qp_irq, 0, irq_cfg->irq_name, irq_cfg);
+ err = request_irq(irq_cfg->irq_id, &qp_irq, 0,
+ irq_cfg->irq_name, irq_cfg);
if (err) {
nicif_err(nic_dev, drv, irq_cfg->netdev, "Failed to request Rx irq\n");
qp_del_napi(irq_cfg);
@@ -138,12 +144,8 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev)
local_cpu = cpumask_local_spread(q_id, dev_to_node(&pdev->dev));
cpumask_set_cpu(local_cpu, &irq_cfg->affinity_mask);
- err = snprintf(irq_cfg->irq_name, sizeof(irq_cfg->irq_name),
- "%s_qp%u", nic_dev->netdev->name, q_id);
- if (err < 0) {
- err = -EINVAL;
- goto req_tx_irq_err;
- }
+ snprintf(irq_cfg->irq_name, sizeof(irq_cfg->irq_name),
+ "%s_qp%u", nic_dev->netdev->name, q_id);
err = hinic3_request_irq(irq_cfg, q_id);
if (err) {
@@ -151,20 +153,25 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev)
goto req_tx_irq_err;
}
- hinic3_set_msix_auto_mask_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ hinic3_set_msix_auto_mask_state(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx,
HINIC3_SET_MSIX_AUTO_MASK);
- hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx, HINIC3_MSIX_ENABLE);
+ hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ HINIC3_MSIX_ENABLE);
}
- INIT_DELAYED_WORK(&nic_dev->moderation_task, hinic3_auto_moderation_work);
+ INIT_DELAYED_WORK(&nic_dev->moderation_task,
+ hinic3_auto_moderation_work);
return 0;
req_tx_irq_err:
for (i = 0; i < q_id; i++) {
irq_cfg = &nic_dev->q_params.irq_cfg[i];
- hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx, HINIC3_MSIX_DISABLE);
- hinic3_set_msix_auto_mask_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ HINIC3_MSIX_DISABLE);
+ hinic3_set_msix_auto_mask_state(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx,
HINIC3_CLR_MSIX_AUTO_MASK);
hinic3_release_irq(irq_cfg);
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
deleted file mode 100644
index 2482c5f..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_LLD_H
-#define HINIC3_LLD_H
-
-#include "hinic3_crm.h"
-
-struct hinic3_lld_dev {
- struct pci_dev *pdev;
- void *hwdev;
-};
-
-struct hinic3_uld_info {
- /* When the function does not need to initialize the corresponding uld,
- * @probe needs to return 0 and uld_dev is set to NULL;
- * if uld_dev is NULL, @remove will not be called when uninstalling
- */
- int (*probe)(struct hinic3_lld_dev *lld_dev, void **uld_dev, char *uld_dev_name);
- void (*remove)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- int (*suspend)(struct hinic3_lld_dev *lld_dev, void *uld_dev, pm_message_t state);
- int (*resume)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- void (*event)(struct hinic3_lld_dev *lld_dev, void *uld_dev,
- struct hinic3_event_info *event);
- int (*ioctl)(void *uld_dev, u32 cmd, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size);
-};
-
-/* hinic3_register_uld - register an upper-layer driver
- * @type: uld service type
- * @uld_info: uld callback
- *
- * Registers an upper-layer driver.
- * Traverse existing devices and call @probe to initialize the uld device.
- */
-int hinic3_register_uld(enum hinic3_service_type type, struct hinic3_uld_info *uld_info);
-
-/**
- * hinic3_unregister_uld - unregister an upper-layer driver
- * @type: uld service type
- *
- * Traverse existing devices and call @remove to uninstall the uld device.
- * Unregisters an existing upper-layer driver.
- */
-void hinic3_unregister_uld(enum hinic3_service_type type);
-
-void lld_hold(void);
-void lld_put(void);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_name - get lld device by chip name
- * @param chip_name: chip name
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_name(const char *chip_name);
-
-/**
- * @brief lld_dev_hold - get reference to lld_dev
- * @param dev: lld device
- *
- * Hold reference to device to keep it from being freed
- **/
-void lld_dev_hold(struct hinic3_lld_dev *dev);
-
-/**
- * @brief lld_dev_put - release reference to lld_dev
- * @param dev: lld device
- *
- * Release reference to device to allow it to be freed
- **/
-void lld_dev_put(struct hinic3_lld_dev *dev);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name_unsafe - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * hinic3_get_lld_dev_by_dev_name_unsafe() is completely analogous to
- * hinic3_get_lld_dev_by_dev_name(), The only difference is that the reference
- * of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that lld_dev will not be freed during the remove process
- * when using lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name_unsafe(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_and_port - get lld device by chip name and port id
- * @param chip_name: chip name
- * @param port_id: port id
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name, u8 port_id);
-
-/**
- * @brief hinic3_get_ppf_lld_dev - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief hinic3_get_ppf_lld_dev_unsafe - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * hinic3_get_ppf_lld_dev_unsafe() is completely analogous to hinic3_get_ppf_lld_dev(),
- * The only difference is that the reference of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that ppf's lld_dev will not be freed during the remove process
- * when using ppf lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev_unsafe(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief uld_dev_hold - get reference to uld_dev
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * Hold reference to uld device to keep it from being freed
- **/
-void uld_dev_hold(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief uld_dev_put - release reference to lld_dev
- * @param dev: lld device
- * @param type: uld service type
- *
- * Release reference to uld device to allow it to be freed
- **/
-void uld_dev_put(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * The value of uld_dev reference increases when uld_dev is obtained. The caller needs
- * to release the reference by calling uld_dev_put.
- **/
-void *hinic3_get_uld_dev(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev_unsafe - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * hinic3_get_uld_dev_unsafe() is completely analogous to hinic3_get_uld_dev(),
- * The only difference is that the reference of uld_dev is not increased when uld_dev is obtained.
- *
- * The caller must ensure that uld_dev will not be freed during the remove process
- * when using uld_dev.
- **/
-void *hinic3_get_uld_dev_unsafe(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_chip_name - get chip name by lld device
- * @param lld_dev: lld device
- * @param chip_name: String for storing the chip name
- * @param max_len: Maximum number of characters to be copied for chip_name
- **/
-int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len);
-
-struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev);
-
-struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev);
-
-bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service);
-
-int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
- bool vf_srv_load);
-
-int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id,
- u16 service, bool en);
-
-bool hinic3_get_vf_load_state(struct pci_dev *pdev);
-
-int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state);
-
-int hinic3_attach_nic(struct hinic3_lld_dev *lld_dev);
-
-void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
-
-int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-const char **hinic3_get_uld_names(void);
-int hinic3_lld_init(void);
-void hinic3_lld_exit(void);
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
index 2fe808b..5e4e184 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
@@ -17,11 +17,22 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_hw.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_common.h"
+#include "mag_mpu_cmd_defs.h"
+
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
+#define CAP_INFO_MAX_LEN 512
+#define DEVICE_VENDOR_MAX_LEN 17
+#define READ_RSFEC_REGISTER_DELAY_TIME_MS 500
+
+struct parse_tlv_info g_page_info = {0};
+struct drv_tag_mag_cmd_get_xsfp_tlv_rsp g_xsfp_tlv_info = {0};
static int mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
@@ -78,8 +89,10 @@ int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats)
return -ENOMEM;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
memset(&stats_info, 0, sizeof(stats_info));
stats_info.port_id = hinic3_physical_port_id(hwdev);
@@ -104,6 +117,64 @@ out:
}
EXPORT_SYMBOL(hinic3_get_phy_port_stats);
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats)
+{
+ struct mag_cmd_get_mag_cnt *port_stats = NULL;
+ struct mag_cmd_get_mag_cnt stats_info;
+ u16 out_size = sizeof(*port_stats);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !stats)
+ return -EINVAL;
+
+ port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
+ if (!port_stats)
+ return -ENOMEM;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ memset(&stats_info, 0, sizeof(stats_info));
+ stats_info.port_id = hinic3_physical_port_id(hwdev);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT,
+ &stats_info, sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+ /* 读2遍, 清除误码残留 */
+ msleep(READ_RSFEC_REGISTER_DELAY_TIME_MS);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT, &stats_info,
+ sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+
+ memcpy(stats, &port_stats->mag_csr[MAG_RX_RSFEC_ERR_CW_CNT],
+ sizeof(u32));
+
+out:
+ kfree(port_stats);
+
+ return err;
+}
+EXPORT_SYMBOL(hinic3_get_phy_rsfec_stats);
+
int hinic3_set_port_funcs_state(void *hwdev, bool enable)
{
return 0;
@@ -180,6 +251,8 @@ int hinic3_get_loopback_mode(void *hwdev, u8 *mode, u8 *enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_cfg_loopback_mode(nic_io, MGMT_MSG_CMD_OP_GET, mode,
enable);
@@ -195,6 +268,8 @@ int hinic3_set_loopback_mode(void *hwdev, u8 mode, u8 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) {
nic_err(nic_io->dev_hdl, "Invalid loopback mode %u to set\n",
@@ -218,6 +293,9 @@ int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&led_info, 0, sizeof(led_info));
led_info.function_id = hinic3_global_func_id(hwdev);
@@ -249,6 +327,8 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
memset(&port_msg, 0, sizeof(port_msg));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
port_msg.port_id = hinic3_physical_port_id(hwdev);
@@ -268,9 +348,12 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
port_info->port_type = port_msg.wire_type;
port_info->speed = port_msg.speed;
port_info->fec = port_msg.fec;
+ port_info->lanes = port_msg.lanes;
port_info->supported_mode = port_msg.supported_mode;
port_info->advertised_mode = port_msg.advertised_mode;
-
+ port_info->supported_fec_mode = port_msg.supported_fec_mode;
+ /* switch Gbps to Mbps */
+ port_info->bond_speed = (u32)port_msg.bond_speed * RATE_MBPS_TO_GBPS;
return 0;
}
@@ -306,6 +389,8 @@ int hinic3_set_link_settings(void *hwdev,
memset(&info, 0, sizeof(info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
info.port_id = hinic3_physical_port_id(hwdev);
info.config_bitmap = settings->valid_bitmap;
@@ -335,6 +420,8 @@ int hinic3_get_link_state(void *hwdev, u8 *link_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&get_link, 0, sizeof(get_link));
get_link.port_id = hinic3_physical_port_id(hwdev);
@@ -364,9 +451,10 @@ void hinic3_notify_vf_link_status(struct hinic3_nic_io *nic_io,
if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
link.status = link_status;
link.port_id = hinic3_physical_port_id(nic_io->hwdev);
- err = hinic3_mbox_to_vf(nic_io->hwdev, vf_id, HINIC3_MOD_HILINK,
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
MAG_CMD_GET_LINK_STATUS, &link,
- sizeof(link), &link, &out_size, 0,
+ sizeof(link), &link, &out_size,
HINIC3_CHANNEL_NIC);
if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
@@ -387,6 +475,8 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
u16 i;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
nic_io->link_status = link_status;
for (i = 1; i <= nic_io->max_vfs; i++) {
if (!nic_io->vf_infos[HW_VF_ID_TO_OS(i)].link_forced)
@@ -394,6 +484,165 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
}
}
+static char *g_hw_to_char_fec[HILINK_FEC_MAX_TYPE] = {
+ "not set", "rsfec", "basefec",
+ "nofec", "llrsfec"};
+static char *g_hw_to_speed_info[PORT_SPEED_UNKNOWN] = {
+ "not set", "10MB", "100MB", "1GB", "10GB",
+ "25GB", "40GB", "50GB", "100GB", "200GB"};
+static char *g_hw_to_an_state_info[PORT_CFG_AN_OFF + 1] = {
+ "not set", "on", "off"};
+
+struct port_type_table {
+ u32 port_type;
+ char *port_type_name;
+};
+
+static const struct port_type_table port_optical_type_table_s[] = {
+ {LINK_PORT_UNKNOWN, "UNKNOWN"},
+ {LINK_PORT_OPTICAL_MM, "optical_sr"},
+ {LINK_PORT_OPTICAL_SM, "optical_lr"},
+ {LINK_PORT_PAS_COPPER, "copper"},
+ {LINK_PORT_ACC, "ACC"},
+ {LINK_PORT_BASET, "baset"},
+ {LINK_PORT_AOC, "AOC"},
+ {LINK_PORT_ELECTRIC, "electric"},
+ {LINK_PORT_BACKBOARD_INTERFACE, "interface"},
+};
+
+static char *get_port_type_name(u32 type)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(port_optical_type_table_s); i++) {
+ if (type == port_optical_type_table_s[i].port_type)
+ return port_optical_type_table_s[i].port_type_name;
+ }
+ return "UNKNOWN TYPE";
+}
+
+static void get_port_type(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ char **port_type)
+{
+ if (info->port_type <= LINK_PORT_BACKBOARD_INTERFACE)
+ *port_type = get_port_type_name(info->port_type);
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown port type: %u\n", info->port_type);
+}
+
+static int get_port_temperature_power(struct mag_cmd_event_port_info *info,
+ char *str)
+{
+ char cap_info[CAP_INFO_MAX_LEN];
+
+ memset(cap_info, 0, sizeof(cap_info));
+ snprintf(cap_info, CAP_INFO_MAX_LEN, "%s, %s, Temperature: %u", str,
+ info->sfp_type ? "QSFP" : "SFP", info->cable_temp);
+
+ if (info->sfp_type)
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuw %uuW %uuW %uuW",
+ cap_info, info->power[0x0], info->power[0x1],
+ info->power[0x2], info->power[0x3]);
+ else
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuW, tx power: %uuW",
+ cap_info, info->power[0x0], info->power[0x1]);
+
+ return 0;
+}
+
+static void print_cable_info(struct hinic3_nic_io *nic_io, struct mag_cmd_event_port_info *info)
+{
+ char tmp_str[CAP_INFO_MAX_LEN] = {0};
+ char tmp_vendor[DEVICE_VENDOR_MAX_LEN] = {0};
+ char *port_type = "Unknown port type";
+ int i;
+ int err = 0;
+
+ if (info->gpio_insert) {
+ sdk_info(nic_io->dev_hdl, "Cable unpresent\n");
+ return;
+ }
+
+ get_port_type(nic_io, info, &port_type);
+
+ for (i = sizeof(info->vendor_name) - 1; i >= 0; i--) {
+ if (info->vendor_name[i] == ' ')
+ info->vendor_name[i] = '\0';
+ else
+ break;
+ }
+
+ memcpy(tmp_vendor, info->vendor_name, sizeof(info->vendor_name));
+ snprintf(tmp_str, CAP_INFO_MAX_LEN, "Vendor: %s, %s, length: %um, max_speed: %uGbps",
+ tmp_vendor, port_type, info->cable_length, info->max_speed);
+
+ if (info->port_type == LINK_PORT_OPTICAL_MM ||
+ info->port_type == LINK_PORT_AOC) {
+ err = get_port_temperature_power(info, tmp_str);
+ if (err)
+ return;
+ }
+
+ sdk_info(nic_io->dev_hdl, "Cable information: %s\n", tmp_str);
+}
+
+static void print_link_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ enum hinic3_nic_event_type type)
+{
+ char *fec = "None";
+ char *speed = "None";
+ char *an_state = "None";
+
+ if (info->fec < HILINK_FEC_MAX_TYPE)
+ fec = g_hw_to_char_fec[info->fec];
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown fec type: %u\n", info->fec);
+
+ if (info->an_state > PORT_CFG_AN_OFF) {
+ sdk_info(nic_io->dev_hdl, "an_state %d is invalid",
+ info->an_state);
+ return;
+ }
+
+ an_state = g_hw_to_an_state_info[info->an_state];
+
+ if (info->speed >= PORT_SPEED_UNKNOWN) {
+ sdk_info(nic_io->dev_hdl, "speed %u is invalid", info->speed);
+ return;
+ }
+
+ speed = g_hw_to_speed_info[info->speed];
+ sdk_info(nic_io->dev_hdl, "Link information: speed %s, %s, autoneg %s",
+ speed, fec, an_state);
+}
+
+void print_port_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *port_info,
+ enum hinic3_nic_event_type type)
+{
+ print_cable_info(nic_io, port_info);
+
+ print_link_info(nic_io, port_info, type);
+
+ if (type == EVENT_NIC_LINK_UP)
+ return;
+
+ sdk_info(nic_io->dev_hdl, "PMA ctrl: %s, tx %s, rx %s, PMA fifo reg: 0x%x, PMA signal ok reg: 0x%x, RF/LF status reg: 0x%x\n",
+ port_info->pma_ctrl == 1 ? "off" : "on",
+ port_info->tx_enable ? "enable" : "disable",
+ port_info->rx_enable ? "enable" : "disable", port_info->pma_fifo_reg,
+ port_info->pma_signal_ok_reg, port_info->rf_lf);
+ sdk_info(nic_io->dev_hdl, "alos: %u, rx_los: %u, PCS 64 66b reg: 0x%x, PCS link: 0x%x, MAC link: 0x%x PCS_err_cnt: 0x%x\n",
+ port_info->alos, port_info->rx_los, port_info->pcs_64_66b_reg,
+ port_info->pcs_link, port_info->pcs_mac_link,
+ port_info->pcs_err_cnt);
+ sdk_info(nic_io->dev_hdl, "his_link_machine_state = 0x%08x, cur_link_machine_state = 0x%08x\n",
+ port_info->his_link_machine_state,
+ port_info->cur_link_machine_state);
+}
+
static int hinic3_get_vf_link_status_msg_handler(struct hinic3_nic_io *nic_io,
u16 vf_id, void *buf_in,
u16 in_size, void *buf_out,
@@ -433,6 +682,10 @@ static void get_port_info(void *hwdev,
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (hinic3_func_type(hwdev) != TYPE_VF && link_status->status) {
err = hinic3_get_port_info(hwdev, &port_info, HINIC3_CHANNEL_NIC);
if (err) {
@@ -457,8 +710,18 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
struct hinic3_event_info event_info = {0};
struct hinic3_event_link_info *link_info = (void *)event_info.event_data;
struct hinic3_nic_io *nic_io = NULL;
+#ifndef __UEFI__
+ struct pci_dev *pdev = NULL;
+#endif
+ /* Ignore link change event */
+ if (hinic3_is_bm_slave_host(hwdev))
+ return;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
link_status = buf_in;
sdk_info(nic_io->dev_hdl, "Link status report received, func_id: %u, status: %u\n",
@@ -475,6 +738,15 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
hinic3_event_callback(hwdev, &event_info);
+#ifndef __UEFI__
+ if (nic_io->pcidev_hdl != NULL) {
+ pdev = nic_io->pcidev_hdl;
+ if (pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID) {
+ return;
+ }
+ }
+#endif
+
if (hinic3_func_type(hwdev) != TYPE_VF) {
hinic3_notify_all_vfs_link_changed(hwdev, link_status->status);
ret_link_status = buf_out;
@@ -483,20 +755,142 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
}
}
+static void port_info_event_printf(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_event_port_info *port_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info;
+ enum hinic3_nic_event_type type;
+
+ if (!hwdev) {
+ pr_err("hwdev is NULL\n");
+ return;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ if (in_size != sizeof(*port_info)) {
+ sdk_info(nic_io->dev_hdl, "Invalid port info message size %d, should be %ld\n",
+ in_size, sizeof(*port_info));
+ return;
+ }
+
+ ((struct mag_cmd_event_port_info *)buf_out)->head.status = 0;
+
+ type = port_info->event_type;
+ if (type < EVENT_NIC_LINK_DOWN || type > EVENT_NIC_LINK_UP) {
+ sdk_info(nic_io->dev_hdl, "Invalid hilink info report, type: %d\n",
+ type);
+ return;
+ }
+
+ print_port_info(nic_io, port_info, type);
+
+ memset(&event_info, 0, sizeof(event_info));
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = type;
+
+ *out_size = sizeof(*port_info);
+
+ hinic3_event_callback(hwdev, &event_info);
+}
+
+void hinic3_notify_vf_bond_status(struct hinic3_nic_io *nic_io,
+ u16 vf_id, u8 bond_status)
+{
+ struct mag_cmd_get_bond_status bond;
+ struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ u16 out_size = sizeof(bond);
+ int err;
+
+ memset(&bond, 0, sizeof(bond));
+ if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
+ bond.status = bond_status;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
+ MAG_CMD_GET_BOND_STATUS, &bond,
+ sizeof(bond), &bond, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF %u not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return;
+ }
+ if (err || !out_size || bond.head.status)
+ nic_err(nic_io->dev_hdl,
+ "Send bond change event to VF %hu failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err, bond.head.status,
+ out_size);
+ }
+}
+
+void hinic3_notify_all_vfs_bond_changed(void *hwdev, u8 bond_status)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 i;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ nic_io->link_status = bond_status;
+ for (i = 1; i <= nic_io->max_vfs; i++)
+ hinic3_notify_vf_bond_status(nic_io, i, bond_status);
+}
+
+static void bond_status_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_get_bond_status *bond_status = NULL;
+ struct hinic3_event_info event_info = {};
+ struct hinic3_nic_io *nic_io = NULL;
+ struct mag_cmd_get_bond_status *ret_bond_status = NULL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+
+ bond_status = (struct mag_cmd_get_bond_status *)buf_in;
+ sdk_info(nic_io->dev_hdl, "bond status report received, func_id: %u, status: %u\n",
+ hinic3_global_func_id(hwdev), bond_status->status);
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = bond_status->status ?
+ EVENT_NIC_BOND_UP : EVENT_NIC_BOND_DOWN;
+
+ hinic3_event_callback(hwdev, &event_info);
+
+ if (hinic3_func_type(hwdev) != TYPE_VF) {
+ hinic3_notify_all_vfs_bond_changed(hwdev, bond_status->status);
+ ret_bond_status = buf_out;
+ ret_bond_status->head.status = 0;
+ *out_size = sizeof(*ret_bond_status);
+ }
+}
+
static void cable_plug_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct mag_cmd_wire_event *plug_event = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_event_info event_info;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
rt_cmd->mpu_send_sfp_abs = false;
rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
memset(&event_info, 0, sizeof(event_info));
@@ -518,9 +912,12 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
{
struct mag_cmd_get_xsfp_info *sfp_info = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_info)) {
sdk_err(nic_io->dev_hdl, "Invalid sfp info cmd, length: %u, should be %ld\n",
in_size, sizeof(*sfp_info));
@@ -528,10 +925,41 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
}
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
memcpy(&rt_cmd->std_sfp_info, sfp_info,
sizeof(struct mag_cmd_get_xsfp_info));
rt_cmd->mpu_send_sfp_info = true;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+}
+
+static void port_xsfp_tlv_info_event(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *xsfp_tlv_info = buf_in;
+ struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
+ size_t cpy_len = in_size - sizeof(struct mgmt_msg_head) -
+ XSFP_TLV_PRE_INFO_LEN;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL)
+ return;
+
+ if (cpy_len > XSFP_CMIS_INFO_MAX_SIZE) {
+ sdk_err(nic_io->dev_hdl, "invalid cpy_len(%lu)\n", cpy_len);
+ return;
+ }
+ rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ rt_cmd_ext->std_xsfp_tlv_info.port_id = xsfp_tlv_info->port_id;
+ memcpy(&(rt_cmd_ext->std_xsfp_tlv_info.tlv_buf[0]),
+ &(xsfp_tlv_info->tlv_buf[0]), cpy_len);
+ rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = true;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
}
@@ -543,6 +971,8 @@ static void port_sfp_abs_event(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_abs)) {
sdk_err(nic_io->dev_hdl, "Invalid sfp absent cmd, length: %u, should be %ld\n",
in_size, sizeof(*sfp_abs));
@@ -564,9 +994,11 @@ bool hinic3_if_sfp_absent(void *hwdev)
u8 port_id = hinic3_physical_port_id(hwdev);
u16 out_size = sizeof(sfp_abs);
int err;
- bool sfp_abs_status;
+ bool sfp_abs_status = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return true;
memset(&sfp_abs, 0, sizeof(sfp_abs));
rt_cmd = &nic_io->nic_cfg.rt_cmd;
@@ -597,10 +1029,185 @@ bool hinic3_if_sfp_absent(void *hwdev)
return (sfp_abs.abs_status == 0 ? false : true);
}
+int hinic3_get_sfp_tlv_info(void *hwdev, struct drv_tag_mag_cmd_get_xsfp_tlv_rsp
+ *sfp_tlv_info,
+ const struct tag_mag_cmd_get_xsfp_tlv_req
+ *sfp_tlv_info_req)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ u16 out_size = sizeof(*sfp_tlv_info);
+ int err;
+
+ if ((hwdev == NULL) || (sfp_tlv_info == NULL))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL)
+ return -EINVAL;
+
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ if (rt_cmd_ext->mpu_send_xsfp_tlv_info == true) {
+ if (rt_cmd_ext->std_xsfp_tlv_info.head.status != 0) {
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return -EIO;
+ }
+
+ memcpy(sfp_tlv_info, &rt_cmd_ext->std_xsfp_tlv_info,
+ sizeof(*sfp_tlv_info));
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_TLV_INFO,
+ (void *)sfp_tlv_info_req,
+ sizeof(*sfp_tlv_info_req),
+ sfp_tlv_info, &out_size);
+ if ((sfp_tlv_info->head.status != 0) || (err != 0) || (out_size == 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get port%u tlv sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
+ hinic3_physical_port_id(hwdev), err,
+ sfp_tlv_info->head.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_get_page_pos(u32 page_id, u32 content_len, u32 *pos)
+{
+ if (page_id <= QSFP_CMIS_PAGE_03H) {
+ *pos = (page_id * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_11H) {
+ *pos = (QSFP_CMIS_PAGE_04H * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_12H) {
+ *pos = (QSFP_CMIS_PAGE_05H * content_len);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int hinic3_get_page_key_info(struct mgmt_tlv_info *tlv_info,
+ struct parse_tlv_info *page_info, u8 idx,
+ u32 *total_len)
+{
+ u8 *src_addr = NULL;
+ u8 *dst_addr = NULL;
+ u8 *tmp_addr = NULL;
+ u32 page_id = 0;
+ u32 content_len = 0;
+ u32 src_pos = 0;
+ int ret;
+
+ page_id = MGMT_TLV_GET_U32(tlv_info->value);
+ content_len = tlv_info->length - MGMT_TLV_U32_SIZE;
+ if (page_id == QSFP_CMIS_PAGE_00H) {
+ tmp_addr = (u8 *)(tlv_info + 1);
+ page_info->id = *(tmp_addr + MGMT_TLV_U32_SIZE);
+ }
+
+ ret = hinic3_trans_cmis_get_page_pos(page_id, content_len, &src_pos);
+ if (ret != 0)
+ return ret;
+
+ src_addr = page_info->tlv_page_info + src_pos;
+ tmp_addr = (u8 *)(tlv_info + 1);
+ dst_addr = tmp_addr + MGMT_TLV_U32_SIZE;
+ memcpy(src_addr, dst_addr, content_len);
+
+ if (idx < XSFP_CMIS_PARSE_PAGE_NUM)
+ page_info->tlv_page_num[idx] = page_id;
+
+ *total_len += content_len;
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_tlv_info_to_buf(u8 *sfp_tlv_info,
+ struct parse_tlv_info *page_info)
+{
+ struct mgmt_tlv_info *tlv_info = NULL;
+ u8 *tlv_buf = sfp_tlv_info;
+ u8 idx = 0;
+ u32 total_len = 0;
+ int ret = 0;
+ bool need_continue = true;
+
+ if ((sfp_tlv_info == NULL) || (page_info == NULL))
+ return -EIO;
+
+ while (need_continue) {
+ tlv_info = (struct mgmt_tlv_info *)tlv_buf;
+ switch (tlv_info->type) {
+ case MAG_XSFP_TYPE_PAGE:
+ ret = hinic3_get_page_key_info(
+ tlv_info, page_info, idx, &total_len);
+ if (ret != 0) {
+ pr_err("lib_get_page_key_info fail,ret:0x%x.\n",
+ ret);
+ break;
+ }
+ idx++;
+ break;
+
+ case MAG_XSFP_TYPE_WIRE_TYPE:
+ page_info->wire_type =
+ MGMT_TLV_GET_U32(&(tlv_info->value));
+ break;
+
+ case MAG_XSFP_TYPE_END:
+ need_continue = false;
+ break;
+
+ default:
+ break;
+ }
+
+ tlv_buf += (sizeof(struct mgmt_tlv_info) + tlv_info->length);
+ }
+
+ page_info->tlv_page_info_len = total_len;
+
+ return 0;
+}
+
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len)
+{
+ int err = 0;
+ struct tag_mag_cmd_get_xsfp_tlv_req xsfp_tlv_info_req = {0};
+
+ xsfp_tlv_info_req.rsp_buf_len = XSFP_CMIS_INFO_MAX_SIZE;
+ xsfp_tlv_info_req.port_id = hinic3_physical_port_id(hwdev);
+ err = hinic3_get_sfp_tlv_info(hwdev, &g_xsfp_tlv_info,
+ &xsfp_tlv_info_req);
+ if (err != 0)
+ return err;
+
+ err = hinic3_trans_cmis_tlv_info_to_buf(g_xsfp_tlv_info.tlv_buf,
+ &g_page_info);
+ if (err)
+ return -ENOMEM;
+
+ memcpy(data, g_page_info.tlv_page_info, len);
+
+ return (err == 0) ? 0 : -ENOMEM;
+}
+
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
{
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ u8 sfp_info_status = 0;
u16 out_size = sizeof(*sfp_info);
int err;
@@ -608,13 +1215,17 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ sfp_info_status = rt_cmd->std_sfp_info.head.status;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (sfp_info_status != 0) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return -EIO;
+ return (sfp_info_status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ ? HINIC3_MGMT_CMD_UNSUPPORTED : -EIO;
}
memcpy(sfp_info, &rt_cmd->std_sfp_info, sizeof(*sfp_info));
@@ -626,7 +1237,12 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
sfp_info->port_id = hinic3_physical_port_id(hwdev);
err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_INFO, sfp_info,
sizeof(*sfp_info), sfp_info, &out_size);
- if (sfp_info->head.status || err || !out_size) {
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ return HINIC3_MGMT_CMD_UNSUPPORTED;
+
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ return -EOPNOTSUPP;
+ if ((sfp_info->head.status != 0) || (err != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Failed to get port%u sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
hinic3_physical_port_id(hwdev), err,
@@ -642,7 +1258,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
struct mag_cmd_get_xsfp_info sfp_info;
int err;
- if (!hwdev || !data)
+ if (!hwdev || !data || len > PAGE_SIZE)
return -EINVAL;
if (hinic3_if_sfp_absent(hwdev))
@@ -654,7 +1270,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
if (err)
return err;
- memcpy(data, sfp_info.sfp_info, len);
+ memcpy(data, sfp_info.sfp_info, sizeof(sfp_info.sfp_info));
return 0;
}
@@ -664,7 +1280,7 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
- int err;
+ int err = 0;
if (!hwdev || !sfp_type || !sfp_type_ext)
return -EINVAL;
@@ -677,20 +1293,35 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (rt_cmd->std_sfp_info.head.status == 0) {
+ *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
+ *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ if (rt_cmd->std_sfp_info.head.status != HINIC3_MGMT_CMD_UNSUPPORTED) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
return -EIO;
}
- *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
- *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
- mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return 0;
+ err = HINIC3_MGMT_CMD_UNSUPPORTED; /* cmis */
}
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
- STD_SFP_INFO_MAX_SIZE);
+ if (err == 0) {
+ err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ } else {
+ /* mpu_send_sfp_info is false */
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ }
+
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+
if (err)
return err;
@@ -796,16 +1427,23 @@ int hinic3_set_pf_bw_limit(void *hwdev, u32 bw_limit)
return -EINVAL;
}
- old_bw_limit = nic_io->nic_cfg.pf_bw_limit;
- nic_io->nic_cfg.pf_bw_limit = bw_limit;
+ if (nic_io->direct == HINIC3_NIC_TX) {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_tx_limit;
+ nic_io->nic_cfg.pf_bw_tx_limit = bw_limit;
+ } else {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_rx_limit;
+ nic_io->nic_cfg.pf_bw_rx_limit = bw_limit;
+ }
err = hinic3_update_pf_bw(hwdev);
if (err) {
- nic_io->nic_cfg.pf_bw_limit = old_bw_limit;
- return err;
+ if (nic_io->direct == HINIC3_NIC_TX)
+ nic_io->nic_cfg.pf_bw_tx_limit = old_bw_limit;
+ else
+ nic_io->nic_cfg.pf_bw_rx_limit = old_bw_limit;
}
- return 0;
+ return err;
}
static const struct vf_msg_handler vf_mag_cmd_handler[] = {
@@ -828,6 +1466,9 @@ int hinic3_pf_mag_mbox_handler(void *hwdev, u16 vf_id,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
for (index = 0; index < cmd_size; index++) {
handler = &vf_mag_cmd_handler[index];
@@ -848,6 +1489,11 @@ static struct nic_event_handler mag_cmd_handler[] = {
.handler = link_status_event_handler,
},
+ {
+ .cmd = MAG_CMD_EVENT_PORT_INFO,
+ .handler = port_info_event_printf,
+ },
+
{
.cmd = MAG_CMD_WIRE_EVENT,
.handler = cable_plug_event,
@@ -862,6 +1508,16 @@ static struct nic_event_handler mag_cmd_handler[] = {
.cmd = MAG_CMD_GET_XSFP_PRESENT,
.handler = port_sfp_abs_event,
},
+
+ {
+ .cmd = MAG_CMD_GET_BOND_STATUS,
+ .handler = bond_status_event_handler,
+ },
+
+ {
+ .cmd = MAG_CMD_GET_XSFP_TLV_INFO,
+ .handler = port_xsfp_tlv_info_event,
+ },
};
static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
@@ -877,6 +1533,9 @@ static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
for (i = 0; i < size; i++) {
if (cmd == mag_cmd_handler[i].cmd) {
mag_cmd_handler[i].handler(hwdev, buf_in, in_size,
@@ -917,7 +1576,8 @@ static int _mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u32 i, cmd_cnt = ARRAY_LEN(vf_mag_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_mag_cmd_handler[i].cmd) {
cmd_to_pf = true;
@@ -949,3 +1609,124 @@ static int mag_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in,
return _mag_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out,
out_size, channel);
}
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+struct fecparam_value_map {
+ u8 hinic3_fec_offset;
+ u8 hinic3_fec_value;
+ u8 ethtool_fec_value;
+};
+
+static void fecparam_convert(u32 opcode, u8 in_fec_param, u8 *out_fec_param)
+{
+ u8 i;
+ u8 fec_value_table_lenth;
+ struct fecparam_value_map fec_value_table[] = {
+ {PORT_FEC_NOT_SET, BIT(PORT_FEC_NOT_SET), ETHTOOL_FEC_NONE},
+ {PORT_FEC_RSFEC, BIT(PORT_FEC_RSFEC), ETHTOOL_FEC_RS},
+ {PORT_FEC_BASEFEC, BIT(PORT_FEC_BASEFEC), ETHTOOL_FEC_BASER},
+ {PORT_FEC_NOFEC, BIT(PORT_FEC_NOFEC), ETHTOOL_FEC_OFF},
+#ifdef ETHTOOL_FEC_LLRS
+ {PORT_FEC_LLRSFEC, BIT(PORT_FEC_LLRSFEC), ETHTOOL_FEC_LLRS},
+#endif
+ {PORT_FEC_AUTO, BIT(PORT_FEC_AUTO), ETHTOOL_FEC_AUTO}
+ };
+
+ *out_fec_param = 0;
+ fec_value_table_lenth = (u8)(sizeof(fec_value_table) / sizeof(struct fecparam_value_map));
+
+ if (opcode == MAG_CMD_OPCODE_SET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].ethtool_fec_value) != 0)
+ /* The MPU uses the offset to determine the FEC mode. */
+ *out_fec_param =
+ fec_value_table[i].hinic3_fec_offset;
+ }
+ }
+
+ if (opcode == MAG_CMD_OPCODE_GET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].hinic3_fec_value) != 0)
+ *out_fec_param |=
+ fec_value_table[i].ethtool_fec_value;
+ }
+ }
+}
+
+/* When the ethtool is used to set the FEC mode */
+static bool check_fecparam_is_valid(u8 fec_param)
+{
+ if (
+#ifdef ETHTOOL_FEC_LLRS
+ (fec_param == ETHTOOL_FEC_LLRS) ||
+#endif
+ (fec_param == ETHTOOL_FEC_RS) ||
+ (fec_param == ETHTOOL_FEC_BASER) ||
+ (fec_param == ETHTOOL_FEC_OFF)) {
+ return true;
+ }
+ return false;
+}
+
+int set_fecparam(void *hwdev, u8 fecparam)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ u8 advertised_fec = 0;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (check_fecparam_is_valid(fecparam) == false) {
+ nic_err(nic_io->dev_hdl, "fec param is invalid, failed to set fec param\n");
+ return -EINVAL;
+ }
+ fecparam_convert(MAG_CMD_OPCODE_SET, fecparam, &advertised_fec);
+ fec_msg.opcode = MAG_CMD_OPCODE_SET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ fec_msg.advertised_fec = advertised_fec;
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0))
+ return -EINVAL;
+ return 0;
+}
+
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ fec_msg.opcode = MAG_CMD_OPCODE_GET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0))
+ return -EINVAL;
+
+ /* fec_msg.advertised_fec: bit offset,
+ *value is BIT(fec_msg.advertised_fec); fec_msg.supported_fec: value
+ */
+ fecparam_convert(MAG_CMD_OPCODE_GET, BIT(fec_msg.advertised_fec),
+ advertised_fec);
+ fecparam_convert(MAG_CMD_OPCODE_GET, fec_msg.supported_fec,
+ supported_fec);
+ return 0;
+}
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
index 6f90c86..9d14e0f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
@@ -20,6 +20,9 @@
#include <linux/debugfs.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#include "hinic3_hw.h"
#include "hinic3_crm.h"
#include "hinic3_mt.h"
@@ -35,8 +38,8 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
#include "hinic3_profile.h"
+#include "hinic3_bond.h"
-/*lint -e806*/
#define DEFAULT_POLL_WEIGHT 64
static unsigned int poll_weight = DEFAULT_POLL_WEIGHT;
module_param(poll_weight, uint, 0444);
@@ -68,7 +71,9 @@ static unsigned char set_link_status_follow = HINIC3_LINK_FOLLOW_STATUS_MAX;
module_param(set_link_status_follow, byte, 0444);
MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=default,1=follow,2=separate,3=unset");
-/*lint +e806*/
+static bool page_pool_enabled = true;
+module_param(page_pool_enabled, bool, 0444);
+MODULE_PARM_DESC(page_pool_enabled, "enable/disable page_pool feature for rxq page management (default enable)");
#define HINIC3_NIC_DEV_WQ_NAME "hinic3_nic_dev_wq"
@@ -80,6 +85,8 @@ MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=
#define HINIC3_SQ_DEPTH 1024
#define HINIC3_RQ_DEPTH 1024
+#define LRO_ENABLE 1
+
enum hinic3_rx_buff_len {
RX_BUFF_VALID_2KB = 2,
RX_BUFF_VALID_4KB = 4,
@@ -87,12 +94,15 @@ enum hinic3_rx_buff_len {
RX_BUFF_VALID_16KB = 16,
};
+#define NIC_MAX_PF_NUM 32
+
#define CONVERT_UNIT 1024
-#define BIFUR_RESOURCE_PF_SSID 0x5a1
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
-static int hinic3_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr);
+static int hinic3_netdev_event(struct notifier_block *notifier,
+ unsigned long event, void *ptr);
/* used for netdev notifier register/unregister */
static DEFINE_MUTEX(hinic3_netdev_notifiers_mutex);
@@ -101,6 +111,17 @@ static struct notifier_block hinic3_netdev_notifier = {
.notifier_call = hinic3_netdev_event,
};
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+static const struct udp_tunnel_nic_info hinic3_udp_tunnels = {
+ .set_port = hinic3_udp_tunnel_set_port,
+ .unset_port = hinic3_udp_tunnel_unset_port,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static void hinic3_register_notifier(struct hinic3_nic_dev *nic_dev)
{
int err;
@@ -134,7 +155,8 @@ static void hinic3_unregister_notifier(struct hinic3_nic_dev *nic_dev)
NETIF_F_SCTP_CRC | NETIF_F_RXCSUM | \
NETIF_F_ALL_TSO)
-static int hinic3_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr)
+static int hinic3_netdev_event(struct notifier_block *notifier,
+ unsigned long event, void *ptr)
{
struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
struct net_device *real_dev = NULL;
@@ -266,6 +288,11 @@ static void netdev_feature_init(struct net_device *netdev)
netdev->features |= dft_fts | cso_fts | tso_fts | vlan_fts;
netdev->vlan_features |= dft_fts | cso_fts | tso_fts;
+ if (nic_dev->nic_cap.lro_enable == LRO_ENABLE) {
+ netdev->features |= NETIF_F_LRO;
+ netdev->vlan_features |= NETIF_F_LRO;
+ }
+
#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT
hw_features |= get_netdev_hw_features(netdev);
#else
@@ -306,7 +333,8 @@ static void init_intr_coal_param(struct hinic3_nic_dev *nic_dev)
info->pending_limt = qp_pending_limit;
info->coalesce_timer_cfg = qp_coalesc_timer_cfg;
- info->resend_timer_cfg = HINIC3_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG;
+ info->resend_timer_cfg =
+ HINIC3_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG;
info->pkt_rate_high = HINIC3_RX_RATE_HIGH;
info->rx_usecs_high = HINIC3_RX_COAL_TIME_HIGH;
@@ -350,6 +378,7 @@ static int hinic3_init_intr_coalesce(struct hinic3_nic_dev *nic_dev)
static void hinic3_free_intr_coalesce(struct hinic3_nic_dev *nic_dev)
{
kfree(nic_dev->intr_coalesce);
+ nic_dev->intr_coalesce = NULL;
}
static int hinic3_alloc_txrxqs(struct hinic3_nic_dev *nic_dev)
@@ -396,15 +425,18 @@ static void hinic3_free_txrxqs(struct hinic3_nic_dev *nic_dev)
static void hinic3_tx_rx_ops_init(struct hinic3_nic_dev *nic_dev)
{
if (HINIC3_SUPPORT_TX_COMPACT_WQE_OL(nic_dev->hwdev)) {
- nic_dev->tx_rx_ops.tx_set_wqebb_cnt = hinic3_tx_set_compact_offload_wqebb_cnt;
- nic_dev->tx_rx_ops.tx_set_wqe_task = hinic3_tx_set_compact_offload_wqe_task;
+ nic_dev->tx_rx_ops.tx_set_wqebb_cnt =
+ hinic3_tx_set_compact_offload_wqebb_cnt;
+ nic_dev->tx_rx_ops.tx_set_wqe_task =
+ hinic3_tx_set_compact_offload_wqe_task;
} else {
nic_dev->tx_rx_ops.tx_set_wqebb_cnt = hinic3_tx_set_wqebb_cnt;
nic_dev->tx_rx_ops.tx_set_wqe_task = hinic3_tx_set_wqe_task;
}
if (HINIC3_SUPPORT_RX_COMPACT_CQE(nic_dev->hwdev))
- nic_dev->tx_rx_ops.rx_get_cqe_info = hinic3_rx_get_compact_cqe_info;
+ nic_dev->tx_rx_ops.rx_get_cqe_info =
+ hinic3_rx_get_compact_cqe_info;
else
nic_dev->tx_rx_ops.rx_get_cqe_info = hinic3_rx_get_cqe_info;
}
@@ -420,53 +452,47 @@ static void hinic3_sw_deinit(struct hinic3_nic_dev *nic_dev)
HINIC3_CHANNEL_NIC);
hinic3_clear_rss_config(nic_dev);
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+
+ hinic3_dcb_deinit(nic_dev);
}
-static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
+static void hinic3_netdev_mtu_init(struct net_device *netdev)
+{
+ /* MTU range: 384 - 9600 */
+#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
+ netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+
+#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
+ netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+}
+
+static int hinic3_set_default_mac(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
u8 mac_addr[ETH_ALEN];
- u64 nic_features;
int err = 0;
- nic_features = hinic3_get_feature_cap(nic_dev->hwdev);
- /* You can update the features supported by the driver according to the
- * scenario here
- */
- nic_features &= NIC_DRV_DEFAULT_FEATURE;
- hinic3_update_nic_feature(nic_dev->hwdev, nic_features);
-
- sema_init(&nic_dev->port_state_sem, 1);
-
- err = hinic3_dcb_init(nic_dev);
- if (err) {
- nic_err(&nic_dev->pdev->dev, "Failed to init dcb\n");
- return -EFAULT;
- }
-
- nic_dev->q_params.sq_depth = HINIC3_SQ_DEPTH;
- nic_dev->q_params.rq_depth = HINIC3_RQ_DEPTH;
-
- hinic3_try_to_enable_rss(nic_dev);
-
err = hinic3_get_default_mac(nic_dev->hwdev, mac_addr);
if (err) {
nic_err(&nic_dev->pdev->dev, "Failed to get MAC address\n");
- goto get_mac_err;
+ return err;
}
+
eth_hw_addr_set(netdev, mac_addr);
if (!is_valid_ether_addr(netdev->dev_addr)) {
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
nic_err(&nic_dev->pdev->dev, "Invalid MAC address %pM\n",
- netdev->dev_addr);
- err = -EIO;
- goto err_mac;
- }
+ netdev->dev_addr);
+ return -EIO;
+ }
- nic_info(&nic_dev->pdev->dev, "Invalid MAC address %pM, using random\n",
+ nic_info(&nic_dev->pdev->dev,
+ "Invalid MAC address %pM, using random\n",
netdev->dev_addr);
eth_hw_addr_random(netdev);
}
@@ -478,21 +504,62 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
* MAC, and we can't consider this condition is error status during
* driver probe procedure.
*/
- if (err && err != HINIC3_PF_SET_VF_ALREADY) {
+ if (err && err != HINIC3_PF_SET_VF_ALREADY)
nic_err(&nic_dev->pdev->dev, "Failed to set default MAC\n");
- goto set_mac_err;
+
+ if (err == HINIC3_PF_SET_VF_ALREADY)
+ return 0;
+
+ return err;
+}
+
+static void hinic3_outband_cfg_init(struct hinic3_nic_dev *nic_dev)
+{
+ u16 outband_default_vid = 0;
+ int err = 0;
+
+ if (!nic_dev->nic_cap.outband_vlan_cfg_en)
+ return;
+
+ err = hinic3_get_outband_vlan_cfg(nic_dev->hwdev, &outband_default_vid);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev,
+ "Failed to get_outband_cfg, err: %d\n", err);
+ return;
}
- /* MTU range: 384 - 9600 */
-#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
- netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
+ nic_dev->outband_cfg.outband_default_vid = outband_default_vid;
+}
-#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
- netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
+static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
+{
+ struct net_device *netdev = nic_dev->netdev;
+ u64 nic_features;
+ int err = 0;
+
+ nic_features = hinic3_get_feature_cap(nic_dev->hwdev);
+ /* You can update the features supported by the driver according to the
+ * scenario here
+ */
+ nic_features &= NIC_DRV_DEFAULT_FEATURE;
+ hinic3_update_nic_feature(nic_dev->hwdev, nic_features);
+
+ err = hinic3_dcb_init(nic_dev);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev, "Failed to init dcb\n");
+ return -EFAULT;
+ }
+
+ nic_dev->q_params.sq_depth = HINIC3_SQ_DEPTH;
+ nic_dev->q_params.rq_depth = HINIC3_RQ_DEPTH;
+
+ hinic3_try_to_enable_rss(nic_dev);
+
+ err = hinic3_set_default_mac(nic_dev);
+ if (err)
+ goto set_mac_err;
+
+ hinic3_netdev_mtu_init(netdev);
err = hinic3_alloc_txrxqs(nic_dev);
if (err) {
@@ -500,6 +567,8 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
goto alloc_qps_err;
}
+ hinic3_outband_cfg_init(nic_dev);
+
hinic3_tx_rx_ops_init(nic_dev);
return 0;
@@ -510,8 +579,6 @@ alloc_qps_err:
HINIC3_CHANNEL_NIC);
set_mac_err:
-err_mac:
-get_mac_err:
hinic3_clear_rss_config(nic_dev);
return err;
@@ -623,7 +690,8 @@ static void calc_coal_para(struct hinic3_nic_dev *nic_dev,
*pending_limt =
(u8)((rx_rate - q_coal->pkt_rate_low) *
- (q_coal->rx_pending_limt_high - q_coal->rx_pending_limt_low) /
+ (q_coal->rx_pending_limt_high -
+ q_coal->rx_pending_limt_low) /
(q_coal->pkt_rate_high - q_coal->pkt_rate_low) +
q_coal->rx_pending_limt_low);
}
@@ -637,8 +705,10 @@ static void update_queue_coal(struct hinic3_nic_dev *nic_dev, u16 qid,
q_coal = &nic_dev->intr_coalesce[qid];
- if (rx_rate > HINIC3_RX_RATE_THRESH && avg_pkt_size > HINIC3_AVG_PKT_SMALL) {
- calc_coal_para(nic_dev, q_coal, rx_rate, &coalesc_timer_cfg, &pending_limt);
+ if (rx_rate > HINIC3_RX_RATE_THRESH &&
+ avg_pkt_size > HINIC3_AVG_PKT_SMALL) {
+ calc_coal_para(nic_dev, q_coal, rx_rate,
+ &coalesc_timer_cfg, &pending_limt);
} else {
coalesc_timer_cfg = HINIC3_LOWEST_LATENCY;
pending_limt = q_coal->rx_pending_limt_low;
@@ -701,20 +771,55 @@ void hinic3_auto_moderation_work(struct work_struct *work)
static void hinic3_periodic_work_handler(struct work_struct *work)
{
struct delayed_work *delay = to_delayed_work(work);
- struct hinic3_nic_dev *nic_dev = container_of(delay, struct hinic3_nic_dev, periodic_work);
+ struct hinic3_nic_dev *nic_dev =
+ container_of(delay, struct hinic3_nic_dev, periodic_work);
if (test_and_clear_bit(EVENT_WORK_TX_TIMEOUT, &nic_dev->event_flag))
- hinic3_fault_event_report(nic_dev->hwdev, HINIC3_FAULT_SRC_TX_TIMEOUT,
+ hinic3_fault_event_report(nic_dev->hwdev,
+ HINIC3_FAULT_SRC_TX_TIMEOUT,
FAULT_LEVEL_SERIOUS_FLR);
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
}
+static void hinic3_vport_stats_work_handler(struct work_struct *work)
+{
+ int err;
+ struct hinic3_vport_stats vport_stats = {0};
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_nic_dev *nic_dev = container_of(delay,
+ struct hinic3_nic_dev,
+ vport_stats_work);
+ err = hinic3_get_vport_stats(nic_dev->hwdev,
+ hinic3_global_func_id(nic_dev->hwdev),
+ &vport_stats);
+ if (err)
+ nic_err(&nic_dev->pdev->dev, "Failed to get dropped stats from fw\n");
+ else
+ nic_dev->vport_stats.rx_discard_vport =
+ vport_stats.rx_discard_vport;
+ queue_delayed_work(nic_dev->workq, &nic_dev->vport_stats_work, HZ);
+}
+
+static void free_nic_dev_vram(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram = get_use_vram_flag();
+
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)nic_dev->nic_vram, nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ else
+ kfree(nic_dev->nic_vram);
+ nic_dev->nic_vram = NULL;
+}
+
static void free_nic_dev(struct hinic3_nic_dev *nic_dev)
{
hinic3_deinit_nic_prof_adapter(nic_dev);
destroy_workqueue(nic_dev->workq);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+ free_nic_dev_vram(nic_dev);
}
static int setup_nic_dev(struct net_device *netdev,
@@ -724,6 +829,10 @@ static int setup_nic_dev(struct net_device *netdev,
struct hinic3_nic_dev *nic_dev;
char *netdev_name_fmt;
u32 page_num;
+ u16 func_id;
+ int ret;
+ int is_in_kexec = vram_get_kexec_flag();
+ int is_use_vram = get_use_vram_flag();
nic_dev = (struct hinic3_nic_dev *)netdev_priv(netdev);
nic_dev->netdev = netdev;
@@ -738,22 +847,60 @@ static int setup_nic_dev(struct net_device *netdev,
nic_dev->dma_rx_buff_size = RX_BUFF_NUM_PER_PAGE * nic_dev->rx_buff_len;
page_num = nic_dev->dma_rx_buff_size / PAGE_SIZE;
nic_dev->page_order = page_num > 0 ? ilog2(page_num) : 0;
+ nic_dev->page_pool_enabled = page_pool_enabled;
+ nic_dev->outband_cfg.outband_default_vid = 0;
+
+ // value other than 0 indicates hot replace
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(nic_dev->nic_vram_name, VRAM_NAME_MAX_LEN,
+ "%s%hu", VRAM_NIC_VRAM, func_id);
+
+ nic_dev->nic_vram = (struct hinic3_vram *)hi_vram_kalloc(
+ nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+
+ if (is_in_kexec == 0)
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ else
+ netdev->mtu = nic_dev->nic_vram->vram_mtu;
+ } else {
+ nic_dev->nic_vram = kzalloc(sizeof(struct hinic3_vram),
+ GFP_KERNEL);
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ }
mutex_init(&nic_dev->nic_mutex);
nic_dev->vlan_bitmap = kzalloc(VLAN_BITMAP_SIZE(nic_dev), GFP_KERNEL);
- if (!nic_dev->vlan_bitmap)
- return -ENOMEM;
+ if (!nic_dev->vlan_bitmap) {
+ nic_err(&pdev->dev, "Failed to allocate vlan bitmap\n");
+ ret = -ENOMEM;
+ goto vlan_bitmap_error;
+ }
nic_dev->workq = create_singlethread_workqueue(HINIC3_NIC_DEV_WQ_NAME);
if (!nic_dev->workq) {
nic_err(&pdev->dev, "Failed to initialize nic workqueue\n");
- kfree(nic_dev->vlan_bitmap);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto create_workq_error;
}
- INIT_DELAYED_WORK(&nic_dev->periodic_work, hinic3_periodic_work_handler);
- INIT_DELAYED_WORK(&nic_dev->rxq_check_work, hinic3_rxq_check_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->periodic_work,
+ hinic3_periodic_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->rxq_check_work,
+ hinic3_rxq_check_work_handler);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ INIT_DELAYED_WORK(&nic_dev->vport_stats_work,
+ hinic3_vport_stats_work_handler);
INIT_LIST_HEAD(&nic_dev->uc_filter_list);
INIT_LIST_HEAD(&nic_dev->mc_filter_list);
@@ -766,10 +913,23 @@ static int setup_nic_dev(struct net_device *netdev,
hinic3_init_nic_prof_adapter(nic_dev);
netdev_name_fmt = hinic3_get_dft_netdev_name_fmt(nic_dev);
- if (netdev_name_fmt)
- strscpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (netdev_name_fmt) {
+ ret = strscpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (ret < 0)
+ goto get_netdev_name_error;
+ }
return 0;
+
+get_netdev_name_error:
+ hinic3_deinit_nic_prof_adapter(nic_dev);
+ destroy_workqueue(nic_dev->workq);
+create_workq_error:
+ kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+vlan_bitmap_error:
+ free_nic_dev_vram(nic_dev);
+ return ret;
}
static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
@@ -808,6 +968,31 @@ static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
return 0;
}
+static void hinic3_bond_init(struct hinic3_nic_dev *nic_dev)
+{
+ u32 bond_id = HINIC3_INVALID_BOND_ID;
+ int err = hinic3_create_bond(nic_dev->hwdev, &bond_id);
+
+ if (err != 0)
+ goto bond_init_failed;
+
+ /* bond id does not change, means this pf is not bond active pf, no log is generated */
+ if (bond_id == HINIC3_INVALID_BOND_ID)
+ return;
+
+ err = hinic3_open_close_bond(nic_dev->hwdev, true);
+ if (err != 0) {
+ hinic3_delete_bond(nic_dev->hwdev);
+ goto bond_init_failed;
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Bond %d init success\n", bond_id);
+ return;
+
+bond_init_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond init failed\n");
+}
+
static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
char *uld_dev_name)
{
@@ -838,6 +1023,12 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
goto err_out;
}
+ err = hinic3_get_dev_cap(lld_dev->hwdev);
+ if (err != 0) {
+ nic_err(&pdev->dev, "Failed to get dev cap\n");
+ goto err_out;
+ }
+
max_qps = hinic3_func_max_nic_qnum(lld_dev->hwdev);
netdev = alloc_etherdev_mq(sizeof(*nic_dev), max_qps);
if (!netdev) {
@@ -870,10 +1061,17 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
hinic3_assign_netdev_ops(nic_dev);
netdev_feature_init(netdev);
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+ netdev->udp_tunnel_nic_info = &hinic3_udp_tunnels;
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
err = hinic3_set_default_hw_feature(nic_dev);
if (err)
goto set_features_err;
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0)
+ hinic3_bond_init(nic_dev);
+
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
hinic3_register_notifier(nic_dev);
#endif
@@ -888,6 +1086,9 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
}
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->vport_stats_work, HZ);
netif_carrier_off(netdev);
*uld_dev = nic_dev;
@@ -920,6 +1121,25 @@ err_out:
return err;
}
+static void hinic3_bond_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ int ret = 0;
+
+ ret = hinic3_open_close_bond(nic_dev->hwdev, false);
+ if (ret != 0)
+ goto bond_deinit_failed;
+
+ ret = hinic3_delete_bond(nic_dev->hwdev);
+ if (ret != 0)
+ goto bond_deinit_failed;
+
+ nic_info(&nic_dev->pdev->dev, "Bond deinit success\n");
+ return;
+
+bond_deinit_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond deinit failed\n");
+}
+
static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
{
struct hinic3_nic_dev *nic_dev = adapter;
@@ -939,6 +1159,8 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_unregister_notifier(nic_dev);
#endif
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ cancel_delayed_work_sync(&nic_dev->vport_stats_work);
cancel_delayed_work_sync(&nic_dev->periodic_work);
cancel_delayed_work_sync(&nic_dev->rxq_check_work);
cancel_work_sync(&nic_dev->rx_mode_work);
@@ -946,6 +1168,9 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_flush_rx_flow_rule(nic_dev);
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0)
+ hinic3_bond_deinit(nic_dev);
+
hinic3_update_nic_feature(nic_dev->hwdev, 0);
hinic3_set_nic_feature_to_hw(nic_dev->hwdev);
@@ -955,6 +1180,7 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_deinit_nic_prof_adapter(nic_dev);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
free_netdev(netdev);
@@ -971,8 +1197,10 @@ static void sriov_state_change(struct hinic3_nic_dev *nic_dev,
static void hinic3_port_module_event_handler(struct hinic3_nic_dev *nic_dev,
struct hinic3_event_info *event)
{
- const char *g_hinic3_module_link_err[LINK_ERR_NUM] = { "Unrecognized module" };
- struct hinic3_port_module_event *module_event = (void *)event->event_data;
+ const char *g_hinic3_module_link_err[LINK_ERR_NUM] = {
+ "Unrecognized module" };
+ struct hinic3_port_module_event *module_event =
+ (void *)event->event_data;
enum port_module_event_type type = module_event->type;
enum link_err_type err_type = module_event->err_type;
@@ -1003,6 +1231,116 @@ static void hinic3_port_module_event_handler(struct hinic3_nic_dev *nic_dev,
}
}
+bool hinic3_need_proc_link_event(struct hinic3_lld_dev *lld_dev)
+{
+ int ret = 0;
+ u16 func_id;
+ u8 roce_enable = false;
+ bool is_slave_func = false;
+ struct hinic3_hw_bond_infos hw_bond_infos = {0};
+
+ if (!lld_dev)
+ return false;
+
+ /* 非slave设备需要处理link down事件 */
+ ret = hinic3_is_slave_func(lld_dev->hwdev, &is_slave_func);
+ if (ret != 0) {
+ nic_err(&lld_dev->pdev->dev, "NIC get info, lld_dev is null\n");
+ return true;
+ }
+
+ if (!is_slave_func)
+ return true;
+
+ /* 未使能了vroce功能,需处理link down事件 */
+ func_id = hinic3_global_func_id(lld_dev->hwdev);
+ ret = hinic3_get_func_vroce_enable(lld_dev->hwdev, func_id, &roce_enable);
+ if (ret != 0)
+ return true;
+
+ if (!roce_enable)
+ return true;
+
+ /* 未创建bond,需要处理link down事件 */
+ hw_bond_infos.bond_id = HINIC_OVS_BOND_DEFAULT_ID;
+
+ ret = hinic3_get_hw_bond_infos(lld_dev->hwdev, &hw_bond_infos, HINIC3_CHANNEL_COMM);
+ if (ret != 0) {
+ pr_err("[ROCE, ERR] Get chipf bond info failed (%d)\n", ret);
+ return true;
+ }
+
+ if (!hw_bond_infos.valid)
+ return true;
+
+ return false;
+}
+
+bool hinic3_need_proc_bond_event(struct hinic3_lld_dev *lld_dev)
+{
+ return !hinic3_need_proc_link_event(lld_dev);
+}
+
+static void hinic_porc_bond_state_change(struct hinic3_lld_dev *lld_dev, void *adapter,
+ struct hinic3_event_info *event)
+{
+ struct hinic3_nic_dev *nic_dev = adapter;
+
+ if (!nic_dev || !event || !hinic3_support_nic(lld_dev->hwdev, NULL))
+ return;
+
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond down\n");
+ hinic3_link_status_change(nic_dev, false);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond up\n");
+ hinic3_link_status_change(nic_dev, true);
+ break;
+ default:
+ break;
+ }
+}
+
+static void hinic3_outband_cfg_event_handler(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_outband_cfg_info *info)
+{
+ int err = 0;
+
+ if (!nic_dev || !info || !hinic3_support_nic(nic_dev->hwdev, NULL)) {
+ pr_err("Outband cfg event invalid param\n");
+ return;
+ }
+
+ if (hinic3_func_type(nic_dev->hwdev) != TYPE_VF &&
+ info->func_id >= NIC_MAX_PF_NUM) {
+ err = hinic3_notify_vf_outband_cfg(nic_dev->hwdev,
+ info->func_id,
+ info->outband_default_vid);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev,
+ "Outband cfg event notify vf err: %d, func_id: 0x%x, vid: 0x%x\n",
+ err, info->func_id, info->outband_default_vid);
+ return;
+ }
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Change outband default vid from %u to %u\n",
+ nic_dev->outband_cfg.outband_default_vid,
+ info->outband_default_vid);
+
+ nic_dev->outband_cfg.outband_default_vid = info->outband_default_vid;
+}
+
static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
struct hinic3_event_info *event)
{
@@ -1014,21 +1352,35 @@ static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_DOWN):
+ if (!hinic3_need_proc_link_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc link event\n");
+ return;
+ }
hinic3_link_status_change(nic_dev, false);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_UP):
hinic3_link_status_change(nic_dev, true);
break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ hinic_porc_bond_state_change(lld_dev, adapter, event);
+ break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_PORT_MODULE_EVENT):
hinic3_port_module_event_handler(nic_dev, event);
break;
- case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_SRIOV_STATE_CHANGE):
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_OUTBAND_CFG):
+ hinic3_outband_cfg_event_handler(nic_dev,
+ (void *)event->event_data);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM,
+ EVENT_COMM_SRIOV_STATE_CHANGE):
sriov_state_change(nic_dev, (void *)event->event_data);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_FAULT):
fault = (void *)event->event_data;
if (fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
- fault->event.chip.func_id == hinic3_global_func_id(lld_dev->hwdev))
+ fault->event.chip.func_id ==
+ hinic3_global_func_id(lld_dev->hwdev))
hinic3_link_status_change(nic_dev, false);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_PCIE_LINK_DOWN):
@@ -1081,7 +1433,7 @@ struct hinic3_uld_info g_nic_uld_info = {
.resume = NULL,
.event = nic_event,
.ioctl = nic_ioctl,
-}; /*lint -e766*/
+};
struct hinic3_uld_info *get_nic_uld_info(void)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
index 94e606e..8adc48d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
@@ -9,6 +9,7 @@
/* Interrupt at most records, interrupt will be recorded in the FFM */
#define NICTOOL_CMD_TYPE (0x18)
+#define HINIC3_CARD_NAME_MAX_LEN (128)
struct api_cmd_rd {
u32 pf_id;
@@ -110,7 +111,8 @@ enum dbgtool_cmd {
DBGTOOL_CMD_NUM
};
-#define PF_MAX_SIZE (16)
+#define HINIC_PF_MAX_SIZE (16)
+#define HINIC_VF_MAX_SIZE (4096)
#define BUSINFO_LEN (32)
enum module_name {
@@ -132,7 +134,8 @@ enum module_name {
SEND_TO_MIGRATE_DRIVER,
SEND_TO_PPA_DRIVER,
SEND_TO_CUSTOM_DRIVER = SEND_TO_SRV_DRV_BASE + 11,
- SEND_TO_BIFUR_DRIVER = SEND_TO_SRV_DRV_BASE + 15,
+ SEND_TO_VSOCK_DRIVER = SEND_TO_SRV_DRV_BASE + 14,
+ SEND_TO_BIFUR_DRIVER,
SEND_TO_DRIVER_MAX = SEND_TO_SRV_DRV_BASE + 16, /* reserved */
};
@@ -160,7 +163,7 @@ enum driver_cmd_type {
GET_CHIP_FAULT_STATS,
NIC_RSVD1,
NIC_RSVD2,
- NIC_RSVD3,
+ GET_OS_HOT_REPLACE_INFO,
GET_CHIP_ID,
GET_SINGLE_CARD_INFO,
GET_FIRMWARE_ACTIVE_STATUS,
@@ -171,7 +174,7 @@ enum driver_cmd_type {
GET_LOOPBACK_MODE = 32,
SET_LOOPBACK_MODE,
SET_LINK_MODE,
- SET_PF_BW_LIMIT,
+ SET_TX_PF_BW_LIMIT,
GET_PF_BW_LIMIT,
ROCE_CMD,
GET_POLL_WEIGHT,
@@ -189,6 +192,7 @@ enum driver_cmd_type {
GET_NIC_STATS_STRING,
GET_NIC_STATS_INFO,
GET_PF_ID,
+ GET_MBOX_CNT,
NIC_RSVD4,
NIC_RSVD5,
DCB_QOS_INFO,
@@ -205,6 +209,8 @@ enum driver_cmd_type {
RSS_INDIR,
PORT_ID,
+ SET_RX_PF_BW_LIMIT = 0x43,
+
GET_FUNC_CAP = 0x50,
GET_XSFP_PRESENT = 0x51,
GET_XSFP_INFO = 0x52,
@@ -216,6 +222,10 @@ enum driver_cmd_type {
WIN_CSR_WRITE = 0x62,
WIN_API_CMD_RD = 0x63,
+ GET_FUSION_Q = 0x64,
+
+ ROCE_CMD_BOND_HASH_TYPE_SET = 0xb2,
+
BIFUR_SET_ENABLE = 0xc0,
BIFUR_GET_ENABLE = 0xc1,
@@ -234,7 +244,8 @@ enum sm_cmd_type {
SM_CTR_RD64,
SM_CTR_RD32_CLEAR,
SM_CTR_RD64_PAIR_CLEAR,
- SM_CTR_RD64_CLEAR
+ SM_CTR_RD64_CLEAR,
+ SM_CTR_RD16_CLEAR,
};
struct cqm_stats {
@@ -321,10 +332,22 @@ struct pf_info {
};
struct card_info {
- struct pf_info pf[PF_MAX_SIZE];
+ struct pf_info pf[HINIC_PF_MAX_SIZE];
u32 pf_num;
};
+struct func_mbox_cnt_info {
+ char bus_info[BUSINFO_LEN];
+ u64 send_cnt;
+ u64 ack_cnt;
+};
+
+struct card_mbox_cnt_info {
+ struct func_mbox_cnt_info func_info[HINIC_PF_MAX_SIZE +
+ HINIC_VF_MAX_SIZE];
+ u32 func_num;
+};
+
struct hinic3_nic_loop_mode {
u32 loop_mode;
u32 loop_ctrl;
@@ -665,6 +688,161 @@ struct get_card_bond_msg_s {
struct bond_all_msg_s all_msg[MAX_BONDING_CNT_PER_CARD];
};
+#define MAX_FUSION_Q_STATS_STR_LEN 16
+#define MAX_FUSION_Q_NUM 256
+struct queue_status_s {
+ pid_t tgid;
+ char status[MAX_FUSION_Q_STATS_STR_LEN];
+};
+struct fusion_q_status_s {
+ u16 queue_num;
+ struct queue_status_s queue[MAX_FUSION_Q_NUM];
+};
+
+struct fusion_q_tx_hw_page {
+ u64 phy_addr;
+ u64 *map_addr;
+};
+
+struct fusion_sq_info {
+ u16 q_id;
+ u16 pi;
+ u16 ci; /* sw_ci */
+ u16 fi; /* hw_ci */
+ u32 q_depth;
+ u16 pi_reverse;
+ u16 wqebb_size;
+ u8 priority;
+ u16 *ci_addr;
+ u64 cla_addr;
+ void *slq_handle;
+ struct fusion_q_tx_hw_page direct_wqe;
+ struct fusion_q_tx_hw_page doorbell;
+ u32 page_idx;
+ u32 glb_sq_id;
+};
+
+struct fusion_q_tx_wqe {
+ u32 data[4];
+};
+
+struct fusion_rq_info {
+ u16 q_id;
+ u16 delta;
+ u16 hw_pi;
+ u16 ci; /* sw_ci */
+ u16 sw_pi;
+ u16 wqebb_size;
+ u16 q_depth;
+ u16 buf_len;
+
+ void *slq_handle;
+ u64 ci_wqe_page_addr;
+ u64 ci_cla_tbl_addr;
+
+ u8 coalesc_timer_cfg;
+ u8 pending_limt;
+ u16 msix_idx;
+ u32 msix_vector;
+};
+
+struct fusion_q_rx_wqe {
+ u32 data[8];
+};
+
+struct fusion_q_rx_cqe {
+ union {
+ struct {
+ unsigned int checksum_err : 16;
+ unsigned int lro_num : 8;
+ unsigned int rsvd1 : 7;
+ unsigned int rx_done : 1;
+ } bs;
+ unsigned int value;
+ } dw0;
+
+ union {
+ struct {
+ unsigned int vlan : 16;
+ unsigned int length : 16;
+ } bs;
+ unsigned int value;
+ } dw1;
+
+ union {
+ struct {
+ unsigned int pkt_types : 12;
+ unsigned int rsvd : 4;
+ unsigned int udp_0 : 1;
+ unsigned int ipv6_ex_add : 1;
+ unsigned int loopback : 1;
+ unsigned int umbcast : 2;
+ unsigned int vlan_offload_en : 1;
+ unsigned int tag_num : 2;
+ unsigned int rss_type : 8;
+ } bs;
+ unsigned int value;
+ } dw2;
+
+ union {
+ struct {
+ unsigned int rss_hash_value;
+ } bs;
+ unsigned int value;
+ } dw3;
+
+ union {
+ struct {
+ unsigned int tx_ts_seq : 16;
+ unsigned int message_1588_offset : 8;
+ unsigned int message_1588_type : 4;
+ unsigned int rsvd : 1;
+ unsigned int if_rx_ts : 1;
+ unsigned int if_tx_ts : 1;
+ unsigned int if_1588 : 1;
+ } bs;
+ unsigned int value;
+ } dw4;
+
+ union {
+ struct {
+ unsigned int ts;
+ } bs;
+ unsigned int value;
+ } dw5;
+
+ union {
+ struct {
+ unsigned int lro_ts;
+ } bs;
+ unsigned int value;
+ } dw6;
+
+ union {
+ struct {
+ unsigned int rsvd0;
+ } bs;
+ unsigned int value;
+ } dw7; /* 16Bytes Align */
+};
+
+struct os_hot_repalce_func_info {
+ char card_name[HINIC3_CARD_NAME_MAX_LEN];
+ u32 bus_num;
+ u32 valid;
+ u32 bdf;
+ int partition;
+ u16 backup_pf;
+ u16 pf_idx;
+ int port_id;
+};
+
+#define ALL_CARD_PF_NUM 2048 /* 64 card * 32 pf */
+struct os_hot_replace_info {
+ struct os_hot_repalce_func_info func_infos[ALL_CARD_PF_NUM];
+ u32 func_cnt;
+};
+
int alloc_buff_in(void *hwdev, struct msg_module *nt_msg, u32 in_size, void **buf_in);
int alloc_buff_out(void *hwdev, struct msg_module *nt_msg, u32 out_size, void **buf_out);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
index ea1d506..66c41f8 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
@@ -15,6 +15,9 @@
#include <linux/ip.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#ifdef HAVE_XDP_SUPPORT
#include <linux/bpf.h>
#endif
@@ -28,6 +31,10 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
+#include "nic_npu_cmd.h"
+
+#include "vram_common.h"
+
#define HINIC3_DEFAULT_RX_CSUM_OFFLOAD 0xFFF
#define HINIC3_LRO_DEFAULT_COAL_PKT_SIZE 32
@@ -47,8 +54,63 @@ static void hinic3_nic_set_rx_mode(struct net_device *netdev)
queue_work(nic_dev->workq, &nic_dev->rx_mode_work);
}
+static void hinic3_free_irq_vram(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_dyna_txrxq_params *in_q_params)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ struct hinic3_dyna_txrxq_params q_params = nic_dev->q_params;
+
+ if (q_params.irq_cfg == NULL)
+ return;
+
+ size = sizeof(struct hinic3_irq) * (q_params.num_qps);
+
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)q_params.irq_cfg, q_params.irq_cfg_vram_name, size);
+ q_params.irq_cfg = NULL;
+ } else {
+ kfree(in_q_params->irq_cfg);
+ in_q_params->irq_cfg = NULL;
+ }
+}
+
+static int hinic3_alloc_irq_vram(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_dyna_txrxq_params *q_params, bool is_up_eth)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ u16 func_id;
+
+ size = sizeof(struct hinic3_irq) * q_params->num_qps;
+
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(q_params->irq_cfg_vram_name, VRAM_NAME_MAX_LEN,
+ "%s%hu", VRAM_NIC_IRQ_VRAM, func_id);
+ q_params->irq_cfg = (struct hinic3_irq *)hi_vram_kalloc(
+ q_params->irq_cfg_vram_name, size);
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq vram alloc failed.\n");
+ return -ENOMEM;
+ }
+ /* in order to clear napi stored in vram, irq need to init when eth up */
+ if (is_up_eth)
+ memset(q_params->irq_cfg, 0, size);
+ } else {
+ q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq alloc failed.\n");
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_txrxq_params *q_params)
+ struct hinic3_dyna_txrxq_params *q_params,
+ bool is_up_eth)
{
u32 size;
int err;
@@ -70,12 +132,9 @@ static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
goto alloc_rxqs_res_arr_err;
}
- size = sizeof(*q_params->irq_cfg) * q_params->num_qps;
- q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
- if (!q_params->irq_cfg) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to alloc irq resource array\n");
- err = -ENOMEM;
+ err = hinic3_alloc_irq_vram(nic_dev, q_params, is_up_eth);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc irq resource array\n");
goto alloc_irq_cfg_err;
}
@@ -102,8 +161,7 @@ alloc_rxqs_res_err:
q_params->txqs_res);
alloc_txqs_res_err:
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ hinic3_free_irq_vram(nic_dev, q_params);
alloc_irq_cfg_err:
kfree(q_params->rxqs_res);
@@ -117,15 +175,17 @@ alloc_rxqs_res_arr_err:
}
static void hinic3_free_txrxq_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_txrxq_params *q_params)
+ struct hinic3_dyna_txrxq_params *q_params)
{
+ int is_in_kexec = vram_get_kexec_flag();
+
hinic3_free_rxqs_res(nic_dev, q_params->num_qps, q_params->rq_depth,
q_params->rxqs_res);
hinic3_free_txqs_res(nic_dev, q_params->num_qps, q_params->sq_depth,
q_params->txqs_res);
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ if (is_in_kexec == 0)
+ hinic3_free_irq_vram(nic_dev, q_params);
kfree(q_params->rxqs_res);
q_params->rxqs_res = NULL;
@@ -161,6 +221,7 @@ static int hinic3_configure_txrxqs(struct hinic3_nic_dev *nic_dev,
static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos;
if (!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
@@ -171,12 +232,13 @@ static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
num_cos = hinic3_get_dev_user_cos_num(nic_dev);
hinic3_update_qp_cos_cfg(nic_dev, num_cos);
/* For now, we don't support to change num_cos */
- if (num_cos > nic_dev->cos_config_num_max ||
+ if (num_cos > dcb->cos_config_num_max ||
nic_dev->q_params.num_qps < num_cos) {
nicif_err(nic_dev, drv, netdev, "Invalid num_cos: %u or num_qps: %u, disable DCB\n",
num_cos, nic_dev->q_params.num_qps);
nic_dev->q_params.num_cos = 0;
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
/* if we can't enable rss or get enough num_qps,
* need to sync default configure to hw
*/
@@ -190,17 +252,22 @@ static int hinic3_configure(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
- err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
- if (err) {
- nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
- return err;
+ if (is_in_kexec == 0) {
+ err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
+ return err;
+ }
}
config_dcb_qps_map(nic_dev);
/* rx rss init */
- err = hinic3_rx_configure(netdev, test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ err = hinic3_rx_configure(netdev,
+ test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)
+ ? 1 : 0);
if (err) {
nicif_err(nic_dev, drv, netdev, "Failed to configure rx\n");
return err;
@@ -256,10 +323,11 @@ static void config_dcb_num_qps(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dyna_txrxq_params *q_params,
u16 max_qps)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos = q_params->num_cos;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (!num_cos || num_cos > nic_dev->cos_config_num_max || num_cos > max_qps)
+ if (!num_cos || num_cos > dcb->cos_config_num_max || num_cos > max_qps)
return; /* will disable DCB in config_dcb_qps_map() */
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
@@ -313,8 +381,10 @@ static int hinic3_setup_num_qps(struct hinic3_nic_dev *nic_dev)
return -EINVAL;
}
nic_dev->qps_irq_info = kzalloc(irq_size, GFP_KERNEL);
- if (!nic_dev->qps_irq_info)
+ if (!nic_dev->qps_irq_info) {
+ nicif_err(nic_dev, drv, netdev, "Failed to alloc qps_irq_info\n");
return -ENOMEM;
+ }
hinic3_config_num_qps(nic_dev, &nic_dev->q_params);
@@ -332,57 +402,10 @@ static void hinic3_destroy_num_qps(struct hinic3_nic_dev *nic_dev)
kfree(nic_dev->qps_irq_info);
}
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev)
-{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- err = hinic3_set_port_enable(nic_dev->hwdev, false, HINIC3_CHANNEL_NIC);
- if (!err)
- nic_dev->force_port_disable = true;
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
-{
- int err = 0;
-
- down(&nic_dev->port_state_sem);
-
- nic_dev->force_port_disable = false;
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
- HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- /* Do nothing when force disable
- * Port will disable when call force port disable
- * and should not enable port when in force mode
- */
- if (nic_dev->force_port_disable) {
- up(&nic_dev->port_state_sem);
- return 0;
- }
-
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
- HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
+ return hinic3_set_port_enable(nic_dev->hwdev, enable,
+ HINIC3_CHANNEL_NIC);
}
static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
@@ -398,8 +421,8 @@ static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
}
static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+ struct hinic3_dyna_qp_params *qp_params,
+ struct hinic3_dyna_txrxq_params *trxq_params, bool is_up_eth)
{
int err;
@@ -414,7 +437,7 @@ static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
return err;
}
- err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params);
+ err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params, is_up_eth);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc txrxq resources\n");
hinic3_free_qps(nic_dev->hwdev, qp_params);
@@ -425,8 +448,8 @@ static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
}
static void hinic3_free_channel_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+ struct hinic3_dyna_qp_params *qp_params,
+ struct hinic3_dyna_txrxq_params *trxq_params)
{
mutex_lock(&nic_dev->nic_mutex);
hinic3_free_txrxq_resources(nic_dev, trxq_params);
@@ -521,7 +544,8 @@ int hinic3_vport_up(struct hinic3_nic_dev *nic_dev)
queue_delayed_work(nic_dev->workq, &nic_dev->moderation_task,
HINIC3_MODERATONE_DELAY);
if (test_bit(HINIC3_RXQ_RECOVERY, &nic_dev->flags))
- queue_delayed_work(nic_dev->workq, &nic_dev->rxq_check_work, HZ);
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->rxq_check_work, HZ);
hinic3_print_link_message(nic_dev, link_status);
@@ -542,9 +566,52 @@ vport_enable_err:
return err;
}
+static int hinic3_flush_rq_and_check(struct hinic3_nic_dev *nic_dev, u16 glb_func_id)
+{
+ struct hinic3_flush_rq *rq_flush_msg = NULL;
+ struct hinic3_cmd_buf *cmd_buf = NULL;
+ int out_buf_len = sizeof(struct hinic3_flush_rq);
+ u16 rq_id;
+ u64 out_param = 0;
+ int ret;
+
+ cmd_buf = hinic3_alloc_cmd_buf(nic_dev->hwdev);
+ if (!cmd_buf) {
+ nic_err(&nic_dev->pdev->dev, "Failed to allocate cmd buf\n");
+ return -ENOMEM;
+ }
+
+ cmd_buf->size = sizeof(struct hinic3_flush_rq);
+ rq_flush_msg = (struct hinic3_flush_rq *)cmd_buf->buf;
+ rq_flush_msg->dw.bs.func_id = glb_func_id;
+ for (rq_id = 0; rq_id < nic_dev->q_params.num_qps; rq_id++) {
+ rq_flush_msg->dw.bs.rq_id = rq_id;
+ hinic3_cpu_to_be32(rq_flush_msg, out_buf_len);
+ ret = hinic3_cmdq_direct_resp(nic_dev->hwdev, HINIC3_MOD_L2NIC,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ cmd_buf, &out_param, 0,
+ HINIC3_CHANNEL_NIC);
+ if (ret != 0 || out_param != 0) {
+ nic_err(&nic_dev->pdev->dev, "Failed to flush rq, ret:%d, func:%u, rq:%u\n",
+ ret, glb_func_id, rq_id);
+ goto err;
+ }
+ hinic3_be32_to_cpu(rq_flush_msg, out_buf_len);
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Func:%u rq_num:%u flush rq success\n",
+ glb_func_id, nic_dev->q_params.num_qps);
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return 0;
+err:
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return -1;
+}
+
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
{
u16 glb_func_id;
+ int is_in_kexec = vram_get_kexec_flag();
netif_carrier_off(nic_dev->netdev);
netif_tx_disable(nic_dev->netdev);
@@ -557,18 +624,21 @@ void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, 0);
- hinic3_maybe_set_port_state(nic_dev, false);
+ if (is_in_kexec != 0)
+ nicif_info(nic_dev, drv, nic_dev->netdev, "Skip changing mag status!\n");
+ else
+ hinic3_maybe_set_port_state(nic_dev, false);
glb_func_id = hinic3_global_func_id(nic_dev->hwdev);
hinic3_set_vport_enable(nic_dev->hwdev, glb_func_id, false,
HINIC3_CHANNEL_NIC);
hinic3_flush_txqs(nic_dev->netdev);
- /* After set vport disable 100ms,
- * no packets will be send to host
- * FPGA set 2000ms
- */
- msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+
+ if (is_in_kexec == 0)
+ msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+ else
+ (void)hinic3_flush_rq_and_check(nic_dev, glb_func_id);
hinic3_flush_qps_res(nic_dev->hwdev);
}
}
@@ -581,11 +651,12 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_qp_params new_qp_params = {0};
struct hinic3_dyna_qp_params cur_qp_params = {0};
int err;
+ bool is_free_resources = false;
hinic3_config_num_qps(nic_dev, trxq_params);
err = hinic3_alloc_channel_resources(nic_dev, &new_qp_params,
- trxq_params);
+ trxq_params, false);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc channel resources\n");
@@ -597,10 +668,19 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
hinic3_close_channel(nic_dev, &cur_qp_params);
hinic3_free_channel_resources(nic_dev, &cur_qp_params,
&nic_dev->q_params);
+ is_free_resources = true;
}
if (nic_dev->num_qp_irq > trxq_params->num_qps)
hinic3_qp_irq_change(nic_dev, trxq_params->num_qps);
+
+ if (is_free_resources) {
+ err = hinic3_alloc_irq_vram(nic_dev, trxq_params, false);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Change chl alloc irq failed\n");
+ goto alloc_irq_err;
+ }
+ }
nic_dev->q_params = *trxq_params;
if (reopen_handler)
@@ -621,7 +701,7 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
vport_up_err:
hinic3_close_channel(nic_dev, &new_qp_params);
-
+alloc_irq_err:
open_channel_err:
hinic3_free_channel_resources(nic_dev, &new_qp_params, trxq_params);
@@ -652,7 +732,7 @@ int hinic3_open(struct net_device *netdev)
}
err = hinic3_alloc_channel_resources(nic_dev, &qp_params,
- &nic_dev->q_params);
+ &nic_dev->q_params, true);
if (err)
goto alloc_channel_res_err;
@@ -691,12 +771,31 @@ setup_qps_err:
return err;
}
+static void hinic3_delete_napi(struct hinic3_nic_dev *nic_dev)
+{
+ u16 q_id;
+ int is_in_kexec = vram_get_kexec_flag();
+ struct hinic3_irq *irq_cfg = NULL;
+
+ if (is_in_kexec == 0 || nic_dev->q_params.irq_cfg == NULL)
+ return;
+
+ for (q_id = 0; q_id < nic_dev->q_params.num_qps; q_id++) {
+ irq_cfg = &(nic_dev->q_params.irq_cfg[q_id]);
+ qp_del_napi(irq_cfg);
+ }
+
+ hinic3_free_irq_vram(nic_dev, &nic_dev->q_params);
+}
+
int hinic3_close(struct net_device *netdev)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic3_dyna_qp_params qp_params = {0};
if (!test_and_clear_bit(HINIC3_INTF_UP, &nic_dev->flags)) {
+ /* delete napi in os hotreplace rollback */
+ hinic3_delete_napi(nic_dev);
nicif_info(nic_dev, drv, netdev, "Netdev already close, do nothing\n");
return 0;
}
@@ -776,7 +875,8 @@ static u8 parse_ipv6_info(struct sk_buff *skb, u32 *rss_tunple,
return 0;
}
-static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb,
+static u16 select_queue_by_hash_func(struct net_device *dev,
+ struct sk_buff *skb,
unsigned int num_tx_queues)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(dev);
@@ -831,17 +931,20 @@ static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb
}
#define GET_DSCP_PRI_OFFSET 2
-static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev, struct sk_buff *skb)
+static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev,
+ struct sk_buff *skb)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int dscp_cp;
if (skb->protocol == htons(ETH_P_IP))
dscp_cp = ipv4_get_dsfield(ip_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
else if (skb->protocol == htons(ETH_P_IPV6))
- dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
+ dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >>
+ GET_DSCP_PRI_OFFSET;
else
- return nic_dev->hw_dcb_cfg.default_cos;
- return nic_dev->hw_dcb_cfg.dscp2cos[dscp_cp];
+ return dcb->hw_dcb_cfg.default_cos;
+ return dcb->hw_dcb_cfg.dscp2cos[dscp_cp];
}
#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY)
@@ -867,11 +970,13 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif /* end of HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK */
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u16 txq;
u8 cos, qp_num;
if (test_bit(HINIC3_SAME_RXTX, &nic_dev->flags))
- return select_queue_by_hash_func(netdev, skb, netdev->real_num_tx_queues);
+ return select_queue_by_hash_func(netdev, skb,
+ netdev->real_num_tx_queues);
txq =
#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY)
@@ -887,18 +992,19 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (nic_dev->hw_dcb_cfg.trust == DCB_PCP) {
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP) {
if (skb->vlan_tci)
- cos = nic_dev->hw_dcb_cfg.pcp2cos[skb->vlan_tci >> VLAN_PRIO_SHIFT];
+ cos = dcb->hw_dcb_cfg.pcp2cos[skb->vlan_tci >>
+ VLAN_PRIO_SHIFT];
else
- cos = nic_dev->hw_dcb_cfg.default_cos;
+ cos = dcb->hw_dcb_cfg.default_cos;
} else {
cos = hinic3_get_dscp_up(nic_dev, skb);
}
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cos] ?
- txq % nic_dev->hw_dcb_cfg.cos_qp_num[cos] : 0;
- txq = nic_dev->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
+ qp_num = dcb->hw_dcb_cfg.cos_qp_num[cos] ?
+ txq % dcb->hw_dcb_cfg.cos_qp_num[cos] : 0;
+ txq = dcb->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
}
return txq;
@@ -976,7 +1082,7 @@ static struct net_device_stats *hinic3_get_stats(struct net_device *netdev)
stats->rx_packets = packets;
stats->rx_bytes = bytes;
stats->rx_errors = errors;
- stats->rx_dropped = dropped;
+ stats->rx_dropped = dropped + nic_dev->vport_stats.rx_discard_vport;
#ifndef HAVE_VOID_NDO_GET_STATS64
return stats;
@@ -1023,10 +1129,18 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
u32 mtu = (u32)new_mtu;
int err = 0;
+ int is_in_kexec = vram_get_kexec_flag();
#ifdef HAVE_XDP_SUPPORT
u32 xdp_max_mtu;
+#endif
+ if (is_in_kexec != 0) {
+ nicif_info(nic_dev, drv, netdev, "Hotreplace skip change mtu\n");
+ return err;
+ }
+
+#ifdef HAVE_XDP_SUPPORT
if (hinic3_is_xdp_enable(nic_dev)) {
xdp_max_mtu = hinic3_xdp_max_mtu(nic_dev);
if (mtu > xdp_max_mtu) {
@@ -1045,6 +1159,7 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
nicif_info(nic_dev, drv, nic_dev->netdev, "Change mtu from %u to %d\n",
netdev->mtu, new_mtu);
netdev->mtu = mtu;
+ nic_dev->nic_vram->vram_mtu = mtu;
}
return err;
@@ -1078,6 +1193,76 @@ static int hinic3_set_mac_addr(struct net_device *netdev, void *addr)
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+static int hinic3_udp_tunnel_port_config(struct net_device *netdev,
+ struct udp_tunnel_info *ti,
+ u8 action)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u16 func_id = hinic3_global_func_id(nic_dev->hwdev);
+ u16 dst_port;
+ int ret = 0;
+
+ switch (ti->type) {
+ case UDP_TUNNEL_TYPE_VXLAN:
+ dst_port = ntohs(ti->port);
+ ret = hinic3_vlxan_port_config(nic_dev->hwdev,
+ func_id, dst_port, action);
+ if (ret != 0) {
+ nicif_warn(nic_dev, drv, netdev,
+ "Failed to set vxlan port %u to device\n",
+ dst_port);
+ break;
+ }
+ nicif_info(nic_dev, link, netdev, "Vxlan dst port set to %u\n",
+ action == HINIC3_CMD_OP_ADD
+ ? dst_port : ntohs(VXLAN_OFFLOAD_PORT_LE));
+ break;
+ default:
+ nicif_err(nic_dev, drv, netdev, "Failed to add port, only vxlan dst port is supported\n");
+ ret = -EINVAL;
+ }
+ return ret;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+static void hinic3_udp_tunnel_add(struct net_device *netdev,
+ struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+static void hinic3_udp_tunnel_del(struct net_device *netdev,
+ struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD */
+
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev,
+ __always_unused unsigned int table,
+ __always_unused unsigned int entry,
+ struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev,
+ __always_unused unsigned int table,
+ __always_unused unsigned int entry,
+ struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static int
hinic3_vlan_rx_add_vid(struct net_device *netdev,
__always_unused __be16 proto,
@@ -1124,7 +1309,7 @@ hinic3_vlan_rx_kill_vid(struct net_device *netdev,
int err = 0;
col = VID_COL(nic_dev, vid);
- line = VID_LINE(nic_dev, vid);
+ line = (int)VID_LINE(nic_dev, vid);
/* In the broadcast scenario, ucode finds the corresponding function
* based on VLAN 0 of vlan table. If we delete VLAN 0, the VLAN function
@@ -1163,14 +1348,12 @@ static int hinic3_vlan_restore(struct net_device *netdev)
return -EFAULT;
rcu_read_lock();
for (i = 0; i < VLAN_N_VID; i++) {
-/* lint -e778 */
#ifdef HAVE_VLAN_FIND_DEV_DEEP_RCU
vlandev =
__vlan_find_dev_deep_rcu(netdev, htons(ETH_P_8021Q), i);
#else
vlandev = __vlan_find_dev_deep(netdev, htons(ETH_P_8021Q), i);
#endif
-/* lint +e778 */
col = VID_COL(nic_dev, i);
line = VID_LINE(nic_dev, i);
if (!vlandev && (vlan_bitmap[line] & (1UL << col)) != 0) {
@@ -1328,12 +1511,17 @@ static int set_feature_vlan_filter(struct hinic3_nic_dev *nic_dev,
return 0;
#ifdef NEED_VLAN_RESTORE
- if (en)
+ if (en) {
err = hinic3_vlan_restore(nic_dev->netdev);
+ if (err) {
+ hinic3_err(nic_dev, drv, "vlan restore failed\n");
+ *failed_features |= vlan_filter_feature;
+ return err;
+ }
+ }
#endif
- if (err == 0)
- err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
+ err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
if (err) {
hinic3_err(nic_dev, drv, "%s rx vlan filter failed\n",
SET_FEATURES_OP_STR(en));
@@ -1427,8 +1615,8 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
struct hinic3_nic_dev *adapter = netdev_priv(netdev);
int err;
- if (is_multicast_ether_addr(mac) || /*lint !e574*/
- vf >= pci_num_vf(adapter->pdev)) /*lint !e574*/
+ if (is_multicast_ether_addr(mac) ||
+ vf >= pci_num_vf(adapter->pdev))
return -EINVAL;
err = hinic3_set_vf_mac(adapter->hwdev, OS_VF_ID_TO_HW(vf), mac);
@@ -1446,7 +1634,6 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
return 0;
}
-/*lint -save -e574 -e734*/
#ifdef IFLA_VF_MAX
static int set_hw_vf_vlan(void *hwdev, u16 cur_vlanprio, int vf,
u16 vlan, u8 qos)
@@ -1529,7 +1716,8 @@ static int hinic3_ndo_set_vf_spoofchk(struct net_device *netdev, int vf,
#endif
#ifdef HAVE_NDO_SET_VF_TRUST
-static int hinic3_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting)
+static int hinic3_ndo_set_vf_trust(struct net_device *netdev, int vf,
+ bool setting)
{
struct hinic3_nic_dev *adapter = netdev_priv(netdev);
int err;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
index 11c1731..7288c5c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
@@ -10,6 +10,8 @@
#include "hinic3_common.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
/* ************************ array index define ********************* */
#define ARRAY_INDEX_0 0
@@ -21,6 +23,36 @@
#define ARRAY_INDEX_6 6
#define ARRAY_INDEX_7 7
+#define XSFP_TLV_PRE_INFO_LEN 4
+
+enum hinic3_link_port_type {
+ LINK_PORT_UNKNOWN,
+ LINK_PORT_OPTICAL_MM,
+ LINK_PORT_OPTICAL_SM,
+ LINK_PORT_PAS_COPPER,
+ LINK_PORT_ACC,
+ LINK_PORT_BASET,
+ LINK_PORT_AOC = 0x40,
+ LINK_PORT_ELECTRIC,
+ LINK_PORT_BACKBOARD_INTERFACE,
+};
+
+enum hilink_fibre_subtype {
+ FIBRE_SUBTYPE_SR = 1,
+ FIBRE_SUBTYPE_LR,
+ FIBRE_SUBTYPE_MAX,
+};
+
+enum hilink_fec_type {
+ HILINK_FEC_NOT_SET,
+ HILINK_FEC_RSFEC,
+ HILINK_FEC_BASEFEC,
+ HILINK_FEC_NOFEC,
+ HILINK_FEC_LLRSFE,
+ HILINK_FEC_MAX_TYPE,
+};
+
+
#define SQ_CI_ADDR_SHIFT 2
#define RQ_CI_ADDR_SHIFT 4
@@ -71,6 +103,12 @@ struct hinic3_port_routine_cmd {
struct mag_cmd_get_xsfp_present abs;
};
+struct hinic3_port_routine_cmd_extern {
+ bool mpu_send_xsfp_tlv_info;
+
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp std_xsfp_tlv_info;
+};
+
struct hinic3_nic_cfg {
struct semaphore cfg_lock;
@@ -84,11 +122,13 @@ struct hinic3_nic_cfg {
struct nic_port_info port_info;
/* percentage of pf link bandwidth */
- u32 pf_bw_limit;
- u32 rsvd2;
+ u32 pf_bw_tx_limit;
+ u32 pf_bw_rx_limit;
- struct hinic3_port_routine_cmd rt_cmd;
- struct mutex sfp_mutex; /* mutex used for copy sfp info */
+ struct hinic3_port_routine_cmd rt_cmd;
+ struct hinic3_port_routine_cmd_extern rt_cmd_ext;
+ /* mutex used for copy sfp info */
+ struct mutex sfp_mutex;
};
struct hinic3_nic_cmdq_ops;
@@ -98,7 +138,7 @@ struct hinic3_nic_io {
void *dev_hdl;
u8 link_status;
- u8 rsvd1;
+ u8 direct;
u32 rsvd2;
struct hinic3_io_queue *sq;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
index 747ac03..f136893 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
@@ -21,11 +21,132 @@
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_nic_cmdq.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_common.h"
#include "hinic3_nic_cfg.h"
-int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_sq_attr *attr)
+#include "vram_common.h"
+
+int hinic3_delete_bond(void *hwdev)
+{
+ struct hinic3_cmd_delete_bond cmd_delete_bond;
+ u16 out_size = sizeof(cmd_delete_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_delete_bond, 0, sizeof(cmd_delete_bond));
+ cmd_delete_bond.bond_id = HINIC3_INVALID_BOND_ID;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_DELETE,
+ &cmd_delete_bond, sizeof(cmd_delete_bond),
+ &cmd_delete_bond, &out_size);
+ if (err || !out_size || cmd_delete_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to delete bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_delete_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_delete_bond.bond_id != HINIC3_INVALID_BOND_ID)
+ nic_info(nic_io->dev_hdl, "Delete bond success\n");
+
+ return 0;
+}
+
+int hinic3_open_close_bond(void *hwdev, u32 bond_en)
+{
+ struct hinic3_cmd_open_close_bond cmd_open_close_bond;
+ u16 out_size = sizeof(cmd_open_close_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_open_close_bond, 0, sizeof(cmd_open_close_bond));
+ cmd_open_close_bond.open_close_bond_info.bond_id =
+ HINIC3_INVALID_BOND_ID;
+ cmd_open_close_bond.open_close_bond_info.open_close_flag = bond_en;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_OPEN_CLOSE,
+ &cmd_open_close_bond,
+ sizeof(cmd_open_close_bond),
+ &cmd_open_close_bond, &out_size);
+ if (err || !out_size || cmd_open_close_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to %s bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ bond_en == true ? "open" : "close", err,
+ cmd_open_close_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_open_close_bond.open_close_bond_info.bond_id !=
+ HINIC3_INVALID_BOND_ID) {
+ nic_info(nic_io->dev_hdl, "%s bond success\n", bond_en == true ? "Open" : "Close");
+ }
+
+ return 0;
+}
+
+int hinic3_create_bond(void *hwdev, u32 *bond_id)
+{
+ struct hinic3_cmd_create_bond cmd_create_bond;
+ u16 out_size = sizeof(cmd_create_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_create_bond, 0, sizeof(cmd_create_bond));
+ cmd_create_bond.create_bond_info.default_param_flag = true;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_CREATE,
+ &cmd_create_bond, sizeof(cmd_create_bond),
+ &cmd_create_bond, &out_size);
+ if (err || !out_size || cmd_create_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to create default bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_create_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_create_bond.create_bond_info.bond_id !=
+ HINIC3_INVALID_BOND_ID) {
+ *bond_id = cmd_create_bond.create_bond_info.bond_id;
+ nic_info(nic_io->dev_hdl, "Create bond success\n");
+ }
+
+ return 0;
+}
+
+int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io,
+ struct hinic3_sq_attr *attr)
{
struct hinic3_cmd_cons_idx_attr cons_idx_attr;
u16 out_size = sizeof(cons_idx_attr);
@@ -48,7 +169,8 @@ int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_sq_attr *at
cons_idx_attr.l2nic_sqn = attr->l2nic_sqn;
cons_idx_attr.ci_addr = attr->ci_dma_base >> SQ_CI_ADDR_SHIFT;
- err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_SQ_CI_ATTR_SET,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC3_NIC_CMD_SQ_CI_ATTR_SET,
&cons_idx_attr, sizeof(cons_idx_attr),
&cons_idx_attr, &out_size);
if (err || !out_size || cons_idx_attr.msg_head.status) {
@@ -61,7 +183,8 @@ int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_sq_attr *at
return 0;
}
-int hinic3_set_rq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_rq_attr *attr)
+int hinic3_set_rq_ci_ctx(struct hinic3_nic_io *nic_io,
+ struct hinic3_rq_attr *attr)
{
struct hinic3_rq_cqe_ctx cons_idx_ctx;
u16 out_size = sizeof(cons_idx_ctx);
@@ -76,15 +199,19 @@ int hinic3_set_rq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_rq_attr *at
cons_idx_ctx.timer_loop = attr->coalescing_time;
cons_idx_ctx.threshold_cqe_num = attr->pending_limit;
cons_idx_ctx.msix_entry_idx = attr->intr_idx;
- cons_idx_ctx.ci_addr_hi = upper_32_bits(attr->ci_dma_base >> RQ_CI_ADDR_SHIFT);
- cons_idx_ctx.ci_addr_lo = lower_32_bits(attr->ci_dma_base >> RQ_CI_ADDR_SHIFT);
+ cons_idx_ctx.ci_addr_hi = upper_32_bits(attr->ci_dma_base >>
+ RQ_CI_ADDR_SHIFT);
+ cons_idx_ctx.ci_addr_lo = lower_32_bits(attr->ci_dma_base >>
+ RQ_CI_ADDR_SHIFT);
- err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_SET_RQ_CI_CTX,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC3_NIC_CMD_SET_RQ_CI_CTX,
&cons_idx_ctx, sizeof(cons_idx_ctx),
&cons_idx_ctx, &out_size);
if (err || !out_size || cons_idx_ctx.msg_head.status) {
nic_err(nic_io->dev_hdl, "Set rq cqe ctx fail, qid: %d, err: %d, status: 0x%x, out_size: 0x%x",
- attr->l2nic_rqn, err, cons_idx_ctx.msg_head.status, out_size);
+ attr->l2nic_rqn, err,
+ cons_idx_ctx.msg_head.status, out_size);
return -EFAULT;
}
@@ -142,8 +269,8 @@ int hinic3_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
&mac_info, sizeof(mac_info),
&mac_info, &out_size, channel);
if (err || !out_size ||
- hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
- mac_info.vlan_id)) {
+ (hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
+ mac_info.vlan_id) != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, mac_info.msg_head.status, out_size, channel);
@@ -178,6 +305,8 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -193,7 +322,8 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
&mac_info, sizeof(mac_info), &mac_info,
&out_size, channel);
if (err || !out_size ||
- (mac_info.msg_head.status && !PF_SET_VF_MAC(hwdev, mac_info.msg_head.status))) {
+ (mac_info.msg_head.status &&
+ !PF_SET_VF_MAC(hwdev, mac_info.msg_head.status))) {
nic_err(nic_io->dev_hdl,
"Failed to delete MAC, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, mac_info.msg_head.status, out_size, channel);
@@ -223,6 +353,8 @@ int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -239,8 +371,8 @@ int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
&mac_info, sizeof(mac_info),
&mac_info, &out_size);
if (err || !out_size ||
- hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
- mac_info.vlan_id)) {
+ (hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
+ mac_info.vlan_id) != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x\n",
err, mac_info.msg_head.status, out_size);
@@ -273,6 +405,8 @@ int hinic3_get_default_mac(void *hwdev, u8 *mac_addr)
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
mac_info.func_id = hinic3_global_func_id(hwdev);
@@ -318,6 +452,44 @@ static int hinic3_config_vlan(struct hinic3_nic_io *nic_io, u8 opcode,
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action)
+{
+ struct hinic3_cmd_vxlan_port_info vxlan_port_info;
+ u16 out_size = sizeof(vxlan_port_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ memset(&vxlan_port_info, 0, sizeof(vxlan_port_info));
+ vxlan_port_info.opcode = action;
+ vxlan_port_info.cfg_mode = 0; // other tool set
+ vxlan_port_info.func_id = func_id;
+ vxlan_port_info.vxlan_port = port;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+ &vxlan_port_info, sizeof(vxlan_port_info), &vxlan_port_info, &out_size);
+ if (err || !out_size || vxlan_port_info.msg_head.status) {
+ if (vxlan_port_info.msg_head.status == 0x2) // other tool set failed
+ nic_warn(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port because it has already been set by hinicadm\n",
+ action == HINIC3_CMD_OP_ADD
+ ? "add" : "delete");
+ else
+ nic_err(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port, err: %d, status: 0x%x, out size: 0x%x\n",
+ action == HINIC3_CMD_OP_ADD ? "add" : "delete",
+ err, vxlan_port_info.msg_head.status, out_size);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
{
struct hinic3_nic_io *nic_io = NULL;
@@ -326,6 +498,8 @@ int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan_id, func_id);
}
@@ -337,6 +511,8 @@ int hinic3_del_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_DEL, vlan_id, func_id);
}
@@ -380,6 +556,8 @@ int hinic3_set_dcb_state(void *hwdev, struct hinic3_dcb_state *dcb_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (!memcmp(&nic_io->dcb_state, dcb_state, sizeof(nic_io->dcb_state)))
return 0;
@@ -423,7 +601,8 @@ int hinic3_get_cos_by_pri(void *hwdev, u8 pri, u8 *cos)
if (pri >= NIC_DCB_UP_MAX && nic_io->dcb_state.trust == HINIC3_DCB_PCP)
return -EINVAL;
- if (pri >= NIC_DCB_IP_PRI_MAX && nic_io->dcb_state.trust == HINIC3_DCB_DSCP)
+ if (pri >= NIC_DCB_IP_PRI_MAX &&
+ nic_io->dcb_state.trust == HINIC3_DCB_DSCP)
return -EINVAL;
/*lint -e662*/
@@ -541,13 +720,15 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_cfg = &nic_io->nic_cfg;
down(&nic_cfg->cfg_lock);
err = hinic3_cfg_hw_pause(nic_io, HINIC3_CMD_OP_SET, &nic_pause);
- if (err) {
+ if (err != 0) {
up(&nic_cfg->cfg_lock);
return err;
}
@@ -566,7 +747,6 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
{
- struct hinic3_nic_cfg *nic_cfg = NULL;
struct hinic3_nic_io *nic_io = NULL;
int err = 0;
@@ -574,17 +754,13 @@ int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- nic_cfg = &nic_io->nic_cfg;
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_hw_pause(nic_io, HINIC3_CMD_OP_GET, nic_pause);
- if (err)
+ if (err != 0)
return err;
- if (nic_cfg->pause_set || !nic_pause->auto_neg) {
- nic_pause->rx_pause = nic_cfg->nic_pause.rx_pause;
- nic_pause->tx_pause = nic_cfg->nic_pause.tx_pause;
- }
-
return 0;
}
@@ -599,6 +775,8 @@ int hinic3_sync_dcb_state(void *hwdev, u8 op_code, u8 state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&dcb_state, 0, sizeof(dcb_state));
@@ -607,7 +785,8 @@ int hinic3_sync_dcb_state(void *hwdev, u8 op_code, u8 state)
dcb_state.func_id = hinic3_global_func_id(hwdev);
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_QOS_DCB_STATE,
- &dcb_state, sizeof(dcb_state), &dcb_state, &out_size);
+ &dcb_state, sizeof(dcb_state),
+ &dcb_state, &out_size);
if (err || dcb_state.head.status || !out_size) {
nic_err(nic_io->dev_hdl,
"Failed to set dcb state, err: %d, status: 0x%x, out size: 0x%x\n",
@@ -675,7 +854,8 @@ int hinic3_cache_out_qps_res(void *hwdev)
qp_res.func_id = hinic3_global_func_id(hwdev);
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
- &qp_res, sizeof(qp_res), &qp_res, &out_size);
+ &qp_res, sizeof(qp_res),
+ &qp_res, &out_size);
if (err || !out_size || qp_res.msg_head.status) {
nic_err(nic_io->dev_hdl, "Failed to cache out qp resources, err: %d, status: 0x%x, out size: 0x%x\n",
err, qp_res.msg_head.status, out_size);
@@ -685,45 +865,8 @@ int hinic3_cache_out_qps_res(void *hwdev)
return 0;
}
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats)
-{
- struct hinic3_port_stats *port_stats = NULL;
- struct hinic3_port_stats_info stats_info;
- u16 out_size = sizeof(*port_stats);
- struct hinic3_nic_io *nic_io = NULL;
- int err;
-
- port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
- if (!port_stats)
- return -ENOMEM;
-
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
-
- memset(&stats_info, 0, sizeof(stats_info));
-
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_PORT_STAT,
- &stats_info, sizeof(stats_info),
- port_stats, &out_size);
- if (err || !out_size || port_stats->msg_head.status) {
- nic_err(nic_io->dev_hdl,
- "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
- err, port_stats->msg_head.status, out_size);
- err = -EIO;
- goto out;
- }
-
- memcpy(stats, &port_stats->stats, sizeof(*stats));
-
-out:
- kfree(port_stats);
-
- return err;
-}
-EXPORT_SYMBOL(hinic3_get_fpga_phy_port_stats);
-
-int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *stats)
+int hinic3_get_vport_stats(void *hwdev, u16 func_id,
+ struct hinic3_vport_stats *stats)
{
struct hinic3_port_stats_info stats_info;
struct hinic3_cmd_vport_stats vport_stats;
@@ -738,6 +881,8 @@ int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *
memset(&vport_stats, 0, sizeof(vport_stats));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
stats_info.func_id = func_id;
@@ -756,7 +901,8 @@ int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *
return 0;
}
-static int hinic3_set_function_table(struct hinic3_nic_io *nic_io, u32 cfg_bitmap,
+static int hinic3_set_function_table(struct hinic3_nic_io *nic_io,
+ u32 cfg_bitmap,
const struct hinic3_func_tbl_cfg *cfg)
{
struct hinic3_cmd_set_func_tbl cmd_func_tbl;
@@ -804,6 +950,8 @@ int hinic3_set_port_mtu(void *hwdev, u16 new_mtu)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (new_mtu < HINIC3_MIN_MTU_SIZE) {
nic_err(nic_io->dev_hdl,
@@ -834,6 +982,8 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&feature_nego, 0, sizeof(feature_nego));
feature_nego.func_id = hinic3_global_func_id(hwdev);
feature_nego.opcode = opcode;
@@ -855,29 +1005,24 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return 0;
}
-static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
+static int hinic3_get_bios_pf_bw_tx_limit(void *hwdev,
+ struct hinic3_nic_io *nic_io,
+ u16 func_id, u32 *pf_rate)
{
- struct hinic3_nic_io *nic_io = NULL;
+ int err = 0; // default success
struct nic_cmd_bios_cfg cfg = {{0}};
u16 out_size = sizeof(cfg);
- int err;
-
- if (!hwdev || !pf_bw_limit)
- return -EINVAL;
-
- if (hinic3_func_type(hwdev) == TYPE_VF || !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
- return 0;
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- cfg.bios_cfg.func_id = (u8)hinic3_global_func_id(hwdev);
+ cfg.bios_cfg.func_id = (u8)func_id;
cfg.bios_cfg.func_valid = 1;
- cfg.op_code = 0 | NIC_NVM_DATA_PF_SPEED_LIMIT;
+ cfg.op_code = 0 | NIC_NVM_DATA_PF_TX_SPEED_LIMIT;
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BIOS_CFG, &cfg, sizeof(cfg),
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BIOS_CFG,
+ &cfg, sizeof(cfg),
&cfg, &out_size);
if (err || !out_size || cfg.head.status) {
nic_err(nic_io->dev_hdl,
- "Failed to get bios pf bandwidth limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ "Failed to get bios pf bandwidth tx limit, err: %d, status: 0x%x, out size: 0x%x\n",
err, cfg.head.status, out_size);
return -EIO;
}
@@ -887,13 +1032,86 @@ static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
nic_warn(nic_io->dev_hdl, "Invalid bios configuration data, signature: 0x%x\n",
cfg.bios_cfg.signature);
- if (cfg.bios_cfg.pf_bw > MAX_LIMIT_BW) {
+ if (cfg.bios_cfg.pf_tx_bw > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
+ cfg.bios_cfg.pf_tx_bw);
+ return -EINVAL;
+ }
+
+ (*pf_rate) = cfg.bios_cfg.pf_tx_bw;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_rx_limit(void *hwdev,
+ struct hinic3_nic_io *nic_io,
+ u16 func_id, u32 *pf_rate)
+{
+ int err = 0; // default success
+ struct nic_rx_rate_bios_cfg rx_bios_conf = {{0}};
+ u16 out_size = sizeof(rx_bios_conf);
+
+ rx_bios_conf.func_id = (u8)func_id;
+ rx_bios_conf.op_code = 0; /* 1-save, 0-read */
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_RX_RATE_CFG,
+ &rx_bios_conf, sizeof(rx_bios_conf),
+ &rx_bios_conf, &out_size);
+ if (rx_bios_conf.msg_head.status == HINIC3_MGMT_CMD_UNSUPPORTED &&
+ err == 0) { // Compatible older firmware
+ nic_warn(nic_io->dev_hdl, "Not support get bios pf bandwidth rx limit\n");
+ return 0;
+ } else if (err || !out_size || rx_bios_conf.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get bios pf bandwidth rx limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, rx_bios_conf.msg_head.status, out_size);
+ return -EIO;
+ }
+ if (rx_bios_conf.rx_rate_limit > MAX_LIMIT_BW) {
nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
- cfg.bios_cfg.pf_bw);
+ rx_bios_conf.rx_rate_limit);
return -EINVAL;
}
- *pf_bw_limit = cfg.bios_cfg.pf_bw;
+ (*pf_rate) = rx_bios_conf.rx_rate_limit;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit, u8 direct)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u32 pf_rate = 0;
+ int err = 0;
+ u16 func_id;
+
+ func_id = hinic3_global_func_id(hwdev);
+
+ if (!hwdev || !pf_bw_limit)
+ return -EINVAL;
+
+ if (hinic3_func_type(hwdev) == TYPE_VF ||
+ !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
+ return 0;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (direct == HINIC3_NIC_TX)
+ err = hinic3_get_bios_pf_bw_tx_limit(hwdev, nic_io,
+ func_id, &pf_rate);
+ else if (direct == HINIC3_NIC_RX)
+ err = hinic3_get_bios_pf_bw_rx_limit(hwdev, nic_io,
+ func_id, &pf_rate);
+
+ if (err != 0)
+ return err;
+
+ if (pf_rate > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl,
+ "Invalid bios cfg pf bandwidth limit: %u\n", pf_rate);
+ return -EINVAL;
+ }
+
+ *pf_bw_limit = pf_rate;
return 0;
}
@@ -902,8 +1120,9 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
{
struct hinic3_cmd_tx_rate_cfg rate_cfg = {{0}};
struct hinic3_nic_io *nic_io = NULL;
+ u32 rate_limit;
u16 out_size = sizeof(rate_cfg);
- u32 pf_rate;
+ u32 pf_rate = 0;
int err;
u32 speed_convert[PORT_SPEED_UNKNOWN] = {
0, 10, 100, 1000, 10000, 25000, 40000, 50000, 100000, 200000
@@ -914,30 +1133,34 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
return -EINVAL;
if (speed_level >= PORT_SPEED_UNKNOWN) {
- nic_err(nic_io->dev_hdl, "Invalid speed level: %u\n", speed_level);
+ nic_err(nic_io->dev_hdl,
+ "Invalid speed level: %u\n", speed_level);
return -EINVAL;
}
- if (nic_io->nic_cfg.pf_bw_limit == MAX_LIMIT_BW) {
- pf_rate = 0;
- } else {
+ rate_limit = (nic_io->direct == HINIC3_NIC_TX) ?
+ nic_io->nic_cfg.pf_bw_tx_limit : nic_io->nic_cfg.pf_bw_rx_limit;
+ if (rate_limit != MAX_LIMIT_BW) {
/* divided by 100 to convert to percentage */
- pf_rate = (speed_convert[speed_level] / 100) * nic_io->nic_cfg.pf_bw_limit;
+ pf_rate = (speed_convert[speed_level] / 100) * rate_limit;
/* bandwidth limit is very small but not unlimit in this case */
- if (pf_rate == 0 && speed_level != PORT_SPEED_NOT_SET)
+ if ((pf_rate == 0) && (speed_level != PORT_SPEED_NOT_SET))
pf_rate = 1;
}
rate_cfg.func_id = hinic3_global_func_id(hwdev);
rate_cfg.min_rate = 0;
rate_cfg.max_rate = pf_rate;
+ rate_cfg.direct = nic_io->direct;
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_MAX_MIN_RATE, &rate_cfg,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
+ &rate_cfg,
sizeof(rate_cfg), &rate_cfg, &out_size);
if (err || !out_size || rate_cfg.msg_head.status) {
nic_err(nic_io->dev_hdl, "Failed to set rate(%u), err: %d, status: 0x%x, out size: 0x%x\n",
pf_rate, err, rate_cfg.msg_head.status, out_size);
- return rate_cfg.msg_head.status ? rate_cfg.msg_head.status : -EIO;
+ return rate_cfg.msg_head.status
+ ? rate_cfg.msg_head.status : -EIO;
}
return 0;
@@ -954,7 +1177,8 @@ int hinic3_set_nic_feature_to_hw(void *hwdev)
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- return nic_feature_nego(hwdev, HINIC3_CMD_OP_SET, &nic_io->feature_cap, 1);
+ return nic_feature_nego(hwdev, HINIC3_CMD_OP_SET,
+ &nic_io->feature_cap, 1);
}
u64 hinic3_get_feature_cap(void *hwdev)
@@ -962,6 +1186,8 @@ u64 hinic3_get_feature_cap(void *hwdev)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
return nic_io->feature_cap;
}
@@ -971,12 +1197,17 @@ void hinic3_update_nic_feature(void *hwdev, u64 s_feature)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
nic_io->feature_cap = s_feature;
- nic_info(nic_io->dev_hdl, "Update nic feature to 0x%llx\n", nic_io->feature_cap);
+ nic_info(nic_io->dev_hdl,
+ "Update nic feature to 0x%llx\n",
+ nic_io->feature_cap);
}
-static inline int init_nic_hwdev_param_valid(const void *hwdev, const void *pcidev_hdl,
+static inline int init_nic_hwdev_param_valid(const void *hwdev,
+ const void *pcidev_hdl,
const void *dev_hdl)
{
if (!hwdev || !pcidev_hdl || !dev_hdl)
@@ -1004,6 +1235,7 @@ static int hinic3_init_nic_io(void *hwdev, void *pcidev_hdl, void *dev_hdl,
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_abs = false;
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_info = false;
+ (*nic_io)->nic_cfg.rt_cmd_ext.mpu_send_xsfp_tlv_info = false;
return 0;
}
@@ -1020,27 +1252,34 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
{
struct hinic3_nic_io *nic_io = NULL;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
err = hinic3_init_nic_io(hwdev, pcidev_hdl, dev_hdl, &nic_io);
- if (err)
+ if (err != 0)
return err;
+ nic_io->rx_buff_len = rx_buff_len;
+
err = hinic3_register_service_adapter(hwdev, nic_io, SERVICE_T_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to register service adapter\n");
goto register_sa_err;
}
- err = hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 1, HINIC3_CHANNEL_NIC);
- if (err) {
+ err = hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC,
+ 1, HINIC3_CHANNEL_NIC);
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set function svc used state\n");
goto set_used_state_err;
}
- err = hinic3_init_function_table(nic_io);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to init function table\n");
- goto err_out;
+ if (is_in_kexec == 0) {
+ err = hinic3_init_function_table(nic_io);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to init function table\n");
+ goto err_out;
+ }
}
err = hinic3_get_nic_feature_from_hw(hwdev, &nic_io->feature_cap, 1);
@@ -1052,24 +1291,35 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
sdk_info(dev_hdl, "nic features: 0x%llx\n", nic_io->feature_cap);
hinic3_nic_cmdq_adapt_init(nic_io);
- err = hinic3_get_bios_pf_bw_limit(hwdev, &nic_io->nic_cfg.pf_bw_limit);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to get pf bandwidth limit\n");
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_tx_limit,
+ HINIC3_NIC_TX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf tx bandwidth limit\n");
+ goto err_out;
+ }
+
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_rx_limit,
+ HINIC3_NIC_RX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf rx bandwidth limit\n");
goto err_out;
}
err = hinic3_vf_func_init(nic_io);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to init vf info\n");
goto err_out;
}
- nic_io->rx_buff_len = rx_buff_len;
-
return 0;
err_out:
- hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 0, HINIC3_CHANNEL_NIC);
+ if (hinic3_set_func_svc_used_state(
+ hwdev, SVC_T_NIC, 0, HINIC3_CHANNEL_NIC) != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to set function svc used state\n");
+ }
set_used_state_err:
hinic3_unregister_service_adapter(hwdev, SERVICE_T_NIC);
@@ -1119,6 +1369,8 @@ int hinic3_force_drop_tx_pkt(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&pkt_drop, 0, sizeof(pkt_drop));
pkt_drop.port = hinic3_physical_port_id(hwdev);
@@ -1147,6 +1399,8 @@ int hinic3_set_rx_mode(void *hwdev, u32 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&rx_mode_cfg, 0, sizeof(rx_mode_cfg));
rx_mode_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1175,6 +1429,8 @@ int hinic3_set_rx_vlan_offload(void *hwdev, u8 en)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_cfg, 0, sizeof(vlan_cfg));
vlan_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1192,7 +1448,8 @@ int hinic3_set_rx_vlan_offload(void *hwdev, u8 en)
return 0;
}
-int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
+int hinic3_update_mac_vlan(void *hwdev, const u16 old_vlan,
+ u16 new_vlan, int vf_id)
{
struct vf_data_storage *vf_info = NULL;
struct hinic3_nic_io *nic_io = NULL;
@@ -1203,6 +1460,8 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
if (!nic_io->vf_infos || is_zero_ether_addr(vf_info->drv_mac_addr))
return 0;
@@ -1211,7 +1470,7 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
err = hinic3_del_mac(nic_io->hwdev, vf_info->drv_mac_addr,
old_vlan, func_id, HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to delete VF %d MAC %pM vlan %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->drv_mac_addr, old_vlan);
return err;
@@ -1219,7 +1478,7 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
err = hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
new_vlan, func_id, HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to add VF %d MAC %pM vlan %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->drv_mac_addr, new_vlan);
hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
@@ -1242,6 +1501,8 @@ static int hinic3_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en,
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_cfg, 0, sizeof(lro_cfg));
lro_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1273,6 +1534,8 @@ static int hinic3_set_rx_lro_timer(void *hwdev, u32 timer_value)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_timer, 0, sizeof(lro_timer));
lro_timer.opcode = HINIC3_CMD_OP_SET;
@@ -1305,12 +1568,14 @@ int hinic3_set_rx_lro_state(void *hwdev, u8 lro_en, u32 lro_timer,
ipv6_en = lro_en ? 1 : 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_info(nic_io->dev_hdl, "Set LRO max coalesce packet size to %uK\n",
lro_max_pkt_len);
err = hinic3_set_rx_lro(hwdev, ipv4_en, ipv6_en, (u8)lro_max_pkt_len);
- if (err)
+ if (err != 0)
return err;
/* we don't set LRO timer for VF */
@@ -1333,6 +1598,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_filter, 0, sizeof(vlan_filter));
vlan_filter.func_id = hinic3_global_func_id(hwdev);
@@ -1352,7 +1619,6 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
{
- // struct hinic_hwdev *dev = hwdev;
struct nic_cmd_capture_info cap_info = {{0}};
u16 out_size = sizeof(cap_info);
int err;
@@ -1361,7 +1627,6 @@ int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
return -EINVAL;
/* 2 function capture types */
- // cap_info.op_type = UP_UCAPTURE_OP_TYPE_FUNC;
cap_info.is_en_trx = cap_en;
cap_info.func_port = func_id;
@@ -1386,6 +1651,8 @@ int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (tcam_rule->index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to add is invalid\n");
return -EINVAL;
@@ -1421,6 +1688,8 @@ int hinic3_del_tcam_rule(void *hwdev, u32 index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to del is invalid\n");
return -EINVAL;
@@ -1470,6 +1739,8 @@ static int hinic3_mgmt_tcam_block(void *hwdev, u8 alloc_en, u16 *index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&tcam_block_info, 0,
sizeof(struct nic_cmd_ctrl_tcam_block_out));
@@ -1515,6 +1786,8 @@ int hinic3_set_fdir_tcam_rule_filter(void *hwdev, bool enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
port_tcam_cmd.func_id = hinic3_global_func_id(hwdev);
port_tcam_cmd.tcam_enable = (u8)enable;
@@ -1543,6 +1816,8 @@ int hinic3_flush_tcam_rule(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&tcam_flush, 0, sizeof(struct nic_cmd_flush_tcam_rules));
tcam_flush.func_id = hinic3_global_func_id(hwdev);
@@ -1560,7 +1835,8 @@ int hinic3_flush_tcam_rule(void *hwdev)
return 0;
}
-int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type)
+int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info,
+ u16 num_qps, u16 wqe_type)
{
struct hinic3_cmd_buf *cmd_buf = NULL;
struct hinic3_nic_io *nic_io = NULL;
@@ -1573,6 +1849,8 @@ int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -1587,9 +1865,11 @@ int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
cmd_buf->size = sizeof(struct hinic3_rxq_hw);
- err = hinic3_cmdq_detail_resp(hwdev, HINIC3_MOD_L2NIC, HINIC3_UCODE_CMD_RXQ_INFO_GET,
- cmd_buf, cmd_buf, NULL, 0, HINIC3_CHANNEL_NIC);
- if (err)
+ err = hinic3_cmdq_detail_resp(hwdev, HINIC3_MOD_L2NIC,
+ HINIC3_UCODE_CMD_RXQ_INFO_GET,
+ cmd_buf, cmd_buf, NULL, 0,
+ HINIC3_CHANNEL_NIC);
+ if (err != 0)
goto get_rxq_info_failed;
rxq_info_out = cmd_buf->buf;
@@ -1604,7 +1884,8 @@ get_rxq_info_failed:
return err;
}
-int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_state)
+int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced,
+ bool link_state)
{
struct hinic3_nic_io *nic_io = NULL;
struct vf_data_storage *vf_infos = NULL;
@@ -1615,8 +1896,10 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return -EINVAL;
}
- if (hinic3_func_type(hwdev) == TYPE_VF)
+ if (hinic3_func_type(hwdev) == TYPE_VF) {
+ pr_err("VF are not supported to set link state.\n");
return -EINVAL;
+ }
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
if (!nic_io) {
@@ -1633,3 +1916,35 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return 0;
}
EXPORT_SYMBOL(hinic3_pf_set_vf_link_state);
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid)
+{
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ u16 out_size = sizeof(outband_cfg_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !outband_default_vid)
+ return -EINVAL;
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_OUTBAND_CFG,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size);
+ if (err || !out_size || outband_cfg_info.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get outband cfg, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, outband_cfg_info.msg_head.status, out_size);
+ return -EINVAL;
+ }
+
+ *outband_default_vid = outband_cfg_info.outband_default_vid;
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
index dd2c2fd..e0350e3 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
@@ -7,9 +7,10 @@
#include <linux/types.h>
#include <linux/netdevice.h>
-#include "hinic3_mgmt_interface.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
+#include "nic_cfg_comm.h"
+#include "nic_mpu_cmd_defs.h"
#define OS_VF_ID_TO_HW(os_vf_id) ((os_vf_id) + 1)
#define HW_VF_ID_TO_OS(hw_vf_id) ((hw_vf_id) - 1)
@@ -54,6 +55,8 @@
#define MAX_LIMIT_BW 100
+#define HINIC3_INVALID_BOND_ID 0xffffffff
+
enum hinic3_valid_link_settings {
HILINK_LINK_SET_SPEED = 0x1,
HILINK_LINK_SET_AUTONEG = 0x2,
@@ -67,6 +70,11 @@ enum hinic3_link_follow_status {
HINIC3_LINK_FOLLOW_STATUS_MAX,
};
+enum hinic3_nic_pf_direct {
+ HINIC3_NIC_RX = 0,
+ HINIC3_NIC_TX,
+};
+
struct hinic3_link_ksettings {
u32 valid_bitmap;
u8 speed; /* enum nic_speed_level */
@@ -152,8 +160,12 @@ struct nic_port_info {
u8 duplex;
u8 speed;
u8 fec;
+ u8 lanes;
+ u8 rsvd;
u32 supported_mode;
u32 advertised_mode;
+ u32 supported_fec_mode;
+ u32 bond_speed;
};
struct nic_pause_config {
@@ -178,11 +190,17 @@ struct hinic3_rxq_hw {
#define MODULE_TYPE_QSFP28 0x11
#define MODULE_TYPE_QSFP 0x0C
#define MODULE_TYPE_QSFP_PLUS 0x0D
+#define MODULE_TYPE_DSFP 0x1B
+#define MODULE_TYPE_QSFP_CMIS 0x1E
#define TCAM_IP_TYPE_MASK 0x1
#define TCAM_TUNNEL_TYPE_MASK 0xF
#define TCAM_FUNC_ID_MASK 0x7FFF
+int hinic3_delete_bond(void *hwdev);
+int hinic3_open_close_bond(void *hwdev, u32 bond_en);
+int hinic3_create_bond(void *hwdev, u32 *bond_id);
+
int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule);
int hinic3_del_tcam_rule(void *hwdev, u32 index);
@@ -335,7 +353,7 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr);
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr);
/* *
* @brief hinic3_vf_info_vlanprio - get vf vlan priority
@@ -510,7 +528,14 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table);
*/
int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats);
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats);
+/* *
+ * @brief hinic3_get_phy_rsfec_stats - get rsfec stats
+ * @param hwdev: device pointer to hwdev
+ * @param stats: rsfec(Reed-Solomon Forward Error Correction) stats
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats);
int hinic3_set_port_funcs_state(void *hwdev, bool enable);
@@ -546,6 +571,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl);
void hinic3_clear_vfs_info(void *hwdev);
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id);
+
int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id);
int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
@@ -565,9 +592,13 @@ int hinic3_set_autoneg(void *hwdev, bool enable);
int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext);
int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len);
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len);
bool hinic3_if_sfp_absent(void *hwdev);
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info);
+int hinic3_get_sfp_tlv_info(void *hwdev,
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info,
+ const struct tag_mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req);
/* *
* @brief hinic3_set_nic_feature_to_hw - sync nic feature to hardware
@@ -620,4 +651,19 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level);
int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type);
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+/* *
+ * @brief hinic3_vlxan_port_config - add/del vxlan dst port
+ * @param hwdev: device pointer to hwdev
+ * @param func_id: function id
+ * @param port: vxlan dst port
+ * @param action: add or del, del will set to default value (0x12B5)
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action);
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
index 15d081b..c0e0a61 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
@@ -22,7 +22,8 @@
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_nic_cmdq.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
/*lint -e806*/
static unsigned char set_vf_link_state;
@@ -59,7 +60,8 @@ static int hinic3_set_vlan_ctx(struct hinic3_nic_io *nic_io, u16 func_id,
vlan_tag, q_id, vlan_mode);
err = hinic3_cmdq_direct_resp(nic_io->hwdev, HINIC3_MOD_L2NIC,
- cmd, cmd_buf, &out_param, 0, HINIC3_CHANNEL_NIC);
+ cmd, cmd_buf, &out_param,
+ 0, HINIC3_CHANNEL_NIC);
hinic3_free_cmd_buf(nic_io->hwdev, cmd_buf);
@@ -108,7 +110,7 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
err = hinic3_set_vlan_ctx(nic_io, glb_func_id, vlan_tag,
NIC_CONFIG_ALL_QUEUE_VLAN_CTX,
opcode == HINIC3_CMD_OP_ADD);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d vlan ctx, err: %d\n",
HW_VF_ID_TO_OS(vf_id), err);
@@ -129,12 +131,15 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
/* this function just be called by hinic3_ndo_set_vf_mac,
* others are not permitted.
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr)
{
- struct vf_data_storage *vf_info;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_info = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
#ifndef __VMWARE__
/* duplicate request, so just return success */
@@ -152,13 +157,15 @@ int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan, qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan = vlan;
@@ -172,17 +179,19 @@ int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
vf_infos = nic_io->vf_infos;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_DEL,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_info(nic_io->dev_hdl, "Remove VLAN %u on VF %d\n",
@@ -197,11 +206,13 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
u16 hinic3_vf_info_vlanprio(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
u16 pf_vlan, vlanprio;
u8 pf_qos;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
pf_vlan = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan;
pf_qos = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos;
@@ -214,9 +225,14 @@ int hinic3_set_vf_link_state(void *hwdev, u16 vf_id, int link)
{
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ struct vf_data_storage *vf_infos = NULL;
u8 link_status = 0;
+ if (!nic_io)
+ return -EINVAL;
+
+ vf_infos = nic_io->vf_infos;
+
switch (link) {
case HINIC3_IFLA_VF_LINK_STATE_AUTO:
vf_infos[HW_VF_ID_TO_OS(vf_id)].link_forced = false;
@@ -256,6 +272,8 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
vf_infos = nic_io->vf_infos;
memset(&spoofchk_cfg, 0, sizeof(spoofchk_cfg));
@@ -280,9 +298,11 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
bool hinic3_vf_info_spoofchk(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].spoofchk;
}
@@ -296,7 +316,7 @@ int hinic3_set_vf_trust(void *hwdev, u16 vf_id, bool trust)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
+ if (!nic_io || vf_id > nic_io->max_vfs)
return -EINVAL;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust = trust;
@@ -309,11 +329,11 @@ bool hinic3_get_vf_trust(void *hwdev, int vf_id)
struct hinic3_nic_io *nic_io = NULL;
if (!hwdev)
- return -EINVAL;
+ return false;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
- return -EINVAL;
+ if (!nic_io || vf_id > nic_io->max_vfs)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust;
}
@@ -331,6 +351,7 @@ static int hinic3_set_vf_tx_rate_max_min(struct hinic3_nic_io *nic_io,
rate_cfg.func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf_id;
rate_cfg.max_rate = max_rate;
rate_cfg.min_rate = min_rate;
+ rate_cfg.direct = HINIC3_NIC_TX;
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
&rate_cfg, sizeof(rate_cfg), &rate_cfg,
@@ -351,13 +372,15 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (!HINIC3_SUPPORT_RATE_LIMIT(hwdev)) {
nic_err(nic_io->dev_hdl, "Current function doesn't support to set vf rate limit\n");
return -EOPNOTSUPP;
}
err = hinic3_set_vf_tx_rate_max_min(nic_io, vf_id, max_rate, min_rate);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].max_rate = max_rate;
@@ -368,12 +391,16 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
void hinic3_get_vf_config(void *hwdev, u16 vf_id, struct ifla_vf_info *ivi)
{
- struct vf_data_storage *vfinfo;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vfinfo = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
vfinfo = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vfinfo)
+ return;
ivi->vf = HW_VF_ID_TO_OS(vf_id);
ether_addr_copy(ivi->mac, vfinfo->user_mac_addr);
@@ -446,13 +473,15 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
int err;
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
- nic_io->hwdev, hinic3_vf_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_vf_event_handler);
+ if (err != 0)
return err;
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
- nic_io->hwdev, hinic3_vf_mag_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_vf_mag_event_handler);
+ if (err != 0)
goto reg_hilink_err;
memset(®ister_info, 0, sizeof(register_info));
@@ -464,6 +493,11 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
®ister_info, &out_size, 0,
HINIC3_CHANNEL_NIC);
if (err || !out_size || register_info.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev)) {
+ nic_warn(nic_io->dev_hdl, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, register_info.msg_head.status, out_size);
+ return 0;
+ }
nic_err(nic_io->dev_hdl, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
err, register_info.msg_head.status, out_size);
err = -EIO;
@@ -498,18 +532,20 @@ static int pf_init_vf_infos(struct hinic3_nic_io *nic_io)
for (i = 0; i < nic_io->max_vfs; i++) {
err = hinic3_init_vf_infos(nic_io, i);
- if (err)
+ if (err != 0)
goto init_vf_infos_err;
}
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
- nic_io->hwdev, hinic3_pf_mbox_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_mbox_handler);
+ if (err != 0)
goto register_pf_mbox_cb_err;
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
- nic_io->hwdev, hinic3_pf_mag_mbox_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_mag_mbox_handler);
+ if (err != 0)
goto register_pf_mag_mbox_cb_err;
return 0;
@@ -531,17 +567,19 @@ int hinic3_vf_func_init(struct hinic3_nic_io *nic_io)
return vf_func_register(nic_io);
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
- nic_io->hwdev, hinic3_pf_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_event_handler);
+ if (err != 0)
return err;
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
- nic_io->hwdev, hinic3_pf_mag_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_mag_event_handler);
+ if (err != 0)
goto register_mgmt_msg_cb_err;
err = pf_init_vf_infos(nic_io);
- if (err)
+ if (err != 0)
goto pf_init_vf_infos_err;
return 0;
@@ -568,17 +606,24 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
&unregister, sizeof(unregister),
&unregister, &out_size, 0,
HINIC3_CHANNEL_NIC);
- if (err || !out_size || unregister.msg_head.status)
- nic_err(nic_io->dev_hdl, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
- err, unregister.msg_head.status, out_size);
-
+ if (err || !out_size || unregister.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev)) {
+ nic_info(nic_io->dev_hdl, "vRoCE VF notify PF unsuccessful is allowed");
+ } else {
+ nic_err(nic_io->dev_hdl, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, unregister.msg_head.status, out_size);
+ }
+ }
hinic3_unregister_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
} else {
if (nic_io->vf_infos) {
- hinic3_unregister_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK);
- hinic3_unregister_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
+ hinic3_unregister_pf_mbox_cb(nic_io->hwdev,
+ HINIC3_MOD_HILINK);
+ hinic3_unregister_pf_mbox_cb(nic_io->hwdev,
+ HINIC3_MOD_L2NIC);
hinic3_clear_vfs_info(nic_io->hwdev);
kfree(nic_io->vf_infos);
+ nic_io->vf_infos = NULL;
}
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
@@ -587,11 +632,15 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
static void clear_vf_infos(void *hwdev, u16 vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
u16 func_id;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
func_id = hinic3_glb_pf_vf_offset(hwdev) + vf_id;
vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
@@ -620,10 +669,59 @@ static void clear_vf_infos(void *hwdev, u16 vf_id)
void hinic3_clear_vfs_info(void *hwdev)
{
+ u16 i;
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- u16 i;
+
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
for (i = 0; i < nic_io->max_vfs; i++)
clear_vf_infos(hwdev, OS_VF_ID_TO_HW(i));
}
+
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id)
+{
+ int err = 0;
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ struct vf_data_storage *vf_infos = NULL;
+ u16 out_size = sizeof(outband_cfg_info);
+ u16 vf_id;
+ struct hinic3_nic_io *nic_io =
+ hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return 0;
+ }
+
+ vf_id = func_id - hinic3_glb_pf_vf_offset(nic_io->hwdev);
+ vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+ if (vf_infos->registered) {
+ outband_cfg_info.func_id = func_id;
+ outband_cfg_info.outband_default_vid = vlan_id;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_L2NIC,
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return 0;
+ }
+ if (err || !out_size || outband_cfg_info.msg_head.status)
+ nic_err(nic_io->dev_hdl,
+ "outband cfg event to VF %d failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err,
+ outband_cfg_info.msg_head.status, out_size);
+ }
+
+ return err;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
index 0ec4b32..b45c875 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
@@ -30,6 +30,8 @@ int hinic3_dbg_get_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (q_id >= nic_io->num_qps) {
pr_err("q_id[%u] > num_qps_cfg[%u].\n", q_id, nic_io->num_qps);
return -EINVAL;
@@ -69,6 +71,8 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -82,6 +86,8 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
sq = &nic_io->sq[q_id];
+ if (!sq)
+ return -EINVAL;
sq_info->q_id = q_id;
sq_info->pi = hinic3_get_sq_local_pi(sq);
@@ -112,6 +118,8 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -125,6 +133,8 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
rq = &nic_io->rq[q_id];
+ if (!rq)
+ return -EINVAL;
rq_info->q_id = q_id;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
index e76a66b..38aa8f7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
@@ -15,9 +15,10 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
#include "hinic3_dcb.h"
+#include "vram_common.h"
#define HINIC3_NIC_DRV_NAME "hinic3"
-#define HINIC3_NIC_DRV_VERSION HINIC3_DRV_VERSION
+#define HINIC3_NIC_DRV_VERSION "17.7.8.1"
#define HINIC3_FUNC_IS_VF(hwdev) (hinic3_func_type(hwdev) == TYPE_VF)
@@ -25,6 +26,10 @@
#define HINIC3_MODERATONE_DELAY HZ
#define LP_PKT_CNT 64
+#define LP_PKT_LEN 60
+
+#define NAPI_IS_REGIN 1
+#define NAPI_NOT_REGIN 0
enum hinic3_flags {
HINIC3_INTF_UP,
@@ -91,6 +96,8 @@ struct hinic3_irq {
u16 rsvd1;
u32 irq_id; /* The IRQ number from OS */
+ u32 napi_reign;
+
char irq_name[IFNAMSIZ + 16];
struct napi_struct napi;
cpumask_t affinity_mask;
@@ -123,6 +130,41 @@ struct hinic3_dyna_txrxq_params {
struct hinic3_dyna_txq_res *txqs_res;
struct hinic3_dyna_rxq_res *rxqs_res;
struct hinic3_irq *irq_cfg;
+ char irq_cfg_vram_name[VRAM_NAME_MAX_LEN];
+};
+
+struct hinic3_flush_rq {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 lb_proc : 1;
+ u32 rsvd : 10;
+ u32 rq_id : 8;
+ u32 func_id : 13;
+#else
+ u32 func_id : 13;
+ u32 rq_id : 8;
+ u32 rsvd : 10;
+ u32 lb_proc : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd2 : 2;
+ u32 src_chnl : 12;
+ u32 pkt_len : 18;
+#else
+ u32 pkt_len : 18;
+ u32 src_chnl : 12;
+ u32 rsvd2 : 2;
+#endif
+ } bs;
+ u32 value;
+ } lb_info0; /* loop back information, used by uCode */
};
#define HINIC3_NIC_STATS_INC(nic_dev, field) \
@@ -147,6 +189,11 @@ struct hinic3_nic_stats {
#endif
};
+struct hinic3_nic_vport_stats {
+ u64 rx_discard_vport;
+};
+
+
#define HINIC3_TCAM_DYNAMIC_BLOCK_SIZE 16
#define HINIC3_MAX_TCAM_FILTERS 512
@@ -185,6 +232,29 @@ struct hinic3_tcam_info {
struct hinic3_tcam_dynamic_block_info tcam_dynamic_info;
};
+struct hinic3_dcb {
+ u8 cos_config_num_max;
+ u8 func_dft_cos_bitmap;
+ /* used to tool validity check */
+ u16 port_dft_cos_bitmap;
+
+ struct hinic3_dcb_config hw_dcb_cfg;
+ struct hinic3_dcb_config wanted_dcb_cfg;
+ unsigned long dcb_flags;
+};
+
+struct hinic3_vram {
+ u32 vram_mtu;
+ u16 vram_num_qps;
+ unsigned long flags;
+};
+
+struct hinic3_outband_cfg {
+ u16 outband_default_vid;
+ u16 rsvd;
+};
+
+
struct hinic3_nic_dev {
struct pci_dev *pdev;
struct net_device *netdev;
@@ -204,6 +274,7 @@ struct hinic3_nic_dev {
u32 dma_rx_buff_size;
u16 rx_buff_len;
u32 page_order;
+ bool page_pool_enabled;
/* Rss related varibles */
u8 rss_hash_engine;
@@ -213,17 +284,13 @@ struct hinic3_nic_dev {
u32 *rss_hkey_be;
u32 *rss_indir;
- u8 cos_config_num_max;
- u8 func_dft_cos_bitmap;
- u16 port_dft_cos_bitmap; /* used to tool validity check */
+ struct hinic3_dcb *dcb;
+ char dcb_name[VRAM_NAME_MAX_LEN];
+
+ struct hinic3_vram *nic_vram;
+ char nic_vram_name[VRAM_NAME_MAX_LEN];
- struct hinic3_dcb_config hw_dcb_cfg;
- struct hinic3_dcb_config wanted_dcb_cfg;
- struct hinic3_dcb_config dcb_cfg;
- unsigned long dcb_flags;
int disable_port_cnt;
- /* lock for disable or enable traffic flow */
- struct semaphore dcb_sem;
struct hinic3_intr_coal_info *intr_coalesce;
unsigned long last_moder_jiffies;
@@ -235,11 +302,10 @@ struct hinic3_nic_dev {
#endif
struct hinic3_nic_stats stats;
+ struct hinic3_nic_vport_stats vport_stats;
/* lock for nic resource */
struct mutex nic_mutex;
- bool force_port_disable;
- struct semaphore port_state_sem;
u8 link_status;
struct nic_service_cap nic_cap;
@@ -281,9 +347,10 @@ struct hinic3_nic_dev {
struct hinic3_nic_prof_attr *prof_attr;
struct hinic3_prof_adapter *prof_adap;
u64 rsvd8[7];
- u32 rsvd9;
+ struct hinic3_outband_cfg outband_cfg;
u32 rxq_get_err_times;
struct delayed_work rxq_check_work;
+ struct delayed_work vport_stats_work;
struct hinic3_tx_rx_ops tx_rx_ops;
};
@@ -312,7 +379,7 @@ struct hinic3_uld_info *get_nic_uld_info(void);
u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev);
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
int hinic3_open(struct net_device *netdev);
@@ -331,6 +398,8 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev);
void hinic3_qps_irq_deinit(struct hinic3_nic_dev *nic_dev);
+void qp_del_napi(struct hinic3_irq *irq_cfg);
+
void hinic3_set_netdev_ops(struct hinic3_nic_dev *nic_dev);
bool hinic3_is_netdev_ops_match(const struct net_device *netdev);
@@ -348,10 +417,6 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
int hinic3_get_sset_count(struct net_device *netdev, int sset);
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev);
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
#ifdef ETHTOOL_GLINKSETTINGS
@@ -386,5 +451,18 @@ bool hinic3_is_xdp_enable(struct hinic3_nic_dev *nic_dev);
int hinic3_xdp_max_mtu(struct hinic3_nic_dev *nic_dev);
#endif
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+int set_fecparam(void *hwdev, u8 fecparam);
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec);
+#endif
+
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
index 57cf07c..c53c125 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
@@ -21,11 +21,12 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
{
- struct vf_data_storage *vf_info;
+ struct vf_data_storage *vf_info = NULL;
u16 func_id;
int err = 0;
@@ -38,7 +39,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
vf_info->pf_vlan, func_id,
HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d MAC\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -51,7 +52,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD,
vf_info->pf_vlan, vf_info->pf_qos,
vf_id);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to add VF %d VLAN_QOS\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -62,7 +63,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_vf_tx_rate(nic_io->hwdev, vf_id,
vf_info->max_rate,
vf_info->min_rate);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d max rate %u, min rate %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->max_rate,
vf_info->min_rate);
@@ -84,7 +85,7 @@ static int register_vf_msg_handler(struct hinic3_nic_io *nic_io, u16 vf_id)
}
err = hinic3_init_vf_config(nic_io, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].registered = true;
@@ -137,6 +138,9 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
int err;
+ if (!vf_info)
+ return -EINVAL;
+
if (register_vf->op_register) {
vf_info->support_extra_feature = register_vf->support_extra_feature;
err = register_vf_msg_handler(nic_io, vf_id);
@@ -145,7 +149,7 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
vf_info->support_extra_feature = 0;
}
- if (err)
+ if (err != 0)
register_info->msg_head.status = EFAULT;
*out_size = sizeof(*register_info);
@@ -157,6 +161,8 @@ void hinic3_unregister_vf(struct hinic3_nic_io *nic_io, u16 vf_id)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vf_info)
+ return;
unregister_vf_msg_handler(nic_io, vf_id);
vf_info->support_extra_feature = 0;
}
@@ -181,14 +187,21 @@ static int hinic3_get_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
void *buf_out, u16 *out_size)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf);
+ struct hinic3_port_mac_set *mac_in =
+ (struct hinic3_port_mac_set *)buf_in;
struct hinic3_port_mac_set *mac_info = buf_out;
int err;
+ if (!mac_info || !vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (HINIC3_SUPPORT_VF_MAC(nic_io->hwdev)) {
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_GET_MAC, buf_in,
in_size, buf_out, out_size);
- if (!err) {
+ if (err == 0) {
if (is_zero_ether_addr(mac_info->mac))
ether_addr_copy(mac_info->mac, vf_info->drv_mac_addr);
}
@@ -211,6 +224,11 @@ static int hinic3_set_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -247,6 +265,10 @@ static int hinic3_del_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -283,10 +305,13 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
struct hinic3_port_mac_update *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
if (!is_valid_ether_addr(mac_in->new_mac)) {
nic_err(nic_io->dev_hdl, "Update VF MAC is invalid.\n");
return -EINVAL;
}
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
#ifndef __VMWARE__
if (vf_info->use_specified_mac && !vf_info->trust) {
@@ -301,7 +326,7 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
HW_VF_ID_TO_OS(vf),
HINIC_CFG_VF_MAC_CHANGED,
(void *)mac_in->new_mac);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to config VF %d MAC request, err: %d\n",
HW_VF_ID_TO_OS(vf), err);
return err;
@@ -359,10 +384,11 @@ static int _l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u16 in_size, void *buf_out, u16 *out_size,
u16 channel)
{
- u32 i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
+ int i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_cmd_handler[i].cmd)
cmd_to_pf = true;
@@ -397,13 +423,15 @@ int hinic3_pf_mbox_handler(void *hwdev,
u16 vf_id, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- u32 index, cmd_size = ARRAY_LEN(vf_cmd_handler);
+ int index, cmd_size = ARRAY_LEN(vf_cmd_handler);
struct hinic3_nic_io *nic_io = NULL;
if (!hwdev)
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (index = 0; index < cmd_size; index++) {
if (cmd == vf_cmd_handler[index].cmd)
@@ -460,10 +488,14 @@ void hinic3_notify_dcb_state_event(struct hinic3_nic_io *nic_io,
static void dcb_state_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- struct hinic3_cmd_vf_dcb_state *vf_dcb;
- struct hinic3_nic_io *nic_io;
+ struct hinic3_cmd_vf_dcb_state *vf_dcb = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
vf_dcb = buf_in;
if (!vf_dcb)
@@ -479,6 +511,10 @@ static void tx_pause_excp_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*excp_info)) {
nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
@@ -501,6 +537,10 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_event_info event_info = {0};
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*active_info)) {
nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
@@ -515,6 +555,36 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
hinic3_event_callback(nic_io->hwdev, &event_info);
}
+static void outband_vlan_cfg_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out,
+ u16 *out_size)
+{
+ struct hinic3_outband_cfg_info *outband_cfg_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info = {0};
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ nic_info(nic_io->dev_hdl, "outband vlan cfg event received\n");
+
+ if (in_size != sizeof(*outband_cfg_info)) {
+ nic_err(nic_io->dev_hdl, "outband cfg info invalid in_size: %u, should be %lu\n",
+ in_size, sizeof(*outband_cfg_info));
+ return;
+ }
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = EVENT_NIC_OUTBAND_CFG;
+ memcpy((void *)event_info.event_data,
+ outband_cfg_info, sizeof(*outband_cfg_info));
+
+ hinic3_event_callback(nic_io->hwdev, &event_info);
+}
+
static const struct nic_event_handler nic_cmd_handler[] = {
{
.cmd = HINIC3_NIC_CMD_VF_COS,
@@ -529,6 +599,11 @@ static const struct nic_event_handler nic_cmd_handler[] = {
.cmd = HINIC3_NIC_CMD_BOND_ACTIVE_NOTICE,
.handler = bond_active_event_handler,
},
+
+ {
+ .cmd = HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ .handler = outband_vlan_cfg_event_handler,
+ },
};
static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
@@ -543,6 +618,8 @@ static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (i = 0; i < size; i++) {
if (cmd == nic_cmd_handler[i].cmd) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
index a827f44..f3bb4c5 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
@@ -16,9 +16,10 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
-#include "hinic3_nic_io.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_nic_cmdq.h"
+#include "hinic3_nic_io.h"
#define HINIC3_DEAULT_TX_CI_PENDING_LIMIT 1
#define HINIC3_DEAULT_TX_CI_COALESCING_TIME 1
@@ -35,7 +36,7 @@ MODULE_PARM_DESC(tx_coalescing_time, "TX CI coalescing parameter coalescing_time
static unsigned char rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
module_param(rq_wqe_type, byte, 0444);
-MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 0-8Bytes, 1-16Bytes, 2-32Bytes (default=1)");
+MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 1-16Bytes, 2-32Bytes (default=2)");
/*lint +e806*/
static u32 tx_drop_thd_on = HINIC3_DEAULT_DROP_THD_ON;
@@ -46,7 +47,7 @@ static u32 tx_drop_thd_off = HINIC3_DEAULT_DROP_THD_OFF;
module_param(tx_drop_thd_off, uint, 0644);
MODULE_PARM_DESC(tx_drop_thd_off, "TX parameter drop_thd_off (default=0)");
/* performance: ci addr RTE_CACHE_SIZE(64B) alignment */
-#define HINIC3_CI_Q_ADDR_SIZE (64)
+#define HINIC3_CI_Q_ADDR_SIZE (64U)
#define CI_TABLE_SIZE(num_qps, pg_sz) \
(ALIGN((num_qps) * HINIC3_CI_Q_ADDR_SIZE, pg_sz))
@@ -255,7 +256,7 @@ static int hinic3_create_sq(struct hinic3_nic_io *nic_io, struct hinic3_io_queue
err = hinic3_wq_create(nic_io->hwdev, &sq->wq, sq_depth,
(u16)BIT(HINIC3_SQ_WQEBB_SHIFT));
- if (err) {
+ if (err != 0) {
sdk_err(nic_io->dev_hdl, "Failed to create tx queue(%u) wq\n",
q_id);
return err;
@@ -291,13 +292,22 @@ static int hinic3_create_rq(struct hinic3_nic_io *nic_io, struct hinic3_io_queue
{
int err;
- rq->wqe_type = (u8)(hinic3_get_rq_wqe_type(nic_io->hwdev));
+ /* rq_wqe_type Only support type 1-16Bytes, 2-32Bytes */
+ if (rq_wqe_type != HINIC3_NORMAL_RQ_WQE &&
+ rq_wqe_type != HINIC3_EXTEND_RQ_WQE) {
+ sdk_warn(nic_io->dev_hdl, "Module Parameter rq_wqe_type value %d is out of range: [%d, %d].",
+ rq_wqe_type, HINIC3_NORMAL_RQ_WQE,
+ HINIC3_EXTEND_RQ_WQE);
+ rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
+ }
+
+ rq->wqe_type = rq_wqe_type;
rq->q_id = q_id;
rq->msix_entry_idx = rq_msix_idx;
err = hinic3_wq_create(nic_io->hwdev, &rq->wq, rq_depth,
(u16)BIT(HINIC3_RQ_WQEBB_SHIFT + rq->wqe_type));
- if (err) {
+ if (err != 0) {
sdk_err(nic_io->dev_hdl, "Failed to create rx queue(%u) wq\n",
q_id);
return err;
@@ -318,14 +328,14 @@ static int create_qp(struct hinic3_nic_io *nic_io, struct hinic3_io_queue *sq,
int err;
err = hinic3_create_sq(nic_io, sq, q_id, sq_depth, qp_msix_idx);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to create sq, qid: %u\n",
q_id);
return err;
}
err = hinic3_create_rq(nic_io, rq, q_id, rq_depth, qp_msix_idx);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to create rq, qid: %u\n",
q_id);
goto create_rq_err;
@@ -364,14 +374,14 @@ int hinic3_init_nicio_res(void *hwdev)
nic_io->max_qps = hinic3_func_max_qnum(hwdev);
err = hinic3_alloc_db_addr(hwdev, &db_base, NULL);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to allocate doorbell for sqs\n");
goto alloc_sq_db_fail;
}
nic_io->sqs_db_addr = (u8 *)db_base;
err = hinic3_alloc_db_addr(hwdev, &db_base, NULL);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to allocate doorbell for rqs\n");
goto alloc_rq_db_fail;
}
@@ -474,7 +484,7 @@ int hinic3_alloc_qps(void *hwdev, struct irq_info *qps_msix_arry,
for (q_id = 0; q_id < num_qps; q_id++) {
err = create_qp(nic_io, &sqs[q_id], &rqs[q_id], q_id, qp_params->sq_depth,
qp_params->rq_depth, qps_msix_arry[q_id].msix_entry_idx);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to allocate qp %u, err: %d\n", q_id, err);
goto create_qp_err;
}
@@ -599,14 +609,14 @@ int hinic3_create_qps(void *hwdev, u16 num_qp, u32 sq_depth, u32 rq_depth,
}
err = hinic3_init_nicio_res(hwdev);
- if (err)
+ if (err != 0)
return err;
qp_params.num_qps = num_qp;
qp_params.sq_depth = sq_depth;
qp_params.rq_depth = rq_depth;
err = hinic3_alloc_qps(hwdev, qps_msix_arry, &qp_params);
- if (err) {
+ if (err != 0) {
hinic3_deinit_nicio_res(hwdev);
nic_err(nic_io->dev_hdl,
"Failed to allocate qps, err: %d\n", err);
@@ -906,11 +916,11 @@ static int init_qp_ctxts(struct hinic3_nic_io *nic_io)
int err;
err = init_sq_ctxts(nic_io);
- if (err)
+ if (err != 0)
return err;
err = init_rq_ctxts(nic_io);
- if (err)
+ if (err != 0)
return err;
return 0;
@@ -1026,14 +1036,14 @@ int hinic3_init_qp_ctxts(void *hwdev)
return -EFAULT;
err = init_qp_ctxts(nic_io);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to init QP ctxts\n");
return err;
}
/* clean LRO/TSO context space */
err = clean_qp_offload_ctxt(nic_io);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to clean qp offload ctxts\n");
return err;
}
@@ -1042,13 +1052,13 @@ int hinic3_init_qp_ctxts(void *hwdev)
err = hinic3_set_root_ctxt(hwdev, rq_depth, nic_io->sq[0].wq.q_depth,
nic_io->rx_buff_len, HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set root context\n");
return err;
}
err = init_sq_ci_ctxts(nic_io);
- if (err)
+ if (err != 0)
goto clean_root_ctxt;
if (HINIC3_SUPPORT_RX_COMPACT_CQE(hwdev)) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
index 37f923d..c5e02ad 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
@@ -317,7 +317,7 @@ static inline void hinic3_write_db(struct hinic3_io_queue *queue, int cos,
wmb(); /* Write all before the doorbell */
- writeq(*((u64 *)&db), DB_ADDR(queue, pi));
+ writeq(*((u64 *)(u8 *)&db), DB_ADDR(queue, pi));
}
struct hinic3_dyna_qp_params {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
index 78d943d..9ea93a0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
@@ -32,7 +32,7 @@ struct hinic3_prof_adapter nic_prof_adap_objs[] = {
void hinic3_init_nic_prof_adapter(struct hinic3_nic_dev *nic_dev)
{
- u16 num_adap = ARRAY_SIZE(nic_prof_adap_objs);
+ int num_adap = ARRAY_LEN(nic_prof_adap_objs);
nic_dev->prof_adap = hinic3_prof_init(nic_dev, nic_prof_adap_objs, num_adap,
(void *)&nic_dev->prof_attr);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
index 6302fb8..dc4bb9e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
@@ -430,7 +430,8 @@ hinic3_dynamic_lookup_tcam_filter(struct hinic3_nic_dev *nic_dev,
list_for_each_entry(tmp,
&tcam_info->tcam_dynamic_info.tcam_dynamic_list,
block_list)
- if (tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)
+ if (tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE ||
+ !tmp)
break;
if (!tmp || tmp->dynamic_index_cnt >= HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) {
@@ -512,7 +513,7 @@ static int hinic3_add_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, queue: %d, tcam_rule_nums: %d succeed\n",
+ "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, queue: %u, tcam_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev),
tcam_filter->dynamic_block_id, index, fdir_tcam_rule->index,
fdir_tcam_rule->data.qid, tcam_info->tcam_rule_nums + 1);
@@ -579,7 +580,7 @@ static int hinic3_del_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, local_rules_nums: %d, global_rule_nums: %d succeed\n",
+ "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, local_rules_nums: %u, global_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev), dynamic_block_id,
tcam_filter->index, index, tmp->dynamic_index_cnt - 1,
tcam_info->tcam_rule_nums - 1);
@@ -605,7 +606,7 @@ static inline struct hinic3_tcam_filter *
hinic3_tcam_filter_lookup(const struct list_head *filter_list,
struct tag_tcam_key *key)
{
- struct hinic3_tcam_filter *iter;
+ struct hinic3_tcam_filter *iter = NULL;
list_for_each_entry(iter, filter_list, tcam_filter_list) {
if (memcmp(key, &iter->tcam_key,
@@ -630,7 +631,7 @@ static int hinic3_remove_one_rule(struct hinic3_nic_dev *nic_dev,
struct hinic3_ethtool_rx_flow_rule *eth_rule)
{
struct hinic3_tcam_info *tcam_info = &nic_dev->tcam;
- struct hinic3_tcam_filter *tcam_filter;
+ struct hinic3_tcam_filter *tcam_filter = NULL;
struct nic_tcam_cfg_rule fdir_tcam_rule;
struct tag_tcam_key tcam_key;
int err;
@@ -751,7 +752,7 @@ static int validate_flow(struct hinic3_nic_dev *nic_dev,
{
if (fs->location >= MAX_NUM_OF_ETHTOOL_NTUPLE_RULES) {
nicif_err(nic_dev, drv, nic_dev->netdev, "loc exceed limit[0,%lu]\n",
- MAX_NUM_OF_ETHTOOL_NTUPLE_RULES);
+ MAX_NUM_OF_ETHTOOL_NTUPLE_RULES - 1);
return -EINVAL;
}
@@ -872,7 +873,7 @@ int hinic3_ethtool_get_flow(const struct hinic3_nic_dev *nic_dev,
int hinic3_ethtool_get_all_flows(const struct hinic3_nic_dev *nic_dev,
struct ethtool_rxnfc *info, u32 *rule_locs)
{
- int idx = 0;
+ u32 idx = 0;
struct hinic3_ethtool_rx_flow_rule *eth_rule = NULL;
if (!HINIC3_SUPPORT_FDIR(nic_dev->hwdev)) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h b/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
index a93f3b6..9202218 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
@@ -38,13 +38,12 @@ struct hinic3_prof_adapter {
#define LLT_STATIC_DEF_SAVED
#endif
-/*lint -save -e661 */
static inline struct hinic3_prof_adapter *
hinic3_prof_init(void *device, struct hinic3_prof_adapter *adap_objs, int num_adap,
void **prof_attr)
{
struct hinic3_prof_adapter *prof_obj = NULL;
- u16 i;
+ int i;
for (i = 0; i < num_adap; i++) {
prof_obj = &adap_objs[i];
@@ -68,7 +67,6 @@ static inline void hinic3_prof_deinit(struct hinic3_prof_adapter *prof_obj, void
prof_obj->deinit(prof_attr);
}
-/*lint -restore*/
/* module-level interface */
#ifdef CONFIG_MODULE_PROF
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
index e4705c2..2a909d8 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/dcbnl.h>
+#include <linux/init.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -23,7 +24,6 @@
#include "hinic3_hw.h"
#include "hinic3_rss.h"
-/*lint -e806*/
static u16 num_qps;
module_param(num_qps, ushort, 0444);
MODULE_PARM_DESC(num_qps, "Number of Queue Pairs (default=0)");
@@ -104,88 +104,84 @@ static int hinic3_get_rq2iq_map(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev, u8 num_cos, u32 *indir)
+static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev,
+ u8 group_num, u32 *indir)
{
- u16 k, group_size, start_qid = 0, qp_num = 0;
- int i = 0;
- u8 j, cur_cos = 0, default_cos;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ u16 k, group_size, start_qid = 0, cur_cos_qnum = 0;
+ u32 i = 0;
+ u8 j, cur_cos = 0, group = 0;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
- if (num_cos == 0) {
+ if (group_num == 0) {
for (i = 0; i < NIC_RSS_INDIR_SIZE; i++)
indir[i] = i % nic_dev->q_params.num_qps;
} else {
- group_size = NIC_RSS_INDIR_SIZE / num_cos;
-
- for (j = 0; j < num_cos; j++) {
- while (cur_cos < NIC_DCB_COS_MAX &&
- nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos] == 0)
- cur_cos++;
-
- if (cur_cos >= NIC_DCB_COS_MAX) {
- if (BIT(nic_dev->hw_dcb_cfg.default_cos) & valid_cos_map)
- default_cos = nic_dev->hw_dcb_cfg.default_cos;
- else
- default_cos = (u8)fls(valid_cos_map) - 1;
+ group_size = NIC_RSS_INDIR_SIZE / group_num;
+
+ for (group = 0; group < group_num; group++) {
+ cur_cos = dcb->hw_dcb_cfg.default_cos;
+ for (j = 0; j < NIC_DCB_COS_MAX; j++) {
+ if ((BIT(j) & valid_cos_map) != 0) {
+ cur_cos = j;
+ valid_cos_map -= (u8)BIT(j);
+ break;
+ }
+ }
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[default_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[default_cos];
+ cur_cos_qnum = dcb->hw_dcb_cfg.cos_qp_num[cur_cos];
+ if (cur_cos_qnum > 0) {
+ start_qid =
+ dcb->hw_dcb_cfg.cos_qp_offset[cur_cos];
} else {
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[cur_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos];
+ start_qid = cur_cos % nic_dev->q_params.num_qps;
+ /* Ensure that the offset of start_id is 0. */
+ cur_cos_qnum = 1;
}
for (k = 0; k < group_size; k++)
- indir[i++] = start_qid + k % qp_num;
-
- cur_cos++;
+ indir[i++] = start_qid + k % cur_cos_qnum;
}
}
}
-/*lint -e528*/
int hinic3_rss_init(struct hinic3_nic_dev *nic_dev, u8 *rq2iq_map, u32 map_size, u8 dcb_en)
{
struct net_device *netdev = nic_dev->netdev;
- u8 i, cos_num;
- u8 cos_map[NIC_DCB_UP_MAX] = {0};
- u8 cfg_map[NIC_DCB_UP_MAX] = {0};
+ u8 i, group_num, cos_bitmap, group = 0;
+ u8 cos_group[NIC_DCB_UP_MAX] = {0};
int err;
- if (dcb_en) {
- cos_num = hinic3_get_dev_user_cos_num(nic_dev);
+ if (dcb_en != 0) {
+ group_num = (u8)roundup_pow_of_two(
+ hinic3_get_dev_user_cos_num(nic_dev));
- if (nic_dev->hw_dcb_cfg.trust == 0) {
- memcpy(cfg_map, nic_dev->hw_dcb_cfg.pcp2cos, sizeof(cfg_map));
- } else if (nic_dev->hw_dcb_cfg.trust == 1) {
- for (i = 0; i < NIC_DCB_UP_MAX; i++)
- cfg_map[i] = nic_dev->hw_dcb_cfg.dscp2cos[i * NIC_DCB_DSCP_NUM];
- }
-#define COS_CHANGE_OFFSET 4
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[COS_CHANGE_OFFSET + i] = cfg_map[i];
-
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[i] = cfg_map[NIC_DCB_UP_MAX - (i + 1)];
+ cos_bitmap = hinic3_get_dev_valid_cos_map(nic_dev);
- while (cos_num & (cos_num - 1))
- cos_num++;
+ for (i = 0; i < NIC_DCB_UP_MAX; i++) {
+ if ((BIT(i) & cos_bitmap) != 0)
+ cos_group[NIC_DCB_UP_MAX - i - 1] = group++;
+ else
+ cos_group[NIC_DCB_UP_MAX - i - 1] =
+ group_num - 1;
+ }
} else {
- cos_num = 0;
+ group_num = 0;
}
- err = hinic3_set_hw_rss_parameters(netdev, 1, cos_num, cos_map, dcb_en);
+ err = hinic3_set_hw_rss_parameters(netdev, 1, group_num,
+ cos_group, dcb_en);
if (err)
return err;
- err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps, cos_num, cos_map,
- NIC_DCB_UP_MAX, nic_dev->rss_indir, rq2iq_map, map_size);
+ err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps,
+ group_num, cos_group, NIC_DCB_UP_MAX,
+ nic_dev->rss_indir, rq2iq_map, map_size);
if (err)
nicif_err(nic_dev, drv, netdev, "Failed to get rq map\n");
return err;
}
-/*lint -e528*/
void hinic3_rss_deinit(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -246,11 +242,28 @@ discard_user_rss_indir:
hinic3_set_default_rss_indir(netdev);
}
+#ifdef HAVE_HOT_REPLACE_FUNC
+bool partition_slave_doing_hotupgrade(void)
+{
+ return get_partition_role() && partition_doing_hotupgrade();
+}
+#endif
+
static void decide_num_qps(struct hinic3_nic_dev *nic_dev)
{
u16 tmp_num_qps = nic_dev->max_qps;
u16 num_cpus = 0;
+ u16 max_num_cpus;
int i, node;
+ int is_in_kexec = vram_get_kexec_flag();
+
+ if (is_in_kexec != 0) {
+ nic_dev->q_params.num_qps = nic_dev->nic_vram->vram_num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Os hotreplace use vram to init num qps 1:%u 2:%u\n",
+ nic_dev->q_params.num_qps, nic_dev->nic_vram->vram_num_qps);
+ return;
+ }
if (nic_dev->nic_cap.default_num_queues != 0 &&
nic_dev->nic_cap.default_num_queues < nic_dev->max_qps)
@@ -258,16 +271,29 @@ static void decide_num_qps(struct hinic3_nic_dev *nic_dev)
MOD_PARA_VALIDATE_NUM_QPS(nic_dev, num_qps, tmp_num_qps);
- for (i = 0; i < (int)num_online_cpus(); i++) {
+#ifdef HAVE_HOT_REPLACE_FUNC
+ if (partition_slave_doing_hotupgrade())
+ max_num_cpus = (u16)num_present_cpus();
+ else
+ max_num_cpus = (u16)num_online_cpus();
+#else
+ max_num_cpus = (u16)num_online_cpus();
+#endif
+
+ for (i = 0; i < max_num_cpus; i++) {
node = (int)cpu_to_node(i);
if (node == dev_to_node(&nic_dev->pdev->dev))
num_cpus++;
}
if (!num_cpus)
- num_cpus = (u16)num_online_cpus();
+ num_cpus = max_num_cpus;
nic_dev->q_params.num_qps = (u16)min_t(u16, tmp_num_qps, num_cpus);
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "init num qps 1:%u 2:%u\n",
+ nic_dev->q_params.num_qps, nic_dev->nic_vram->vram_num_qps);
}
static void copy_value_to_rss_hkey(struct hinic3_nic_dev *nic_dev,
@@ -312,6 +338,8 @@ static int alloc_rss_resource(struct hinic3_nic_dev *nic_dev)
nic_dev->rss_indir = kzalloc(sizeof(u32) * NIC_RSS_INDIR_SIZE, GFP_KERNEL);
if (!nic_dev->rss_indir) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to alloc memory for rss_indir\n");
kfree(nic_dev->rss_hkey);
nic_dev->rss_hkey = NULL;
return -ENOMEM;
@@ -322,7 +350,6 @@ static int alloc_rss_resource(struct hinic3_nic_dev *nic_dev)
return 0;
}
-/*lint -e528*/
void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -361,6 +388,7 @@ void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
set_q_params:
clear_bit(HINIC3_RSS_ENABLE, &nic_dev->flags);
nic_dev->q_params.num_qps = nic_dev->max_qps;
+ nic_dev->nic_vram->vram_num_qps = nic_dev->max_qps;
}
static int hinic3_config_rss_hw_resource(struct hinic3_nic_dev *nic_dev,
@@ -754,6 +782,7 @@ int hinic3_set_channels(struct net_device *netdev,
nic_dev->q_params.num_qps = (u16)count;
}
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
return 0;
}
@@ -814,7 +843,7 @@ int hinic3_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
int err = 0;
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
@@ -921,7 +950,7 @@ int hinic3_get_rxfh_indir(struct net_device *netdev, u32 *indir)
indir = indir1->ring_index;
#endif
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
index 071418d..4f4b18c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
@@ -15,14 +15,15 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_nic_cfg.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_hw.h"
#include "hinic3_nic.h"
#include "hinic3_nic_cmdq.h"
#include "hinic3_common.h"
static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
- u8 *key)
+ u8 *key, u16 key_size)
{
struct hinic3_cmd_rss_hash_key hash_key;
u16 out_size = sizeof(hash_key);
@@ -33,7 +34,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
hash_key.opcode = opcode;
if (opcode == HINIC3_CMD_OP_SET)
- memcpy(hash_key.key, key, NIC_RSS_KEY_SIZE);
+ memcpy(hash_key.key, key, key_size);
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_CFG_RSS_HASH_KEY,
@@ -47,7 +48,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
}
if (opcode == HINIC3_CMD_OP_GET)
- memcpy(key, hash_key.key, NIC_RSS_KEY_SIZE);
+ memcpy(key, hash_key.key, key_size);
return 0;
}
@@ -61,8 +62,12 @@ int hinic3_rss_set_hash_key(void *hwdev, const u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memcpy(hash_key, key, NIC_RSS_KEY_SIZE);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET, hash_key);
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET,
+ hash_key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
@@ -73,7 +78,11 @@ int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET, key);
+ if (!nic_io)
+ return -EINVAL;
+
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET,
+ key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
@@ -89,6 +98,7 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
if (nic_io == NULL)
return -EINVAL;
+
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (cmd_buf == NULL) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -159,6 +169,8 @@ static int hinic3_cmdq_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
@@ -210,6 +222,9 @@ static int hinic3_mgmt_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&ctx_tbl, 0, sizeof(ctx_tbl));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
ctx |= HINIC3_RSS_TYPE_SET(1, VALID) |
@@ -259,6 +274,8 @@ int hinic3_get_rss_type(void *hwdev, struct nic_rss_type *rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&ctx_tbl, 0, sizeof(struct hinic3_rss_context_table));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
@@ -292,6 +309,9 @@ static int hinic3_rss_cfg_hash_engine(struct hinic3_nic_io *nic_io, u8 opcode,
u16 out_size = sizeof(hash_type);
int err;
+ if (!nic_io)
+ return -EINVAL;
+
memset(&hash_type, 0, sizeof(struct hinic3_cmd_rss_engine_type));
hash_type.func_id = hinic3_global_func_id(nic_io->hwdev);
@@ -325,6 +345,9 @@ int hinic3_rss_set_hash_engine(void *hwdev, u8 type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_SET, &type);
}
@@ -336,6 +359,9 @@ int hinic3_rss_get_hash_engine(void *hwdev, u8 *type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_GET, type);
}
@@ -351,6 +377,9 @@ int hinic3_rss_cfg(void *hwdev, u8 rss_en, u8 cos_num, u8 *prio_tc, u16 num_qps)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&rss_cfg, 0, sizeof(struct hinic3_cmd_rss_config));
rss_cfg.func_id = hinic3_global_func_id(hwdev);
rss_cfg.rss_en = rss_en;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
index f8a866d..9027a3d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
@@ -21,6 +21,7 @@
#include <linux/ipv6.h>
#include <linux/module.h>
#include <linux/compiler.h>
+#include <linux/filter.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -63,19 +64,31 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
struct pci_dev *pdev = nic_dev->pdev;
struct page *page = rx_info->page;
dma_addr_t dma = rx_info->buf_dma_addr;
+ u32 page_offset = 0;
if (likely(dma))
return true;
/* alloc new page for storage */
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page = page_pool_alloc_frag(rx_info->page_pool, &page_offset,
+ nic_dev->rx_buff_len,
+ GFP_ATOMIC | __GFP_COLD | __GFP_COMP);
+ if (unlikely(!page))
+ return false;
+ dma = page_pool_get_dma_addr(page);
+ goto set_rx_info;
+ }
+#endif
page = alloc_pages_node(NUMA_NO_NODE, GFP_ATOMIC | __GFP_COLD |
__GFP_COMP, nic_dev->page_order);
if (unlikely(!page))
return false;
/* map page for use */
- dma = dma_map_page(&pdev->dev, page, 0, nic_dev->dma_rx_buff_size,
- DMA_FROM_DEVICE);
+ dma = dma_map_page(&pdev->dev, page, page_offset,
+ nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
/* if mapping failed free memory back to system since
* there isn't much point in holding memory we can't use
*/
@@ -83,10 +96,12 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
__free_pages(page, nic_dev->page_order);
return false;
}
+ goto set_rx_info;
+set_rx_info:
rx_info->page = page;
rx_info->buf_dma_addr = dma;
- rx_info->page_offset = 0;
+ rx_info->page_offset = page_offset;
return true;
}
@@ -108,7 +123,7 @@ static u32 hinic3_rx_fill_wqe(struct hinic3_rxq *rxq)
/* unit of cqe length is 16B */
hinic3_set_sge(&rq_wqe->extend_wqe.cqe_sect.sge,
rx_info->cqe_dma,
- (sizeof(struct hinic3_rq_cqe) >>
+ (HINIC3_CQE_LEN >>
HINIC3_CQE_SIZE_SHIFT));
/* use fixed len */
rq_wqe->extend_wqe.buf_desc.sge.len =
@@ -169,7 +184,7 @@ static u32 hinic3_rx_fill_buffers(struct hinic3_rxq *rxq)
if (likely(i)) {
hinic3_write_db(rxq->rq,
- rxq->q_id & 3,
+ rxq->q_id & (NIC_RX_DB_COS_MAX - 1),
RQ_CFLAG_DP,
(u16)((u32)rxq->next_to_update <<
rxq->rq->wqe_type));
@@ -206,6 +221,18 @@ static void hinic3_rx_free_buffers(struct hinic3_nic_dev *nic_dev, u32 q_depth,
for (i = 0; i < q_depth; i++) {
rx_info = &rx_info_arr[i];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ if (rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool,
+ rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ }
+ continue;
+ }
+#endif
+
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev,
rx_info->buf_dma_addr,
@@ -265,8 +292,15 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
DMA_FROM_DEVICE);
if (size <= HINIC3_RX_HDR_SIZE && !skb_is_nonlinear(skb)) {
- memcpy(__skb_put(skb, size), va + offset,
- ALIGN(size, sizeof(long))); /*lint !e666*/
+ __skb_put_data(skb, va + offset, size);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool,
+ page, false);
+ return false;
+ }
+#endif
/* page is not reserved, we can reuse buffer as-is */
if (likely(page_to_nid(page) == numa_node_id()))
@@ -274,25 +308,38 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
/* this page cannot be reused so discard it */
put_page(page);
- return false;
+ goto discard_page;
}
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
- (int)(rx_info->page_offset + offset), (int)size, rxq->buf_len);
+ (int)(rx_info->page_offset + offset), (int)size,
+ rxq->buf_len);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
/* avoid re-using remote pages */
if (unlikely(page_to_nid(page) != numa_node_id()))
- return false;
+ goto discard_page;
/* if we are only owner of page we can reuse it */
if (unlikely(page_count(page) != 1))
- return false;
+ goto discard_page;
/* flip page offset to other buffer */
rx_info->page_offset ^= rxq->buf_len;
get_page(page);
return true;
+
+discard_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
}
static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
@@ -338,10 +385,6 @@ static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
if (likely(hinic3_add_rx_frag(rxq, rx_info, skb, frag_size, tmp_pkt_offset))) {
hinic3_reuse_rx_page(rxq, rx_info);
- } else {
- /* we are not reusing the buffer so unmap it */
- dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
- rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
}
/* clear contents of buffer_info */
rx_info->buf_dma_addr = 0;
@@ -486,9 +529,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
protocol = hdr.eth->h_proto;
/* L2 header */
- /*lint -save -e778*/
if (protocol == htons(ETH_P_8021_AD) ||
- protocol == htons(ETH_P_8021_Q)) { /*lint -restore*/
+ protocol == htons(ETH_P_8021_Q)) {
if (unlikely(max_len < ETH_HLEN + VLAN_HLEN))
return max_len;
@@ -500,9 +542,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
}
/* L3 header */
- /*lint -save -e778*/
switch (protocol) {
- case htons(ETH_P_IP): /*lint -restore*/
+ case htons(ETH_P_IP):
if ((int)(hdr.data - data) >
(int)(max_len - sizeof(struct iphdr)))
return max_len;
@@ -713,7 +754,10 @@ static inline void hinic3_lro_set_gso_params(struct sk_buff *skb, u16 num_lro)
}
#ifdef HAVE_XDP_SUPPORT
-enum hinic3_xdp_pkt {
+enum hinic3_xdp_status {
+ // bpf_prog status
+ HINIC3_XDP_PROG_EMPTY,
+ // pkt action
HINIC3_XDP_PKT_PASS,
HINIC3_XDP_PKT_DROP,
};
@@ -724,9 +768,15 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
while (weqbb_num) {
rx_info = &rxq->rx_info[rxq->cons_idx & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool)
+ goto discard_direct;
+#endif
if (likely(page_to_nid(rx_info->page) == numa_node_id()))
hinic3_reuse_rx_page(rxq, rx_info);
+ goto discard_direct;
+discard_direct:
rx_info->buf_dma_addr = 0;
rx_info->page = NULL;
rxq->cons_idx++;
@@ -736,11 +786,11 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
}
}
-int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
+int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len, struct xdp_buff *xdp)
{
struct bpf_prog *xdp_prog = NULL;
struct hinic3_rx_info *rx_info = NULL;
- struct xdp_buff xdp;
+ struct net_device *netdev = rxq->netdev;
int result = HINIC3_XDP_PKT_PASS;
u16 weqbb_num = 1; /* xdp can only use one rx_buff */
u8 *va = NULL;
@@ -748,13 +798,14 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
rcu_read_lock();
xdp_prog = READ_ONCE(rxq->xdp_prog);
- if (!xdp_prog)
+ if (!xdp_prog) {
+ result = HINIC3_XDP_PROG_EMPTY;
goto unlock_rcu;
+ }
if (unlikely(pkt_len > rxq->buf_len)) {
RXQ_STATS_INC(rxq, xdp_large_pkt);
- weqbb_num = (u16)(pkt_len >> rxq->rx_buff_shift) +
- ((pkt_len & (rxq->buf_len - 1)) ? 1 : 0);
+ weqbb_num = HINIC3_GET_SGE_NUM(pkt_len, rxq);
result = HINIC3_XDP_PKT_DROP;
goto xdp_out;
}
@@ -765,26 +816,27 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
dma_sync_single_range_for_cpu(rxq->dev, rx_info->buf_dma_addr,
rx_info->page_offset,
rxq->buf_len, DMA_FROM_DEVICE);
- xdp.data = va;
- xdp.data_hard_start = xdp.data;
- xdp.data_end = xdp.data + pkt_len;
+ xdp->data = va;
+ xdp->data_hard_start = xdp->data;
+ xdp->data_end = xdp->data + pkt_len;
#ifdef HAVE_XDP_FRAME_SZ
- xdp.frame_sz = rxq->buf_len;
+ xdp->frame_sz = rxq->buf_len;
#endif
#ifdef HAVE_XDP_DATA_META
- xdp_set_data_meta_invalid(&xdp);
+ xdp_set_data_meta_invalid(xdp);
#endif
- prefetchw(xdp.data_hard_start);
- act = bpf_prog_run_xdp(xdp_prog, &xdp);
+ prefetchw(xdp->data_hard_start);
+ act = bpf_prog_run_xdp(xdp_prog, xdp);
switch (act) {
case XDP_PASS:
+ result = HINIC3_XDP_PKT_PASS;
break;
case XDP_DROP:
result = HINIC3_XDP_PKT_DROP;
break;
default:
result = HINIC3_XDP_PKT_DROP;
- bpf_warn_invalid_xdp_action(rxq->netdev, xdp_prog, act);
+ bpf_warn_invalid_xdp_action(netdev, xdp_prog, act);
}
xdp_out:
@@ -798,9 +850,86 @@ unlock_rcu:
return result;
}
+
+static bool hinic3_add_rx_frag_with_xdp(struct hinic3_rxq *rxq, u32 pkt_len,
+ struct hinic3_rx_info *rx_info,
+ struct sk_buff *skb, struct xdp_buff *xdp)
+{
+ struct page *page = rx_info->page;
+
+ if (pkt_len <= HINIC3_RX_HDR_SIZE) {
+ __skb_put_data(skb, xdp->data, pkt_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool, page, false);
+ return false;
+ }
+#endif
+ if (likely(page_to_nid(page) == numa_node_id()))
+ return true;
+
+ put_page(page);
+ goto umap_page;
+ }
+
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
+ (int)(rx_info->page_offset +
+ (xdp->data - xdp->data_hard_start)),
+ (int)pkt_len, rxq->buf_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
+ if (unlikely(page_to_nid(page) != numa_node_id()))
+ goto umap_page;
+ if (unlikely(page_count(page) != 1))
+ goto umap_page;
+
+ rx_info->page_offset ^= rxq->buf_len;
+ get_page(page);
+
+ return true;
+umap_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
+}
+
+static struct sk_buff *hinic3_fetch_rx_buffer_xdp(struct hinic3_rxq *rxq,
+ u32 pkt_len,
+ struct xdp_buff *xdp)
+{
+ struct sk_buff *skb;
+ struct hinic3_rx_info *rx_info;
+ u32 sw_ci;
+ bool reuse;
+
+ sw_ci = rxq->cons_idx & rxq->q_mask;
+ rx_info = &rxq->rx_info[sw_ci];
+
+ skb = netdev_alloc_skb_ip_align(rxq->netdev, HINIC3_RX_HDR_SIZE);
+ if (unlikely(!skb))
+ return NULL;
+
+ reuse = hinic3_add_rx_frag_with_xdp(rxq, pkt_len, rx_info, skb, xdp);
+ if (likely(reuse))
+ hinic3_reuse_rx_page(rxq, rx_info);
+
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+
+ rxq->cons_idx += 1;
+ rxq->delta += 1;
+
+ return skb;
+}
+
#endif
-static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_cqe_info *cqe_info)
+static int recv_one_pkt(struct hinic3_rxq *rxq,
+ struct hinic3_cqe_info *cqe_info)
{
struct sk_buff *skb = NULL;
struct net_device *netdev = rxq->netdev;
@@ -808,13 +937,25 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_cqe_info *cqe_info
#ifdef HAVE_XDP_SUPPORT
u32 xdp_status;
+ struct xdp_buff xdp = { 0 };
- xdp_status = (u32)(hinic3_run_xdp(rxq, cqe_info->pkt_len));
+ xdp_status = (u32)(hinic3_run_xdp(rxq, cqe_info->pkt_len, &xdp));
if (xdp_status == HINIC3_XDP_PKT_DROP)
return 0;
-#endif
+ // build skb
+ if (xdp_status != HINIC3_XDP_PROG_EMPTY) {
+ // xdp_prog configured, build skb with xdp
+ skb = hinic3_fetch_rx_buffer_xdp(rxq, cqe_info->pkt_len, &xdp);
+ } else {
+ // xdp_prog not configured, build skb
+ skb = hinic3_fetch_rx_buffer(rxq, cqe_info);
+ }
+#else
+
+ // xdp is not supported
skb = hinic3_fetch_rx_buffer(rxq, cqe_info);
+#endif
if (unlikely(!skb)) {
RXQ_STATS_INC(rxq, alloc_skb_err);
return -ENOMEM;
@@ -842,7 +983,7 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_cqe_info *cqe_info
if (unlikely(test_bit(HINIC3_LP_TEST, &nic_dev->flags)))
hinic3_copy_lp_data(nic_dev, skb);
- if (cqe_info->lro_num)
+ if (cqe_info->lro_num > 1)
hinic3_lro_set_gso_params(skb, cqe_info->lro_num);
skb_record_rx_queue(skb, rxq->q_id);
@@ -1021,12 +1162,39 @@ int hinic3_rx_poll(struct hinic3_rxq *rxq, int budget)
return pkts;
}
+#ifdef HAVE_PAGE_POOL_SUPPORT
+static struct page_pool *hinic3_create_page_pool(struct hinic3_nic_dev *nic_dev,
+ u32 rq_depth,
+ struct hinic3_rx_info *rx_info_arr)
+{
+ struct page_pool_params pp_params = {
+ .flags = PP_FLAG_DMA_MAP | PP_FLAG_PAGE_FRAG | PP_FLAG_DMA_SYNC_DEV,
+ .order = nic_dev->page_order,
+ .pool_size = rq_depth * nic_dev->rx_buff_len /
+ (PAGE_SIZE << nic_dev->page_order),
+ .nid = dev_to_node(&(nic_dev->pdev->dev)),
+ .dev = &(nic_dev->pdev->dev),
+ .dma_dir = DMA_FROM_DEVICE,
+ .offset = 0,
+ .max_len = PAGE_SIZE << nic_dev->page_order,
+ };
+ struct page_pool *page_pool;
+ int i;
+
+ page_pool = nic_dev->page_pool_enabled ?
+ page_pool_create(&pp_params) : NULL;
+ for (i = 0; i < rq_depth; i++)
+ rx_info_arr[i].page_pool = page_pool;
+ return page_pool;
+}
+#endif
+
int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
u32 rq_depth, struct hinic3_dyna_rxq_res *rxqs_res)
{
struct hinic3_dyna_rxq_res *rqres = NULL;
u64 cqe_mem_size = sizeof(struct hinic3_rq_cqe) * rq_depth;
- int idx, i;
+ int idx;
u32 pkts;
u64 size;
@@ -1045,51 +1213,53 @@ int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
if (!rqres->rx_info) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx info\n", idx);
- goto err_out;
+ goto err_alloc_rx_info;
}
-
if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
rqres->cqe_start_vaddr =
- dma_zalloc_coherent(&nic_dev->pdev->dev, cqe_mem_size,
+ dma_zalloc_coherent(&nic_dev->pdev->dev,
+ cqe_mem_size,
&rqres->cqe_start_paddr,
GFP_KERNEL);
if (!rqres->cqe_start_vaddr) {
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d cqe\n", idx);
- goto err_out;
+ goto err_alloc_cqe;
}
}
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ rqres->page_pool = hinic3_create_page_pool(nic_dev, rq_depth,
+ rqres->rx_info);
+ if (nic_dev->page_pool_enabled && !rqres->page_pool) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to create rxq%d page pool\n", idx);
+ goto err_create_page_pool;
+ }
+#endif
pkts = hinic3_rx_alloc_buffers(nic_dev, rq_depth,
rqres->rx_info);
if (!pkts) {
- if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- }
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx buffers\n", idx);
- goto err_out;
+ goto err_alloc_buffers;
}
rqres->next_to_alloc = (u16)pkts;
}
return 0;
-err_out:
- for (i = 0; i < idx; i++) {
- rqres = &rxqs_res[i];
-
- hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
- if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- }
- kfree(rqres->rx_info);
- }
-
+err_alloc_buffers:
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ page_pool_destroy(rqres->page_pool);
+err_create_page_pool:
+#endif
+ dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
+ rqres->cqe_start_vaddr,
+ rqres->cqe_start_paddr);
+err_alloc_cqe:
+ kfree(rqres->rx_info);
+err_alloc_rx_info:
+ hinic3_free_rxqs_res(nic_dev, idx, rq_depth, rxqs_res);
return -ENOMEM;
}
@@ -1104,6 +1274,10 @@ void hinic3_free_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
rqres = &rxqs_res[idx];
hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rqres->page_pool)
+ page_pool_destroy(rqres->page_pool);
+#endif
if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
rqres->cqe_start_vaddr,
@@ -1191,6 +1365,7 @@ void hinic3_free_rxqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->rxqs);
+ nic_dev->rxqs = NULL;
}
int hinic3_alloc_rxqs(struct net_device *netdev)
@@ -1312,6 +1487,14 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
nic_info(&nic_dev->pdev->dev, "rxq %u restore_buf_num:%u\n", q_id, rxq->restore_buf_num);
rx_info = &rxq->rx_info[(hw_ci + rxq->q_depth - 1) & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool && rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool, rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ goto reset_rxq;
+ }
+#endif
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev, rx_info->buf_dma_addr,
nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
@@ -1322,7 +1505,9 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
__free_pages(rx_info->page, nic_dev->page_order);
rx_info->page = NULL;
}
+ goto reset_rxq;
+reset_rxq:
rxq->delta = 1;
rxq->next_to_update = (u16)((hw_ci + rxq->q_depth - 1) & rxq->q_mask);
rxq->cons_idx = (u16)((rxq->next_to_update + 1) & rxq->q_mask);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
index 586a221..480f787 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
@@ -4,6 +4,10 @@
#ifndef HINIC3_RX_H
#define HINIC3_RX_H
+#ifdef HAVE_PAGE_POOL_SUPPORT
+#include <net/page_pool/helpers.h>
+#endif
+
#include <linux/types.h>
#include <linux/device.h>
#include <linux/mm_types.h>
@@ -27,6 +31,7 @@
#define HINIC3_RX_CSUM_IPSU_OTHER_ERR BIT(8)
#define HINIC3_HEADER_DATA_UNIT 2
+#define HINIC3_CQE_LEN 32
#define HINIC3_COMPACT_CQE_8B 8
#define HINIC3_COMPACT_CQE_16B 16
@@ -35,20 +40,20 @@
#define HINIC3_RQ_CQE_INTEGRATE 1
struct hinic3_rxq_stats {
- u64 packets;
- u64 bytes;
- u64 errors;
- u64 csum_errors;
- u64 other_errors;
- u64 dropped;
- u64 xdp_dropped;
- u64 rx_buf_empty;
-
- u64 alloc_skb_err;
- u64 alloc_rx_buf_err;
- u64 xdp_large_pkt;
- u64 restore_drop_sge;
- u64 rsvd2;
+ u64 packets;
+ u64 bytes;
+ u64 errors;
+ u64 csum_errors;
+ u64 other_errors;
+ u64 dropped;
+ u64 xdp_dropped;
+ u64 rx_buf_empty;
+
+ u64 alloc_skb_err;
+ u64 alloc_rx_buf_err;
+ u64 xdp_large_pkt;
+ u64 restore_drop_sge;
+ u64 rsvd2;
#ifdef HAVE_NDO_GET_STATS64
struct u64_stats_sync syncp;
#else
@@ -62,6 +67,9 @@ struct hinic3_rx_info {
struct hinic3_rq_cqe *cqe;
dma_addr_t cqe_dma;
struct page *page;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
u32 page_offset;
u32 rsvd1;
struct hinic3_rq_wqe *rq_wqe;
@@ -102,7 +110,7 @@ struct hinic3_rxq {
u16 next_to_update;
struct device *dev; /* device for DMA mapping */
- unsigned long status;
+ u64 status;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
@@ -130,6 +138,9 @@ struct hinic3_dyna_rxq_res {
struct hinic3_rx_info *rx_info;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
};
int hinic3_alloc_rxqs(struct net_device *netdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
index bdd5a8e..d816609 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
@@ -11,10 +11,12 @@
#ifndef HINIC3_SRV_NIC_H
#define HINIC3_SRV_NIC_H
-#include "hinic3_mgmt_interface.h"
+#include <linux/netdevice.h>
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_lld.h"
+#include "nic_cfg_comm.h"
+#include "nic_mpu_cmd_defs.h"
enum hinic3_queue_type {
HINIC3_SQ,
@@ -64,6 +66,7 @@ enum hinic3_nic_event_type {
EVENT_NIC_DCB_STATE_CHANGE,
EVENT_NIC_BOND_DOWN,
EVENT_NIC_BOND_UP,
+ EVENT_NIC_OUTBAND_CFG,
};
/* *
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
index bc1a8ef..d05813e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
@@ -223,24 +223,72 @@ static void get_inner_l3_l4_type(struct sk_buff *skb, union hinic3_ip *ip,
enum sq_l3_type *l3_type, u8 *l4_proto)
{
unsigned char *exthdr = NULL;
- __be16 frag_off = 0;
if (ip->v4->version == IP4_VERSION) {
*l3_type = IPV4_PKT_WITH_CHKSUM_OFFLOAD;
*l4_proto = ip->v4->protocol;
+
+#ifdef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
+ /* inner_transport_header is wrong in centos7.0 and suse12.1 */
+ l4->hdr = ip->hdr + ((u8)ip->v4->ihl << IP_HDR_IHL_UNIT_SHIFT);
+#endif
} else if (ip->v4->version == IP6_VERSION) {
*l3_type = IPV6_PKT;
exthdr = ip->hdr + sizeof(*ip->v6);
*l4_proto = ip->v6->nexthdr;
- if (exthdr != l4->hdr)
+ if (exthdr != l4->hdr) {
+ __be16 frag_off = 0;
+#ifndef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
ipv6_skip_exthdr(skb, (int)(exthdr - skb->data),
- l4_proto, &frag_off);
+ l4_proto, &frag_off);
+#else
+ int pld_off = 0;
+
+ pld_off = ipv6_skip_exthdr(skb,
+ (int)(exthdr - skb->data),
+ l4_proto, &frag_off);
+ l4->hdr = skb->data + pld_off;
+#endif
+ }
} else {
*l3_type = UNKNOWN_L3TYPE;
*l4_proto = 0;
}
}
+static u8 hinic3_get_inner_l4_type(struct sk_buff *skb)
+{
+ enum sq_l3_type l3_type;
+ u8 l4_proto;
+ union hinic3_ip ip;
+ union hinic3_l4 l4;
+
+ ip.hdr = skb_inner_network_header(skb);
+ l4.hdr = skb_inner_transport_header(skb);
+
+ get_inner_l3_l4_type(skb, &ip, &l4, &l3_type, &l4_proto);
+
+ return l4_proto;
+}
+
+static void hinic3_set_unknown_tunnel_csum(struct sk_buff *skb)
+{
+ int csum_offset;
+ __sum16 skb_csum;
+ u8 l4_proto;
+
+ l4_proto = hinic3_get_inner_l4_type(skb);
+ /* Unsupport tunnel packet, disable csum offload */
+ skb_checksum_help(skb);
+ /* The value of csum is changed from 0xffff to 0 according to RFC1624. */
+ if (skb->ip_summed == CHECKSUM_NONE && l4_proto != IPPROTO_UDP) {
+ csum_offset = skb_checksum_start_offset(skb) + skb->csum_offset;
+ skb_csum = *(__sum16 *)(skb->data + csum_offset);
+ if (skb_csum == 0xffff)
+ *(__sum16 *)(skb->data + csum_offset) = 0;
+ }
+}
+
static int hinic3_tx_csum(struct hinic3_txq *txq, struct sk_buff *skb,
struct hinic3_offload_info *offload_info,
struct hinic3_queue_info *queue_info)
@@ -276,10 +324,9 @@ static int hinic3_tx_csum(struct hinic3_txq *txq, struct sk_buff *skb,
if (l4_proto == IPPROTO_UDP)
queue_info->udp_dp_en = 1;
- if (l4_proto != IPPROTO_UDP ||
- ((struct udphdr *)skb_transport_header(skb))->dest != VXLAN_OFFLOAD_PORT_LE) {
+ if (l4_proto != IPPROTO_UDP) {
TXQ_STATS_INC(txq, unknown_tunnel_pkt);
- skb_checksum_help(skb);
+ hinic3_set_unknown_tunnel_csum(skb);
return 0;
}
}
@@ -682,6 +729,14 @@ static netdev_tx_t hinic3_send_one_skb(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
+ /* l2nic outband vlan cfg enable */
+ if ((!skb_vlan_tag_present(skb)) &&
+ (nic_dev->nic_cap.outband_vlan_cfg_en == 1) &&
+ nic_dev->outband_cfg.outband_default_vid != 0) {
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+ (u16)nic_dev->outband_cfg.outband_default_vid);
+ }
+
offload = hinic3_tx_offload(skb, &offload_info, &queue_info, txq);
if (unlikely(offload == TX_OFFLOAD_INVALID)) {
TXQ_STATS_INC(txq, offload_cow_skb_err);
@@ -880,6 +935,7 @@ int hinic3_alloc_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
tqres->bds = kzalloc(size, GFP_KERNEL);
if (!tqres->bds) {
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc txq%d bds info\n", idx);
goto err_out;
@@ -893,7 +949,9 @@ err_out:
tqres = &txqs_res[i];
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
return -ENOMEM;
@@ -910,7 +968,9 @@ void hinic3_free_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
free_all_tx_skbs(nic_dev, sq_depth, tqres->tx_info);
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
}
@@ -982,6 +1042,7 @@ void hinic3_free_txqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->txqs);
+ nic_dev->txqs = NULL;
}
static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
@@ -998,7 +1059,7 @@ static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
static int hinic3_stop_sq(struct hinic3_txq *txq)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(txq->netdev);
- unsigned long timeout;
+ u64 timeout;
int err;
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -1007,7 +1068,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
return 0;
usleep_range(900, 1000); /* sleep 900 us ~ 1000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* force hardware to drop packets */
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -1020,7 +1081,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
break;
usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* Avoid msleep takes too long and get a fake result */
if (is_hw_complete_sq_process(txq->sq))
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
index 1b9e509..7ae029b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
@@ -29,7 +29,7 @@ struct hinic3_wq {
#define WQ_MASK_IDX(wq, idx) ((idx) & (wq)->idx_mask)
#define WQ_MASK_PAGE(wq, pg_idx) \
- ((pg_idx) < (wq)->num_wq_pages ? (pg_idx) : 0)
+ (((pg_idx) < ((wq)->num_wq_pages)) ? (pg_idx) : 0)
#define WQ_PAGE_IDX(wq, idx) ((idx) >> (wq)->wqebbs_per_page_shift)
#define WQ_OFFSET_IN_PAGE(wq, idx) ((idx) & (wq)->wqebbs_per_page_mask)
#define WQ_GET_WQEBB_ADDR(wq, pg_idx, idx_in_pg) \
@@ -75,7 +75,7 @@ static inline void *hinic3_wq_get_multi_wqebbs(struct hinic3_wq *wq,
pg_idx = WQ_PAGE_IDX(wq, *prod_idx);
off_in_page = WQ_OFFSET_IN_PAGE(wq, *prod_idx);
- if (off_in_page + num_wqebbs > wq->wqebbs_per_page) {
+ if ((off_in_page + num_wqebbs) > wq->wqebbs_per_page) {
/* wqe across wq page boundary */
*second_part_wqebbs_addr =
WQ_GET_WQEBB_ADDR(wq, WQ_MASK_PAGE(wq, pg_idx + 1), 0);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
index 597d3fe..468351f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
@@ -400,12 +400,15 @@ static int wait_for_status_poll(struct hinic3_api_cmd_chain *chain)
API_CMD_STATUS_TIMEOUT, 100); /* wait 100 us once */
}
-static void copy_resp_data(struct hinic3_api_cmd_cell_ctxt *ctxt, void *ack,
+static void copy_resp_data(struct hinic3_api_cmd_chain *chain,
+ struct hinic3_api_cmd_cell_ctxt *ctxt, void *ack,
u16 ack_size)
{
struct hinic3_api_cmd_resp_fmt *resp = ctxt->resp;
+ int rsp_size_align = chain->rsp_size_align - 0x8;
+ int rsp_size = (ack_size > rsp_size_align) ? rsp_size_align : ack_size;
- memcpy(ack, &resp->resp_data, ack_size);
+ memcpy(ack, &resp->resp_data, rsp_size);
ctxt->status = 0;
}
@@ -464,7 +467,7 @@ static int wait_for_api_cmd_completion(struct hinic3_api_cmd_chain *chain,
case HINIC3_API_CMD_POLL_READ:
err = wait_for_resp_polling(ctxt);
if (err == 0)
- copy_resp_data(ctxt, ack, ack_size);
+ copy_resp_data(chain, ctxt, ack, ack_size);
else
sdk_err(dev, "API CMD poll response timeout\n");
break;
@@ -1054,13 +1057,11 @@ alloc_cells_buf_err:
alloc_wb_status_err:
kfree(chain->cell_ctxt);
-/*lint -save -e548*/
alloc_cell_ctxt_err:
if (chain->chain_type == HINIC3_API_CMD_WRITE_ASYNC_TO_MGMT_CPU)
spin_lock_deinit(&chain->async_lock);
else
sema_deinit(&chain->sem);
-/*lint -restore*/
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
index 38474ba..9f10131 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
@@ -801,7 +801,7 @@ static int cmdq_sync_cmd(struct hinic3_cmdq *cmdq, u8 mod, u8 cmd,
hinic3_cmdq_fill_completion_info(cmd_info, &cmpt_code, &done, &errcode, out_param);
cmdq_set_cmd_buf(cmd_info, cmdq->hwdev, buf_in, buf_out);
- memcpy(&saved_cmd_info, cmd_info, sizeof(*cmd_info));
+ memcpy(&saved_cmd_info, cmd_info, sizeof(struct hinic3_cmdq_cmd_info));
cmdq_sync_wqe_prepare(cmdq, mod, cmd, buf_in, buf_out, curr_wqe, curr_pi, nic_cmd_type);
@@ -1075,6 +1075,7 @@ int hinic3_cmdq_async(void *hwdev, u8 mod, u8 cmd, struct hinic3_cmd_buf *buf_in
return cmdq_async_cmd(&cmdqs->cmdq[HINIC3_CMDQ_SYNC], mod,
cmd, buf_in, channel);
}
+EXPORT_SYMBOL(hinic3_cmdq_async);
int hinic3_cmdq_async_cos(void *hwdev, u8 mod, u8 cmd,
u8 cos_id, struct hinic3_cmd_buf *buf_in, u16 channel)
@@ -1320,6 +1321,7 @@ cmd_infos_err:
static void free_cmdq(struct hinic3_cmdq *cmdq)
{
kfree(cmdq->cmd_infos);
+ cmdq->cmd_infos = NULL;
spin_lock_deinit(&cmdq->cmdq_lock);
}
@@ -1530,7 +1532,7 @@ static int create_cmdq_wq(struct hinic3_cmdqs *cmdqs)
type = HINIC3_CMDQ_SYNC;
for (; type < cmdqs->cmdq_num; type++)
memcpy((u8 *)cmdqs->wq_block_vaddr +
- CMDQ_WQ_CLA_SIZE * type,
+ ((u64)type * CMDQ_WQ_CLA_SIZE),
cmdqs->cmdq[type].wq.wq_block_vaddr,
cmdqs->cmdq[type].wq.num_wq_pages * sizeof(u64));
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
index b9b884f..4f4639d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
@@ -15,11 +15,6 @@
#include "hinic3_common.h"
#include "hinic3_hwdev.h"
-struct dma_pool {
- unsigned int size;
- void *dev_hdl;
-};
-
#define HINIC3_SCMD_DATA_LEN 16
#define HINIC3_CMDQ_DEPTH 4096
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c
index c212bcc..d7e4985 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c
@@ -16,7 +16,6 @@
#include "ossl_knl.h"
#include "npu_cmdq_base_defs.h"
-#include "comm_defs.h"
#include "hinic3_crm.h"
#include "hinic3_hw.h"
#include "hinic3_hwdev.h"
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
index 5e0139a..f0b2b1a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
@@ -22,11 +22,15 @@
#include "hinic3_sriov.h"
#include "hinic3_nictool.h"
#include "hinic3_pci_id_tbl.h"
+#include "hinic3_hwdev.h"
+#include "cfg_mgmt_mpu_cmd_defs.h"
+#include "mpu_cmd_base_defs.h"
#include "hinic3_dev_mgmt.h"
#define HINIC3_WAIT_TOOL_CNT_TIMEOUT 10000
#define HINIC3_WAIT_TOOL_MIN_USLEEP_TIME 9900
#define HINIC3_WAIT_TOOL_MAX_USLEEP_TIME 10000
+#define HIGHT_BDF 8
static unsigned long card_bit_map;
@@ -60,14 +64,24 @@ void lld_dev_cnt_init(struct hinic3_pcidev *pci_adapter)
void lld_dev_hold(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_inc(&pci_adapter->ref_cnt);
}
void lld_dev_put(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_dec(&pci_adapter->ref_cnt);
}
@@ -236,6 +250,40 @@ void hinic3_get_all_chip_id(void *id_info)
card_id->num = (u32)i;
}
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+ u64 bar1_phy_addr = 0;
+ u64 bar3_phy_addr = 0;
+ u64 bar1_size = 0;
+ u64 bar3_size = 0;
+
+ lld_hold();
+
+ /* get PF bar1 or bar3 physical address to verify */
+ list_for_each_entry(chip_node, &g_hinic3_chip_list, node) {
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (hinic3_func_type(dev->hwdev) == TYPE_VF)
+ continue;
+
+ bar1_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+ bar1_size = pci_resource_len(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+
+ bar3_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ bar3_size = pci_resource_len(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ if ((phy_addr == bar1_phy_addr && vmsize <= bar1_size) ||
+ (phy_addr == bar3_phy_addr && vmsize <= bar3_size)) {
+ lld_put();
+ return 0;
+ }
+ }
+ }
+
+ lld_put();
+ return -EINVAL;
+}
+
void hinic3_get_card_func_info_by_card_name(const char *chip_name,
struct hinic3_card_func_info *card_func)
{
@@ -422,6 +470,29 @@ struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name
return NULL;
}
+void *hinic3_get_ppf_dev(void)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct list_head *chip_list = NULL;
+
+ lld_hold();
+ chip_list = get_hinic3_chip_list();
+
+ list_for_each_entry(chip_node, chip_list, node)
+ list_for_each_entry(pci_adapter, &chip_node->func_list, node)
+ if (hinic3_func_type(pci_adapter->hwdev) == TYPE_PPF) {
+ pr_info("Get ppf_func_id:%u",
+ hinic3_global_func_id(pci_adapter->hwdev));
+ lld_put();
+ return pci_adapter->lld_dev.hwdev;
+ }
+
+ lld_put();
+ return NULL;
+}
+EXPORT_SYMBOL(hinic3_get_ppf_dev);
+
struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
enum hinic3_service_type type)
{
@@ -518,6 +589,7 @@ EXPORT_SYMBOL(hinic3_get_ppf_lld_dev_unsafe);
int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len)
{
struct hinic3_pcidev *pci_adapter = NULL;
+ int ret = 0;
if (!lld_dev || !chip_name || !max_len)
return -EINVAL;
@@ -527,12 +599,18 @@ int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 ma
return -EFAULT;
lld_hold();
- strscpy(chip_name, pci_adapter->chip_node->chip_name, max_len);
+ if (strscpy(chip_name, pci_adapter->chip_node->chip_name, max_len) < 0)
+ goto RELEASE;
chip_name[max_len - 1] = '\0';
lld_put();
return 0;
+
+RELEASE:
+ lld_put();
+
+ return ret;
}
EXPORT_SYMBOL(hinic3_get_chip_name);
@@ -541,6 +619,87 @@ struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev)
return lld_dev->hwdev;
}
+void hinic3_write_oshr_info(struct os_hot_replace_info *out_oshr_info,
+ struct hw_pf_info *info,
+ struct hinic3_board_info *board_info,
+ struct card_node *chip_node, u32 serivce_enable,
+ u32 func_info_idx)
+{
+ out_oshr_info->func_infos[func_info_idx].pf_idx = info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].backup_pf =
+ (((info->glb_func_idx) / (board_info->port_num)) %
+ HOT_REPLACE_PARTITION_NUM == 0) ?
+ ((info->glb_func_idx) + (board_info->port_num)) :
+ ((info->glb_func_idx) - (board_info->port_num));
+ out_oshr_info->func_infos[func_info_idx].partition =
+ ((info->glb_func_idx) / (board_info->port_num)) %
+ HOT_REPLACE_PARTITION_NUM;
+ out_oshr_info->func_infos[func_info_idx].port_id = info->port_id;
+ out_oshr_info->func_infos[func_info_idx].bdf =
+ (info->bus_num << HIGHT_BDF) + info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].bus_num = chip_node->bus_num;
+ out_oshr_info->func_infos[func_info_idx].valid = serivce_enable;
+ memcpy(out_oshr_info->func_infos[func_info_idx].card_name,
+ chip_node->chip_name, IFNAMSIZ);
+}
+
+void hinic3_get_os_hot_replace_info(void *oshr_info)
+{
+ struct os_hot_replace_info *out_oshr_info =
+ (struct os_hot_replace_info *)oshr_info;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dst_dev = NULL;
+ struct hinic3_board_info *board_info = NULL;
+ struct hw_pf_info *infos = NULL;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ struct hinic3_hwdev *hwdev = NULL;
+ u32 func_info_idx = 0, func_id = 0, func_num, serivce_enable = 0;
+ struct list_head *hinic3_chip_list = get_hinic3_chip_list();
+ int err;
+
+ lld_hold();
+ pf_infos = kzalloc(sizeof(struct hinic3_hw_pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ pr_err("kzalloc pf_infos fail\n");
+ lld_put();
+ return;
+ }
+ list_for_each_entry(chip_node, hinic3_chip_list, node) {
+ list_for_each_entry(dst_dev, &chip_node->func_list, node) {
+ err = hinic3_get_hw_pf_infos(dst_dev->hwdev,
+ pf_infos,
+ HINIC3_CHANNEL_COMM);
+ if (err != 0) {
+ pr_err("get pf info failed\n");
+ break;
+ }
+ hwdev = (struct hinic3_hwdev *)dst_dev->hwdev;
+ serivce_enable = 0;
+ infos = pf_infos->infos;
+ board_info = &hwdev->board_info;
+ if (hwdev->hot_replace_mode == HOT_REPLACE_ENABLE)
+ serivce_enable = 1;
+ break;
+ }
+
+ func_num = pf_infos->num_pfs;
+ if (func_num <= 0) {
+ pr_err("get pf num failed\n");
+ break;
+ }
+
+ for (func_id = 0; func_id < func_num; func_id++) {
+ hinic3_write_oshr_info(out_oshr_info, &infos[func_id],
+ board_info, chip_node,
+ serivce_enable, func_info_idx);
+ func_info_idx++;
+ }
+ }
+ out_oshr_info->func_cnt = func_info_idx;
+ kfree(pf_infos);
+ lld_put();
+}
+
struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(lld_dev->pdev);
@@ -608,21 +767,24 @@ void hinic3_get_card_info(const void *hwdev, void *bufin)
if (hinic3_support_nic(fun_hwdev, NULL)) {
if (dev->uld_dev[SERVICE_T_NIC]) {
info->pf[i].pf_type |= (u32)BIT(SERVICE_T_NIC);
- get_dynamic_uld_dev_name(dev, SERVICE_T_NIC, info->pf[i].name);
+ get_dynamic_uld_dev_name(dev, SERVICE_T_NIC,
+ info->pf[i].name);
}
}
if (hinic3_support_ppa(fun_hwdev, NULL)) {
if (dev->uld_dev[SERVICE_T_PPA]) {
info->pf[i].pf_type |= (u32)BIT(SERVICE_T_PPA);
- get_dynamic_uld_dev_name(dev, SERVICE_T_PPA, info->pf[i].name);
+ get_dynamic_uld_dev_name(dev, SERVICE_T_PPA,
+ info->pf[i].name);
}
}
if (hinic3_func_for_mgmt(fun_hwdev))
strscpy(info->pf[i].name, "FOR_MGMT", IFNAMSIZ);
- if (dev->lld_dev.pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID)
+ if (dev->lld_dev.pdev->subsystem_device ==
+ BIFUR_RESOURCE_PF_SSID)
strscpy(info->pf[i].name, "bifur", IFNAMSIZ);
strscpy(info->pf[i].bus_info, pci_name(dev->pcidev),
@@ -721,6 +883,7 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
struct card_node *chip_node = NULL;
unsigned char i;
unsigned char bus_number = 0;
+ int err;
if (chip_node_is_exist(pci_adapter, &bus_number))
return 0;
@@ -746,7 +909,10 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
/* bus number */
chip_node->bus_num = bus_number;
- if (snprintf(chip_node->chip_name, IFNAMSIZ, "%s%u", HINIC3_CHIP_NAME, i) < 0) {
+ snprintf(chip_node->chip_name, IFNAMSIZ, "%s%u", HINIC3_CHIP_NAME, i);
+
+ err = sscanf(chip_node->chip_name, HINIC3_CHIP_NAME "%d", &(chip_node->chip_id));
+ if (err <= 0) {
clear_bit(i, &card_bit_map);
kfree(chip_node);
return -EINVAL;
@@ -803,3 +969,36 @@ int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *
return 0;
}
+
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin)
+{
+ struct card_node *chip_node = NULL;
+ struct card_mbox_cnt_info *info = (struct card_mbox_cnt_info *)bufin;
+ struct hinic3_pcidev *dev = NULL;
+ struct hinic3_hwdev *func_hwdev = NULL;
+ u32 i = 0;
+
+ info->func_num = 0;
+ chip_node = hinic3_get_chip_node_by_hwdev(hwdev);
+ if (chip_node == NULL)
+ return;
+
+ lld_hold();
+
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ func_hwdev = (struct hinic3_hwdev *)dev->hwdev;
+ strscpy(info->func_info[i].bus_info, pci_name(dev->pcidev),
+ sizeof(info->func_info[i].bus_info));
+
+ info->func_info[i].send_cnt = func_hwdev->mbox_send_cnt;
+ info->func_info[i].ack_cnt = func_hwdev->mbox_ack_cnt;
+ info->func_num++;
+ i = info->func_num;
+ if (i >= ARRAY_SIZE(info->func_info)) {
+ sdk_err(&dev->pcidev->dev, "chip_node->func_list bigger than pf_max + vf_max\n");
+ break;
+ }
+ }
+
+ lld_put();
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
index 5c7c7cd..9815082 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
@@ -22,8 +22,13 @@
#define BIFUR_RESOURCE_PF_SSID 0x05a1
-#define HINIC3_IS_VF_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_VF)
-#define HINIC3_IS_SPU_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_SPU)
+#define HINIC3_IS_VF_DEV(pdev) \
+ ((pdev)->device == HINIC3_DEV_ID_VF || \
+ (pdev)->device == HINIC3_DEV_SDI_5_1_ID_VF)
+#define HINIC3_IS_SPU_DEV(pdev) \
+ (((pdev)->device == HINIC3_DEV_ID_SPU) || \
+ ((pdev)->device == HINIC3_DEV_ID_SDI_5_0_PF) || \
+ (((pdev)->device == HINIC3_DEV_ID_DPU_PF)))
enum {
HINIC3_NOT_PROBE = 1,
@@ -79,6 +84,13 @@ struct hinic3_pcidev {
u16 probe_fault_level;
u16 rsvd2;
u64 rsvd4;
+
+ struct workqueue_struct *multi_host_mgmt_workq;
+ struct work_struct slave_nic_work;
+ struct work_struct slave_vroce_work;
+
+ struct workqueue_struct *migration_probe_workq;
+ struct delayed_work migration_probe_dwork;
};
struct hinic_chip_info {
@@ -104,4 +116,6 @@ void wait_lld_dev_unused(struct hinic3_pcidev *pci_adapter);
void *hinic3_get_hwdev_by_pcidev(struct pci_dev *pdev);
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
index 11561a0..59ff722 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
@@ -101,7 +101,8 @@ static bool check_image_device_type(struct hinic3_hwdev *hwdev, u32 device_type)
static void encapsulate_update_cmd(struct hinic3_cmd_update_firmware *msg,
struct firmware_section *section_info,
- int *remain_len, u32 *send_len, u32 *send_pos)
+ const int *remain_len, u32 *send_len,
+ u32 *send_pos)
{
memset(msg->data, 0, sizeof(msg->data));
msg->ctl_info.sf = (*remain_len == section_info->section_len) ? true : false;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
index 937d699..be7c82b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
@@ -26,6 +26,8 @@
#include "hinic3_prof_adap.h"
#include "hinic3_eqs.h"
+#include "vram_common.h"
+
#define HINIC3_EQS_WQ_NAME "hinic3_eqs"
#define AEQ_CTRL_0_INTR_IDX_SHIFT 0
@@ -66,7 +68,6 @@
#define HINIC3_TASK_PROCESS_EQE_LIMIT 1024
#define HINIC3_EQ_UPDATE_CI_STEP 64
-/*lint -e806*/
static uint g_aeq_len = HINIC3_DEFAULT_AEQ_LEN;
module_param(g_aeq_len, uint, 0444);
MODULE_PARM_DESC(g_aeq_len,
@@ -83,7 +84,6 @@ static uint g_num_ceqe_in_tasklet = HINIC3_TASK_PROCESS_EQE_LIMIT;
module_param(g_num_ceqe_in_tasklet, uint, 0444);
MODULE_PARM_DESC(g_num_ceqe_in_tasklet,
"The max number of ceqe can be processed in tasklet, default = 1024");
-/*lint +e806*/
#define CEQ_CTRL_0_INTR_IDX_SHIFT 0
#define CEQ_CTRL_0_DMA_ATTR_SHIFT 12
@@ -819,18 +819,22 @@ static int alloc_eq_pages(struct hinic3_eq *eq)
u32 reg, init_val;
u16 pg_idx, i;
int err;
+ gfp_t gfp_vram;
eq->eq_pages = kcalloc(eq->num_pages, sizeof(*eq->eq_pages),
GFP_KERNEL);
if (!eq->eq_pages)
return -ENOMEM;
+ gfp_vram = hi_vram_get_gfp_vram();
+
for (pg_idx = 0; pg_idx < eq->num_pages; pg_idx++) {
eq_page = &eq->eq_pages[pg_idx];
err = hinic3_dma_zalloc_coherent_align(eq->hwdev->dev_hdl,
eq->page_size,
HINIC3_MIN_EQ_PAGE_SIZE,
- GFP_KERNEL, eq_page);
+ GFP_KERNEL | gfp_vram,
+ eq_page);
if (err) {
sdk_err(eq->hwdev->dev_hdl, "Failed to alloc eq page, page index: %u\n",
pg_idx);
@@ -881,6 +885,7 @@ static void free_eq_pages(struct hinic3_eq *eq)
&eq->eq_pages[pg_idx]);
kfree(eq->eq_pages);
+ eq->eq_pages = NULL;
}
static inline u32 get_page_size(const struct hinic3_eq *eq)
@@ -1120,7 +1125,8 @@ int hinic3_aeqs_init(struct hinic3_hwdev *hwdev, u16 num_aeqs,
hwdev->aeqs = aeqs;
aeqs->hwdev = hwdev;
aeqs->num_aeqs = num_aeqs;
- aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME, WQ_MEM_RECLAIM,
+ aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME,
+ WQ_MEM_RECLAIM | WQ_HIGHPRI,
HINIC3_MAX_AEQS);
if (!aeqs->workq) {
sdk_err(hwdev->dev_hdl, "Failed to initialize aeq workqueue\n");
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
index a4cbac8..6b96b87 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
@@ -82,6 +82,48 @@ int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id,
return 0;
}
+/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read and clear to zero
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
+ u16 *value)
+{
+ struct chipif_sml_ctr_rd_req req;
+ union ctr_rd_rsp rsp;
+ int ret;
+
+ if (!hwdev || !value)
+ return -EFAULT;
+
+ if (!COMM_SUPPORT_API_CHAIN((struct hinic3_hwdev *)hwdev))
+ return -EPERM;
+
+ memset(&req, 0, sizeof(req));
+
+ hinic3_sml_ctr_read_build_req(&req, instance,
+ CHIPIF_SM_CTR_OP_READ_CLEAR,
+ CHIPIF_ACK, ctr_id, 0);
+
+ ret = hinic3_api_cmd_read_ack(hwdev, node, (u8 *)&req,
+ (unsigned short)sizeof(req),
+ (void *)&rsp,
+ (unsigned short)sizeof(rsp));
+ if (ret) {
+ sdk_err(((struct hinic3_hwdev *)hwdev)->dev_hdl,
+ "Sm 16bit counter clear fail, err(%d)\n", ret);
+ return ret;
+ }
+ sml_ctr_htonl_n((u32 *)&rsp, sizeof(rsp) / sizeof(u32));
+ *value = rsp.bs_ss16_rsp.value1;
+
+ return 0;
+}
+
/**
* hinic3_sm_ctr_rd32 - small single 32 counter read
* @hwdev: the hardware device
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
index 030ef6d..5a8d2a4 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
@@ -34,13 +34,18 @@ static void parse_pub_res_cap_dfx(struct hinic3_hwdev *hwdev,
cap->max_vf);
sdk_info(hwdev->dev_hdl, "Host_pf_num: 0x%x, pf_id_start: 0x%x, host_vf_num: 0x%x, vf_id_start: 0x%x\n",
cap->pf_num, cap->pf_id_start, cap->vf_num, cap->vf_id_start);
- sdk_info(hwdev->dev_hdl, "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x\n",
- cap->host_valid_bitmap, cap->master_host_id, cap->srv_multi_host_mode);
sdk_info(hwdev->dev_hdl,
- "fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
- cap->fake_vf_start_id, cap->fake_vf_num, cap->fake_vf_max_pctx);
- sdk_info(hwdev->dev_hdl, "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x\n",
- cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len);
+ "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x, hot_plug_disable: 0x%x\n",
+ cap->host_valid_bitmap, cap->master_host_id,
+ cap->srv_multi_host_mode, cap->hot_plug_disable);
+ sdk_info(hwdev->dev_hdl,
+ "os_hot_replace: 0x%x, fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
+ cap->os_hot_replace, cap->fake_vf_start_id,
+ cap->fake_vf_num, cap->fake_vf_max_pctx);
+ sdk_info(hwdev->dev_hdl,
+ "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x, bond_create_mode: 0x%x\n",
+ cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len,
+ cap->bond_create_mode);
}
static void parse_cqm_res_cap(struct hinic3_hwdev *hwdev, struct service_cap *cap,
@@ -109,6 +114,9 @@ static void parse_pub_res_cap(struct hinic3_hwdev *hwdev,
cap->host_valid_bitmap = dev_cap->host_valid_bitmap;
cap->master_host_id = dev_cap->master_host_id;
cap->srv_multi_host_mode = dev_cap->srv_multi_host_mode;
+ cap->hot_plug_disable = dev_cap->hot_plug_disable;
+ cap->bond_create_mode = dev_cap->bond_create_mode;
+ cap->os_hot_replace = dev_cap->os_hot_replace;
cap->fake_vf_en = dev_cap->fake_vf_en;
cap->fake_vf_start_bit = dev_cap->fake_vf_start_bit;
cap->fake_vf_end_bit = dev_cap->fake_vf_end_bit;
@@ -148,18 +156,27 @@ static void parse_l2nic_res_cap(struct hinic3_hwdev *hwdev,
nic_cap->max_sqs = dev_cap->nic_max_sq_id + 1;
nic_cap->max_rqs = dev_cap->nic_max_rq_id + 1;
nic_cap->default_num_queues = dev_cap->nic_default_num_queues;
+ nic_cap->outband_vlan_cfg_en = dev_cap->outband_vlan_cfg_en;
+ nic_cap->lro_enable = dev_cap->lro_enable;
sdk_info(hwdev->dev_hdl, "L2nic resource capbility, max_sqs: 0x%x, max_rqs: 0x%x\n",
nic_cap->max_sqs, nic_cap->max_rqs);
/* Check parameters from firmware */
- if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP ||
- nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
- sdk_info(hwdev->dev_hdl, "Number of qp exceed limit[1-%d]: sq: %u, rq: %u\n",
- HINIC3_CFG_MAX_QP, nic_cap->max_sqs, nic_cap->max_rqs);
+ if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of sq exceed limit[1-%d]: sq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_sqs);
nic_cap->max_sqs = HINIC3_CFG_MAX_QP;
+ }
+
+ if (nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of rq exceed limit[1-%d]: rq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_rqs);
nic_cap->max_rqs = HINIC3_CFG_MAX_QP;
}
+
+ if (nic_cap->outband_vlan_cfg_en)
+ sdk_info(hwdev->dev_hdl, "L2nic outband vlan cfg enabled\n");
}
static void parse_fc_res_cap(struct hinic3_hwdev *hwdev,
@@ -333,6 +350,28 @@ static void parse_ipsec_res_cap(struct hinic3_hwdev *hwdev,
dev_cap->ipsec_max_sactx, dev_cap->ipsec_max_cq);
}
+static void parse_vbs_res_cap(struct hinic3_hwdev *hwdev,
+ struct service_cap *cap,
+ struct cfg_cmd_dev_cap *dev_cap,
+ enum func_type type)
+{
+ struct vbs_service_cap *vbs_cap = &cap->vbs_cap;
+
+ vbs_cap->vbs_max_volq = dev_cap->vbs_max_volq;
+ vbs_cap->vbs_main_pf_enable = dev_cap->vbs_main_pf_enable;
+ vbs_cap->vbs_vsock_pf_enable = dev_cap->vbs_vsock_pf_enable;
+ vbs_cap->vbs_fushion_queue_pf_enable = dev_cap->vbs_fushion_queue_pf_enable;
+
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS resource capbility, vbs_max_volq: 0x%x\n",
+ dev_cap->vbs_max_volq);
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS pf info, vbs_main_pf_enable: 0x%x, vbs_vsock_pf_enable: 0x%x, vbs_fushion_queue_pf_enable: 0x%x\n",
+ dev_cap->vbs_main_pf_enable,
+ dev_cap->vbs_vsock_pf_enable,
+ dev_cap->vbs_fushion_queue_pf_enable);
+}
+
static void parse_dev_cap(struct hinic3_hwdev *dev,
struct cfg_cmd_dev_cap *dev_cap, enum func_type type)
{
@@ -375,6 +414,9 @@ static void parse_dev_cap(struct hinic3_hwdev *dev,
if (IS_PPA_TYPE(dev))
parse_ppa_res_cap(dev, cap, dev_cap, type);
+
+ if (IS_VBS_TYPE(dev))
+ parse_vbs_res_cap(dev, cap, dev_cap, type);
}
static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
@@ -404,6 +446,23 @@ static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
return 0;
}
+u8 hinic3_get_bond_create_mode(void *dev)
+{
+ struct hinic3_hwdev *hwdev = NULL;
+ struct service_cap *cap = NULL;
+
+ if (!dev) {
+ pr_err("pointer dev is NULL\n");
+ return -EINVAL;
+ }
+
+ hwdev = (struct hinic3_hwdev *)dev;
+ cap = &hwdev->cfg_mgmt->svc_cap;
+
+ return cap->bond_create_mode;
+}
+EXPORT_SYMBOL(hinic3_get_bond_create_mode);
+
int hinic3_get_dev_cap(void *dev)
{
enum func_type type;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
index 671eed6..2f2310a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
@@ -166,6 +166,11 @@ struct service_cap {
u8 srv_multi_host_mode;
u16 virtio_vq_size;
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 os_hot_replace;
+ u8 rsvd1;
+
u8 timer_pf_num;
u8 timer_pf_id_start;
u16 timer_vf_num;
@@ -335,5 +340,7 @@ void free_capability(struct hinic3_hwdev *dev);
int hinic3_init_vf_dev_cap(void *hwdev);
+u8 hinic3_get_bond_create_mode(void *dev);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
index 8a87d25..cb3b609 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
@@ -21,6 +21,7 @@
#include "hinic3_hw_cfg.h"
#include "hinic3_cmdq.h"
#include "mpu_inband_cmd_defs.h"
+#include "vram_common.h"
#include "hinic3_hw_comm.h"
#define HINIC3_MSIX_CNT_LLI_TIMER_SHIFT 0
@@ -242,12 +243,19 @@ int hinic3_func_reset(void *dev, u16 func_id, u64 reset_flag, u16 channel)
struct hinic3_hwdev *hwdev = dev;
u16 out_size = sizeof(func_reset);
int err = 0;
+ int is_in_kexec;
if (!dev) {
pr_err("Invalid para: dev is null.\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ sdk_info(hwdev->dev_hdl, "Skip function reset!\n");
+ return 0;
+ }
+
sdk_info(hwdev->dev_hdl, "Function is reset, flag: 0x%llx, channel:0x%x\n",
reset_flag, channel);
@@ -554,7 +562,7 @@ EXPORT_SYMBOL(hinic3_set_ppf_flr_type);
int hinic3_set_ppf_tbl_hotreplace_flag(void *hwdev, u8 flag)
{
- struct comm_cmd_ppf_tbl_htrp_config htr_info = {0};
+ struct comm_cmd_ppf_tbl_htrp_config htr_info = {};
u16 out_size = sizeof(struct comm_cmd_ppf_tbl_htrp_config);
struct hinic3_hwdev *dev = hwdev;
int ret;
@@ -899,11 +907,19 @@ static int set_ppf_tmr_status(struct hinic3_hwdev *hwdev,
int hinic3_ppf_tmr_start(void *hwdev)
{
+ int is_in_kexec;
+
if (!hwdev) {
pr_err("Hwdev pointer is NULL for starting ppf timer\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ pr_info("Skip starting ppt timer during kexec");
+ return 0;
+ }
+
return set_ppf_tmr_status(hwdev, HINIC_PPF_TMR_FLAG_START);
}
EXPORT_SYMBOL(hinic3_ppf_tmr_start);
@@ -919,18 +935,114 @@ int hinic3_ppf_tmr_stop(void *hwdev)
}
EXPORT_SYMBOL(hinic3_ppf_tmr_stop);
+static int hi_vram_kalloc_align(struct hinic3_hwdev *hwdev, char *name, u32 page_size, u32 page_num,
+ struct hinic3_dma_addr_align *mem_align)
+{
+ void *vaddr = NULL, *align_vaddr = NULL;
+ dma_addr_t paddr, align_paddr;
+ u64 real_size = page_size;
+ u64 align = page_size;
+
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ /* align */
+ if (align_paddr == paddr) {
+ align_vaddr = vaddr;
+ goto out;
+ }
+
+ hi_vram_kfree((void *)vaddr, name, real_size);
+
+ /* realloc memory for align */
+ real_size = page_size + align;
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc align failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ align_vaddr = (void *)((u64)vaddr + (align_paddr - paddr));
+
+out:
+ mem_align->real_size = (u32)real_size;
+ mem_align->ori_vaddr = vaddr;
+ mem_align->ori_paddr = paddr;
+ mem_align->align_vaddr = align_vaddr;
+ mem_align->align_paddr = align_paddr;
+
+ return 0;
+}
+
+static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
+{
+ u32 i;
+ struct hinic3_dma_addr_align *page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = hwdev->mqm_eqm_vram_name;
+
+ page_addr = hwdev->mqm_att.brm_srch_page_addr;
+
+ for (i = 0; i < hwdev->mqm_att.page_num; i++) {
+ if (is_use_vram != 0) {
+ hi_vram_kfree(page_addr->ori_vaddr, mqm_eqm_vram_name[i].vram_name,
+ page_addr->real_size);
+ } else {
+ hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
+ }
+ page_addr->ori_vaddr = NULL;
+ page_addr++;
+ }
+
+ kfree(mqm_eqm_vram_name);
+ hwdev->mqm_eqm_vram_name = NULL;
+}
+
static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
u32 page_num)
{
struct hinic3_dma_addr_align *page_addr = hwdev->mqm_att.brm_srch_page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = NULL;
u32 valid_num = 0;
u32 flag = 1;
u32 i = 0;
int err;
+ u16 func_id;
+
+ mqm_eqm_vram_name = kcalloc(page_num, sizeof(struct mqm_eqm_vram_name_s), GFP_KERNEL);
+ if (mqm_eqm_vram_name == NULL) {
+ sdk_err(hwdev->dev_hdl, "mqm eqm alloc vram name failed.\n");
+ return -ENOMEM;
+ }
+
+ hwdev->mqm_eqm_vram_name = mqm_eqm_vram_name;
+ func_id = hinic3_global_func_id(hwdev);
for (i = 0; i < page_num; i++) {
- err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl, page_size,
- page_size, GFP_KERNEL, page_addr);
+ if (is_use_vram != 0) {
+ snprintf(mqm_eqm_vram_name[i].vram_name,
+ VRAM_NAME_MAX_LEN, "%s%hu%s%u",
+ VRAM_CQM_GLB_FUNC_BASE, func_id,
+ VRAM_NIC_MQM, i);
+ err = hi_vram_kalloc_align(hwdev,
+ mqm_eqm_vram_name[i].vram_name,
+ page_size, page_num,
+ page_addr);
+ } else {
+ err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl,
+ page_size,
+ page_size,
+ GFP_KERNEL,
+ page_addr);
+ }
if (err) {
flag = 0;
break;
@@ -939,15 +1051,12 @@ static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
page_addr++;
}
+ hwdev->mqm_att.page_num = valid_num;
+
if (flag == 1) {
hwdev->mqm_att.page_size = page_size;
- hwdev->mqm_att.page_num = page_num;
} else {
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
- for (i = 0; i < valid_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
+ mqm_eqm_free_page_mem(hwdev);
return -EFAULT;
}
@@ -986,19 +1095,6 @@ static int mqm_eqm_alloc_page_mem(struct hinic3_hwdev *hwdev)
return ret;
}
-static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
-{
- u32 i;
- struct hinic3_dma_addr_align *page_addr;
-
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
-
- for (i = 0; i < hwdev->mqm_att.page_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
-}
-
static int mqm_eqm_set_cfg_2_hw(struct hinic3_hwdev *hwdev, u8 valid)
{
struct comm_cmd_eqm_cfg info_eqm_cfg;
@@ -1129,6 +1225,7 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
{
struct comm_cmd_get_eqm_num info_eqm_fix;
int ret;
+ int is_in_kexec;
if (hwdev->hwif->attr.func_type != TYPE_PPF)
return 0;
@@ -1158,10 +1255,16 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
goto err_page;
}
- ret = mqm_eqm_set_page_2_hw(hwdev);
- if (ret) {
- sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
- goto err_ecmd;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ ret = mqm_eqm_set_page_2_hw(hwdev);
+ if (ret) {
+ sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
+ goto err_ecmd;
+ }
+ } else {
+ sdk_info(hwdev->dev_hdl,
+ "Mqm db don't set to chip when os hot replace.\r\n");
}
ret = mqm_eqm_set_cfg_2_hw(hwdev, 1);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
index e8aa7ef..722fecd 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
@@ -252,97 +252,6 @@ static u32 get_up_timeout_val(enum hinic3_mod_type mod, u16 cmd)
return 0; /* use default mbox/apichain timeout time */
}
-static int api_csr_read(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
-{
- struct up_log_msg_st *up_log_msg = (struct up_log_msg_st *)buf_in;
- u8 *buf_out_tmp = (u8 *)buf_out;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
-
- if (!buf_in || !buf_out || in_size != sizeof(*up_log_msg) ||
- *out_size != up_log_msg->rd_len || up_log_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = up_log_msg->rd_len;
- rd_addr = up_log_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_rd32(hwdev, node_id,
- rd_addr + offset,
- (u32 *)(buf_out_tmp + offset));
- if (ret) {
- pr_err("Csr rd fail, err: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, node_id, rd_addr + offset);
- return ret;
- }
- offset += DW_WIDTH;
- }
- *out_size = rd_len;
-
- return ret;
-}
-
-static int api_csr_write(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out,
- u32 *out_size)
-{
- struct csr_write_st *csr_write_msg = (struct csr_write_st *)buf_in;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
- u8 *data = NULL;
-
- if (!buf_in || in_size != sizeof(*csr_write_msg) || csr_write_msg->rd_len == 0 ||
- csr_write_msg->rd_len > API_CSR_MAX_RD_LEN || csr_write_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = csr_write_msg->rd_len;
- rd_addr = csr_write_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- data = kzalloc(rd_len, GFP_KERNEL);
- if (!data)
- return -EFAULT;
-
- if (copy_from_user(data, (void *)csr_write_msg->data, rd_len)) {
- pr_err("Copy information from user failed\n");
- kfree(data);
- return -EFAULT;
- }
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_wr32(hwdev, node_id,
- rd_addr + offset,
- *((u32 *)(data + offset)));
- if (ret) {
- pr_err("Csr wr fail, ret: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, rd_addr + offset, node_id);
- kfree(data);
- return ret;
- }
- offset += DW_WIDTH;
- }
-
- *out_size = 0;
- kfree(data);
- return ret;
-}
-
int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
@@ -369,10 +278,8 @@ int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
return ret;
}
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_BYPASS) {
- if (nt_msg->mpu_cmd.cmd == API_CSR_WRITE)
- return api_csr_write(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
-
- ret = api_csr_read(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
+ pr_err("Unsupported api_type %u\n", nt_msg->mpu_cmd.api_type);
+ return -EINVAL;
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_TO_MPU) {
timeout = get_up_timeout_val(mod, cmd);
if (hinic3_pcie_itf_id(hwdev) != SPU_HOST_ID)
@@ -439,6 +346,23 @@ static int sm_rd16(void *hwdev, u32 id, u8 instance,
return ret;
}
+static int sm_rd16_clear(void *hwdev, u32 id, u8 instance,
+ u8 node, struct sm_out_st *buf_out)
+{
+ u16 val1;
+ int ret;
+
+ ret = hinic3_sm_ctr_rd16_clear(hwdev, node, instance, id, &val1);
+ if (ret != 0) {
+ pr_err("Get sm ctr clear information (16 bits)failed!\n");
+ val1 = 0xffff;
+ }
+
+ buf_out->val1 = val1;
+
+ return ret;
+}
+
static int sm_rd32(void *hwdev, u32 id, u8 instance,
u8 node, struct sm_out_st *buf_out)
{
@@ -558,6 +482,7 @@ const struct sm_module_handle sm_module_cmd_handle[] = {
{SM_CTR_RD32, sm_rd32},
{SM_CTR_RD64_PAIR, sm_rd64_pair},
{SM_CTR_RD64, sm_rd64},
+ {SM_CTR_RD16_CLEAR, sm_rd16_clear},
{SM_CTR_RD32_CLEAR, sm_rd32_clear},
{SM_CTR_RD64_PAIR_CLEAR, sm_rd64_pair_clear},
{SM_CTR_RD64_CLEAR, sm_rd64_clear}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
index 83e7b63..c317f4a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
@@ -101,6 +101,12 @@ enum hinic3_pcie_tph {
#define SLAVE_HOST_STATUS_SET(host_id, enable) (((u8)(enable) & 1U) << (host_id))
#define SLAVE_HOST_STATUS_GET(host_id, val) (!!((val) & (1U << (host_id))))
+#ifdef HAVE_HOT_REPLACE_FUNC
+ extern int get_partition_id(void);
+#else
+ static int get_partition_id(void) {return 0; }
+#endif
+
void set_slave_host_enable(void *hwdev, u8 host_id, bool enable)
{
u32 reg_val;
@@ -207,6 +213,27 @@ static void hinic3_init_host_mode_pre(struct hinic3_hwdev *hwdev)
}
}
+static void hinic3_init_hot_plug_status(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->hot_plug_disable)
+ hwdev->hot_plug_mode = HOT_PLUG_DISABLE;
+ else
+ hwdev->hot_plug_mode = HOT_PLUG_ENABLE;
+}
+
+static void hinic3_init_os_hot_replace(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->os_hot_replace) {
+ hwdev->hot_replace_mode = HOT_REPLACE_ENABLE;
+ } else {
+ hwdev->hot_replace_mode = HOT_REPLACE_DISABLE;
+ }
+}
+
static u8 hinic3_nic_sw_aeqe_handler(void *hwdev, u8 event, u8 *data)
{
struct hinic3_hwdev *dev = hwdev;
@@ -270,14 +297,20 @@ static void chip_fault_show(struct hinic3_hwdev *hwdev,
"fatal", "reset", "host", "flr", "general", "suggestion"};
char level_str[FAULT_SHOW_STR_LEN + 1];
u8 level;
+ int ret;
memset(level_str, 0, FAULT_SHOW_STR_LEN + 1);
level = event->event.chip.err_level;
- if (level < FAULT_LEVEL_MAX)
- strscpy(level_str, fault_level[level],
- FAULT_SHOW_STR_LEN);
- else
- strscpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (level < FAULT_LEVEL_MAX) {
+ ret = strscpy(level_str, fault_level[level],
+ FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ } else {
+ ret = strscpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ }
if (level == FAULT_LEVEL_SERIOUS_FLR)
dev_err(hwdev->dev_hdl, "err_level: %u [%s], flr func_id: %u\n",
@@ -299,6 +332,7 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
"reg rd timeout", "reg wr timeout", "phy fault", "tsensor fault"};
char type_str[FAULT_SHOW_STR_LEN + 1] = {0};
struct fault_event_stats *fault = NULL;
+ int ret;
sdk_err(hwdev->dev_hdl, "Fault event report received, func_id: %u\n",
hinic3_global_func_id(hwdev));
@@ -306,10 +340,14 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
fault = &hwdev->hw_stats.fault_event_stats;
if (event->type < FAULT_TYPE_MAX) {
- strscpy(type_str, fault_type[event->type], sizeof(type_str));
+ ret = strscpy(type_str, fault_type[event->type], sizeof(type_str));
+ if (ret < 0)
+ return;
atomic_inc(&fault->fault_type_stat[event->type]);
} else {
- strscpy(type_str, "Unknown", sizeof(type_str));
+ ret = strscpy(type_str, "Unknown", sizeof(type_str));
+ if (ret < 0)
+ return;
}
sdk_err(hwdev->dev_hdl, "Fault type: %u [%s]\n", event->type, type_str);
@@ -1536,15 +1574,29 @@ int hinic3_init_hwdev(struct hinic3_init_para *para)
hinic3_init_host_mode_pre(hwdev);
+ hinic3_init_hot_plug_status(hwdev);
+
+ hinic3_init_os_hot_replace(hwdev);
+
err = hinic3_multi_host_mgmt_init(hwdev);
if (err != 0) {
sdk_err(hwdev->dev_hdl, "Failed to init function mode\n");
goto init_multi_host_fail;
}
- err = hinic3_init_ppf_work(hwdev);
- if (err != 0)
- goto init_ppf_work_fail;
+ // hot_replace_mode is enable, run ppf function only when partition_id is 0
+ // or run ppf function directly
+ if (hwdev->hot_replace_mode == HOT_REPLACE_ENABLE) {
+ if (get_partition_id() == 0) {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0)
+ goto init_ppf_work_fail;
+ }
+ } else {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0)
+ goto init_ppf_work_fail;
+ }
err = hinic3_set_comm_features(hwdev, hwdev->features, COMM_MAX_FEATURE_QWORD);
if (err != 0) {
@@ -1948,6 +2000,19 @@ void hinic3_link_event_stats(void *dev, u8 link)
}
EXPORT_SYMBOL(hinic3_link_event_stats);
+int hinic3_get_link_event_stats(void *dev, int *link_state)
+{
+ struct hinic3_hwdev *hwdev = dev;
+
+ if (!hwdev || !link_state)
+ return -EINVAL;
+
+ *link_state = hwdev->hw_stats.link_event_stats.link_down_stats.counter;
+
+ return 0;
+}
+EXPORT_SYMBOL(hinic3_get_link_event_stats);
+
u8 hinic3_max_pf_num(void *hwdev)
{
if (!hwdev)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
index b8a3356..0ca639f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
@@ -10,6 +10,7 @@
#include "hinic3_hw.h"
#include "mpu_inband_cmd_defs.h"
#include "hinic3_profile.h"
+#include "vram_common.h"
struct cfg_mgmt_info;
@@ -82,6 +83,22 @@ enum hinic3_host_mode_e {
HINIC3_SDI_MODE_MAX,
};
+enum hinic3_hot_plug_mode {
+ HOT_PLUG_ENABLE,
+ HOT_PLUG_DISABLE,
+};
+
+enum hinic3_os_hot_replace_mode {
+ HOT_REPLACE_DISABLE,
+ HOT_REPLACE_ENABLE,
+};
+
+#define UNSUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_DISABLE)
+
+#define SUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_ENABLE)
+
#define MULTI_HOST_CHIP_MODE_SHIFT 0
#define MULTI_HOST_MASTER_MBX_STS_SHIFT 17
#define MULTI_HOST_PRIV_DATA_SHIFT 0x8
@@ -100,6 +117,10 @@ enum hinic3_host_mode_e {
((val) & (~(MULTI_HOST_##member##_MASK \
<< MULTI_HOST_##member##_SHIFT)))
+struct mqm_eqm_vram_name_s {
+ char vram_name[VRAM_NAME_MAX_LEN];
+};
+
struct hinic3_hwdev {
void *adapter_hdl; /* pointer to hinic3_pcidev or NDIS_Adapter */
void *pcidev_hdl; /* pointer to pcidev or Handler */
@@ -138,6 +159,9 @@ struct hinic3_hwdev {
u32 rsvd2;
struct hinic3_multi_host_mgmt *mhost_mgmt;
+ char mhost_mgmt_name[VRAM_NAME_MAX_LEN];
+
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name;
struct mutex stateful_mutex; /* protect cqm init and deinit */
@@ -170,6 +194,8 @@ struct hinic3_hwdev {
struct hinic3_devlink *devlink_dev;
enum hinic3_func_mode func_mode;
+ enum hinic3_hot_plug_mode hot_plug_mode;
+ enum hinic3_os_hot_replace_mode hot_replace_mode;
u32 rsvd3;
DECLARE_BITMAP(func_probe_in_host, MAX_FUNCTION_NUM);
@@ -179,7 +205,10 @@ struct hinic3_hwdev {
u64 last_recv_aeq_cnt;
u16 aeq_busy_cnt;
- u64 rsvd4[8];
+ u64 mbox_send_cnt;
+ u64 mbox_ack_cnt;
+
+ u64 rsvd4[5];
u8 cmdq_mode;
};
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
index 33f1210..8590f70 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
@@ -544,6 +544,7 @@ static void free_db_area(struct hinic3_free_db_area *free_db_area)
{
spin_lock_deinit(&free_db_area->idx_lock);
kfree(free_db_area->db_bitmap_array);
+ free_db_area->db_bitmap_array = NULL;
}
static int get_db_idx(struct hinic3_hwif *hwif, u32 *idx)
@@ -841,6 +842,7 @@ void hinic3_free_hwif(struct hinic3_hwdev *hwdev)
free_db_area(&hwdev->hwif->free_db_area);
enable_all_msix(hwdev);
kfree(hwdev->hwif);
+ hwdev->hwif = NULL;
}
u16 hinic3_global_func_id(void *hwdev)
@@ -856,6 +858,44 @@ u16 hinic3_global_func_id(void *hwdev)
}
EXPORT_SYMBOL(hinic3_global_func_id);
+/**
+ * get function id from register,used by sriov hot migration process
+ * @hwdev: the pointer to hw device
+ */
+u16 hinic3_global_func_id_hw(void *hwdev)
+{
+ u32 addr, attr0;
+ struct hinic3_hwdev *dev;
+
+ dev = (struct hinic3_hwdev *)hwdev;
+ addr = HINIC3_CSR_FUNC_ATTR0_ADDR;
+ attr0 = hinic3_hwif_read_reg(dev->hwif, addr);
+
+ return HINIC3_AF0_GET(attr0, FUNC_GLOBAL_IDX);
+}
+
+/**
+ * get function id, used by sriov hot migratition process.
+ * @hwdev: the pointer to hw device
+ * @func_id: function id
+ */
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id)
+{
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)hwdev;
+
+ if (!hwdev || !func_id)
+ return -EINVAL;
+
+ /* only vf get func_id from chip reg for sriov migrate */
+ if (!HINIC3_IS_VF(dev)) {
+ *func_id = hinic3_global_func_id(hwdev);
+ return 0;
+ }
+
+ *func_id = hinic3_global_func_id_hw(dev);
+ return 0;
+}
+
u16 hinic3_intr_num(void *hwdev)
{
struct hinic3_hwif *hwif = NULL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
index 6ab1b92..6650572 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
@@ -16,6 +16,7 @@
#include <linux/rtc.h>
#include <linux/aer.h>
#include <linux/debugfs.h>
+#include <linux/notifier.h>
#include "ossl_knl.h"
#include "hinic3_mt.h"
@@ -26,13 +27,38 @@
#include "hinic3_dev_mgmt.h"
#include "hinic3_nictool.h"
#include "hinic3_hw.h"
+#include "hinic3_multi_host_mgmt.h"
+#include "hinic3_hw_cfg.h"
#include "hinic3_lld.h"
#include "hinic3_profile.h"
#include "hinic3_hwdev.h"
#include "hinic3_prof_adap.h"
-#include "comm_msg_intf.h"
+#include "hinic3_devlink.h"
+#include "vram_common.h"
+
+enum partition_dev_type {
+ PARTITION_DEV_NONE = 0,
+ PARTITION_DEV_SHARED,
+ PARTITION_DEV_EXCLUSIVE,
+ PARTITION_DEV_BACKUP,
+};
+
+#ifdef HAVE_HOT_REPLACE_FUNC
+static int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type,
+ unsigned int partition_id);
+static int get_partition_id(void);
+#else
+static int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type,
+ unsigned int partition_id)
+{
+ return 0;
+}
+static int get_partition_id(void) { return 0; }
+#endif
+
+static bool g_is_pf_migrated;
static bool disable_vf_load;
module_param(disable_vf_load, bool, 0444);
MODULE_PARM_DESC(disable_vf_load,
@@ -44,10 +70,12 @@ MODULE_PARM_DESC(disable_attach, "disable_attach or not - default is false");
#define HINIC3_WAIT_SRIOV_CFG_TIMEOUT 15000
-MODULE_AUTHOR("Huawei Technologies CO., Ltd");
-MODULE_DESCRIPTION(HINIC3_DRV_DESC);
-MODULE_VERSION(HINIC3_DRV_VERSION);
-MODULE_LICENSE("GPL");
+#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
+static DEVICE_ATTR_RW(sriov_numvfs, 0644,
+ sriov_numvfs_show, sriov_numvfs_store);
+static DEVICE_ATTR_RO(sriov_totalvfs, 0444,
+ sriov_totalvfs_show, NULL);
+#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
static struct attribute *hinic3_attributes[] = {
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
@@ -64,7 +92,18 @@ static const struct attribute_group hinic3_attr_group = {
struct hinic3_uld_info g_uld_info[SERVICE_T_MAX] = { {0} };
#define HINIC3_EVENT_PROCESS_TIMEOUT 10000
+#define HINIC3_WAIT_EVENT_PROCESS_TIMEOUT 100
struct mutex g_uld_mutex; /* g_uld_info lock */
+#define BUS_MAX_DEV_NUM 256
+#define HINIC3_SLAVE_WORK_MAX_NUM 20
+
+struct vf_offset_info {
+ u8 valid;
+ u16 vf_offset_from_pf[CMD_MAX_MAX_PF_NUM];
+};
+
+static struct vf_offset_info g_vf_offset;
+DEFINE_MUTEX(g_vf_offset_lock);
void hinic3_uld_lock_init(void)
{
@@ -73,13 +112,23 @@ void hinic3_uld_lock_init(void)
static const char *s_uld_name[SERVICE_T_MAX] = {
"nic", "ovs", "roce", "toe", "ioe",
- "fc", "vbs", "ipsec", "virtio", "migrate", "ppa", "bifur", "custom"};
+ "fc", "vbs", "ipsec", "virtio", "migrate",
+ "ppa", "custom", "vroce", "crypt", "vsock", "bifur"};
const char **hinic3_get_uld_names(void)
{
return s_uld_name;
}
+#ifdef CONFIG_PCI_IOV
+static int hinic3_get_pf_device_id(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_dev = pci_physfn(pdev);
+
+ return pf_dev->device;
+}
+#endif
+
static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
const struct hinic3_uld_info *uld_info)
{
@@ -98,6 +147,10 @@ static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
atomic_set(&dev->uld_ref_cnt[type], 0);
+ if (!uld_info->probe) {
+ err = 0;
+ goto out_unlock;
+ }
err = uld_info->probe(&dev->lld_dev, &uld_dev, dev->uld_dev_name[type]);
if (err) {
sdk_err(&dev->pcidev->dev,
@@ -166,6 +219,10 @@ static void detach_uld(struct hinic3_pcidev *dev,
wait_uld_unused(dev, type);
+ if (!uld_info->remove) {
+ mutex_unlock(&dev->pdev_mutex);
+ return;
+ }
uld_info->remove(&dev->lld_dev, dev->uld_dev[type]);
dev->uld_dev[type] = NULL;
@@ -182,11 +239,14 @@ static void attach_ulds(struct hinic3_pcidev *dev)
{
enum hinic3_service_type type;
struct pci_dev *pdev = dev->pcidev;
+ int is_in_kexec = vram_get_kexec_flag();
+
+ if (is_in_kexec == 0)
+ lld_hold();
- lld_hold();
mutex_lock(&g_uld_mutex);
- for (type = SERVICE_T_NIC; type < SERVICE_T_MAX; type++) {
+ for (type = SERVICE_T_OVS; type < SERVICE_T_MAX; type++) {
if (g_uld_info[type].probe) {
if (pdev->is_virtfn &&
(!hinic3_get_vf_service_load(pdev, (u16)type))) {
@@ -198,7 +258,9 @@ static void attach_ulds(struct hinic3_pcidev *dev)
}
}
mutex_unlock(&g_uld_mutex);
- lld_put();
+
+ if (is_in_kexec == 0)
+ lld_put();
}
static void detach_ulds(struct hinic3_pcidev *dev)
@@ -305,7 +367,7 @@ void hinic3_unregister_uld(enum hinic3_service_type type)
}
uld_info = &g_uld_info[type];
- memset(uld_info, 0, sizeof(*uld_info));
+ memset(uld_info, 0, sizeof(struct hinic3_uld_info));
mutex_unlock(&g_uld_mutex);
lld_put();
}
@@ -359,6 +421,26 @@ void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_ser
}
EXPORT_SYMBOL(hinic3_detach_service);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ __module_get(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_get);
+
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ module_put(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_put);
+
static void hinic3_sync_time_to_fmw(struct hinic3_pcidev *pdev_pri)
{
struct timeval tv = {0};
@@ -441,23 +523,447 @@ static void send_event_to_all_pf(struct hinic3_pcidev *dev,
lld_put();
}
+u32 hinic3_pdev_is_virtfn(struct pci_dev *pdev)
+{
+#ifdef CONFIG_PCI_IOV
+ return pdev->is_virtfn;
+#else
+ return 0;
+#endif
+}
+
+static int hinic3_get_function_enable(struct pci_dev *pdev, bool *en)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+ int err;
+
+ /* PF in host os or function in guest os, probe sdk in default */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev) {
+ *en = true;
+ return 0;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev) {
+ /* vf in host and pf sdk not probed */
+ return -EFAULT;
+ }
+ pf_hwdev = pci_adapter->hwdev;
+
+ err = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (err) {
+ sdk_err(&pci_adapter->pcidev->dev,
+ "Func hinic3_get_vfid_by_vfpci fail %d\n", err);
+ return err;
+ }
+
+ err = hinic3_get_func_nic_enable(pf_hwdev, global_func_id, en);
+ if (!!err) {
+ sdk_info(&pdev->dev, "Failed to get function nic status, err %d.\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+int hinic3_set_func_probe_in_host(void *hwdev, u16 func_id, bool probe)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (hinic3_func_type(hwdev) != TYPE_PPF)
+ return -EINVAL;
+
+ if (probe)
+ set_bit(func_id, dev->func_probe_in_host);
+ else
+ clear_bit(func_id, dev->func_probe_in_host);
+
+ return 0;
+}
+
+bool hinic3_get_func_probe_in_host(void *hwdev, u16 func_id)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+ bool probed = false;
+
+ if (!hwdev)
+ return false;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return false;
+ }
+
+ probed = !!test_bit(func_id, ppf_dev->func_probe_in_host);
+ up(&dev->ppf_sem);
+
+ return probed;
+}
+
+void *hinic3_get_ppf_hwdev_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ chip_node = pci_adapter->chip_node;
+ lld_dev_hold(&pci_adapter->lld_dev);
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (dev->lld_state == HINIC3_IN_REMOVE)
+ continue;
+
+ if (dev->hwdev && hinic3_func_type(dev->hwdev) == TYPE_PPF) {
+ lld_dev_put(&pci_adapter->lld_dev);
+ return dev->hwdev;
+ }
+ }
+ lld_dev_put(&pci_adapter->lld_dev);
+
+ return NULL;
+}
+
+static int hinic3_set_vf_nic_used_state(void *hwdev, u16 func_id, bool opened)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+
+ if (!dev || func_id >= MAX_FUNCTION_NUM)
+ return -EINVAL;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return -EINVAL;
+ }
+
+ if (opened)
+ set_bit(func_id, ppf_dev->netdev_setup_state);
+ else
+ clear_bit(func_id, ppf_dev->netdev_setup_state);
+
+ up(&dev->ppf_sem);
+
+ return 0;
+}
+
+static void set_vf_func_in_use(struct pci_dev *pdev, bool in_use)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+
+ /* only need to be set when VF is on the host */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev)
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev)
+ return;
+
+ pf_hwdev = pci_adapter->hwdev;
+
+ global_func_id = (u16)pdev->devfn + hinic3_glb_pf_vf_offset(pf_hwdev);
+ (void)hinic3_set_vf_nic_used_state(pf_hwdev, global_func_id, in_use);
+}
+
+
+static int hinic3_pf_get_vf_offset_info(struct hinic3_pcidev *des_dev, u16 *vf_offset)
+{
+ int err, i;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ u16 pf_func_id;
+ struct hinic3_pcidev *pf_pci_adapter = NULL;
+
+ pf_pci_adapter = (hinic3_pdev_is_virtfn(des_dev->pcidev)) ?
+ pci_get_drvdata(des_dev->pcidev->physfn) : des_dev;
+ pf_func_id = hinic3_global_func_id(pf_pci_adapter->hwdev);
+ if (pf_func_id >= CMD_MAX_MAX_PF_NUM || !vf_offset)
+ return -EINVAL;
+
+ mutex_lock(&g_vf_offset_lock);
+ if (g_vf_offset.valid == 0) {
+ pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ sdk_err(&pf_pci_adapter->pcidev->dev, "Malloc pf_infos fail\n");
+ err = -ENOMEM;
+ goto err_malloc;
+ }
+
+ err = hinic3_get_hw_pf_infos(pf_pci_adapter->hwdev,
+ pf_infos, HINIC3_CHANNEL_COMM);
+ if (err) {
+ sdk_warn(&pf_pci_adapter->pcidev->dev,
+ "Hinic3_get_hw_pf_infos fail err %d\n", err);
+ err = -EFAULT;
+ goto err_out;
+ }
+
+ g_vf_offset.valid = 1;
+ for (i = 0; i < CMD_MAX_MAX_PF_NUM; i++)
+ g_vf_offset.vf_offset_from_pf[i] = pf_infos->infos[i].vf_offset;
+
+ kfree(pf_infos);
+ }
+
+ *vf_offset = g_vf_offset.vf_offset_from_pf[pf_func_id];
+
+ mutex_unlock(&g_vf_offset_lock);
+
+ return 0;
+
+err_out:
+ kfree(pf_infos);
+err_malloc:
+ mutex_unlock(&g_vf_offset_lock);
+ return err;
+}
+
+static struct pci_dev *get_vf_pdev_by_pf(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ int err;
+ u16 bus_num;
+ u16 vf_start, vf_end;
+ u16 des_fn, pf_func_id, vf_offset;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ pf_func_id = hinic3_global_func_id(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end || pf_func_id >= CMD_MAX_MAX_PF_NUM)
+ return NULL;
+
+ err = hinic3_pf_get_vf_offset_info(des_dev, &vf_offset);
+ if (err) {
+ sdk_warn(&des_dev->pcidev->dev, "Hinic3_pf_get_vf_offset_info fail\n");
+ return NULL;
+ }
+
+ des_fn = ((func_id - vf_start) - 1) + pf_func_id + vf_offset;
+ bus_num = des_dev->pcidev->bus->number + des_fn / BUS_MAX_DEV_NUM;
+
+ return pci_get_domain_bus_and_slot(0, bus_num, (des_fn % BUS_MAX_DEV_NUM));
+}
+
+static struct hinic3_pcidev *get_des_pci_adapter(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ struct pci_dev *des_pdev = NULL;
+ u16 vf_start, vf_end;
+ bool probe_in_host = false;
+
+ if (hinic3_global_func_id(des_dev->hwdev) == func_id)
+ return des_dev;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end)
+ return NULL;
+
+ des_pdev = get_vf_pdev_by_pf(des_dev, func_id);
+ if (!des_pdev)
+ return NULL;
+
+ pci_dev_put(des_pdev);
+
+ probe_in_host = hinic3_get_func_probe_in_host(des_dev->hwdev, func_id);
+ if (!probe_in_host)
+ return NULL;
+
+ return pci_get_drvdata(des_pdev);
+}
+
+int __set_vroce_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ u8 enable_vroce = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_vroce_enable(pci_adapter->hwdev,
+ func_id, &enable_vroce);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Failed to get vroce state.\n");
+ return err;
+ }
+
+ mutex_lock(&g_uld_mutex);
+
+ if (!!enable_vroce) {
+ if (!g_uld_info[SERVICE_T_ROCE].probe) {
+ sdk_info(&pdev->dev, "Uld(roce_info) has not been registered!\n");
+ mutex_unlock(&g_uld_mutex);
+ return 0;
+ }
+
+ err = attach_uld(pci_adapter, SERVICE_T_ROCE,
+ &g_uld_info[SERVICE_T_ROCE]);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Failed to initialize VROCE.\n");
+ mutex_unlock(&g_uld_mutex);
+ return err;
+ }
+ } else {
+ sdk_info(&pdev->dev, "Func %u vroce state: disable.\n", func_id);
+ if (g_uld_info[SERVICE_T_ROCE].remove)
+ detach_uld(pci_adapter, SERVICE_T_ROCE);
+ }
+
+ mutex_unlock(&g_uld_mutex);
+
+ return 0;
+}
+
+void slave_host_mgmt_vroce_work(struct work_struct *work)
+{
+#ifndef __HIFC__
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_vroce_work);
+
+ __set_vroce_func_state(pci_adapter);
+#endif
+}
+
+void *hinic3_get_roce_uld_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ return pci_adapter->uld_dev[SERVICE_T_ROCE];
+}
+
+static int func_service_state_process(struct hinic3_pcidev *event_dev,
+ struct hinic3_pcidev *des_dev,
+ struct hinic3_mhost_nic_func_state *state,
+ u16 cmd)
+{
+ int err = 0;
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)event_dev->hwdev;
+
+ switch (cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ state->enable = hinic3_get_roce_uld_by_pdev(des_dev->pcidev) ? 1 : 0;
+ break;
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive nic[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ if (event_dev->multi_host_mgmt_workq) {
+ queue_work(event_dev->multi_host_mgmt_workq,
+ &des_dev->slave_nic_work);
+ } else {
+ sdk_err(&des_dev->pcidev->dev, "Can not schedule slave nic work\n");
+ err = -EFAULT;
+ }
+ break;
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive vroce[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ queue_work_on(hisdk3_get_work_cpu_affinity(dev, WORK_TYPE_MBOX),
+ event_dev->multi_host_mgmt_workq,
+ &des_dev->slave_vroce_work);
+ break;
+ default:
+ sdk_warn(&des_dev->pcidev->dev,
+ "Service state process with unknown cmd: %u\n", cmd);
+ err = -EFAULT;
+ break;
+ }
+
+ return err;
+}
+
+static void multi_host_mgmt(struct hinic3_pcidev *dev,
+ struct hinic3_multi_host_mgmt_event *mhost_mgmt)
+{
+ struct hinic3_pcidev *cur_dev = NULL;
+ struct hinic3_pcidev *des_dev = NULL;
+ struct hinic3_mhost_nic_func_state *nic_state = NULL;
+ u16 sub_cmd = mhost_mgmt->sub_cmd;
+
+ switch (sub_cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ nic_state = mhost_mgmt->data;
+ nic_state->status = 0;
+ if (!dev->hwdev)
+ return;
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)dev->hwdev))
+ return;
+
+ /* find func_idx pci_adapter and disable or enable nic */
+ lld_dev_hold(&dev->lld_dev);
+ list_for_each_entry(cur_dev, &dev->chip_node->func_list, node) {
+ if (cur_dev->lld_state == HINIC3_IN_REMOVE ||
+ hinic3_pdev_is_virtfn(cur_dev->pcidev))
+ continue;
+
+ des_dev = get_des_pci_adapter(cur_dev, nic_state->func_idx);
+ if (!des_dev)
+ continue;
+
+ if (func_service_state_process(dev, des_dev, nic_state, sub_cmd))
+ nic_state->status = 1;
+ break;
+ }
+ lld_dev_put(&dev->lld_dev);
+ break;
+ default:
+ sdk_warn(&dev->pcidev->dev, "Received unknown multi-host mgmt event: %u\n",
+ mhost_mgmt->sub_cmd);
+ break;
+ }
+}
+
static void hinic3_event_process(void *adapter, struct hinic3_event_info *event)
{
struct hinic3_pcidev *dev = adapter;
struct hinic3_fault_event *fault = (void *)event->event_data;
+ struct hinic3_multi_host_mgmt_event *mhost_event =
+ (void *)event->event_data;
u16 func_id;
- if ((event->service == EVENT_SRV_COMM && event->type == EVENT_COMM_FAULT) &&
- fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
- fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
- func_id = fault->event.chip.func_id;
- return send_event_to_dst_pf(adapter, func_id, event);
- }
-
- if (event->type == EVENT_COMM_MGMT_WATCHDOG)
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MULTI_HOST_MGMT):
+ multi_host_mgmt(dev, mhost_event);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_FAULT):
+ if (fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
+ fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
+ func_id = fault->event.chip.func_id;
+ return send_event_to_dst_pf(adapter, func_id, event);
+ }
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MGMT_WATCHDOG):
send_event_to_all_pf(adapter, event);
- else
+ break;
+ default:
send_uld_dev_event(adapter, event);
+ break;
+ }
}
static void uld_def_init(struct hinic3_pcidev *pci_adapter)
@@ -605,31 +1111,70 @@ static void hinic3_pci_deinit(struct pci_dev *pdev)
kfree(pci_adapter);
}
-#ifdef CONFIG_X86
-/**
- * cfg_order_reg - when cpu model is haswell or broadwell, should configure dma
- * order register to zero
- * @pci_adapter: pci_adapter
- **/
-/*lint -save -e40 */
-static void cfg_order_reg(struct hinic3_pcidev *pci_adapter)
+static void set_vf_load_state(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
{
- u8 cpu_model[] = {0x3c, 0x3f, 0x45, 0x46, 0x3d, 0x47, 0x4f, 0x56};
- struct cpuinfo_x86 *cpuinfo = NULL;
- u32 i;
+ /* In bm mode, slave host will load vfs in default */
+ if (IS_BMGW_SLAVE_HOST(((struct hinic3_hwdev *)pci_adapter->hwdev)) &&
+ hinic3_func_type(pci_adapter->hwdev) != TYPE_VF)
+ hinic3_set_vf_load_state(pdev, false);
- if (hinic3_func_type(pci_adapter->hwdev) == TYPE_VF)
- return;
+ if (!disable_attach) {
+ if ((hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) &&
+ hinic3_is_bm_slave_host(pci_adapter->hwdev)) {
+ if (hinic3_func_max_vf(pci_adapter->hwdev) == 0) {
+ sdk_warn(&pdev->dev, "The sriov enabling process is skipped, vfs_num: 0.\n");
+ return;
+ }
+ hinic3_pci_sriov_enable(
+ pdev, hinic3_func_max_vf(pci_adapter->hwdev));
+ }
+ }
+}
- cpuinfo = &cpu_data(0);
- for (i = 0; i < sizeof(cpu_model); i++) {
- if (cpu_model[i] == cpuinfo->x86_model)
- hinic3_set_pcie_order_cfg(pci_adapter->hwdev);
+static void hinic3_init_ppf_hwdev(struct hinic3_hwdev *hwdev)
+{
+ if (!hwdev) {
+ pr_err("[%s:%d] null hwdev pointer\n", __FILE__, __LINE__);
+ return;
}
+
+ hwdev->ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(hwdev->pcidev_hdl);
}
-/*lint -restore*/
-#endif
+static int set_nic_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ bool enable_nic = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_nic_enable(pci_adapter->hwdev, func_id, &enable_nic);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Failed to get nic state.\n");
+ return err;
+ }
+
+ if (!enable_nic) {
+ sdk_info(&pdev->dev, "Func %u nic state: disable.\n", func_id);
+ detach_uld(pci_adapter, SERVICE_T_NIC);
+ return 0;
+ }
+
+ if (IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ (void)hinic3_init_vf_dev_cap(pci_adapter->hwdev);
+
+ if (g_uld_info[SERVICE_T_NIC].probe) {
+ err = attach_uld(pci_adapter, SERVICE_T_NIC, &g_uld_info[SERVICE_T_NIC]);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Initialize NIC failed\n");
+ return err;
+ }
+ }
+
+ return 0;
+}
static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
{
@@ -689,7 +1234,16 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
list_add_tail(&pci_adapter->node, &pci_adapter->chip_node->func_list);
lld_unlock_chip_node();
+ hinic3_init_ppf_hwdev((struct hinic3_hwdev *)pci_adapter->hwdev);
+
+ set_vf_load_state(pdev, pci_adapter);
+
if (!disable_attach) {
+ /* NIC is base driver, probe firstly */
+ err = set_nic_func_state(pci_adapter);
+ if (err)
+ goto set_nic_func_state_err;
+
attach_ulds(pci_adapter);
if (hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) {
@@ -700,10 +1254,6 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
goto create_sysfs_err;
}
}
-
-#ifdef CONFIG_X86
- cfg_order_reg(pci_adapter);
-#endif
}
return 0;
@@ -711,6 +1261,8 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
create_sysfs_err:
detach_ulds(pci_adapter);
+
+set_nic_func_state_err:
lld_lock_chip_node();
list_del(&pci_adapter->node);
lld_unlock_chip_node();
@@ -759,6 +1311,7 @@ static void hinic3_func_deinit(struct pci_dev *pdev)
hinic3_free_stateful(pci_adapter->hwdev);
hinic3_free_hwdev(pci_adapter->hwdev);
+ pci_adapter->hwdev = NULL;
}
static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
@@ -770,14 +1323,57 @@ static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
clear_bit(HINIC3_FUNC_PERSENT, &sriov_info->state);
usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- end = jiffies + msecs_to_jiffies(HINIC3_WAIT_SRIOV_CFG_TIMEOUT);
- do {
- if (!test_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state) &&
- !test_bit(HINIC3_SRIOV_DISABLE, &sriov_info->state))
- return;
+ end = jiffies + msecs_to_jiffies(HINIC3_WAIT_SRIOV_CFG_TIMEOUT);
+ do {
+ if (!test_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state) &&
+ !test_bit(HINIC3_SRIOV_DISABLE, &sriov_info->state))
+ return;
+
+ usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
+ } while (time_before(jiffies, end));
+}
+
+static bool hinic3_get_vf_nic_en_status(struct pci_dev *pdev)
+{
+ bool nic_en = false;
+ u16 global_func_id;
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev) {
+ pr_err("pdev is null.\n");
+ return false;
+ }
+
+ if (pdev->is_virtfn)
+ pf_pdev = pdev->physfn;
+ else
+ return false;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return false;
+ }
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ return false;
+
+ if (hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id)) {
+ sdk_err(&pdev->dev, "Get vf id by vfpci failed\n");
+ return false;
+ }
+
+ if (hinic3_get_mhost_func_nic_enable(pci_adapter->hwdev,
+ global_func_id, &nic_en)) {
+ sdk_err(&pdev->dev, "Get function nic status failed\n");
+ return false;
+ }
+
+ sdk_info(&pdev->dev, "Func %hu %s default probe in host\n",
+ global_func_id, (nic_en) ? "enable" : "disable");
- usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- } while (time_before(jiffies, end));
+ return nic_en;
}
bool hinic3_get_vf_load_state(struct pci_dev *pdev)
@@ -834,6 +1430,8 @@ int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state)
}
EXPORT_SYMBOL(hinic3_set_vf_load_state);
+
+
bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service)
{
struct hinic3_pcidev *pci_adapter = NULL;
@@ -897,6 +1495,32 @@ int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
}
EXPORT_SYMBOL(hinic3_set_vf_service_load);
+static bool hinic3_is_host_vmsec_enable(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct pci_dev *pf_pdev = NULL;
+
+ if (pdev->is_virtfn)
+ pf_pdev = pdev->physfn;
+ else
+ pf_pdev = pdev;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ pr_err("Pci_adapter is null.\n");
+ return false;
+ }
+
+ /* pf/vf used in host */
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ (hinic3_func_type(pci_adapter->hwdev) == TYPE_PF) &&
+ IS_RDMA_TYPE((struct hinic3_hwdev *)pci_adapter->hwdev)) {
+ return true;
+ }
+
+ return false;
+}
+
static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
@@ -910,6 +1534,13 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
pci_adapter->lld_state = HINIC3_IN_REMOVE;
mutex_unlock(&pci_adapter->pdev_mutex);
+ if (!(pdev->is_virtfn) && (hinic3_is_host_vmsec_enable(pdev) == true) &&
+ (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF)) {
+ cancel_delayed_work_sync(&pci_adapter->migration_probe_dwork);
+ flush_workqueue(pci_adapter->migration_probe_workq);
+ destroy_workqueue(pci_adapter->migration_probe_workq);
+ }
+
hinic3_detect_hw_present(pci_adapter->hwdev);
hisdk3_remove_pre_process(pci_adapter->hwdev);
@@ -934,23 +1565,128 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
sdk_info(&pdev->dev, "Pcie device removed function\n");
+ set_vf_func_in_use(pdev, false);
+
return 0;
}
+int hinic3_get_vfid_by_vfpci(void *hwdev, struct pci_dev *pdev, u16 *global_func_id)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ u16 pf_bus, vf_bus, vf_offset;
+ int err;
+
+ if (!pdev || !global_func_id || !hinic3_pdev_is_virtfn(pdev))
+ return -EINVAL;
+ (void)hwdev;
+ pf_pdev = pdev->physfn;
+
+ vf_bus = pdev->bus->number;
+ pf_bus = pf_pdev->bus->number;
+
+ if (pdev->vendor == HINIC3_VIRTIO_VNEDER_ID)
+ return -EPERM;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return -EINVAL;
+ }
+
+ err = hinic3_pf_get_vf_offset_info(pci_adapter, &vf_offset);
+ if (err) {
+ sdk_err(&pdev->dev, "Func hinic3_pf_get_vf_offset_info fail\n");
+ return -EFAULT;
+ }
+
+ *global_func_id = (u16)((vf_bus - pf_bus) * BUS_MAX_DEV_NUM) + (u16)pdev->devfn +
+ (u16)(CMD_MAX_MAX_PF_NUM - g_vf_offset.vf_offset_from_pf[0]);
+
+ return 0;
+}
+EXPORT_SYMBOL(hinic3_get_vfid_by_vfpci);
+
+static void hinic3_set_vf_status_in_host(struct pci_dev *pdev, bool status)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ void *ppf_hwdev = NULL;
+ u16 global_func_id;
+ int ret;
+
+ if (!pf_pdev)
+ return;
+
+ if (!hinic3_pdev_is_virtfn(pdev))
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ pf_hwdev = pci_adapter->hwdev;
+ ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(pf_pdev);
+ if (!pf_hwdev || !ppf_hwdev)
+ return;
+
+ ret = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (ret) {
+ sdk_err(&pci_adapter->pcidev->dev,
+ "Func hinic3_get_vfid_by_vfpci fail %d\n", ret);
+ return;
+ }
+
+ ret = hinic3_set_func_probe_in_host(ppf_hwdev, global_func_id, status);
+ if (ret)
+ sdk_err(&pci_adapter->pcidev->dev,
+ "Set the function probe status in host failed\n");
+}
+
+#ifdef CONFIG_PCI_IOV
+/* Check whether pdev is a VF and whether it belongs to the PF of the SDI card */
+static bool check_pdev_type_and_state(struct pci_dev *pdev)
+{
+ if (!(pdev->is_virtfn))
+ return false;
+
+ if ((hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_1_PF) &&
+ (hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_0_PF)) {
+ return false;
+ }
+
+ if (!hinic3_get_vf_load_state(pdev))
+ return false;
+
+ return true;
+}
+#endif
+
static void hinic3_remove(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
+ sdk_info(&pdev->dev, "Pcie device remove begin\n");
+
if (!pci_adapter)
- return;
+ goto out;
- sdk_info(&pdev->dev, "Pcie device remove begin\n");
+
+#ifdef CONFIG_PCI_IOV
+ if (check_pdev_type_and_state(pdev))
+ goto out;
+#endif
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
hinic3_remove_func(pci_adapter);
+ if (!pci_adapter->pcidev->is_virtfn &&
+ pci_adapter->multi_host_mgmt_workq)
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
hinic3_pci_deinit(pdev);
hinic3_probe_pre_unprocess(pdev);
+out:
+ hinic3_set_vf_status_in_host(pdev, false);
sdk_info(&pdev->dev, "Pcie device removed\n");
}
@@ -969,7 +1705,7 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
if (pci_adapter->lld_state >= HINIC3_PROBE_START) {
sdk_warn(&pdev->dev, "Don not probe repeat\n");
mutex_unlock(&pci_adapter->pdev_mutex);
- return 0;
+ return -EEXIST;
}
pci_adapter->lld_state = HINIC3_PROBE_START;
mutex_unlock(&pci_adapter->pdev_mutex);
@@ -977,15 +1713,28 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
return 0;
}
+static void hinic3_probe_success_process(struct hinic3_pcidev *pci_adapter)
+{
+ hinic3_probe_success(pci_adapter->hwdev);
+
+ mutex_lock(&pci_adapter->pdev_mutex);
+ pci_adapter->lld_state = HINIC3_PROBE_OK;
+ mutex_unlock(&pci_adapter->pdev_mutex);
+}
+
static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
int err;
err = probe_func_param_init(pci_adapter);
- if (err)
+ if (err == -EEXIST)
+ return 0;
+ else if (err)
return err;
+ set_vf_func_in_use(pdev, true);
+
err = mapping_bar(pdev, pci_adapter);
if (err) {
sdk_err(&pdev->dev, "Failed to map bar\n");
@@ -1017,11 +1766,7 @@ static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
}
}
- hinic3_probe_success(pci_adapter->hwdev);
-
- mutex_lock(&pci_adapter->pdev_mutex);
- pci_adapter->lld_state = HINIC3_PROBE_OK;
- mutex_unlock(&pci_adapter->pdev_mutex);
+ hinic3_probe_success_process(pci_adapter);
return 0;
@@ -1037,18 +1782,298 @@ alloc_chip_node_fail:
unmapping_bar(pci_adapter);
map_bar_failed:
+ set_vf_func_in_use(pdev, false);
sdk_err(&pdev->dev, "Pcie device probe function failed\n");
return err;
}
+void hinic3_set_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int err;
+ bool enable_func = false;
+
+ err = hinic3_get_function_enable(pdev, &enable_func);
+ if (err) {
+ sdk_info(&pdev->dev, "Get function enable failed\n");
+ return;
+ }
+
+ sdk_info(&pdev->dev, "%s function resource start\n",
+ enable_func ? "Initialize" : "Free");
+ if (enable_func) {
+ err = hinic3_probe_func(pci_adapter);
+ if (err)
+ sdk_info(&pdev->dev, "Function probe failed\n");
+ } else {
+ hinic3_remove_func(pci_adapter);
+ }
+ if (err == 0)
+ sdk_info(&pdev->dev, "%s function resource end\n",
+ enable_func ? "Initialize" : "Free");
+}
+
+void slave_host_mgmt_work(struct work_struct *work)
+{
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_nic_work);
+
+ if (hinic3_pdev_is_virtfn(pci_adapter->pcidev))
+ hinic3_set_func_state(pci_adapter);
+ else
+ set_nic_func_state(pci_adapter);
+}
+
+static int pci_adapter_assign_val(struct hinic3_pcidev **ppci_adapter,
+ struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ *ppci_adapter = pci_get_drvdata(pdev);
+ (*ppci_adapter)->disable_vf_load = disable_vf_load;
+ (*ppci_adapter)->id = *id;
+ (*ppci_adapter)->lld_state = HINIC3_NOT_PROBE;
+ (*ppci_adapter)->probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ lld_dev_cnt_init(*ppci_adapter);
+
+ (*ppci_adapter)->multi_host_mgmt_workq = alloc_workqueue(
+ "hinic_mhost_mgmt",
+ WQ_UNBOUND,
+ HINIC3_SLAVE_WORK_MAX_NUM);
+ if (!(*ppci_adapter)->multi_host_mgmt_workq) {
+ hinic3_pci_deinit(pdev);
+ sdk_err(&pdev->dev, "Alloc multi host mgmt workqueue failed\n");
+ return -ENOMEM;
+ }
+
+ INIT_WORK(&(*ppci_adapter)->slave_nic_work, slave_host_mgmt_work);
+ INIT_WORK(&(*ppci_adapter)->slave_vroce_work,
+ slave_host_mgmt_vroce_work);
+
+ return 0;
+}
+
+static void slave_host_vfio_probe_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_pcidev *pci_adapter = container_of(delay, struct hinic3_pcidev,
+ migration_probe_dwork);
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int (*dev_migration_probe)(struct pci_dev *pdev);
+ int rc;
+
+ if (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) != TYPE_PF)
+ return;
+
+ dev_migration_probe = __symbol_get("migration_dev_migration_probe");
+ if (!(dev_migration_probe)) {
+ sdk_err(&pdev->dev,
+ "Failed to find: migration_dev_migration_probe");
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork,
+ WAIT_TIME * HZ);
+ } else {
+ rc = dev_migration_probe(pdev);
+ __symbol_put("migration_dev_migration_probe");
+ if (rc) {
+ sdk_err(&pdev->dev,
+ "Failed to __dev_migration_probe, rc:0x%x, pf migrated(%d).\n",
+ rc, g_is_pf_migrated);
+ } else {
+ g_is_pf_migrated = true;
+ sdk_info(&pdev->dev,
+ "Succeeded in __dev_migration_probe, pf migrated(%d).\n",
+ g_is_pf_migrated);
+ }
+ }
+}
+
+struct vf_add_delaywork {
+ struct pci_dev *vf_pdev;
+ struct delayed_work migration_vf_add_dwork;
+};
+
+static void slave_host_migration_vf_add_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct vf_add_delaywork *vf_add = container_of(delay, struct vf_add_delaywork,
+ migration_vf_add_dwork);
+ struct pci_dev *vf_pdev = vf_add->vf_pdev;
+ struct pci_dev *pf_pdev = NULL;
+ int (*migration_dev_add_vf)(struct pci_dev *vf_pdev);
+ int ret;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!vf_pdev) {
+ pr_err("vf pdev is null.\n");
+ goto err1;
+ }
+ if (!vf_pdev->is_virtfn) {
+ sdk_err(&vf_pdev->dev, "Pdev is not virtfn.\n");
+ goto err1;
+ }
+
+ pf_pdev = vf_pdev->physfn;
+ if (!pf_pdev) {
+ sdk_err(&vf_pdev->dev, "pf_pdev is null.\n");
+ goto err1;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&vf_pdev->dev, "Pci_adapter is null.\n");
+ goto err1;
+ }
+
+ if (!g_is_pf_migrated) {
+ sdk_info(&vf_pdev->dev, "pf is not migrated yet, so vf continues to try again.\n");
+ goto delay_work;
+ }
+
+ migration_dev_add_vf = __symbol_get("migration_dev_add_vf");
+ if (migration_dev_add_vf) {
+ ret = migration_dev_add_vf(vf_pdev);
+ __symbol_put("migration_dev_add_vf");
+ if (ret)
+ sdk_err(&vf_pdev->dev, "vf get migration symbol succeeded, but dev add vf failed, ret:%d.\n",
+ ret);
+ else
+ sdk_info(&vf_pdev->dev, "vf get migration symbol succeeded, and dev add vf success.\n");
+ goto err1;
+ }
+ sdk_info(&vf_pdev->dev, "pf is migrated, but vf get migration symbol failed.\n");
+
+delay_work:
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork, WAIT_TIME * HZ);
+ return;
+
+err1:
+ kfree(vf_add);
+}
+
+static void hinic3_probe_vf_add_dwork(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!hinic3_is_host_vmsec_enable(pdev))
+ return;
+
+#if defined(CONFIG_SP_VID_DID)
+ if ((pdev->vendor == PCI_VENDOR_ID_SPNIC) && (pdev->device == HINIC3_DEV_SDI_5_1_ID_VF)) {
+#elif defined(CONFIG_NF_VID_DID)
+ if ((pdev->vendor == PCI_VENDOR_ID_NF) && (pdev->device == NFNIC_DEV_ID_VF)) {
+#else
+ if ((pdev->vendor == PCI_VENDOR_ID_HUAWEI) && (pdev->device == HINIC3_DEV_SDI_5_0_ID_VF)) {
+#endif
+ struct vf_add_delaywork *vf_add = kmalloc(sizeof(struct vf_add_delaywork),
+ GFP_ATOMIC);
+
+ if (!vf_add) {
+ sdk_info(&pdev->dev, "vf_add is null.\n");
+ return;
+ }
+ vf_add->vf_pdev = pdev;
+
+ pf_pdev = pdev->physfn;
+
+ if (!pf_pdev) {
+ sdk_info(&pdev->dev, "Vf-pf_pdev is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_info(&pdev->dev, "Pci_adapter is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ INIT_DELAYED_WORK(&vf_add->migration_vf_add_dwork,
+ slave_host_migration_vf_add_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork,
+ WAIT_TIME * HZ);
+ }
+}
+
+static int hinic3_probe_migration_dwork(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+{
+ if (!hinic3_is_host_vmsec_enable(pdev)) {
+ sdk_info(&pdev->dev, "Probe_migration : hinic3_is_host_vmsec_enable is (0).\n");
+ return 0;
+ }
+
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF) {
+ pci_adapter->migration_probe_workq =
+ create_singlethread_workqueue("hinic3_migration_probe_delay");
+ if (!pci_adapter->migration_probe_workq) {
+ sdk_err(&pdev->dev, "Failed to create work queue:%s\n",
+ "hinic3_migration_probe_delay");
+ return -EINVAL;
+ }
+
+ INIT_DELAYED_WORK(&pci_adapter->migration_probe_dwork,
+ slave_host_vfio_probe_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork, WAIT_TIME * HZ);
+ }
+
+ return 0;
+}
+
+static bool hinic3_os_hot_replace_allow(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_hwdev *hwdev = (struct hinic3_hwdev *)pci_adapter->hwdev;
+ // check service enable and dev is not VF
+ if (hinic3_func_type(hwdev) == TYPE_VF || hwdev->hot_replace_mode == HOT_REPLACE_DISABLE)
+ return false;
+
+ return true;
+}
+
+static bool hinic3_os_hot_replace_process(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_board_info *board_info;
+ u16 cur_pf_id = hinic3_global_func_id(pci_adapter->hwdev);
+ u8 cur_partion_id;
+
+ board_info = &((struct hinic3_hwdev *)(pci_adapter->hwdev))->board_info;
+ // probe to os
+ vpci_set_partition_attrs(pci_adapter->pcidev, PARTITION_DEV_EXCLUSIVE,
+ get_function_partition(cur_pf_id, board_info->port_num));
+
+ // check pf_id is in the right partition_id
+ cur_partion_id = get_partition_id();
+ if (get_function_partition(cur_pf_id, board_info->port_num) ==
+ cur_partion_id)
+ return true;
+
+ pci_adapter->probe_fault_level = FAULT_LEVEL_SUGGESTION;
+ return false;
+}
+
static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct hinic3_pcidev *pci_adapter = NULL;
u16 probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ u32 device_id, function_id;
int err;
sdk_info(&pdev->dev, "Pcie device probe begin\n");
+#ifdef CONFIG_PCI_IOV
+ hinic3_set_vf_status_in_host(pdev, true);
+ if (check_pdev_type_and_state(pdev)) {
+ sdk_info(&pdev->dev, "VFs are not binded to hinic\n");
+ hinic3_probe_vf_add_dwork(pdev);
+ return -EINVAL;
+ }
+#endif
+
err = hinic3_probe_pre_process(pdev);
if (err != 0 && err != HINIC3_NOT_PROBE)
goto out;
@@ -1060,26 +2085,48 @@ static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (err)
goto pci_init_err;
- pci_adapter = pci_get_drvdata(pdev);
- pci_adapter->disable_vf_load = disable_vf_load;
- pci_adapter->id = *id;
- pci_adapter->lld_state = HINIC3_NOT_PROBE;
- pci_adapter->probe_fault_level = probe_fault_level;
- lld_dev_cnt_init(pci_adapter);
+ err = pci_adapter_assign_val(&pci_adapter, pdev, id);
+ if (err)
+ goto allco_queue_err;
- if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev))) {
+ if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev)) &&
+ (!hinic3_get_vf_nic_en_status(pdev))) {
sdk_info(&pdev->dev, "VF device disable load in host\n");
return 0;
}
- err = hinic3_probe_func(pci_adapter);
- if (err)
+ if (hinic3_probe_func(pci_adapter))
+ goto hinic3_probe_func_fail;
+
+ if (hinic3_os_hot_replace_allow(pci_adapter)) {
+ if (!hinic3_os_hot_replace_process(pci_adapter)) {
+ device_id = PCI_SLOT(pdev->devfn);
+ function_id = PCI_FUNC(pdev->devfn);
+ sdk_info(&pdev->dev,
+ "os hot replace: skip function %d:%d for partition %d",
+ device_id, function_id, get_partition_id());
+ goto os_hot_repalce_not_allow;
+ }
+ }
+
+ if (hinic3_probe_migration_dwork(pdev, pci_adapter))
goto hinic3_probe_func_fail;
sdk_info(&pdev->dev, "Pcie device probed\n");
return 0;
+os_hot_repalce_not_allow:
+ hinic3_func_deinit(pdev);
+ lld_lock_chip_node();
+ free_chip_node(pci_adapter);
+ lld_unlock_chip_node();
+ unmapping_bar(pci_adapter);
+ set_vf_func_in_use(pdev, false);
hinic3_probe_func_fail:
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
+allco_queue_err:
probe_fault_level = pci_adapter->probe_fault_level;
hinic3_pci_deinit(pdev);
@@ -1105,6 +2152,11 @@ static int hinic3_get_pf_info(struct pci_dev *pdev, u16 service,
}
*pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (*pf_infos == NULL) {
+ sdk_err(&pdev->dev, "pf_infos kzalloc failed\n");
+ return -EFAULT;
+ }
+
err = hinic3_get_hw_pf_infos(dev->hwdev, *pf_infos, HINIC3_CHANNEL_COMM);
if (err) {
kfree(*pf_infos);
@@ -1120,6 +2172,7 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
{
int err;
+ mutex_lock(&dst_dev->pdev_mutex);
/* unload invalid vf func id */
if (!en && vf_func_id != hinic3_global_func_id(dst_dev->hwdev) &&
!strcmp(des_pdev->driver->name, HINIC3_DRV_NAME)) {
@@ -1137,6 +2190,8 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
err = hinic3_probe_func(dst_dev);
if (err)
return -EFAULT;
+ } else {
+ mutex_unlock(&dst_dev->pdev_mutex);
}
return 0;
@@ -1161,7 +2216,6 @@ static int get_vf_service_state_param(struct pci_dev *pdev, struct hinic3_pcidev
return 0;
}
-#define BUS_MAX_DEV_NUM 256
static int hinic3_dst_pdev_valid(struct hinic3_pcidev *dst_dev, struct pci_dev **des_pdev_ptr,
u16 vf_devfn, bool en)
{
@@ -1175,7 +2229,7 @@ static int hinic3_dst_pdev_valid(struct hinic3_pcidev *dst_dev, struct pci_dev
return -EFAULT;
}
- if (!(*des_pdev_ptr)->driver) {
+ if ((*des_pdev_ptr)->driver == NULL) {
pr_err("des_pdev_ptr->driver is NULL\n");
return -EFAULT;
}
@@ -1243,7 +2297,6 @@ int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id, u16 servic
if (en)
pci_dev_put(des_pdev);
- mutex_lock(&dst_dev->pdev_mutex);
find_dst_dev = true;
break;
}
@@ -1263,19 +2316,30 @@ free_pf_info:
}
EXPORT_SYMBOL(hinic3_set_vf_service_state);
-/*lint -save -e133 -e10*/
static const struct pci_device_id hinic3_pci_table[] = {
+#if defined(CONFIG_SP_VID_DID)
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_STANDARD), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_SDI_5_1_PF), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_SDI_5_0_PF), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_SPN120), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_VF), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_SDI_5_1_ID_VF), 0},
+#elif defined(CONFIG_NF_VID_DID)
+ {PCI_VDEVICE(NF, NFNIC_DEV_ID_STANDARD), 0},
+ {PCI_VDEVICE(NF, NFNIC_DEV_ID_VF), 0},
+#else
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SPU), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_STANDARD), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_1_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_SDI_5_1_ID_VF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_VF), 0},
+#endif
{0, 0}
};
-/*lint -restore*/
-
MODULE_DEVICE_TABLE(pci, hinic3_pci_table);
/**
@@ -1307,14 +2371,27 @@ static pci_ers_result_t hinic3_io_error_detected(struct pci_dev *pdev,
return PCI_ERS_RESULT_CAN_RECOVER;
}
+static void hinic3_timer_disable(void *hwdev)
+{
+ if (!hwdev)
+ return;
+
+ if (hinic3_get_stateful_enable(hwdev) && hinic3_get_timer_enable(hwdev))
+ (void)hinic3_func_tmr_bitmap_set(hwdev,
+ hinic3_global_func_id(hwdev),
+ false);
+}
+
static void hinic3_shutdown(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
sdk_info(&pdev->dev, "Shutdown device\n");
- if (pci_adapter)
+ if (pci_adapter) {
+ hinic3_timer_disable(pci_adapter->hwdev);
hinic3_shutdown_hwdev(pci_adapter->hwdev);
+ }
pci_disable_device(pdev);
@@ -1341,6 +2418,9 @@ static struct pci_driver hinic3_driver = {
.probe = hinic3_probe,
.remove = hinic3_remove,
.shutdown = hinic3_shutdown,
+#ifdef CONFIG_PARTITION_DEVICE
+ .driver.probe_concurrency = true,
+#endif
#if defined(HAVE_SRIOV_CONFIGURE)
.sriov_configure = hinic3_pci_sriov_configure,
#elif defined(HAVE_RHEL6_SRIOV_CONFIGURE)
@@ -1362,16 +2442,21 @@ int hinic3_lld_init(void)
err = hinic3_module_pre_init();
if (err) {
pr_err("Init custom failed\n");
- return err;
+ goto module_pre_init_err;
}
err = pci_register_driver(&hinic3_driver);
if (err) {
- hinic3_module_post_exit();
- return err;
+ pr_err("sdk3 pci register driver failed\n");
+ goto register_pci_driver_err;
}
return 0;
+
+register_pci_driver_err:
+ hinic3_module_post_exit();
+module_pre_init_err:
+ return err;
}
void hinic3_lld_exit(void)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
index b2851c6..3626262 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
@@ -584,6 +584,7 @@ static void free_recv_mbox(struct hinic3_recv_mbox *recv_msg)
kfree(recv_msg->resp_buff);
kfree(recv_msg->msg);
kfree(recv_msg);
+ recv_msg = NULL;
}
static void recv_func_mbox_work_handler(struct work_struct *work)
@@ -1232,6 +1233,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
set_mbox_to_func_event(func_to_func, EVENT_FAIL);
goto send_err;
}
+ func_to_func->hwdev->mbox_send_cnt++;
if (wait_mbox_msg_completion(func_to_func, timeout) != 0) {
sdk_err(func_to_func->hwdev->dev_hdl,
@@ -1240,6 +1242,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
err = -ETIMEDOUT;
goto send_err;
}
+ func_to_func->hwdev->mbox_ack_cnt++;
if (mod != msg_desc->mod || cmd != msg_desc->cmd) {
sdk_err(func_to_func->hwdev->dev_hdl,
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
index 2bd63f1..4718458 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
@@ -861,6 +861,7 @@ static int alloc_recv_msg(struct hinic3_recv_msg *recv_msg)
static void free_recv_msg(struct hinic3_recv_msg *recv_msg)
{
kfree(recv_msg->msg);
+ recv_msg->msg = NULL;
}
/**
@@ -932,6 +933,9 @@ static void free_msg_buf(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt)
free_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
+ pf_to_mgmt->mgmt_ack_buf = NULL;
+ pf_to_mgmt->sync_msg_buf = NULL;
+ pf_to_mgmt->async_msg_buf = NULL;
}
/**
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
index 3548410..a0f5e73 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
@@ -676,6 +676,9 @@ static int hinic3_register_slave_ppf(struct hinic3_hwdev *hwdev, bool registered
if (!IS_SLAVE_HOST(hwdev))
return -EINVAL;
+ if (UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev))
+ return 0;
+
host_info = kcalloc(1, sizeof(struct register_slave_host), GFP_KERNEL);
if (!host_info)
return -ENOMEM;
@@ -1075,7 +1078,8 @@ int hinic3_get_func_nic_enable(void *hwdev, u16 glb_func_idx, bool *en)
return -EINVAL;
/* if single host, return true. */
- if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev)) {
+ if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev) ||
+ UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev)) {
*en = true;
return 0;
}
@@ -1145,11 +1149,21 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
{
int err;
struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+ int is_use_vram, is_in_kexec;
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
- hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0) {
+ snprintf(hwdev->mhost_mgmt_name, VRAM_NAME_MAX_LEN, "%s",
+ VRAM_NIC_MHOST_MGMT);
+ hwdev->mhost_mgmt = hi_vram_kalloc(hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ } else {
+ hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ }
+
if (!hwdev->mhost_mgmt)
return -ENOMEM;
@@ -1165,8 +1179,11 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK, hwdev, hilink_ppf_mbox_handler);
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC, hwdev, sw_func_ppf_mbox_handler);
- bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
- bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ }
/* Slave host:
* register slave host ppf functions
@@ -1179,7 +1196,11 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
return 0;
out_free_mhost_mgmt:
- kfree(hwdev->mhost_mgmt);
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)hwdev->mhost_mgmt, hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ else
+ kfree(hwdev->mhost_mgmt);
hwdev->mhost_mgmt = NULL;
return err;
@@ -1187,6 +1208,8 @@ out_free_mhost_mgmt:
int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
{
+ int is_use_vram;
+
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
@@ -1203,7 +1226,13 @@ int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC);
- kfree(hwdev->mhost_mgmt);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)hwdev->mhost_mgmt, hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ else
+ kfree(hwdev->mhost_mgmt);
+
hwdev->mhost_mgmt = NULL;
return 0;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
index 5e4804a..a0340d9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
@@ -17,14 +17,13 @@
#include "hinic3_hwdev.h"
#include "hinic3_lld.h"
#include "hinic3_hw_mt.h"
+#include "hinic3_dev_mgmt.h"
#include "hinic3_nictool.h"
static int g_nictool_ref_cnt;
static dev_t g_dev_id = {0};
-/*lint -save -e104 -e808*/
static struct class *g_nictool_class;
-/*lint -restore*/
static struct cdev g_nictool_cdev;
#define HINIC3_MAX_BUF_SIZE (2048 * 1024)
@@ -92,6 +91,23 @@ static int get_all_chip_id_cmd(struct hinic3_lld_dev *lld_dev, const void *buf_i
return 0;
}
+#ifndef __HIFC__
+static int get_os_hot_replace_info(struct hinic3_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ if (*out_size != sizeof(struct os_hot_replace_info) || !buf_out) {
+ pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
+ *out_size, sizeof(struct os_hot_replace_info));
+ return -EFAULT;
+ }
+
+ hinic3_get_os_hot_replace_info(buf_out);
+
+ return 0;
+}
+#endif
+
static int get_card_usr_api_chain_mem(int card_idx)
{
unsigned char *tmp = NULL;
@@ -166,7 +182,7 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
if (!buf_out || *out_size != sizeof(struct pf_dev_info) * PF_DEV_INFO_NUM) {
pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
- *out_size, sizeof(dev_info) * PF_DEV_INFO_NUM);
+ *out_size, sizeof(*dev_info) * PF_DEV_INFO_NUM);
return -EFAULT;
}
@@ -193,13 +209,18 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
return 0;
}
-static long dbgtool_knl_free_mem(int id)
+static void dbgtool_knl_free_mem(int id)
{
unsigned char *tmp = NULL;
int i;
+ if (id < 0 || id >= MAX_CARD_NUM) {
+ pr_err("Invalid card id\n");
+ return;
+ }
+
if (!g_card_vir_addr[id])
- return 0;
+ return;
tmp = g_card_vir_addr[id];
for (i = 0; i < (1 << DBGTOOL_PAGE_ORDER); i++) {
@@ -211,7 +232,6 @@ static long dbgtool_knl_free_mem(int id)
g_card_vir_addr[id] = NULL;
g_card_phy_addr[id] = 0;
- return 0;
}
static int free_knl_mem(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_size,
@@ -337,7 +357,6 @@ static int get_hw_drv_version(struct hinic3_lld_dev *lld_dev, const void *buf_in
void *buf_out, u32 *out_size)
{
struct drv_version_info *ver_info = buf_out;
- int err;
if (!buf_out) {
pr_err("Buf_out is NULL.\n");
@@ -350,10 +369,8 @@ static int get_hw_drv_version(struct hinic3_lld_dev *lld_dev, const void *buf_in
return -EINVAL;
}
- err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s", HINIC3_DRV_VERSION,
- "2023-05-17_19:56:38");
- if (err < 0)
- return -EINVAL;
+ snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s", HINIC3_DRV_VERSION,
+ "2025-05-08_00:00:08");
return 0;
}
@@ -386,6 +403,22 @@ static int get_pf_id(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_
return 0;
}
+#ifndef __HIFC__
+/* not support fc yet */
+static int get_mbox_cnt(struct hinic3_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ if (buf_out == NULL || *out_size != sizeof(struct card_mbox_cnt_info)) {
+ pr_err("buf_out is NULL, or out_size != %lu\n", sizeof(struct card_info));
+ return -EINVAL;
+ }
+
+ hinic3_get_mbox_cnt(hinic3_get_sdk_hwdev_by_lld(lld_dev), buf_out);
+
+ return 0;
+}
+#endif
+
struct hw_drv_module_handle hw_driv_module_cmd_handle[] = {
{FUNC_TYPE, get_func_type},
{GET_FUNC_IDX, get_func_id},
@@ -402,6 +435,10 @@ struct hw_drv_module_handle hw_driv_module_cmd_handle[] = {
{GET_FUNC_CAP, get_pf_cap_info},
{GET_DRV_VERSION, get_hw_drv_version},
{GET_PF_ID, get_pf_id},
+#ifndef __HIFC__
+ {GET_OS_HOT_REPLACE_INFO, get_os_hot_replace_info},
+ {GET_MBOX_CNT, (hw_driv_module)get_mbox_cnt},
+#endif
};
static int alloc_tmp_buf(void *hwdev, struct msg_module *nt_msg, u32 in_size,
@@ -439,8 +476,8 @@ static void free_tmp_buf(void *hwdev, struct msg_module *nt_msg,
static int send_to_hw_driver(struct hinic3_lld_dev *lld_dev, struct msg_module *nt_msg,
const void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(hw_driv_module_cmd_handle) /
- sizeof(hw_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(hw_driv_module_cmd_handle) /
+ sizeof(hw_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type =
(enum driver_cmd_type)(nt_msg->msg_formate);
int err = 0;
@@ -482,8 +519,8 @@ static int send_to_service_driver(struct hinic3_lld_dev *lld_dev, struct msg_mod
if (nt_msg->msg_formate == GET_DRV_VERSION)
return 0;
- pr_err("Can not get the uld dev correctly: %s, %s driver may be not register\n",
- nt_msg->device_name, service_name[type]);
+ pr_err("Can not get the uld dev correctly: %s driver may be not register\n",
+ service_name[type]);
return -EINVAL;
}
@@ -566,8 +603,8 @@ static struct hinic3_lld_dev *get_lld_dev_by_nt_msg(struct msg_module *nt_msg)
} else {
lld_dev = hinic3_get_lld_dev_by_chip_name(nt_msg->device_name);
if (!lld_dev)
- lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
- SERVICE_T_MAX);
+ lld_dev = hinic3_get_lld_dev_by_dev_name(
+ nt_msg->device_name, SERVICE_T_MAX);
}
return lld_dev;
@@ -597,8 +634,10 @@ static long hinicadm_k_unlocked_ioctl(struct file *pfile, unsigned long arg)
return -ENODEV;
}
- if (nt_msg.msg_formate == DEV_NAME_TEST)
+ if (nt_msg.msg_formate == DEV_NAME_TEST) {
+ lld_dev_put(lld_dev);
return 0;
+ }
ret = alloc_tmp_buf(hinic3_get_sdk_hwdev_by_lld(lld_dev), &nt_msg,
in_size, &buf_in, out_size_expect, &buf_out);
@@ -642,6 +681,9 @@ out_free_lock:
static long dbgtool_knl_ffm_info_rd(struct dbgtool_param *para,
struct dbgtool_k_glb_info *dbgtool_info)
{
+ if (!para->param.ffm_rd || !dbgtool_info->ffm)
+ return -EINVAL;
+
/* Copy the ffm_info to user mode */
if (copy_to_user(para->param.ffm_rd, dbgtool_info->ffm,
(unsigned int)sizeof(struct ffm_record_info))) {
@@ -674,13 +716,14 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
card_info = (struct card_node *)g_card_node_array[i];
if (!card_info)
continue;
- if (!strncmp(param.chip_name, card_info->chip_name, IFNAMSIZ))
+ if (memcmp(param.chip_name, card_info->chip_name,
+ strlen(card_info->chip_name) + 1) == 0)
break;
}
if (i == MAX_CARD_NUM || !card_info) {
lld_put();
- pr_err("Can't find this card %s\n", param.chip_name);
+ pr_err("Can't find this card.\n");
return -EFAULT;
}
@@ -697,10 +740,10 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
pr_err("Not suppose to use this cmd(0x%x).\n", real_cmd);
ret = 0;
break;
-
default:
pr_err("Dbgtool cmd(0x%x) not support now\n", real_cmd);
ret = -EFAULT;
+ break;
}
up(&dbgtool_info->dbgtool_sem);
@@ -746,9 +789,11 @@ static long nictool_k_unlocked_ioctl(struct file *pfile,
static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
{
+ pgprot_t vm_page_prot;
unsigned long vmsize = vma->vm_end - vma->vm_start;
phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
phys_addr_t phy_addr;
+ int err = 0;
if (vmsize > (PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER))) {
pr_err("Map size = %lu is bigger than alloc\n", vmsize);
@@ -758,13 +803,18 @@ static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
/* old version of tool set vma->vm_pgoff to 0 */
phy_addr = offset ? offset : g_card_phy_addr[card_id];
- if (!phy_addr) {
- pr_err("Card_id = %d physical address is 0\n", card_id);
- return -EAGAIN;
+ /* check phy_addr valid */
+ if (phy_addr != g_card_phy_addr[card_id]) {
+ err = hinic3_bar_mmap_param_valid(phy_addr, vmsize);
+ if (err != 0) {
+ pr_err("mmap param invalid, err: %d\n", err);
+ return err;
+ }
}
/* Disable cache and write buffer in the mapping area */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_page_prot = vm_page_prot;
if (remap_pfn_range(vma, vma->vm_start, (phy_addr >> PAGE_SHIFT),
vmsize, vma->vm_page_prot)) {
pr_err("Remap pfn range failed.\n");
@@ -787,7 +837,6 @@ static const struct file_operations fifo_operations = {
static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
{
struct dbgtool_k_glb_info *dbgtool_info = NULL;
- int err, id;
if (hinic3_func_type(hwdev) != TYPE_VF)
chip_info->func_handle_array[hinic3_global_func_id(hwdev)] = NULL;
@@ -795,23 +844,22 @@ static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
if (--chip_info->func_num)
return;
- err = sscanf(chip_info->chip_name, HINIC3_CHIP_NAME "%d", &id);
- if (err < 0)
- pr_err("Failed to get card id\n");
-
- if (id < MAX_CARD_NUM)
- g_card_node_array[id] = NULL;
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ g_card_node_array[chip_info->chip_id] = NULL;
dbgtool_info = chip_info->dbgtool_info;
/* FFM deinit */
- kfree(dbgtool_info->ffm);
- dbgtool_info->ffm = NULL;
+ if (dbgtool_info && dbgtool_info->ffm) {
+ kfree(dbgtool_info->ffm);
+ dbgtool_info->ffm = NULL;
+ }
kfree(dbgtool_info);
+
chip_info->dbgtool_info = NULL;
- if (id < MAX_CARD_NUM)
- (void)dbgtool_knl_free_mem(id);
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ dbgtool_knl_free_mem(chip_info->chip_id);
}
static int alloc_dbgtool_info(void *hwdev, struct card_node *chip_info)
@@ -872,7 +920,7 @@ dbgtool_info_fail:
* nictool_k_init - initialize the hw interface
**/
/* temp for dbgtool_info */
-/*lint -e438*/
+
int nictool_k_init(void *hwdev, void *chip_node)
{
struct card_node *chip_info = (struct card_node *)chip_node;
@@ -895,9 +943,7 @@ int nictool_k_init(void *hwdev, void *chip_node)
}
/* Create equipment */
- /*lint -save -e160*/
g_nictool_class = class_create(HIADM3_DEV_CLASS);
- /*lint -restore*/
if (IS_ERR(g_nictool_class)) {
pr_err("Create nictool_class fail\n");
err = -EFAULT;
@@ -944,7 +990,7 @@ alloc_chdev_fail:
free_dbgtool_info(hwdev, chip_info);
return err;
-} /*lint +e438*/
+}
void nictool_k_uninit(void *hwdev, void *chip_node)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
index f368133..c943dfc 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
@@ -18,6 +18,8 @@
int nictool_k_init(void *hwdev, void *chip_node);
void nictool_k_uninit(void *hwdev, void *chip_node);
+void hinic3_get_os_hot_replace_info(void *oshr_info);
+
void hinic3_get_all_chip_id(void *id_info);
void hinic3_get_card_func_info_by_card_name
@@ -29,6 +31,8 @@ bool hinic3_is_in_host(void);
int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *isvalid);
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin);
+
extern struct hinic3_uld_info g_uld_info[SERVICE_T_MAX];
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
index 2d5423e..e961ef7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
@@ -19,6 +19,20 @@
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
+#elif defined(CONFIG_NF_VID_DID)
+#define PCI_VENDOR_ID_NF 0x2036
+#define NFNIC_DEV_ID_STANDARD 0x1618
+#define NFNIC_DEV_ID_SDI_5_1_PF 0x0226
+#define NFNIC_DEV_ID_SDI_5_0_PF 0x0225
+#define NFNIC_DEV_ID_DPU_PF 0x0224
+#define NFNIC_DEV_ID_VF 0x1619
+#define NFNIC_DEV_ID_VF_HV 0x379F
+#define NFNIC_DEV_SDI_5_1_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_0_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_1_ID_VF_HV 0x379F
+#define NFNIC_DEV_ID_SPU 0xAC00
+#define NFNIC_DEV_SDI_5_1_SSDID_VF 0x1000
+#define NFNIC_DEV_SDI_V100_SSDID_MASK (3 << 12)
#else
#define PCI_VENDOR_ID_HUAWEI 0x19e5
#define HINIC3_DEV_ID_STANDARD 0x0222
@@ -28,16 +42,33 @@
#define HINIC3_DEV_ID_VF 0x375F
#define HINIC3_DEV_ID_VF_HV 0x379F
#define HINIC3_DEV_SDI_5_1_ID_VF 0x375F
+#define HINIC3_DEV_SDI_5_0_ID_VF 0x375F
#define HINIC3_DEV_SDI_5_1_ID_VF_HV 0x379F
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
#endif
+#define NFNIC_DEV_SSID_2X25G_NF 0x0860
+#define NFNIC_DEV_SSID_4X25G_NF 0x0861
+#define NFNIC_DEV_SSID_2x100G_NF 0x0862
+#define NFNIC_DEV_SSID_2x200G_NF 0x0863
+
+#define HINIC3_DEV_SSID_2X10G 0x0035
#define HINIC3_DEV_SSID_2X25G 0x0051
#define HINIC3_DEV_SSID_4X25G 0x0052
+#define HINIC3_DEV_SSID_4X25G_BD 0x0252
+#define HINIC3_DEV_SSID_4X25G_SMARTNIC 0x0152
+#define HINIC3_DEV_SSID_6X25G_VL 0x0356
#define HINIC3_DEV_SSID_2X100G 0x00A1
+#define HINIC3_DEV_SSID_2X100G_SMARTNIC 0x01A1
+#define HINIC3_DEV_SSID_2X200G 0x04B1
#define HINIC3_DEV_SSID_2X100G_VF 0x1000
+#define HINIC3_DEV_SSID_HPC_4_HOST_NIC 0x005A
+#define HINIC3_DEV_SSID_2X200G_VL 0x00B1
+#define HINIC3_DEV_SSID_1X100G 0x02A4
+
+#define BIFUR_RESOURCE_PF_SSID 0x05a1
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
index b23b69f..056397f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
@@ -52,7 +52,7 @@ static int hinic3_deinit_vf_hw(void *hwdev, u16 start_vf_id, u16 end_vf_id)
}
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
-ssize_t hinic3_sriov_totalvfs_show(struct device *dev,
+ssize_t sriov_totalvfs_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
@@ -60,7 +60,7 @@ ssize_t hinic3_sriov_totalvfs_show(struct device *dev,
return sprintf(buf, "%d\n", pci_sriov_get_totalvfs(pdev));
}
-ssize_t hinic3_sriov_numvfs_show(struct device *dev,
+ssize_t sriov_numvfs_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
@@ -68,8 +68,7 @@ ssize_t hinic3_sriov_numvfs_show(struct device *dev,
return sprintf(buf, "%d\n", pci_num_vf(pdev));
}
-/*lint -save -e713*/
-ssize_t hinic3_sriov_numvfs_store(struct device *dev,
+ssize_t sriov_numvfs_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
@@ -116,7 +115,6 @@ ssize_t hinic3_sriov_numvfs_store(struct device *dev,
return count;
}
-/*lint -restore*/
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
int hinic3_pci_sriov_disable(struct pci_dev *dev)
@@ -174,24 +172,15 @@ int hinic3_pci_sriov_disable(struct pci_dev *dev)
return 0;
}
-int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
-{
#ifdef CONFIG_PCI_IOV
- struct hinic3_sriov_info *sriov_info = NULL;
- struct hinic3_event_info event = {0};
- void *hwdev = NULL;
- int pre_existing_vfs = 0;
- int err = 0;
-
- sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
- hwdev = hinic3_get_hwdev_by_pcidev(dev);
- if (!hwdev) {
- sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
- return -EPERM;
- }
+int hinic3_pci_sriov_check(struct hinic3_sriov_info *sriov_info, struct pci_dev *dev, int num_vfs)
+{
+ int pre_existing_vfs;
+ int err;
if (test_and_set_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state)) {
- sdk_err(&dev->dev, "SR-IOV enable in process, please wait, num_vfs %d\n",
+ sdk_err(&dev->dev,
+ "SR-IOV enable in process, please wait, num_vfs %d\n",
num_vfs);
return -EPERM;
}
@@ -202,6 +191,7 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
clear_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state);
return -ERANGE;
}
+
if (pre_existing_vfs && pre_existing_vfs != num_vfs) {
err = hinic3_pci_sriov_disable(dev);
if (err) {
@@ -213,6 +203,29 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
return num_vfs;
}
+ return 0;
+}
+#endif
+
+int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
+{
+#ifdef CONFIG_PCI_IOV
+ struct hinic3_sriov_info *sriov_info = NULL;
+ struct hinic3_event_info event = {0};
+ void *hwdev = NULL;
+ int err = 0;
+
+ sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
+ hwdev = hinic3_get_hwdev_by_pcidev(dev);
+ if (!hwdev) {
+ sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
+ return -EPERM;
+ }
+
+ err = hinic3_pci_sriov_check(sriov_info, dev, num_vfs);
+ if (err != 0)
+ return err;
+
err = hinic3_init_vf_hw(hwdev, 1, (u16)num_vfs);
if (err) {
sdk_err(&dev->dev, "Failed to init vf in hardware before enable sriov, error %d\n",
@@ -262,6 +275,3 @@ int hinic3_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
else
return hinic3_pci_sriov_enable(dev, num_vfs);
}
-
-/*lint -restore*/
-
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h
index 4a640ad..20eb728 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h
@@ -7,11 +7,11 @@
#include <linux/pci.h>
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
-ssize_t hinic3_sriov_totalvfs_show(struct device *dev,
+ssize_t sriov_totalvfs_show(struct device *dev,
struct device_attribute *attr, char *buf);
-ssize_t hinic3_sriov_numvfs_show(struct device *dev,
+ssize_t sriov_numvfs_show(struct device *dev,
struct device_attribute *attr, char *buf);
-ssize_t hinic3_sriov_numvfs_store(struct device *dev,
+ssize_t sriov_numvfs_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count);
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c b/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c
index f8aea696..be83022 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c
@@ -117,3 +117,4 @@ u64 ossl_get_real_time(void)
tv_msec = (u64)tv.tv_sec * MSEC_PER_SEC + (u64)tv.tv_usec / USEC_PER_MSEC;
return tv_msec;
}
+
diff --git a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
index 9e8fc75..01ab739 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
@@ -10,6 +10,10 @@
#define OVS_PORT_NUM_MAX BOND_PORT_MAX_NUM
#define DEFAULT_ROCE_BOND_FUNC 0xFFFFFFFF
+#define BOND_ID_IS_VALID(_id) \
+ (((_id) >= BOND_FIRST_ID) && ((_id) <= BOND_MAX_ID))
+#define BOND_ID_IS_INVALID(_id) (!(BOND_ID_IS_VALID(_id)))
+
enum bond_group_id {
BOND_FIRST_ID = 1,
BOND_MAX_ID = 4,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
index e7e16fc..f9737ea 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
@@ -52,6 +52,8 @@ enum scenes_id_define {
SCENES_ID_STORAGE_ROCE = 6,
SCENES_ID_COMPUTE_ROCE = 7,
SCENES_ID_STORAGE_TOE = 8,
+ SCENES_ID_COMPUTE_DPU = 100,
+ SCENES_ID_COMPUTE_SMART_NIC = 101,
SCENES_ID_MAX
};
@@ -122,13 +124,18 @@ struct cfg_cmd_dev_cap {
u8 srv_multi_host_mode;
u8 virtio_vq_size;
- u32 rsvd_func3[5];
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 lro_enable;
+ u8 os_hot_replace;
+
+ u32 rsvd_func3[4];
/* l2nic */
u16 nic_max_sq_id;
u16 nic_max_rq_id;
u16 nic_default_num_queues;
- u16 rsvd1_nic;
+ u16 outband_vlan_cfg_en;
u32 rsvd2_nic[2];
/* RoCE */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
index d9f67e2..6c5b995 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
@@ -37,7 +37,7 @@ static inline void hinic3_cpu_to_be32(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -59,7 +59,7 @@ static inline void hinic3_be32_to_cpu(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -86,52 +86,16 @@ static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
sge->len = (u32)len;
}
-#ifdef HW_CONVERT_ENDIAN
#define hinic3_hw_be32(val) (val)
#define hinic3_hw_cpu32(val) (val)
#define hinic3_hw_cpu16(val) (val)
-#else
-#define hinic3_hw_be32(val) cpu_to_be32(val)
-#define hinic3_hw_cpu32(val) be32_to_cpu(val)
-#define hinic3_hw_cpu16(val) be16_to_cpu(val)
-#endif
static inline void hinic3_hw_be32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_be32(*mem);
- mem++;
- }
-#endif
}
static inline void hinic3_hw_cpu32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_cpu32(*mem);
- mem++;
- }
-#endif
}
int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
@@ -149,6 +113,8 @@ int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
/* func_attr.glb_func_idx, global function index */
u16 hinic3_global_func_id(void *hwdev);
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id);
+
/* func_attr.p2p_idx, belongs to which pf */
u8 hinic3_pf_id_of_vf(void *hwdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
index 9a9bfe2..e36ba1d 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
@@ -219,5 +219,7 @@ void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
const char **hinic3_get_uld_names(void);
+int hinic3_lld_init(void);
+void hinic3_lld_exit(void);
#endif
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
index 97d34f0..4cd6f94 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
@@ -43,6 +43,10 @@ enum mag_cmd {
MAG_CMD_GET_XSFP_PRESENT = 62, /* get xsfp present status @see mag_cmd_get_xsfp_present */
MAG_CMD_SET_XSFP_RW = 63, /* sfp/qsfp single byte read/write, @see mag_cmd_set_xsfp_rw */
MAG_CMD_CFG_XSFP_TEMPERATURE = 64, /* get xsfp temp @see mag_cmd_sfp_temp_out_info */
+ /**< set xsfp tlv info @see struct mag_cmd_set_xsfp_tlv_req */
+ MAG_CMD_SET_XSFP_TLV_INFO = 65,
+ /**< get xsfp tlv info @see struct drv_tag_mag_cmd_get_xsfp_tlv_rsp */
+ MAG_CMD_GET_XSFP_TLV_INFO = 66,
/* Event reported 100-149 */
MAG_CMD_WIRE_EVENT = 100,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
index caaba5d..d33b9f4 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
@@ -31,17 +31,28 @@ enum board_type_define_e {
BOARD_TYPE_STRG_2X100G_ROCE_AA = 42, /* 2X100G SmartIO ROCE_AA Card */
BOARD_TYPE_CAL_2X25G_NIC_75MPPS = 100, /* 2X25G ETH Standard card 75MPPS */
BOARD_TYPE_CAL_2X25G_NIC_40MPPS = 101, /* 2X25G ETH Standard card 40MPPS */
- BOARD_TYPE_CAL_2X100G_DPU = 102, /* 2x100G DPU Card */
+ BOARD_TYPE_CAL_2X100G_DPU_VL = 102, /* 2x100G DPU Card */
BOARD_TYPE_CAL_4X25G_NIC_120MPPS = 105, /* 4X25G ETH Standard card 120MPPS */
BOARD_TYPE_CAL_4X25G_COMSTORAGE = 106, /* 4X25GE compute storage Onboard Card */
BOARD_TYPE_CAL_2X32G_FC_HBA = 110, /* 2X32G FC HBA card */
BOARD_TYPE_CAL_2X16G_FC_HBA = 111, /* 2X16G FC HBA card */
BOARD_TYPE_CAL_2X100G_NIC_120MPPS = 115, /* 2X100G ETH Standard card 120MPPS */
- BOARD_TYPE_CAL_2X25G_DPU = 116, /* 2x25G DPU Card */
- BOARD_TYPE_CAL_4X25G_DPU = 118, /* 4x25G DPU Card */
+ BOARD_TYPE_CAL_2X25G_DPU_BD = 116, /* 2x25G DPU Card */
+ BOARD_TYPE_CAL_2X100G_TCE_BACKPLANE = 117,
+ BOARD_TYPE_CAL_4X25G_DPU_VL = 118, /* 4x25G DPU Card */
+ BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS = 119,
+ BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS = 120,
+ BOARD_TYPE_CAL_6X25G_DPU_VL = 121, /* 6x25G DPU Card */
+ BOARD_TYPE_CAL_4X25G_DPU_BD = 122,
+ BOARD_TYPE_CAL_2X25G_NIC_4HOST = 123,
+ BOARD_TYPE_CAL_2X10G_LOW_POWER = 125,
+ BOARD_TYPE_CAL_2X200G_NIC_INTERNET = 127,
+ BOARD_TYPE_CAL_1X100GR2_OCP = 129, /* 1X100G ETH Standard card */
+ BOARD_TYPE_CAL_2X200G_DPU_VL = 130,
BOARD_TYPE_CLD_2X100G_SDI5_1 = 170, /* 2X100G SDI 5.1 Card */
BOARD_TYPE_CLD_2X25G_SDI5_0_LITE = 171, /* 2x25G SDI5.0 Lite Card */
BOARD_TYPE_CLD_2X100G_SDI5_0 = 172, /* 2x100G SDI5.0 Card */
+ BOARD_TYPE_CLD_4X25G_SDI5_0_C = 175,
BOARD_TYPE_MAX_INDEX = 0xFF
};
@@ -49,23 +60,62 @@ static inline u32 spu_board_type_valid(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
- ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
}
static inline int board_type_is_sdi(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_1) ||
((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
- ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0);
+ ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C);
+}
+
+static inline int board_type_is_dpu_spu(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
}
static inline int board_type_is_dpu(u32 board_type)
{
- return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_6X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
+}
+
+/* 此接口判断是否是分布式存储的标卡以及计算的标卡(含ROCE特性),
+ * 仅用于LLDP TX功能冲突命令字处理的判断
+ */
+static inline int board_type_is_compute(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_75MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_40MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_NIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_COMSTORAGE) ||
+ ((board_type) == BOARD_TYPE_CAL_2X10G_LOW_POWER) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_NIC_INTERNET) ||
+ ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_4HOST) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_NIC_120MPPS);
+}
+
+/* 此接口判断服务器输入reboot网卡是否需要复位 */
+static inline int board_type_is_multi_socket(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP);
}
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
index 291e475..4d4d543 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
@@ -4,8 +4,95 @@
#ifndef MPU_CMD_BASE_DEFS_H
#define MPU_CMD_BASE_DEFS_H
-#include "mgmt_msg_base.h"
-#include "comm_defs.h"
+/** MPU CMD MODULE TYPE */
+enum hinic3_mod_type {
+ HINIC3_MOD_COMM = 0, /* HW communication module */
+ HINIC3_MOD_L2NIC = 1, /* L2NIC module */
+ HINIC3_MOD_ROCE = 2,
+ HINIC3_MOD_PLOG = 3,
+ HINIC3_MOD_TOE = 4,
+ HINIC3_MOD_FLR = 5,
+ HINIC3_MOD_VROCE = 6,
+ HINIC3_MOD_CFGM = 7, /* Configuration management */
+ HINIC3_MOD_CQM = 8,
+ HINIC3_MOD_VMSEC = 9,
+ COMM_MOD_FC = 10,
+ HINIC3_MOD_OVS = 11,
+ HINIC3_MOD_DSW = 12,
+ HINIC3_MOD_MIGRATE = 13,
+ HINIC3_MOD_HILINK = 14,
+ HINIC3_MOD_CRYPT = 15, /* secure crypto module */
+ HINIC3_MOD_VIO = 16,
+ HINIC3_MOD_IMU = 17,
+ HINIC3_MOD_DFX = 18, /* DFX */
+ HINIC3_MOD_HW_MAX = 19, /* hardware max module id */
+ /* Software module id, for PF/VF and multi-host */
+ HINIC3_MOD_SW_FUNC = 20,
+ HINIC3_MOD_MAX,
+};
+
+/* func reset的flag ,用于指示清理哪种资源 */
+enum func_reset_flag_e {
+ RES_TYPE_FLUSH_BIT = 0,
+ RES_TYPE_MQM,
+ RES_TYPE_SMF,
+ RES_TYPE_PF_BW_CFG,
+
+ RES_TYPE_COMM = 10,
+ RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_NIC,
+ RES_TYPE_OVS,
+ RES_TYPE_VBS,
+ RES_TYPE_ROCE,
+ RES_TYPE_FC,
+ RES_TYPE_TOE,
+ RES_TYPE_IPSEC,
+ RES_TYPE_MAX,
+};
+
+#define HINIC3_COMM_RES \
+ ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
+ (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
+ (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
+
+#define HINIC3_NIC_RES (1 << RES_TYPE_NIC)
+#define HINIC3_OVS_RES (1 << RES_TYPE_OVS)
+#define HINIC3_VBS_RES (1 << RES_TYPE_VBS)
+#define HINIC3_ROCE_RES (1 << RES_TYPE_ROCE)
+#define HINIC3_FC_RES (1 << RES_TYPE_FC)
+#define HINIC3_TOE_RES (1 << RES_TYPE_TOE)
+#define HINIC3_IPSEC_RES (1 << RES_TYPE_IPSEC)
+
+/* MODE OVS、NIC、UNKNOWN */
+#define HINIC3_WORK_MODE_OVS 0
+#define HINIC3_WORK_MODE_UNKNOWN 1
+#define HINIC3_WORK_MODE_NIC 2
+
+#define DEVICE_TYPE_L2NIC 0
+#define DEVICE_TYPE_NVME 1
+#define DEVICE_TYPE_VIRTIO_NET 2
+#define DEVICE_TYPE_VIRTIO_BLK 3
+#define DEVICE_TYPE_VIRTIO_VSOCK 4
+#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
+#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
+#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
+#define DEVICE_TYPE_VIRTIO_HPC 8
+#define DEVICE_TYPE_VIRTIO_FS 9
+
+#define IS_STORAGE_DEVICE_TYPE(dev_type) \
+ ((dev_type) == DEVICE_TYPE_VIRTIO_BLK || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_BLK_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_SCSI_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_FS)
+
+#define MGMT_MSG_CMD_OP_SET 1
+#define MGMT_MSG_CMD_OP_GET 0
+
+#define MGMT_MSG_CMD_OP_START 1
+#define MGMT_MSG_CMD_OP_STOP 0
+
+#define HOT_REPLACE_PARTITION_NUM 2
enum hinic3_svc_type {
SVC_T_COMM = 0,
@@ -23,4 +110,54 @@ enum hinic3_svc_type {
SVC_T_MAX,
};
+/**
+ * Common header control information of the COMM message interaction
+ * command word between the driver and PF
+ * struct mgmt_msg_head and struct comm_info_head are the same structure
+ */
+struct mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+/**
+ * Common header control information of the COMM message interaction
+ * command word between the driver and PF
+ */
+struct comm_info_head {
+ /** response status code, 0: success, others: error code */
+ u8 status;
+
+ /** firmware version for command */
+ u8 version;
+
+ /** response aeq number, unused for now */
+ u8 rep_aeq_num;
+ u8 rsvd[5];
+};
+
+static inline u32 get_function_partition(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM;
+}
+
+static inline u32 is_primary_function(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0;
+}
+
+static inline u32 mpu_nic_get_primary_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ function_id : (function_id - port_num);
+}
+
+// when func_id is in partition 0/1, it will get its another func_id in partition 1/0
+static inline u32 mpu_nic_get_backup_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ (function_id + port_num) : (function_id - port_num);
+}
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
index a8e2d63..3841bb5 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
@@ -91,6 +91,10 @@ enum hinic3_mgmt_cmd {
* @see comm_read_ucode_sm_resp
*/
COMM_MGMT_CMD_CLEAR_LOG, /**< clear log @see comm_cmd_clear_log_s */
+ COMM_MGMT_CMD_UCODE_SM_COUNTER_PER,
+ /**< get ucode sm counter @see struct comm_read_ucode_sm_per_req
+ * @see struct comm_read_ucode_sm_per_resp
+ */
COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140, /* check if switch workmode reserved
* @see comm_cmd_check_if_switch_workmode
@@ -103,6 +107,7 @@ enum hinic3_mgmt_cmd {
COMM_MGMT_CMD_CPI_TCAM_DBG, /* enable or disable the scheduled cpi tcam task,
* set task interval time @see comm_cmd_cpi_tcam_dbg_s
*/
+ COMM_MGMT_CMD_LLDP_TX_FUNC_SET,
COMM_MGMT_CMD_SECTION_RSVD_0 = 160, /**< rsvd0 section */
COMM_MGMT_CMD_SECTION_RSVD_1 = 170, /**< rsvd1 section */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
index 674603d..698730f 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
@@ -338,7 +338,8 @@ struct comm_cmd_get_fw_version {
struct mgmt_msg_head head;
u16 fw_type; /**< firmware type @see enum hinic3_fw_ver_type */
- u16 rsvd1;
+ u16 fw_dfx_vld : 1; /**< 0: release, 1: debug */
+ u16 rsvd1 : 15;
u8 ver[HINIC3_FW_VERSION_LEN]; /**< firmware version */
u8 time[HINIC3_FW_COMPILE_TIME_LEN]; /**< firmware compile time */
};
@@ -430,6 +431,22 @@ struct comm_cmd_bdf_info {
u8 rsvd2[5];
};
+struct mpu_pcie_pf_info {
+ u32 device_id; /**< device id */
+ u32 vendor_id; /**< vendor id */
+};
+
+struct mpu_pcie_device_info {
+ u8 status;
+ u8 version;
+ u8 rep_aeq_num;
+ u8 rsvd[5];
+
+ struct mpu_pcie_pf_info pf_info[32];
+ u32 bus_id; /**< bus id */
+ u32 pf_num; /**< pf index */
+};
+
#define TABLE_INDEX_MAX 129
struct sml_table_id_info {
u8 node_id;
@@ -446,6 +463,13 @@ struct comm_cmd_sdi_info {
u32 cfg_sdi_mode; /**< host mode, 0:normal 1:virtual machine 2:bare metal */
};
+struct comm_cmd_root_ctx_load_req {
+ struct comm_info_head head;
+ u32 func_id; /**< function id */
+ u32 smf_id; /**< smf id */
+ u32 queue_id; /**< queue id */
+};
+
#define HINIC_OVS_BOND_DEFAULT_ID 1
struct hinic3_hw_bond_infos {
u8 bond_id;
@@ -685,6 +709,28 @@ struct comm_read_ucode_sm_resp {
u64 val2;
};
+#define PER_REQ_MAX_DATA_LEN 0x600
+
+struct comm_read_ucode_sm_per_req {
+ struct mgmt_msg_head msg_head;
+
+ u32 tbl_type;
+ u32 count_id;
+};
+
+struct comm_read_ucode_sm_per_resp {
+ struct mgmt_msg_head msg_head;
+
+ u8 data[PER_REQ_MAX_DATA_LEN];
+};
+
+struct ucode_sm_counter_get_info {
+ u32 width_type;
+ u32 tbl_type;
+ unsigned int base_count;
+ unsigned int count_num;
+};
+
enum log_type {
MPU_LOG_CLEAR = 0,
SMU_LOG_CLEAR = 1,
@@ -693,6 +739,11 @@ enum log_type {
ALL_LOG_CLEAR = 4,
};
+struct comm_cmd_clear_log {
+ struct comm_info_head head;
+ u32 type; /**< log type @see enum log_type */
+};
+
#define ABLESWITCH 1
#define IMABLESWITCH 2
enum switch_workmode_op {
@@ -717,6 +768,14 @@ struct comm_cmd_check_if_switch_workmode {
u32 rsvd3[3];
};
+struct comm_cmd_switch_workmode {
+ struct mgmt_msg_head head;
+ u8 operation;
+ u8 work_mode;
+ u16 rsvd1[3];
+ u32 rsvd2[3];
+};
+
#define MIG_NOR_VM_ONE_MAX_SGE_MEM (64 * 8)
#define MIG_NOR_VM_ONE_MAX_MEM (MIG_NOR_VM_ONE_MAX_SGE_MEM + 16)
#define MIG_VM_MAX_SML_ENTRY_NUM 24
@@ -755,6 +814,15 @@ struct cmd_get_bdf_info_s {
#define CPI_TCAM_DBG_CMD_TYPE_SET 0
#define CPI_TCAM_DBG_CMD_TYPE_GET 1
+struct comm_cmd_cpi_tcam_dbg {
+ struct comm_info_head head;
+ u8 type;
+ u8 set_bitmap;
+ u8 enable;
+ u8 rsvd;
+ u32 time_interval;
+};
+
#define UDIE_ID_DATA_LEN 8
#define TDIE_ID_DATA_LEN 18
struct comm_cmd_get_die_id {
@@ -808,6 +876,12 @@ struct cmd_query_fw {
u32 len; /**< length */
};
+struct comm_cmd_get_cfg_info_t {
+ struct comm_info_head head;
+ u8 rsvd[8];
+ u8 info[64]; /**< flash config info */
+};
+
struct nic_cmd_get_uart_log_info {
struct comm_info_head head;
struct {
@@ -969,6 +1043,7 @@ enum comm_virtio_dev_type {
COMM_VIRTIO_NET_TYPE = 0,
COMM_VIRTIO_BLK_TYPE = 1,
COMM_VIRTIO_SCSI_TYPE = 4,
+ COMM_VIRTIO_FS_TYPE = 5,
};
struct comm_virtio_dev_cmd {
@@ -1030,6 +1105,13 @@ struct cmd_patch_sram_optimize {
u32 data[4]; /**< reserved */
};
+struct comm_cmd_con_sel_sta {
+ struct comm_info_head head;
+ u8 valid;
+ u8 host_id; /**< host id, range[0,3] */
+ u8 rsvd[2];
+};
+
/* ncsi counter */
struct nsci_counter_in_info_s {
struct comm_info_head head;
@@ -1082,7 +1164,9 @@ struct comm_cmd_ncsi_settings {
u8 lldp_over_ncsi_enable;
u8 lldp_over_mctp_enable;
u32 magicwd;
- u8 rsvd[8];
+ u8 lldp_tx_enable;
+ u8 rsvd[3];
+ u32 crc;
struct tag_ncsi_chan_info ncsi_chan_info;
};
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
index fde8617..1ee44a8 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
@@ -114,6 +114,14 @@ struct tag_ncsi_client_info {
#define AEN_CTRL_CONFIG_REQ_SHIFT 1
#define AEN_CTRL_DRV_CHANGE_SHIFT 2
+/* AEN Type */
+enum aen_type_e {
+ AEN_LINK_STATUS_CHANGE_TYPE = 0x0,
+ AEN_CONFIG_REQUIRED_TYPE = 0x1,
+ OEM_AEN_CONFIG_REQUEST_TYPE = 0x80,
+ AEN_TYPE_MAX = 0x100
+};
+
/* get link status 0x0A */
#define GET_LINK_STATUS_REQ_LEN 0
#define GET_LINK_STATUS_RSP_LEN 16
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
index 0bd168c..5b2bdc8 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
@@ -36,6 +36,7 @@ enum nic_rss_hash_type {
#define NIC_RX_MODE_BC 0x04
#define NIC_RX_MODE_MC_ALL 0x08
#define NIC_RX_MODE_PROMISC 0x10
+#define NIC_RX_DB_COS_MAX 0x4
/* IEEE 802.1Qaz std */
#define NIC_DCB_COS_MAX 0x8
@@ -52,4 +53,7 @@ enum nic_rss_hash_type {
#define NIC_DCB_PRIO_STRICT 0x1
#define NIC_DCB_MAX_PFC_NUM 0x4
+
+#define NIC_ETS_PERCENT_WEIGHT 100
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
index 801aeed..5476287 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
@@ -23,7 +23,11 @@
#define VRAM_CQM_BITMAP_BASE "B"
#define VRAM_NIC_DCB "DCB"
+#define VRAM_NIC_MHOST_MGMT "MHOST_MGMT"
#define VRAM_NIC_VRAM "NIC_VRAM"
+#define VRAM_NIC_IRQ_VRAM "NIC_IRQ"
+
+#define VRAM_NIC_MQM "NM"
#define VRAM_VBS_BASE_IOCB "BASE_IOCB"
#define VRAM_VBS_EX_IOCB "EX_IOCB"
@@ -32,6 +36,9 @@
#define VRAM_VBS_VOLQ_MTT "VOLQ_MTT"
#define VRAM_VBS_VOLQ_MTT_PAGE "MTT_PAGE"
+#define VRAM_OVS_PORT_CONF "OVS_PORT_CONF"
+#define VRAM_OVS_DFX_MGR "OVS_DFX_MGR"
+
#define VRAM_VROCE_ENTRY_POOL "VROCE_ENTRY"
#define VRAM_VROCE_GROUP_POOL "VROCE_GROUP"
#define VRAM_VROCE_UUID "VROCE_UUID"
@@ -42,6 +49,17 @@
#define VRAM_VROCE_DEV "VROCE_DEV"
#define VRAM_VROCE_RGROUP_HT_CNT "RGROUP_CNT"
#define VRAM_VROCE_RACL_HT_CNT "RACL_CNT"
+#define VRAM_VROCE_MQM_ENQC "VROCE_MQM_ENQC"
+
+#define VRAM_DTOE_NUMA_MEM "DTOE_NUMA"
+#define VRAM_DTOE_CARD_MEM "DTOE_CARD"
+#define VRAM_DTOE_CONN_MEM "DTOE_CONN"
+#define VRAM_DTOE_SUB_LEN 10
+
+#define VRAM_VROCE_MIG_ENTRY_POOL "VROCE_MIG_ENTRY"
+#define VRAM_VROCE_MIG_ENTRY_HT_CNT "MIG_ENTRY_CNT"
+
+#define VRAM_VBS_DEV_INDEX "VBS_INDEX"
#define VRAM_NAME_APPLY_LEN 64
@@ -55,11 +73,16 @@ enum KUP_HOOK_POINT {
PRE_FREEZE,
FREEZE_TO_KILL,
PRE_UPDATE_KERNEL,
- FLUSH_DURING_KUP,
POST_UPDATE_KERNEL,
UNFREEZE_TO_RUN,
POST_RUN,
KUP_HOOK_MAX,
};
+#define hi_vram_kalloc(name, size) 0
+#define hi_vram_kfree(vaddr, name, size)
+#define get_use_vram_flag(void) 0
+#define vram_get_kexec_flag(void) 0
+#define hi_vram_get_gfp_vram(void) 0
+
#endif /* VRAM_COMMON_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
similarity index 79%
rename from drivers/net/ethernet/huawei/hinic3/mag_cmd.h
rename to drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
index 9649503..ead8e69 100644
--- a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
@@ -9,6 +9,7 @@
/* serdes cmd struct define */
#define CMD_ARRAY_BUF_SIZE 64
#define SERDES_CMD_DATA_BUF_SIZE 512
+#define RATE_MBPS_TO_GBPS 1000
struct serdes_in_info {
u32 chip_id : 16;
u32 macro_id : 16;
@@ -127,6 +128,7 @@ enum mag_cmd_cnt_type {
MAG_RX_PCS_E_BLK_CNT = 5,
MAG_RX_PCS_DEC_ERR_BLK_CNT = 6,
MAG_RX_PCS_LANE_BIP_ERR_CNT = 7,
+ MAG_RX_RSFEC_ERR_CW_CNT = 8,
MAG_CNT_NUM
};
@@ -208,7 +210,9 @@ struct mag_cmd_get_port_info {
u32 supported_mode;
u32 advertised_mode;
- u8 rsvd2[8];
+ u32 supported_fec_mode;
+ u16 bond_speed;
+ u8 rsvd2[2];
};
#define MAG_CMD_OPCODE_GET 0
@@ -330,8 +334,8 @@ struct mag_cmd_cfg_fec_mode {
u8 port_id;
u8 opcode; /* 0:get fec mode 1:set fec mode */
- u8 fec;
- u8 rsvd0;
+ u8 advertised_fec;
+ u8 supported_fec;
};
/* speed */
@@ -641,7 +645,7 @@ struct mag_cmd_event_port_info {
u32 cable_length; /* 1/3/5m */
u8 cable_temp; /* temp */
u8 max_speed; /* Maximum rate of an optical module */
- u8 sfp_type; /* sfp/qsfp */
+ u8 sfp_type; /* sfp/qsfp/dsfp */
u8 rsvd1;
u32 power[4]; /* Optical Power */
@@ -678,6 +682,10 @@ struct mag_cmd_event_port_info {
u8 rsvd3[360];
};
+struct mag_cmd_rsfec_stats {
+ u32 rx_err_lane_phy;
+};
+
struct mag_cmd_port_stats {
u64 mac_tx_fragment_pkt_num;
u64 mac_tx_undersize_pkt_num;
@@ -913,10 +921,223 @@ struct mag_cmd_sfp_temp_in_info {
};
struct mag_cmd_sfp_temp_out_info {
- struct mgmt_msg_head head; /* 8B */
- s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
- s32 max_temp; /* Chip optical module threshold */
- s32 min_temp; /* Chip optical module threshold */
+ struct mgmt_msg_head head; /* 8B */
+ s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
+ s32 max_temp; /* Chip optical module threshold */
+ s32 min_temp; /* Chip optical module threshold */
+};
+
+#define XSFP_CMIS_PARSE_PAGE_NUM 6
+#define XSFP_CMIS_INFO_MAX_SIZE 1536
+#define QSFP_CMIS_PAGE_SIZE 128
+#define QSFP_CMIS_MAX_CHANNEL_NUM 0x8
+
+/* Lower: Control and Essentials, Upper: Administrative Information */
+#define QSFP_CMIS_PAGE_00H 0x00
+/* Advertising */
+#define QSFP_CMIS_PAGE_01H 0x01
+/* Module and lane Thresholds */
+#define QSFP_CMIS_PAGE_02H 0x02
+/* User EEPROM */
+#define QSFP_CMIS_PAGE_03H 0x03
+/* Laser Capabilities Advertising (Page 04h, Optional) */
+#define QSFP_CMIS_PAGE_04H 0x04
+#define QSFP_CMIS_PAGE_05H 0x05
+/* Lane and Data Path Control */
+#define QSFP_CMIS_PAGE_10H 0x10
+/* Lane Status */
+#define QSFP_CMIS_PAGE_11H 0x11
+#define QSFP_CMIS_PAGE_12H 0x12
+
+#define MGMT_TLV_U8_SIZE 1
+#define MGMT_TLV_U16_SIZE 2
+#define MGMT_TLV_U32_SIZE 4
+
+#define MGMT_TLV_GET_U8(addr) (*((u8 *)(void *)(addr)))
+#define MGMT_TLV_SET_U8(addr, value) \
+ ((*((u8 *)(void *)(addr))) = ((u8)(value)))
+
+#define MGMT_TLV_GET_U16(addr) (*((u16 *)(void *)(addr)))
+#define MGMT_TLV_SET_U16(addr, value) \
+ ((*((u16 *)(void *)(addr))) = ((u16)(value)))
+
+#define MGMT_TLV_GET_U32(addr) (*((u32 *)(void *)(addr)))
+#define MGMT_TLV_SET_U32(addr, value) \
+ ((*((u32 *)(void *)(addr))) = ((u32)(value)))
+
+#define MGMT_TLV_TYPE_END 0xFFFF
+
+enum mag_xsfp_type {
+ MAG_XSFP_TYPE_PAGE = 0x01,
+ MAG_XSFP_TYPE_WIRE_TYPE = 0x02,
+ MAG_XSFP_TYPE_END = MGMT_TLV_TYPE_END
+};
+
+struct qsfp_cmis_lower_page_00_s {
+ u8 resv0[14];
+ u8 temperature_msb;
+ u8 temperature_lsb;
+ u8 volt_supply[2];
+ u8 resv1[67];
+ u8 media_type;
+ u8 electrical_interface_id;
+ u8 media_interface_id;
+ u8 lane_count;
+ u8 resv2[39];
+};
+
+struct qsfp_cmis_upper_page_00_s {
+ u8 identifier;
+ u8 vendor_name[16];
+ u8 vendor_oui[3];
+ u8 vendor_pn[16];
+ u8 vendor_rev[2];
+ u8 vendor_sn[16];
+ u8 date_code[8];
+ u8 clei_code[10];
+ u8 power_character[2];
+ u8 cable_len;
+ u8 connector;
+ u8 copper_cable_attenuation[6];
+ u8 near_end_implementation;
+ u8 far_end_config;
+ u8 media_technology;
+ u8 resv0[43];
+};
+
+struct qsfp_cmis_upper_page_01_s {
+ u8 firmware_rev[2];
+ u8 hardware_rev[2];
+ u8 smf_len_km;
+ u8 om5_len;
+ u8 om4_len;
+ u8 om3_len;
+ u8 om2_len;
+ u8 resv0;
+ u8 wavelength[2];
+ u8 wavelength_tolerance[2];
+ u8 pages_implement;
+ u8 resv1[16];
+ u8 monitor_implement[2];
+ u8 resv2[95];
+};
+
+struct qsfp_cmis_upper_page_02_s {
+ u8 temperature_high_alarm[2];
+ u8 temperature_low_alarm[2];
+ u8 temperature_high_warn[2];
+ u8 temperature_low_warn[2];
+ u8 volt_high_alarm[2];
+ u8 volt_low_alarm[2];
+ u8 volt_high_warn[2];
+ u8 volt_low_warn[2];
+ u8 resv0[32];
+ u8 tx_power_high_alarm[2];
+ u8 tx_power_low_alarm[2];
+ u8 tx_power_high_warn[2];
+ u8 tx_power_low_warn[2];
+ u8 tx_bias_high_alarm[2];
+ u8 tx_bias_low_alarm[2];
+ u8 tx_bias_high_warn[2];
+ u8 tx_bias_low_warn[2];
+ u8 rx_power_high_alarm[2];
+ u8 rx_power_low_alarm[2];
+ u8 rx_power_high_warn[2];
+ u8 rx_power_low_warn[2];
+ u8 resv1[56];
+};
+
+struct qsfp_cmis_upper_page_03_s {
+ u8 resv0[QSFP_CMIS_PAGE_SIZE]; /* Reg 128-255: Upper Memory: Page 03H */
+};
+
+struct qsfp_cmis_upper_page_10_s {
+ u8 resv0[2]; /* Reg 128-129: Upper Memory: Page 10H */
+ u8 tx_disable; /* Reg 130: Tx disable, 0b=enabled, 1b=disabled */
+ u8 resv1[125]; /* Reg 131-255 */
+};
+
+struct qsfp_cmis_upper_page_11_s {
+ u8 resv0[7];
+ u8 tx_fault;
+ u8 tx_los;
+ u8 resv1[10];
+ u8 rx_los;
+ u8 resv2[6];
+ u8 tx_power[16];
+ u8 tx_bias[16];
+ u8 rx_power[16];
+ u8 resv3[54];
+};
+
+struct qsfp_cmis_info_s {
+ struct qsfp_cmis_lower_page_00_s lower_page_00;
+ struct qsfp_cmis_upper_page_00_s upper_page_00;
+ struct qsfp_cmis_upper_page_01_s upper_page_01;
+ struct qsfp_cmis_upper_page_02_s upper_page_02;
+ struct qsfp_cmis_upper_page_10_s upper_page_10;
+ struct qsfp_cmis_upper_page_11_s upper_page_11;
+};
+
+struct qsfp_cmis_comm_power_s {
+ u32 chl_power[QSFP_CMIS_MAX_CHANNEL_NUM];
+};
+
+struct qsfp_cmis_wire_info_s {
+ struct qsfp_cmis_comm_power_s rx_power;
+ u8 rx_los;
+ u8 resv0[3];
+};
+
+struct mgmt_tlv_info {
+ u16 type;
+ u16 length;
+ u8 value[];
+};
+
+struct mag_cmd_set_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 tlv_buf[];
+};
+
+struct mag_cmd_set_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+};
+
+struct tag_mag_cmd_get_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd;
+ u16 rsp_buf_len;
+};
+
+struct mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[];
+};
+
+
+struct parse_tlv_info {
+ u8 tlv_page_info[XSFP_CMIS_INFO_MAX_SIZE + 1];
+ u32 tlv_page_info_len;
+ u32 tlv_page_num[XSFP_CMIS_PARSE_PAGE_NUM];
+ u32 wire_type;
+ u8 id;
+};
+
+struct drv_tag_mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[XSFP_CMIS_INFO_MAX_SIZE];
};
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h b/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
deleted file mode 100644
index 257bf67..0000000
--- a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : mgmt_msg_base.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef MGMT_MSG_BASE_H
-#define MGMT_MSG_BASE_H
-
-#define MGMT_MSG_CMD_OP_SET 1
-#define MGMT_MSG_CMD_OP_GET 0
-
-#define MGMT_MSG_CMD_OP_START 1
-#define MGMT_MSG_CMD_OP_STOP 0
-
-struct mgmt_msg_head {
- u8 status;
- u8 version;
- u8 rsvd0[6];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
deleted file mode 100644
index abcfa27..0000000
--- a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2001-2021, Huawei Tech. Co., Ltd.
- * File Name : nic_cfg_comm.h
- * Version : Initial Draft
- * Description : nic config common header file
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef NIC_CFG_COMM_H
-#define NIC_CFG_COMM_H
-
-#include <linux/types.h>
-
-/* rss */
-#define HINIC3_RSS_TYPE_VALID_SHIFT 23
-#define HINIC3_RSS_TYPE_TCP_IPV6_EXT_SHIFT 24
-#define HINIC3_RSS_TYPE_IPV6_EXT_SHIFT 25
-#define HINIC3_RSS_TYPE_TCP_IPV6_SHIFT 26
-#define HINIC3_RSS_TYPE_IPV6_SHIFT 27
-#define HINIC3_RSS_TYPE_TCP_IPV4_SHIFT 28
-#define HINIC3_RSS_TYPE_IPV4_SHIFT 29
-#define HINIC3_RSS_TYPE_UDP_IPV6_SHIFT 30
-#define HINIC3_RSS_TYPE_UDP_IPV4_SHIFT 31
-
-#define HINIC3_RSS_TYPE_SET(val, member) (((u32)(val) & 0x1) << HINIC3_RSS_TYPE_##member##_SHIFT)
-#define HINIC3_RSS_TYPE_GET(val, member) (((u32)(val) >> HINIC3_RSS_TYPE_##member##_SHIFT) & 0x1)
-
-enum nic_rss_hash_type {
- NIC_RSS_HASH_TYPE_XOR = 0,
- NIC_RSS_HASH_TYPE_TOEP,
-
- NIC_RSS_HASH_TYPE_MAX /* MUST BE THE LAST ONE */
-};
-
-#define NIC_RSS_INDIR_SIZE 256
-#define NIC_RSS_KEY_SIZE 40
-
-/* *
- * Definition of the NIC receiving mode
- */
-#define NIC_RX_MODE_UC 0x01
-#define NIC_RX_MODE_MC 0x02
-#define NIC_RX_MODE_BC 0x04
-#define NIC_RX_MODE_MC_ALL 0x08
-#define NIC_RX_MODE_PROMISC 0x10
-
-/* IEEE 802.1Qaz std */
-#define NIC_DCB_COS_MAX 0x8
-#define NIC_DCB_UP_MAX 0x8
-#define NIC_DCB_TC_MAX 0x8
-#define NIC_DCB_PG_MAX 0x8
-#define NIC_DCB_TSA_SP 0x0
-#define NIC_DCB_TSA_CBS 0x1
-#define NIC_DCB_TSA_ETS 0x2
-#define NIC_DCB_DSCP_NUM 0x8
-#define NIC_DCB_IP_PRI_MAX 0x40
-
-#define NIC_DCB_PRIO_DWRR 0x0
-#define NIC_DCB_PRIO_STRICT 0x1
-
-#define NIC_DCB_MAX_PFC_NUM 0x4
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
similarity index 77%
rename from drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
rename to drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
index c35bc82..a228522 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
- * File Name : hinic3_comm_cmd.h
+ * File Name : hinic3_nic_mpu_cmd.h
* Version : Initial Draft
* Created : 2019/4/25
* Last Modified :
@@ -33,10 +33,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_CFG_LOCAL_LRO_STATE,
HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
+ HINIC3_NIC_CMD_SET_FUNC_ER_FWD_ID,
HINIC3_NIC_CMD_SET_RQ_CI_CTX,
- /* MAC & VLAN CFG */
+ /* MAC & VLAN CFG & VXLAN CFG */
HINIC3_NIC_CMD_GET_MAC = 20,
HINIC3_NIC_CMD_SET_MAC,
HINIC3_NIC_CMD_DEL_MAC,
@@ -47,6 +48,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_VLAN_FILTER_EN,
HINIC3_NIC_CMD_SET_RX_VLAN_OFFLOAD,
HINIC3_NIC_CMD_SMAC_CHECK_STATE,
+ HINIC3_NIC_CMD_OUTBAND_SET_FUNC_VLAN,
+ HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+
+ HINIC3_NIC_CMD_RX_RATE_CFG,
+ HINIC3_NIC_CMD_WR_ORDERING_CFG,
/* SR-IOV */
HINIC3_NIC_CMD_CFG_VF_VLAN = 40,
@@ -63,6 +69,7 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC,
/* IP checksum error packets, enable rss quadruple hash */
HINIC3_NIC_CMD_IPCS_ERR_RSS_ENABLE_OP = 66,
+ HINIC3_NIC_CMD_GTP_INNER_PARSE_STATUS,
/* PPA/FDIR */
HINIC3_NIC_CMD_ADD_TC_FLOW = 80,
@@ -78,6 +85,10 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_CFG_PPA_FLUSH,
HINIC3_NIC_CMD_SET_FDIR_STATUS,
HINIC3_NIC_CMD_GET_PPA_COUNTER,
+ HINIC3_NIC_CMD_SET_FUNC_FLOW_BIFUR_ENABLE,
+ HINIC3_NIC_CMD_SET_BOND_MASK,
+ HINIC3_NIC_CMD_GET_BLOCK_TC_FLOWS,
+ HINIC3_NIC_CMD_GET_BOND_MASK,
/* PORT CFG */
HINIC3_NIC_CMD_SET_PORT_ENABLE = 100,
@@ -96,6 +107,8 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_QOS_PORT_CFG,
HINIC3_NIC_CMD_QOS_MAP_CFG,
HINIC3_NIC_CMD_FORCE_PKT_DROP,
+ HINIC3_NIC_CMD_CFG_TX_PROMISC_SKIP = 114,
+ HINIC3_NIC_CMD_SET_PORT_FLOW_BIFUR_ENABLE = 117,
HINIC3_NIC_CMD_TX_PAUSE_EXCP_NOTICE = 118,
HINIC3_NIC_CMD_INQUIRT_PAUSE_CFG = 119,
@@ -118,6 +131,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_UCAPTURE_OPT = 160, /* TODO: move to roce */
HINIC3_NIC_CMD_SET_VHD_CFG,
+ /* OUT OF BAND */
+ HINIC3_NIC_CMD_GET_OUTBAND_CFG = 170, /* Get outband vlan cfg info */
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE, /* Outband vlan cfg info report */
+
+
/* TODO: move to HILINK */
HINIC3_NIC_CMD_GET_PORT_STAT = 200,
HINIC3_NIC_CMD_CLEAN_PORT_STAT,
@@ -138,24 +156,23 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_LINK_ERR_EVENT,
HINIC3_NIC_CMD_SET_LED_STATUS,
- HINIC3_NIC_CMD_MAX = 256,
-};
+ /* mig */
+ HINIC3_NIC_CMD_MIG_SET_CEQ_CTRL = 230,
+ HINIC3_NIC_CMD_MIG_CFG_MSIX_INFO,
+ HINIC3_NIC_CMD_MIG_CFG_FUNC_VAT_TBL,
+ HINIC3_NIC_CMD_MIG_GET_VF_INFO,
+ HINIC3_NIC_CMD_MIG_CHK_MBX_EMPTY,
+ HINIC3_NIC_CMD_MIG_SET_VPORT_ENABLE,
+ HINIC3_NIC_CMD_MIG_CFG_SQ_CI,
+ HINIC3_NIC_CMD_MIG_CFG_RSS_TBL,
+ HINIC3_NIC_CMD_MIG_CFG_MAC_TBL,
+ HINIC3_NIC_CMD_MIG_TMP_SET_CMDQ_CTX,
+
+ HINIC3_OSHR_CMD_ACTIVE_FUNCTION = 240,
-/* NIC CMDQ MODE */
-enum hinic3_ucode_cmd {
- HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
- HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
- HINIC3_UCODE_CMD_ARM_SQ,
- HINIC3_UCODE_CMD_ARM_RQ,
- HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_SET_IQ_ENABLE,
- HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
- HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
- HINIC3_UCODE_CMD_PPA_HASH_TABLE,
- HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_NIC_CMD_GET_RQ_INFO = 241,
+
+ HINIC3_NIC_CMD_MAX = 256,
};
#endif /* HINIC3_NIC_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
new file mode 100644
index 0000000..5c28573
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
@@ -0,0 +1,1440 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+
+#ifndef NIC_MPU_CMD_DEFS_H
+#define NIC_MPU_CMD_DEFS_H
+
+#include "nic_cfg_comm.h"
+#include "mpu_cmd_base_defs.h"
+
+#ifndef ETH_ALEN
+#define ETH_ALEN 6
+#endif
+
+#define HINIC3_CMD_OP_SET 1
+#define HINIC3_CMD_OP_GET 0
+
+#define HINIC3_CMD_OP_ADD 1
+#define HINIC3_CMD_OP_DEL 0
+
+#define NIC_TCAM_BLOCK_LARGE_NUM 256
+#define NIC_TCAM_BLOCK_LARGE_SIZE 16
+
+#define TRAFFIC_BIFUR_MODEL_TYPE 2
+
+#define NIC_TCAM_FLOW_BIFUR_FLAG (1 << 0)
+
+#ifndef BIT
+#define BIT(n) (1UL << (n))
+#endif
+
+enum nic_feature_cap {
+ NIC_F_CSUM = BIT(0),
+ NIC_F_SCTP_CRC = BIT(1),
+ NIC_F_TSO = BIT(2),
+ NIC_F_LRO = BIT(3),
+ NIC_F_UFO = BIT(4),
+ NIC_F_RSS = BIT(5),
+ NIC_F_RX_VLAN_FILTER = BIT(6),
+ NIC_F_RX_VLAN_STRIP = BIT(7),
+ NIC_F_TX_VLAN_INSERT = BIT(8),
+ NIC_F_VXLAN_OFFLOAD = BIT(9),
+ NIC_F_IPSEC_OFFLOAD = BIT(10),
+ NIC_F_FDIR = BIT(11),
+ NIC_F_PROMISC = BIT(12),
+ NIC_F_ALLMULTI = BIT(13),
+ NIC_F_XSFP_REPORT = BIT(14),
+ NIC_F_VF_MAC = BIT(15),
+ NIC_F_RATE_LIMIT = BIT(16),
+ NIC_F_RXQ_RECOVERY = BIT(17),
+ NIC_F_TX_COMPACT_WQE_OL = BIT(19),
+ NIC_F_RX_COMPACT_CQE = BIT(20),
+ NIC_F_HTN_CMDQ = BIT(21),
+};
+
+#define NIC_F_ALL_MASK 0x7FBFFFF /* 使能所有属性 */
+
+struct hinic3_mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+#define NIC_MAX_FEATURE_QWORD 4
+struct hinic3_cmd_feature_nego {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 1: set, 0: get */
+ u8 rsvd;
+ u64 s_feature[NIC_MAX_FEATURE_QWORD];
+};
+
+struct hinic3_port_mac_set {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 rsvd1;
+ u8 mac[ETH_ALEN];
+};
+
+struct hinic3_port_mac_update {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 rsvd1;
+ u8 old_mac[ETH_ALEN];
+ u16 rsvd2;
+ u8 new_mac[ETH_ALEN];
+};
+
+struct hinic3_vport_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 state; /* 0--disable, 1--enable */
+ u8 rsvd2[3];
+};
+
+struct hinic3_port_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 state; /* 0--disable, 1--enable */
+ u8 rsvd2[3];
+};
+
+#define HINIC3_SET_PORT_CAR_PROFILE 0
+#define HINIC3_SET_PORT_CAR_STATE 1
+#define HINIC3_GET_PORT_CAR_LIMIT_SPEED 2
+
+struct hinic3_port_car_info {
+ u32 cir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
+ u32 xir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
+ u32 cbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
+ u32 xbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
+};
+
+struct hinic3_cmd_set_port_car {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode; /* 0--set car profile, 1--set car state */
+ u8 state; /* 0--disable, 1--enable */
+ u8 level;
+
+ struct hinic3_port_car_info car;
+};
+
+struct hinic3_cmd_clear_qp_resource {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_cmd_cache_out_qp_resource {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_port_stats_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_vport_stats {
+ u64 tx_unicast_pkts_vport;
+ u64 tx_unicast_bytes_vport;
+ u64 tx_multicast_pkts_vport;
+ u64 tx_multicast_bytes_vport;
+ u64 tx_broadcast_pkts_vport;
+ u64 tx_broadcast_bytes_vport;
+
+ u64 rx_unicast_pkts_vport;
+ u64 rx_unicast_bytes_vport;
+ u64 rx_multicast_pkts_vport;
+ u64 rx_multicast_bytes_vport;
+ u64 rx_broadcast_pkts_vport;
+ u64 rx_broadcast_bytes_vport;
+
+ u64 tx_discard_vport;
+ u64 rx_discard_vport;
+ u64 tx_err_vport;
+ u64 rx_err_vport;
+};
+
+struct hinic3_phy_fpga_port_stats {
+ u64 mac_rx_total_octs_port;
+ u64 mac_tx_total_octs_port;
+ u64 mac_rx_under_frame_pkts_port;
+ u64 mac_rx_frag_pkts_port;
+ u64 mac_rx_64_oct_pkts_port;
+ u64 mac_rx_127_oct_pkts_port;
+ u64 mac_rx_255_oct_pkts_port;
+ u64 mac_rx_511_oct_pkts_port;
+ u64 mac_rx_1023_oct_pkts_port;
+ u64 mac_rx_max_oct_pkts_port;
+ u64 mac_rx_over_oct_pkts_port;
+ u64 mac_tx_64_oct_pkts_port;
+ u64 mac_tx_127_oct_pkts_port;
+ u64 mac_tx_255_oct_pkts_port;
+ u64 mac_tx_511_oct_pkts_port;
+ u64 mac_tx_1023_oct_pkts_port;
+ u64 mac_tx_max_oct_pkts_port;
+ u64 mac_tx_over_oct_pkts_port;
+ u64 mac_rx_good_pkts_port;
+ u64 mac_rx_crc_error_pkts_port;
+ u64 mac_rx_broadcast_ok_port;
+ u64 mac_rx_multicast_ok_port;
+ u64 mac_rx_mac_frame_ok_port;
+ u64 mac_rx_length_err_pkts_port;
+ u64 mac_rx_vlan_pkts_port;
+ u64 mac_rx_pause_pkts_port;
+ u64 mac_rx_unknown_mac_frame_port;
+ u64 mac_tx_good_pkts_port;
+ u64 mac_tx_broadcast_ok_port;
+ u64 mac_tx_multicast_ok_port;
+ u64 mac_tx_underrun_pkts_port;
+ u64 mac_tx_mac_frame_ok_port;
+ u64 mac_tx_vlan_pkts_port;
+ u64 mac_tx_pause_pkts_port;
+};
+
+struct hinic3_port_stats {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ struct hinic3_phy_fpga_port_stats stats;
+};
+
+struct hinic3_cmd_vport_stats {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u32 stats_size;
+ u32 rsvd1;
+ struct hinic3_vport_stats stats;
+ u64 rsvd2[6];
+};
+
+struct hinic3_cmd_qpn {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 base_qpn;
+};
+
+enum hinic3_func_tbl_cfg_bitmap {
+ FUNC_CFG_INIT,
+ FUNC_CFG_RX_BUF_SIZE,
+ FUNC_CFG_MTU,
+};
+
+struct hinic3_func_tbl_cfg {
+ u16 rx_wqe_buf_size;
+ u16 mtu;
+ u32 rsvd[9];
+};
+
+struct hinic3_cmd_set_func_tbl {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd;
+
+ u32 cfg_bitmap;
+ struct hinic3_func_tbl_cfg tbl_cfg;
+};
+
+struct hinic3_cmd_cons_idx_attr {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_idx;
+ u8 dma_attr_off;
+ u8 pending_limit;
+ u8 coalescing_time;
+ u8 intr_en;
+ u16 intr_idx;
+ u32 l2nic_sqn;
+ u32 rsvd;
+ u64 ci_addr;
+};
+
+union sm_tbl_args {
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } mac_table_arg;
+ struct {
+ u32 er_id;
+ u32 vlan_id;
+ } vlan_elb_table_arg;
+ struct {
+ u32 func_id;
+ } vlan_filter_arg;
+ struct {
+ u32 mc_id;
+ } mc_elb_arg;
+ struct {
+ u32 func_id;
+ } func_tbl_arg;
+ struct {
+ u32 port_id;
+ } port_tbl_arg;
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } fdir_io_table_arg;
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } flexq_table_arg;
+ u32 args[4];
+};
+
+struct hinic3_rq_cqe_ctx {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 cqe_type;
+ u8 rq_id;
+ u8 threshold_cqe_num;
+ u8 rsvd1;
+
+ u16 msix_entry_idx;
+ u16 rsvd2;
+
+ u32 ci_addr_hi;
+ u32 ci_addr_lo;
+
+ u16 timer_loop;
+ u16 rsvd3;
+};
+
+#define DFX_SM_TBL_BUF_MAX (768)
+
+struct nic_cmd_dfx_sm_table {
+ struct hinic3_mgmt_msg_head msg_head;
+ u32 tbl_type;
+ union sm_tbl_args args;
+ u8 tbl_buf[DFX_SM_TBL_BUF_MAX];
+};
+
+struct hinic3_cmd_vlan_offload {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 vlan_offload;
+ u8 rsvd1[5];
+};
+
+/* ucode capture cfg info */
+struct nic_cmd_capture_info {
+ struct hinic3_mgmt_msg_head msg_head;
+ u32 op_type;
+ u32 func_port;
+ u32 is_en_trx;
+ u32 offset_cos;
+ u32 data_vlan;
+};
+
+struct hinic3_cmd_lro_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u8 lro_ipv4_en;
+ u8 lro_ipv6_en;
+ u8 lro_max_pkt_len; /* unit is 1K */
+ u8 resv2[13];
+};
+
+struct hinic3_cmd_lro_timer {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 opcode; /* 1: set timer value, 0: get timer value */
+ u8 rsvd1;
+ u16 rsvd2;
+ u32 timer;
+};
+
+struct hinic3_cmd_local_lro_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 state; /* 0: disable, 1: enable */
+};
+
+struct hinic3_cmd_gtp_inner_parse_status {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 status; /* 0: disable, 1: enable */
+};
+
+struct hinic3_cmd_vf_vlan_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u16 vlan_id;
+ u8 qos;
+ u8 rsvd2[5];
+};
+
+struct hinic3_cmd_spoofchk_set {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 state;
+ u8 rsvd1;
+};
+
+struct hinic3_cmd_tx_rate_cfg {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 rsvd1;
+ u8 direct;
+ u32 min_rate;
+ u32 max_rate;
+ u8 rsvd2[8];
+};
+
+struct hinic3_cmd_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+ u8 port_type;
+ u8 autoneg_cap;
+ u8 autoneg_state;
+ u8 duplex;
+ u8 speed;
+ u8 fec;
+ u16 rsvd2;
+ u32 rsvd3[4];
+};
+
+struct hinic3_cmd_register_vf {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 op_register; /* 0 - unregister, 1 - register */
+ u8 rsvd1[3];
+ u32 support_extra_feature;
+ u8 rsvd2[32];
+};
+
+struct hinic3_cmd_link_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 state;
+ u16 rsvd1;
+};
+
+struct hinic3_cmd_vlan_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 outband_defvid_flag;
+ u16 vlan_id;
+ u8 blacklist_flag;
+ u8 rsvd2;
+};
+
+#define VLAN_BLACKLIST_ENABLE 1
+#define VLAN_BLACKLIST_DISABLE 0
+
+struct hinic3_cmd_vxlan_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 cfg_mode;
+ u16 vxlan_port;
+ u16 rsvd2;
+};
+
+/* set vlan filter */
+struct hinic3_cmd_set_vlan_filter {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 resvd[2];
+ u32 vlan_filter_ctrl; /* bit0:vlan filter en; bit1:broadcast_filter_en */
+};
+
+struct hinic3_cmd_link_ksettings_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+
+ u32 valid_bitmap;
+ u8 speed; /* enum nic_speed_level */
+ u8 autoneg; /* 0 - off, 1 - on */
+ u8 fec; /* 0 - RSFEC, 1 - BASEFEC, 2 - NOFEC */
+ u8 rsvd2[21]; /* reserved for duplex, port, etc. */
+};
+
+struct mpu_lt_info {
+ u8 node;
+ u8 inst;
+ u8 entry_size;
+ u8 rsvd;
+ u32 lt_index;
+ u32 offset;
+ u32 len;
+};
+
+struct nic_mpu_lt_opera {
+ struct hinic3_mgmt_msg_head msg_head;
+ struct mpu_lt_info net_lt_cmd;
+ u8 data[100];
+};
+
+struct hinic3_force_pkt_drop {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port;
+ u8 rsvd1[3];
+};
+
+struct hinic3_rx_mode_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u32 rx_mode;
+};
+
+/* rss */
+struct hinic3_rss_context_table {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u32 context;
+};
+
+struct hinic3_cmd_rss_engine_type {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 hash_engine;
+ u8 rsvd1[4];
+};
+
+struct hinic3_cmd_rss_hash_key {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u8 key[NIC_RSS_KEY_SIZE];
+};
+
+struct hinic3_rss_indir_table {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 indir[NIC_RSS_INDIR_SIZE];
+};
+
+#define NIC_RSS_CMD_TEMP_ALLOC 0x01
+#define NIC_RSS_CMD_TEMP_FREE 0x02
+
+struct hinic3_rss_template_mgmt {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 cmd;
+ u8 template_id;
+ u8 rsvd1[4];
+};
+
+struct hinic3_cmd_rss_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 rss_en;
+ u8 rq_priority_number;
+ u8 prio_tc[NIC_DCB_COS_MAX];
+ u16 num_qps;
+ u16 rsvd1;
+};
+
+struct hinic3_dcb_state {
+ u8 dcb_on;
+ u8 default_cos;
+ u8 trust;
+ u8 rsvd1;
+ u8 pcp2cos[NIC_DCB_UP_MAX];
+ u8 dscp2cos[64];
+ u32 rsvd2[7];
+};
+
+struct hinic3_cmd_vf_dcb_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ struct hinic3_dcb_state state;
+};
+
+struct hinic3_up_ets_cfg { /* delet */
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+
+ u8 cos_tc[NIC_DCB_COS_MAX];
+ u8 tc_bw[NIC_DCB_TC_MAX];
+ u8 cos_prio[NIC_DCB_COS_MAX];
+ u8 cos_bw[NIC_DCB_COS_MAX];
+ u8 tc_prio[NIC_DCB_TC_MAX];
+};
+
+#define CMD_QOS_ETS_COS_TC BIT(0)
+#define CMD_QOS_ETS_TC_BW BIT(1)
+#define CMD_QOS_ETS_COS_PRIO BIT(2)
+#define CMD_QOS_ETS_COS_BW BIT(3)
+#define CMD_QOS_ETS_TC_PRIO BIT(4)
+#define CMD_QOS_ETS_TC_RATELIMIT BIT(5)
+struct hinic3_cmd_ets_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 1 - set, 0 - get */
+ /* bit0 - cos_tc, bit1 - tc_bw, bit2 - cos_prio, bit3 - cos_bw, bit4 - tc_prio */
+ u8 cfg_bitmap;
+ u8 rsvd;
+
+ u8 cos_tc[NIC_DCB_COS_MAX];
+ u8 tc_bw[NIC_DCB_TC_MAX];
+ u8 cos_prio[NIC_DCB_COS_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 cos_bw[NIC_DCB_COS_MAX];
+ u8 tc_prio[NIC_DCB_TC_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 rate_limit[NIC_DCB_TC_MAX];
+};
+
+struct hinic3_cmd_set_dcb_state {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 op_code; /* 0 - get dcb state, 1 - set dcb state */
+ u8 state; /* 0 - disable, 1 - enable dcb */
+ u8 port_state; /* 0 - disable, 1 - enable dcb */
+ u8 rsvd[7];
+};
+
+#define PFC_BIT_MAP_NUM 8
+struct hinic3_cmd_set_pfc {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 0:get 1: set pfc_en 2: set pfc_bitmap 3: set all */
+ u8 pfc_en; /* pfc_en 和 pfc_bitmap 必须同时设置 */
+ u8 pfc_bitmap;
+ u8 rsvd[4];
+};
+
+#define CMD_QOS_PORT_TRUST BIT(0)
+#define CMD_QOS_PORT_DFT_COS BIT(1)
+struct hinic3_cmd_qos_port_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 0 - get, 1 - set */
+ u8 cfg_bitmap; /* bit0 - trust, bit1 - dft_cos */
+ u8 rsvd0;
+
+ u8 trust;
+ u8 dft_cos;
+ u8 rsvd1[18];
+};
+
+#define MAP_COS_MAX_NUM 8
+#define CMD_QOS_MAP_PCP2COS BIT(0)
+#define CMD_QOS_MAP_DSCP2COS BIT(1)
+struct hinic3_cmd_qos_map_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 op_code;
+ u8 cfg_bitmap; /* bit0 - pcp2cos, bit1 - dscp2cos */
+ u16 rsvd0;
+
+ u8 pcp2cos[8]; /* 8 must be configured together */
+ /* If the dscp2cos parameter is set to 0xFF, the MPU ignores the DSCP priority,
+ * Multiple mappings between DSCP values and CoS values can be configured at a time.
+ */
+ u8 dscp2cos[64];
+ u32 rsvd1[4];
+};
+
+struct hinic3_cos_up_map {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 cos_valid_mask; /* every bit indicate index of map is valid 1 or not 0 */
+ u16 rsvd1;
+
+ /* user priority in cos(index:cos, value: up pri) */
+ u8 map[NIC_DCB_UP_MAX];
+};
+
+struct hinic3_cmd_pause_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode;
+ u16 rsvd1;
+ u8 auto_neg;
+ u8 rx_pause;
+ u8 tx_pause;
+ u8 rsvd2[5];
+};
+
+struct nic_cmd_pause_inquiry_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 valid;
+
+ u32 type; /* 1: set, 2: get */
+
+ u32 cos_id;
+
+ u32 rx_inquiry_pause_drop_pkts_en;
+ u32 rx_inquiry_pause_period_ms;
+ u32 rx_inquiry_pause_times;
+ /* rx pause Detection Threshold, Default PAUSE_FRAME_THD_10G/25G/40G/100 */
+ u32 rx_inquiry_pause_frame_thd;
+ u32 rx_inquiry_tx_total_pkts;
+
+ u32 tx_inquiry_pause_en; /* tx pause detect enable */
+ u32 tx_inquiry_pause_period_ms; /* tx pause Default Detection Period 200ms */
+ u32 tx_inquiry_pause_times; /* tx pause Default Times Period 5 */
+ u32 tx_inquiry_pause_frame_thd; /* tx pause Detection Threshold */
+ u32 tx_inquiry_rx_total_pkts;
+ u32 rsvd[3];
+};
+
+/* pfc/pause Storm TX exception reporting */
+struct nic_cmd_tx_pause_notice {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 tx_pause_except; /* 1: abnormality,0: normal */
+ u32 except_level;
+ u32 rsvd;
+};
+
+#define HINIC3_CMD_OP_FREE 0
+#define HINIC3_CMD_OP_ALLOC 1
+
+struct hinic3_cmd_cfg_qps {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 1: alloc qp, 0: free qp */
+ u8 rsvd1;
+ u16 num_qps;
+ u16 rsvd2;
+};
+
+struct hinic3_cmd_led_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port;
+ u8 type;
+ u8 mode;
+ u8 rsvd1;
+};
+
+struct hinic3_cmd_port_loopback {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode;
+ u8 mode;
+ u8 en;
+ u32 rsvd1[2];
+};
+
+struct hinic3_cmd_get_light_module_abs {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 abs_status; /* 0:present, 1:absent */
+ u8 rsv[2];
+};
+
+#define STD_SFP_INFO_MAX_SIZE 640
+struct hinic3_cmd_get_std_sfp_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 wire_type;
+ u16 eeprom_len;
+ u32 rsvd;
+ u8 sfp_info[STD_SFP_INFO_MAX_SIZE];
+};
+
+struct hinic3_cable_plug_event {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 plugged; /* 0: unplugged, 1: plugged */
+ u8 port_id;
+};
+
+struct nic_cmd_mac_info {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 valid_bitmap;
+ u16 rsvd;
+
+ u8 host_id[32];
+ u8 port_id[32];
+ u8 mac_addr[192];
+};
+
+struct nic_cmd_set_tcam_enable {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 tcam_enable;
+ u8 rsvd1;
+ u32 rsvd2;
+};
+
+struct nic_cmd_set_fdir_status {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 pkt_type_en;
+ u8 pkt_type;
+ u8 qid;
+ u8 rsvd2;
+};
+
+#define HINIC3_TCAM_BLOCK_ENABLE 1
+#define HINIC3_TCAM_BLOCK_DISABLE 0
+#define HINIC3_MAX_TCAM_RULES_NUM 4096
+
+/* tcam block type, according to tcam block size */
+enum {
+ NIC_TCAM_BLOCK_TYPE_LARGE = 0, /* block_size: 16 */
+ NIC_TCAM_BLOCK_TYPE_SMALL, /* block_size: 0 */
+ NIC_TCAM_BLOCK_TYPE_MAX
+};
+
+/* alloc tcam block input struct */
+struct nic_cmd_ctrl_tcam_block_in {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
+ /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
+ u8 tcam_type;
+ u16 tcam_block_index;
+ /* Size of the block that the driver wants to allocate
+ * Interface returned by the UP to the driver,
+ * indicating the size of the allocated TCAM block supported by the UP
+ */
+ u16 alloc_block_num;
+};
+
+/* alloc tcam block output struct */
+struct nic_cmd_ctrl_tcam_block_out {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
+ /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
+ u8 tcam_type;
+ u16 tcam_block_index;
+ /* Size of the block that the driver wants to allocate
+ * Interface returned by the UP to the driver,
+ * indicating the size of the allocated TCAM block supported by the UP
+ */
+ u16 mpu_alloc_block_size;
+};
+
+struct nic_cmd_flush_tcam_rules {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u16 rsvd;
+};
+
+struct nic_cmd_dfx_fdir_tcam_block_table {
+ struct hinic3_mgmt_msg_head head;
+ u8 tcam_type;
+ u8 valid;
+ u16 tcam_block_index;
+ u16 use_function_id;
+ u16 rsvd;
+};
+
+struct tcam_result {
+ u32 qid;
+ u32 rsvd;
+};
+
+#define TCAM_FLOW_KEY_SIZE (44)
+
+struct tcam_key_x_y {
+ u8 x[TCAM_FLOW_KEY_SIZE];
+ u8 y[TCAM_FLOW_KEY_SIZE];
+};
+
+struct nic_tcam_cfg_rule {
+ u32 index;
+ struct tcam_result data;
+ struct tcam_key_x_y key;
+};
+
+#define TCAM_RULE_FDIR_TYPE 0
+#define TCAM_RULE_PPA_TYPE 1
+
+struct nic_cmd_fdir_add_rule {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 type;
+ u8 fdir_ext; /* 0x1: flow bifur en bit */
+ struct nic_tcam_cfg_rule rule;
+};
+
+struct nic_cmd_fdir_del_rules {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 type;
+ u8 rsvd;
+ u32 index_start;
+ u32 index_num;
+};
+
+struct nic_cmd_fdir_get_rule {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 index;
+ u8 valid;
+ u8 type;
+ u16 rsvd;
+ struct tcam_key_x_y key;
+ struct tcam_result data;
+ u64 packet_count;
+ u64 byte_count;
+};
+
+struct nic_cmd_fdir_get_block_rules {
+ struct hinic3_mgmt_msg_head head;
+ u8 tcam_block_type; // only NIC_TCAM_BLOCK_TYPE_LARGE
+ u8 tcam_table_type; // TCAM_RULE_PPA_TYPE or TCAM_RULE_FDIR_TYPE
+ u16 tcam_block_index;
+ u8 valid[NIC_TCAM_BLOCK_LARGE_SIZE];
+ struct tcam_key_x_y key[NIC_TCAM_BLOCK_LARGE_SIZE];
+ struct tcam_result data[NIC_TCAM_BLOCK_LARGE_SIZE];
+};
+
+struct hinic3_tcam_key_ipv4_mem {
+ u32 rsvd1 : 1;
+ u32 bifur_flag : 2;
+ u32 model : 1;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+ u32 sipv4_h : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+ u32 dipv4_h : 16;
+ u32 sipv4_l : 16;
+ u32 vlan_id : 15;
+ u32 vlan_flag : 1;
+ u32 dipv4_l : 16;
+ u32 rsvd3;
+ u32 dport : 16;
+ u32 rsvd4 : 16;
+ u32 rsvd5 : 16;
+ u32 sport : 16;
+ u32 outer_sipv4_h : 16;
+ u32 rsvd6 : 16;
+ u32 outer_dipv4_h : 16;
+ u32 outer_sipv4_l : 16;
+ u32 vni_h : 16;
+ u32 outer_dipv4_l : 16;
+ u32 rsvd7 : 16;
+ u32 vni_l : 16;
+};
+
+union hinic3_tag_tcam_ext_info {
+ struct {
+ u32 id : 16; /* id */
+ u32 type : 4; /* type: 0-func, 1-vmdq, 2-port, 3-rsvd, 4-trunk, 5-dp, 6-mc */
+ u32 host_id : 3;
+ u32 rss_q_num : 8; /* rss queue num */
+ u32 ext : 1;
+ } bs;
+ u32 value;
+};
+
+struct hinic3_tcam_key_ipv6_mem {
+ u32 bifur_flag : 2;
+ u32 vlan_flag : 1;
+ u32 outer_ip_type : 1;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+ u32 sipv6_key0 : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+ u32 sipv6_key2 : 16;
+ u32 sipv6_key1 : 16;
+ u32 sipv6_key4 : 16;
+ u32 sipv6_key3 : 16;
+ u32 sipv6_key6 : 16;
+ u32 sipv6_key5 : 16;
+ u32 dport : 16;
+ u32 sipv6_key7 : 16;
+ u32 dipv6_key0 : 16;
+ u32 sport : 16;
+ u32 dipv6_key2 : 16;
+ u32 dipv6_key1 : 16;
+ u32 dipv6_key4 : 16;
+ u32 dipv6_key3 : 16;
+ u32 dipv6_key6 : 16;
+ u32 dipv6_key5 : 16;
+ u32 rsvd2 : 16;
+ u32 dipv6_key7 : 16;
+};
+
+struct hinic3_tcam_key_vxlan_ipv6_mem {
+ u32 rsvd1 : 4;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+
+ u32 dipv6_key0 : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+
+ u32 dipv6_key2 : 16;
+ u32 dipv6_key1 : 16;
+
+ u32 dipv6_key4 : 16;
+ u32 dipv6_key3 : 16;
+
+ u32 dipv6_key6 : 16;
+ u32 dipv6_key5 : 16;
+
+ u32 dport : 16;
+ u32 dipv6_key7 : 16;
+
+ u32 rsvd2 : 16;
+ u32 sport : 16;
+
+ u32 outer_sipv4_h : 16;
+ u32 rsvd3 : 16;
+
+ u32 outer_dipv4_h : 16;
+ u32 outer_sipv4_l : 16;
+
+ u32 vni_h : 16;
+ u32 outer_dipv4_l : 16;
+
+ u32 rsvd4 : 16;
+ u32 vni_l : 16;
+};
+
+struct tag_tcam_key {
+ union {
+ struct hinic3_tcam_key_ipv4_mem key_info;
+ struct hinic3_tcam_key_ipv6_mem key_info_ipv6;
+ struct hinic3_tcam_key_vxlan_ipv6_mem key_info_vxlan_ipv6;
+ };
+
+ union {
+ struct hinic3_tcam_key_ipv4_mem key_mask;
+ struct hinic3_tcam_key_ipv6_mem key_mask_ipv6;
+ struct hinic3_tcam_key_vxlan_ipv6_mem key_mask_vxlan_ipv6;
+ };
+};
+
+enum {
+ PPA_TABLE_ID_CLEAN_CMD = 0,
+ PPA_TABLE_ID_ADD_CMD,
+ PPA_TABLE_ID_DEL_CMD,
+ FDIR_TABLE_ID_ADD_CMD,
+ FDIR_TABLE_ID_DEL_CMD,
+ PPA_TABEL_ID_MAX
+};
+
+struct hinic3_ppa_cfg_table_id_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u16 cmd;
+ u16 table_id;
+ u16 rsvd1;
+};
+
+struct hinic3_ppa_cfg_ppa_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 ppa_en;
+ u8 ppa_miss_drop_en;
+};
+
+struct hinic3_func_flow_bifur_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 func_id;
+ u8 flow_bifur_en;
+ u8 rsvd[5];
+};
+
+struct hinic3_port_flow_bifur_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 port_id;
+ u8 flow_bifur_en;
+ u8 flow_bifur_type; /* 0->vf bifur, 2->traffic bifur */
+ u8 rsvd[4];
+};
+
+struct hinic3_bond_mask_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 func_id;
+ u8 bond_mask;
+ u8 bond_en;
+ u8 func_valid;
+ u8 rsvd[3];
+};
+
+struct hinic3_func_er_value_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 vf_id;
+ u16 er_fwd_id;
+};
+
+#define HINIC3_TX_SET_PROMISC_SKIP 0
+#define HINIC3_TX_GET_PROMISC_SKIP 1
+
+#define HINIC3_GET_TRAFFIC_BIFUR_STATE 0
+#define HINIC3_SET_TRAFFIC_BIFUR_STATE 1
+
+struct hinic3_tx_promisc_cfg {
+ struct hinic3_mgmt_msg_head msg_head;
+ u8 port_id;
+ u8 promisc_skip_en; /* 0: disable tx promisc replication, 1: enable */
+ u8 opcode; /* 0: set, 1: get */
+ u8 rsvd1;
+};
+
+struct hinic3_ppa_cfg_mode_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u8 ppa_mode;
+ u8 qpc_func_nums;
+ u16 base_qpc_func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_ppa_flush_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u8 flush_en; /* 0 flush done, 1 in flush operation */
+ u8 rsvd1;
+};
+
+struct hinic3_ppa_fdir_query_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u32 index;
+ u32 rsvd;
+ u64 pkt_nums;
+ u64 pkt_bytes;
+};
+
+/* BIOS CONF */
+enum {
+ NIC_NVM_DATA_SET = BIT(0), /* 1-save, 0-read */
+ NIC_NVM_DATA_PXE = BIT(1),
+ NIC_NVM_DATA_VLAN = BIT(2),
+ NIC_NVM_DATA_VLAN_PRI = BIT(3),
+ NIC_NVM_DATA_VLAN_ID = BIT(4),
+ NIC_NVM_DATA_WORK_MODE = BIT(5),
+ NIC_NVM_DATA_PF_TX_SPEED_LIMIT = BIT(6),
+ NIC_NVM_DATA_GE_MODE = BIT(7),
+ NIC_NVM_DATA_AUTO_NEG = BIT(8),
+ NIC_NVM_DATA_LINK_FEC = BIT(9),
+ NIC_NVM_DATA_PF_ADAPTIVE_LINK = BIT(10),
+ NIC_NVM_DATA_SRIOV_CONTROL = BIT(11),
+ NIC_NVM_DATA_EXTEND_MODE = BIT(12),
+ NIC_NVM_DATA_LEGACY_VLAN = BIT(13),
+ NIC_NVM_DATA_LEGACY_VLAN_PRI = BIT(14),
+ NIC_NVM_DATA_LEGACY_VLAN_ID = BIT(15),
+ NIC_NVM_DATA_RESET = BIT(31),
+};
+
+#define BIOS_CFG_SIGNATURE 0x1923E518
+#define BIOS_OP_CFG_ALL(op_code_val) \
+ ((((op_code_val) >> 1) & (0xFFFFFFFF)) != 0)
+#define BIOS_OP_CFG_WRITE(op_code_val) \
+ ((((op_code_val) & NIC_NVM_DATA_SET)) != 0)
+#define BIOS_OP_CFG_PXE_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PXE) != 0)
+#define BIOS_OP_CFG_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN) != 0)
+#define BIOS_OP_CFG_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_ID) != 0)
+#define BIOS_OP_CFG_WORK_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_WORK_MODE) != 0)
+#define BIOS_OP_CFG_PF_BW(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_TX_SPEED_LIMIT) != 0)
+#define BIOS_OP_CFG_GE_SPEED(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_GE_MODE) != 0)
+#define BIOS_OP_CFG_AUTO_NEG(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_AUTO_NEG) != 0)
+#define BIOS_OP_CFG_LINK_FEC(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LINK_FEC) != 0)
+#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_ADAPTIVE_LINK) != 0)
+#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_SRIOV_CONTROL) != 0)
+#define BIOS_OP_CFG_EXTEND_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_EXTEND_MODE) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_ID) != 0)
+#define BIOS_OP_CFG_RST_DEF_SET(op_code_val) \
+ (((op_code_val) & (u32)NIC_NVM_DATA_RESET) != 0)
+
+
+#define NIC_BIOS_CFG_MAX_PF_BW 100
+
+struct nic_legacy_vlan_cfg {
+ /* Legacy mode PXE VLAN enable: 0 - disable 1 - enable */
+ u8 pxe_vlan_en : 1;
+ /* Legacy mode PXE VLAN priority: 0-7 */
+ u8 pxe_vlan_pri : 3;
+ /* Legacy mode PXE VLAN ID 1-4094 */
+ u16 pxe_vlan_id : 12;
+};
+
+/* Note: This structure must be 4-byte aligned. */
+struct nic_bios_cfg {
+ u32 signature;
+ u8 pxe_en;
+ u8 extend_mode;
+ struct nic_legacy_vlan_cfg nlvc;
+ u8 pxe_vlan_en;
+ u8 pxe_vlan_pri;
+ u16 pxe_vlan_id;
+ u32 service_mode;
+ u32 pf_tx_bw;
+ u8 speed;
+ u8 auto_neg;
+ u8 lanes;
+ u8 fec;
+ u8 auto_adapt;
+ u8 func_valid;
+ u8 func_id;
+ u8 sriov_en;
+};
+
+struct nic_cmd_bios_cfg {
+ struct hinic3_mgmt_msg_head head;
+ u32 op_code; /* Operation Code: Bit0[0: read 1:write, BIT1-6: cfg_mask */
+ struct nic_bios_cfg bios_cfg;
+};
+
+struct nic_rx_rate_bios_cfg {
+ struct mgmt_msg_head msg_head;
+
+ u32 op_code; /* Operation Code:[0:read 1:write] */
+ u8 rx_rate_limit;
+ u8 func_id;
+};
+
+struct nic_cmd_vhd_config {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 vhd_type;
+ u8 virtio_small_enable; /* 0: mergeable mode, 1: small mode */
+};
+
+/* BOND */
+struct hinic3_create_bond_info {
+ u32 bond_id;
+ u32 master_slave_port_id;
+ u32 slave_bitmap; /* bond port id bitmap */
+ u32 poll_timeout; /* Bond device link check time */
+ u32 up_delay; /* Temporarily reserved */
+ u32 down_delay; /* Temporarily reserved */
+ u32 bond_mode; /* Temporarily reserved */
+ u32 active_pf; /* bond use active pf id */
+ u32 active_port_max_num; /* Maximum number of active bond member interfaces */
+ u32 active_port_min_num; /* Minimum number of active bond member interfaces */
+ u32 xmit_hash_policy;
+ u32 default_param_flag;
+ u32 rsvd;
+};
+
+struct hinic3_cmd_create_bond {
+ struct hinic3_mgmt_msg_head head;
+ struct hinic3_create_bond_info create_bond_info;
+};
+
+struct hinic3_cmd_delete_bond {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 rsvd[2];
+};
+
+struct hinic3_open_close_bond_info {
+ u32 bond_id;
+ u32 open_close_flag; /* Bond flag. 1: open; 0: close. */
+ u32 rsvd[2];
+};
+
+struct hinic3_cmd_open_close_bond {
+ struct hinic3_mgmt_msg_head head;
+ struct hinic3_open_close_bond_info open_close_bond_info;
+};
+
+struct lacp_port_params {
+ u16 port_number;
+ u16 port_priority;
+ u16 key;
+ u16 system_priority;
+ u8 system[ETH_ALEN];
+ u8 port_state;
+ u8 rsvd;
+};
+
+struct lacp_port_info {
+ u32 selected;
+ u32 aggregator_port_id;
+
+ struct lacp_port_params actor;
+ struct lacp_port_params partner;
+
+ u64 tx_lacp_pkts;
+ u64 rx_lacp_pkts;
+ u64 rx_8023ad_drop;
+ u64 tx_8023ad_drop;
+ u64 unknown_pkt_drop;
+ u64 rx_marker_pkts;
+ u64 tx_marker_pkts;
+};
+
+struct hinic3_bond_status_info {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 bon_mmi_status;
+ u32 active_bitmap;
+ u32 port_count;
+
+ struct lacp_port_info port_info[4];
+
+ u64 success_report_cnt[4];
+ u64 fail_report_cnt[4];
+
+ u64 poll_timeout;
+ u64 fast_periodic_timeout;
+ u64 slow_periodic_timeout;
+ u64 short_timeout;
+ u64 long_timeout;
+ u64 aggregate_wait_timeout;
+ u64 tx_period_timeout;
+ u64 rx_marker_timer;
+};
+
+struct hinic3_bond_active_report_info {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 bon_mmi_status;
+ u32 active_bitmap;
+
+ u8 rsvd[16];
+};
+
+/* IP checksum error packets, enable rss quadruple hash. */
+struct hinic3_ipcs_err_rss_enable_operation_s {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 en_tag;
+ u8 type; /* 1: set 0: get */
+ u8 rsvd[2];
+};
+
+struct hinic3_smac_check_state {
+ struct hinic3_mgmt_msg_head head;
+ u8 smac_check_en; /* 1: enable 0: disable */
+ u8 op_code; /* 1: set 0: get */
+ u8 flash_en; /* 1: enable 0: disable */
+ u8 rsvd;
+};
+
+struct hinic3_clear_log_state {
+ struct hinic3_mgmt_msg_head head;
+ u32 type;
+};
+
+struct hinic3_outband_cfg_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 outband_default_vid;
+ u16 func_id;
+};
+
+struct hinic3_wr_ordering {
+ struct hinic3_mgmt_msg_head head;
+ u8 op_code; /* 1: set 0: get */
+ u8 wr_pkt_so_ro;
+ u8 rd_pkt_so_ro;
+ u8 rsvd;
+};
+
+struct hinic3_function_active_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_rq_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rq_depth;
+ u16 rq_num;
+ u16 pf_num;
+ u16 port_num;
+};
+
+#endif /* HINIC_MGMT_INTERFACE_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
new file mode 100644
index 0000000..3e625fc
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
+ * File Name : nic_npu_cmd.h
+ * Version : Initial Draft
+ * Created : 2019/4/25
+ * Last Modified :
+ * Description : NIC Commands between Driver and NPU
+ * Function List :
+ */
+
+#ifndef NIC_NPU_CMD_H
+#define NIC_NPU_CMD_H
+
+/* NIC CMDQ MODE */
+enum hinic3_ucode_cmd {
+ HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
+ HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
+ HINIC3_UCODE_CMD_ARM_SQ, /**< Unused */
+ HINIC3_UCODE_CMD_ARM_RQ, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_IQ_ENABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
+ HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
+ HINIC3_UCODE_CMD_PPA_HASH_TABLE,
+ HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_UCODE_MIG_CFG_Q_CTX = 14,
+ HINIC3_UCODE_MIG_CHK_SQ_STOP,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ HINIC3_UCODE_MIG_CFG_BAT_INFO,
+};
+
+#endif /* NIC_NPU_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
index 78a8d7f..00f4a24 100644
--- a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
+++ b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
@@ -4,7 +4,9 @@
#ifndef OSSL_KNL_LINUX_H_
#define OSSL_KNL_LINUX_H_
+#include <net/checksum.h>
#include <net/ipv6.h>
+#include <net/devlink.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/device.h>
@@ -18,6 +20,12 @@
#include <linux/list.h>
#include <linux/bitmap.h>
#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/filter.h>
+#include <linux/aer.h>
+#include <linux/socket.h>
#ifndef NETIF_F_SCTP_CSUM
#define NETIF_F_SCTP_CSUM 0
@@ -173,12 +181,10 @@ static inline void *_hinic3_dma_zalloc_coherent(struct device *dev,
}
#endif
-#ifndef DT_KNL_EMU
struct timeval {
__kernel_old_time_t tv_sec; /* seconds */
__kernel_suseconds_t tv_usec; /* microseconds */
};
-#endif
#ifndef do_gettimeofday
#define do_gettimeofday(time) _kc_do_gettimeofday(time)
@@ -196,6 +202,10 @@ static inline void _kc_do_gettimeofday(struct timeval *tv)
#define ETH_GET_HEADLEN_NEED_DEV
#define HAVE_GENL_OPS_FIELD_VALIDATE
+#ifndef FIELD_SIZEOF
+#define FIELD_SIZEOF(t, f) (sizeof(((t *)0)->f))
+#endif
+
#define HAVE_DEVLINK_FLASH_UPDATE_PARAMS
#ifndef rtc_time_to_tm
@@ -253,12 +263,12 @@ static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size,
size, vaddr, dma_handle);
}
-#define HAVE_DEVLINK_FW_FILE_NAME_MEMBER
-
#define HAVE_ENCAPSULATION_TSO
#define HAVE_ENCAPSULATION_CSUM
+#define HAVE_UDP_TUNNEL_NIC_INFO
+
#ifndef eth_zero_addr
static inline void hinic3_eth_zero_addr(u8 *addr)
{
@@ -333,4 +343,15 @@ u64 ossl_get_real_time(void);
#define tasklet_state(tasklet) ((tasklet)->state)
+dma_addr_t pci_map_single(struct pci_dev *pdev,
+ void *ptr, size_t size, int direction);
+int pci_dma_mapping_error(struct pci_dev *pdev,
+ dma_addr_t dma_addr);
+void pci_unmap_single(struct pci_dev *pdev,
+ dma_addr_t dma_addr, size_t size, int direction);
+void *pci_alloc_consistent(struct pci_dev *pdev,
+ size_t size, dma_addr_t *dma_handle);
+void pci_free_consistent(struct pci_dev *pdev,
+ size_t size, void *vaddr, dma_addr_t dma_handle);
+
#endif
--
2.45.1.windows.1
2
1

08 May '25
From: zhuyikai <zhuyikai1(a)h-partners.com>
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IC5K44?from=project-issue
CVE: NA
--------------------------------
Add optical module type adaptation.
Add ethtool fec function.
Add NIC XDP PASS function.
Add QoS persistence.
Add NIC out-of-band VLAN configuration function.
Fix NIC bifur bugs.
Fix performance test bugs.
Fix NIC RX bugs.
Fix NIC VF bugs.
Fix the bug of exiting when probing NIC.
Fix bond bugs.
Fix the bug of reading NIC status incorrectly.
Fix and add some statistics.
Signed-off-by: zhuyikai <zhuyikai1(a)h-partners.com>
---
drivers/net/ethernet/huawei/hinic3/Makefile | 1 +
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c | 136 +-
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h | 1 +
drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h | 212 ---
drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h | 239 ---
drivers/net/ethernet/huawei/hinic3/comm_defs.h | 105 --
drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h | 103 --
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c | 51 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h | 2 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c | 86 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c | 1 -
drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c | 28 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c | 27 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c | 35 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c | 9 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c | 12 +-
drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h | 185 ---
drivers/net/ethernet/huawei/hinic3/hinic3_common.h | 118 --
drivers/net/ethernet/huawei/hinic3/hinic3_crm.h | 30 +-
drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c | 305 ++--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c | 267 ++--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h | 7 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c | 227 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c | 387 +++--
drivers/net/ethernet/huawei/hinic3/hinic3_filter.c | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_hw.h | 18 +
drivers/net/ethernet/huawei/hinic3/hinic3_irq.c | 11 +-
drivers/net/ethernet/huawei/hinic3/hinic3_lld.h | 205 ---
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c | 836 +++++++++-
drivers/net/ethernet/huawei/hinic3/hinic3_main.c | 476 +++++-
drivers/net/ethernet/huawei/hinic3/hinic3_mt.h | 197 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c | 372 +++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic.h | 61 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c | 450 +++++-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h | 55 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c | 167 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c | 13 +
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h | 221 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c | 119 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c | 18 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c | 18 +-
drivers/net/ethernet/huawei/hinic3/hinic3_profile.h | 146 --
drivers/net/ethernet/huawei/hinic3/hinic3_rss.c | 140 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c | 41 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rx.c | 357 +++--
drivers/net/ethernet/huawei/hinic3/hinic3_rx.h | 39 +-
drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h | 6 +-
drivers/net/ethernet/huawei/hinic3/hinic3_tx.c | 141 +-
drivers/net/ethernet/huawei/hinic3/hinic3_wq.h | 4 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c | 15 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c | 13 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h | 5 -
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c | 206 ++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h | 13 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c | 5 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c | 14 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c | 42 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c | 91 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h | 13 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c | 163 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c | 116 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c | 87 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h | 34 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c | 40 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c | 1221 +++++++++++++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c | 3 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c | 6 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c | 44 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c | 182 ++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h | 4 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h | 31 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c | 52 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c | 2 +-
drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h | 4 +
.../include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h | 13 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h | 42 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h | 2 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h | 130 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h | 109 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h | 5 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h | 30 +-
.../include/mpu/mpu_outband_ncsi_cmd_defs.h | 8 +
drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h | 16 +-
drivers/net/ethernet/huawei/hinic3/include/vram_common.h | 11 +-
drivers/net/ethernet/huawei/hinic3/{mag_cmd.h => mag_mpu_cmd_defs.h} | 237 ++-
drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h | 27 -
drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h | 63 -
drivers/net/ethernet/huawei/hinic3/{hinic3_nic_cmd.h => nic_mpu_cmd.h} | 59 +-
drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h | 1420 +++++++++++++++++
drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h | 36 +
drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h | 94 +-
96 files changed, 8366 insertions(+), 3041 deletions(-)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_defs.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_common.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
rename drivers/net/ethernet/huawei/hinic3/{mag_cmd.h => mag_mpu_cmd_defs.h} (79%)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
rename drivers/net/ethernet/huawei/hinic3/{hinic3_nic_cmd.h => nic_mpu_cmd.h} (77%)
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
diff --git a/drivers/net/ethernet/huawei/hinic3/Makefile b/drivers/net/ethernet/huawei/hinic3/Makefile
index 11fe010..21d8093 100644
--- a/drivers/net/ethernet/huawei/hinic3/Makefile
+++ b/drivers/net/ethernet/huawei/hinic3/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/hw/
+ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/bond/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/cqm/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/cqm/
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
index ba3076c..a252e09 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
@@ -9,14 +9,18 @@
#include <linux/net.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
+#include <linux/version.h>
+#include "ossl_knl.h"
#include "hinic3_lld.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic_dev.h"
#include "hinic3_hw.h"
-#include "mpu_inband_cmd.h"
-#include "hinic3_hwdev.h"
#include "hinic3_bond.h"
+#include "hinic3_hwdev.h"
+
+#include "bond_common_defs.h"
+#include "vram_common.h"
#define PORT_INVALID_ID 0xFF
@@ -214,10 +218,10 @@ static void bond_dev_untrack_port(struct hinic3_bond_dev *bdev, u8 idx)
spin_lock(&bdev->lock);
if (bdev->tracker.ndev[idx]) {
- pr_info("hinic3_bond: untrack port:%u ndev:%s cnt:%d\n", idx,
- bdev->tracker.ndev[idx]->name, bdev->tracker.cnt);
bdev->tracker.ndev[idx] = NULL;
bdev->tracker.cnt--;
+ pr_info("hinic3_bond: untrack port:%u ndev:%s cnt:%d\n", idx,
+ bdev->tracker.ndev[idx]->name, bdev->tracker.cnt);
}
spin_unlock(&bdev->lock);
@@ -268,11 +272,16 @@ static void bond_master_event(struct hinic3_bond_dev *bdev,
queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
}
-static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
+static struct hinic3_bond_dev *bond_get_bdev(struct bonding *bond)
{
struct hinic3_bond_dev *bdev = NULL;
int bid;
+ if (bond == NULL) {
+ pr_err("hinic3_bond: bond is NULL\n");
+ return NULL;
+ }
+
mutex_lock(&g_bond_mutex);
for (bid = BOND_FIRST_ID; bid <= BOND_MAX_ID; bid++) {
bdev = bond_mngr.bond_dev[bid];
@@ -283,38 +292,72 @@ static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
mutex_unlock(&g_bond_mutex);
return bdev;
}
+
+ if (strncmp(bond->dev->name, bdev->name, BOND_NAME_MAX_LEN) == 0) {
+ bdev->bond = bond;
+ return bdev;
+ }
}
mutex_unlock(&g_bond_mutex);
return NULL;
}
-static void bond_handle_rtnl_event(struct net_device *ndev)
+static struct bonding *get_bonding_by_netdev(struct net_device *ndev)
{
- struct hinic3_bond_dev *bdev = NULL;
struct bonding *bond = NULL;
struct slave *slave = NULL;
if (netif_is_bond_master(ndev)) {
bond = netdev_priv(ndev);
- bdev = bond_get_bdev(bond);
} else if (netif_is_bond_slave(ndev)) {
- /*lint -e(160) */
slave = bond_slave_get_rtnl(ndev);
if (slave) {
bond = bond_get_bond_by_slave(slave);
- bdev = bond_get_bdev(bond);
}
}
- if (!bond || !bdev)
+ return bond;
+}
+/*lint -e580 -e546*/
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+
+ if (!ndev) {
+ pr_err("hinic3_bond: netdev is NULL\n");
+ return false;
+ }
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
+ return false;
+
+ return bdev->status == BOND_DEV_STATUS_ACTIVATED;
+}
+EXPORT_SYMBOL(hinic3_is_bond_dev_status_actived);
+/*lint +e580 +e546*/
+
+static void bond_handle_rtnl_event(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+ struct slave *slave = NULL;
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
return;
bond_update_attr(bdev, bond);
- if (slave)
+ if (netif_is_bond_slave(ndev)) {
+ slave = bond_slave_get_rtnl(ndev);
bond_slave_event(bdev, slave);
- else
+ } else {
bond_master_event(bdev, bond);
+ }
}
static void bond_rtnl_data_ready(struct sock *sk)
@@ -478,7 +521,11 @@ static void bond_update_slave_info(struct hinic3_bond_dev *bdev,
continue;
}
+ if (!bdev->tracker.ndev[i])
+ continue;
+
bond_pf_bitmap_set(bdev, i);
+
if (!bdev->tracker.netdev_state[i].tx_enabled)
continue;
@@ -516,6 +563,7 @@ static int bond_upcmd_config(struct hinic3_bond_dev *bdev,
attr->active_slaves,
attr->lacp_collect_slaves);
pr_info("bond_pf_bitmap: 0x%x\n", attr->bond_pf_bitmap);
+ pr_info("bond user_bitmap 0x%x\n", attr->user_bitmap);
err = bond_send_upcmd(bdev, attr, MPU_CMD_BOND_SET_ATTR);
if (!err)
@@ -560,17 +608,36 @@ static void bond_call_service_func(struct hinic3_bond_dev *bdev, struct bond_att
mutex_unlock(&g_bond_service_func_mutex);
}
+static u32 bond_get_user_bitmap(struct hinic3_bond_dev *bdev)
+{
+ u32 user_bitmap = 0;
+ u8 user;
+
+ for (user = HINIC3_BOND_USER_OVS; user < HINIC3_BOND_USER_NUM; user++) {
+ if (bdev->slot_used[user] == 1)
+ BITMAP_SET(user_bitmap, user);
+ }
+ return user_bitmap;
+}
+
static void bond_do_work(struct hinic3_bond_dev *bdev)
{
bool is_bonded = 0;
struct bond_attr attr;
+ int is_in_kexec;
int err = 0;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ pr_info("Skip changing bond status during os replace\n");
+ return;
+ }
+
spin_lock(&bdev->lock);
is_bonded = bdev->tracker.is_bonded;
attr = bdev->new_attr;
spin_unlock(&bdev->lock);
- attr.user_bitmap = 0;
+ attr.user_bitmap = bond_get_user_bitmap(bdev);
/* is_bonded indicates whether bond should be activated. */
if (is_bonded && !bond_dev_is_activated(bdev)) {
@@ -591,17 +658,21 @@ static void bond_do_work(struct hinic3_bond_dev *bdev)
pr_err("hinic3_bond: Do bond failed\n");
}
-#define MIN_BOND_SLAVE_CNT 2
static void bond_try_do_work(struct work_struct *work)
{
struct delayed_work *delayed_work = to_delayed_work(work);
struct hinic3_bond_dev *bdev =
container_of(delayed_work, struct hinic3_bond_dev, bond_work);
+ int status;
- if (g_bond_service_func[HINIC3_BOND_USER_ROCE] && bdev->tracker.cnt < MIN_BOND_SLAVE_CNT)
+ status = mutex_trylock(&g_bond_mutex);
+ if (status == 0) {
+ /* Delay 1 sec and retry */
queue_delayed_work(bdev->wq, &bdev->bond_work, HZ);
- else
+ } else {
bond_do_work(bdev);
+ mutex_unlock(&g_bond_mutex);
+ }
}
static int bond_dev_init(struct hinic3_bond_dev *bdev, const char *name)
@@ -630,6 +701,7 @@ static int bond_dev_release(struct hinic3_bond_dev *bdev)
err = bond_upcmd_deactivate(bdev);
if (err) {
pr_err("hinic3_bond: Failed to deactivate dev\n");
+ mutex_unlock(&g_bond_mutex);
return err;
}
@@ -764,20 +836,28 @@ static struct hinic3_bond_dev *bond_dev_by_name(const char *name)
static void bond_dev_user_attach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user)
{
+ u32 user_bitmap;
+
+ if (user < 0 || user >= HINIC3_BOND_USER_NUM)
+ return;
+
if (bdev->slot_used[user])
return;
bdev->slot_used[user] = 1;
if (!kref_get_unless_zero(&bdev->ref))
kref_init(&bdev->ref);
+ else {
+ user_bitmap = bond_get_user_bitmap(bdev);
+ pr_info("hinic3_bond: user %u attach bond %s, user_bitmap %#x\n",
+ user, bdev->name, user_bitmap);
+ queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
+ }
}
static void bond_dev_user_detach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user, bool *freed)
{
- if (user < 0 || user >= HINIC3_BOND_USER_NUM)
- return;
-
if (bdev->slot_used[user]) {
bdev->slot_used[user] = 0;
if (kref_read(&bdev->ref) == 1)
@@ -790,12 +870,15 @@ static struct bonding *bond_get_knl_bonding(const char *name)
{
struct net_device *ndev_tmp = NULL;
+ rcu_read_lock();
for_each_netdev(&init_net, ndev_tmp) {
if (netif_is_bond_master(ndev_tmp) &&
- !strcmp(ndev_tmp->name, name))
+ !strcmp(ndev_tmp->name, name)) {
+ rcu_read_unlock();
return netdev_priv(ndev_tmp);
+ }
}
-
+ rcu_read_unlock();
return NULL;
}
@@ -852,8 +935,9 @@ int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user)
int err = 0;
bool lock_freed = false;
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
- pr_warn("hinic3_bond: Invalid bond id:%u to delete\n", bond_id);
+ if (!BOND_ID_IS_VALID(bond_id) || user >= HINIC3_BOND_USER_NUM) {
+ pr_warn("hinic3_bond: Invalid bond id or user, bond_id: %u, user: %d\n",
+ bond_id, user);
return -EINVAL;
}
@@ -891,7 +975,7 @@ EXPORT_SYMBOL(hinic3_bond_clean_user);
int hinic3_bond_get_uplink_id(u16 bond_id, u32 *uplink_id)
{
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID || !uplink_id) {
+ if (!BOND_ID_IS_VALID(bond_id) || !uplink_id) {
pr_warn("hinic3_bond: Invalid args, id: %u, uplink: %d\n",
bond_id, !!uplink_id);
return -EINVAL;
@@ -941,7 +1025,7 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
int i;
int len;
- if (!info || bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
+ if (!info || !BOND_ID_IS_VALID(bond_id)) {
pr_warn("hinic3_bond: Invalid args, info: %d,id: %u\n",
!!info, bond_id);
return -EINVAL;
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
index 024de95..5ab36f7 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
@@ -82,6 +82,7 @@ struct hinic3_bond_cmd {
char bond_name[16];
};
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev);
void hinic3_bond_set_user_bitmap(struct bond_attr *attr, enum hinic3_bond_user user);
int hinic3_bond_attach(const char *name, enum hinic3_bond_user user, u16 *bond_id);
int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user);
diff --git a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h b/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
deleted file mode 100644
index 557f326..0000000
--- a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2016-2022. All rights reserved.
- * File name: Cfg_mgt_comm_pub.h
- * Version No.: Draft
- * Generation date: 2016 year 05 month 07 day
- * Latest modification:
- * Function description: Header file for communication between the: Host and FW
- * Function list:
- * Modification history:
- * 1. Date: 2016 May 07
- * Modify content: Create a file.
- */
-#ifndef CFG_MGT_COMM_PUB_H
-#define CFG_MGT_COMM_PUB_H
-
-#include "mgmt_msg_base.h"
-
-enum servic_bit_define {
- SERVICE_BIT_NIC = 0,
- SERVICE_BIT_ROCE = 1,
- SERVICE_BIT_VBS = 2,
- SERVICE_BIT_TOE = 3,
- SERVICE_BIT_IPSEC = 4,
- SERVICE_BIT_FC = 5,
- SERVICE_BIT_VIRTIO = 6,
- SERVICE_BIT_OVS = 7,
- SERVICE_BIT_NVME = 8,
- SERVICE_BIT_ROCEAA = 9,
- SERVICE_BIT_CURRENET = 10,
- SERVICE_BIT_PPA = 11,
- SERVICE_BIT_MIGRATE = 12,
- SERVICE_BIT_MAX
-};
-
-#define CFG_SERVICE_MASK_NIC (0x1 << SERVICE_BIT_NIC)
-#define CFG_SERVICE_MASK_ROCE (0x1 << SERVICE_BIT_ROCE)
-#define CFG_SERVICE_MASK_VBS (0x1 << SERVICE_BIT_VBS)
-#define CFG_SERVICE_MASK_TOE (0x1 << SERVICE_BIT_TOE)
-#define CFG_SERVICE_MASK_IPSEC (0x1 << SERVICE_BIT_IPSEC)
-#define CFG_SERVICE_MASK_FC (0x1 << SERVICE_BIT_FC)
-#define CFG_SERVICE_MASK_VIRTIO (0x1 << SERVICE_BIT_VIRTIO)
-#define CFG_SERVICE_MASK_OVS (0x1 << SERVICE_BIT_OVS)
-#define CFG_SERVICE_MASK_NVME (0x1 << SERVICE_BIT_NVME)
-#define CFG_SERVICE_MASK_ROCEAA (0x1 << SERVICE_BIT_ROCEAA)
-#define CFG_SERVICE_MASK_CURRENET (0x1 << SERVICE_BIT_CURRENET)
-#define CFG_SERVICE_MASK_PPA (0x1 << SERVICE_BIT_PPA)
-#define CFG_SERVICE_MASK_MIGRATE (0x1 << SERVICE_BIT_MIGRATE)
-
-/* Definition of the scenario ID in the cfg_data, which is used for SML memory allocation. */
-enum scenes_id_define {
- SCENES_ID_FPGA_ETH = 0,
- SCENES_ID_FPGA_TIOE = 1, /* Discarded */
- SCENES_ID_STORAGE_ROCEAA_2x100 = 2,
- SCENES_ID_STORAGE_ROCEAA_4x25 = 3,
- SCENES_ID_CLOUD = 4,
- SCENES_ID_FC = 5,
- SCENES_ID_STORAGE_ROCE = 6,
- SCENES_ID_COMPUTE_ROCE = 7,
- SCENES_ID_STORAGE_TOE = 8,
- SCENES_ID_MAX
-};
-
-/* struct cfg_cmd_dev_cap.sf_svc_attr */
-enum {
- SF_SVC_FT_BIT = (1 << 0),
- SF_SVC_RDMA_BIT = (1 << 1),
-};
-
-enum cfg_cmd {
- CFG_CMD_GET_DEV_CAP = 0,
- CFG_CMD_GET_HOST_TIMER = 1,
-};
-
-struct cfg_cmd_host_timer {
- struct mgmt_msg_head head;
-
- u8 host_id;
- u8 rsvd1;
-
- u8 timer_pf_num;
- u8 timer_pf_id_start;
- u16 timer_vf_num;
- u16 timer_vf_id_start;
- u32 rsvd2[8];
-};
-
-struct cfg_cmd_dev_cap {
- struct mgmt_msg_head head;
-
- u16 func_id;
- u16 rsvd1;
-
- /* Public resources */
- u8 host_id;
- u8 ep_id;
- u8 er_id;
- u8 port_id;
-
- u16 host_total_func;
- u8 host_pf_num;
- u8 pf_id_start;
- u16 host_vf_num;
- u16 vf_id_start;
- u8 host_oq_id_mask_val;
- u8 timer_en;
- u8 host_valid_bitmap;
- u8 rsvd_host;
-
- u16 svc_cap_en;
- u16 max_vf;
- u8 flexq_en;
- u8 valid_cos_bitmap;
- /* Reserved for func_valid_cos_bitmap */
- u8 port_cos_valid_bitmap;
- u8 rsvd_func1;
- u32 rsvd_func2;
-
- u8 sf_svc_attr;
- u8 func_sf_en;
- u8 lb_mode;
- u8 smf_pg;
-
- u32 max_conn_num;
- u16 max_stick2cache_num;
- u16 max_bfilter_start_addr;
- u16 bfilter_len;
- u16 hash_bucket_num;
-
- /* shared resource */
- u8 host_sf_en;
- u8 master_host_id;
- u8 srv_multi_host_mode;
- u8 virtio_vq_size;
-
- u32 rsvd_func3[5];
-
- /* l2nic */
- u16 nic_max_sq_id;
- u16 nic_max_rq_id;
- u16 nic_default_num_queues;
- u16 rsvd1_nic;
- u32 rsvd2_nic[2];
-
- /* RoCE */
- u32 roce_max_qp;
- u32 roce_max_cq;
- u32 roce_max_srq;
- u32 roce_max_mpt;
- u32 roce_max_drc_qp;
-
- u32 roce_cmtt_cl_start;
- u32 roce_cmtt_cl_end;
- u32 roce_cmtt_cl_size;
-
- u32 roce_dmtt_cl_start;
- u32 roce_dmtt_cl_end;
- u32 roce_dmtt_cl_size;
-
- u32 roce_wqe_cl_start;
- u32 roce_wqe_cl_end;
- u32 roce_wqe_cl_size;
- u8 roce_srq_container_mode;
- u8 rsvd_roce1[3];
- u32 rsvd_roce2[5];
-
- /* IPsec */
- u32 ipsec_max_sactx;
- u16 ipsec_max_cq;
- u16 rsvd_ipsec1;
- u32 rsvd_ipsec[2];
-
- /* OVS */
- u32 ovs_max_qpc;
- u32 rsvd_ovs1[3];
-
- /* ToE */
- u32 toe_max_pctx;
- u32 toe_max_cq;
- u16 toe_max_srq;
- u16 toe_srq_id_start;
- u16 toe_max_mpt;
- u16 toe_max_cctxt;
- u32 rsvd_toe[2];
-
- /* FC */
- u32 fc_max_pctx;
- u32 fc_max_scq;
- u32 fc_max_srq;
-
- u32 fc_max_cctx;
- u32 fc_cctx_id_start;
-
- u8 fc_vp_id_start;
- u8 fc_vp_id_end;
- u8 rsvd_fc1[2];
- u32 rsvd_fc2[5];
-
- /* VBS */
- u16 vbs_max_volq;
- u16 rsvd0_vbs;
- u32 rsvd1_vbs[3];
-
- u16 fake_vf_start_id;
- u16 fake_vf_num;
- u32 fake_vf_max_pctx;
- u16 fake_vf_bfilter_start_addr;
- u16 fake_vf_bfilter_len;
- u32 rsvd_glb[8];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
deleted file mode 100644
index 6f5f87b..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/******************************************************************************
- * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
- ******************************************************************************
- File Name : comm_cmdq_intf.h
- Version : Initial Draft
- Description : common command queue interface
- Function List :
- History :
- Modification: Created file
-
-******************************************************************************/
-
-#ifndef COMM_CMDQ_INTF_H
-#define COMM_CMDQ_INTF_H
-
-/* Cmdq ack type */
-enum hinic3_ack_type {
- HINIC3_ACK_TYPE_CMDQ,
- HINIC3_ACK_TYPE_SHARE_CQN,
- HINIC3_ACK_TYPE_APP_CQN,
-
- HINIC3_MOD_ACK_MAX = 15,
-};
-
-/* Defines the queue type of the set arm bit. */
-enum {
- SET_ARM_BIT_FOR_CMDQ = 0,
- SET_ARM_BIT_FOR_L2NIC_SQ,
- SET_ARM_BIT_FOR_L2NIC_RQ,
- SET_ARM_BIT_TYPE_NUM
-};
-
-/* Defines the type. Each function supports a maximum of eight CMDQ types. */
-enum {
- CMDQ_0 = 0,
- CMDQ_1 = 1, /* dedicated and non-blocking queues */
- CMDQ_NUM
-};
-
-/* *******************cmd common command data structure ************************ */
-// Func->ucode, which is used to set arm bit data,
-// The microcode needs to perform big-endian conversion.
-struct comm_info_ucode_set_arm_bit {
- u32 q_type;
- u32 q_id;
-};
-
-/* *******************WQE data structure ************************ */
-union cmdq_wqe_cs_dw0 {
- struct {
- u32 err_status : 29;
- u32 error_code : 2;
- u32 rsvd : 1;
- } bs;
- u32 val;
-};
-
-union cmdq_wqe_cs_dw1 {
- // This structure is used when the driver writes the wqe.
- struct {
- u32 token : 16; // [15:0]
- u32 cmd : 8; // [23:16]
- u32 mod : 5; // [28:24]
- u32 ack_type : 2; // [30:29]
- u32 obit : 1; // [31]
- } drv_wr;
-
- /* The uCode writes back the structure of the CS_DW1.
- * The driver reads and uses the structure. */
- struct {
- u32 mod : 5; // [4:0]
- u32 ack_type : 3; // [7:5]
- u32 cmd : 8; // [15:8]
- u32 arm : 1; // [16]
- u32 rsvd : 14; // [30:17]
- u32 obit : 1; // [31]
- } wb;
- u32 val;
-};
-
-/* CmdQ BD information or write back buffer information */
-struct cmdq_sge {
- u32 pa_h; // Upper 32 bits of the physical address
- u32 pa_l; // Upper 32 bits of the physical address
- u32 len; // Invalid bit[31].
- u32 resv;
-};
-
-/* Ctrls section definition of WQE */
-struct cmdq_wqe_ctrls {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
-};
-
-/* Complete section definition of WQE */
-struct cmdq_wqe_cs {
- union cmdq_wqe_cs_dw0 dw0;
- union cmdq_wqe_cs_dw1 dw1;
- union {
- struct cmdq_sge sge;
- u32 dw2_5[4];
- } ack;
-};
-
-/* Inline header in WQE inline, describing the length of inline data */
-union cmdq_wqe_inline_header {
- struct {
- u32 buf_len : 11; // [10:0] inline data len
- u32 rsv : 21; // [31:11]
- } bs;
- u32 val;
-};
-
-/* Definition of buffer descriptor section in WQE */
-union cmdq_wqe_bds {
- struct {
- struct cmdq_sge bds_sge;
- u32 rsvd[4]; /* Zwy is used to transfer the virtual address of the buffer. */
- } lcmd; /* Long command, non-inline, and SGE describe the buffer information. */
-};
-
-/* Definition of CMDQ WQE */
-/* (long cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(16B) |
- * | |
- * +----------------------------------------+
- * | driver section(16B) |
- * +----------------------------------------+
- *
- *
- * (middle cmd, 128B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(88B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- *
- *
- * (short cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(24B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- */
-struct cmdq_wqe {
- struct cmdq_wqe_ctrls ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds bds;
-};
-
-/* Definition of ctrls section in inline WQE */
-struct cmdq_wqe_ctrls_inline {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
- u64 db;
-};
-
-/* Buffer descriptor section definition of WQE */
-union cmdq_wqe_bds_inline {
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[80];
- } mcmd; /* Middle command, inline mode */
-
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[16];
- } scmd; /* Short command, inline mode */
-};
-
-struct cmdq_wqe_inline {
- struct cmdq_wqe_ctrls_inline ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds_inline bds;
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_defs.h b/drivers/net/ethernet/huawei/hinic3/comm_defs.h
deleted file mode 100644
index 91d298d..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_defs.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_defs.h
- * Version : Initial Draft
- * Description : common definitions
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef COMM_DEFS_H
-#define COMM_DEFS_H
-
-/* CMDQ MODULE_TYPE */
-enum hinic3_mod_type {
- HINIC3_MOD_COMM = 0, /* HW communication module */
- HINIC3_MOD_L2NIC = 1, /* L2NIC module */
- HINIC3_MOD_ROCE = 2,
- HINIC3_MOD_PLOG = 3,
- HINIC3_MOD_TOE = 4,
- HINIC3_MOD_FLR = 5,
- HINIC3_MOD_RSVD1 = 6,
- HINIC3_MOD_CFGM = 7, /* Configuration module */
- HINIC3_MOD_CQM = 8,
- HINIC3_MOD_RSVD2 = 9,
- COMM_MOD_FC = 10,
- HINIC3_MOD_OVS = 11,
- HINIC3_MOD_DSW = 12,
- HINIC3_MOD_MIGRATE = 13,
- HINIC3_MOD_HILINK = 14,
- HINIC3_MOD_CRYPT = 15, /* secure crypto module */
- HINIC3_MOD_VIO = 16,
- HINIC3_MOD_IMU = 17,
- HINIC3_MOD_DFT = 18, /* DFT */
- HINIC3_MOD_HW_MAX = 19, /* hardware max module id */
- /* Software module id, for PF/VF and multi-host */
- HINIC3_MOD_SW_FUNC = 20,
- HINIC3_MOD_MAX,
-};
-
-/* func reset的flag ,用于指示清理哪种资源 */
-enum func_reset_flag {
- RES_TYPE_FLUSH_BIT = 0,
- RES_TYPE_MQM,
- RES_TYPE_SMF,
- RES_TYPE_PF_BW_CFG,
-
- RES_TYPE_COMM = 10,
- RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_NIC,
- RES_TYPE_OVS,
- RES_TYPE_VBS,
- RES_TYPE_ROCE,
- RES_TYPE_FC,
- RES_TYPE_TOE,
- RES_TYPE_IPSEC,
- RES_TYPE_MAX,
-};
-
-#define HINIC3_COMM_RES \
- ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
- (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
- (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
-
-#define HINIC3_NIC_RES (1 << RES_TYPE_NIC)
-#define HINIC3_OVS_RES (1 << RES_TYPE_OVS)
-#define HINIC3_VBS_RES (1 << RES_TYPE_VBS)
-#define HINIC3_ROCE_RES (1 << RES_TYPE_ROCE)
-#define HINIC3_FC_RES (1 << RES_TYPE_FC)
-#define HINIC3_TOE_RES (1 << RES_TYPE_TOE)
-#define HINIC3_IPSEC_RES (1 << RES_TYPE_IPSEC)
-
-/* MODE OVS、NIC、UNKNOWN */
-#define HINIC3_WORK_MODE_OVS 0
-#define HINIC3_WORK_MODE_UNKNOWN 1
-#define HINIC3_WORK_MODE_NIC 2
-
-#define DEVICE_TYPE_L2NIC 0
-#define DEVICE_TYPE_NVME 1
-#define DEVICE_TYPE_VIRTIO_NET 2
-#define DEVICE_TYPE_VIRTIO_BLK 3
-#define DEVICE_TYPE_VIRTIO_VSOCK 4
-#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
-#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
-#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
-#define DEVICE_TYPE_VIRTIO_HPC 8
-
-#define IS_STORAGE_DEVICE_TYPE(dev_type) \
- ((dev_type) == DEVICE_TYPE_VIRTIO_BLK || \
- (dev_type) == DEVICE_TYPE_VIRTIO_BLK_TRANSITION || \
- (dev_type) == DEVICE_TYPE_VIRTIO_SCSI_TRANSITION)
-
-/* Common header control information of the COMM message
- * interaction command word between the driver and PF
- */
-struct comm_info_head {
- u8 status;
- u8 version;
- u8 rep_aeq_num;
- u8 rsvd[5];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
deleted file mode 100644
index ae998cf..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_msg_intf.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef COMM_MSG_INTF_H
-#define COMM_MSG_INTF_H
-
-#include "comm_defs.h"
-#include "mgmt_msg_base.h"
-#include "mpu_cmd_base_defs.h"
-#include "mpu_inband_cmd_defs.h"
-
-struct spu_cmd_freq_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: check */
- u8 rsvd[3];
- u32 freq;
-};
-
-struct spu_cmd_power_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: init */
- u8 slave_addr;
- u8 cmd_id;
- u8 size;
- u32 value;
-};
-
-struct spu_cmd_tsensor_operation {
- struct comm_info_head head;
-
- u8 op_code;
- u8 rsvd[3];
- s16 fabric_tsensor_temp_avg;
- s16 fabric_tsensor_temp;
- s16 sys_tsensor_temp_avg;
- s16 sys_tsensor_temp;
-};
-
-enum cfg_msix_operation {
- CFG_MSIX_OPERATION_FREE = 0,
- CFG_MSIX_OPERATION_ALLOC = 1,
-};
-
-struct comm_cmd_ffm_info {
- struct mgmt_msg_head head;
-
- u8 node_id;
- /* error level of the interrupt source */
- u8 err_level;
- /* Classification by interrupt source properties */
- u16 err_type;
- u32 err_csr_addr;
- u32 err_csr_value;
- u32 rsvd1;
-};
-
-struct hinic3_cmd_update_firmware {
- struct mgmt_msg_head msg_head;
-
- struct {
- u32 sl : 1;
- u32 sf : 1;
- u32 flag : 1;
- u32 bit_signed : 1;
- u32 reserved : 12;
- u32 fragment_len : 16;
- } ctl_info;
-
- struct {
- u32 section_crc;
- u32 section_type;
- } section_info;
-
- u32 total_len;
- u32 section_len;
- u32 section_version;
- u32 section_offset;
- u32 data[384];
-};
-
-struct hinic3_cmd_activate_firmware {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-struct hinic3_cmd_switch_config {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
index 76e128e..1562c59 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
@@ -28,6 +28,8 @@
#include "cqm_npu_cmd.h"
#include "cqm_npu_cmd_defs.h"
+#include "vram_common.h"
+
static void cqm_bat_fill_cla_common_gpa(struct tag_cqm_handle *cqm_handle,
struct tag_cqm_cla_table *cla_table,
struct tag_cqm_bat_entry_standerd *bat_entry_standerd)
@@ -367,6 +369,14 @@ static s32 cqm_bat_update_cmd(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
struct tag_cqm_cmdq_bat_update *bat_update_cmd = NULL;
s32 ret = CQM_FAIL;
+ int is_in_kexec;
+
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip updating the cqm_bat to chip during kexec!\n");
+ return CQM_SUCCESS;
+ }
+
bat_update_cmd = (struct tag_cqm_cmdq_bat_update *)(buf_in->buf);
bat_update_cmd->offset = 0;
@@ -644,6 +654,7 @@ void cqm_bat_uninit(struct tag_cqm_handle *cqm_handle)
static s32 cqm_cla_fill_buf(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *cla_base_buf,
struct tag_cqm_buf *cla_sub_buf, u8 gpa_check_enable)
{
+ struct hinic3_hwdev *handle = cqm_handle->ex_handle;
struct hinic3_func_attr *func_attr = NULL;
dma_addr_t *base = NULL;
u64 fake_en = 0;
@@ -655,13 +666,17 @@ static s32 cqm_cla_fill_buf(struct tag_cqm_handle *cqm_handle, struct tag_cqm_bu
/* Apply for space for base_buf */
if (!cla_base_buf->buf_list) {
- if (cqm_buf_alloc(cqm_handle, cla_base_buf, false) == CQM_FAIL)
+ if (cqm_buf_alloc(cqm_handle, cla_base_buf, false) ==
+ CQM_FAIL) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(cla_base_buf));
return CQM_FAIL;
+ }
}
/* Apply for space for sub_buf */
if (!cla_sub_buf->buf_list) {
if (cqm_buf_alloc(cqm_handle, cla_sub_buf, false) == CQM_FAIL) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(cla_sub_buf));
cqm_buf_free(cla_base_buf, cqm_handle);
return CQM_FAIL;
}
@@ -768,8 +783,10 @@ static s32 cqm_cla_xyz_lvl1(struct tag_cqm_handle *cqm_handle,
/* Applying for CLA_Z_BUF Space */
cla_z_buf = &cla_table->cla_z_buf;
cla_z_buf->buf_size = trunk_size;
- cla_z_buf->buf_number = (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
- cla_z_buf->page_number = cla_z_buf->buf_number << cla_table->trunk_order;
+ cla_z_buf->buf_number =
+ (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
+ cla_z_buf->page_number = cla_z_buf->buf_number <<
+ cla_table->trunk_order;
/* All buffer space must be statically allocated. */
if (cla_table->alloc_static) {
@@ -785,6 +802,7 @@ static s32 cqm_cla_xyz_lvl1(struct tag_cqm_handle *cqm_handle,
cla_z_buf->buf_list = vmalloc(cla_z_buf->buf_number *
sizeof(struct tag_cqm_buf_list));
if (!cla_z_buf->buf_list) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_1_z_buf));
cqm_buf_free(cla_y_buf, cqm_handle);
return CQM_FAIL;
}
@@ -840,6 +858,7 @@ static s32 cqm_cla_xyz_lvl2_xyz_apply(struct tag_cqm_handle *cqm_handle,
cla_x_buf->buf_size = trunk_size;
cla_x_buf->buf_number = 1;
cla_x_buf->page_number = cla_x_buf->buf_number << cla_table->trunk_order;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
ret = cqm_buf_alloc(cqm_handle, cla_x_buf, false);
if (ret != CQM_SUCCESS)
return CQM_FAIL;
@@ -869,14 +888,20 @@ static s32 cqm_cla_xyz_vram_name_init(struct tag_cqm_cla_table *cla_table,
cla_x_buf = &cla_table->cla_x_buf;
cla_z_buf = &cla_table->cla_z_buf;
cla_y_buf = &cla_table->cla_y_buf;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_x_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_X);
+ VRAM_NAME_APPLY_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_X);
+ cla_y_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_y_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Y);
+ VRAM_NAME_APPLY_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Y);
+ cla_z_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_z_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Z);
+ VRAM_NAME_APPLY_LEN, "%s%s",
+ cla_table->name, VRAM_CQM_CLA_COORD_Z);
return CQM_SUCCESS;
}
@@ -925,6 +950,7 @@ static s32 cqm_cla_xyz_lvl2(struct tag_cqm_handle *cqm_handle,
cla_z_buf->buf_list = vmalloc(cla_z_buf->buf_number *
sizeof(struct tag_cqm_buf_list));
if (!cla_z_buf->buf_list) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_2_z_buf));
cqm_buf_free(cla_x_buf, cqm_handle);
return CQM_FAIL;
}
@@ -934,6 +960,7 @@ static s32 cqm_cla_xyz_lvl2(struct tag_cqm_handle *cqm_handle,
cla_y_buf->buf_list = vmalloc(cla_y_buf->buf_number *
sizeof(struct tag_cqm_buf_list));
if (!cla_y_buf->buf_list) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_2_y_buf));
cqm_buf_free(cla_z_buf, cqm_handle);
cqm_buf_free(cla_x_buf, cqm_handle);
return CQM_FAIL;
@@ -1188,7 +1215,7 @@ static void cqm_cla_init_entry_extern(struct tag_cqm_handle *cqm_handle,
* exceed 128 x 4 KB. Otherwise, clearing the timer buffer of
* the function is complex.
*/
- cla_table->trunk_order = CQM_4K_PAGE_ORDER;
+ cla_table->trunk_order = CQM_8K_PAGE_ORDER;
cla_table->max_buffer_size = capability->timer_number *
capability->timer_basic_size;
cla_table->obj_size = capability->timer_basic_size;
@@ -1237,7 +1264,7 @@ static s32 cqm_cla_init_entry_condition(struct tag_cqm_handle *cqm_handle, u32 e
memcpy(cla_table_timer, cla_table, sizeof(struct tag_cqm_cla_table));
snprintf(cla_table_timer->name,
- VRAM_NAME_MAX_LEN - 1, "%s%s%01u", cla_table->name,
+ VRAM_NAME_APPLY_LEN, "%s%s%01u", cla_table->name,
VRAM_CQM_CLA_SMF_BASE, i);
if (cqm_cla_xyz(cqm_handle, cla_table_timer) ==
@@ -1268,7 +1295,7 @@ static s32 cqm_cla_init_entry(struct tag_cqm_handle *cqm_handle,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
cla_table->type = bat_table->bat_entry_type[i];
- snprintf(cla_table->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(cla_table->name, VRAM_NAME_APPLY_LEN,
"%s%s%s%02u", cqm_handle->name, VRAM_CQM_CLA_BASE,
VRAM_CQM_CLA_TYPE_BASE, cla_table->type);
@@ -1485,11 +1512,11 @@ static s32 cqm_cla_update(struct tag_cqm_handle *cqm_handle,
spu_en = 0;
pa = ((buf_node_parent->pa + (child_index * sizeof(dma_addr_t))) |
- (u32)spu_en);
+ spu_en);
cmd.gpa_h = CQM_ADDR_HI(pa);
cmd.gpa_l = CQM_ADDR_LW(pa);
- pa = (buf_node_child->pa | (u32)spu_en);
+ pa = (buf_node_child->pa | spu_en);
cmd.value_h = CQM_ADDR_HI(pa);
cmd.value_l = CQM_ADDR_LW(pa);
@@ -1980,7 +2007,7 @@ struct tag_cqm_cla_table *cqm_cla_table_get(struct tag_cqm_bat_table *bat_table,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
- if (cla_table && entry_type == cla_table->type)
+ if ((cla_table != NULL) && (entry_type == cla_table->type))
return cla_table;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
index dd0766e..a51c1dc 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
@@ -9,6 +9,7 @@
#include "cqm_bitmap_table.h"
#include "cqm_object.h"
+#include "vram_common.h"
/* When the connection check is enabled, the maximum number of connections
* supported by the chip is 1M - 63, which cannot reach 1M
@@ -19,6 +20,7 @@
#define CLA_TABLE_PAGE_ORDER 0
#define CQM_4K_PAGE_ORDER 0
#define CQM_4K_PAGE_SIZE 4096
+#define CQM_8K_PAGE_ORDER 1
#define CQM_BAT_ENTRY_MAX 16
#define CQM_BAT_ENTRY_SIZE 16
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
index f4844d5..86b268c 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
@@ -254,8 +254,10 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
}
pages = vmalloc(sizeof(struct page *) * buf->page_number);
- if (!pages)
+ if (!pages) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(pages));
return CQM_FAIL;
+ }
for (i = 0; i < buf->buf_number; i++) {
for (j = 0; j < ((u32)1 << order); j++)
@@ -273,6 +275,11 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
return CQM_SUCCESS;
}
+static bool check_use_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ return buf->buf_info.use_vram ? true : false;
+}
+
static bool check_use_non_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
{
return buf->buf_info.use_vram ? false : true;
@@ -294,11 +301,48 @@ static bool check_for_nouse_node_alloc(struct hinic3_hwdev *handle, struct tag_c
return false;
}
+static s32 cqm_buf_vram_kalloc(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ void *vaddr = NULL;
+ int i;
+
+ vaddr = hi_vram_kalloc(buf->buf_info.buf_vram_name, (u64)buf->buf_size * buf->buf_number);
+ if (!vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
+ return CQM_FAIL;
+ }
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = (void *)((char *)vaddr + i * (u64)buf->buf_size);
+
+ return CQM_SUCCESS;
+}
+
+static void cqm_buf_vram_free(struct tag_cqm_buf *buf)
+{
+ s32 i;
+
+ if (buf->buf_list == NULL) {
+ return;
+ }
+
+ if (buf->buf_list[0].va)
+ hi_vram_kfree(buf->buf_list[0].va, buf->buf_info.buf_vram_name,
+ (u64)buf->buf_size * buf->buf_number);
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = NULL;
+}
+
static void cqm_buf_free_page_common(struct tag_cqm_buf *buf)
{
u32 order;
s32 i;
+ if (buf->buf_list == NULL) {
+ return;
+ }
+
order = (u32)get_order(buf->buf_size);
for (i = 0; i < (s32)buf->buf_number; i++) {
@@ -320,8 +364,10 @@ static s32 cqm_buf_use_node_alloc_page(struct hinic3_hwdev *handle, struct tag_c
node = dev_to_node(handle->dev_hdl);
for (i = 0; i < (s32)buf->buf_number; i++) {
newpage = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, order);
- if (!newpage)
+ if (!newpage) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
va = (void *)page_address(newpage);
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
@@ -349,8 +395,10 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
for (i = 0; i < (s32)buf->buf_number; i++) {
va = (void *)ossl_get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
- if (!va)
+ if (!va) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
* value must be 0.
@@ -367,21 +415,21 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
return CQM_SUCCESS;
}
-#define MALLOC_FUNCS_COUNT 2
-#define FREE_FUNCS_COUNT 1
-static const struct malloc_memory g_malloc_funcs[MALLOC_FUNCS_COUNT] = {
+static const struct malloc_memory g_malloc_funcs[] = {
+ {check_use_vram, cqm_buf_vram_kalloc},
{check_for_use_node_alloc, cqm_buf_use_node_alloc_page},
{check_for_nouse_node_alloc, cqm_buf_unused_node_alloc_page}
};
-static const struct free_memory g_free_funcs[FREE_FUNCS_COUNT] = {
+static const struct free_memory g_free_funcs[] = {
+ {check_use_vram, cqm_buf_vram_free},
{check_use_non_vram, cqm_buf_free_page_common}
};
static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *buf)
{
struct hinic3_hwdev *handle = cqm_handle->ex_handle;
- u32 malloc_funcs_num = MALLOC_FUNCS_COUNT;
+ u32 malloc_funcs_num = ARRAY_SIZE(g_malloc_funcs);
u32 i;
for (i = 0; i < malloc_funcs_num; i++) {
@@ -398,7 +446,7 @@ static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
static void cqm_buf_free_page(struct tag_cqm_buf *buf)
{
- u32 free_funcs_num = FREE_FUNCS_COUNT;
+ u32 free_funcs_num = ARRAY_SIZE(g_free_funcs);
u32 i;
for (i = 0; i < free_funcs_num; i++) {
@@ -447,8 +495,11 @@ static s32 cqm_buf_get_secure_mem_pages(struct tag_cqm_handle *cqm_handle, struc
cqm_get_secure_mem_pages(handle,
(u32)get_order(buf->buf_size),
&buf->buf_list[i].pa);
- if (!buf->buf_list[i].va)
+ if (!buf->buf_list[i].va) {
+ cqm_err(handle->dev_hdl,
+ CQM_ALLOC_FAIL(cqm_get_secure_mem_pages));
break;
+ }
}
if (i != buf->buf_number) {
@@ -780,7 +831,10 @@ static s32 cqm_single_bitmap_init(struct tag_cqm_bitmap *bitmap)
*/
bit_number = (ALIGN(bitmap->max_num, CQM_NUM_BIT_BYTE) >>
CQM_BYTE_BIT_SHIFT);
- bitmap->table = vmalloc(bit_number);
+ if (bitmap->bitmap_info.use_vram != 0)
+ bitmap->table = hi_vram_kalloc(bitmap->bitmap_info.buf_vram_name, bit_number);
+ else
+ bitmap->table = vmalloc(bit_number);
if (!bitmap->table)
return CQM_FAIL;
memset(bitmap->table, 0, bit_number);
@@ -859,7 +913,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
}
bitmap = &cla_table->bitmap;
- snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_APPLY_LEN,
"%s%s%02d", cla_table->name,
VRAM_CQM_BITMAP_BASE, cla_table->type);
@@ -869,6 +923,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
bitmap->reserved_top = capability->qpc_reserved;
bitmap->reserved_back = capability->qpc_reserved_back;
bitmap->last = capability->qpc_reserved;
+ bitmap->bitmap_info.use_vram = get_use_vram_flag();
cqm_info(handle->dev_hdl,
"Bitmap init: cla_table_type=%u, max_num=0x%x\n",
cla_table->type, bitmap->max_num);
@@ -948,7 +1003,12 @@ void cqm_bitmap_uninit(struct tag_cqm_handle *cqm_handle)
if (cla_table->type != CQM_BAT_ENTRY_T_INVALID &&
bitmap->table) {
spin_lock_deinit(&bitmap->lock);
- vfree(bitmap->table);
+ if (bitmap->bitmap_info.use_vram != 0)
+ hi_vram_kfree(bitmap->table, bitmap->bitmap_info.buf_vram_name,
+ ALIGN(bitmap->max_num, CQM_NUM_BIT_BYTE) >>
+ CQM_BYTE_BIT_SHIFT);
+ else
+ vfree(bitmap->table);
bitmap->table = NULL;
}
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
index 7febf76..06b8661 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
@@ -9,6 +9,7 @@
#include <linux/spinlock.h>
#include "cqm_object.h"
+#include "vram_common.h"
struct tag_cqm_bitmap {
ulong *table;
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c
index cf7df37..3d38edc 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c
@@ -15,7 +15,6 @@
#include "cqm_bitmap_table.h"
#include "cqm_bat_cla.h"
#include "cqm_main.h"
-#include "cqm_cmd.h"
/**
* cqm_cmd_alloc - Apply for a cmd buffer. The buffer size is fixed to 2 KB,
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
index 9a13ae0..db65c8b 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
@@ -196,6 +196,12 @@ void *cqm_get_db_addr(void *ex_handle, u32 service_type)
pr_err("[CQM]%s: ex_handle is null\n", __func__);
return NULL;
}
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return NULL;
+ }
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -218,6 +224,17 @@ s32 cqm_ring_hardware_db(void *ex_handle, u32 service_type, u8 db_count, u64 db)
struct tag_cqm_service *service = NULL;
struct hinic3_hwdev *handle = NULL;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -278,6 +295,17 @@ s32 cqm_ring_direct_wqe_db(void *ex_handle, u32 service_type, u8 db_count,
u64 *tmp = (u64 *)direct_wqe;
int i;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
index 19a8b56..0e8a579 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
@@ -23,6 +23,8 @@
#include "cqm_memsec.h"
#include "cqm_main.h"
+#include "vram_common.h"
+
static unsigned char roce_qpc_rsv_mode = CQM_QPC_ROCE_NORMAL;
module_param(roce_qpc_rsv_mode, byte, 0644);
MODULE_PARM_DESC(roce_qpc_rsv_mode,
@@ -98,10 +100,17 @@ static s32 cqm_set_timer_enable(void *ex_handle)
{
struct hinic3_hwdev *handle = (struct hinic3_hwdev *)ex_handle;
struct tag_cqm_handle *cqm_handle = NULL;
+ int is_in_kexec;
if (!ex_handle)
return CQM_FAIL;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip starting cqm timer during kexec\n");
+ return CQM_SUCCESS;
+ }
+
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
if (cqm_handle->func_capability.fake_func_type == CQM_FAKE_FUNC_PARENT &&
cqm_set_fake_vf_timer(cqm_handle) != CQM_SUCCESS)
@@ -456,7 +465,7 @@ static void cqm_service_capability_init_roce(struct tag_cqm_handle *cqm_handle,
cqm_info(handle->dev_hdl, "Cap init: roce qpc 0x%x, scqc 0x%x, srqc 0x%x, drc_qp 0x%x\n",
roce_own_cap->max_qps, roce_own_cap->max_cqs,
roce_own_cap->max_srqs, roce_own_cap->max_drc_qps);
- cqm_info(handle->dev_hdl, "Cap init: type 0x%x, scenes:0x%x, qpc_rsv:0x%x, srv_bmp:0x%x\n",
+ cqm_info(handle->dev_hdl, "Cap init: board_type 0x%x, scenes_id:0x%x, qpc_rsv_mode:0x%x, srv_bmp:0x%x\n",
board_info->board_type, board_info->scenes_id,
roce_qpc_rsv_mode, board_info->service_en_bitmap);
@@ -610,7 +619,7 @@ static void cqm_service_capability_init_ipsec(struct tag_cqm_handle *cqm_handle,
func_cap->scqc_basic_size);
func_cap->scqc_alloc_static = true;
cqm_info(handle->dev_hdl, "Cap init: ipsec is valid\n");
- cqm_info(handle->dev_hdl, "Cap init: ipsec 0x%x, childc %d, scqc 0x%x, scqc_bsize %d\n",
+ cqm_info(handle->dev_hdl, "Cap init: ipsec childc_num 0x%x, childc_bsize %d, scqc_num 0x%x, scqc_bsize %d\n",
ipsec_srvcap->max_sactxs, func_cap->childc_basic_size,
ipsec_srvcap->max_cqs, func_cap->scqc_basic_size);
}
@@ -812,7 +821,7 @@ static int cqm_capability_init_bloomfilter(struct hinic3_hwdev *handle)
func_cap->bloomfilter_addr = service_capability->bfilter_start_addr;
if (func_cap->bloomfilter_length != 0 &&
!cqm_check_align(func_cap->bloomfilter_length)) {
- cqm_err(handle->dev_hdl, "Cap bloomfilter len %u is not the power of 2\n",
+ cqm_err(handle->dev_hdl, "Cap init: bloomfilter_length %u is not the power of 2\n",
func_cap->bloomfilter_length);
return CQM_FAIL;
@@ -883,7 +892,7 @@ static int cqm_capability_init_timer(struct hinic3_hwdev *handle)
func_cap->timer_vf_num = service_capability->timer_vf_num;
func_cap->timer_vf_id_start = service_capability->timer_vf_id_start;
cqm_info(handle->dev_hdl,
- "timer init: pf_num 0x%x, pf_start 0x%x, vf_num 0x%x, vf_start 0x%x\n",
+ "host timer init: timer_pf_num 0x%x, timer_pf_id_start 0x%x, timer_vf_num 0x%x, timer_vf_id_start 0x%x\n",
func_cap->timer_pf_num, func_cap->timer_pf_id_start,
func_cap->timer_vf_num, func_cap->timer_vf_id_start);
@@ -891,7 +900,7 @@ static int cqm_capability_init_timer(struct hinic3_hwdev *handle)
if (IS_SLAVE_HOST(handle)) {
total_timer_num *= CQM_TIMER_NUM_MULTI;
cqm_info(handle->dev_hdl,
- "timer init: need double tw resources, total_timer_num=0x%x\n",
+ "host timer init: need double tw resources, total_timer_num=0x%x\n",
total_timer_num);
}
}
@@ -1059,8 +1068,10 @@ static s32 cqm_fake_init(struct tag_cqm_handle *cqm_handle)
for (i = 0; i < (u32)child_func_number; i++) {
fake_cqm_handle = kmalloc(sizeof(*fake_cqm_handle), GFP_KERNEL | __GFP_ZERO);
- if (!fake_cqm_handle)
+ if (!fake_cqm_handle) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(fake_cqm_handle));
goto err;
+ }
/* Copy the attributes of the parent CQM handle to the child CQM
* handle and modify the values of function.
@@ -1129,7 +1140,7 @@ static s32 cqm_fake_mem_init(struct tag_cqm_handle *cqm_handle)
for (i = 0; i < (u32)child_func_number; i++) {
fake_cqm_handle = cqm_handle->fake_cqm_handle[i];
- snprintf(fake_cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(fake_cqm_handle->name, VRAM_NAME_APPLY_LEN,
"%s%s%02u", cqm_handle->name, VRAM_CQM_FAKE_MEM_BASE, i);
if (cqm_bat_init(fake_cqm_handle) != CQM_SUCCESS) {
@@ -1174,7 +1185,7 @@ s32 cqm_mem_init(void *ex_handle)
struct tag_cqm_handle *cqm_handle = NULL;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
- snprintf(cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(cqm_handle->name, VRAM_NAME_APPLY_LEN,
"%s%02u", VRAM_CQM_GLB_FUNC_BASE, hinic3_global_func_id(handle));
if (cqm_fake_init(cqm_handle) != CQM_SUCCESS) {
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
index 4f87bd1..8d1e481 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
@@ -362,6 +362,7 @@ s32 cqm_fake_vf_num_set(void *ex_handle, u16 fake_vf_num_cfg);
#define CQM_LOG_ID 0
#define CQM_PTR_NULL(x) "%s: " #x " is null\n", __func__
+#define CQM_ALLOC_FAIL(x) "%s: " #x " alloc fail\n", __func__
#define CQM_MAP_FAIL(x) "%s: " #x " map fail\n", __func__
#define CQM_FUNCTION_FAIL(x) "%s: " #x " return failure\n", __func__
#define CQM_WRONG_VALUE(x) "%s: " #x " %u is wrong\n", __func__, (u32)(x)
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
index 4888b0a..258c10a 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
@@ -21,6 +21,7 @@
#include "cqm_bloomfilter.h"
#include "cqm_db.h"
#include "cqm_main.h"
+#include "vram_common.h"
#include "vmsec_mpu_common.h"
#include "cqm_memsec.h"
@@ -34,6 +35,8 @@
#define STD_INPUT_ONE_PARA 1
#define STD_INPUT_TWO_PARA 2
#define MR_KEY_2_INDEX_SHIFT 8
+#define IS_ADDR_IN_MEMSEC(va, len, start, end) \
+ ((va) >= (start) && (va) + (len) < (end))
static int memsec_proc_show(struct seq_file *seq, void *offset);
static int memsec_proc_open(struct inode *inode, struct file *file);
@@ -49,12 +52,21 @@ static ssize_t memsec_proc_write(struct file *file, const char __user *data, siz
static struct proc_dir_entry *g_hinic3_memsec_proc_ent; /* proc dir */
static atomic_t g_memsec_proc_refcnt = ATOMIC_INIT(0);
+#if KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE
+static const struct file_operations memsec_proc_fops = {
+ .open = memsec_proc_open,
+ .read = seq_read,
+ .write = memsec_proc_write,
+ .release = memsec_proc_release,
+};
+#else
static const struct proc_ops memsec_proc_fops = {
.proc_open = memsec_proc_open,
.proc_read = seq_read,
.proc_write = memsec_proc_write,
.proc_release = memsec_proc_release,
};
+#endif
bool cqm_need_secure_mem(void *hwdev)
{
@@ -63,6 +75,9 @@ bool cqm_need_secure_mem(void *hwdev)
struct hinic3_hwdev *handle = (struct hinic3_hwdev *)hwdev;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (cqm_handle == NULL) {
+ return false;
+ }
info = &cqm_handle->secure_mem;
return ((info->need_secure_mem) && hinic3_is_guest_vmsec_enable(hwdev));
}
@@ -275,9 +290,10 @@ static int test_query_context(struct hinic3_hwdev *handle, char *data, size_t le
case CQM_OBJECT_SERVICE_CTX:
case CQM_OBJECT_MPT:
qpc_mpt = (struct tag_cqm_qpc_mpt *)cqm_obj;
- if (qpc_mpt->vaddr >= (u8 *)info->va_base &&
- (qpc_mpt->vaddr + cqm_obj->object_size) < (u8 *)info->va_end)
- in_secmem = true;
+ in_secmem = IS_ADDR_IN_MEMSEC(qpc_mpt->vaddr,
+ cqm_obj->object_size,
+ (u8 *)info->va_base,
+ (u8 *)info->va_end);
cqm_info(handle->dev_hdl,
"[memsec_dfx]Query %s:0x%x, va=%p %sin secure mem\n",
query_type == CQM_OBJECT_MPT ? "MPT, mpt_index" : "QPC, qpn",
@@ -286,9 +302,10 @@ static int test_query_context(struct hinic3_hwdev *handle, char *data, size_t le
case CQM_OBJECT_RDMA_SRQ:
case CQM_OBJECT_RDMA_SCQ:
cqm_queue = (struct tag_cqm_queue *)cqm_obj;
- if (cqm_queue->q_ctx_vaddr >= (u8 *)info->va_base &&
- (cqm_queue->q_ctx_vaddr + cqm_obj->object_size) < (u8 *)info->va_end)
- in_secmem = true;
+ in_secmem = IS_ADDR_IN_MEMSEC(cqm_queue->q_ctx_vaddr,
+ cqm_obj->object_size,
+ (u8 *)info->va_base,
+ (u8 *)info->va_end);
cqm_info(handle->dev_hdl,
"[memsec_dfx]Query %s:0x%x, va=%p %sin secure mem\n",
query_type == CQM_OBJECT_RDMA_SRQ ? "SRQC, srqn " : "SCQC, scqn",
@@ -378,7 +395,7 @@ static int hinic3_secure_mem_proc_node_remove(void *hwdev)
atomic_dec(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
@@ -401,7 +418,7 @@ static int hinic3_secure_mem_proc_node_add(void *hwdev)
atomic_inc(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
/* 0400 Read by owner */
@@ -653,7 +670,7 @@ void cqm_free_secure_mem_pages(struct hinic3_hwdev *handle, void *va, u32 order)
return;
}
- if (va < info->va_base || va > (info->va_end - PAGE_SIZE) ||
+ if (va < info->va_base || (va > (info->va_end - PAGE_SIZE)) ||
!PAGE_ALIGNED((va - info->va_base)))
cqm_err(handle->dev_hdl, "%s va wrong value\n", __func__);
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c
index 7d1bd35..86359c0 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c
@@ -180,8 +180,10 @@ struct tag_cqm_queue *cqm_object_recv_queue_create(void *ex_handle, u32 service_
rq_qinfo->common.q_header_vaddr =
cqm_kmalloc_align(sizeof(struct tag_cqm_queue_header),
GFP_KERNEL | __GFP_ZERO, CQM_QHEAD_ALIGN_ORDER);
- if (!rq_qinfo->common.q_header_vaddr)
+ if (!rq_qinfo->common.q_header_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_header_vaddr));
goto err1;
+ }
rq_qinfo->common.q_header_paddr =
pci_map_single(cqm_handle->dev, rq_qinfo->common.q_header_vaddr,
@@ -484,7 +486,8 @@ static bool cqm_object_nonrdma_queue_param_check(struct hinic3_hwdev *handle, u3
struct tag_cqm_handle *cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
/* exception of service registrion check */
- if (!cqm_handle->service[service_type].has_register) {
+ if (service_type >= CQM_SERVICE_T_MAX ||
+ !cqm_handle->service[service_type].has_register) {
cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(service_type));
return false;
}
@@ -1487,4 +1490,4 @@ void cqm_srq_used_rq_container_delete(struct tag_cqm_object *object, u8 *contain
}
kfree((void *)addr);
}
-EXPORT_SYMBOL(cqm_srq_used_rq_container_delete);
+EXPORT_SYMBOL(cqm_srq_used_rq_container_delete);
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c
index 92c19c4..1007b44 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c
@@ -127,8 +127,10 @@ s32 cqm_container_create(struct tag_cqm_object *object, u8 **container_addr, boo
* of the Container.
*/
new_container = kmalloc(qinfo->container_size, GFP_ATOMIC | __GFP_ZERO);
- if (!new_container)
+ if (!new_container) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(new_container));
return CQM_FAIL;
+ }
/* Container PCI mapping */
new_container_pa = pci_map_single(cqm_handle->dev, new_container,
@@ -299,8 +301,10 @@ s32 cqm_share_recv_queue_create(struct tag_cqm_object *object)
/* apply for buffer for SRQC */
common->q_ctx_vaddr = kmalloc(qinfo->q_ctx_size,
GFP_KERNEL | __GFP_ZERO);
- if (!common->q_ctx_vaddr)
+ if (!common->q_ctx_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_ctx_vaddr));
goto err2;
+ }
return CQM_SUCCESS;
err2:
@@ -808,8 +812,10 @@ static s32 cqm_nonrdma_queue_ctx_create(struct tag_cqm_object *object)
common->q_ctx_vaddr = cqm_kmalloc_align(qinfo->q_ctx_size,
GFP_KERNEL | __GFP_ZERO,
(u16)shift);
- if (!common->q_ctx_vaddr)
+ if (!common->q_ctx_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_ctx_vaddr));
return CQM_FAIL;
+ }
common->q_ctx_paddr = pci_map_single(cqm_handle->dev, common->q_ctx_vaddr,
qinfo->q_ctx_size, PCI_DMA_BIDIRECTIONAL);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h b/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
deleted file mode 100644
index ad732c3..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2019-2022. All rights reserved.
- * File Name : hinic3_comm_cmd.h
- * Version : Initial Draft
- * Created : 2019/4/25
- * Last Modified :
- * Description : COMM Commands between Driver and MPU
- * Function List :
- */
-
-#ifndef HINIC3_COMMON_CMD_H
-#define HINIC3_COMMON_CMD_H
-
-/* COMM Commands between Driver to MPU */
-enum hinic3_mgmt_cmd {
- /* flr及资源清理相关命令 */
- COMM_MGMT_CMD_FUNC_RESET = 0,
- COMM_MGMT_CMD_FEATURE_NEGO,
- COMM_MGMT_CMD_FLUSH_DOORBELL,
- COMM_MGMT_CMD_START_FLUSH,
- COMM_MGMT_CMD_SET_FUNC_FLR,
- COMM_MGMT_CMD_GET_GLOBAL_ATTR,
- COMM_MGMT_CMD_SET_PPF_FLR_TYPE,
- COMM_MGMT_CMD_SET_FUNC_SVC_USED_STATE,
-
- /* 分配msi-x中断资源 */
- COMM_MGMT_CMD_CFG_MSIX_NUM = 10,
-
- /* 驱动相关配置命令 */
- COMM_MGMT_CMD_SET_CMDQ_CTXT = 20,
- COMM_MGMT_CMD_SET_VAT,
- COMM_MGMT_CMD_CFG_PAGESIZE,
- COMM_MGMT_CMD_CFG_MSIX_CTRL_REG,
- COMM_MGMT_CMD_SET_CEQ_CTRL_REG,
- COMM_MGMT_CMD_SET_DMA_ATTR,
-
- /* INFRA配置相关命令字 */
- COMM_MGMT_CMD_GET_MQM_FIX_INFO = 40,
- COMM_MGMT_CMD_SET_MQM_CFG_INFO,
- COMM_MGMT_CMD_SET_MQM_SRCH_GPA,
- COMM_MGMT_CMD_SET_PPF_TMR,
- COMM_MGMT_CMD_SET_PPF_HT_GPA,
- COMM_MGMT_CMD_SET_FUNC_TMR_BITMAT,
- COMM_MGMT_CMD_SET_MBX_CRDT,
- COMM_MGMT_CMD_CFG_TEMPLATE,
- COMM_MGMT_CMD_SET_MQM_LIMIT,
-
- /* 信息获取相关命令字 */
- COMM_MGMT_CMD_GET_FW_VERSION = 60,
- COMM_MGMT_CMD_GET_BOARD_INFO,
- COMM_MGMT_CMD_SYNC_TIME,
- COMM_MGMT_CMD_GET_HW_PF_INFOS,
- COMM_MGMT_CMD_SEND_BDF_INFO,
- COMM_MGMT_CMD_GET_VIRTIO_BDF_INFO,
- COMM_MGMT_CMD_GET_SML_TABLE_INFO,
- COMM_MGMT_CMD_GET_SDI_INFO,
-
- /* 升级相关命令字 */
- COMM_MGMT_CMD_UPDATE_FW = 80,
- COMM_MGMT_CMD_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_DONE_NOTICE,
- COMM_MGMT_CMD_SWITCH_CFG,
- COMM_MGMT_CMD_CHECK_FLASH,
- COMM_MGMT_CMD_CHECK_FLASH_RW,
- COMM_MGMT_CMD_RESOURCE_CFG,
- COMM_MGMT_CMD_UPDATE_BIOS, /* TODO: merge to COMM_MGMT_CMD_UPDATE_FW */
- COMM_MGMT_CMD_MPU_GIT_CODE,
-
- /* chip reset相关 */
- COMM_MGMT_CMD_FAULT_REPORT = 100,
- COMM_MGMT_CMD_WATCHDOG_INFO,
- COMM_MGMT_CMD_MGMT_RESET,
- COMM_MGMT_CMD_FFM_SET, /* TODO: check if needed */
-
- /* chip info/log 相关 */
- COMM_MGMT_CMD_GET_LOG = 120,
- COMM_MGMT_CMD_TEMP_OP,
- COMM_MGMT_CMD_EN_AUTO_RST_CHIP,
- COMM_MGMT_CMD_CFG_REG,
- COMM_MGMT_CMD_GET_CHIP_ID,
- COMM_MGMT_CMD_SYSINFO_DFX,
- COMM_MGMT_CMD_PCIE_DFX_NTC,
- COMM_MGMT_CMD_DICT_LOG_STATUS, /* LOG STATUS 127 */
- COMM_MGMT_CMD_MSIX_INFO,
- COMM_MGMT_CMD_CHANNEL_DETECT,
- COMM_MGMT_CMD_DICT_COUNTER_STATUS,
-
- /* switch workmode 相关 */
- COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140,
- COMM_MGMT_CMD_SWITCH_WORKMODE,
-
- /* mpu 相关 */
- COMM_MGMT_CMD_MIGRATE_DFX_HPA = 150,
- COMM_MGMT_CMD_BDF_INFO,
- COMM_MGMT_CMD_NCSI_CFG_INFO_GET_PROC,
-
- /* rsvd0 section */
- COMM_MGMT_CMD_SECTION_RSVD_0 = 160,
-
- /* rsvd1 section */
- COMM_MGMT_CMD_SECTION_RSVD_1 = 170,
-
- /* rsvd2 section */
- COMM_MGMT_CMD_SECTION_RSVD_2 = 180,
-
- /* rsvd3 section */
- COMM_MGMT_CMD_SECTION_RSVD_3 = 190,
-
- /* TODO: move to DFT mode */
- COMM_MGMT_CMD_GET_DIE_ID = 200,
- COMM_MGMT_CMD_GET_EFUSE_TEST,
- COMM_MGMT_CMD_EFUSE_INFO_CFG,
- COMM_MGMT_CMD_GPIO_CTL,
- COMM_MGMT_CMD_HI30_SERLOOP_START, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_SERLOOP_STOP, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_SET_FLAG, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_GET_RESULT, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_ECC_TEST,
- COMM_MGMT_CMD_FUNC_BIST_TEST, /* 209 */
-
- COMM_MGMT_CMD_VPD_SET = 210,
- COMM_MGMT_CMD_VPD_GET,
-
- COMM_MGMT_CMD_ERASE_FLASH,
- COMM_MGMT_CMD_QUERY_FW_INFO,
- COMM_MGMT_CMD_GET_CFG_INFO,
- COMM_MGMT_CMD_GET_UART_LOG,
- COMM_MGMT_CMD_SET_UART_CMD,
- COMM_MGMT_CMD_SPI_TEST,
-
- /* TODO: ALL reg read/write merge to COMM_MGMT_CMD_CFG_REG */
- COMM_MGMT_CMD_UP_REG_GET,
- COMM_MGMT_CMD_UP_REG_SET, /* 219 */
-
- COMM_MGMT_CMD_REG_READ = 220,
- COMM_MGMT_CMD_REG_WRITE,
- COMM_MGMT_CMD_MAG_REG_WRITE,
- COMM_MGMT_CMD_ANLT_REG_WRITE,
-
- COMM_MGMT_CMD_HEART_EVENT, /* TODO: delete */
- COMM_MGMT_CMD_NCSI_OEM_GET_DRV_INFO, /* TODO: delete */
- COMM_MGMT_CMD_LASTWORD_GET,
- COMM_MGMT_CMD_READ_BIN_DATA, /* TODO: delete */
- /* COMM_MGMT_CMD_WWPN_GET, TODO: move to FC? */
- /* COMM_MGMT_CMD_WWPN_SET, TODO: move to FC? */ /* 229 */
-
- /* TODO: check if needed */
- COMM_MGMT_CMD_SET_VIRTIO_DEV = 230,
- COMM_MGMT_CMD_SET_MAC,
- /* MPU patch cmd */
- COMM_MGMT_CMD_LOAD_PATCH,
- COMM_MGMT_CMD_REMOVE_PATCH,
- COMM_MGMT_CMD_PATCH_ACTIVE,
- COMM_MGMT_CMD_PATCH_DEACTIVE,
- COMM_MGMT_CMD_PATCH_SRAM_OPTIMIZE,
- /* container host process */
- COMM_MGMT_CMD_CONTAINER_HOST_PROC,
- /* nsci counter */
- COMM_MGMT_CMD_NCSI_COUNTER_PROC,
- COMM_MGMT_CMD_CHANNEL_STATUS_CHECK, /* 239 */
-
- /* hot patch rsvd cmd */
- COMM_MGMT_CMD_RSVD_0 = 240,
- COMM_MGMT_CMD_RSVD_1,
- COMM_MGMT_CMD_RSVD_2,
- COMM_MGMT_CMD_RSVD_3,
- COMM_MGMT_CMD_RSVD_4,
- /* 无效字段,版本收编删除,编译使用 */
- COMM_MGMT_CMD_SEND_API_ACK_BY_UP,
-
- /* 注:添加cmd,不能修改已有命令字的值,请在前方rsvd
- * section中添加;原则上所有分支cmd表完全一致
- */
- COMM_MGMT_CMD_MAX = 255,
-};
-
-/* CmdQ Common subtype */
-enum comm_cmdq_cmd {
- COMM_CMD_UCODE_ARM_BIT_SET = 2,
- COMM_CMD_SEND_NPU_DFT_CMD,
-};
-
-#endif /* HINIC3_COMMON_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
deleted file mode 100644
index 9ce908e..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_COMMON_H
-#define HINIC3_COMMON_H
-
-#include <linux/types.h>
-
-struct hinic3_dma_addr_align {
- u32 real_size;
-
- void *ori_vaddr;
- dma_addr_t ori_paddr;
-
- void *align_vaddr;
- dma_addr_t align_paddr;
-};
-
-enum hinic3_wait_return {
- WAIT_PROCESS_CPL = 0,
- WAIT_PROCESS_WAITING = 1,
- WAIT_PROCESS_ERR = 2,
-};
-
-struct hinic3_sge {
- u32 hi_addr;
- u32 lo_addr;
- u32 len;
-};
-
-#ifdef static
-#undef static
-#define LLT_STATIC_DEF_SAVED
-#endif
-
-/* *
- * hinic_cpu_to_be32 - convert data to big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert, must be Multiple of 4B
- */
-static inline void hinic3_cpu_to_be32(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = cpu_to_be32(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_cpu_to_be32 - convert data from big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert
- */
-static inline void hinic3_be32_to_cpu(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = be32_to_cpu(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_set_sge - set dma area in scatter gather entry
- * @sge: scatter gather entry
- * @addr: dma address
- * @len: length of relevant data in the dma address
- */
-static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
- int len)
-{
- sge->hi_addr = upper_32_bits(addr);
- sge->lo_addr = lower_32_bits(addr);
- sge->len = len;
-}
-
-#define hinic3_hw_be32(val) (val)
-#define hinic3_hw_cpu32(val) (val)
-#define hinic3_hw_cpu16(val) (val)
-
-static inline void hinic3_hw_be32_len(void *data, int len)
-{
-}
-
-static inline void hinic3_hw_cpu32_len(void *data, int len)
-{
-}
-
-int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
- unsigned int flag,
- struct hinic3_dma_addr_align *mem_align);
-
-void hinic3_dma_free_coherent_align(void *dev_hdl,
- struct hinic3_dma_addr_align *mem_align);
-
-typedef enum hinic3_wait_return (*wait_cpl_handler)(void *priv_data);
-
-int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
- u32 wait_total_ms, u32 wait_once_us);
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
index f269691..7979244 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
@@ -8,7 +8,7 @@
#include "mpu_cmd_base_defs.h"
-#define HINIC3_DRV_VERSION "15.17.1.1"
+#define HINIC3_DRV_VERSION "17.7.8.1"
#define HINIC3_DRV_DESC "Intelligent Network Interface Card Driver"
#define HIUDK_DRV_DESC "Intelligent Network Unified Driver"
@@ -45,6 +45,8 @@ enum hinic3_service_type {
SERVICE_T_CUSTOM,
SERVICE_T_VROCE,
SERVICE_T_CRYPT,
+ SERVICE_T_VSOCK,
+ SERVICE_T_BIFUR,
SERVICE_T_MAX,
/* Only used for interruption resource management,
@@ -63,6 +65,9 @@ struct nic_service_cap {
u16 max_sqs;
u16 max_rqs;
u16 default_num_queues;
+ u16 outband_vlan_cfg_en;
+ u8 lro_enable;
+ u8 rsvd1[3];
};
struct ppa_service_cap {
@@ -76,6 +81,10 @@ struct ppa_service_cap {
u16 rsvd1;
};
+struct bifur_service_cap {
+ u8 rsvd;
+};
+
struct vbs_service_cap {
u16 vbs_max_volq;
u8 vbs_main_pf_enable;
@@ -785,6 +794,15 @@ bool hinic3_support_toe(void *hwdev, struct toe_service_cap *cap);
*/
bool hinic3_support_ppa(void *hwdev, struct ppa_service_cap *cap);
+/* *
+ * @brief hinic3_support_bifur - function support bifur
+ * @param hwdev: device pointer to hwdev
+ * @param cap: bifur service capbility
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+bool hinic3_support_bifur(void *hwdev, struct bifur_service_cap *cap);
+
/* *
* @brief hinic3_support_migr - function support migrate
* @param hwdev: device pointer to hwdev
@@ -895,6 +913,13 @@ int hinic3_get_mgmt_version(void *hwdev, u8 *mgmt_ver, u8 version_size,
int hinic3_get_fw_version(void *hwdev, struct hinic3_fw_version *fw_ver,
u16 channel);
+/* *
+ * @brief hinic3_get_bond_create_mode - get bond create mode
+ * @param hwdev: device pointer to hwdev
+ * @retval global function id
+ */
+u8 hinic3_get_bond_create_mode(void *udkdev);
+
/* *
* @brief hinic3_global_func_id - get global function id
* @param hwdev: device pointer to hwdev
@@ -1249,4 +1274,7 @@ int hinic3_mbox_to_host_sync(void *hwdev, enum hinic3_mod_type mod,
int hinic3_get_func_vroce_enable(void *hwdev, u16 glb_func_idx, u8 *en);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type);
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
index 5863bee..9b5f017 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
@@ -18,9 +18,8 @@
#include "hinic3_tx.h"
#include "hinic3_dcb.h"
#include "hinic3_nic.h"
-#include "hinic3_mgmt_interface.h"
-#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "hinic3_bond.h"
+#include "nic_mpu_cmd_defs.h"
typedef int (*nic_driv_module)(struct hinic3_nic_dev *nic_dev,
const void *buf_in, u32 in_size,
@@ -48,7 +47,7 @@ static int get_nic_drv_version(void *buf_out, const u32 *out_size)
}
err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
- HINIC3_NIC_DRV_VERSION, "2024-07-03_09:33:00");
+ HINIC3_NIC_DRV_VERSION, "2025-05-01_00:00:03");
if (err < 0)
return -EINVAL;
@@ -94,13 +93,13 @@ static int get_q_num(struct hinic3_nic_dev *nic_dev,
return -EFAULT;
}
- if (!buf_out) {
+ if (!buf_out || !out_size) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Get queue number para buf_out is NULL.\n");
return -EINVAL;
}
- if (!out_size || *out_size != sizeof(u16)) {
+ if (*out_size != sizeof(u16)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user: %u, expect: %lu\n",
*out_size, sizeof(u16));
@@ -126,7 +125,8 @@ static int get_tx_wqe_info(struct hinic3_nic_dev *nic_dev,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -178,7 +178,8 @@ static int get_rx_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
rq_info->delta = (u16)nic_dev->rxqs[q_id].delta;
- rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx & nic_dev->rxqs[q_id].q_mask);
+ rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx &
+ nic_dev->rxqs[q_id].q_mask);
rq_info->sw_pi = nic_dev->rxqs[q_id].next_to_update;
rq_info->msix_vector = nic_dev->rxqs[q_id].irq_id;
@@ -201,7 +202,8 @@ static int get_rx_wqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -230,7 +232,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EFAULT;
}
- if (!buf_in || !buf_out) {
+ if (!buf_in || !buf_out || !out_size) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Buf_in or buf_out is NULL.\n");
return -EINVAL;
@@ -243,7 +245,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EINVAL;
}
- if (!out_size || *out_size != sizeof(struct hinic3_rq_cqe)) {
+ if (*out_size != sizeof(struct hinic3_rq_cqe)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(struct hinic3_rq_cqe));
@@ -252,10 +254,16 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
q_id = (u16)info->q_id;
idx = (u16)info->wqe_id;
- if (q_id >= nic_dev->q_params.num_qps || idx >= nic_dev->rxqs[q_id].q_depth) {
+ if (q_id >= nic_dev->q_params.num_qps) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid q_id[%u] >= %u.\n", q_id,
+ nic_dev->q_params.num_qps);
+ return -EFAULT;
+ }
+ if (idx >= nic_dev->rxqs[q_id].q_depth) {
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Invalid q_id[%u] >= %u, or wqe idx[%u] >= %u.\n",
- q_id, nic_dev->q_params.num_qps, idx, nic_dev->rxqs[q_id].q_depth);
+ "Invalid wqe idx[%u] >= %u.\n", idx,
+ nic_dev->rxqs[q_id].q_depth);
return -EFAULT;
}
@@ -338,7 +346,8 @@ static int set_loopback_mode(struct hinic3_nic_dev *nic_dev, const void *buf_in,
err = hinic3_set_loopback_mode(nic_dev->hwdev, (u8)mode->loop_mode,
(u8)mode->loop_ctrl);
if (err == 0)
- nicif_info(nic_dev, drv, nic_dev->netdev, "Set loopback mode %u en %u succeed\n",
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Set loopback mode %u en %u succeed\n",
mode->loop_mode, mode->loop_ctrl);
return err;
@@ -417,6 +426,59 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
{
u32 pf_bw_limit;
int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
+
+ if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To set VF bandwidth rate, please use ip link cmd\n");
+ return -EINVAL;
+ }
+
+ if (!buf_in || !buf_out || in_size != sizeof(u32) ||
+ !out_size || *out_size != sizeof(u8))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_TX;
+ pf_bw_limit = *((u32 *)buf_in);
+
+ err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
+ if (err) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %u%%\n",
+ pf_bw_limit);
+ if (err < 0)
+ return err;
+ }
+
+ *((u8 *)buf_out) = (u8)err;
+
+ return 0;
+}
+
+static int set_rx_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ u32 pf_bw_limit;
+ int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
nicif_err(nic_dev, drv, nic_dev->netdev, "To set VF bandwidth rate, please use ip link cmd\n");
@@ -426,11 +488,16 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || !buf_out || in_size != sizeof(u32) || !out_size || *out_size != sizeof(u8))
return -EINVAL;
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_RX;
pf_bw_limit = *((u32 *)buf_in);
err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %d%%\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to set pf bandwidth limit to %d%%\n",
pf_bw_limit);
if (err < 0)
return err;
@@ -445,19 +512,21 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
struct hinic3_nic_io *nic_io = NULL;
+ u32 *rate_limit = (u32 *)buf_out;
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "To get VF bandwidth rate, please use ip link cmd\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To get VF bandwidth rate, please use ip link cmd\n");
return -EINVAL;
}
if (!buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(u32)) {
+ if (*out_size != sizeof(u32) * 2) { // 2:Stored in an array, TX and RX, both length are u32
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user: %d, expect: %lu\n",
- *out_size, sizeof(u32));
+ *out_size, sizeof(u32) * 2);
return -EFAULT;
}
@@ -465,8 +534,12 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!nic_io)
return -EINVAL;
- *((u32 *)buf_out) = nic_io->nic_cfg.pf_bw_limit;
+ rate_limit[HINIC3_NIC_RX] = nic_io->nic_cfg.pf_bw_rx_limit;
+ rate_limit[HINIC3_NIC_TX] = nic_io->nic_cfg.pf_bw_tx_limit;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "read rate cfg success rx rate is: %u, tx rate is : %u\n",
+ rate_limit[HINIC3_NIC_RX], rate_limit[HINIC3_NIC_TX]);
return 0;
}
@@ -477,8 +550,8 @@ static int get_sset_count(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || in_size != sizeof(u32) || !out_size ||
*out_size != sizeof(u32) || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
@@ -504,16 +577,16 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
int err;
if (!buf_in || in_size != sizeof(u32) || !out_size || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
size = sizeof(u32);
err = get_sset_count(nic_dev, buf_in, in_size, &count, &size);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Get sset count failed, ret=%d\n",
- err);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Get sset count failed, ret=%d\n", err);
return -EINVAL;
}
if (count * sizeof(*items) != *out_size) {
@@ -527,12 +600,14 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
switch (sset) {
case HINIC3_SHOW_SSET_IO_STATS:
- hinic3_get_io_stats(nic_dev, items);
+ err = hinic3_get_io_stats(nic_dev, items);
+ if (err < 0)
+ return -EINVAL;
break;
default:
- nicif_err(nic_dev, drv, nic_dev->netdev, "Unknown %u to get stats\n",
- sset);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unknown %u to get stats\n", sset);
err = -EINVAL;
break;
}
@@ -544,15 +619,18 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int i;
u8 cos_num = 0, valid_cos_bitmap = 0;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_PCP2COS) {
for (i = 0; i < NIC_DCB_UP_MAX; i++) {
- if (!(nic_dev->func_dft_cos_bitmap & BIT(qos_in->pcp2cos[i]))) {
+ if (!(dcb->func_dft_cos_bitmap &
+ BIT(qos_in->pcp2cos[i]))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- qos_in->pcp2cos[i], nic_dev->func_dft_cos_bitmap);
+ qos_in->pcp2cos[i],
+ dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -562,7 +640,8 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
}
- memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos, sizeof(qos_in->pcp2cos));
+ memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos,
+ sizeof(qos_in->pcp2cos));
wanted_dcb_cfg->pcp_user_cos_num = cos_num;
wanted_dcb_cfg->pcp_valid_cos_map = valid_cos_bitmap;
}
@@ -572,12 +651,14 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = 0;
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++) {
u8 cos = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->wanted_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ dcb->wanted_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
- if (cos >= NIC_DCB_UP_MAX || !(nic_dev->func_dft_cos_bitmap & BIT(cos))) {
+ if (cos >= NIC_DCB_UP_MAX ||
+ !(dcb->func_dft_cos_bitmap & BIT(cos))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- cos, nic_dev->func_dft_cos_bitmap);
+ cos, dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -588,8 +669,10 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- wanted_dcb_cfg->dscp2cos[i] = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->hw_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ wanted_dcb_cfg->dscp2cos[i] =
+ qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
+ dcb->hw_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
wanted_dcb_cfg->dscp_user_cos_num = cos_num;
wanted_dcb_cfg->dscp_valid_cos_map = valid_cos_bitmap;
}
@@ -601,11 +684,12 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int ret;
u8 cos_num, valid_cos_bitmap;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_TRUST) {
- if (qos_in->trust > DCB_DSCP) {
+ if (qos_in->trust > HINIC3_DCB_DSCP) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid trust=%u\n", qos_in->trust);
return -EINVAL;
@@ -615,7 +699,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
}
if (qos_in->cfg_bitmap & CMD_QOS_DEV_DFT_COS) {
- if (!(BIT(qos_in->dft_cos) & nic_dev->func_dft_cos_bitmap)) {
+ if (!(BIT(qos_in->dft_cos) & dcb->func_dft_cos_bitmap)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid dft_cos=%u\n", qos_in->dft_cos);
return -EINVAL;
@@ -628,7 +712,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
if (ret)
return ret;
- if (wanted_dcb_cfg->trust == DCB_PCP) {
+ if (wanted_dcb_cfg->trust == HINIC3_DCB_PCP) {
cos_num = wanted_dcb_cfg->pcp_user_cos_num;
valid_cos_bitmap = wanted_dcb_cfg->pcp_valid_cos_map;
} else {
@@ -636,18 +720,11 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = wanted_dcb_cfg->dscp_valid_cos_map;
}
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "DCB is on, cos num should not more than channel num:%u\n",
- nic_dev->q_params.num_qps);
- return -EOPNOTSUPP;
- }
- }
-
if (!(BIT(wanted_dcb_cfg->default_cos) & valid_cos_bitmap)) {
- nicif_info(nic_dev, drv, nic_dev->netdev, "Current default_cos=%u, change to %u\n",
- wanted_dcb_cfg->default_cos, (u8)fls(valid_cos_bitmap) - 1);
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Current default_cos=%u, change to %u\n",
+ wanted_dcb_cfg->default_cos,
+ (u8)fls(valid_cos_bitmap) - 1);
wanted_dcb_cfg->default_cos = (u8)fls(valid_cos_bitmap) - 1;
}
@@ -657,6 +734,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_dev_cfg *qos_in = buf_in;
struct hinic3_mt_qos_dev_cfg *qos_out = buf_out;
u8 i;
@@ -675,9 +753,10 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(qos_out, qos_in, sizeof(*qos_in));
qos_out->head.status = 0;
if (qos_in->op_code & MT_DCB_OPCODE_WR) {
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg,
+ memcpy(&dcb->wanted_dcb_cfg, &dcb->hw_dcb_cfg,
sizeof(struct hinic3_dcb_config));
- err = update_wanted_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg, qos_in);
+ err = update_wanted_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg,
+ qos_in);
if (err) {
qos_out->head.status = MT_EINVAL;
return 0;
@@ -687,12 +766,12 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
qos_out->head.status = MT_EIO;
} else {
- qos_out->dft_cos = nic_dev->hw_dcb_cfg.default_cos;
- qos_out->trust = nic_dev->hw_dcb_cfg.trust;
+ qos_out->dft_cos = dcb->hw_dcb_cfg.default_cos;
+ qos_out->trust = dcb->hw_dcb_cfg.trust;
for (i = 0; i < NIC_DCB_UP_MAX; i++)
- qos_out->pcp2cos[i] = nic_dev->hw_dcb_cfg.pcp2cos[i];
+ qos_out->pcp2cos[i] = dcb->hw_dcb_cfg.pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- qos_out->dscp2cos[i] = nic_dev->hw_dcb_cfg.dscp2cos[i];
+ qos_out->dscp2cos[i] = dcb->hw_dcb_cfg.dscp2cos[i];
}
return 0;
@@ -721,27 +800,17 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(dcb_out, dcb_in, sizeof(*dcb_in));
dcb_out->head.status = 0;
if (dcb_in->op_code & MT_DCB_OPCODE_WR) {
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) == dcb_in->state)
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ==
+ dcb_in->state)
return 0;
- if (dcb_in->state) {
- if (user_cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "cos num %u should not more than channel num %u\n",
- user_cos_num,
- nic_dev->q_params.num_qps);
-
- return -EOPNOTSUPP;
- }
- }
-
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? user_cos_num : 0,
+ err = hinic3_setup_cos(nic_dev->netdev,
+ dcb_in->state ? user_cos_num : 0,
netif_run);
if (err)
goto setup_cos_fail;
@@ -751,7 +820,6 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
goto vport_up_fail;
}
- rtnl_unlock();
} else {
dcb_out->state = !!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
}
@@ -759,12 +827,12 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
vport_up_fail:
- hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num,
+ netif_run);
setup_cos_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
return err;
}
@@ -772,13 +840,15 @@ setup_cos_fail:
static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_cos_cfg *cos_cfg_in = buf_in;
struct hinic3_mt_qos_cos_cfg *cos_cfg_out = buf_out;
if (!buf_in || !buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(*cos_cfg_out) || in_size != sizeof(*cos_cfg_in)) {
+ if (*out_size != sizeof(*cos_cfg_out) ||
+ in_size != sizeof(*cos_cfg_in)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
in_size, *out_size, sizeof(*cos_cfg_in));
@@ -789,9 +859,9 @@ static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
cos_cfg_out->head.status = 0;
cos_cfg_out->port_id = hinic3_physical_port_id(nic_dev->hwdev);
- cos_cfg_out->func_cos_bitmap = (u8)nic_dev->func_dft_cos_bitmap;
- cos_cfg_out->port_cos_bitmap = (u8)nic_dev->port_dft_cos_bitmap;
- cos_cfg_out->func_max_cos_num = nic_dev->cos_config_num_max;
+ cos_cfg_out->func_cos_bitmap = (u8)dcb->func_dft_cos_bitmap;
+ cos_cfg_out->port_cos_bitmap = (u8)dcb->port_dft_cos_bitmap;
+ cos_cfg_out->func_max_cos_num = dcb->cos_config_num_max;
return 0;
}
@@ -803,7 +873,13 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
intr_num = hinic3_intr_num(nic_dev->hwdev);
- if (!buf_out || !out_size || *out_size != sizeof(u16)) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != sizeof(u16)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(u16));
@@ -817,20 +893,27 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
static int get_netdev_name(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- if (!buf_out || !out_size || *out_size != IFNAMSIZ) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != IFNAMSIZ) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %u\n",
*out_size, IFNAMSIZ);
return -EFAULT;
}
- strlcpy(buf_out, nic_dev->netdev->name, IFNAMSIZ);
+ strscpy(buf_out, nic_dev->netdev->name, IFNAMSIZ);
return 0;
}
-static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
int *tx_timeout = buf_out;
@@ -839,7 +922,8 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (*out_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, out_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, out_size: %u, expect: %lu\n",
*out_size, sizeof(int));
return -EINVAL;
}
@@ -849,8 +933,9 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return 0;
}
-static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
const int *tx_timeout = buf_in;
@@ -859,13 +944,15 @@ static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (in_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, in_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, in_size: %u, expect: %lu\n",
in_size, sizeof(int));
return -EINVAL;
}
net_dev->watchdog_timeo = *tx_timeout * HZ;
- nicif_info(nic_dev, drv, net_dev, "Set tx timeout check period to %ds\n", *tx_timeout);
+ nicif_info(nic_dev, drv, net_dev,
+ "Set tx timeout check period to %ds\n", *tx_timeout);
return 0;
}
@@ -891,6 +978,34 @@ static int get_xsfp_present(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
}
+static int get_xsfp_tlv_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct drv_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info = buf_out;
+ const struct mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req = buf_in;
+ int err;
+
+ if ((buf_in == NULL) || (buf_out == NULL) || (out_size == NULL))
+ return -EINVAL;
+
+ if (*out_size != sizeof(*sfp_tlv_info) ||
+ in_size != sizeof(*sfp_tlv_info_req)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
+ in_size, *out_size, sizeof(*sfp_tlv_info));
+ return -EINVAL;
+ }
+
+ err = hinic3_get_sfp_tlv_info(nic_dev->hwdev,
+ sfp_tlv_info, sfp_tlv_info_req);
+ if (err != 0) {
+ sfp_tlv_info->head.status = MT_EIO;
+ return 0;
+ }
+
+ return 0;
+}
+
static int get_xsfp_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
@@ -928,7 +1043,7 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{GET_LOOPBACK_MODE, get_loopback_mode},
{SET_LOOPBACK_MODE, set_loopback_mode},
{SET_LINK_MODE, set_link_mode},
- {SET_PF_BW_LIMIT, set_pf_bw_limit},
+ {SET_TX_PF_BW_LIMIT, set_pf_bw_limit},
{GET_PF_BW_LIMIT, get_pf_bw_limit},
{GET_SSET_COUNT, get_sset_count},
{GET_SSET_ITEMS, get_sset_stats},
@@ -940,17 +1055,22 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{SET_TX_TIMEOUT, set_netdev_tx_timeout},
{GET_XSFP_PRESENT, get_xsfp_present},
{GET_XSFP_INFO, get_xsfp_info},
+ {GET_XSFP_INFO_COMP_CMIS, get_xsfp_tlv_info},
+ {SET_RX_PF_BW_LIMIT, set_rx_pf_bw_limit}
};
static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
u32 cmd, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(nic_driv_module_cmd_handle) /
- sizeof(nic_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(nic_driv_module_cmd_handle) /
+ sizeof(nic_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type = (enum driver_cmd_type)cmd;
int err = 0;
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_lock();
+
mutex_lock(&nic_dev->nic_mutex);
for (index = 0; index < num_cmds; index++) {
if (cmd_type ==
@@ -963,6 +1083,9 @@ static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
}
mutex_unlock(&nic_dev->nic_mutex);
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_unlock();
+
if (index == num_cmds) {
pr_err("Can't find callback for %d\n", cmd_type);
return -EINVAL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
index a1fb4af..aa53c19 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
@@ -24,82 +24,80 @@
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_user_cos_num;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_user_cos_num;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_user_cos_num;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_user_cos_num;
return 0;
}
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_valid_cos_map;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_valid_cos_map;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_valid_cos_map;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_valid_cos_map;
return 0;
}
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
- u8 i, remainder, num_sq_per_cos, cur_cos_num = 0;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ struct hinic3_dcb_config *wanted_dcb_cfg =
+ &nic_dev->dcb->wanted_dcb_cfg;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
+ u8 cos_qp_num, cos_qp_offset = 0;
+ u8 i, remainder, num_qp_per_cos;
- if (num_cos == 0)
- return;
-
- num_sq_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
- if (num_sq_per_cos == 0)
+ if (num_cos == 0 || nic_dev->q_params.num_qps == 0)
return;
- remainder = nic_dev->q_params.num_qps % num_sq_per_cos;
+ num_qp_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
+ remainder = nic_dev->q_params.num_qps % num_cos;
- memset(dcb_cfg->cos_qp_offset, 0, sizeof(dcb_cfg->cos_qp_offset));
- memset(dcb_cfg->cos_qp_num, 0, sizeof(dcb_cfg->cos_qp_num));
+ memset(hw_dcb_cfg->cos_qp_offset, 0, sizeof(hw_dcb_cfg->cos_qp_offset));
+ memset(hw_dcb_cfg->cos_qp_num, 0, sizeof(hw_dcb_cfg->cos_qp_num));
for (i = 0; i < PCP_MAX_UP; i++) {
if (BIT(i) & valid_cos_map) {
- u8 cos_qp_num = num_sq_per_cos;
- u8 cos_qp_offset = (u8)(cur_cos_num * num_sq_per_cos);
-
- if (cur_cos_num < remainder) {
- cos_qp_num++;
- cos_qp_offset += cur_cos_num;
- } else {
- cos_qp_offset += remainder;
- }
-
- cur_cos_num++;
- valid_cos_map -= (u8)BIT(i);
+ cos_qp_num = num_qp_per_cos + ((remainder > 0) ?
+ (remainder--, 1) : 0);
- dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
- dcb_cfg->cos_qp_num[i] = cos_qp_num;
+ hw_dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
+ hw_dcb_cfg->cos_qp_num[i] = cos_qp_num;
hinic3_info(nic_dev, drv, "cos %u, cos_qp_offset=%u cos_qp_num=%u\n",
i, cos_qp_offset, cos_qp_num);
+
+ cos_qp_offset += cos_qp_num;
+ valid_cos_map -= (int)BIT(i);
}
}
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_offset, dcb_cfg->cos_qp_offset,
- sizeof(dcb_cfg->cos_qp_offset));
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_num, dcb_cfg->cos_qp_num,
- sizeof(dcb_cfg->cos_qp_num));
+ memcpy(wanted_dcb_cfg->cos_qp_offset, hw_dcb_cfg->cos_qp_offset,
+ sizeof(hw_dcb_cfg->cos_qp_offset));
+ memcpy(wanted_dcb_cfg->cos_qp_num, hw_dcb_cfg->cos_qp_num,
+ sizeof(hw_dcb_cfg->cos_qp_num));
}
void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
u8 i;
u16 start_qid, q_num;
hinic3_set_txq_cos(nic_dev, 0, nic_dev->q_params.num_qps,
- nic_dev->hw_dcb_cfg.default_cos);
+ hw_dcb_cfg->default_cos);
if (!dcb_en)
return;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- q_num = (u16)nic_dev->hw_dcb_cfg.cos_qp_num[i];
+ q_num = (u16)hw_dcb_cfg->cos_qp_num[i];
if (q_num) {
- start_qid = (u16)nic_dev->hw_dcb_cfg.cos_qp_offset[i];
+ start_qid = (u16)hw_dcb_cfg->cos_qp_offset[i];
hinic3_set_txq_cos(nic_dev, start_qid, q_num, i);
hinic3_info(nic_dev, drv, "update tx db cos, start_qid %u, q_num=%u cos=%u\n",
@@ -110,30 +108,29 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ struct hinic3_dcb_config *hw_dcb_cfg = &dcb->hw_dcb_cfg;
struct hinic3_dcb_state dcb_state = {0};
u8 i;
int err;
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- /* VF does not support DCB, use the default cos */
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
-
- return 0;
- }
+ u32 pcp2cos_size = sizeof(dcb_state.pcp2cos);
+ u32 dscp2cos_size = sizeof(dcb_state.dscp2cos);
dcb_state.dcb_on = dcb_en;
- dcb_state.default_cos = dcb_cfg->default_cos;
- dcb_state.trust = dcb_cfg->trust;
+ dcb_state.default_cos = hw_dcb_cfg->default_cos;
+ dcb_state.trust = hw_dcb_cfg->trust;
if (dcb_en) {
for (i = 0; i < NIC_DCB_COS_MAX; i++)
- dcb_state.pcp2cos[i] = dcb_cfg->pcp2cos[i];
+ dcb_state.pcp2cos[i] = hw_dcb_cfg->pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- dcb_state.dscp2cos[i] = dcb_cfg->dscp2cos[i];
+ dcb_state.dscp2cos[i] = hw_dcb_cfg->dscp2cos[i];
} else {
- memset(dcb_state.pcp2cos, dcb_cfg->default_cos, sizeof(dcb_state.pcp2cos));
- memset(dcb_state.dscp2cos, dcb_cfg->default_cos, sizeof(dcb_state.dscp2cos));
+ memset(dcb_state.pcp2cos, hw_dcb_cfg->default_cos,
+ pcp2cos_size);
+ memset(dcb_state.dscp2cos, hw_dcb_cfg->default_cos,
+ dscp2cos_size);
}
err = hinic3_set_dcb_state(nic_dev->hwdev, &dcb_state);
@@ -143,7 +140,7 @@ static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
return err;
}
-static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
int err;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
@@ -169,11 +166,13 @@ static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
goto rx_configure_fail;
}
- if (dcb_en)
+ if (dcb_en) {
set_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
- else
+ set_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ } else {
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
-
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ }
return 0;
rx_configure_fail:
hinic3_set_tx_cos_state(nic_dev, dcb_en ? 0 : 1);
@@ -188,6 +187,7 @@ set_tx_cos_fail:
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err;
if (cos && test_bit(HINIC3_SAME_RXTX, &nic_dev->flags)) {
@@ -195,9 +195,10 @@ int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
return -EOPNOTSUPP;
}
- if (cos > nic_dev->cos_config_num_max) {
- nicif_err(nic_dev, drv, netdev, "Invalid num_tc: %u, max cos: %u\n",
- cos, nic_dev->cos_config_num_max);
+ if (cos > dcb->cos_config_num_max) {
+ nicif_err(nic_dev, drv, netdev,
+ "Invalid num_tc: %u, max cos: %u\n",
+ cos, dcb->cos_config_num_max);
return -EINVAL;
}
@@ -223,36 +224,48 @@ static u8 get_cos_num(u8 hw_valid_cos_bitmap)
static void hinic3_sync_dcb_cfg(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dcb_config *dcb_cfg)
{
- struct hinic3_dcb_config *hw_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
- memcpy(hw_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(hw_dcb_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
}
static int init_default_dcb_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *dcb_cfg)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 i, hw_dft_cos_map, port_cos_bitmap, dscp_ind;
int err;
+ int is_in_kexec;
- err = hinic3_cos_valid_bitmap(nic_dev->hwdev, &hw_dft_cos_map, &port_cos_bitmap);
+ err = hinic3_cos_valid_bitmap(nic_dev->hwdev,
+ &hw_dft_cos_map, &port_cos_bitmap);
if (err) {
hinic3_err(nic_dev, drv, "None cos supported\n");
return -EFAULT;
}
- nic_dev->func_dft_cos_bitmap = hw_dft_cos_map;
- nic_dev->port_dft_cos_bitmap = port_cos_bitmap;
- nic_dev->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+ is_in_kexec = vram_get_kexec_flag();
- dcb_cfg->trust = DCB_PCP;
- dcb_cfg->pcp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->dscp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
+ dcb->func_dft_cos_bitmap = hw_dft_cos_map;
+ dcb->port_dft_cos_bitmap = port_cos_bitmap;
+
+ dcb->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+
+ if (is_in_kexec == 0) {
+ dcb_cfg->trust = HINIC3_DCB_PCP;
+ dcb_cfg->default_cos = (u8)fls(dcb->func_dft_cos_bitmap) - 1;
+ } else {
+ dcb_cfg->trust = nic_dev->dcb->hw_dcb_cfg.trust;
+ dcb_cfg->default_cos = nic_dev->dcb->hw_dcb_cfg.default_cos;
+ }
+ dcb_cfg->pcp_user_cos_num = dcb->cos_config_num_max;
+ dcb_cfg->dscp_user_cos_num = dcb->cos_config_num_max;
dcb_cfg->pcp_valid_cos_map = hw_dft_cos_map;
dcb_cfg->dscp_valid_cos_map = hw_dft_cos_map;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i) ? i : dcb_cfg->default_cos;
+ dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i)
+ ? i : (u8)fls(dcb->func_dft_cos_bitmap) - 1;
for (dscp_ind = 0; dscp_ind < NIC_DCB_COS_MAX; dscp_ind++)
dcb_cfg->dscp2cos[i * NIC_DCB_DSCP_NUM + dscp_ind] = dcb_cfg->pcp2cos[i];
}
@@ -276,58 +289,121 @@ int hinic3_configure_dcb(struct net_device *netdev)
int err;
err = hinic3_sync_dcb_state(nic_dev->hwdev, 1,
- test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)
+ ? 1 : 0);
if (err) {
hinic3_err(nic_dev, drv, "Set dcb state failed\n");
return err;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ hinic3_sync_dcb_cfg(nic_dev, &nic_dev->dcb->wanted_dcb_cfg);
else
hinic3_dcb_reset_hw_config(nic_dev);
return 0;
}
+static int hinic3_dcb_alloc(struct hinic3_nic_dev *nic_dev)
+{
+ u16 func_id;
+ int is_use_vram;
+ int ret;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ ret = snprintf(nic_dev->dcb_name, VRAM_NAME_MAX_LEN,
+ "%s%u%s", VRAM_CQM_GLB_FUNC_BASE, func_id,
+ VRAM_NIC_DCB);
+ if (ret < 0) {
+ hinic3_err(nic_dev, drv, "Nic dcb snprintf failed, ret:%d.\n", ret);
+ return ret;
+ }
+
+ nic_dev->dcb = (struct hinic3_dcb *)hi_vram_kalloc(nic_dev->dcb_name,
+ sizeof(*nic_dev->dcb));
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to vram alloc dcb.\n");
+ return -EFAULT;
+ }
+ } else {
+ nic_dev->dcb = kzalloc(sizeof(*nic_dev->dcb), GFP_KERNEL);
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to create dcb.\n");
+ return -EFAULT;
+ }
+ }
+
+ return 0;
+}
+
+static void hinic3_dcb_free(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram)
+ hi_vram_kfree((void *)nic_dev->dcb, nic_dev->dcb_name, sizeof(*nic_dev->dcb));
+ else
+ kfree(nic_dev->dcb);
+ nic_dev->dcb = NULL;
+}
+
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
+ hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+
+ hinic3_dcb_free(nic_dev);
+}
+
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = NULL;
int err;
u8 dcb_en = test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0;
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- return hinic3_set_tx_cos_state(nic_dev, dcb_en);
+ err = hinic3_dcb_alloc(nic_dev);
+ if (err != 0) {
+ hinic3_err(nic_dev, drv, "Dcb alloc failed.\n");
+ return err;
+ }
- err = init_default_dcb_cfg(nic_dev, dcb_cfg);
+ hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ err = init_default_dcb_cfg(nic_dev, hw_dcb_cfg);
if (err) {
- hinic3_err(nic_dev, drv, "Initialize dcb configuration failed\n");
+ hinic3_err(nic_dev, drv,
+ "Initialize dcb configuration failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&nic_dev->dcb->wanted_dcb_cfg, hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
hinic3_info(nic_dev, drv, "Support num cos %u, default cos %u\n",
- nic_dev->cos_config_num_max, dcb_cfg->default_cos);
+ nic_dev->dcb->cos_config_num_max, hw_dcb_cfg->default_cos);
err = hinic3_set_tx_cos_state(nic_dev, dcb_en);
if (err) {
hinic3_err(nic_dev, drv, "Set tx cos state failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- sema_init(&nic_dev->dcb_sem, 1);
-
return 0;
}
-static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dcb_config *dcb_cfg)
+static int change_qos_cfg(struct hinic3_nic_dev *nic_dev,
+ const struct hinic3_dcb_config *dcb_cfg)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err = 0;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags)) {
+ if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags)) {
nicif_warn(nic_dev, drv, netdev,
"Cos_up map setting in inprocess, please try again later\n");
return -EFAULT;
@@ -337,40 +413,44 @@ static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dc
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
- clear_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags);
+ clear_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags);
return err;
}
int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err, rollback_err;
u8 netif_run = 0;
struct hinic3_dcb_config old_dcb_cfg;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- memcpy(&old_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&old_dcb_cfg, &dcb->hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
- if (!memcmp(&nic_dev->wanted_dcb_cfg, &old_dcb_cfg, sizeof(struct hinic3_dcb_config))) {
+ if (!memcmp(&dcb->wanted_dcb_cfg, &old_dcb_cfg,
+ sizeof(struct hinic3_dcb_config))) {
nicif_info(nic_dev, drv, nic_dev->netdev,
"Same valid up bitmap, don't need to change anything\n");
return 0;
}
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = change_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ err = change_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Set cos_up map to hw failed\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Set cos_up map to hw failed\n");
goto change_qos_cfg_fail;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- err = hinic3_setup_cos(nic_dev->netdev, user_cos_num, netif_run);
+ err = hinic3_setup_cos(nic_dev->netdev,
+ user_cos_num, netif_run);
if (err)
goto set_err;
}
@@ -381,13 +461,12 @@ int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
goto vport_up_fail;
}
- rtnl_unlock();
-
return 0;
vport_up_fail:
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_setup_cos(nic_dev->netdev, user_cos_num ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, user_cos_num
+ ? 0 : user_cos_num, netif_run);
set_err:
rollback_err = change_qos_cfg(nic_dev, &old_dcb_cfg);
@@ -399,7 +478,5 @@ change_qos_cfg_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
-
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
index 7987f56..e0b35cb 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
@@ -24,11 +24,6 @@ struct hinic3_tc_cfg {
u16 rsvd;
};
-enum HINIC3_DCB_TRUST {
- DCB_PCP,
- DCB_DSCP,
-};
-
#define PCP_MAX_UP 8
#define DSCP_MAC_UP 64
#define DBG_DFLT_DSCP_VAL 0xFF
@@ -50,6 +45,7 @@ struct hinic3_dcb_config {
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev);
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev);
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev);
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev);
void hinic3_dcb_reset_hw_config(struct hinic3_nic_dev *nic_dev);
int hinic3_configure_dcb(struct net_device *netdev);
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run);
@@ -75,4 +71,5 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos);
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev);
int hinic3_vport_up(struct hinic3_nic_dev *nic_dev);
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
index 2b3561e..548d67d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
@@ -44,9 +44,9 @@ static void hinic3_get_drvinfo(struct net_device *netdev,
u8 mgmt_ver[HINIC3_MGMT_VERSION_MAX_LEN] = {0};
int err;
- strlcpy(info->driver, HINIC3_NIC_DRV_NAME, sizeof(info->driver));
- strlcpy(info->version, HINIC3_NIC_DRV_VERSION, sizeof(info->version));
- strlcpy(info->bus_info, pci_name(pdev), sizeof(info->bus_info));
+ strscpy(info->driver, HINIC3_NIC_DRV_NAME, sizeof(info->driver));
+ strscpy(info->version, HINIC3_NIC_DRV_VERSION, sizeof(info->version));
+ strscpy(info->bus_info, pci_name(pdev), sizeof(info->bus_info));
err = hinic3_get_mgmt_version(nic_dev->hwdev, mgmt_ver,
HINIC3_MGMT_VERSION_MAX_LEN,
@@ -123,10 +123,15 @@ reset_err:
return err;
}
+#ifdef HAVE_ETHTOOL_RINGPARAM_EXTACK
static void hinic3_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring,
struct kernel_ethtool_ringparam *kernel_ring,
struct netlink_ext_ack *extack)
+#else
+static void hinic3_get_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+#endif
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
@@ -176,10 +181,15 @@ static int check_ringparam_valid(struct net_device *netdev,
return 0;
}
+#ifdef HAVE_ETHTOOL_RINGPARAM_EXTACK
static int hinic3_set_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring,
struct kernel_ethtool_ringparam *kernel_ring,
struct netlink_ext_ack *extack)
+#else
+static int hinic3_set_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+#endif
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic3_dyna_txrxq_params q_params = {0};
@@ -273,7 +283,7 @@ static int get_coalesce(struct net_device *netdev,
static int set_queue_coalesce(struct hinic3_nic_dev *nic_dev, u16 q_id,
struct hinic3_intr_coal_info *coal)
{
- struct hinic3_intr_coal_info *intr_coal;
+ struct hinic3_intr_coal_info *intr_coal = NULL;
struct interrupt_info info = {0};
struct net_device *netdev = nic_dev->netdev;
int err;
@@ -367,24 +377,11 @@ static int is_coalesce_exceed_limit(struct net_device *netdev,
return 0;
}
-static int is_coalesce_legal(struct net_device *netdev,
- const struct ethtool_coalesce *coal)
+static int is_coalesce_allowed_change(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct ethtool_coalesce tmp_coal = {0};
- int err;
-
- if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
- nicif_err(nic_dev, drv, netdev,
- "tx-usecs must be equal to rx-usecs\n");
- return -EINVAL;
- }
-
- if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
- nicif_err(nic_dev, drv, netdev,
- "tx-frames must be equal to rx-frames\n");
- return -EINVAL;
- }
tmp_coal.cmd = coal->cmd;
tmp_coal.rx_coalesce_usecs = coal->rx_coalesce_usecs;
@@ -409,6 +406,31 @@ static int is_coalesce_legal(struct net_device *netdev,
return -EOPNOTSUPP;
}
+ return 0;
+}
+
+static int is_coalesce_legal(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-usecs must be equal to rx-usecs\n");
+ return -EINVAL;
+ }
+
+ if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-frames must be equal to rx-frames\n");
+ return -EINVAL;
+ }
+
+ err = is_coalesce_allowed_change(netdev, coal);
+ if (err)
+ return err;
+
err = is_coalesce_exceed_limit(netdev, coal);
if (err)
return err;
@@ -491,19 +513,10 @@ static int set_hw_coal_param(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static int set_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *coal, u16 queue)
+static void check_coalesce_align(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
- struct hinic3_intr_coal_info intr_coal = {0};
- struct hinic3_intr_coal_info *ori_intr_coal = NULL;
- u32 last_adaptive_rx;
- char obj_str[32] = {0};
- int err = 0;
-
- err = is_coalesce_legal(netdev, coal);
- if (err)
- return err;
CHECK_COALESCE_ALIGN(coal, rx_coalesce_usecs, COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal, rx_max_coalesced_frames,
@@ -516,6 +529,14 @@ static int set_coalesce(struct net_device *netdev,
COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal, rx_max_coalesced_frames_low,
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int check_coalesce_change(struct net_device *netdev,
+ u16 queue, struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info *ori_intr_coal = NULL;
+ char obj_str[32] = {0};
if (queue == COALESCE_ALL_QUEUE) {
ori_intr_coal = &nic_dev->intr_coalesce[0];
@@ -524,6 +545,7 @@ static int set_coalesce(struct net_device *netdev,
ori_intr_coal = &nic_dev->intr_coalesce[queue];
snprintf(obj_str, sizeof(obj_str), "for queue %u", queue);
}
+
CHECK_COALESCE_CHANGED(coal, rx_coalesce_usecs, COALESCE_TIMER_CFG_UNIT,
ori_intr_coal->coalesce_timer_cfg, obj_str);
CHECK_COALESCE_CHANGED(coal, rx_max_coalesced_frames,
@@ -545,28 +567,52 @@ static int set_coalesce(struct net_device *netdev,
CHECK_COALESCE_CHANGED(coal, rx_max_coalesced_frames_low,
COALESCE_PENDING_LIMIT_UNIT,
ori_intr_coal->rx_pending_limt_low, obj_str);
+ return 0;
+}
- intr_coal.coalesce_timer_cfg =
+static void init_intr_coal_params(struct hinic3_intr_coal_info *intr_coal,
+ struct ethtool_coalesce *coal)
+{
+ intr_coal->coalesce_timer_cfg =
(u8)(coal->rx_coalesce_usecs / COALESCE_TIMER_CFG_UNIT);
- intr_coal.pending_limt = (u8)(coal->rx_max_coalesced_frames /
- COALESCE_PENDING_LIMIT_UNIT);
+ intr_coal->pending_limt = (u8)(coal->rx_max_coalesced_frames /
+ COALESCE_PENDING_LIMIT_UNIT);
- last_adaptive_rx = nic_dev->adaptive_rx_coal;
- nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
-
- intr_coal.pkt_rate_high = coal->pkt_rate_high;
- intr_coal.rx_usecs_high =
+ intr_coal->pkt_rate_high = coal->pkt_rate_high;
+ intr_coal->rx_usecs_high =
(u8)(coal->rx_coalesce_usecs_high / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_high =
+ intr_coal->rx_pending_limt_high =
(u8)(coal->rx_max_coalesced_frames_high /
COALESCE_PENDING_LIMIT_UNIT);
- intr_coal.pkt_rate_low = coal->pkt_rate_low;
- intr_coal.rx_usecs_low =
+ intr_coal->pkt_rate_low = coal->pkt_rate_low;
+ intr_coal->rx_usecs_low =
(u8)(coal->rx_coalesce_usecs_low / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_low =
+ intr_coal->rx_pending_limt_low =
(u8)(coal->rx_max_coalesced_frames_low /
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal, u16 queue)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info intr_coal = {0};
+ u32 last_adaptive_rx;
+ int err = 0;
+
+ err = is_coalesce_legal(netdev, coal);
+ if (err)
+ return err;
+
+ check_coalesce_align(netdev, coal);
+
+ check_coalesce_change(netdev, queue, coal);
+
+ init_intr_coal_params(&intr_coal, coal);
+
+ last_adaptive_rx = nic_dev->adaptive_rx_coal;
+ nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
/* coalesce timer or pending set to zero will disable coalesce */
if (!nic_dev->adaptive_rx_coal &&
@@ -588,18 +634,28 @@ static int set_coalesce(struct net_device *netdev,
return set_hw_coal_param(nic_dev, &intr_coal, queue);
}
+#ifdef HAVE_ETHTOOL_COALESCE_EXTACK
static int hinic3_get_coalesce(struct net_device *netdev,
struct ethtool_coalesce *coal,
struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack)
+#else
+static int hinic3_get_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
+#endif
{
return get_coalesce(netdev, coal, COALESCE_ALL_QUEUE);
}
+#ifdef HAVE_ETHTOOL_COALESCE_EXTACK
static int hinic3_set_coalesce(struct net_device *netdev,
struct ethtool_coalesce *coal,
struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack)
+#else
+static int hinic3_set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
+#endif
{
return set_coalesce(netdev, coal, COALESCE_ALL_QUEUE);
}
@@ -762,6 +818,14 @@ static int hinic3_get_module_info(struct net_device *netdev,
modinfo->type = ETH_MODULE_SFF_8636;
modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
break;
+ case MODULE_TYPE_DSFP:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
+ case MODULE_TYPE_QSFP_CMIS:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
default:
nicif_warn(nic_dev, drv, netdev,
"Optical module unknown: 0x%x\n", sfp_type);
@@ -784,6 +848,9 @@ static int hinic3_get_module_eeprom(struct net_device *netdev,
memset(data, 0, ee->len);
err = hinic3_get_sfp_eeprom(nic_dev->hwdev, (u8 *)sfp_data, ee->len);
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(nic_dev->hwdev, (u8 *)sfp_data, sizeof(sfp_data));
+
if (err)
return err;
@@ -814,7 +881,7 @@ static u32 hinic3_get_priv_flags(struct net_device *netdev)
return priv_flags;
}
-int hinic3_set_rxq_recovery_flag(struct net_device *netdev, u32 priv_flags)
+static int hinic3_set_rxq_recovery_flag(struct net_device *netdev, u32 priv_flags)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
@@ -844,12 +911,14 @@ static int hinic3_set_symm_rss_flag(struct net_device *netdev, u32 priv_flags)
if (priv_flags & HINIC3_PRIV_FLAGS_SYMM_RSS) {
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, netdev, "Failed to open Symmetric RSS while DCB is enabled\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to open Symmetric RSS while DCB is enabled\n");
return -EOPNOTSUPP;
}
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, netdev, "Failed to open Symmetric RSS while RSS is disabled\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to open Symmetric RSS while RSS is disabled\n");
return -EOPNOTSUPP;
}
@@ -1129,10 +1198,61 @@ static void hinic3_diag_test(struct net_device *netdev,
hinic3_lp_test(netdev, eth_test, data, 0);
}
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+static int hinic3_get_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u8 advertised_fec = 0;
+ u8 supported_fec = 0;
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_GFECPARAM) {
+ nicif_err(nic_dev, drv, netdev,
+ "get fecparam cmd err.exp:0x%x,real:0x%x\n",
+ ETHTOOL_GFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = get_fecparam(nic_dev->hwdev, &advertised_fec, &supported_fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Get fec param failed\n");
+ return err;
+ }
+ fecparam->active_fec = (u32)advertised_fec;
+ fecparam->fec = (u32)supported_fec;
+
+ nicif_info(nic_dev, drv, netdev, "Get fec param success\n");
+ return 0;
+}
+
+static int hinic3_set_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_SFECPARAM) {
+ nicif_err(nic_dev, drv, netdev, "Set fecparam cmd err.exp:0x%x,real:0x%x\n", ETHTOOL_SFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = set_fecparam(nic_dev->hwdev, (u8)fecparam->fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Set fec param failed\n");
+ return err;
+ }
+
+ nicif_info(nic_dev, drv, netdev, "Set fec param success\n");
+ return 0;
+}
+#endif
+
static const struct ethtool_ops hinic3_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1179,6 +1299,11 @@ static const struct ethtool_ops hinic3_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
+
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
@@ -1239,7 +1364,10 @@ static const struct ethtool_ops_ext hinic3_ethtool_ops_ext = {
static const struct ethtool_ops hinic3vf_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1266,6 +1394,11 @@ static const struct ethtool_ops hinic3vf_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
+
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
index de59b76..ec89f62 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
@@ -24,11 +24,24 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
-#define FPGA_PORT_COUNTER 0
-#define EVB_PORT_COUNTER 1
-u16 mag_support_mode = EVB_PORT_COUNTER;
-module_param(mag_support_mode, ushort, 0444);
-MODULE_PARM_DESC(mag_support_mode, "Set mag port counter support mode, 0:FPGA 1:EVB, default is 1");
+#define HINIC_SET_LINK_STR_LEN 128
+#define HINIC_ETHTOOL_FEC_INFO_LEN 6
+#define HINIC_SUPPORTED_FEC_CMD 0
+#define HINIC_ADVERTISED_FEC_CMD 1
+
+struct hinic3_ethtool_fec {
+ u8 hinic_fec_offset;
+ u8 ethtool_bit_offset;
+};
+
+static struct hinic3_ethtool_fec hinic3_ethtool_fec_info[HINIC_ETHTOOL_FEC_INFO_LEN] = {
+ {PORT_FEC_NOT_SET, 0xFF}, /* The ethtool does not have the corresponding enumeration variable */
+ {PORT_FEC_RSFEC, 0x32}, /* ETHTOOL_LINK_MODE_FEC_RS_BIT */
+ {PORT_FEC_BASEFEC, 0x33}, /* ETHTOOL_LINK_MODE_FEC_BASER_BIT */
+ {PORT_FEC_NOFEC, 0x31}, /* ETHTOOL_LINK_MODE_FEC_NONE_BIT */
+ {PORT_FEC_LLRSFEC, 0x4A}, /* ETHTOOL_LINK_MODE_FEC_LLRS_BIT: Available only in later versions */
+ {PORT_FEC_AUTO, 0XFF} /* The ethtool does not have the corresponding enumeration variable */
+};
struct hinic3_stats {
char name[ETH_GSTRING_LEN];
@@ -36,6 +49,20 @@ struct hinic3_stats {
int offset;
};
+struct hinic3_netdev_link_count_str {
+ u64 link_down_events_phy;
+};
+
+#define HINIC3_NETDEV_LINK_COUNT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic3_netdev_link_count_str, _stat_item), \
+ .offset = offsetof(struct hinic3_netdev_link_count_str, _stat_item) \
+}
+
+static struct hinic3_stats hinic3_netdev_link_count[] = {
+ HINIC3_NETDEV_LINK_COUNT(link_down_events_phy),
+};
+
#define HINIC3_NETDEV_STAT(_stat_item) { \
.name = #_stat_item, \
.size = FIELD_SIZEOF(struct rtnl_link_stats64, _stat_item), \
@@ -94,7 +121,6 @@ static struct hinic3_stats hinic3_nic_dev_stats_extern[] = {
.offset = offsetof(struct hinic3_txq_stats, _stat_item) \
}
-/*lint -save -e786*/
static struct hinic3_stats hinic3_rx_queue_stats[] = {
HINIC3_RXQ_STAT(packets),
HINIC3_RXQ_STAT(bytes),
@@ -135,8 +161,6 @@ static struct hinic3_stats hinic3_tx_queue_stats_extern[] = {
HINIC3_TXQ_STAT(rsvd2),
};
-/*lint -restore*/
-
#define HINIC3_FUNC_STAT(_stat_item) { \
.name = #_stat_item, \
.size = FIELD_SIZEOF(struct hinic3_vport_stats, _stat_item), \
@@ -260,49 +284,22 @@ static struct hinic3_stats hinic3_port_stats[] = {
HINIC3_PORT_STAT(mac_rx_unfilter_pkt_num),
};
+#define HINIC3_RSFEC_STAT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct mag_cmd_rsfec_stats, _stat_item), \
+ .offset = offsetof(struct mag_cmd_rsfec_stats, _stat_item) \
+}
+
+static struct hinic3_stats g_hinic3_rsfec_stats[] = {
+ HINIC3_RSFEC_STAT(rx_err_lane_phy),
+};
+
#define HINIC3_FGPA_PORT_STAT(_stat_item) { \
.name = #_stat_item, \
.size = FIELD_SIZEOF(struct hinic3_phy_fpga_port_stats, _stat_item), \
.offset = offsetof(struct hinic3_phy_fpga_port_stats, _stat_item) \
}
-static struct hinic3_stats g_hinic3_fpga_port_stats[] = {
- HINIC3_FGPA_PORT_STAT(mac_rx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_under_frame_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_frag_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_crc_error_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_length_err_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_pause_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_unknown_mac_frame_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_underrun_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_pause_pkts_port),
-};
-
static char g_hinic_priv_flags_strings[][ETH_GSTRING_LEN] = {
"Symmetric-RSS",
"Force-Link-up",
@@ -313,12 +310,12 @@ u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev)
{
u32 count;
- count = ARRAY_LEN(hinic3_nic_dev_stats) +
+ count = (u32)(ARRAY_LEN(hinic3_nic_dev_stats) +
ARRAY_LEN(hinic3_nic_dev_stats_extern) +
(ARRAY_LEN(hinic3_tx_queue_stats) +
ARRAY_LEN(hinic3_tx_queue_stats_extern) +
ARRAY_LEN(hinic3_rx_queue_stats) +
- ARRAY_LEN(hinic3_rx_queue_stats_extern)) * nic_dev->max_qps;
+ ARRAY_LEN(hinic3_rx_queue_stats_extern)) * nic_dev->max_qps);
return count;
}
@@ -342,46 +339,81 @@ u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev)
} \
} while (0)
-#define QUEUE_STATS_PACK(items, item_idx, array, stats_ptr, qid) do { \
- int j; \
- for (j = 0; j < ARRAY_LEN(array); j++) { \
- memcpy((items)[item_idx].name, (array)[j].name, \
- HINIC3_SHOW_ITEM_LEN); \
- snprintf((items)[item_idx].name, HINIC3_SHOW_ITEM_LEN, \
- (array)[j].name, (qid)); \
- (items)[item_idx].hexadecimal = 0; \
- (items)[item_idx].value = \
- GET_VALUE_OF_PTR((array)[j].size, \
- (char *)(stats_ptr) + (array)[j].offset); \
- (item_idx)++; \
- } \
-} while (0)
+int hinic3_rx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat, struct hinic3_rxq_stats *rxq_stats, u16 qid)
+{
+ int ret;
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
+ ret = snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
+ if (ret < 0)
+ return -EINVAL;
+
+ item->hexadecimal = 0;
+ item->value = GET_VALUE_OF_PTR(stat->size, (char *)(rxq_stats) + stat->offset);
+
+ return 0;
+}
+
+int hinic3_tx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat, struct hinic3_txq_stats *txq_stats, u16 qid)
+{
+ int ret;
+
+ ret = snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
+ if (ret < 0)
+ return -EINVAL;
+
+ item->hexadecimal = 0;
+ item->value = GET_VALUE_OF_PTR(stat->size, (char *)(txq_stats) + stat->offset);
+
+ return 0;
+}
+
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
{
struct hinic3_show_item *items = stats;
int item_idx = 0;
u16 qid;
+ int idx;
+ int ret;
DEV_STATS_PACK(items, item_idx, hinic3_nic_dev_stats, &nic_dev->stats);
- DEV_STATS_PACK(items, item_idx, hinic3_nic_dev_stats_extern,
- &nic_dev->stats);
+ DEV_STATS_PACK(items, item_idx, hinic3_nic_dev_stats_extern, &nic_dev->stats);
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- QUEUE_STATS_PACK(items, item_idx, hinic3_tx_queue_stats,
- &nic_dev->txqs[qid].txq_stats, qid);
- QUEUE_STATS_PACK(items, item_idx, hinic3_tx_queue_stats_extern,
- &nic_dev->txqs[qid].txq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++], &hinic3_tx_queue_stats[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats_extern); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++], &hinic3_tx_queue_stats_extern[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
}
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- QUEUE_STATS_PACK(items, item_idx, hinic3_rx_queue_stats,
- &nic_dev->rxqs[qid].rxq_stats, qid);
- QUEUE_STATS_PACK(items, item_idx, hinic3_rx_queue_stats_extern,
- &nic_dev->rxqs[qid].rxq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++], &hinic3_rx_queue_stats[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats_extern); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++], &hinic3_rx_queue_stats_extern[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
}
-}
+ return 0;
+}
static char g_hinic3_test_strings[][ETH_GSTRING_LEN] = {
"Internal lb test (on/offline)",
"External lb test (external_lb)",
@@ -398,16 +430,15 @@ int hinic3_get_sset_count(struct net_device *netdev, int sset)
case ETH_SS_STATS:
q_num = nic_dev->q_params.num_qps;
count = ARRAY_LEN(hinic3_netdev_stats) +
- ARRAY_LEN(hinic3_nic_dev_stats) +
+ ARRAY_LEN(hinic3_nic_dev_stats) +
+ ARRAY_LEN(hinic3_netdev_link_count) +
ARRAY_LEN(hinic3_function_stats) +
(ARRAY_LEN(hinic3_tx_queue_stats) +
ARRAY_LEN(hinic3_rx_queue_stats)) * q_num;
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER)
- count += ARRAY_LEN(g_hinic3_fpga_port_stats);
- else
- count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(g_hinic3_rsfec_stats);
}
return count;
@@ -452,9 +483,9 @@ static void get_drv_queue_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
}
}
-static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct hinic3_phy_fpga_port_stats *port_stats = NULL;
+ struct mag_cmd_port_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
@@ -464,19 +495,19 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to malloc port stats\n");
memset(&data[i], 0,
- ARRAY_LEN(g_hinic3_fpga_port_stats) * sizeof(*data));
- i += ARRAY_LEN(g_hinic3_fpga_port_stats);
+ ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
+ i += ARRAY_LEN(hinic3_port_stats);
return i;
}
- err = hinic3_get_fpga_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to get port stats from fw\n");
- for (j = 0; j < ARRAY_LEN(g_hinic3_fpga_port_stats); j++, i++) {
- p = (char *)(port_stats) + g_hinic3_fpga_port_stats[j].offset;
- data[i] = (g_hinic3_fpga_port_stats[j].size ==
+ for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
+ p = (char *)(port_stats) + hinic3_port_stats[j].offset;
+ data[i] = (hinic3_port_stats[j].size ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
@@ -485,35 +516,32 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
return i;
}
-static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_rsfec_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct mag_cmd_port_stats *port_stats = NULL;
+ struct mag_cmd_rsfec_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
- if (mag_support_mode == FPGA_PORT_COUNTER)
- return get_fpga_port_stats(nic_dev, data);
-
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
if (!port_stats) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to malloc port stats\n");
memset(&data[i], 0,
- ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
- i += ARRAY_LEN(hinic3_port_stats);
+ ARRAY_LEN(g_hinic3_rsfec_stats) * sizeof(*data));
+ i += ARRAY_LEN(g_hinic3_rsfec_stats);
return i;
- }
+ }
- err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_rsfec_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to get port stats from fw\n");
+ "Failed to get rsfec stats from fw\n");
- for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
- p = (char *)(port_stats) + hinic3_port_stats[j].offset;
- data[i] = (hinic3_port_stats[j].size ==
- sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+ for (j = 0; j < ARRAY_LEN(g_hinic3_rsfec_stats); j++, i++) {
+ p = (char *)(port_stats) + g_hinic3_rsfec_stats[j].offset;
+ data[i] = (g_hinic3_rsfec_stats[j].size ==
+ sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
kfree(port_stats);
@@ -537,6 +565,8 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
u16 i = 0, j = 0;
char *p = NULL;
int err;
+ int link_down_events_phy_tmp = 0;
+ struct hinic3_netdev_link_count_str link_count = {0};
#ifdef HAVE_NDO_GET_STATS64
net_stats = dev_get_stats(netdev, &temp);
@@ -554,6 +584,14 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = GET_VALUE_OF_PTR(hinic3_nic_dev_stats[j].size, p);
}
+ err = hinic3_get_link_event_stats(nic_dev->hwdev, &link_down_events_phy_tmp);
+
+ link_count.link_down_events_phy = (u64)link_down_events_phy_tmp;
+ for (j = 0; j < ARRAY_LEN(hinic3_netdev_link_count); j++, i++) {
+ p = (char *)(&link_count) + hinic3_netdev_link_count[j].offset;
+ data[i] = GET_VALUE_OF_PTR(hinic3_netdev_link_count[j].size, p);
+ }
+
err = hinic3_get_vport_stats(nic_dev->hwdev, hinic3_global_func_id(nic_dev->hwdev),
&vport_stats);
if (err)
@@ -565,8 +603,10 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = GET_VALUE_OF_PTR(hinic3_function_stats[j].size, p);
}
- if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
i += get_ethtool_port_stats(nic_dev, data + i);
+ i += get_ethtool_rsfec_stats(nic_dev, data + i);
+ }
get_drv_queue_stats(nic_dev, data + i);
}
@@ -588,6 +628,12 @@ static u16 get_drv_dev_strings(struct hinic3_nic_dev *nic_dev, char *p)
cnt++;
}
+ for (i = 0; i < ARRAY_LEN(hinic3_netdev_link_count); i++) {
+ memcpy(p, hinic3_netdev_link_count[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+
return cnt;
}
@@ -603,18 +649,16 @@ static u16 get_hw_stats_strings(struct hinic3_nic_dev *nic_dev, char *p)
}
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER) {
- for (i = 0; i < ARRAY_LEN(g_hinic3_fpga_port_stats); i++) {
- memcpy(p, g_hinic3_fpga_port_stats[i].name, ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
- } else {
- for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
- memcpy(p, hinic3_port_stats[i].name, ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
+ for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
+ memcpy(p, hinic3_port_stats[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+ for (i = 0; i < ARRAY_LEN(g_hinic3_rsfec_stats); i++) {
+ memcpy(p, g_hinic3_rsfec_stats[i].name,
+ ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
}
}
@@ -758,7 +802,6 @@ struct hw2ethtool_link_mode {
u32 speed;
};
-/*lint -save -e26 */
static const struct hw2ethtool_link_mode
hw2ethtool_link_mode_table[LINK_MODE_MAX_NUMBERS] = {
[LINK_MODE_GE] = {
@@ -818,8 +861,6 @@ static const struct hw2ethtool_link_mode
},
};
-/*lint -restore */
-
#define GET_SUPPORTED_MODE 0
#define GET_ADVERTISED_MODE 1
@@ -838,29 +879,33 @@ struct cmd_link_settings {
#define ETHTOOL_ADD_ADVERTISED_LINK_MODE(ecmd, mode) \
set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->advertising)
-#define ETHTOOL_ADD_SUPPORTED_SPEED_LINK_MODE(ecmd, mode) \
-do { \
- u32 i; \
- for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) { \
- if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >= \
- __ETHTOOL_LINK_MODE_MASK_NBITS) \
- continue; \
- set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i], \
- (ecmd)->supported); \
- } \
-} while (0)
+static void ethtool_add_supported_speed_link_mode(struct cmd_link_settings *link_settings,
+ u32 mode)
+{
+ u32 i;
-#define ETHTOOL_ADD_ADVERTISED_SPEED_LINK_MODE(ecmd, mode) \
-do { \
- u32 i; \
- for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) { \
- if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >= \
- __ETHTOOL_LINK_MODE_MASK_NBITS) \
- continue; \
- set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i], \
- (ecmd)->advertising); \
- } \
-} while (0)
+ for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
+ if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
+ continue;
+ set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
+ link_settings->supported);
+ }
+}
+
+static void ethtool_add_advertised_speed_link_mode(struct cmd_link_settings *link_settings,
+ u32 mode)
+{
+ u32 i;
+
+ for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
+ if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
+ continue;
+ set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
+ link_settings->advertising);
+ }
+}
/* Related to enum mag_cmd_port_speed */
static u32 hw_to_ethtool_speed[] = {
@@ -888,11 +933,11 @@ static void hinic3_add_ethtool_link_mode(struct cmd_link_settings *link_settings
for (link_mode = 0; link_mode < LINK_MODE_MAX_NUMBERS; link_mode++) {
if (hw_link_mode & BIT(link_mode)) {
if (name == GET_SUPPORTED_MODE)
- ETHTOOL_ADD_SUPPORTED_SPEED_LINK_MODE
- (link_settings, link_mode);
+ ethtool_add_supported_speed_link_mode(
+ link_settings, link_mode);
else
- ETHTOOL_ADD_ADVERTISED_SPEED_LINK_MODE
- (link_settings, link_mode);
+ ethtool_add_advertised_speed_link_mode(
+ link_settings, link_mode);
}
}
}
@@ -915,10 +960,15 @@ static int hinic3_link_speed_set(struct hinic3_nic_dev *nic_dev,
err = hinic3_get_link_state(nic_dev->hwdev, &link_state);
if (!err && link_state) {
- link_settings->speed =
- port_info->speed < ARRAY_LEN(hw_to_ethtool_speed) ?
- hw_to_ethtool_speed[port_info->speed] :
- (u32)SPEED_UNKNOWN;
+ if (hinic3_get_bond_create_mode(nic_dev->hwdev)) {
+ link_settings->speed = port_info->bond_speed;
+ } else {
+ link_settings->speed =
+ port_info->speed <
+ ARRAY_LEN(hw_to_ethtool_speed) ?
+ hw_to_ethtool_speed[port_info->speed] :
+ (u32)SPEED_UNKNOWN;
+ }
link_settings->duplex = port_info->duplex;
} else {
@@ -993,6 +1043,39 @@ static int get_link_pause_settings(struct hinic3_nic_dev *nic_dev,
return 0;
}
+static bool is_bit_offset_defined(u8 bit_offset)
+{
+ if (bit_offset < __ETHTOOL_LINK_MODE_MASK_NBITS)
+ return true;
+ return false;
+}
+
+static void
+ethtool_add_supported_advertised_fec(struct cmd_link_settings *link_settings,
+ u32 fec, u8 cmd)
+{
+ u8 i;
+ for (i = 0; i < HINIC_ETHTOOL_FEC_INFO_LEN; i++) {
+ if ((fec & BIT(hinic3_ethtool_fec_info[i].hinic_fec_offset)) == 0)
+ continue;
+ if ((is_bit_offset_defined(hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true) &&
+ (cmd == HINIC_ADVERTISED_FEC_CMD)) {
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset, link_settings->advertising);
+ return; /* There can be only one advertised fec mode. */
+ }
+ if ((is_bit_offset_defined(hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true) &&
+ (cmd == HINIC_SUPPORTED_FEC_CMD))
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset, link_settings->supported);
+ }
+}
+
+static void hinic3_link_fec_type(struct cmd_link_settings *link_settings,
+ u32 fec, u32 supported_fec)
+{
+ ethtool_add_supported_advertised_fec(link_settings, supported_fec, HINIC_SUPPORTED_FEC_CMD);
+ ethtool_add_supported_advertised_fec(link_settings, fec, HINIC_ADVERTISED_FEC_CMD);
+}
+
static int get_link_settings(struct net_device *netdev,
struct cmd_link_settings *link_settings)
{
@@ -1013,6 +1096,9 @@ static int get_link_settings(struct net_device *netdev,
hinic3_link_port_type(link_settings, port_info.port_type);
+ hinic3_link_fec_type(link_settings, BIT(port_info.fec),
+ port_info.supported_fec_mode);
+
link_settings->autoneg = port_info.autoneg_state == PORT_CFG_AN_ON ?
AUTONEG_ENABLE : AUTONEG_DISABLE;
if (port_info.autoneg_cap)
@@ -1138,10 +1224,11 @@ static int hinic3_set_settings_to_hw(struct hinic3_nic_dev *nic_dev,
struct net_device *netdev = nic_dev->netdev;
struct hinic3_link_ksettings settings = {0};
int speed_level = 0;
- char set_link_str[128] = {0};
+ char set_link_str[HINIC_SET_LINK_STR_LEN] = {0};
+ char link_info[HINIC_SET_LINK_STR_LEN] = {0};
int err = 0;
- err = snprintf(set_link_str, sizeof(set_link_str) - 1, "%s",
+ err = snprintf(link_info, sizeof(link_info), "%s",
(bool)(set_settings & HILINK_LINK_SET_AUTONEG) ?
((bool)autoneg ? "autong enable " : "autong disable ") : "");
if (err < 0)
@@ -1149,8 +1236,8 @@ static int hinic3_set_settings_to_hw(struct hinic3_nic_dev *nic_dev,
if (set_settings & HILINK_LINK_SET_SPEED) {
speed_level = hinic3_ethtool_to_hw_speed_level(speed);
- err = snprintf(set_link_str, sizeof(set_link_str) - 1,
- "%sspeed %u ", set_link_str, speed);
+ err = snprintf(set_link_str, sizeof(set_link_str),
+ "%sspeed %u ", link_info, speed);
if (err < 0)
return -EINVAL;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
index 70346d6..2daa7f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
@@ -82,7 +82,7 @@ static struct hinic3_mac_filter *hinic3_add_filter(struct hinic3_nic_dev *nic_de
struct list_head *mac_filter_list,
u8 *addr)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
@@ -117,7 +117,7 @@ static void hinic3_del_filter(struct hinic3_nic_dev *nic_dev,
static struct hinic3_mac_filter *hinic3_mac_filter_entry_clone(const struct hinic3_mac_filter *src)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
index ef8c62b..7fed1c1 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
@@ -40,6 +40,7 @@ enum hinic3_channel_id {
HINIC3_CHANNEL_DSW,
HINIC3_CHANNEL_MIG,
HINIC3_CHANNEL_CRYPT,
+ HINIC3_CHANNEL_VROCE,
HINIC3_CHANNEL_MAX = 32,
};
@@ -397,6 +398,16 @@ void hinic3_free_cmd_buf(void *hwdev, struct hinic3_cmd_buf *cmd_buf);
**/
int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read clear
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+
/**
* @brief hinic3_sm_ctr_rd32 - small single 32 counter read
* @param hwdev: device pointer to hwdev
@@ -810,6 +821,13 @@ int hinic3_dbg_lt_wr_16byte_mask(void *hwdev, u8 dest, u8 instance,
*/
void hinic3_link_event_stats(void *dev, u8 link);
+/**
+ * @brief hinic3_get_link_event_stats - link event stats
+ * @param hwdev: device pointer to hwdev
+ * @param link: link status
+ */
+int hinic3_get_link_event_stats(void *dev, int *link_state);
+
/**
* @brief hinic3_get_hw_pf_infos - get pf infos
* @param hwdev: device pointer to hwdev
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
index 3c835ff..7a2644c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
@@ -12,6 +12,7 @@
#include <linux/netdevice.h>
#include <linux/debugfs.h>
+#include "ossl_knl.h"
#include "hinic3_hw.h"
#include "hinic3_crm.h"
#include "hinic3_nic_io.h"
@@ -47,12 +48,16 @@ static void qp_add_napi(struct hinic3_irq *irq_cfg)
netif_napi_add(nic_dev->netdev, &irq_cfg->napi,
hinic3_poll, nic_dev->poll_weight);
napi_enable(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_IS_REGIN;
}
-static void qp_del_napi(struct hinic3_irq *irq_cfg)
+void qp_del_napi(struct hinic3_irq *irq_cfg)
{
- napi_disable(&irq_cfg->napi);
- netif_napi_del(&irq_cfg->napi);
+ if (irq_cfg->napi_reign == NAPI_IS_REGIN) {
+ napi_disable(&irq_cfg->napi);
+ netif_napi_del(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_NOT_REGIN;
+ }
}
static irqreturn_t qp_irq(int irq, void *data)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
deleted file mode 100644
index 2482c5f..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_LLD_H
-#define HINIC3_LLD_H
-
-#include "hinic3_crm.h"
-
-struct hinic3_lld_dev {
- struct pci_dev *pdev;
- void *hwdev;
-};
-
-struct hinic3_uld_info {
- /* When the function does not need to initialize the corresponding uld,
- * @probe needs to return 0 and uld_dev is set to NULL;
- * if uld_dev is NULL, @remove will not be called when uninstalling
- */
- int (*probe)(struct hinic3_lld_dev *lld_dev, void **uld_dev, char *uld_dev_name);
- void (*remove)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- int (*suspend)(struct hinic3_lld_dev *lld_dev, void *uld_dev, pm_message_t state);
- int (*resume)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- void (*event)(struct hinic3_lld_dev *lld_dev, void *uld_dev,
- struct hinic3_event_info *event);
- int (*ioctl)(void *uld_dev, u32 cmd, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size);
-};
-
-/* hinic3_register_uld - register an upper-layer driver
- * @type: uld service type
- * @uld_info: uld callback
- *
- * Registers an upper-layer driver.
- * Traverse existing devices and call @probe to initialize the uld device.
- */
-int hinic3_register_uld(enum hinic3_service_type type, struct hinic3_uld_info *uld_info);
-
-/**
- * hinic3_unregister_uld - unregister an upper-layer driver
- * @type: uld service type
- *
- * Traverse existing devices and call @remove to uninstall the uld device.
- * Unregisters an existing upper-layer driver.
- */
-void hinic3_unregister_uld(enum hinic3_service_type type);
-
-void lld_hold(void);
-void lld_put(void);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_name - get lld device by chip name
- * @param chip_name: chip name
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_name(const char *chip_name);
-
-/**
- * @brief lld_dev_hold - get reference to lld_dev
- * @param dev: lld device
- *
- * Hold reference to device to keep it from being freed
- **/
-void lld_dev_hold(struct hinic3_lld_dev *dev);
-
-/**
- * @brief lld_dev_put - release reference to lld_dev
- * @param dev: lld device
- *
- * Release reference to device to allow it to be freed
- **/
-void lld_dev_put(struct hinic3_lld_dev *dev);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name_unsafe - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * hinic3_get_lld_dev_by_dev_name_unsafe() is completely analogous to
- * hinic3_get_lld_dev_by_dev_name(), The only difference is that the reference
- * of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that lld_dev will not be freed during the remove process
- * when using lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name_unsafe(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_and_port - get lld device by chip name and port id
- * @param chip_name: chip name
- * @param port_id: port id
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name, u8 port_id);
-
-/**
- * @brief hinic3_get_ppf_lld_dev - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief hinic3_get_ppf_lld_dev_unsafe - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * hinic3_get_ppf_lld_dev_unsafe() is completely analogous to hinic3_get_ppf_lld_dev(),
- * The only difference is that the reference of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that ppf's lld_dev will not be freed during the remove process
- * when using ppf lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev_unsafe(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief uld_dev_hold - get reference to uld_dev
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * Hold reference to uld device to keep it from being freed
- **/
-void uld_dev_hold(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief uld_dev_put - release reference to lld_dev
- * @param dev: lld device
- * @param type: uld service type
- *
- * Release reference to uld device to allow it to be freed
- **/
-void uld_dev_put(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * The value of uld_dev reference increases when uld_dev is obtained. The caller needs
- * to release the reference by calling uld_dev_put.
- **/
-void *hinic3_get_uld_dev(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev_unsafe - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * hinic3_get_uld_dev_unsafe() is completely analogous to hinic3_get_uld_dev(),
- * The only difference is that the reference of uld_dev is not increased when uld_dev is obtained.
- *
- * The caller must ensure that uld_dev will not be freed during the remove process
- * when using uld_dev.
- **/
-void *hinic3_get_uld_dev_unsafe(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_chip_name - get chip name by lld device
- * @param lld_dev: lld device
- * @param chip_name: String for storing the chip name
- * @param max_len: Maximum number of characters to be copied for chip_name
- **/
-int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len);
-
-struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev);
-
-struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev);
-
-bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service);
-
-int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
- bool vf_srv_load);
-
-int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id,
- u16 service, bool en);
-
-bool hinic3_get_vf_load_state(struct pci_dev *pdev);
-
-int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state);
-
-int hinic3_attach_nic(struct hinic3_lld_dev *lld_dev);
-
-void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
-
-int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-const char **hinic3_get_uld_names(void);
-int hinic3_lld_init(void);
-void hinic3_lld_exit(void);
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
index 2fe808b..8cd891e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
@@ -17,12 +17,22 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_hw.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_common.h"
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
+#define CAP_INFO_MAX_LEN 512
+#define DEVICE_VENDOR_MAX_LEN 17
+#define READ_RSFEC_REGISTER_DELAY_TIME_MS 500
+
+struct parse_tlv_info g_page_info = {0};
+struct drv_mag_cmd_get_xsfp_tlv_rsp g_xsfp_tlv_info = {0};
+
static int mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
static int mag_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in,
@@ -78,8 +88,10 @@ int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats)
return -ENOMEM;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
memset(&stats_info, 0, sizeof(stats_info));
stats_info.port_id = hinic3_physical_port_id(hwdev);
@@ -104,6 +116,64 @@ out:
}
EXPORT_SYMBOL(hinic3_get_phy_port_stats);
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats)
+{
+ struct mag_cmd_get_mag_cnt *port_stats = NULL;
+ struct mag_cmd_get_mag_cnt stats_info;
+ u16 out_size = sizeof(*port_stats);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !stats)
+ return -EINVAL;
+
+ port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
+ if (!port_stats)
+ return -ENOMEM;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ memset(&stats_info, 0, sizeof(stats_info));
+ stats_info.port_id = hinic3_physical_port_id(hwdev);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT,
+ &stats_info, sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+ /* 读2遍, 清除误码残留 */
+ msleep(READ_RSFEC_REGISTER_DELAY_TIME_MS);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT, &stats_info,
+ sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+
+ memcpy(stats, &port_stats->mag_csr[MAG_RX_RSFEC_ERR_CW_CNT],
+ sizeof(u32));
+
+out:
+ kfree(port_stats);
+
+ return err;
+}
+EXPORT_SYMBOL(hinic3_get_phy_rsfec_stats);
+
int hinic3_set_port_funcs_state(void *hwdev, bool enable)
{
return 0;
@@ -180,6 +250,8 @@ int hinic3_get_loopback_mode(void *hwdev, u8 *mode, u8 *enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_cfg_loopback_mode(nic_io, MGMT_MSG_CMD_OP_GET, mode,
enable);
@@ -195,6 +267,8 @@ int hinic3_set_loopback_mode(void *hwdev, u8 mode, u8 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) {
nic_err(nic_io->dev_hdl, "Invalid loopback mode %u to set\n",
@@ -218,6 +292,9 @@ int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&led_info, 0, sizeof(led_info));
led_info.function_id = hinic3_global_func_id(hwdev);
@@ -249,6 +326,8 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
memset(&port_msg, 0, sizeof(port_msg));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
port_msg.port_id = hinic3_physical_port_id(hwdev);
@@ -268,9 +347,12 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
port_info->port_type = port_msg.wire_type;
port_info->speed = port_msg.speed;
port_info->fec = port_msg.fec;
+ port_info->lanes = port_msg.lanes;
port_info->supported_mode = port_msg.supported_mode;
port_info->advertised_mode = port_msg.advertised_mode;
-
+ port_info->supported_fec_mode = port_msg.supported_fec_mode;
+ /* switch Gbps to Mbps */
+ port_info->bond_speed = (u32)port_msg.bond_speed * RATE_MBPS_TO_GBPS;
return 0;
}
@@ -306,6 +388,8 @@ int hinic3_set_link_settings(void *hwdev,
memset(&info, 0, sizeof(info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
info.port_id = hinic3_physical_port_id(hwdev);
info.config_bitmap = settings->valid_bitmap;
@@ -335,6 +419,8 @@ int hinic3_get_link_state(void *hwdev, u8 *link_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&get_link, 0, sizeof(get_link));
get_link.port_id = hinic3_physical_port_id(hwdev);
@@ -364,9 +450,10 @@ void hinic3_notify_vf_link_status(struct hinic3_nic_io *nic_io,
if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
link.status = link_status;
link.port_id = hinic3_physical_port_id(nic_io->hwdev);
- err = hinic3_mbox_to_vf(nic_io->hwdev, vf_id, HINIC3_MOD_HILINK,
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
MAG_CMD_GET_LINK_STATUS, &link,
- sizeof(link), &link, &out_size, 0,
+ sizeof(link), &link, &out_size,
HINIC3_CHANNEL_NIC);
if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
@@ -387,6 +474,9 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
u16 i;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
+
nic_io->link_status = link_status;
for (i = 1; i <= nic_io->max_vfs; i++) {
if (!nic_io->vf_infos[HW_VF_ID_TO_OS(i)].link_forced)
@@ -394,6 +484,167 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
}
}
+static char *g_hw_to_char_fec[HILINK_FEC_MAX_TYPE] = {
+ "not set", "rsfec", "basefec",
+ "nofec", "llrsfec"};
+static char *g_hw_to_speed_info[PORT_SPEED_UNKNOWN] = {
+ "not set", "10MB", "100MB", "1GB", "10GB",
+ "25GB", "40GB", "50GB", "100GB", "200GB"};
+static char *g_hw_to_an_state_info[PORT_CFG_AN_OFF + 1] = {
+ "not set", "on", "off"};
+
+struct port_type_table {
+ u32 port_type;
+ char *port_type_name;
+};
+
+static const struct port_type_table port_optical_type_table_s[] = {
+ {LINK_PORT_UNKNOWN, "UNKNOWN"},
+ {LINK_PORT_OPTICAL_MM, "optical_sr"},
+ {LINK_PORT_OPTICAL_SM, "optical_lr"},
+ {LINK_PORT_PAS_COPPER, "copper"},
+ {LINK_PORT_ACC, "ACC"},
+ {LINK_PORT_BASET, "baset"},
+ {LINK_PORT_AOC, "AOC"},
+ {LINK_PORT_ELECTRIC, "electric"},
+ {LINK_PORT_BACKBOARD_INTERFACE, "interface"},
+};
+
+static char *get_port_type_name(u32 type)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(port_optical_type_table_s); i++) {
+ if (type == port_optical_type_table_s[i].port_type)
+ return port_optical_type_table_s[i].port_type_name;
+ }
+ return "UNKNOWN TYPE";
+}
+
+static void get_port_type(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ char **port_type)
+{
+ if (info->port_type <= LINK_PORT_BACKBOARD_INTERFACE)
+ *port_type = get_port_type_name(info->port_type);
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown port type: %u\n",
+ info->port_type);
+}
+
+static int get_port_temperature_power(struct mag_cmd_event_port_info *info,
+ char *str)
+{
+ char cap_info[CAP_INFO_MAX_LEN];
+
+ memset(cap_info, 0, sizeof(cap_info));
+ snprintf(cap_info, CAP_INFO_MAX_LEN, "%s, %s, Temperature: %u", str,
+ info->sfp_type ? "QSFP" : "SFP", info->cable_temp);
+
+ if (info->sfp_type)
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuw %uuW %uuW %uuW",
+ cap_info, info->power[0x0], info->power[0x1],
+ info->power[0x2], info->power[0x3]);
+ else
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuW, tx power: %uuW",
+ cap_info, info->power[0x0], info->power[0x1]);
+
+ return 0;
+}
+
+static void print_cable_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info)
+{
+ char tmp_str[CAP_INFO_MAX_LEN] = {0};
+ char tmp_vendor[DEVICE_VENDOR_MAX_LEN] = {0};
+ char *port_type = "Unknown port type";
+ int i;
+ int err = 0;
+
+ if (info->gpio_insert) {
+ sdk_info(nic_io->dev_hdl, "Cable unpresent\n");
+ return;
+ }
+
+ get_port_type(nic_io, info, &port_type);
+
+ for (i = sizeof(info->vendor_name) - 1; i >= 0; i--) {
+ if (info->vendor_name[i] == ' ')
+ info->vendor_name[i] = '\0';
+ else
+ break;
+ }
+
+ memcpy(tmp_vendor, info->vendor_name, sizeof(info->vendor_name));
+ snprintf(tmp_str, CAP_INFO_MAX_LEN, "Vendor: %s, %s, length: %um, max_speed: %uGbps",
+ tmp_vendor, port_type, info->cable_length, info->max_speed);
+
+ if (info->port_type == LINK_PORT_OPTICAL_MM ||
+ info->port_type == LINK_PORT_AOC) {
+ err = get_port_temperature_power(info, tmp_str);
+ if (err)
+ return;
+ }
+
+ sdk_info(nic_io->dev_hdl, "Cable information: %s\n", tmp_str);
+}
+
+static void print_link_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ enum hinic3_nic_event_type type)
+{
+ char *fec = "None";
+ char *speed = "None";
+ char *an_state = "None";
+
+ if (info->fec < HILINK_FEC_MAX_TYPE)
+ fec = g_hw_to_char_fec[info->fec];
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown fec type: %u\n", info->fec);
+
+ if (info->an_state > PORT_CFG_AN_OFF) {
+ sdk_info(nic_io->dev_hdl, "an_state %u is invalid",
+ info->an_state);
+ return;
+ }
+
+ an_state = g_hw_to_an_state_info[info->an_state];
+
+ if (info->speed >= PORT_SPEED_UNKNOWN) {
+ sdk_info(nic_io->dev_hdl, "speed %u is invalid", info->speed);
+ return;
+ }
+
+ speed = g_hw_to_speed_info[info->speed];
+ sdk_info(nic_io->dev_hdl, "Link information: speed %s, %s, autoneg %s",
+ speed, fec, an_state);
+}
+
+void print_port_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *port_info,
+ enum hinic3_nic_event_type type)
+{
+ print_cable_info(nic_io, port_info);
+
+ print_link_info(nic_io, port_info, type);
+
+ if (type == EVENT_NIC_LINK_UP)
+ return;
+
+ sdk_info(nic_io->dev_hdl, "PMA ctrl: %s, tx %s, rx %s, PMA fifo reg: 0x%x, PMA signal ok reg: 0x%x, RF/LF status reg: 0x%x\n",
+ port_info->pma_ctrl == 1 ? "off" : "on",
+ port_info->tx_enable ? "enable" : "disable",
+ port_info->rx_enable ? "enable" : "disable", port_info->pma_fifo_reg,
+ port_info->pma_signal_ok_reg, port_info->rf_lf);
+ sdk_info(nic_io->dev_hdl, "alos: %u, rx_los: %u, PCS 64 66b reg: 0x%x, PCS link: 0x%x, MAC link: 0x%x PCS_err_cnt: 0x%x\n",
+ port_info->alos, port_info->rx_los, port_info->pcs_64_66b_reg,
+ port_info->pcs_link, port_info->pcs_mac_link,
+ port_info->pcs_err_cnt);
+ sdk_info(nic_io->dev_hdl, "his_link_machine_state = 0x%08x, cur_link_machine_state = 0x%08x\n",
+ port_info->his_link_machine_state,
+ port_info->cur_link_machine_state);
+}
+
static int hinic3_get_vf_link_status_msg_handler(struct hinic3_nic_io *nic_io,
u16 vf_id, void *buf_in,
u16 in_size, void *buf_out,
@@ -433,6 +684,10 @@ static void get_port_info(void *hwdev,
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (hinic3_func_type(hwdev) != TYPE_VF && link_status->status) {
err = hinic3_get_port_info(hwdev, &port_info, HINIC3_CHANNEL_NIC);
if (err) {
@@ -457,8 +712,17 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
struct hinic3_event_info event_info = {0};
struct hinic3_event_link_info *link_info = (void *)event_info.event_data;
struct hinic3_nic_io *nic_io = NULL;
+ struct pci_dev *pdev = NULL;
+
+ /* Ignore link change event */
+ if (hinic3_is_bm_slave_host(hwdev))
+ return;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
link_status = buf_in;
sdk_info(nic_io->dev_hdl, "Link status report received, func_id: %u, status: %u\n",
@@ -475,6 +739,13 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
hinic3_event_callback(hwdev, &event_info);
+ if (nic_io->pcidev_hdl != NULL) {
+ pdev = nic_io->pcidev_hdl;
+ if (pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID) {
+ return;
+ }
+ }
+
if (hinic3_func_type(hwdev) != TYPE_VF) {
hinic3_notify_all_vfs_link_changed(hwdev, link_status->status);
ret_link_status = buf_out;
@@ -483,20 +754,142 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
}
}
+static void port_info_event_printf(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_event_port_info *port_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info;
+ enum hinic3_nic_event_type type;
+
+ if (!hwdev) {
+ pr_err("hwdev is NULL\n");
+ return;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ if (in_size != sizeof(*port_info)) {
+ sdk_info(nic_io->dev_hdl, "Invalid port info message size %u, should be %lu\n",
+ in_size, sizeof(*port_info));
+ return;
+ }
+
+ ((struct mag_cmd_event_port_info *)buf_out)->head.status = 0;
+
+ type = port_info->event_type;
+ if (type < EVENT_NIC_LINK_DOWN || type > EVENT_NIC_LINK_UP) {
+ sdk_info(nic_io->dev_hdl, "Invalid hilink info report, type: %d\n",
+ type);
+ return;
+ }
+
+ print_port_info(nic_io, port_info, type);
+
+ memset(&event_info, 0, sizeof(event_info));
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = type;
+
+ *out_size = sizeof(*port_info);
+
+ hinic3_event_callback(hwdev, &event_info);
+}
+
+void hinic3_notify_vf_bond_status(struct hinic3_nic_io *nic_io,
+ u16 vf_id, u8 bond_status)
+{
+ struct mag_cmd_get_bond_status bond;
+ struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ u16 out_size = sizeof(bond);
+ int err;
+
+ memset(&bond, 0, sizeof(bond));
+ if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
+ bond.status = bond_status;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
+ MAG_CMD_GET_BOND_STATUS, &bond,
+ sizeof(bond), &bond, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF %hu not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return;
+ }
+ if (err || !out_size || bond.head.status)
+ nic_err(nic_io->dev_hdl,
+ "Send bond change event to VF %hu failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err, bond.head.status,
+ out_size);
+ }
+}
+
+void hinic3_notify_all_vfs_bond_changed(void *hwdev, u8 bond_status)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 i;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ nic_io->link_status = bond_status;
+ for (i = 1; i <= nic_io->max_vfs; i++)
+ hinic3_notify_vf_bond_status(nic_io, i, bond_status);
+}
+
+static void bond_status_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_get_bond_status *bond_status = NULL;
+ struct hinic3_event_info event_info = {};
+ struct hinic3_nic_io *nic_io = NULL;
+ struct mag_cmd_get_bond_status *ret_bond_status = NULL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+
+ bond_status = (struct mag_cmd_get_bond_status *)buf_in;
+ sdk_info(nic_io->dev_hdl, "bond status report received, func_id: %u, status: %u\n",
+ hinic3_global_func_id(hwdev), bond_status->status);
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = bond_status->status ?
+ EVENT_NIC_BOND_UP : EVENT_NIC_BOND_DOWN;
+
+ hinic3_event_callback(hwdev, &event_info);
+
+ if (hinic3_func_type(hwdev) != TYPE_VF) {
+ hinic3_notify_all_vfs_bond_changed(hwdev, bond_status->status);
+ ret_bond_status = buf_out;
+ ret_bond_status->head.status = 0;
+ *out_size = sizeof(*ret_bond_status);
+ }
+}
+
static void cable_plug_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct mag_cmd_wire_event *plug_event = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_event_info event_info;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
rt_cmd->mpu_send_sfp_abs = false;
rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
memset(&event_info, 0, sizeof(event_info));
@@ -518,20 +911,54 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
{
struct mag_cmd_get_xsfp_info *sfp_info = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_info)) {
- sdk_err(nic_io->dev_hdl, "Invalid sfp info cmd, length: %u, should be %ld\n",
+ sdk_err(nic_io->dev_hdl, "Invalid sfp info cmd, length: %u, should be %lu\n",
in_size, sizeof(*sfp_info));
return;
}
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
memcpy(&rt_cmd->std_sfp_info, sfp_info,
sizeof(struct mag_cmd_get_xsfp_info));
rt_cmd->mpu_send_sfp_info = true;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+}
+
+static void port_xsfp_tlv_info_event(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_get_xsfp_tlv_rsp *xsfp_tlv_info = buf_in;
+ struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
+ size_t cpy_len = in_size - sizeof(struct mgmt_msg_head) -
+ XSFP_TLV_PRE_INFO_LEN;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL)
+ return;
+
+ if (cpy_len > XSFP_CMIS_INFO_MAX_SIZE) {
+ sdk_err(nic_io->dev_hdl, "invalid cpy_len(%lu)\n", cpy_len);
+ return;
+ }
+ rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ rt_cmd_ext->std_xsfp_tlv_info.port_id = xsfp_tlv_info->port_id;
+ memcpy(&(rt_cmd_ext->std_xsfp_tlv_info.tlv_buf[0]),
+ &(xsfp_tlv_info->tlv_buf[0]), cpy_len);
+ rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = true;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
}
@@ -543,8 +970,10 @@ static void port_sfp_abs_event(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_abs)) {
- sdk_err(nic_io->dev_hdl, "Invalid sfp absent cmd, length: %u, should be %ld\n",
+ sdk_err(nic_io->dev_hdl, "Invalid sfp absent cmd, length: %u, should be %lu\n",
in_size, sizeof(*sfp_abs));
return;
}
@@ -564,9 +993,11 @@ bool hinic3_if_sfp_absent(void *hwdev)
u8 port_id = hinic3_physical_port_id(hwdev);
u16 out_size = sizeof(sfp_abs);
int err;
- bool sfp_abs_status;
+ bool sfp_abs_status = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return true;
memset(&sfp_abs, 0, sizeof(sfp_abs));
rt_cmd = &nic_io->nic_cfg.rt_cmd;
@@ -597,10 +1028,187 @@ bool hinic3_if_sfp_absent(void *hwdev)
return (sfp_abs.abs_status == 0 ? false : true);
}
+int hinic3_get_sfp_tlv_info(void *hwdev, struct drv_mag_cmd_get_xsfp_tlv_rsp
+ *sfp_tlv_info,
+ const struct mag_cmd_get_xsfp_tlv_req
+ *sfp_tlv_info_req)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ u16 out_size = sizeof(*sfp_tlv_info);
+ int err;
+
+ if ((hwdev == NULL) || (sfp_tlv_info == NULL))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL)
+ return -EINVAL;
+
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ if (rt_cmd_ext->mpu_send_xsfp_tlv_info == true) {
+ if (rt_cmd_ext->std_xsfp_tlv_info.head.status != 0) {
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return -EIO;
+ }
+
+ memcpy(sfp_tlv_info, &rt_cmd_ext->std_xsfp_tlv_info,
+ sizeof(*sfp_tlv_info));
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_TLV_INFO,
+ (void *)sfp_tlv_info_req,
+ sizeof(*sfp_tlv_info_req),
+ sfp_tlv_info, &out_size);
+ if ((sfp_tlv_info->head.status != 0) || (err != 0) || (out_size == 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get port%u tlv sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
+ hinic3_physical_port_id(hwdev), err,
+ sfp_tlv_info->head.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_get_page_pos(u32 page_id, u32 content_len, u32 *pos)
+{
+ if (page_id <= QSFP_CMIS_PAGE_03H) {
+ *pos = (page_id * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_11H) {
+ *pos = (QSFP_CMIS_PAGE_04H * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_12H) {
+ *pos = (QSFP_CMIS_PAGE_05H * content_len);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int hinic3_get_page_key_info(struct mgmt_tlv_info *tlv_info,
+ struct parse_tlv_info *page_info, u8 idx,
+ u32 *total_len)
+{
+ u8 *src_addr = NULL;
+ u8 *dst_addr = NULL;
+ u8 *tmp_addr = NULL;
+ u32 page_id = 0;
+ u32 content_len = 0;
+ u32 src_pos = 0;
+ int ret;
+
+ page_id = MGMT_TLV_GET_U32(tlv_info->value);
+ content_len = tlv_info->length - MGMT_TLV_U32_SIZE;
+ if (page_id == QSFP_CMIS_PAGE_00H) {
+ tmp_addr = (u8 *)(tlv_info + 1);
+ page_info->id = *(tmp_addr + MGMT_TLV_U32_SIZE);
+ }
+
+ ret = hinic3_trans_cmis_get_page_pos(page_id, content_len, &src_pos);
+ if (ret != 0)
+ return ret;
+
+ src_addr = page_info->tlv_page_info + src_pos;
+ tmp_addr = (u8 *)(tlv_info + 1);
+ dst_addr = tmp_addr + MGMT_TLV_U32_SIZE;
+ memcpy(src_addr, dst_addr, content_len);
+ if (ret != 0)
+ return ret;
+
+ if (idx < XSFP_CMIS_PARSE_PAGE_NUM)
+ page_info->tlv_page_num[idx] = page_id;
+
+ *total_len += content_len;
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_tlv_info_to_buf(u8 *sfp_tlv_info,
+ struct parse_tlv_info *page_info)
+{
+ struct mgmt_tlv_info *tlv_info = NULL;
+ u8 *tlv_buf = sfp_tlv_info;
+ u8 idx = 0;
+ u32 total_len = 0;
+ int ret = 0;
+ bool need_continue = true;
+
+ if ((sfp_tlv_info == NULL) || (page_info == NULL))
+ return -EIO;
+
+ while (need_continue) {
+ tlv_info = (struct mgmt_tlv_info *)tlv_buf;
+ switch (tlv_info->type) {
+ case MAG_XSFP_TYPE_PAGE:
+ ret = hinic3_get_page_key_info(
+ tlv_info, page_info, idx, &total_len);
+ if (ret != 0) {
+ pr_err("lib_get_page_key_info fail,ret:0x%x.\n",
+ ret);
+ break;
+ }
+ idx++;
+ break;
+
+ case MAG_XSFP_TYPE_WIRE_TYPE:
+ page_info->wire_type =
+ MGMT_TLV_GET_U32(&(tlv_info->value[0]));
+ break;
+
+ case MAG_XSFP_TYPE_END:
+ need_continue = false;
+ break;
+
+ default:
+ break;
+ }
+
+ tlv_buf += (sizeof(struct mgmt_tlv_info) + tlv_info->length);
+ }
+
+ page_info->tlv_page_info_len = total_len;
+
+ return 0;
+}
+
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len)
+{
+ int err = 0;
+ struct mag_cmd_get_xsfp_tlv_req xsfp_tlv_info_req = {0};
+
+ xsfp_tlv_info_req.rsp_buf_len = XSFP_CMIS_INFO_MAX_SIZE;
+ xsfp_tlv_info_req.port_id = hinic3_physical_port_id(hwdev);
+ err = hinic3_get_sfp_tlv_info(hwdev, &g_xsfp_tlv_info,
+ &xsfp_tlv_info_req);
+ if (err != 0)
+ return err;
+
+ err = hinic3_trans_cmis_tlv_info_to_buf(g_xsfp_tlv_info.tlv_buf,
+ &g_page_info);
+ if (err)
+ return -ENOMEM;
+
+ memcpy(data, g_page_info.tlv_page_info, len);
+
+ return (err == 0) ? 0 : -ENOMEM;
+}
+
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
{
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ u8 sfp_info_status = 0;
u16 out_size = sizeof(*sfp_info);
int err;
@@ -608,13 +1216,17 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ sfp_info_status = rt_cmd->std_sfp_info.head.status;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (sfp_info_status != 0) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return -EIO;
+ return (sfp_info_status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ ? HINIC3_MGMT_CMD_UNSUPPORTED : -EIO;
}
memcpy(sfp_info, &rt_cmd->std_sfp_info, sizeof(*sfp_info));
@@ -626,7 +1238,14 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
sfp_info->port_id = hinic3_physical_port_id(hwdev);
err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_INFO, sfp_info,
sizeof(*sfp_info), sfp_info, &out_size);
- if (sfp_info->head.status || err || !out_size) {
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED) {
+ return HINIC3_MGMT_CMD_UNSUPPORTED;
+ }
+
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED) {
+ return -EOPNOTSUPP;
+ }
+ if ((sfp_info->head.status != 0) || (err != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Failed to get port%u sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
hinic3_physical_port_id(hwdev), err,
@@ -642,7 +1261,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
struct mag_cmd_get_xsfp_info sfp_info;
int err;
- if (!hwdev || !data)
+ if (!hwdev || !data || len > PAGE_SIZE)
return -EINVAL;
if (hinic3_if_sfp_absent(hwdev))
@@ -654,7 +1273,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
if (err)
return err;
- memcpy(data, sfp_info.sfp_info, len);
+ memcpy(data, sfp_info.sfp_info, sizeof(sfp_info.sfp_info));
return 0;
}
@@ -664,7 +1283,7 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
- int err;
+ int err = 0;
if (!hwdev || !sfp_type || !sfp_type_ext)
return -EINVAL;
@@ -673,24 +1292,41 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
return -ENXIO;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (rt_cmd->std_sfp_info.head.status == 0) {
+ *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
+ *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ if (rt_cmd->std_sfp_info.head.status != HINIC3_MGMT_CMD_UNSUPPORTED) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
return -EIO;
}
- *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
- *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
- mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return 0;
+ err = HINIC3_MGMT_CMD_UNSUPPORTED; /* cmis */
}
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
- STD_SFP_INFO_MAX_SIZE);
+ if (err == 0) {
+ err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ } else {
+ /* mpu_send_sfp_info is false */
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ }
+
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+
if (err)
return err;
@@ -796,12 +1432,20 @@ int hinic3_set_pf_bw_limit(void *hwdev, u32 bw_limit)
return -EINVAL;
}
- old_bw_limit = nic_io->nic_cfg.pf_bw_limit;
- nic_io->nic_cfg.pf_bw_limit = bw_limit;
+ if (nic_io->direct == HINIC3_NIC_TX) {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_tx_limit;
+ nic_io->nic_cfg.pf_bw_tx_limit = bw_limit;
+ } else {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_rx_limit;
+ nic_io->nic_cfg.pf_bw_rx_limit = bw_limit;
+ }
err = hinic3_update_pf_bw(hwdev);
if (err) {
- nic_io->nic_cfg.pf_bw_limit = old_bw_limit;
+ if (nic_io->direct == HINIC3_NIC_TX)
+ nic_io->nic_cfg.pf_bw_tx_limit = old_bw_limit;
+ else
+ nic_io->nic_cfg.pf_bw_rx_limit = old_bw_limit;
return err;
}
@@ -828,6 +1472,8 @@ int hinic3_pf_mag_mbox_handler(void *hwdev, u16 vf_id,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (index = 0; index < cmd_size; index++) {
handler = &vf_mag_cmd_handler[index];
@@ -848,6 +1494,11 @@ static struct nic_event_handler mag_cmd_handler[] = {
.handler = link_status_event_handler,
},
+ {
+ .cmd = MAG_CMD_EVENT_PORT_INFO,
+ .handler = port_info_event_printf,
+ },
+
{
.cmd = MAG_CMD_WIRE_EVENT,
.handler = cable_plug_event,
@@ -862,6 +1513,16 @@ static struct nic_event_handler mag_cmd_handler[] = {
.cmd = MAG_CMD_GET_XSFP_PRESENT,
.handler = port_sfp_abs_event,
},
+
+ {
+ .cmd = MAG_CMD_GET_BOND_STATUS,
+ .handler = bond_status_event_handler,
+ },
+
+ {
+ .cmd = MAG_CMD_GET_XSFP_TLV_INFO,
+ .handler = port_xsfp_tlv_info_event,
+ },
};
static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
@@ -877,6 +1538,9 @@ static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
for (i = 0; i < size; i++) {
if (cmd == mag_cmd_handler[i].cmd) {
mag_cmd_handler[i].handler(hwdev, buf_in, in_size,
@@ -917,7 +1581,8 @@ static int _mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u32 i, cmd_cnt = ARRAY_LEN(vf_mag_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_mag_cmd_handler[i].cmd) {
cmd_to_pf = true;
@@ -949,3 +1614,124 @@ static int mag_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in,
return _mag_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out,
out_size, channel);
}
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+struct fecparam_value_map {
+ u8 hinic3_fec_offset;
+ u8 hinic3_fec_value;
+ u8 ethtool_fec_value;
+};
+
+static void fecparam_convert(u32 opcode, u8 in_fec_param, u8 *out_fec_param)
+{
+ u8 i;
+ u8 fec_value_table_lenth;
+ struct fecparam_value_map fec_value_table[] = {
+ {PORT_FEC_NOT_SET, BIT(PORT_FEC_NOT_SET), ETHTOOL_FEC_NONE},
+ {PORT_FEC_RSFEC, BIT(PORT_FEC_RSFEC), ETHTOOL_FEC_RS},
+ {PORT_FEC_BASEFEC, BIT(PORT_FEC_BASEFEC), ETHTOOL_FEC_BASER},
+ {PORT_FEC_NOFEC, BIT(PORT_FEC_NOFEC), ETHTOOL_FEC_OFF},
+#ifdef ETHTOOL_FEC_LLRS
+ {PORT_FEC_LLRSFEC, BIT(PORT_FEC_LLRSFEC), ETHTOOL_FEC_LLRS},
+#endif
+ {PORT_FEC_AUTO, BIT(PORT_FEC_AUTO), ETHTOOL_FEC_AUTO}
+ };
+
+ *out_fec_param = 0;
+ fec_value_table_lenth = (u8)(sizeof(fec_value_table) / sizeof(struct fecparam_value_map));
+
+ if (opcode == MAG_CMD_OPCODE_SET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].ethtool_fec_value) != 0)
+ /* The MPU uses the offset to determine the FEC mode. */
+ *out_fec_param =
+ fec_value_table[i].hinic3_fec_offset;
+ }
+ }
+
+ if (opcode == MAG_CMD_OPCODE_GET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].hinic3_fec_value) != 0)
+ *out_fec_param |=
+ fec_value_table[i].ethtool_fec_value;
+ }
+ }
+}
+
+/* When the ethtool is used to set the FEC mode */
+static bool check_fecparam_is_valid(u8 fec_param)
+{
+ if (
+#ifdef ETHTOOL_FEC_LLRS
+ (fec_param == ETHTOOL_FEC_LLRS) ||
+#endif
+ (fec_param == ETHTOOL_FEC_RS) ||
+ (fec_param == ETHTOOL_FEC_BASER) ||
+ (fec_param == ETHTOOL_FEC_OFF)) {
+ return true;
+ }
+ return false;
+}
+
+int set_fecparam(void *hwdev, u8 fecparam)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ u8 advertised_fec = 0;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (check_fecparam_is_valid(fecparam) == false) {
+ nic_err(nic_io->dev_hdl, "fec param is invalid, failed to set fec param\n");
+ return -EINVAL;
+ }
+ fecparam_convert(MAG_CMD_OPCODE_SET, fecparam, &advertised_fec);
+ fec_msg.opcode = MAG_CMD_OPCODE_SET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ fec_msg.advertised_fec = advertised_fec;
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0))
+ return -EINVAL;
+ return 0;
+}
+
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ fec_msg.opcode = MAG_CMD_OPCODE_GET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0))
+ return -EINVAL;
+
+ /* fec_msg.advertised_fec: bit offset,
+ *value is BIT(fec_msg.advertised_fec); fec_msg.supported_fec: value
+ */
+ fecparam_convert(MAG_CMD_OPCODE_GET, BIT(fec_msg.advertised_fec),
+ advertised_fec);
+ fecparam_convert(MAG_CMD_OPCODE_GET, fec_msg.supported_fec,
+ supported_fec);
+ return 0;
+}
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
index 307ad8d..7790ae2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
@@ -20,6 +20,9 @@
#include <linux/debugfs.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#include "hinic3_hw.h"
#include "hinic3_crm.h"
#include "hinic3_mt.h"
@@ -35,8 +38,8 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
#include "hinic3_profile.h"
+#include "hinic3_bond.h"
-/*lint -e806*/
#define DEFAULT_POLL_WEIGHT 64
static unsigned int poll_weight = DEFAULT_POLL_WEIGHT;
module_param(poll_weight, uint, 0444);
@@ -68,7 +71,9 @@ static unsigned char set_link_status_follow = HINIC3_LINK_FOLLOW_STATUS_MAX;
module_param(set_link_status_follow, byte, 0444);
MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=default,1=follow,2=separate,3=unset");
-/*lint +e806*/
+static bool page_pool_enabled = true;
+module_param(page_pool_enabled, bool, 0444);
+MODULE_PARM_DESC(page_pool_enabled, "enable/disable page_pool feature for rxq page management (default enable)");
#define HINIC3_NIC_DEV_WQ_NAME "hinic3_nic_dev_wq"
@@ -80,6 +85,8 @@ MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=
#define HINIC3_SQ_DEPTH 1024
#define HINIC3_RQ_DEPTH 1024
+#define LRO_ENABLE 1
+
enum hinic3_rx_buff_len {
RX_BUFF_VALID_2KB = 2,
RX_BUFF_VALID_4KB = 4,
@@ -88,6 +95,9 @@ enum hinic3_rx_buff_len {
};
#define CONVERT_UNIT 1024
+#define NIC_MAX_PF_NUM 32
+
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
static int hinic3_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr);
@@ -99,6 +109,17 @@ static struct notifier_block hinic3_netdev_notifier = {
.notifier_call = hinic3_netdev_event,
};
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+static const struct udp_tunnel_nic_info hinic3_udp_tunnels = {
+ .set_port = hinic3_udp_tunnel_set_port,
+ .unset_port = hinic3_udp_tunnel_unset_port,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static void hinic3_register_notifier(struct hinic3_nic_dev *nic_dev)
{
int err;
@@ -264,6 +285,11 @@ static void netdev_feature_init(struct net_device *netdev)
netdev->features |= dft_fts | cso_fts | tso_fts | vlan_fts;
netdev->vlan_features |= dft_fts | cso_fts | tso_fts;
+ if (nic_dev->nic_cap.lro_enable == LRO_ENABLE) {
+ netdev->features |= NETIF_F_LRO;
+ netdev->vlan_features |= NETIF_F_LRO;
+ }
+
#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT
hw_features |= get_netdev_hw_features(netdev);
#else
@@ -350,6 +376,7 @@ static int hinic3_init_intr_coalesce(struct hinic3_nic_dev *nic_dev)
static void hinic3_free_intr_coalesce(struct hinic3_nic_dev *nic_dev)
{
kfree(nic_dev->intr_coalesce);
+ nic_dev->intr_coalesce = NULL;
}
static int hinic3_alloc_txrxqs(struct hinic3_nic_dev *nic_dev)
@@ -404,8 +431,85 @@ static void hinic3_sw_deinit(struct hinic3_nic_dev *nic_dev)
HINIC3_CHANNEL_NIC);
hinic3_clear_rss_config(nic_dev);
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+ hinic3_dcb_deinit(nic_dev);
+}
+
+static void hinic3_netdev_mtu_init(struct net_device *netdev)
+{
+ /* MTU range: 384 - 9600 */
+#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
+ netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+
+#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
+ netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+}
+
+static int hinic3_set_default_mac(struct hinic3_nic_dev *nic_dev)
+{
+ struct net_device *netdev = nic_dev->netdev;
+ u8 mac_addr[ETH_ALEN];
+ int err = 0;
+
+ err = hinic3_get_default_mac(nic_dev->hwdev, mac_addr);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev, "Failed to get MAC address\n");
+ return err;
+ }
+
+ ether_addr_copy(netdev->dev_addr, mac_addr);
+
+ if (!is_valid_ether_addr(netdev->dev_addr)) {
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
+ nic_err(&nic_dev->pdev->dev,
+ "Invalid MAC address %pM\n",
+ netdev->dev_addr);
+ return -EIO;
+ }
+
+ nic_info(&nic_dev->pdev->dev,
+ "Invalid MAC address %pM, using random\n",
+ netdev->dev_addr);
+ eth_hw_addr_random(netdev);
+ }
+
+ err = hinic3_set_mac(nic_dev->hwdev, netdev->dev_addr, 0,
+ hinic3_global_func_id(nic_dev->hwdev),
+ HINIC3_CHANNEL_NIC);
+ /* When this is VF driver, we must consider that PF has already set VF
+ * MAC, and we can't consider this condition is error status during
+ * driver probe procedure.
+ */
+ if (err && err != HINIC3_PF_SET_VF_ALREADY) {
+ nic_err(&nic_dev->pdev->dev, "Failed to set default MAC\n");
+ }
+
+ if (err == HINIC3_PF_SET_VF_ALREADY)
+ return 0;
+
+ return err;
+}
+
+static void hinic3_outband_cfg_init(struct hinic3_nic_dev *nic_dev)
+{
+ u16 outband_default_vid = 0;
+ int err = 0;
+
+ if (!nic_dev->nic_cap.outband_vlan_cfg_en)
+ return;
+
+ err = hinic3_get_outband_vlan_cfg(nic_dev->hwdev, &outband_default_vid);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev, "Failed to get_outband_cfg, err: %d\n", err);
+ return;
+ }
+
+ nic_dev->outband_cfg.outband_default_vid = outband_default_vid;
+
+ return;
}
static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
@@ -421,8 +525,6 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
nic_features &= NIC_DRV_DEFAULT_FEATURE;
hinic3_update_nic_feature(nic_dev->hwdev, nic_features);
- sema_init(&nic_dev->port_state_sem, 1);
-
err = hinic3_dcb_init(nic_dev);
if (err) {
nic_err(&nic_dev->pdev->dev, "Failed to init dcb\n");
@@ -434,47 +536,12 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
hinic3_try_to_enable_rss(nic_dev);
- err = hinic3_get_default_mac(nic_dev->hwdev, netdev->dev_addr);
+ err = hinic3_set_default_mac(nic_dev);
if (err) {
- nic_err(&nic_dev->pdev->dev, "Failed to get MAC address\n");
- goto get_mac_err;
- }
-
- if (!is_valid_ether_addr(netdev->dev_addr)) {
- if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- nic_err(&nic_dev->pdev->dev, "Invalid MAC address %pM\n",
- netdev->dev_addr);
- err = -EIO;
- goto err_mac;
- }
-
- nic_info(&nic_dev->pdev->dev, "Invalid MAC address %pM, using random\n",
- netdev->dev_addr);
- eth_hw_addr_random(netdev);
- }
-
- err = hinic3_set_mac(nic_dev->hwdev, netdev->dev_addr, 0,
- hinic3_global_func_id(nic_dev->hwdev),
- HINIC3_CHANNEL_NIC);
- /* When this is VF driver, we must consider that PF has already set VF
- * MAC, and we can't consider this condition is error status during
- * driver probe procedure.
- */
- if (err && err != HINIC3_PF_SET_VF_ALREADY) {
- nic_err(&nic_dev->pdev->dev, "Failed to set default MAC\n");
goto set_mac_err;
}
- /* MTU range: 384 - 9600 */
-#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
- netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
-
-#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
- netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
+ hinic3_netdev_mtu_init(netdev);
err = hinic3_alloc_txrxqs(nic_dev);
if (err) {
@@ -482,6 +549,8 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
goto alloc_qps_err;
}
+ hinic3_outband_cfg_init(nic_dev);
+
return 0;
alloc_qps_err:
@@ -490,8 +559,6 @@ alloc_qps_err:
HINIC3_CHANNEL_NIC);
set_mac_err:
-err_mac:
-get_mac_err:
hinic3_clear_rss_config(nic_dev);
return err;
@@ -690,20 +757,51 @@ static void hinic3_periodic_work_handler(struct work_struct *work)
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
}
+static void hinic3_vport_stats_work_handler(struct work_struct *work)
+{
+ int err;
+ struct hinic3_vport_stats vport_stats = {0};
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_nic_dev *nic_dev = container_of(delay, struct hinic3_nic_dev, vport_stats_work);
+ err = hinic3_get_vport_stats(nic_dev->hwdev, hinic3_global_func_id(nic_dev->hwdev), &vport_stats);
+ if (err)
+ nic_err(&nic_dev->pdev->dev, "Failed to get dropped stats from fw\n");
+ else
+ nic_dev->vport_stats.rx_discard_vport = vport_stats.rx_discard_vport;
+ queue_delayed_work(nic_dev->workq, &nic_dev->vport_stats_work, HZ);
+}
+
+static void free_nic_dev_vram(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)nic_dev->nic_vram, nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ else
+ kfree(nic_dev->nic_vram);
+ nic_dev->nic_vram = NULL;
+}
+
static void free_nic_dev(struct hinic3_nic_dev *nic_dev)
{
hinic3_deinit_nic_prof_adapter(nic_dev);
destroy_workqueue(nic_dev->workq);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+ free_nic_dev_vram(nic_dev);
}
static int setup_nic_dev(struct net_device *netdev,
struct hinic3_lld_dev *lld_dev)
{
struct pci_dev *pdev = lld_dev->pdev;
- struct hinic3_nic_dev *nic_dev;
- char *netdev_name_fmt;
+ struct hinic3_nic_dev *nic_dev = NULL;
+ char *netdev_name_fmt = NULL;
u32 page_num;
+ u16 func_id;
+ int ret;
+ int is_in_kexec = vram_get_kexec_flag();
+ int is_use_vram = get_use_vram_flag();
nic_dev = (struct hinic3_nic_dev *)netdev_priv(netdev);
nic_dev->netdev = netdev;
@@ -718,24 +816,65 @@ static int setup_nic_dev(struct net_device *netdev,
nic_dev->dma_rx_buff_size = RX_BUFF_NUM_PER_PAGE * nic_dev->rx_buff_len;
page_num = nic_dev->dma_rx_buff_size / PAGE_SIZE;
nic_dev->page_order = page_num > 0 ? ilog2(page_num) : 0;
+ nic_dev->page_pool_enabled = page_pool_enabled;
+ nic_dev->outband_cfg.outband_default_vid = 0;
+
+ // value other than 0 indicates hot replace
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ ret = snprintf(nic_dev->nic_vram_name,
+ VRAM_NAME_MAX_LEN,
+ "%s%u", VRAM_NIC_VRAM, func_id);
+ if (ret < 0) {
+ nic_err(&pdev->dev, "NIC vram name snprintf failed, ret:%d.\n",
+ ret);
+ return -EINVAL;
+ }
+
+ nic_dev->nic_vram = (struct hinic3_vram *)hi_vram_kalloc(nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+
+ if (is_in_kexec == 0)
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ else
+ netdev->mtu = nic_dev->nic_vram->vram_mtu;
+ } else {
+ nic_dev->nic_vram = kzalloc(sizeof(struct hinic3_vram),
+ GFP_KERNEL);
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ }
mutex_init(&nic_dev->nic_mutex);
nic_dev->vlan_bitmap = kzalloc(VLAN_BITMAP_SIZE(nic_dev), GFP_KERNEL);
if (!nic_dev->vlan_bitmap) {
nic_err(&pdev->dev, "Failed to allocate vlan bitmap\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto vlan_bitmap_error;
}
nic_dev->workq = create_singlethread_workqueue(HINIC3_NIC_DEV_WQ_NAME);
if (!nic_dev->workq) {
nic_err(&pdev->dev, "Failed to initialize nic workqueue\n");
- kfree(nic_dev->vlan_bitmap);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto create_workq_error;
}
- INIT_DELAYED_WORK(&nic_dev->periodic_work, hinic3_periodic_work_handler);
- INIT_DELAYED_WORK(&nic_dev->rxq_check_work, hinic3_rxq_check_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->periodic_work,
+ hinic3_periodic_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->rxq_check_work,
+ hinic3_rxq_check_work_handler);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ INIT_DELAYED_WORK(&nic_dev->vport_stats_work,
+ hinic3_vport_stats_work_handler);
INIT_LIST_HEAD(&nic_dev->uc_filter_list);
INIT_LIST_HEAD(&nic_dev->mc_filter_list);
@@ -748,10 +887,23 @@ static int setup_nic_dev(struct net_device *netdev,
hinic3_init_nic_prof_adapter(nic_dev);
netdev_name_fmt = hinic3_get_dft_netdev_name_fmt(nic_dev);
- if (netdev_name_fmt)
- strncpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (netdev_name_fmt) {
+ ret = strscpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (ret < 0)
+ goto get_netdev_name_error;
+ }
return 0;
+
+get_netdev_name_error:
+ hinic3_deinit_nic_prof_adapter(nic_dev);
+ destroy_workqueue(nic_dev->workq);
+create_workq_error:
+ kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+vlan_bitmap_error:
+ free_nic_dev_vram(nic_dev);
+ return ret;
}
static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
@@ -790,6 +942,32 @@ static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
return 0;
}
+static void hinic3_bond_init(struct hinic3_nic_dev *nic_dev)
+{
+ u32 bond_id = HINIC3_INVALID_BOND_ID;
+ int err = hinic3_create_bond(nic_dev->hwdev, &bond_id);
+ if (err != 0) {
+ goto bond_init_failed;
+ }
+
+ /* bond id does not change, means this pf is not bond active pf, no log is generated */
+ if (bond_id == HINIC3_INVALID_BOND_ID) {
+ return;
+ }
+
+ err = hinic3_open_close_bond(nic_dev->hwdev, true);
+ if (err != 0) {
+ hinic3_delete_bond(nic_dev->hwdev);
+ goto bond_init_failed;
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Bond %d init success\n", bond_id);
+ return;
+
+bond_init_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond init failed\n");
+}
+
static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
char *uld_dev_name)
{
@@ -820,6 +998,12 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
goto err_out;
}
+ err = hinic3_get_dev_cap(lld_dev->hwdev);
+ if (err != 0) {
+ nic_err(&pdev->dev, "Failed to get dev cap\n");
+ goto err_out;
+ }
+
max_qps = hinic3_func_max_nic_qnum(lld_dev->hwdev);
netdev = alloc_etherdev_mq(sizeof(*nic_dev), max_qps);
if (!netdev) {
@@ -851,23 +1035,35 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
hinic3_assign_netdev_ops(nic_dev);
netdev_feature_init(netdev);
-
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+ netdev->udp_tunnel_nic_info = &hinic3_udp_tunnels;
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
err = hinic3_set_default_hw_feature(nic_dev);
if (err)
goto set_features_err;
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0) {
+ hinic3_bond_init(nic_dev);
+ }
+
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
hinic3_register_notifier(nic_dev);
#endif
- err = register_netdev(netdev);
- if (err) {
- nic_err(&pdev->dev, "Failed to register netdev\n");
- err = -ENOMEM;
- goto netdev_err;
+ if (pdev->subsystem_device != BIFUR_RESOURCE_PF_SSID) {
+ err = register_netdev(netdev);
+ if (err) {
+ nic_err(&pdev->dev, "Failed to register netdev\n");
+ err = -ENOMEM;
+ goto netdev_err;
+ }
}
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->vport_stats_work, HZ);
+
netif_carrier_off(netdev);
*uld_dev = nic_dev;
@@ -900,6 +1096,27 @@ err_out:
return err;
}
+static void hinic3_bond_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ int ret = 0;
+
+ ret = hinic3_open_close_bond(nic_dev->hwdev, false);
+ if (ret != 0) {
+ goto bond_deinit_failed;
+ }
+
+ ret = hinic3_delete_bond(nic_dev->hwdev);
+ if (ret != 0) {
+ goto bond_deinit_failed;
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Bond deinit success\n");
+ return;
+
+bond_deinit_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond deinit failed\n");
+}
+
static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
{
struct hinic3_nic_dev *nic_dev = adapter;
@@ -912,11 +1129,16 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
netdev = nic_dev->netdev;
- unregister_netdev(netdev);
+ if (lld_dev->pdev->subsystem_device != BIFUR_RESOURCE_PF_SSID) {
+ unregister_netdev(netdev);
+ }
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
hinic3_unregister_notifier(nic_dev);
#endif
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ cancel_delayed_work_sync(&nic_dev->vport_stats_work);
+
cancel_delayed_work_sync(&nic_dev->periodic_work);
cancel_delayed_work_sync(&nic_dev->rxq_check_work);
cancel_work_sync(&nic_dev->rx_mode_work);
@@ -924,6 +1146,10 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_flush_rx_flow_rule(nic_dev);
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0) {
+ hinic3_bond_deinit(nic_dev);
+ }
+
hinic3_update_nic_feature(nic_dev->hwdev, 0);
hinic3_set_nic_feature_to_hw(nic_dev->hwdev);
@@ -933,6 +1159,7 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_deinit_nic_prof_adapter(nic_dev);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
free_netdev(netdev);
@@ -981,6 +1208,120 @@ static void hinic3_port_module_event_handler(struct hinic3_nic_dev *nic_dev,
}
}
+bool hinic3_need_proc_link_event(struct hinic3_lld_dev *lld_dev)
+{
+ int ret = 0;
+ u16 func_id;
+ u8 roce_enable = false;
+ bool is_slave_func = false;
+ struct hinic3_hw_bond_infos hw_bond_infos = {0};
+
+ if (!lld_dev)
+ return false;
+
+ /* 非slave设备需要处理link down事件 */
+ ret = hinic3_is_slave_func(lld_dev->hwdev, &is_slave_func);
+ if (ret != 0) {
+ nic_err(&lld_dev->pdev->dev, "NIC get info, lld_dev is null\n");
+ return true;
+ }
+
+ if (!is_slave_func)
+ return true;
+
+ /* 未使能了vroce功能,需处理link down事件 */
+ func_id = hinic3_global_func_id(lld_dev->hwdev);
+ ret = hinic3_get_func_vroce_enable(lld_dev->hwdev, func_id,
+ &roce_enable);
+ if (ret != 0)
+ return true;
+
+ if (!roce_enable)
+ return true;
+
+ /* 未创建bond,需要处理link down事件 */
+ hw_bond_infos.bond_id = HINIC_OVS_BOND_DEFAULT_ID;
+
+ ret = hinic3_get_hw_bond_infos(lld_dev->hwdev, &hw_bond_infos,
+ HINIC3_CHANNEL_COMM);
+ if (ret != 0) {
+ pr_err("[ROCE, ERR] Get chipf bond info failed (%d)\n", ret);
+ return true;
+ }
+
+ if (!hw_bond_infos.valid)
+ return true;
+
+ return false;
+}
+
+bool hinic3_need_proc_bond_event(struct hinic3_lld_dev *lld_dev)
+{
+ return !hinic3_need_proc_link_event(lld_dev);
+}
+
+static void hinic_porc_bond_state_change(struct hinic3_lld_dev *lld_dev,
+ void *adapter,
+ struct hinic3_event_info *event)
+{
+ struct hinic3_nic_dev *nic_dev = adapter;
+
+ if (!nic_dev || !event || !hinic3_support_nic(lld_dev->hwdev, NULL))
+ return;
+
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond down\n");
+ hinic3_link_status_change(nic_dev, false);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond up\n");
+ hinic3_link_status_change(nic_dev, true);
+ break;
+ default:
+ break;
+ }
+}
+
+static void hinic3_outband_cfg_event_handler(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_outband_cfg_info *info)
+{
+ int err = 0;
+ if (!nic_dev || !info || !hinic3_support_nic(nic_dev->hwdev, NULL)) {
+ pr_err("Outband cfg event invalid param\n");
+ return;
+ }
+
+ if (hinic3_func_type(nic_dev->hwdev) != TYPE_VF &&
+ info->func_id >= NIC_MAX_PF_NUM) {
+ err = hinic3_notify_vf_outband_cfg(nic_dev->hwdev,
+ info->func_id,
+ info->outband_default_vid);
+ if (err)
+ nic_err(&nic_dev->pdev->dev, "Outband cfg event notify vf err: %d,"
+ "func_id: 0x%x, vid: 0x%x\n",
+ err, info->func_id, info->outband_default_vid);
+ return;
+ }
+
+ nic_info(&nic_dev->pdev->dev,
+ "Change outband default vid from %u to %u\n",
+ nic_dev->outband_cfg.outband_default_vid,
+ info->outband_default_vid);
+
+ nic_dev->outband_cfg.outband_default_vid = info->outband_default_vid;
+
+ return;
+}
+
static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
struct hinic3_event_info *event)
{
@@ -992,14 +1333,25 @@ static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_DOWN):
+ if (!hinic3_need_proc_link_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc link event\n");
+ return;
+ }
hinic3_link_status_change(nic_dev, false);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_UP):
hinic3_link_status_change(nic_dev, true);
break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ hinic_porc_bond_state_change(lld_dev, adapter, event);
+ break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_PORT_MODULE_EVENT):
hinic3_port_module_event_handler(nic_dev, event);
break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_OUTBAND_CFG):
+ hinic3_outband_cfg_event_handler(nic_dev, (void *)event->event_data);
+ break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_SRIOV_STATE_CHANGE):
sriov_state_change(nic_dev, (void *)event->event_data);
break;
@@ -1059,7 +1411,7 @@ struct hinic3_uld_info g_nic_uld_info = {
.resume = NULL,
.event = nic_event,
.ioctl = nic_ioctl,
-}; /*lint -e766*/
+};
struct hinic3_uld_info *get_nic_uld_info(void)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
index 774193a..4df82ff 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
@@ -4,11 +4,12 @@
#ifndef HINIC3_MT_H
#define HINIC3_MT_H
-#define HINIC3_DRV_NAME "hisdk3"
+#define HINIC3_DRV_NAME "hinic3"
#define HINIC3_CHIP_NAME "hinic"
/* Interrupt at most records, interrupt will be recorded in the FFM */
#define NICTOOL_CMD_TYPE (0x18)
+#define HINIC3_CARD_NAME_MAX_LEN (128)
struct api_cmd_rd {
u32 pf_id;
@@ -110,7 +111,8 @@ enum dbgtool_cmd {
DBGTOOL_CMD_NUM
};
-#define PF_MAX_SIZE (16)
+#define HINIC_PF_MAX_SIZE (16)
+#define HINIC_VF_MAX_SIZE (4096)
#define BUSINFO_LEN (32)
enum module_name {
@@ -132,7 +134,9 @@ enum module_name {
SEND_TO_MIGRATE_DRIVER,
SEND_TO_PPA_DRIVER,
SEND_TO_CUSTOM_DRIVER = SEND_TO_SRV_DRV_BASE + 11,
- SEND_TO_DRIVER_MAX = SEND_TO_SRV_DRV_BASE + 15, /* reserved */
+ SEND_TO_VSOCK_DRIVER = SEND_TO_SRV_DRV_BASE + 14,
+ SEND_TO_BIFUR_DRIVER,
+ SEND_TO_DRIVER_MAX = SEND_TO_SRV_DRV_BASE + 16, /* reserved */
};
enum driver_cmd_type {
@@ -159,7 +163,7 @@ enum driver_cmd_type {
GET_CHIP_FAULT_STATS,
NIC_RSVD1,
NIC_RSVD2,
- NIC_RSVD3,
+ GET_OS_HOT_REPLACE_INFO,
GET_CHIP_ID,
GET_SINGLE_CARD_INFO,
GET_FIRMWARE_ACTIVE_STATUS,
@@ -170,7 +174,7 @@ enum driver_cmd_type {
GET_LOOPBACK_MODE = 32,
SET_LOOPBACK_MODE,
SET_LINK_MODE,
- SET_PF_BW_LIMIT,
+ SET_TX_PF_BW_LIMIT,
GET_PF_BW_LIMIT,
ROCE_CMD,
GET_POLL_WEIGHT,
@@ -188,6 +192,7 @@ enum driver_cmd_type {
GET_NIC_STATS_STRING,
GET_NIC_STATS_INFO,
GET_PF_ID,
+ GET_MBOX_CNT,
NIC_RSVD4,
NIC_RSVD5,
DCB_QOS_INFO,
@@ -204,16 +209,26 @@ enum driver_cmd_type {
RSS_INDIR,
PORT_ID,
+ SET_RX_PF_BW_LIMIT = 0x43,
+
GET_FUNC_CAP = 0x50,
GET_XSFP_PRESENT = 0x51,
GET_XSFP_INFO = 0x52,
DEV_NAME_TEST = 0x53,
+ GET_XSFP_INFO_COMP_CMIS = 0x54,
GET_WIN_STAT = 0x60,
WIN_CSR_READ = 0x61,
WIN_CSR_WRITE = 0x62,
WIN_API_CMD_RD = 0x63,
+ GET_FUSION_Q = 0x64,
+
+ ROCE_CMD_BOND_HASH_TYPE_SET = 0xb2,
+
+ BIFUR_SET_ENABLE = 0xc0,
+ BIFUR_GET_ENABLE = 0xc1,
+
VM_COMPAT_TEST = 0xFF
};
@@ -229,7 +244,8 @@ enum sm_cmd_type {
SM_CTR_RD64,
SM_CTR_RD32_CLEAR,
SM_CTR_RD64_PAIR_CLEAR,
- SM_CTR_RD64_CLEAR
+ SM_CTR_RD64_CLEAR,
+ SM_CTR_RD16_CLEAR,
};
struct cqm_stats {
@@ -317,10 +333,22 @@ struct pf_info {
};
struct card_info {
- struct pf_info pf[PF_MAX_SIZE];
+ struct pf_info pf[HINIC_PF_MAX_SIZE];
u32 pf_num;
};
+struct func_mbox_cnt_info {
+ char bus_info[BUSINFO_LEN];
+ u64 send_cnt;
+ u64 ack_cnt;
+};
+
+struct card_mbox_cnt_info {
+ struct func_mbox_cnt_info func_info[HINIC_PF_MAX_SIZE +
+ HINIC_VF_MAX_SIZE];
+ u32 func_num;
+};
+
struct hinic3_nic_loop_mode {
u32 loop_mode;
u32 loop_ctrl;
@@ -661,6 +689,161 @@ struct get_card_bond_msg_s {
struct bond_all_msg_s all_msg[MAX_BONDING_CNT_PER_CARD];
};
+#define MAX_FUSION_Q_STATS_STR_LEN 16
+#define MAX_FUSION_Q_NUM 256
+struct queue_status_s {
+ pid_t tgid;
+ char status[MAX_FUSION_Q_STATS_STR_LEN];
+};
+struct fusion_q_status_s {
+ u16 queue_num;
+ struct queue_status_s queue[MAX_FUSION_Q_NUM];
+};
+
+struct fusion_q_tx_hw_page {
+ u64 phy_addr;
+ u64 *map_addr;
+};
+
+struct fusion_sq_info {
+ u16 q_id;
+ u16 pi;
+ u16 ci; /* sw_ci */
+ u16 fi; /* hw_ci */
+ u32 q_depth;
+ u16 pi_reverse;
+ u16 wqebb_size;
+ u8 priority;
+ u16 *ci_addr;
+ u64 cla_addr;
+ void *slq_handle;
+ struct fusion_q_tx_hw_page direct_wqe;
+ struct fusion_q_tx_hw_page doorbell;
+ u32 page_idx;
+ u32 glb_sq_id;
+};
+
+struct fusion_q_tx_wqe {
+ u32 data[4];
+};
+
+struct fusion_rq_info {
+ u16 q_id;
+ u16 delta;
+ u16 hw_pi;
+ u16 ci; /* sw_ci */
+ u16 sw_pi;
+ u16 wqebb_size;
+ u16 q_depth;
+ u16 buf_len;
+
+ void *slq_handle;
+ u64 ci_wqe_page_addr;
+ u64 ci_cla_tbl_addr;
+
+ u8 coalesc_timer_cfg;
+ u8 pending_limt;
+ u16 msix_idx;
+ u32 msix_vector;
+};
+
+struct fusion_q_rx_wqe {
+ u32 data[8];
+};
+
+struct fusion_q_rx_cqe {
+ union {
+ struct {
+ unsigned int checksum_err : 16;
+ unsigned int lro_num : 8;
+ unsigned int rsvd1 : 7;
+ unsigned int rx_done : 1;
+ } bs;
+ unsigned int value;
+ } dw0;
+
+ union {
+ struct {
+ unsigned int vlan : 16;
+ unsigned int length : 16;
+ } bs;
+ unsigned int value;
+ } dw1;
+
+ union {
+ struct {
+ unsigned int pkt_types : 12;
+ unsigned int rsvd : 4;
+ unsigned int udp_0 : 1;
+ unsigned int ipv6_ex_add : 1;
+ unsigned int loopback : 1;
+ unsigned int umbcast : 2;
+ unsigned int vlan_offload_en : 1;
+ unsigned int tag_num : 2;
+ unsigned int rss_type : 8;
+ } bs;
+ unsigned int value;
+ } dw2;
+
+ union {
+ struct {
+ unsigned int rss_hash_value;
+ } bs;
+ unsigned int value;
+ } dw3;
+
+ union {
+ struct {
+ unsigned int tx_ts_seq : 16;
+ unsigned int message_1588_offset : 8;
+ unsigned int message_1588_type : 4;
+ unsigned int rsvd : 1;
+ unsigned int if_rx_ts : 1;
+ unsigned int if_tx_ts : 1;
+ unsigned int if_1588 : 1;
+ } bs;
+ unsigned int value;
+ } dw4;
+
+ union {
+ struct {
+ unsigned int ts;
+ } bs;
+ unsigned int value;
+ } dw5;
+
+ union {
+ struct {
+ unsigned int lro_ts;
+ } bs;
+ unsigned int value;
+ } dw6;
+
+ union {
+ struct {
+ unsigned int rsvd0;
+ } bs;
+ unsigned int value;
+ } dw7; /* 16Bytes Align */
+};
+
+struct os_hot_repalce_func_info {
+ char card_name[HINIC3_CARD_NAME_MAX_LEN];
+ int bus_num;
+ int valid;
+ int bdf;
+ int partition;
+ int backup_pf;
+ int pf_idx;
+ int port_id;
+};
+
+#define ALL_CARD_PF_NUM 2048 /* 64 card * 32 pf */
+struct os_hot_replace_info {
+ struct os_hot_repalce_func_info func_infos[ALL_CARD_PF_NUM];
+ u32 func_cnt;
+};
+
int alloc_buff_in(void *hwdev, struct msg_module *nt_msg, u32 in_size, void **buf_in);
int alloc_buff_out(void *hwdev, struct msg_module *nt_msg, u32 out_size, void **buf_out);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
index 81e4030..7cd9e4d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
@@ -15,6 +15,9 @@
#include <linux/ip.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#ifdef HAVE_XDP_SUPPORT
#include <linux/bpf.h>
#endif
@@ -28,6 +31,10 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
+#include "nic_npu_cmd.h"
+
+#include "vram_common.h"
+
#define HINIC3_DEFAULT_RX_CSUM_OFFLOAD 0xFFF
#define HINIC3_LRO_DEFAULT_COAL_PKT_SIZE 32
@@ -47,8 +54,64 @@ static void hinic3_nic_set_rx_mode(struct net_device *netdev)
queue_work(nic_dev->workq, &nic_dev->rx_mode_work);
}
+static void hinic3_free_irq_vram(struct hinic3_nic_dev *nic_dev, struct hinic3_dyna_txrxq_params *in_q_params)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ struct hinic3_dyna_txrxq_params q_params = nic_dev->q_params;
+
+ if (q_params.irq_cfg == NULL)
+ return;
+
+ size = sizeof(struct hinic3_irq) * (q_params.num_qps);
+
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)q_params.irq_cfg, q_params.irq_cfg_vram_name, size);
+ q_params.irq_cfg = NULL;
+ } else {
+ kfree(in_q_params->irq_cfg);
+ in_q_params->irq_cfg = NULL;
+ }
+}
+
+static int hinic3_alloc_irq_vram(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_dyna_txrxq_params *q_params, bool is_up_eth)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ u16 func_id;
+
+ size = sizeof(struct hinic3_irq) * q_params->num_qps;
+
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(q_params->irq_cfg_vram_name,
+ VRAM_NAME_MAX_LEN, "%s%u",
+ VRAM_NIC_IRQ_VRAM, func_id);
+ q_params->irq_cfg = (struct hinic3_irq *)hi_vram_kalloc(
+ q_params->irq_cfg_vram_name, size);
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq vram alloc failed.\n");
+ return -ENOMEM;
+ }
+ /* in order to clear napi stored in vram, irq need to init when eth up */
+ if (is_up_eth) {
+ memset(q_params->irq_cfg, 0, size);
+ }
+ } else {
+ q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq alloc failed.\n");
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_txrxq_params *q_params)
+ struct hinic3_dyna_txrxq_params *q_params,
+ bool is_up_eth)
{
u32 size;
int err;
@@ -70,12 +133,9 @@ static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
goto alloc_rxqs_res_arr_err;
}
- size = sizeof(*q_params->irq_cfg) * q_params->num_qps;
- q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
- if (!q_params->irq_cfg) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to alloc irq resource array\n");
- err = -ENOMEM;
+ err = hinic3_alloc_irq_vram(nic_dev, q_params, is_up_eth);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc irq resource array\n");
goto alloc_irq_cfg_err;
}
@@ -102,8 +162,7 @@ alloc_rxqs_res_err:
q_params->txqs_res);
alloc_txqs_res_err:
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ hinic3_free_irq_vram(nic_dev, q_params);
alloc_irq_cfg_err:
kfree(q_params->rxqs_res);
@@ -119,13 +178,14 @@ alloc_rxqs_res_arr_err:
static void hinic3_free_txrxq_resources(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_txrxq_params *q_params)
{
+ int is_in_kexec = vram_get_kexec_flag();
hinic3_free_rxqs_res(nic_dev, q_params->num_qps, q_params->rq_depth,
q_params->rxqs_res);
hinic3_free_txqs_res(nic_dev, q_params->num_qps, q_params->sq_depth,
q_params->txqs_res);
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ if (is_in_kexec == 0)
+ hinic3_free_irq_vram(nic_dev, q_params);
kfree(q_params->rxqs_res);
q_params->rxqs_res = NULL;
@@ -161,6 +221,7 @@ static int hinic3_configure_txrxqs(struct hinic3_nic_dev *nic_dev,
static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos;
if (!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
@@ -171,12 +232,13 @@ static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
num_cos = hinic3_get_dev_user_cos_num(nic_dev);
hinic3_update_qp_cos_cfg(nic_dev, num_cos);
/* For now, we don't support to change num_cos */
- if (num_cos > nic_dev->cos_config_num_max ||
+ if (num_cos > dcb->cos_config_num_max ||
nic_dev->q_params.num_qps < num_cos) {
nicif_err(nic_dev, drv, netdev, "Invalid num_cos: %u or num_qps: %u, disable DCB\n",
num_cos, nic_dev->q_params.num_qps);
nic_dev->q_params.num_cos = 0;
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
/* if we can't enable rss or get enough num_qps,
* need to sync default configure to hw
*/
@@ -190,11 +252,14 @@ static int hinic3_configure(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
- err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
- if (err) {
- nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
- return err;
+ if (is_in_kexec == 0) {
+ err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
+ return err;
+ }
}
config_dcb_qps_map(nic_dev);
@@ -256,10 +321,11 @@ static void config_dcb_num_qps(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dyna_txrxq_params *q_params,
u16 max_qps)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos = q_params->num_cos;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (!num_cos || num_cos > nic_dev->cos_config_num_max || num_cos > max_qps)
+ if (!num_cos || num_cos > dcb->cos_config_num_max || num_cos > max_qps)
return; /* will disable DCB in config_dcb_qps_map() */
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
@@ -334,57 +400,10 @@ static void hinic3_destroy_num_qps(struct hinic3_nic_dev *nic_dev)
kfree(nic_dev->qps_irq_info);
}
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev)
-{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- err = hinic3_set_port_enable(nic_dev->hwdev, false, HINIC3_CHANNEL_NIC);
- if (!err)
- nic_dev->force_port_disable = true;
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
-{
- int err = 0;
-
- down(&nic_dev->port_state_sem);
-
- nic_dev->force_port_disable = false;
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
- HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- /* Do nothing when force disable
- * Port will disable when call force port disable
- * and should not enable port when in force mode
- */
- if (nic_dev->force_port_disable) {
- up(&nic_dev->port_state_sem);
- return 0;
- }
-
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
+ return hinic3_set_port_enable(nic_dev->hwdev, enable,
HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
}
static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
@@ -401,7 +420,8 @@ static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+ struct hinic3_dyna_txrxq_params *trxq_params,
+ bool is_up_eth)
{
int err;
@@ -416,7 +436,7 @@ static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
return err;
}
- err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params);
+ err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params, is_up_eth);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc txrxq resources\n");
hinic3_free_qps(nic_dev->hwdev, qp_params);
@@ -544,9 +564,53 @@ vport_enable_err:
return err;
}
+static int hinic3_flush_rq_and_check(struct hinic3_nic_dev *nic_dev,
+ u16 glb_func_id)
+{
+ struct hinic3_flush_rq *rq_flush_msg = NULL;
+ struct hinic3_cmd_buf *cmd_buf = NULL;
+ int out_buf_len = sizeof(struct hinic3_flush_rq);
+ u16 rq_id;
+ u64 out_param = 0;
+ int ret;
+
+ cmd_buf = hinic3_alloc_cmd_buf(nic_dev->hwdev);
+ if (!cmd_buf) {
+ nic_err(&nic_dev->pdev->dev, "Failed to allocate cmd buf\n");
+ return -ENOMEM;
+ }
+
+ cmd_buf->size = sizeof(struct hinic3_flush_rq);
+ rq_flush_msg = (struct hinic3_flush_rq *)cmd_buf->buf;
+ rq_flush_msg->dw.bs.func_id = glb_func_id;
+ for (rq_id = 0; rq_id < nic_dev->q_params.num_qps; rq_id++) {
+ rq_flush_msg->dw.bs.rq_id = rq_id;
+ hinic3_cpu_to_be32(rq_flush_msg, out_buf_len);
+ ret = hinic3_cmdq_direct_resp(nic_dev->hwdev, HINIC3_MOD_L2NIC,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ cmd_buf, &out_param, 0,
+ HINIC3_CHANNEL_NIC);
+ if (ret != 0 || out_param != 0) {
+ nic_err(&nic_dev->pdev->dev, "Failed to flush rq, ret:%d, func:%u, rq:%u\n",
+ ret, glb_func_id, rq_id);
+ goto err;
+ }
+ hinic3_be32_to_cpu(rq_flush_msg, out_buf_len);
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Func:%u rq_num:%u flush rq success\n",
+ glb_func_id, nic_dev->q_params.num_qps);
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return 0;
+err:
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return -1;
+}
+
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
{
u16 glb_func_id;
+ int is_in_kexec = vram_get_kexec_flag();
netif_carrier_off(nic_dev->netdev);
netif_tx_disable(nic_dev->netdev);
@@ -559,18 +623,21 @@ void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, 0);
- hinic3_maybe_set_port_state(nic_dev, false);
+ if (is_in_kexec != 0)
+ nicif_info(nic_dev, drv, nic_dev->netdev, "Skip changing mag status!\n");
+ else
+ hinic3_maybe_set_port_state(nic_dev, false);
glb_func_id = hinic3_global_func_id(nic_dev->hwdev);
hinic3_set_vport_enable(nic_dev->hwdev, glb_func_id, false,
HINIC3_CHANNEL_NIC);
hinic3_flush_txqs(nic_dev->netdev);
- /* After set vport disable 100ms,
- * no packets will be send to host
- * FPGA set 2000ms
- */
- msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+ if (is_in_kexec == 0) {
+ msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+ } else {
+ (void)hinic3_flush_rq_and_check(nic_dev, glb_func_id);
+ }
hinic3_flush_qps_res(nic_dev->hwdev);
}
}
@@ -583,11 +650,12 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_qp_params new_qp_params = {0};
struct hinic3_dyna_qp_params cur_qp_params = {0};
int err;
+ bool is_free_resources = false;
hinic3_config_num_qps(nic_dev, trxq_params);
err = hinic3_alloc_channel_resources(nic_dev, &new_qp_params,
- trxq_params);
+ trxq_params, false);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc channel resources\n");
@@ -599,10 +667,19 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
hinic3_close_channel(nic_dev, &cur_qp_params);
hinic3_free_channel_resources(nic_dev, &cur_qp_params,
&nic_dev->q_params);
+ is_free_resources = true;
}
if (nic_dev->num_qp_irq > trxq_params->num_qps)
hinic3_qp_irq_change(nic_dev, trxq_params->num_qps);
+
+ if (is_free_resources) {
+ err = hinic3_alloc_irq_vram(nic_dev, trxq_params, false);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Change chl alloc irq failed\n");
+ goto alloc_irq_err;
+ }
+ }
nic_dev->q_params = *trxq_params;
if (reopen_handler)
@@ -623,7 +700,7 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
vport_up_err:
hinic3_close_channel(nic_dev, &new_qp_params);
-
+alloc_irq_err:
open_channel_err:
hinic3_free_channel_resources(nic_dev, &new_qp_params, trxq_params);
@@ -654,7 +731,7 @@ int hinic3_open(struct net_device *netdev)
}
err = hinic3_alloc_channel_resources(nic_dev, &qp_params,
- &nic_dev->q_params);
+ &nic_dev->q_params, true);
if (err)
goto alloc_channel_res_err;
@@ -693,12 +770,31 @@ setup_qps_err:
return err;
}
+static void hinic3_delete_napi(struct hinic3_nic_dev *nic_dev)
+{
+ u16 q_id;
+ int is_in_kexec = vram_get_kexec_flag();
+ struct hinic3_irq *irq_cfg = NULL;
+
+ if (is_in_kexec == 0 || nic_dev->q_params.irq_cfg == NULL)
+ return;
+
+ for (q_id = 0; q_id < nic_dev->q_params.num_qps; q_id++) {
+ irq_cfg = &(nic_dev->q_params.irq_cfg[q_id]);
+ qp_del_napi(irq_cfg);
+ }
+
+ hinic3_free_irq_vram(nic_dev, &nic_dev->q_params);
+}
+
int hinic3_close(struct net_device *netdev)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic3_dyna_qp_params qp_params = {0};
if (!test_and_clear_bit(HINIC3_INTF_UP, &nic_dev->flags)) {
+ /* delete napi in os hotreplace rollback */
+ hinic3_delete_napi(nic_dev);
nicif_info(nic_dev, drv, netdev, "Netdev already close, do nothing\n");
return 0;
}
@@ -835,6 +931,7 @@ static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb
#define GET_DSCP_PRI_OFFSET 2
static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev, struct sk_buff *skb)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int dscp_cp;
if (skb->protocol == htons(ETH_P_IP))
@@ -842,8 +939,8 @@ static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev, struct sk_buff *skb
else if (skb->protocol == htons(ETH_P_IPV6))
dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
else
- return nic_dev->hw_dcb_cfg.default_cos;
- return nic_dev->hw_dcb_cfg.dscp2cos[dscp_cp];
+ return dcb->hw_dcb_cfg.default_cos;
+ return dcb->hw_dcb_cfg.dscp2cos[dscp_cp];
}
#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY)
@@ -869,6 +966,7 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif /* end of HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK */
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u16 txq;
u8 cos, qp_num;
@@ -889,18 +987,19 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (nic_dev->hw_dcb_cfg.trust == DCB_PCP) {
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP) {
if (skb->vlan_tci)
- cos = nic_dev->hw_dcb_cfg.pcp2cos[skb->vlan_tci >> VLAN_PRIO_SHIFT];
+ cos = dcb->hw_dcb_cfg.pcp2cos[skb->vlan_tci >>
+ VLAN_PRIO_SHIFT];
else
- cos = nic_dev->hw_dcb_cfg.default_cos;
+ cos = dcb->hw_dcb_cfg.default_cos;
} else {
cos = hinic3_get_dscp_up(nic_dev, skb);
}
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cos] ?
- txq % nic_dev->hw_dcb_cfg.cos_qp_num[cos] : 0;
- txq = nic_dev->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
+ qp_num = dcb->hw_dcb_cfg.cos_qp_num[cos] ?
+ txq % dcb->hw_dcb_cfg.cos_qp_num[cos] : 0;
+ txq = dcb->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
}
return txq;
@@ -978,7 +1077,7 @@ static struct net_device_stats *hinic3_get_stats(struct net_device *netdev)
stats->rx_packets = packets;
stats->rx_bytes = bytes;
stats->rx_errors = errors;
- stats->rx_dropped = dropped;
+ stats->rx_dropped = dropped + nic_dev->vport_stats.rx_discard_vport;
#ifndef HAVE_VOID_NDO_GET_STATS64
return stats;
@@ -1025,10 +1124,17 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
u32 mtu = (u32)new_mtu;
int err = 0;
-
+ int is_in_kexec = vram_get_kexec_flag();
#ifdef HAVE_XDP_SUPPORT
u32 xdp_max_mtu;
+#endif
+ if (is_in_kexec != 0) {
+ nicif_info(nic_dev, drv, netdev, "Hotreplace skip change mtu\n");
+ return err;
+ }
+
+#ifdef HAVE_XDP_SUPPORT
if (hinic3_is_xdp_enable(nic_dev)) {
xdp_max_mtu = hinic3_xdp_max_mtu(nic_dev);
if (mtu > xdp_max_mtu) {
@@ -1047,6 +1153,7 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
nicif_info(nic_dev, drv, nic_dev->netdev, "Change mtu from %u to %d\n",
netdev->mtu, new_mtu);
netdev->mtu = mtu;
+ nic_dev->nic_vram->vram_mtu = mtu;
}
return err;
@@ -1080,6 +1187,71 @@ static int hinic3_set_mac_addr(struct net_device *netdev, void *addr)
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+static int hinic3_udp_tunnel_port_config(struct net_device *netdev,
+ struct udp_tunnel_info *ti,
+ u8 action)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u16 func_id = hinic3_global_func_id(nic_dev->hwdev);
+ u16 dst_port;
+ int ret = 0;
+
+ switch (ti->type) {
+ case UDP_TUNNEL_TYPE_VXLAN:
+ dst_port = ntohs(ti->port);
+ ret = hinic3_vlxan_port_config(nic_dev->hwdev, func_id,
+ dst_port, action);
+ if (ret != 0) {
+ nicif_warn(nic_dev, drv, netdev,
+ "Failed to set vxlan port %u to device(%d)\n",
+ dst_port, ret);
+ break;
+ }
+ nicif_info(nic_dev, link, netdev, "Vxlan dst port set to %u\n",
+ action == HINIC3_CMD_OP_ADD ?
+ dst_port : ntohs(VXLAN_OFFLOAD_PORT_LE));
+ break;
+ default:
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to add port, only vxlan dst port is supported\n");
+ ret = -EINVAL;
+ }
+ return ret;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+static void hinic3_udp_tunnel_add(struct net_device *netdev, struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+static void hinic3_udp_tunnel_del(struct net_device *netdev, struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD */
+
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev, __attribute__((unused)) unsigned int table,
+ __attribute__((unused))unsigned int entry, struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev, __attribute__((unused)) unsigned int table,
+ __attribute__((unused)) unsigned int entry, struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static int
hinic3_vlan_rx_add_vid(struct net_device *netdev,
__always_unused __be16 proto,
@@ -1126,7 +1298,7 @@ hinic3_vlan_rx_kill_vid(struct net_device *netdev,
int err = 0;
col = VID_COL(nic_dev, vid);
- line = VID_LINE(nic_dev, vid);
+ line = (int)VID_LINE(nic_dev, vid);
/* In the broadcast scenario, ucode finds the corresponding function
* based on VLAN 0 of vlan table. If we delete VLAN 0, the VLAN function
@@ -1165,14 +1337,12 @@ static int hinic3_vlan_restore(struct net_device *netdev)
return -EFAULT;
rcu_read_lock();
for (i = 0; i < VLAN_N_VID; i++) {
-/* lint -e778 */
#ifdef HAVE_VLAN_FIND_DEV_DEEP_RCU
vlandev =
__vlan_find_dev_deep_rcu(netdev, htons(ETH_P_8021Q), i);
#else
vlandev = __vlan_find_dev_deep(netdev, htons(ETH_P_8021Q), i);
#endif
-/* lint +e778 */
col = VID_COL(nic_dev, i);
line = VID_LINE(nic_dev, i);
if (!vlandev && (vlan_bitmap[line] & (1UL << col)) != 0) {
@@ -1330,12 +1500,17 @@ static int set_feature_vlan_filter(struct hinic3_nic_dev *nic_dev,
return 0;
#ifdef NEED_VLAN_RESTORE
- if (en)
+ if (en) {
err = hinic3_vlan_restore(nic_dev->netdev);
+ if (err) {
+ hinic3_err(nic_dev, drv, "vlan restore failed\n");
+ *failed_features |= vlan_filter_feature;
+ return err;
+ }
+ }
#endif
- if (err == 0)
- err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
+ err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
if (err) {
hinic3_err(nic_dev, drv, "%s rx vlan filter failed\n",
SET_FEATURES_OP_STR(en));
@@ -1429,8 +1604,8 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
struct hinic3_nic_dev *adapter = netdev_priv(netdev);
int err;
- if (is_multicast_ether_addr(mac) || /*lint !e574*/
- vf >= pci_num_vf(adapter->pdev)) /*lint !e574*/
+ if (is_multicast_ether_addr(mac) ||
+ vf >= pci_num_vf(adapter->pdev))
return -EINVAL;
err = hinic3_set_vf_mac(adapter->hwdev, OS_VF_ID_TO_HW(vf), mac);
@@ -1448,7 +1623,6 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
return 0;
}
-/*lint -save -e574 -e734*/
#ifdef IFLA_VF_MAX
static int set_hw_vf_vlan(void *hwdev, u16 cur_vlanprio, int vf,
u16 vlan, u8 qos)
@@ -1670,7 +1844,7 @@ static int hinic3_ndo_set_vf_bw(struct net_device *netdev, int vf,
return -EIO;
/* rate limit cannot be less than 0 and greater than link speed */
- if (max_tx_rate < 0 || max_tx_rate > speeds[port_info.speed]) {
+ if (max_tx_rate < 0 || max_tx_rate > (int)(speeds[port_info.speed])) {
nicif_err(adapter, drv, netdev, "Set vf max tx rate must be in [0 - %u]\n",
speeds[port_info.speed]);
return -EINVAL;
@@ -1719,7 +1893,7 @@ static int hinic3_xdp_setup(struct hinic3_nic_dev *nic_dev,
int max_mtu = hinic3_xdp_max_mtu(nic_dev);
int q_id;
- if (nic_dev->netdev->mtu > max_mtu) {
+ if (nic_dev->netdev->mtu > (u32)max_mtu) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to setup xdp program, the current MTU %d is larger than max allowed MTU %d\n",
nic_dev->netdev->mtu, max_mtu);
@@ -1844,6 +2018,10 @@ static const struct net_device_ops hinic3_netdev_ops = {
.ndo_xdp = hinic3_xdp,
#endif
#endif
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+ .ndo_udp_tunnel_add = hinic3_udp_tunnel_add,
+ .ndo_udp_tunnel_del = hinic3_udp_tunnel_del,
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD */
#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT
};
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
index cc00bdc..1bc6a14 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
@@ -10,6 +10,8 @@
#include "hinic3_common.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
/* ************************ array index define ********************* */
#define ARRAY_INDEX_0 0
@@ -21,6 +23,35 @@
#define ARRAY_INDEX_6 6
#define ARRAY_INDEX_7 7
+#define XSFP_TLV_PRE_INFO_LEN 4
+
+enum hinic3_link_port_type {
+ LINK_PORT_UNKNOWN,
+ LINK_PORT_OPTICAL_MM,
+ LINK_PORT_OPTICAL_SM,
+ LINK_PORT_PAS_COPPER,
+ LINK_PORT_ACC,
+ LINK_PORT_BASET,
+ LINK_PORT_AOC = 0x40,
+ LINK_PORT_ELECTRIC,
+ LINK_PORT_BACKBOARD_INTERFACE,
+};
+
+enum hilink_fibre_subtype {
+ FIBRE_SUBTYPE_SR = 1,
+ FIBRE_SUBTYPE_LR,
+ FIBRE_SUBTYPE_MAX,
+};
+
+enum hilink_fec_type {
+ HILINK_FEC_NOT_SET,
+ HILINK_FEC_RSFEC,
+ HILINK_FEC_BASEFEC,
+ HILINK_FEC_NOFEC,
+ HILINK_FEC_LLRSFE,
+ HILINK_FEC_MAX_TYPE,
+};
+
struct hinic3_sq_attr {
u8 dma_attr_off;
u8 pending_limit;
@@ -58,24 +89,32 @@ struct hinic3_port_routine_cmd {
struct mag_cmd_get_xsfp_present abs;
};
+struct hinic3_port_routine_cmd_extern {
+ bool mpu_send_xsfp_tlv_info;
+
+ struct drv_mag_cmd_get_xsfp_tlv_rsp std_xsfp_tlv_info;
+};
+
struct hinic3_nic_cfg {
- struct semaphore cfg_lock;
+ struct semaphore cfg_lock;
/* Valid when pfc is disable */
- bool pause_set;
- struct nic_pause_config nic_pause;
+ bool pause_set;
+ struct nic_pause_config nic_pause;
- u8 pfc_en;
- u8 pfc_bitmap;
+ u8 pfc_en;
+ u8 pfc_bitmap;
- struct nic_port_info port_info;
+ struct nic_port_info port_info;
/* percentage of pf link bandwidth */
- u32 pf_bw_limit;
- u32 rsvd2;
+ u32 pf_bw_tx_limit;
+ u32 pf_bw_rx_limit;
- struct hinic3_port_routine_cmd rt_cmd;
- struct mutex sfp_mutex; /* mutex used for copy sfp info */
+ struct hinic3_port_routine_cmd rt_cmd;
+ struct hinic3_port_routine_cmd_extern rt_cmd_ext;
+ /* mutex used for copy sfp info */
+ struct mutex sfp_mutex;
};
struct hinic3_nic_io {
@@ -84,7 +123,7 @@ struct hinic3_nic_io {
void *dev_hdl;
u8 link_status;
- u8 rsvd1;
+ u8 direct;
u32 rsvd2;
struct hinic3_io_queue *sq;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
index 2c1b565..525a353 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
@@ -20,10 +20,126 @@
#include "hinic3_nic_io.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_common.h"
#include "hinic3_nic_cfg.h"
+#include "vram_common.h"
+
+int hinic3_delete_bond(void *hwdev)
+{
+ struct hinic3_cmd_delete_bond cmd_delete_bond;
+ u16 out_size = sizeof(cmd_delete_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_delete_bond, 0, sizeof(cmd_delete_bond));
+ cmd_delete_bond.bond_id = HINIC3_INVALID_BOND_ID;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_DELETE,
+ &cmd_delete_bond, sizeof(cmd_delete_bond),
+ &cmd_delete_bond, &out_size);
+ if (err || !out_size || cmd_delete_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to delete bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_delete_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_delete_bond.bond_id != HINIC3_INVALID_BOND_ID) {
+ nic_info(nic_io->dev_hdl, "Delete bond success\n");
+ }
+
+ return 0;
+}
+
+int hinic3_open_close_bond(void *hwdev, u32 bond_en)
+{
+ struct hinic3_cmd_open_close_bond cmd_open_close_bond;
+ u16 out_size = sizeof(cmd_open_close_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_open_close_bond, 0, sizeof(cmd_open_close_bond));
+ cmd_open_close_bond.open_close_bond_info.bond_id = HINIC3_INVALID_BOND_ID;
+ cmd_open_close_bond.open_close_bond_info.open_close_flag = bond_en;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_OPEN_CLOSE,
+ &cmd_open_close_bond, sizeof(cmd_open_close_bond),
+ &cmd_open_close_bond, &out_size);
+ if (err || !out_size || cmd_open_close_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to %s bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ bond_en == true ? "open" : "close", err, cmd_open_close_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_open_close_bond.open_close_bond_info.bond_id != HINIC3_INVALID_BOND_ID) {
+ nic_info(nic_io->dev_hdl, "%s bond success\n", bond_en == true ? "Open" : "Close");
+ }
+
+ return 0;
+}
+
+int hinic3_create_bond(void *hwdev, u32 *bond_id)
+{
+ struct hinic3_cmd_create_bond cmd_create_bond;
+ u16 out_size = sizeof(cmd_create_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_create_bond, 0, sizeof(cmd_create_bond));
+ cmd_create_bond.create_bond_info.default_param_flag = true;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_CREATE,
+ &cmd_create_bond, sizeof(cmd_create_bond),
+ &cmd_create_bond, &out_size);
+ if (err || !out_size || cmd_create_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to create default bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_create_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_create_bond.create_bond_info.bond_id != HINIC3_INVALID_BOND_ID) {
+ *bond_id = cmd_create_bond.create_bond_info.bond_id;
+ nic_info(nic_io->dev_hdl, "Create bond success\n");
+ }
+
+ return 0;
+}
+
int hinic3_set_ci_table(void *hwdev, struct hinic3_sq_attr *attr)
{
struct hinic3_cmd_cons_idx_attr cons_idx_attr;
@@ -37,6 +153,8 @@ int hinic3_set_ci_table(void *hwdev, struct hinic3_sq_attr *attr)
memset(&cons_idx_attr, 0, sizeof(cons_idx_attr));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cons_idx_attr.func_idx = hinic3_global_func_id(hwdev);
@@ -152,6 +270,8 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -183,7 +303,7 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
}
EXPORT_SYMBOL(hinic3_del_mac);
-int hinic3_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
+int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
u16 func_id)
{
struct hinic3_port_mac_update mac_info;
@@ -197,6 +317,8 @@ int hinic3_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -247,6 +369,8 @@ int hinic3_get_default_mac(void *hwdev, u8 *mac_addr)
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
mac_info.func_id = hinic3_global_func_id(hwdev);
@@ -292,6 +416,45 @@ static int hinic3_config_vlan(struct hinic3_nic_io *nic_io, u8 opcode,
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action)
+{
+ struct hinic3_cmd_vxlan_port_info vxlan_port_info;
+ u16 out_size = sizeof(vxlan_port_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ memset(&vxlan_port_info, 0, sizeof(vxlan_port_info));
+ vxlan_port_info.opcode = action;
+ vxlan_port_info.cfg_mode = 0; // other ethtool set
+ vxlan_port_info.func_id = func_id;
+ vxlan_port_info.vxlan_port = port;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+ &vxlan_port_info, sizeof(vxlan_port_info),
+ &vxlan_port_info, &out_size);
+ if (err || !out_size || vxlan_port_info.msg_head.status) {
+ if (vxlan_port_info.msg_head.status == 0x2) {
+ nic_warn(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port because it has already been set by hinicadm\n",
+ action == HINIC3_CMD_OP_ADD ? "add" : "delete");
+ } else {
+ nic_err(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port, err: %d, status: 0x%x, out size: 0x%x\n",
+ action == HINIC3_CMD_OP_ADD ? "add" : "delete",
+ err, vxlan_port_info.msg_head.status, out_size);
+ }
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
{
struct hinic3_nic_io *nic_io = NULL;
@@ -300,6 +463,9 @@ int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan_id, func_id);
}
@@ -311,6 +477,9 @@ int hinic3_del_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_DEL, vlan_id, func_id);
}
@@ -354,6 +523,9 @@ int hinic3_set_dcb_state(void *hwdev, struct hinic3_dcb_state *dcb_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (!memcmp(&nic_io->dcb_state, dcb_state, sizeof(nic_io->dcb_state)))
return 0;
@@ -515,6 +687,8 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_cfg = &nic_io->nic_cfg;
@@ -540,7 +714,6 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
{
- struct hinic3_nic_cfg *nic_cfg = NULL;
struct hinic3_nic_io *nic_io = NULL;
int err = 0;
@@ -548,17 +721,13 @@ int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- nic_cfg = &nic_io->nic_cfg;
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_hw_pause(nic_io, HINIC3_CMD_OP_GET, nic_pause);
if (err)
return err;
- if (nic_cfg->pause_set || !nic_pause->auto_neg) {
- nic_pause->rx_pause = nic_cfg->nic_pause.rx_pause;
- nic_pause->tx_pause = nic_cfg->nic_pause.tx_pause;
- }
-
return 0;
}
@@ -573,6 +742,8 @@ int hinic3_sync_dcb_state(void *hwdev, u8 op_code, u8 state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&dcb_state, 0, sizeof(dcb_state));
@@ -659,44 +830,6 @@ int hinic3_cache_out_qps_res(void *hwdev)
return 0;
}
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats)
-{
- struct hinic3_port_stats *port_stats = NULL;
- struct hinic3_port_stats_info stats_info;
- u16 out_size = sizeof(*port_stats);
- struct hinic3_nic_io *nic_io = NULL;
- int err;
-
- port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
- if (!port_stats)
- return -ENOMEM;
-
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
-
- memset(&stats_info, 0, sizeof(stats_info));
-
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_PORT_STAT,
- &stats_info, sizeof(stats_info),
- port_stats, &out_size);
- if (err || !out_size || port_stats->msg_head.status) {
- nic_err(nic_io->dev_hdl,
- "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
- err, port_stats->msg_head.status, out_size);
- err = -EIO;
- goto out;
- }
-
- memcpy(stats, &port_stats->stats, sizeof(*stats));
-
-out:
- kfree(port_stats);
-
- return err;
-}
-EXPORT_SYMBOL(hinic3_get_fpga_phy_port_stats);
-
int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *stats)
{
struct hinic3_port_stats_info stats_info;
@@ -712,6 +845,8 @@ int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *
memset(&vport_stats, 0, sizeof(vport_stats));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
stats_info.func_id = func_id;
@@ -778,6 +913,8 @@ int hinic3_set_port_mtu(void *hwdev, u16 new_mtu)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (new_mtu < HINIC3_MIN_MTU_SIZE) {
nic_err(nic_io->dev_hdl,
@@ -808,6 +945,9 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&feature_nego, 0, sizeof(feature_nego));
feature_nego.func_id = hinic3_global_func_id(hwdev);
feature_nego.opcode = opcode;
@@ -829,29 +969,21 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return 0;
}
-static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
+static int hinic3_get_bios_pf_bw_tx_limit(void *hwdev, struct hinic3_nic_io *nic_io, u16 func_id, u32 *pf_rate)
{
- struct hinic3_nic_io *nic_io = NULL;
+ int err = 0; // default success
struct nic_cmd_bios_cfg cfg = {{0}};
u16 out_size = sizeof(cfg);
- int err;
- if (!hwdev || !pf_bw_limit)
- return -EINVAL;
-
- if (hinic3_func_type(hwdev) == TYPE_VF || !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
- return 0;
-
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- cfg.bios_cfg.func_id = (u8)hinic3_global_func_id(hwdev);
+ cfg.bios_cfg.func_id = (u8)func_id;
cfg.bios_cfg.func_valid = 1;
- cfg.op_code = 0 | NIC_NVM_DATA_PF_SPEED_LIMIT;
+ cfg.op_code = 0 | NIC_NVM_DATA_PF_TX_SPEED_LIMIT;
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BIOS_CFG, &cfg, sizeof(cfg),
&cfg, &out_size);
if (err || !out_size || cfg.head.status) {
nic_err(nic_io->dev_hdl,
- "Failed to get bios pf bandwidth limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ "Failed to get bios pf bandwidth tx limit, err: %d, status: 0x%x, out size: 0x%x\n",
err, cfg.head.status, out_size);
return -EIO;
}
@@ -861,13 +993,77 @@ static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
nic_warn(nic_io->dev_hdl, "Invalid bios configuration data, signature: 0x%x\n",
cfg.bios_cfg.signature);
- if (cfg.bios_cfg.pf_bw > MAX_LIMIT_BW) {
+ if (cfg.bios_cfg.pf_tx_bw > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
+ cfg.bios_cfg.pf_tx_bw);
+ return -EINVAL;
+ }
+
+ (*pf_rate) = cfg.bios_cfg.pf_tx_bw;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_rx_limit(void *hwdev, struct hinic3_nic_io *nic_io, u16 func_id, u32 *pf_rate)
+{
+ int err = 0; // default success
+ struct nic_rx_rate_bios_cfg rx_bios_conf = {{0}};
+ u16 out_size = sizeof(rx_bios_conf);
+
+ rx_bios_conf.func_id = (u8)func_id;
+ rx_bios_conf.op_code = 0; /* 1-save, 0-read */
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_RX_RATE_CFG, &rx_bios_conf, sizeof(rx_bios_conf),
+ &rx_bios_conf, &out_size);
+ if (rx_bios_conf.msg_head.status == HINIC3_MGMT_CMD_UNSUPPORTED && err == 0) { // Compatible older firmware
+ nic_warn(nic_io->dev_hdl, "Not support get bios pf bandwidth rx limit\n");
+ return 0;
+ } else if (err || !out_size || rx_bios_conf.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get bios pf bandwidth rx limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, rx_bios_conf.msg_head.status, out_size);
+ return -EIO;
+ }
+ if (rx_bios_conf.rx_rate_limit > MAX_LIMIT_BW) {
nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
- cfg.bios_cfg.pf_bw);
+ rx_bios_conf.rx_rate_limit);
return -EINVAL;
}
- *pf_bw_limit = cfg.bios_cfg.pf_bw;
+ (*pf_rate) = rx_bios_conf.rx_rate_limit;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit, u8 direct)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u32 pf_rate = 0;
+ int err = 0;
+ u16 func_id;
+ func_id = hinic3_global_func_id(hwdev);
+
+ if (!hwdev || !pf_bw_limit)
+ return -EINVAL;
+
+ if (hinic3_func_type(hwdev) == TYPE_VF || !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
+ return 0;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (direct == HINIC3_NIC_TX) {
+ err = hinic3_get_bios_pf_bw_tx_limit(hwdev, nic_io, func_id, &pf_rate);
+ } else if (direct == HINIC3_NIC_RX) {
+ err = hinic3_get_bios_pf_bw_rx_limit(hwdev, nic_io, func_id, &pf_rate);
+ }
+
+ if (err != 0)
+ return err;
+
+ if (pf_rate > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n", pf_rate);
+ return -EINVAL;
+ }
+ *pf_bw_limit = pf_rate;
return 0;
}
@@ -876,8 +1072,9 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
{
struct hinic3_cmd_tx_rate_cfg rate_cfg = {{0}};
struct hinic3_nic_io *nic_io = NULL;
+ u32 rate_limit;
u16 out_size = sizeof(rate_cfg);
- u32 pf_rate;
+ u32 pf_rate = 0;
int err;
u32 speed_convert[PORT_SPEED_UNKNOWN] = {
0, 10, 100, 1000, 10000, 25000, 40000, 50000, 100000, 200000
@@ -892,19 +1089,21 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
return -EINVAL;
}
- if (nic_io->nic_cfg.pf_bw_limit == MAX_LIMIT_BW) {
- pf_rate = 0;
- } else {
+ rate_limit = (nic_io->direct == HINIC3_NIC_TX) ?
+ nic_io->nic_cfg.pf_bw_tx_limit : nic_io->nic_cfg.pf_bw_rx_limit;
+
+ if (rate_limit != MAX_LIMIT_BW) {
/* divided by 100 to convert to percentage */
- pf_rate = (speed_convert[speed_level] / 100) * nic_io->nic_cfg.pf_bw_limit;
+ pf_rate = (speed_convert[speed_level] / 100) * rate_limit;
/* bandwidth limit is very small but not unlimit in this case */
- if (pf_rate == 0 && speed_level != PORT_SPEED_NOT_SET)
+ if ((pf_rate == 0) && (speed_level != PORT_SPEED_NOT_SET))
pf_rate = 1;
}
rate_cfg.func_id = hinic3_global_func_id(hwdev);
rate_cfg.min_rate = 0;
rate_cfg.max_rate = pf_rate;
+ rate_cfg.direct = nic_io->direct;
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_MAX_MIN_RATE, &rate_cfg,
sizeof(rate_cfg), &rate_cfg, &out_size);
@@ -927,6 +1126,8 @@ int hinic3_set_nic_feature_to_hw(void *hwdev)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return nic_feature_nego(hwdev, HINIC3_CMD_OP_SET, &nic_io->feature_cap, 1);
}
@@ -936,6 +1137,8 @@ u64 hinic3_get_feature_cap(void *hwdev)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
return nic_io->feature_cap;
}
@@ -945,6 +1148,9 @@ void hinic3_update_nic_feature(void *hwdev, u64 s_feature)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
+
nic_io->feature_cap = s_feature;
nic_info(nic_io->dev_hdl, "Update nic feature to 0x%llx\n", nic_io->feature_cap);
@@ -978,6 +1184,7 @@ static int hinic3_init_nic_io(void *hwdev, void *pcidev_hdl, void *dev_hdl,
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_abs = false;
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_info = false;
+ (*nic_io)->nic_cfg.rt_cmd_ext.mpu_send_xsfp_tlv_info = false;
return 0;
}
@@ -994,11 +1201,14 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
{
struct hinic3_nic_io *nic_io = NULL;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
err = hinic3_init_nic_io(hwdev, pcidev_hdl, dev_hdl, &nic_io);
if (err)
return err;
+ nic_io->rx_buff_len = rx_buff_len;
+
err = hinic3_register_service_adapter(hwdev, nic_io, SERVICE_T_NIC);
if (err) {
nic_err(nic_io->dev_hdl, "Failed to register service adapter\n");
@@ -1011,10 +1221,12 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
goto set_used_state_err;
}
- err = hinic3_init_function_table(nic_io);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to init function table\n");
- goto err_out;
+ if (is_in_kexec == 0) {
+ err = hinic3_init_function_table(nic_io);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to init function table\n");
+ goto err_out;
+ }
}
err = hinic3_get_nic_feature_from_hw(hwdev, &nic_io->feature_cap, 1);
@@ -1025,9 +1237,19 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
sdk_info(dev_hdl, "nic features: 0x%llx\n", nic_io->feature_cap);
- err = hinic3_get_bios_pf_bw_limit(hwdev, &nic_io->nic_cfg.pf_bw_limit);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to get pf bandwidth limit\n");
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_tx_limit,
+ HINIC3_NIC_TX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf tx bandwidth limit\n");
+ goto err_out;
+ }
+
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_rx_limit,
+ HINIC3_NIC_RX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf rx bandwidth limit\n");
goto err_out;
}
@@ -1037,12 +1259,13 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
goto err_out;
}
- nic_io->rx_buff_len = rx_buff_len;
-
return 0;
err_out:
- hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 0, HINIC3_CHANNEL_NIC);
+ if (hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 0,
+ HINIC3_CHANNEL_NIC) != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to set function svc used state\n");
+ }
set_used_state_err:
hinic3_unregister_service_adapter(hwdev, SERVICE_T_NIC);
@@ -1092,6 +1315,8 @@ int hinic3_force_drop_tx_pkt(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&pkt_drop, 0, sizeof(pkt_drop));
pkt_drop.port = hinic3_physical_port_id(hwdev);
@@ -1120,6 +1345,8 @@ int hinic3_set_rx_mode(void *hwdev, u32 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&rx_mode_cfg, 0, sizeof(rx_mode_cfg));
rx_mode_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1148,6 +1375,8 @@ int hinic3_set_rx_vlan_offload(void *hwdev, u8 en)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_cfg, 0, sizeof(vlan_cfg));
vlan_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1176,6 +1405,9 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
if (!nic_io->vf_infos || is_zero_ether_addr(vf_info->drv_mac_addr))
return 0;
@@ -1215,6 +1447,8 @@ static int hinic3_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en,
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_cfg, 0, sizeof(lro_cfg));
lro_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1246,6 +1480,8 @@ static int hinic3_set_rx_lro_timer(void *hwdev, u32 timer_value)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_timer, 0, sizeof(lro_timer));
lro_timer.opcode = HINIC3_CMD_OP_SET;
@@ -1278,6 +1514,8 @@ int hinic3_set_rx_lro_state(void *hwdev, u8 lro_en, u32 lro_timer,
ipv6_en = lro_en ? 1 : 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_info(nic_io->dev_hdl, "Set LRO max coalesce packet size to %uK\n",
lro_max_pkt_len);
@@ -1306,6 +1544,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_filter, 0, sizeof(vlan_filter));
vlan_filter.func_id = hinic3_global_func_id(hwdev);
@@ -1325,7 +1565,6 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
{
- // struct hinic_hwdev *dev = hwdev;
struct nic_cmd_capture_info cap_info = {{0}};
u16 out_size = sizeof(cap_info);
int err;
@@ -1334,7 +1573,6 @@ int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
return -EINVAL;
/* 2 function capture types */
- // cap_info.op_type = UP_UCAPTURE_OP_TYPE_FUNC;
cap_info.is_en_trx = cap_en;
cap_info.func_port = func_id;
@@ -1359,6 +1597,8 @@ int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (tcam_rule->index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to add is invalid\n");
return -EINVAL;
@@ -1394,6 +1634,8 @@ int hinic3_del_tcam_rule(void *hwdev, u32 index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to del is invalid\n");
return -EINVAL;
@@ -1443,6 +1685,8 @@ static int hinic3_mgmt_tcam_block(void *hwdev, u8 alloc_en, u16 *index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&tcam_block_info, 0,
sizeof(struct nic_cmd_ctrl_tcam_block_out));
@@ -1488,6 +1732,8 @@ int hinic3_set_fdir_tcam_rule_filter(void *hwdev, bool enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
port_tcam_cmd.func_id = hinic3_global_func_id(hwdev);
port_tcam_cmd.tcam_enable = (u8)enable;
@@ -1516,6 +1762,9 @@ int hinic3_flush_tcam_rule(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&tcam_flush, 0, sizeof(struct nic_cmd_flush_tcam_rules));
tcam_flush.func_id = hinic3_global_func_id(hwdev);
@@ -1546,6 +1795,9 @@ int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -1588,8 +1840,10 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return -EINVAL;
}
- if (hinic3_func_type(hwdev) == TYPE_VF)
+ if (hinic3_func_type(hwdev) == TYPE_VF) {
+ pr_err("VF are not supported to set link state.\n");
return -EINVAL;
+ }
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
if (!nic_io) {
@@ -1606,3 +1860,35 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return 0;
}
EXPORT_SYMBOL(hinic3_pf_set_vf_link_state);
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid)
+{
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ u16 out_size = sizeof(outband_cfg_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !outband_default_vid)
+ return -EINVAL;
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_OUTBAND_CFG,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size);
+ if (err || !out_size || outband_cfg_info.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get outband cfg, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, outband_cfg_info.msg_head.status, out_size);
+ return -EINVAL;
+ }
+
+ *outband_default_vid = outband_cfg_info.outband_default_vid;
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
index ee0587c..0fe7b9f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
@@ -7,9 +7,9 @@
#include <linux/types.h>
#include <linux/netdevice.h>
-#include "hinic3_mgmt_interface.h"
+#include "nic_mpu_cmd_defs.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#define OS_VF_ID_TO_HW(os_vf_id) ((os_vf_id) + 1)
#define HW_VF_ID_TO_OS(hw_vf_id) ((hw_vf_id) - 1)
@@ -54,6 +54,8 @@
#define MAX_LIMIT_BW 100
+#define HINIC3_INVALID_BOND_ID 0xffffffff
+
enum hinic3_valid_link_settings {
HILINK_LINK_SET_SPEED = 0x1,
HILINK_LINK_SET_AUTONEG = 0x2,
@@ -67,6 +69,11 @@ enum hinic3_link_follow_status {
HINIC3_LINK_FOLLOW_STATUS_MAX,
};
+enum hinic3_nic_pf_direct {
+ HINIC3_NIC_RX = 0,
+ HINIC3_NIC_TX,
+};
+
struct hinic3_link_ksettings {
u32 valid_bitmap;
u8 speed; /* enum nic_speed_level */
@@ -150,8 +157,12 @@ struct nic_port_info {
u8 duplex;
u8 speed;
u8 fec;
+ u8 lanes;
+ u8 rsvd;
u32 supported_mode;
u32 advertised_mode;
+ u32 supported_fec_mode;
+ u32 bond_speed;
};
struct nic_pause_config {
@@ -176,11 +187,17 @@ struct hinic3_rxq_hw {
#define MODULE_TYPE_QSFP28 0x11
#define MODULE_TYPE_QSFP 0x0C
#define MODULE_TYPE_QSFP_PLUS 0x0D
+#define MODULE_TYPE_DSFP 0x1B
+#define MODULE_TYPE_QSFP_CMIS 0x1E
#define TCAM_IP_TYPE_MASK 0x1
#define TCAM_TUNNEL_TYPE_MASK 0xF
#define TCAM_FUNC_ID_MASK 0x7FFF
+int hinic3_delete_bond(void *hwdev);
+int hinic3_open_close_bond(void *hwdev, u32 bond_en);
+int hinic3_create_bond(void *hwdev, u32 *bond_id);
+
int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule);
int hinic3_del_tcam_rule(void *hwdev, u32 index);
@@ -201,7 +218,7 @@ int hinic3_flush_tcam_rule(void *hwdev);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic3_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
+int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
u16 func_id);
/* *
@@ -333,7 +350,7 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr);
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr);
/* *
* @brief hinic3_vf_info_vlanprio - get vf vlan priority
@@ -508,7 +525,14 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table);
*/
int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats);
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats);
+/* *
+ * @brief hinic3_get_phy_rsfec_stats - get rsfec stats
+ * @param hwdev: device pointer to hwdev
+ * @param stats: rsfec(Reed-Solomon Forward Error Correction) stats
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats);
int hinic3_set_port_funcs_state(void *hwdev, bool enable);
@@ -544,6 +568,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl);
void hinic3_clear_vfs_info(void *hwdev);
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id);
+
int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id);
int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
@@ -563,10 +589,13 @@ int hinic3_set_autoneg(void *hwdev, bool enable);
int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext);
int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len);
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len);
bool hinic3_if_sfp_absent(void *hwdev);
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info);
-
+int hinic3_get_sfp_tlv_info(void *hwdev,
+ struct drv_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info,
+ const struct mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req);
/* *
* @brief hinic3_set_nic_feature_to_hw - sync nic feature to hardware
* @param hwdev: device pointer to hwdev
@@ -618,4 +647,18 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level);
int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type);
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+/* *
+ * @brief hinic3_vlxan_port_config - add/del vxlan dst port
+ * @param hwdev: device pointer to hwdev
+ * @param func_id: function id
+ * @param port: vxlan dst port
+ * @param action: add or del, del will set to default value (0x12B5)
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action);
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
index b46cf78..654673f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
@@ -21,7 +21,8 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
/*lint -e806*/
static unsigned char set_vf_link_state;
@@ -116,7 +117,7 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
err = hinic3_set_vlan_ctx(nic_io, glb_func_id, vlan_tag,
NIC_CONFIG_ALL_QUEUE_VLAN_CTX,
opcode == HINIC3_CMD_OP_ADD);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d vlan ctx, err: %d\n",
HW_VF_ID_TO_OS(vf_id), err);
@@ -137,22 +138,21 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
/* this function just be called by hinic3_ndo_set_vf_mac,
* others are not permitted.
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr)
{
- struct vf_data_storage *vf_info;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_info = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
-#ifndef __VMWARE__
+
/* duplicate request, so just return success */
if (ether_addr_equal(vf_info->user_mac_addr, mac_addr))
return 0;
-#else
- if (ether_addr_equal(vf_info->user_mac_addr, mac_addr))
- return 0;
-#endif
ether_addr_copy(vf_info->user_mac_addr, mac_addr);
return 0;
@@ -160,13 +160,15 @@ int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan, qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan = vlan;
@@ -180,17 +182,20 @@ int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_infos = nic_io->vf_infos;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_DEL,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_info(nic_io->dev_hdl, "Remove VLAN %u on VF %d\n",
@@ -205,11 +210,13 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
u16 hinic3_vf_info_vlanprio(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
u16 pf_vlan, vlanprio;
u8 pf_qos;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
pf_vlan = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan;
pf_qos = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos;
@@ -222,9 +229,14 @@ int hinic3_set_vf_link_state(void *hwdev, u16 vf_id, int link)
{
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ struct vf_data_storage *vf_infos = NULL;
u8 link_status = 0;
+ if (!nic_io)
+ return -EINVAL;
+
+ vf_infos = nic_io->vf_infos;
+
switch (link) {
case HINIC3_IFLA_VF_LINK_STATE_AUTO:
vf_infos[HW_VF_ID_TO_OS(vf_id)].link_forced = false;
@@ -264,6 +276,9 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_infos = nic_io->vf_infos;
memset(&spoofchk_cfg, 0, sizeof(spoofchk_cfg));
@@ -288,9 +303,11 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
bool hinic3_vf_info_spoofchk(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].spoofchk;
}
@@ -304,7 +321,7 @@ int hinic3_set_vf_trust(void *hwdev, u16 vf_id, bool trust)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
+ if (!nic_io || vf_id > nic_io->max_vfs)
return -EINVAL;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust = trust;
@@ -317,11 +334,11 @@ bool hinic3_get_vf_trust(void *hwdev, int vf_id)
struct hinic3_nic_io *nic_io = NULL;
if (!hwdev)
- return -EINVAL;
+ return false;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
- return -EINVAL;
+ if (!nic_io || vf_id > nic_io->max_vfs)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust;
}
@@ -339,6 +356,7 @@ static int hinic3_set_vf_tx_rate_max_min(struct hinic3_nic_io *nic_io,
rate_cfg.func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf_id;
rate_cfg.max_rate = max_rate;
rate_cfg.min_rate = min_rate;
+ rate_cfg.direct = HINIC3_NIC_TX;
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
&rate_cfg, sizeof(rate_cfg), &rate_cfg,
@@ -359,13 +377,16 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (!HINIC3_SUPPORT_RATE_LIMIT(hwdev)) {
nic_err(nic_io->dev_hdl, "Current function doesn't support to set vf rate limit\n");
return -EOPNOTSUPP;
}
err = hinic3_set_vf_tx_rate_max_min(nic_io, vf_id, max_rate, min_rate);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].max_rate = max_rate;
@@ -376,12 +397,16 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
void hinic3_get_vf_config(void *hwdev, u16 vf_id, struct ifla_vf_info *ivi)
{
- struct vf_data_storage *vfinfo;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vfinfo = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
vfinfo = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vfinfo)
+ return;
ivi->vf = HW_VF_ID_TO_OS(vf_id);
ether_addr_copy(ivi->mac, vfinfo->user_mac_addr);
@@ -455,12 +480,12 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
nic_io->hwdev, hinic3_vf_event_handler);
- if (err)
+ if (err != 0)
return err;
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
nic_io->hwdev, hinic3_vf_mag_event_handler);
- if (err)
+ if (err != 0)
goto reg_hilink_err;
memset(®ister_info, 0, sizeof(register_info));
@@ -472,6 +497,12 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
®ister_info, &out_size, 0,
HINIC3_CHANNEL_NIC);
if (err || !out_size || register_info.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev)) {
+ nic_warn(nic_io->dev_hdl,
+ "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, register_info.msg_head.status, out_size);
+ return 0;
+ }
nic_err(nic_io->dev_hdl, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
err, register_info.msg_head.status, out_size);
err = -EIO;
@@ -506,18 +537,18 @@ static int pf_init_vf_infos(struct hinic3_nic_io *nic_io)
for (i = 0; i < nic_io->max_vfs; i++) {
err = hinic3_init_vf_infos(nic_io, i);
- if (err)
+ if (err != 0)
goto init_vf_infos_err;
}
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
nic_io->hwdev, hinic3_pf_mbox_handler);
- if (err)
+ if (err != 0)
goto register_pf_mbox_cb_err;
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
nic_io->hwdev, hinic3_pf_mag_mbox_handler);
- if (err)
+ if (err != 0)
goto register_pf_mag_mbox_cb_err;
return 0;
@@ -540,16 +571,16 @@ int hinic3_vf_func_init(struct hinic3_nic_io *nic_io)
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
nic_io->hwdev, hinic3_pf_event_handler);
- if (err)
+ if (err != 0)
return err;
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
nic_io->hwdev, hinic3_pf_mag_event_handler);
- if (err)
+ if (err != 0)
goto register_mgmt_msg_cb_err;
err = pf_init_vf_infos(nic_io);
- if (err)
+ if (err != 0)
goto pf_init_vf_infos_err;
return 0;
@@ -576,9 +607,15 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
&unregister, sizeof(unregister),
&unregister, &out_size, 0,
HINIC3_CHANNEL_NIC);
- if (err || !out_size || unregister.msg_head.status)
- nic_err(nic_io->dev_hdl, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
- err, unregister.msg_head.status, out_size);
+ if (err || !out_size || unregister.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev))
+ nic_info(nic_io->dev_hdl,
+ "vRoCE VF notify PF unsuccessful is allowed");
+ else
+ nic_err(nic_io->dev_hdl,
+ "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, unregister.msg_head.status, out_size);
+ }
hinic3_unregister_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
} else {
@@ -587,6 +624,7 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
hinic3_unregister_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
hinic3_clear_vfs_info(nic_io->hwdev);
kfree(nic_io->vf_infos);
+ nic_io->vf_infos = NULL;
}
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
@@ -595,11 +633,15 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
static void clear_vf_infos(void *hwdev, u16 vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
u16 func_id;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
func_id = hinic3_glb_pf_vf_offset(hwdev) + vf_id;
vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
@@ -628,10 +670,57 @@ static void clear_vf_infos(void *hwdev, u16 vf_id)
void hinic3_clear_vfs_info(void *hwdev)
{
+ u16 i;
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- u16 i;
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
for (i = 0; i < nic_io->max_vfs; i++)
clear_vf_infos(hwdev, OS_VF_ID_TO_HW(i));
}
+
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id)
+{
+ int err = 0;
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ struct vf_data_storage *vf_infos = NULL;
+ u16 out_size = sizeof(outband_cfg_info);
+ u16 vf_id;
+ struct hinic3_nic_io *nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return 0;
+ }
+
+ vf_id = func_id - hinic3_glb_pf_vf_offset(nic_io->hwdev);
+ vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+ if (vf_infos->registered) {
+ outband_cfg_info.func_id = func_id;
+ outband_cfg_info.outband_default_vid = vlan_id;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_L2NIC,
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return 0;
+ }
+ if (err || !out_size || outband_cfg_info.msg_head.status)
+ nic_err(nic_io->dev_hdl,
+ "outband cfg event to VF %d failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err,
+ outband_cfg_info.msg_head.status, out_size);
+ }
+
+ return err;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
index 17d48c4..2878f66 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
@@ -30,6 +30,9 @@ int hinic3_dbg_get_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (q_id >= nic_io->num_qps) {
pr_err("q_id[%u] > num_qps_cfg[%u].\n", q_id, nic_io->num_qps);
return -EINVAL;
@@ -69,6 +72,9 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -82,6 +88,8 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
sq = &nic_io->sq[q_id];
+ if (!sq)
+ return -EINVAL;
sq_info->q_id = q_id;
sq_info->pi = hinic3_get_sq_local_pi(sq);
@@ -112,6 +120,9 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -125,6 +136,8 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
rq = &nic_io->rq[q_id];
+ if (!rq)
+ return -EINVAL;
rq_info->q_id = q_id;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
index 800fa73..137098b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
@@ -15,9 +15,10 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
#include "hinic3_dcb.h"
+#include "vram_common.h"
#define HINIC3_NIC_DRV_NAME "hinic3"
-#define HINIC3_NIC_DRV_VERSION "15.17.1.1"
+#define HINIC3_NIC_DRV_VERSION "17.7.8.1"
#define HINIC3_FUNC_IS_VF(hwdev) (hinic3_func_type(hwdev) == TYPE_VF)
@@ -25,6 +26,10 @@
#define HINIC3_MODERATONE_DELAY HZ
#define LP_PKT_CNT 64
+#define LP_PKT_LEN 60
+
+#define NAPI_IS_REGIN 1
+#define NAPI_NOT_REGIN 0
enum hinic3_flags {
HINIC3_INTF_UP,
@@ -91,6 +96,8 @@ struct hinic3_irq {
u16 rsvd1;
u32 irq_id; /* The IRQ number from OS */
+ u32 napi_reign;
+
char irq_name[IFNAMSIZ + 16];
struct napi_struct napi;
cpumask_t affinity_mask;
@@ -123,6 +130,41 @@ struct hinic3_dyna_txrxq_params {
struct hinic3_dyna_txq_res *txqs_res;
struct hinic3_dyna_rxq_res *rxqs_res;
struct hinic3_irq *irq_cfg;
+ char irq_cfg_vram_name[VRAM_NAME_MAX_LEN];
+};
+
+struct hinic3_flush_rq {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 lb_proc : 1;
+ u32 rsvd : 10;
+ u32 rq_id : 8;
+ u32 func_id : 13;
+#else
+ u32 func_id : 13;
+ u32 rq_id : 8;
+ u32 rsvd : 10;
+ u32 lb_proc : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd2 : 2;
+ u32 src_chnl : 12;
+ u32 pkt_len : 18;
+#else
+ u32 pkt_len : 18;
+ u32 src_chnl : 12;
+ u32 rsvd2 : 2;
+#endif
+ } bs;
+ u32 value;
+ } lb_info0; /* loop back information, used by uCode */
};
#define HINIC3_NIC_STATS_INC(nic_dev, field) \
@@ -147,6 +189,10 @@ struct hinic3_nic_stats {
#endif
};
+struct hinic3_nic_vport_stats {
+ u64 rx_discard_vport;
+};
+
#define HINIC3_TCAM_DYNAMIC_BLOCK_SIZE 16
#define HINIC3_MAX_TCAM_FILTERS 512
@@ -185,104 +231,123 @@ struct hinic3_tcam_info {
struct hinic3_tcam_dynamic_block_info tcam_dynamic_info;
};
+struct hinic3_dcb {
+ u8 cos_config_num_max;
+ u8 func_dft_cos_bitmap;
+ /* used to tool validity check */
+ u16 port_dft_cos_bitmap;
+
+ struct hinic3_dcb_config hw_dcb_cfg;
+ struct hinic3_dcb_config wanted_dcb_cfg;
+ unsigned long dcb_flags;
+};
+
+struct hinic3_vram {
+ u32 vram_mtu;
+ u16 vram_num_qps;
+ unsigned long flags;
+};
+
+struct hinic3_outband_cfg {
+ u16 outband_default_vid;
+ u16 rsvd;
+};
+
struct hinic3_nic_dev {
- struct pci_dev *pdev;
- struct net_device *netdev;
- struct hinic3_lld_dev *lld_dev;
- void *hwdev;
+ struct pci_dev *pdev;
+ struct net_device *netdev;
+ struct hinic3_lld_dev *lld_dev;
+ void *hwdev;
- int poll_weight;
- u32 rsvd1;
- unsigned long *vlan_bitmap;
+ int poll_weight;
+ u32 rsvd1;
+ unsigned long *vlan_bitmap;
- u16 max_qps;
+ u16 max_qps;
- u32 msg_enable;
- unsigned long flags;
+ u32 msg_enable;
+ unsigned long flags;
- u32 lro_replenish_thld;
- u32 dma_rx_buff_size;
- u16 rx_buff_len;
- u32 page_order;
+ u32 lro_replenish_thld;
+ u32 dma_rx_buff_size;
+ u16 rx_buff_len;
+ u32 page_order;
+ bool page_pool_enabled;
/* Rss related varibles */
- u8 rss_hash_engine;
- struct nic_rss_type rss_type;
- u8 *rss_hkey;
+ u8 rss_hash_engine;
+ struct nic_rss_type rss_type;
+ u8 *rss_hkey;
/* hkey in big endian */
- u32 *rss_hkey_be;
- u32 *rss_indir;
+ u32 *rss_hkey_be;
+ u32 *rss_indir;
- u8 cos_config_num_max;
- u8 func_dft_cos_bitmap;
- u16 port_dft_cos_bitmap; /* used to tool validity check */
+ struct hinic3_dcb *dcb;
+ char dcb_name[VRAM_NAME_MAX_LEN];
- struct hinic3_dcb_config hw_dcb_cfg;
- struct hinic3_dcb_config wanted_dcb_cfg;
- struct hinic3_dcb_config dcb_cfg;
- unsigned long dcb_flags;
- int disable_port_cnt;
- /* lock for disable or enable traffic flow */
- struct semaphore dcb_sem;
+ struct hinic3_vram *nic_vram;
+ char nic_vram_name[VRAM_NAME_MAX_LEN];
- struct hinic3_intr_coal_info *intr_coalesce;
- unsigned long last_moder_jiffies;
- u32 adaptive_rx_coal;
- u8 intr_coal_set_flag;
+ int disable_port_cnt;
+
+ struct hinic3_intr_coal_info *intr_coalesce;
+ unsigned long last_moder_jiffies;
+ u32 adaptive_rx_coal;
+ u8 intr_coal_set_flag;
#ifndef HAVE_NETDEV_STATS_IN_NETDEV
- struct net_device_stats net_stats;
+ struct net_device_stats net_stats;
#endif
- struct hinic3_nic_stats stats;
+ struct hinic3_nic_stats stats;
+ struct hinic3_nic_vport_stats vport_stats;
/* lock for nic resource */
- struct mutex nic_mutex;
- bool force_port_disable;
- struct semaphore port_state_sem;
- u8 link_status;
+ struct mutex nic_mutex;
+ u8 link_status;
- struct nic_service_cap nic_cap;
+ struct nic_service_cap nic_cap;
- struct hinic3_txq *txqs;
- struct hinic3_rxq *rxqs;
+ struct hinic3_txq *txqs;
+ struct hinic3_rxq *rxqs;
struct hinic3_dyna_txrxq_params q_params;
- u16 num_qp_irq;
- struct irq_info *qps_irq_info;
+ u16 num_qp_irq;
+ struct irq_info *qps_irq_info;
- struct workqueue_struct *workq;
+ struct workqueue_struct *workq;
- struct work_struct rx_mode_work;
- struct delayed_work moderation_task;
+ struct work_struct rx_mode_work;
+ struct delayed_work moderation_task;
- struct list_head uc_filter_list;
- struct list_head mc_filter_list;
- unsigned long rx_mod_state;
- int netdev_uc_cnt;
- int netdev_mc_cnt;
+ struct list_head uc_filter_list;
+ struct list_head mc_filter_list;
+ unsigned long rx_mod_state;
+ int netdev_uc_cnt;
+ int netdev_mc_cnt;
- int lb_test_rx_idx;
- int lb_pkt_len;
- u8 *lb_test_rx_buf;
+ int lb_test_rx_idx;
+ int lb_pkt_len;
+ u8 *lb_test_rx_buf;
- struct hinic3_tcam_info tcam;
- struct hinic3_rx_flow_rule rx_flow_rule;
+ struct hinic3_tcam_info tcam;
+ struct hinic3_rx_flow_rule rx_flow_rule;
#ifdef HAVE_XDP_SUPPORT
- struct bpf_prog *xdp_prog;
+ struct bpf_prog *xdp_prog;
#endif
- struct delayed_work periodic_work;
+ struct delayed_work periodic_work;
/* reference to enum hinic3_event_work_flags */
- unsigned long event_flag;
-
- struct hinic3_nic_prof_attr *prof_attr;
- struct hinic3_prof_adapter *prof_adap;
- u64 rsvd8[7];
- u32 rsvd9;
- u32 rxq_get_err_times;
- struct delayed_work rxq_check_work;
+ unsigned long event_flag;
+
+ struct hinic3_nic_prof_attr *prof_attr;
+ struct hinic3_prof_adapter *prof_adap;
+ u64 rsvd8[7];
+ struct hinic3_outband_cfg outband_cfg;
+ u32 rxq_get_err_times;
+ struct delayed_work rxq_check_work;
+ struct delayed_work vport_stats_work;
};
#define hinic_msg(level, nic_dev, msglvl, format, arg...) \
@@ -309,7 +374,7 @@ struct hinic3_uld_info *get_nic_uld_info(void);
u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev);
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
int hinic3_open(struct net_device *netdev);
@@ -328,6 +393,8 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev);
void hinic3_qps_irq_deinit(struct hinic3_nic_dev *nic_dev);
+void qp_del_napi(struct hinic3_irq *irq_cfg);
+
void hinic3_set_netdev_ops(struct hinic3_nic_dev *nic_dev);
bool hinic3_is_netdev_ops_match(const struct net_device *netdev);
@@ -345,10 +412,6 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
int hinic3_get_sset_count(struct net_device *netdev, int sset);
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev);
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
#ifdef ETHTOOL_GLINKSETTINGS
@@ -383,5 +446,17 @@ bool hinic3_is_xdp_enable(struct hinic3_nic_dev *nic_dev);
int hinic3_xdp_max_mtu(struct hinic3_nic_dev *nic_dev);
#endif
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+int set_fecparam(void *hwdev, u8 fecparam);
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec);
+#endif
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
index 57cf07c..6cc294e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
@@ -21,11 +21,12 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
{
- struct vf_data_storage *vf_info;
+ struct vf_data_storage *vf_info = NULL;
u16 func_id;
int err = 0;
@@ -38,7 +39,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
vf_info->pf_vlan, func_id,
HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d MAC\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -51,7 +52,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD,
vf_info->pf_vlan, vf_info->pf_qos,
vf_id);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to add VF %d VLAN_QOS\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -62,7 +63,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_vf_tx_rate(nic_io->hwdev, vf_id,
vf_info->max_rate,
vf_info->min_rate);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d max rate %u, min rate %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->max_rate,
vf_info->min_rate);
@@ -84,7 +85,7 @@ static int register_vf_msg_handler(struct hinic3_nic_io *nic_io, u16 vf_id)
}
err = hinic3_init_vf_config(nic_io, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].registered = true;
@@ -137,6 +138,9 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
int err;
+ if (!vf_info)
+ return -EINVAL;
+
if (register_vf->op_register) {
vf_info->support_extra_feature = register_vf->support_extra_feature;
err = register_vf_msg_handler(nic_io, vf_id);
@@ -145,7 +149,7 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
vf_info->support_extra_feature = 0;
}
- if (err)
+ if (err != 0)
register_info->msg_head.status = EFAULT;
*out_size = sizeof(*register_info);
@@ -157,6 +161,9 @@ void hinic3_unregister_vf(struct hinic3_nic_io *nic_io, u16 vf_id)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vf_info)
+ return;
+
unregister_vf_msg_handler(nic_io, vf_id);
vf_info->support_extra_feature = 0;
}
@@ -181,14 +188,21 @@ static int hinic3_get_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
void *buf_out, u16 *out_size)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf);
+ struct hinic3_port_mac_set *mac_in =
+ (struct hinic3_port_mac_set *)buf_in;
struct hinic3_port_mac_set *mac_info = buf_out;
int err;
- if (HINIC3_SUPPORT_VF_MAC(nic_io->hwdev)) {
+ if (!mac_info || !vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
+ if (HINIC3_SUPPORT_VF_MAC(nic_io->hwdev) != 0) {
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_GET_MAC, buf_in,
in_size, buf_out, out_size);
- if (!err) {
+ if (err == 0) {
if (is_zero_ether_addr(mac_info->mac))
ether_addr_copy(mac_info->mac, vf_info->drv_mac_addr);
}
@@ -211,6 +225,11 @@ static int hinic3_set_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -247,6 +266,11 @@ static int hinic3_del_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -283,12 +307,15 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
struct hinic3_port_mac_update *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
if (!is_valid_ether_addr(mac_in->new_mac)) {
nic_err(nic_io->dev_hdl, "Update VF MAC is invalid.\n");
return -EINVAL;
}
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
-#ifndef __VMWARE__
if (vf_info->use_specified_mac && !vf_info->trust) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
HW_VF_ID_TO_OS(vf));
@@ -296,17 +323,7 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
*out_size = sizeof(*mac_out);
return 0;
}
-#else
- err = hinic_config_vf_request(nic_io->hwdev->pcidev_hdl,
- HW_VF_ID_TO_OS(vf),
- HINIC_CFG_VF_MAC_CHANGED,
- (void *)mac_in->new_mac);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to config VF %d MAC request, err: %d\n",
- HW_VF_ID_TO_OS(vf), err);
- return err;
- }
-#endif
+
mac_in->vlan_id = vf_info->pf_vlan;
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_UPDATE_MAC,
buf_in, in_size, buf_out, out_size);
@@ -362,7 +379,8 @@ static int _l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u32 i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_cmd_handler[i].cmd)
cmd_to_pf = true;
@@ -404,6 +422,8 @@ int hinic3_pf_mbox_handler(void *hwdev,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (index = 0; index < cmd_size; index++) {
if (cmd == vf_cmd_handler[index].cmd)
@@ -460,10 +480,14 @@ void hinic3_notify_dcb_state_event(struct hinic3_nic_io *nic_io,
static void dcb_state_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- struct hinic3_cmd_vf_dcb_state *vf_dcb;
- struct hinic3_nic_io *nic_io;
+ struct hinic3_cmd_vf_dcb_state *vf_dcb = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
vf_dcb = buf_in;
if (!vf_dcb)
@@ -479,9 +503,13 @@ static void tx_pause_excp_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*excp_info)) {
- nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
+ nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %lu\n",
in_size, sizeof(*excp_info));
return;
}
@@ -501,6 +529,10 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_event_info event_info = {0};
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*active_info)) {
nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
@@ -515,6 +547,36 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
hinic3_event_callback(nic_io->hwdev, &event_info);
}
+static void outband_vlan_cfg_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out,
+ u16 *out_size)
+{
+ struct hinic3_outband_cfg_info *outband_cfg_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info = {0};
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ nic_info(nic_io->dev_hdl, "outband vlan cfg event received\n");
+
+ if (in_size != sizeof(*outband_cfg_info)) {
+ nic_err(nic_io->dev_hdl, "outband cfg info invalid in_size: %u, should be %lu\n",
+ in_size, sizeof(*outband_cfg_info));
+ return;
+ }
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = EVENT_NIC_OUTBAND_CFG;
+ memcpy((void *)event_info.event_data,
+ outband_cfg_info, sizeof(*outband_cfg_info));
+
+ hinic3_event_callback(nic_io->hwdev, &event_info);
+}
+
static const struct nic_event_handler nic_cmd_handler[] = {
{
.cmd = HINIC3_NIC_CMD_VF_COS,
@@ -529,6 +591,11 @@ static const struct nic_event_handler nic_cmd_handler[] = {
.cmd = HINIC3_NIC_CMD_BOND_ACTIVE_NOTICE,
.handler = bond_active_event_handler,
},
+
+ {
+ .cmd = HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ .handler = outband_vlan_cfg_event_handler,
+ },
};
static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
@@ -543,6 +610,8 @@ static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (i = 0; i < size; i++) {
if (cmd == nic_cmd_handler[i].cmd) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
index 22670ff..a9768b7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
@@ -16,7 +16,8 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_nic_io.h"
#define HINIC3_DEAULT_TX_CI_PENDING_LIMIT 1
@@ -34,7 +35,7 @@ MODULE_PARM_DESC(tx_coalescing_time, "TX CI coalescing parameter coalescing_time
static unsigned char rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
module_param(rq_wqe_type, byte, 0444);
-MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 0-8Bytes, 1-16Bytes, 2-32Bytes (default=2)");
+MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 1-16Bytes, 2-32Bytes (default=2)");
/*lint +e806*/
static u32 tx_drop_thd_on = HINIC3_DEAULT_DROP_THD_ON;
@@ -45,7 +46,7 @@ static u32 tx_drop_thd_off = HINIC3_DEAULT_DROP_THD_OFF;
module_param(tx_drop_thd_off, uint, 0644);
MODULE_PARM_DESC(tx_drop_thd_off, "TX parameter drop_thd_off (default=0)");
/* performance: ci addr RTE_CACHE_SIZE(64B) alignment */
-#define HINIC3_CI_Q_ADDR_SIZE (64)
+#define HINIC3_CI_Q_ADDR_SIZE (64U)
#define CI_TABLE_SIZE(num_qps, pg_sz) \
(ALIGN((num_qps) * HINIC3_CI_Q_ADDR_SIZE, pg_sz))
@@ -350,6 +351,13 @@ static int hinic3_create_rq(struct hinic3_nic_io *nic_io, struct hinic3_io_queue
{
int err;
+ /* rq_wqe_type Only support type 1-16Bytes, 2-32Bytes */
+ if (rq_wqe_type != HINIC3_NORMAL_RQ_WQE && rq_wqe_type != HINIC3_EXTEND_RQ_WQE) {
+ sdk_warn(nic_io->dev_hdl, "Module Parameter rq_wqe_type value %d is out of range: [%d, %d].",
+ rq_wqe_type, HINIC3_NORMAL_RQ_WQE, HINIC3_EXTEND_RQ_WQE);
+ rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
+ }
+
rq->wqe_type = rq_wqe_type;
rq->q_id = q_id;
rq->msix_entry_idx = rq_msix_idx;
@@ -1044,8 +1052,8 @@ static int clean_queue_offload_ctxt(struct hinic3_nic_io *nic_io,
static int clean_qp_offload_ctxt(struct hinic3_nic_io *nic_io)
{
/* clean LRO/TSO context space */
- return (clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_SQ) ||
- clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_RQ));
+ return ((clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_SQ) != 0) ||
+ (clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_RQ) != 0));
}
/* init qps ctxt and set sq ci attr and arm all sq */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
index 5c5585a..943a736 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
@@ -303,7 +303,7 @@ static inline void hinic3_write_db(struct hinic3_io_queue *queue, int cos,
wmb(); /* Write all before the doorbell */
- writeq(*((u64 *)&db), DB_ADDR(queue, pi));
+ writeq(*((u64 *)(u8 *)&db), DB_ADDR(queue, pi));
}
struct hinic3_dyna_qp_params {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
index 78d943d..9ea93a0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
@@ -32,7 +32,7 @@ struct hinic3_prof_adapter nic_prof_adap_objs[] = {
void hinic3_init_nic_prof_adapter(struct hinic3_nic_dev *nic_dev)
{
- u16 num_adap = ARRAY_SIZE(nic_prof_adap_objs);
+ int num_adap = ARRAY_LEN(nic_prof_adap_objs);
nic_dev->prof_adap = hinic3_prof_init(nic_dev, nic_prof_adap_objs, num_adap,
(void *)&nic_dev->prof_attr);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
index 283c544..6d9b0c1 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
@@ -394,7 +394,8 @@ hinic3_alloc_dynamic_block_resource(struct hinic3_nic_dev *nic_dev,
dynamic_block_ptr = kzalloc(sizeof(*dynamic_block_ptr), GFP_KERNEL);
if (!dynamic_block_ptr) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "fdir filter dynamic alloc block index %d memory failed\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "fdir filter dynamic alloc block index %u memory failed\n",
dynamic_block_id);
return NULL;
}
@@ -433,7 +434,8 @@ hinic3_dynamic_lookup_tcam_filter(struct hinic3_nic_dev *nic_dev,
list_for_each_entry(tmp,
&tcam_info->tcam_dynamic_info.tcam_dynamic_list,
block_list)
- if (tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)
+ if (!tmp ||
+ tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)
break;
if (!tmp || tmp->dynamic_index_cnt >= HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) {
@@ -515,7 +517,7 @@ static int hinic3_add_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, queue: %d, tcam_rule_nums: %d succeed\n",
+ "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, queue: %u, tcam_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev),
tcam_filter->dynamic_block_id, index, fdir_tcam_rule->index,
fdir_tcam_rule->data.qid, tcam_info->tcam_rule_nums + 1);
@@ -582,7 +584,7 @@ static int hinic3_del_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, local_rules_nums: %d, global_rule_nums: %d succeed\n",
+ "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, local_rules_nums: %u, global_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev), dynamic_block_id,
tcam_filter->index, index, tmp->dynamic_index_cnt - 1,
tcam_info->tcam_rule_nums - 1);
@@ -608,7 +610,7 @@ static inline struct hinic3_tcam_filter *
hinic3_tcam_filter_lookup(const struct list_head *filter_list,
struct tag_tcam_key *key)
{
- struct hinic3_tcam_filter *iter;
+ struct hinic3_tcam_filter *iter = NULL;
list_for_each_entry(iter, filter_list, tcam_filter_list) {
if (memcmp(key, &iter->tcam_key,
@@ -633,7 +635,7 @@ static int hinic3_remove_one_rule(struct hinic3_nic_dev *nic_dev,
struct hinic3_ethtool_rx_flow_rule *eth_rule)
{
struct hinic3_tcam_info *tcam_info = &nic_dev->tcam;
- struct hinic3_tcam_filter *tcam_filter;
+ struct hinic3_tcam_filter *tcam_filter = NULL;
struct nic_tcam_cfg_rule fdir_tcam_rule;
struct tag_tcam_key tcam_key;
int err;
@@ -754,7 +756,7 @@ static int validate_flow(struct hinic3_nic_dev *nic_dev,
{
if (fs->location >= MAX_NUM_OF_ETHTOOL_NTUPLE_RULES) {
nicif_err(nic_dev, drv, nic_dev->netdev, "loc exceed limit[0,%lu]\n",
- MAX_NUM_OF_ETHTOOL_NTUPLE_RULES);
+ MAX_NUM_OF_ETHTOOL_NTUPLE_RULES - 1);
return -EINVAL;
}
@@ -875,7 +877,7 @@ int hinic3_ethtool_get_flow(const struct hinic3_nic_dev *nic_dev,
int hinic3_ethtool_get_all_flows(const struct hinic3_nic_dev *nic_dev,
struct ethtool_rxnfc *info, u32 *rule_locs)
{
- int idx = 0;
+ u32 idx = 0;
struct hinic3_ethtool_rx_flow_rule *eth_rule = NULL;
if (!HINIC3_SUPPORT_FDIR(nic_dev->hwdev)) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h b/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
deleted file mode 100644
index a93f3b6..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_PROFILE_H
-#define HINIC3_PROFILE_H
-
-typedef bool (*hinic3_is_match_prof)(void *device);
-typedef void *(*hinic3_init_prof_attr)(void *device);
-typedef void (*hinic3_deinit_prof_attr)(void *porf_attr);
-
-enum prof_adapter_type {
- PROF_ADAP_TYPE_INVALID,
- PROF_ADAP_TYPE_PANGEA = 1,
-
- /* Add prof adapter type before default */
- PROF_ADAP_TYPE_DEFAULT,
-};
-
-/**
- * struct hinic3_prof_adapter - custom scene's profile adapter
- * @type: adapter type
- * @match: Check whether the current function is used in the custom scene.
- * Implemented in the current source file
- * @init: When @match return true, the initialization function called in probe.
- * Implemented in the source file of the custom scene
- * @deinit: When @match return true, the deinitialization function called when
- * remove. Implemented in the source file of the custom scene
- */
-struct hinic3_prof_adapter {
- enum prof_adapter_type type;
- hinic3_is_match_prof match;
- hinic3_init_prof_attr init;
- hinic3_deinit_prof_attr deinit;
-};
-
-#ifdef static
-#undef static
-#define LLT_STATIC_DEF_SAVED
-#endif
-
-/*lint -save -e661 */
-static inline struct hinic3_prof_adapter *
-hinic3_prof_init(void *device, struct hinic3_prof_adapter *adap_objs, int num_adap,
- void **prof_attr)
-{
- struct hinic3_prof_adapter *prof_obj = NULL;
- u16 i;
-
- for (i = 0; i < num_adap; i++) {
- prof_obj = &adap_objs[i];
- if (!(prof_obj->match && prof_obj->match(device)))
- continue;
-
- *prof_attr = prof_obj->init ? prof_obj->init(device) : NULL;
-
- return prof_obj;
- }
-
- return NULL;
-}
-
-static inline void hinic3_prof_deinit(struct hinic3_prof_adapter *prof_obj, void *prof_attr)
-{
- if (!prof_obj)
- return;
-
- if (prof_obj->deinit)
- prof_obj->deinit(prof_attr);
-}
-
-/*lint -restore*/
-
-/* module-level interface */
-#ifdef CONFIG_MODULE_PROF
-struct hinic3_module_ops {
- int (*module_prof_init)(void);
- void (*module_prof_exit)(void);
- void (*probe_fault_process)(void *pdev, u16 level);
- int (*probe_pre_process)(void *pdev);
- void (*probe_pre_unprocess)(void *pdev);
-};
-
-struct hinic3_module_ops *hinic3_get_module_prof_ops(void);
-
-static inline void hinic3_probe_fault_process(void *pdev, u16 level)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (ops && ops->probe_fault_process)
- ops->probe_fault_process(pdev, level);
-}
-
-static inline int hinic3_module_pre_init(void)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (!ops || !ops->module_prof_init)
- return -EINVAL;
-
- return ops->module_prof_init();
-}
-
-static inline void hinic3_module_post_exit(void)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (ops && ops->module_prof_exit)
- ops->module_prof_exit();
-}
-
-static inline int hinic3_probe_pre_process(void *pdev)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (!ops || !ops->probe_pre_process)
- return -EINVAL;
-
- return ops->probe_pre_process(pdev);
-}
-
-static inline void hinic3_probe_pre_unprocess(void *pdev)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (ops && ops->probe_pre_unprocess)
- ops->probe_pre_unprocess(pdev);
-}
-#else
-static inline void hinic3_probe_fault_process(void *pdev, u16 level) { };
-
-static inline int hinic3_module_pre_init(void)
-{
- return 0;
-}
-
-static inline void hinic3_module_post_exit(void) { };
-
-static inline int hinic3_probe_pre_process(void *pdev)
-{
- return 0;
-}
-
-static inline void hinic3_probe_pre_unprocess(void *pdev) { };
-#endif
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
index 6bf3b11..94acf61 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/dcbnl.h>
+#include <linux/init.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -23,7 +24,8 @@
#include "hinic3_hw.h"
#include "hinic3_rss.h"
-/*lint -e806*/
+#include "vram_common.h"
+
static u16 num_qps;
module_param(num_qps, ushort, 0444);
MODULE_PARM_DESC(num_qps, "Number of Queue Pairs (default=0)");
@@ -104,88 +106,84 @@ static int hinic3_get_rq2iq_map(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev, u8 num_cos, u32 *indir)
+static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev,
+ u8 group_num, u32 *indir)
{
- u16 k, group_size, start_qid = 0, qp_num = 0;
- int i = 0;
- u8 j, cur_cos = 0, default_cos;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ u16 k, group_size, start_qid = 0, cur_cos_qnum = 0;
+ u32 i = 0;
+ u8 j, cur_cos = 0, group = 0;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
- if (num_cos == 0) {
+ if (group_num == 0) {
for (i = 0; i < NIC_RSS_INDIR_SIZE; i++)
indir[i] = i % nic_dev->q_params.num_qps;
} else {
- group_size = NIC_RSS_INDIR_SIZE / num_cos;
-
- for (j = 0; j < num_cos; j++) {
- while (cur_cos < NIC_DCB_COS_MAX &&
- nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos] == 0)
- cur_cos++;
-
- if (cur_cos >= NIC_DCB_COS_MAX) {
- if (BIT(nic_dev->hw_dcb_cfg.default_cos) & valid_cos_map)
- default_cos = nic_dev->hw_dcb_cfg.default_cos;
- else
- default_cos = (u8)fls(valid_cos_map) - 1;
+ group_size = NIC_RSS_INDIR_SIZE / group_num;
+
+ for (group = 0; group < group_num; group++) {
+ cur_cos = dcb->hw_dcb_cfg.default_cos;
+ for (j = 0; j < NIC_DCB_COS_MAX; j++) {
+ if ((BIT(j) & valid_cos_map) != 0) {
+ cur_cos = j;
+ valid_cos_map -= (u8)BIT(j);
+ break;
+ }
+ }
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[default_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[default_cos];
+ cur_cos_qnum = dcb->hw_dcb_cfg.cos_qp_num[cur_cos];
+ if (cur_cos_qnum > 0) {
+ start_qid =
+ dcb->hw_dcb_cfg.cos_qp_offset[cur_cos];
} else {
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[cur_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos];
+ start_qid = cur_cos % nic_dev->q_params.num_qps;
+ /* Ensure that the offset of start_id is 0. */
+ cur_cos_qnum = 1;
}
for (k = 0; k < group_size; k++)
- indir[i++] = start_qid + k % qp_num;
-
- cur_cos++;
+ indir[i++] = start_qid + k % cur_cos_qnum;
}
}
}
-/*lint -e528*/
int hinic3_rss_init(struct hinic3_nic_dev *nic_dev, u8 *rq2iq_map, u32 map_size, u8 dcb_en)
{
struct net_device *netdev = nic_dev->netdev;
- u8 i, cos_num;
- u8 cos_map[NIC_DCB_UP_MAX] = {0};
- u8 cfg_map[NIC_DCB_UP_MAX] = {0};
+ u8 i, group_num, cos_bitmap, group = 0;
+ u8 cos_group[NIC_DCB_UP_MAX] = {0};
int err;
- if (dcb_en) {
- cos_num = hinic3_get_dev_user_cos_num(nic_dev);
-
- if (nic_dev->hw_dcb_cfg.trust == 0) {
- memcpy(cfg_map, nic_dev->hw_dcb_cfg.pcp2cos, sizeof(cfg_map));
- } else if (nic_dev->hw_dcb_cfg.trust == 1) {
- for (i = 0; i < NIC_DCB_UP_MAX; i++)
- cfg_map[i] = nic_dev->hw_dcb_cfg.dscp2cos[i * NIC_DCB_DSCP_NUM];
- }
-#define COS_CHANGE_OFFSET 4
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[COS_CHANGE_OFFSET + i] = cfg_map[i];
+ if (dcb_en != 0) {
+ group_num = (u8)roundup_pow_of_two(
+ hinic3_get_dev_user_cos_num(nic_dev));
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[i] = cfg_map[NIC_DCB_UP_MAX - (i + 1)];
+ cos_bitmap = hinic3_get_dev_valid_cos_map(nic_dev);
- while (cos_num & (cos_num - 1))
- cos_num++;
+ for (i = 0; i < NIC_DCB_UP_MAX; i++) {
+ if ((BIT(i) & cos_bitmap) != 0)
+ cos_group[NIC_DCB_UP_MAX - i - 1] = group++;
+ else
+ cos_group[NIC_DCB_UP_MAX - i - 1] =
+ group_num - 1;
+ }
} else {
- cos_num = 0;
+ group_num = 0;
}
- err = hinic3_set_hw_rss_parameters(netdev, 1, cos_num, cos_map, dcb_en);
+ err = hinic3_set_hw_rss_parameters(netdev, 1, group_num,
+ cos_group, dcb_en);
if (err)
return err;
- err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps, cos_num, cos_map,
- NIC_DCB_UP_MAX, nic_dev->rss_indir, rq2iq_map, map_size);
+ err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps,
+ group_num, cos_group, NIC_DCB_UP_MAX,
+ nic_dev->rss_indir, rq2iq_map, map_size);
if (err)
nicif_err(nic_dev, drv, netdev, "Failed to get rq map\n");
return err;
}
-/*lint -e528*/
void hinic3_rss_deinit(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -246,28 +244,59 @@ discard_user_rss_indir:
hinic3_set_default_rss_indir(netdev);
}
+#ifdef HAVE_HOT_REPLACE_FUNC
+bool partition_slave_doing_hotupgrade(void)
+{
+ return get_partition_role() && partition_doing_hotupgrade();
+}
+#endif
+
static void decide_num_qps(struct hinic3_nic_dev *nic_dev)
{
u16 tmp_num_qps = nic_dev->max_qps;
u16 num_cpus = 0;
+ u16 max_num_cpus;
int i, node;
+ int is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ nic_dev->q_params.num_qps = nic_dev->nic_vram->vram_num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Os hotreplace use vram to init num qps 1:%hu 2:%hu\n",
+ nic_dev->q_params.num_qps,
+ nic_dev->nic_vram->vram_num_qps);
+ return;
+ }
+
if (nic_dev->nic_cap.default_num_queues != 0 &&
nic_dev->nic_cap.default_num_queues < nic_dev->max_qps)
tmp_num_qps = nic_dev->nic_cap.default_num_queues;
MOD_PARA_VALIDATE_NUM_QPS(nic_dev, num_qps, tmp_num_qps);
- for (i = 0; i < (int)num_online_cpus(); i++) {
+#ifdef HAVE_HOT_REPLACE_FUNC
+ if (partition_slave_doing_hotupgrade())
+ max_num_cpus = (u16)num_present_cpus();
+ else
+ max_num_cpus = (u16)num_online_cpus();
+#else
+ max_num_cpus = (u16)num_online_cpus();
+#endif
+
+ for (i = 0; i < max_num_cpus; i++) {
node = (int)cpu_to_node(i);
if (node == dev_to_node(&nic_dev->pdev->dev))
num_cpus++;
}
if (!num_cpus)
- num_cpus = (u16)num_online_cpus();
+ num_cpus = max_num_cpus;
nic_dev->q_params.num_qps = (u16)min_t(u16, tmp_num_qps, num_cpus);
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "init num qps 1:%u 2:%u\n",
+ nic_dev->q_params.num_qps, nic_dev->nic_vram->vram_num_qps);
}
static void copy_value_to_rss_hkey(struct hinic3_nic_dev *nic_dev,
@@ -324,7 +353,6 @@ static int alloc_rss_resource(struct hinic3_nic_dev *nic_dev)
return 0;
}
-/*lint -e528*/
void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -363,6 +391,7 @@ void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
set_q_params:
clear_bit(HINIC3_RSS_ENABLE, &nic_dev->flags);
nic_dev->q_params.num_qps = nic_dev->max_qps;
+ nic_dev->nic_vram->vram_num_qps = nic_dev->max_qps;
}
static int hinic3_config_rss_hw_resource(struct hinic3_nic_dev *nic_dev,
@@ -756,6 +785,7 @@ int hinic3_set_channels(struct net_device *netdev,
nic_dev->q_params.num_qps = (u16)count;
}
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
return 0;
}
@@ -816,7 +846,7 @@ int hinic3_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
int err = 0;
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
@@ -923,7 +953,7 @@ int hinic3_get_rxfh_indir(struct net_device *netdev, u32 *indir)
indir = indir1->ring_index;
#endif
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
index 175c4d6..902d7e2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
@@ -15,13 +15,14 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_nic_cfg.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_hw.h"
#include "hinic3_nic.h"
#include "hinic3_common.h"
static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
- u8 *key)
+ u8 *key, u16 key_size)
{
struct hinic3_cmd_rss_hash_key hash_key;
u16 out_size = sizeof(hash_key);
@@ -32,7 +33,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
hash_key.opcode = opcode;
if (opcode == HINIC3_CMD_OP_SET)
- memcpy(hash_key.key, key, NIC_RSS_KEY_SIZE);
+ memcpy(hash_key.key, key, key_size);
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_CFG_RSS_HASH_KEY,
@@ -46,7 +47,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
}
if (opcode == HINIC3_CMD_OP_GET)
- memcpy(key, hash_key.key, NIC_RSS_KEY_SIZE);
+ memcpy(key, hash_key.key, key_size);
return 0;
}
@@ -60,8 +61,11 @@ int hinic3_rss_set_hash_key(void *hwdev, const u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memcpy(hash_key, key, NIC_RSS_KEY_SIZE);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET, hash_key);
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET,
+ hash_key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
@@ -72,7 +76,10 @@ int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET, key);
+ if (!nic_io)
+ return -EINVAL;
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET,
+ key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
@@ -86,6 +93,9 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -126,6 +136,8 @@ int hinic3_rss_set_indir_tbl(void *hwdev, const u32 *indir_table)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd buf\n");
@@ -170,6 +182,8 @@ static int hinic3_cmdq_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
@@ -221,6 +235,8 @@ static int hinic3_mgmt_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&ctx_tbl, 0, sizeof(ctx_tbl));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
ctx |= HINIC3_RSS_TYPE_SET(1, VALID) |
@@ -270,6 +286,8 @@ int hinic3_get_rss_type(void *hwdev, struct nic_rss_type *rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&ctx_tbl, 0, sizeof(struct hinic3_rss_context_table));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
@@ -303,6 +321,9 @@ static int hinic3_rss_cfg_hash_engine(struct hinic3_nic_io *nic_io, u8 opcode,
u16 out_size = sizeof(hash_type);
int err;
+ if (!nic_io)
+ return -EINVAL;
+
memset(&hash_type, 0, sizeof(struct hinic3_cmd_rss_engine_type));
hash_type.func_id = hinic3_global_func_id(nic_io->hwdev);
@@ -336,6 +357,9 @@ int hinic3_rss_set_hash_engine(void *hwdev, u8 type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_SET, &type);
}
@@ -347,6 +371,9 @@ int hinic3_rss_get_hash_engine(void *hwdev, u8 *type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_GET, type);
}
@@ -362,6 +389,8 @@ int hinic3_rss_cfg(void *hwdev, u8 rss_en, u8 cos_num, u8 *prio_tc, u16 num_qps)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&rss_cfg, 0, sizeof(struct hinic3_cmd_rss_config));
rss_cfg.func_id = hinic3_global_func_id(hwdev);
rss_cfg.rss_en = rss_en;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
index 5c60d01..4dbd6dd 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
@@ -10,6 +10,7 @@
#include <linux/interrupt.h>
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
+#include <net/xdp.h>
#include <linux/device.h>
#include <linux/pci.h>
#include <linux/u64_stats_sync.h>
@@ -20,6 +21,7 @@
#include <linux/ipv6.h>
#include <linux/module.h>
#include <linux/compiler.h>
+#include <linux/filter.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -31,10 +33,6 @@
#include "hinic3_rss.h"
#include "hinic3_rx.h"
-static u32 rq_pi_rd_en;
-module_param(rq_pi_rd_en, uint, 0644);
-MODULE_PARM_DESC(rq_pi_rd_en, "Enable rq read pi from host, defaut update pi by doorbell (default=0)");
-
/* performance: ci addr RTE_CACHE_SIZE(64B) alignment */
#define HINIC3_RX_HDR_SIZE 256
#define HINIC3_RX_BUFFER_WRITE 16
@@ -63,19 +61,34 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
struct pci_dev *pdev = nic_dev->pdev;
struct page *page = rx_info->page;
dma_addr_t dma = rx_info->buf_dma_addr;
+ u32 page_offset = 0;
if (likely(dma))
return true;
/* alloc new page for storage */
- page = alloc_pages_node(NUMA_NO_NODE, GFP_ATOMIC | __GFP_COLD |
- __GFP_COMP, nic_dev->page_order);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page = page_pool_alloc_frag(rx_info->page_pool, &page_offset,
+ nic_dev->rx_buff_len,
+ GFP_ATOMIC | __GFP_COLD |
+ __GFP_COMP);
+ if (unlikely(!page))
+ return false;
+ dma = page_pool_get_dma_addr(page);
+ goto set_rx_info;
+ }
+#endif
+ page = alloc_pages_node(NUMA_NO_NODE,
+ GFP_ATOMIC | __GFP_COLD | __GFP_COMP,
+ nic_dev->page_order);
+
if (unlikely(!page))
return false;
/* map page for use */
- dma = dma_map_page(&pdev->dev, page, 0, nic_dev->dma_rx_buff_size,
- DMA_FROM_DEVICE);
+ dma = dma_map_page(&pdev->dev, page, page_offset,
+ nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
/* if mapping failed free memory back to system since
* there isn't much point in holding memory we can't use
*/
@@ -83,10 +96,12 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
__free_pages(page, nic_dev->page_order);
return false;
}
+ goto set_rx_info;
+set_rx_info:
rx_info->page = page;
rx_info->buf_dma_addr = dma;
- rx_info->page_offset = 0;
+ rx_info->page_offset = page_offset;
return true;
}
@@ -108,8 +123,8 @@ static u32 hinic3_rx_fill_wqe(struct hinic3_rxq *rxq)
/* unit of cqe length is 16B */
hinic3_set_sge(&rq_wqe->extend_wqe.cqe_sect.sge,
rx_info->cqe_dma,
- (sizeof(struct hinic3_rq_cqe) >>
- HINIC3_CQE_SIZE_SHIFT));
+ (HINIC3_CQE_LEN >>
+ HINIC3_CQE_SIZE_SHIFT));
/* use fixed len */
rq_wqe->extend_wqe.buf_desc.sge.len =
nic_dev->rx_buff_len;
@@ -163,18 +178,11 @@ static u32 hinic3_rx_fill_buffers(struct hinic3_rxq *rxq)
}
if (likely(i)) {
- if (!rq_pi_rd_en) {
- hinic3_write_db(rxq->rq,
- rxq->q_id & (NIC_DCB_COS_MAX - 1),
- RQ_CFLAG_DP,
- (u16)((u32)rxq->next_to_update <<
- rxq->rq->wqe_type));
- } else {
- /* Write all the wqes before pi update */
- wmb();
-
- hinic3_update_rq_hw_pi(rxq->rq, rxq->next_to_update);
- }
+ hinic3_write_db(rxq->rq,
+ rxq->q_id & (NIC_RX_DB_COS_MAX - 1),
+ RQ_CFLAG_DP,
+ (u16)((u32)rxq->next_to_update <<
+ rxq->rq->wqe_type));
rxq->delta -= i;
rxq->next_to_alloc = rxq->next_to_update;
} else if (free_wqebbs == rxq->q_depth - 1) {
@@ -208,6 +216,18 @@ static void hinic3_rx_free_buffers(struct hinic3_nic_dev *nic_dev, u32 q_depth,
for (i = 0; i < q_depth; i++) {
rx_info = &rx_info_arr[i];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ if (rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool,
+ rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ }
+ continue;
+ }
+#endif
+
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev,
rx_info->buf_dma_addr,
@@ -226,7 +246,7 @@ static void hinic3_rx_free_buffers(struct hinic3_nic_dev *nic_dev, u32 q_depth,
static void hinic3_reuse_rx_page(struct hinic3_rxq *rxq,
struct hinic3_rx_info *old_rx_info)
{
- struct hinic3_rx_info *new_rx_info;
+ struct hinic3_rx_info *new_rx_info = NULL;
u16 nta = rxq->next_to_alloc;
new_rx_info = &rxq->rx_info[nta];
@@ -250,8 +270,8 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
struct hinic3_rx_info *rx_info,
struct sk_buff *skb, u32 size)
{
- struct page *page;
- u8 *va;
+ struct page *page = NULL;
+ u8 *va = NULL;
page = rx_info->page;
va = (u8 *)page_address(page) + rx_info->page_offset;
@@ -267,8 +287,15 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
DMA_FROM_DEVICE);
if (size <= HINIC3_RX_HDR_SIZE && !skb_is_nonlinear(skb)) {
- memcpy(__skb_put(skb, size), va,
- ALIGN(size, sizeof(long))); /*lint !e666*/
+ __skb_put_data(skb, va, size);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool,
+ page, false);
+ return false;
+ }
+#endif
/* page is not reserved, we can reuse buffer as-is */
if (likely(page_to_nid(page) == numa_node_id()))
@@ -276,25 +303,37 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
/* this page cannot be reused so discard it */
put_page(page);
- return false;
+ goto discard_page;
}
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
(int)rx_info->page_offset, (int)size, rxq->buf_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
+
/* avoid re-using remote pages */
if (unlikely(page_to_nid(page) != numa_node_id()))
- return false;
+ goto discard_page;
/* if we are only owner of page we can reuse it */
if (unlikely(page_count(page) != 1))
- return false;
+ goto discard_page;
/* flip page offset to other buffer */
rx_info->page_offset ^= rxq->buf_len;
get_page(page);
return true;
+
+discard_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
}
static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
@@ -334,13 +373,9 @@ static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
head_skb->truesize += rxq->buf_len;
}
- if (likely(hinic3_add_rx_frag(rxq, rx_info, skb, size))) {
+ if (likely(hinic3_add_rx_frag(rxq, rx_info, skb, size)))
hinic3_reuse_rx_page(rxq, rx_info);
- } else {
- /* we are not reusing the buffer so unmap it */
- dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
- rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
- }
+
/* clear contents of buffer_info */
rx_info->buf_dma_addr = 0;
rx_info->page = NULL;
@@ -481,9 +516,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
protocol = hdr.eth->h_proto;
/* L2 header */
- /*lint -save -e778*/
if (protocol == htons(ETH_P_8021_AD) ||
- protocol == htons(ETH_P_8021_Q)) { /*lint -restore*/
+ protocol == htons(ETH_P_8021_Q)) {
if (unlikely(max_len < ETH_HLEN + VLAN_HLEN))
return max_len;
@@ -495,9 +529,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
}
/* L3 header */
- /*lint -save -e778*/
switch (protocol) {
- case htons(ETH_P_IP): /*lint -restore*/
+ case htons(ETH_P_IP):
if ((int)(hdr.data - data) >
(int)(max_len - sizeof(struct iphdr)))
return max_len;
@@ -680,7 +713,7 @@ static void hinic3_copy_lp_data(struct hinic3_nic_dev *nic_dev,
nicif_warn(nic_dev, rx_err, netdev, "Loopback test warning, receive too many test pkts\n");
}
- if (skb->len != nic_dev->lb_pkt_len) {
+ if (skb->len != (u32)(nic_dev->lb_pkt_len)) {
nicif_warn(nic_dev, rx_err, netdev, "Wrong packet length\n");
nic_dev->lb_test_rx_idx++;
return;
@@ -714,7 +747,10 @@ static inline void hinic3_lro_set_gso_params(struct sk_buff *skb, u16 num_lro)
}
#ifdef HAVE_XDP_SUPPORT
-enum hinic3_xdp_pkt {
+enum hinic3_xdp_status {
+ // bpf_prog status
+ HINIC3_XDP_PROG_EMPTY,
+ // pkt action
HINIC3_XDP_PKT_PASS,
HINIC3_XDP_PKT_DROP,
};
@@ -725,9 +761,15 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
while (weqbb_num) {
rx_info = &rxq->rx_info[rxq->cons_idx & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool)
+ goto discard_direct;
+#endif
if (likely(page_to_nid(rx_info->page) == numa_node_id()))
hinic3_reuse_rx_page(rxq, rx_info);
+ goto discard_direct;
+discard_direct:
rx_info->buf_dma_addr = 0;
rx_info->page = NULL;
rxq->cons_idx++;
@@ -737,11 +779,10 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
}
}
-int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
+int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len, struct xdp_buff *xdp)
{
struct bpf_prog *xdp_prog = NULL;
struct hinic3_rx_info *rx_info = NULL;
- struct xdp_buff xdp;
int result = HINIC3_XDP_PKT_PASS;
u16 weqbb_num = 1; /* xdp can only use one rx_buff */
u8 *va = NULL;
@@ -749,13 +790,14 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
rcu_read_lock();
xdp_prog = READ_ONCE(rxq->xdp_prog);
- if (!xdp_prog)
+ if (!xdp_prog) {
+ result = HINIC3_XDP_PROG_EMPTY;
goto unlock_rcu;
+ }
if (unlikely(pkt_len > rxq->buf_len)) {
RXQ_STATS_INC(rxq, xdp_large_pkt);
- weqbb_num = (u16)(pkt_len >> rxq->rx_buff_shift) +
- ((pkt_len & (rxq->buf_len - 1)) ? 1 : 0);
+ weqbb_num = HINIC3_GET_SGE_NUM(pkt_len, rxq);
result = HINIC3_XDP_PKT_DROP;
goto xdp_out;
}
@@ -766,19 +808,20 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
dma_sync_single_range_for_cpu(rxq->dev, rx_info->buf_dma_addr,
rx_info->page_offset,
rxq->buf_len, DMA_FROM_DEVICE);
- xdp.data = va;
- xdp.data_hard_start = xdp.data;
- xdp.data_end = xdp.data + pkt_len;
+ xdp->data = va;
+ xdp->data_hard_start = xdp->data;
+ xdp->data_end = xdp->data + pkt_len;
#ifdef HAVE_XDP_FRAME_SZ
- xdp.frame_sz = rxq->buf_len;
+ xdp->frame_sz = rxq->buf_len;
#endif
#ifdef HAVE_XDP_DATA_META
- xdp_set_data_meta_invalid(&xdp);
+ xdp_set_data_meta_invalid(xdp);
#endif
- prefetchw(xdp.data_hard_start);
- act = bpf_prog_run_xdp(xdp_prog, &xdp);
+ prefetchw(xdp->data_hard_start);
+ act = bpf_prog_run_xdp(xdp_prog, xdp);
switch (act) {
case XDP_PASS:
+ result = HINIC3_XDP_PKT_PASS;
break;
case XDP_DROP:
result = HINIC3_XDP_PKT_DROP;
@@ -799,12 +842,94 @@ unlock_rcu:
return result;
}
+
+static bool hinic3_add_rx_frag_with_xdp(struct hinic3_rxq *rxq, u32 pkt_len,
+ struct hinic3_rx_info *rx_info,
+ struct sk_buff *skb,
+ struct xdp_buff *xdp)
+{
+ struct page *page = rx_info->page;
+
+ if (pkt_len <= HINIC3_RX_HDR_SIZE) {
+ __skb_put_data(skb, xdp->data, pkt_len);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool,
+ page, false);
+ return false;
+ }
+#endif
+
+ if (likely(page_to_nid(page) == numa_node_id()))
+ return true;
+
+ put_page(page);
+ goto umap_page;
+ }
+
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
+ (int)(rx_info->page_offset +
+ (xdp->data - xdp->data_hard_start)),
+ (int)pkt_len, rxq->buf_len);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
+ if (unlikely(page_to_nid(page) != numa_node_id()))
+ goto umap_page;
+ if (unlikely(page_count(page) != 1))
+ goto umap_page;
+
+ rx_info->page_offset ^= rxq->buf_len;
+ get_page(page);
+
+ return true;
+
+umap_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
+}
+
+static struct sk_buff *hinic3_fetch_rx_buffer_xdp(struct hinic3_rxq *rxq,
+ u32 pkt_len,
+ struct xdp_buff *xdp)
+{
+ struct sk_buff *skb;
+ struct hinic3_rx_info *rx_info;
+ u32 sw_ci;
+ bool reuse;
+
+ sw_ci = rxq->cons_idx & rxq->q_mask;
+ rx_info = &rxq->rx_info[sw_ci];
+
+ skb = netdev_alloc_skb_ip_align(rxq->netdev, HINIC3_RX_HDR_SIZE);
+ if (unlikely(!skb))
+ return NULL;
+
+ reuse = hinic3_add_rx_frag_with_xdp(rxq, pkt_len, rx_info, skb, xdp);
+ if (likely(reuse))
+ hinic3_reuse_rx_page(rxq, rx_info);
+
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+
+ rxq->cons_idx += 1;
+ rxq->delta += 1;
+
+ return skb;
+}
+
#endif
static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_rq_cqe *rx_cqe,
u32 pkt_len, u32 vlan_len, u32 status)
{
- struct sk_buff *skb;
+ struct sk_buff *skb = NULL;
struct net_device *netdev = rxq->netdev;
u32 offload_type;
u16 num_lro;
@@ -812,13 +937,25 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_rq_cqe *rx_cqe,
#ifdef HAVE_XDP_SUPPORT
u32 xdp_status;
+ struct xdp_buff xdp = { 0 };
- xdp_status = hinic3_run_xdp(rxq, pkt_len);
+ xdp_status = (u32)(hinic3_run_xdp(rxq, pkt_len, &xdp));
if (xdp_status == HINIC3_XDP_PKT_DROP)
return 0;
-#endif
+ // build skb
+ if (xdp_status != HINIC3_XDP_PROG_EMPTY) {
+ // xdp_prog configured, build skb with xdp
+ skb = hinic3_fetch_rx_buffer_xdp(rxq, pkt_len, &xdp);
+ } else {
+ // xdp_prog not configured, build skb
+ skb = hinic3_fetch_rx_buffer(rxq, pkt_len);
+ }
+#else
+
+ // xdp is not supported
skb = hinic3_fetch_rx_buffer(rxq, pkt_len);
+#endif
if (unlikely(!skb)) {
RXQ_STATS_INC(rxq, alloc_skb_err);
return -ENOMEM;
@@ -852,7 +989,7 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_rq_cqe *rx_cqe,
hinic3_copy_lp_data(nic_dev, skb);
num_lro = HINIC3_GET_RX_NUM_LRO(status);
- if (num_lro)
+ if (num_lro > 1)
hinic3_lro_set_gso_params(skb, num_lro);
skb_record_rx_queue(skb, rxq->q_id);
@@ -931,12 +1068,40 @@ int hinic3_rx_poll(struct hinic3_rxq *rxq, int budget)
return pkts;
}
+#ifdef HAVE_PAGE_POOL_SUPPORT
+static struct page_pool *hinic3_create_page_pool(struct hinic3_nic_dev *nic_dev,
+ u32 rq_depth,
+ struct hinic3_rx_info *rx_info_arr)
+{
+ struct page_pool_params pp_params = {
+ .flags = PP_FLAG_DMA_MAP | PP_FLAG_PAGE_FRAG |
+ PP_FLAG_DMA_SYNC_DEV,
+ .order = nic_dev->page_order,
+ .pool_size = rq_depth * nic_dev->rx_buff_len /
+ (PAGE_SIZE << nic_dev->page_order),
+ .nid = dev_to_node(&(nic_dev->pdev->dev)),
+ .dev = &(nic_dev->pdev->dev),
+ .dma_dir = DMA_FROM_DEVICE,
+ .offset = 0,
+ .max_len = PAGE_SIZE << nic_dev->page_order,
+ };
+ struct page_pool *page_pool;
+ int i;
+
+ page_pool = nic_dev->page_pool_enabled ?
+ page_pool_create(&pp_params) : NULL;
+ for (i = 0; i < rq_depth; i++)
+ rx_info_arr[i].page_pool = page_pool;
+ return page_pool;
+}
+#endif
+
int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
u32 rq_depth, struct hinic3_dyna_rxq_res *rxqs_res)
{
struct hinic3_dyna_rxq_res *rqres = NULL;
u64 cqe_mem_size = sizeof(struct hinic3_rq_cqe) * rq_depth;
- int idx, i;
+ int idx;
u32 pkts;
u64 size;
@@ -947,46 +1112,49 @@ int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
if (!rqres->rx_info) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx info\n", idx);
- goto err_out;
+ goto err_alloc_rx_info;
}
-
rqres->cqe_start_vaddr =
dma_zalloc_coherent(&nic_dev->pdev->dev, cqe_mem_size,
&rqres->cqe_start_paddr,
GFP_KERNEL);
if (!rqres->cqe_start_vaddr) {
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d cqe\n", idx);
- goto err_out;
+ goto err_alloc_cqe;
}
-
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ rqres->page_pool = hinic3_create_page_pool(nic_dev, rq_depth,
+ rqres->rx_info);
+ if (nic_dev->page_pool_enabled && !rqres->page_pool) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to create rxq%d page pool\n", idx);
+ goto err_create_page_pool;
+ }
+#endif
pkts = hinic3_rx_alloc_buffers(nic_dev, rq_depth,
rqres->rx_info);
if (!pkts) {
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx buffers\n", idx);
- goto err_out;
+ goto err_alloc_buffers;
}
rqres->next_to_alloc = (u16)pkts;
}
return 0;
-err_out:
- for (i = 0; i < idx; i++) {
- rqres = &rxqs_res[i];
-
- hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- kfree(rqres->rx_info);
- }
-
+err_alloc_buffers:
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ page_pool_destroy(rqres->page_pool);
+err_create_page_pool:
+#endif
+ dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
+ rqres->cqe_start_vaddr,
+ rqres->cqe_start_paddr);
+err_alloc_cqe:
+ kfree(rqres->rx_info);
+err_alloc_rx_info:
+ hinic3_free_rxqs_res(nic_dev, idx, rq_depth, rxqs_res);
return -ENOMEM;
}
@@ -1001,6 +1169,10 @@ void hinic3_free_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
rqres = &rxqs_res[idx];
hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rqres->page_pool)
+ page_pool_destroy(rqres->page_pool);
+#endif
dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
rqres->cqe_start_vaddr,
rqres->cqe_start_paddr);
@@ -1084,6 +1256,7 @@ void hinic3_free_rxqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->rxqs);
+ nic_dev->rxqs = NULL;
}
int hinic3_alloc_rxqs(struct net_device *netdev)
@@ -1207,6 +1380,15 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
nic_info(&nic_dev->pdev->dev, "rxq %u restore_buf_num:%u\n", q_id, rxq->restore_buf_num);
rx_info = &rxq->rx_info[(hw_ci + rxq->q_depth - 1) & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool && rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool,
+ rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ goto reset_rxq;
+ }
+#endif
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev, rx_info->buf_dma_addr,
nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
@@ -1217,7 +1399,9 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
__free_pages(rx_info->page, nic_dev->page_order);
rx_info->page = NULL;
}
+ goto reset_rxq;
+reset_rxq:
rxq->delta = 1;
rxq->next_to_update = (u16)((hw_ci + rxq->q_depth - 1) & rxq->q_mask);
rxq->cons_idx = (u16)((rxq->next_to_update + 1) & rxq->q_mask);
@@ -1238,15 +1422,10 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
return err;
}
- if (!rq_pi_rd_en) {
- hinic3_write_db(rxq->rq, rxq->q_id & (NIC_DCB_COS_MAX - 1),
- RQ_CFLAG_DP, (u16)((u32)rxq->next_to_update << rxq->rq->wqe_type));
- } else {
- /* Write all the wqes before pi update */
- wmb();
+ hinic3_write_db(rxq->rq, rxq->q_id & (NIC_DCB_COS_MAX - 1),
+ RQ_CFLAG_DP,
+ (u16)((u32)rxq->next_to_update << rxq->rq->wqe_type));
- hinic3_update_rq_hw_pi(rxq->rq, rxq->next_to_update);
- }
return 0;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
index f4d6f4f..7dd4618 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
@@ -4,6 +4,9 @@
#ifndef HINIC3_RX_H
#define HINIC3_RX_H
+#ifdef HAVE_PAGE_POOL_SUPPORT
+#include <net/page_pool.h>
+#endif
#include <linux/types.h>
#include <linux/device.h>
#include <linux/mm_types.h>
@@ -27,22 +30,22 @@
#define HINIC3_RX_CSUM_IPSU_OTHER_ERR BIT(8)
#define HINIC3_HEADER_DATA_UNIT 2
+#define HINIC3_CQE_LEN 32
struct hinic3_rxq_stats {
- u64 packets;
- u64 bytes;
- u64 errors;
- u64 csum_errors;
- u64 other_errors;
- u64 dropped;
- u64 xdp_dropped;
- u64 rx_buf_empty;
-
- u64 alloc_skb_err;
- u64 alloc_rx_buf_err;
- u64 xdp_large_pkt;
- u64 restore_drop_sge;
- u64 rsvd2;
+ u64 packets;
+ u64 bytes;
+ u64 errors;
+ u64 csum_errors;
+ u64 other_errors;
+ u64 dropped;
+ u64 xdp_dropped;
+ u64 rx_buf_empty;
+ u64 alloc_skb_err;
+ u64 alloc_rx_buf_err;
+ u64 xdp_large_pkt;
+ u64 restore_drop_sge;
+ u64 rsvd2;
#ifdef HAVE_NDO_GET_STATS64
struct u64_stats_sync syncp;
#else
@@ -56,6 +59,9 @@ struct hinic3_rx_info {
struct hinic3_rq_cqe *cqe;
dma_addr_t cqe_dma;
struct page *page;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
u32 page_offset;
u32 rsvd1;
struct hinic3_rq_wqe *rq_wqe;
@@ -96,7 +102,7 @@ struct hinic3_rxq {
u16 next_to_update;
struct device *dev; /* device for DMA mapping */
- unsigned long status;
+ u64 status;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
@@ -124,6 +130,9 @@ struct hinic3_dyna_rxq_res {
struct hinic3_rx_info *rx_info;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
};
int hinic3_alloc_rxqs(struct net_device *netdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
index bdd5a8e..051f05d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
@@ -11,9 +11,10 @@
#ifndef HINIC3_SRV_NIC_H
#define HINIC3_SRV_NIC_H
-#include "hinic3_mgmt_interface.h"
+#include <linux/netdevice.h>
+#include "nic_mpu_cmd_defs.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_lld.h"
enum hinic3_queue_type {
@@ -64,6 +65,7 @@ enum hinic3_nic_event_type {
EVENT_NIC_DCB_STATE_CHANGE,
EVENT_NIC_BOND_DOWN,
EVENT_NIC_BOND_UP,
+ EVENT_NIC_OUTBAND_CFG,
};
/* *
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
index e958782..d3f8696 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
@@ -218,6 +218,77 @@ static void get_inner_l4_info(struct sk_buff *skb, union hinic3_l4 *l4,
}
}
+static void get_inner_l3_l4_type(struct sk_buff *skb, union hinic3_ip *ip,
+ union hinic3_l4 *l4,
+ enum sq_l3_type *l3_type, u8 *l4_proto)
+{
+ unsigned char *exthdr = NULL;
+
+ if (ip->v4->version == IP4_VERSION) {
+ *l3_type = IPV4_PKT_WITH_CHKSUM_OFFLOAD;
+ *l4_proto = ip->v4->protocol;
+
+#ifdef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
+ /* inner_transport_header is wrong in centos7.0 and suse12.1 */
+ l4->hdr = ip->hdr + ((u8)ip->v4->ihl << IP_HDR_IHL_UNIT_SHIFT);
+#endif
+ } else if (ip->v4->version == IP6_VERSION) {
+ *l3_type = IPV6_PKT;
+ exthdr = ip->hdr + sizeof(*ip->v6);
+ *l4_proto = ip->v6->nexthdr;
+ if (exthdr != l4->hdr) {
+ __be16 frag_off = 0;
+#ifndef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
+ ipv6_skip_exthdr(skb, (int)(exthdr - skb->data),
+ l4_proto, &frag_off);
+#else
+ int pld_off = 0;
+
+ pld_off = ipv6_skip_exthdr(skb,
+ (int)(exthdr - skb->data),
+ l4_proto, &frag_off);
+ l4->hdr = skb->data + pld_off;
+#endif
+ }
+ } else {
+ *l3_type = UNKNOWN_L3TYPE;
+ *l4_proto = 0;
+ }
+}
+
+static u8 hinic3_get_inner_l4_type(struct sk_buff *skb)
+{
+ enum sq_l3_type l3_type;
+ u8 l4_proto;
+ union hinic3_ip ip;
+ union hinic3_l4 l4;
+
+ ip.hdr = skb_inner_network_header(skb);
+ l4.hdr = skb_inner_transport_header(skb);
+
+ get_inner_l3_l4_type(skb, &ip, &l4, &l3_type, &l4_proto);
+ return l4_proto;
+}
+
+static void hinic3_set_unknown_tunnel_csum(struct sk_buff *skb)
+{
+ int csum_offset;
+ __sum16 skb_csum;
+ u8 l4_proto;
+
+ l4_proto = hinic3_get_inner_l4_type(skb);
+ /* Unsupport tunnel packet, disable csum offload */
+ skb_checksum_help(skb);
+ /* The value of csum is changed from 0xffff to 0 according to RFC1624 */
+ if (skb->ip_summed == CHECKSUM_NONE && l4_proto != IPPROTO_UDP) {
+ csum_offset = skb_checksum_start_offset(skb) + skb->csum_offset;
+ skb_csum = *(__sum16 *)(skb->data + csum_offset);
+ if (skb_csum == 0xffff) {
+ *(__sum16 *)(skb->data + csum_offset) = 0;
+ }
+ }
+}
+
static int hinic3_tx_csum(struct hinic3_txq *txq, struct hinic3_sq_task *task,
struct sk_buff *skb)
{
@@ -251,11 +322,9 @@ static int hinic3_tx_csum(struct hinic3_txq *txq, struct hinic3_sq_task *task,
l4_proto = IPPROTO_RAW;
}
- if (l4_proto != IPPROTO_UDP ||
- ((struct udphdr *)skb_transport_header(skb))->dest != VXLAN_OFFLOAD_PORT_LE) {
+ if (l4_proto != IPPROTO_UDP) {
TXQ_STATS_INC(txq, unknown_tunnel_pkt);
- /* Unsupport tunnel packet, disable csum offload */
- skb_checksum_help(skb);
+ hinic3_set_unknown_tunnel_csum(skb);
return 0;
}
}
@@ -265,44 +334,6 @@ static int hinic3_tx_csum(struct hinic3_txq *txq, struct hinic3_sq_task *task,
return 1;
}
-static void get_inner_l3_l4_type(struct sk_buff *skb, union hinic3_ip *ip,
- union hinic3_l4 *l4,
- enum sq_l3_type *l3_type, u8 *l4_proto)
-{
- unsigned char *exthdr = NULL;
-
- if (ip->v4->version == IP4_VERSION) {
- *l3_type = IPV4_PKT_WITH_CHKSUM_OFFLOAD;
- *l4_proto = ip->v4->protocol;
-
-#ifdef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
- /* inner_transport_header is wrong in centos7.0 and suse12.1 */
- l4->hdr = ip->hdr + ((u8)ip->v4->ihl << IP_HDR_IHL_UNIT_SHIFT);
-#endif
- } else if (ip->v4->version == IP6_VERSION) {
- *l3_type = IPV6_PKT;
- exthdr = ip->hdr + sizeof(*ip->v6);
- *l4_proto = ip->v6->nexthdr;
- if (exthdr != l4->hdr) {
- __be16 frag_off = 0;
-#ifndef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
- ipv6_skip_exthdr(skb, (int)(exthdr - skb->data),
- l4_proto, &frag_off);
-#else
- int pld_off = 0;
-
- pld_off = ipv6_skip_exthdr(skb,
- (int)(exthdr - skb->data),
- l4_proto, &frag_off);
- l4->hdr = skb->data + pld_off;
-#endif
- }
- } else {
- *l3_type = UNKNOWN_L3TYPE;
- *l4_proto = 0;
- }
-}
-
static void hinic3_set_tso_info(struct hinic3_sq_task *task, u32 *queue_info,
enum sq_l4offload_type l4_offload,
u32 offset, u32 mss)
@@ -463,7 +494,8 @@ static void get_pkt_stats(struct hinic3_tx_info *tx_info, struct sk_buff *skb)
#endif
} else {
#endif
- ihs = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ ihs = (u32)(skb_transport_offset(skb)) +
+ tcp_hdrlen(skb);
#if (defined(HAVE_SKB_INNER_TRANSPORT_HEADER) && \
defined(HAVE_SK_BUFF_ENCAPSULATION))
}
@@ -471,7 +503,8 @@ static void get_pkt_stats(struct hinic3_tx_info *tx_info, struct sk_buff *skb)
hdr_len = (skb_shinfo(skb)->gso_segs - 1) * ihs;
tx_info->num_bytes = skb->len + (u64)hdr_len;
} else {
- tx_info->num_bytes = skb->len > ETH_ZLEN ? skb->len : ETH_ZLEN;
+ tx_info->num_bytes = (skb->len > ETH_ZLEN) ?
+ skb->len : ETH_ZLEN;
}
tx_info->num_pkts = 1;
@@ -626,6 +659,14 @@ static netdev_tx_t hinic3_send_one_skb(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
+ /* l2nic outband vlan cfg enable */
+ if ((!skb_vlan_tag_present(skb)) &&
+ (nic_dev->nic_cap.outband_vlan_cfg_en == 1) &&
+ nic_dev->outband_cfg.outband_default_vid != 0) {
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+ (u16)nic_dev->outband_cfg.outband_default_vid);
+ }
+
offload = hinic3_tx_offload(skb, &task, &queue_info, txq);
if (unlikely(offload == TX_OFFLOAD_INVALID)) {
TXQ_STATS_INC(txq, offload_cow_skb_err);
@@ -834,6 +875,7 @@ int hinic3_alloc_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
tqres->bds = kzalloc(size, GFP_KERNEL);
if (!tqres->bds) {
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc txq%d bds info\n", idx);
goto err_out;
@@ -847,7 +889,9 @@ err_out:
tqres = &txqs_res[i];
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
return -ENOMEM;
@@ -864,7 +908,9 @@ void hinic3_free_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
free_all_tx_skbs(nic_dev, sq_depth, tqres->tx_info);
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
}
@@ -938,6 +984,7 @@ void hinic3_free_txqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->txqs);
+ nic_dev->txqs = NULL;
}
static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
@@ -954,7 +1001,7 @@ static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
static int hinic3_stop_sq(struct hinic3_txq *txq)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(txq->netdev);
- unsigned long timeout;
+ u64 timeout;
int err;
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -963,7 +1010,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
return 0;
usleep_range(900, 1000); /* sleep 900 us ~ 1000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* force hardware to drop packets */
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -976,7 +1023,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
break;
usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* Avoid msleep takes too long and get a fake result */
if (is_hw_complete_sq_process(txq->sq))
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
index 1b9e509..7ae029b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
@@ -29,7 +29,7 @@ struct hinic3_wq {
#define WQ_MASK_IDX(wq, idx) ((idx) & (wq)->idx_mask)
#define WQ_MASK_PAGE(wq, pg_idx) \
- ((pg_idx) < (wq)->num_wq_pages ? (pg_idx) : 0)
+ (((pg_idx) < ((wq)->num_wq_pages)) ? (pg_idx) : 0)
#define WQ_PAGE_IDX(wq, idx) ((idx) >> (wq)->wqebbs_per_page_shift)
#define WQ_OFFSET_IN_PAGE(wq, idx) ((idx) & (wq)->wqebbs_per_page_mask)
#define WQ_GET_WQEBB_ADDR(wq, pg_idx, idx_in_pg) \
@@ -75,7 +75,7 @@ static inline void *hinic3_wq_get_multi_wqebbs(struct hinic3_wq *wq,
pg_idx = WQ_PAGE_IDX(wq, *prod_idx);
off_in_page = WQ_OFFSET_IN_PAGE(wq, *prod_idx);
- if (off_in_page + num_wqebbs > wq->wqebbs_per_page) {
+ if ((off_in_page + num_wqebbs) > wq->wqebbs_per_page) {
/* wqe across wq page boundary */
*second_part_wqebbs_addr =
WQ_GET_WQEBB_ADDR(wq, WQ_MASK_PAGE(wq, pg_idx + 1), 0);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
index b742f8a..0419fc2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
@@ -400,12 +400,16 @@ static int wait_for_status_poll(struct hinic3_api_cmd_chain *chain)
API_CMD_STATUS_TIMEOUT, 100); /* wait 100 us once */
}
-static void copy_resp_data(struct hinic3_api_cmd_cell_ctxt *ctxt, void *ack,
- u16 ack_size)
+static void copy_resp_data(struct hinic3_api_cmd_chain *chain,
+ struct hinic3_api_cmd_cell_ctxt *ctxt,
+ void *ack, u16 ack_size)
{
struct hinic3_api_cmd_resp_fmt *resp = ctxt->resp;
+ int rsp_size_align = chain->rsp_size_align - 0x8;
+ int rsp_size = (ack_size > rsp_size_align) ? rsp_size_align : ack_size;
+
+ memcpy(ack, &resp->resp_data, rsp_size);
- memcpy(ack, &resp->resp_data, ack_size);
ctxt->status = 0;
}
@@ -464,7 +468,7 @@ static int wait_for_api_cmd_completion(struct hinic3_api_cmd_chain *chain,
case HINIC3_API_CMD_POLL_READ:
err = wait_for_resp_polling(ctxt);
if (err == 0)
- copy_resp_data(ctxt, ack, ack_size);
+ copy_resp_data(chain, ctxt, ack, ack_size);
else
sdk_err(dev, "API CMD poll response timeout\n");
break;
@@ -1055,13 +1059,11 @@ alloc_cells_buf_err:
alloc_wb_status_err:
kfree(chain->cell_ctxt);
-/*lint -save -e548*/
alloc_cell_ctxt_err:
if (chain->chain_type == HINIC3_API_CMD_WRITE_ASYNC_TO_MGMT_CPU)
spin_lock_deinit(&chain->async_lock);
else
sema_deinit(&chain->sem);
-/*lint -restore*/
return err;
}
@@ -1078,6 +1080,7 @@ static void api_chain_free(struct hinic3_api_cmd_chain *chain)
dma_free_coherent(dev, sizeof(*chain->wb_status),
chain->wb_status, chain->wb_status_paddr);
kfree(chain->cell_ctxt);
+ chain->cell_ctxt = NULL;
if (chain->chain_type == HINIC3_API_CMD_WRITE_ASYNC_TO_MGMT_CPU)
spin_lock_deinit(&chain->async_lock);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
index 0878186..ceb7636 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
@@ -657,7 +657,7 @@ static int cmdq_sync_cmd_direct_resp(struct hinic3_cmdq *cmdq, u8 mod,
cmd_info->channel = channel;
cmdq_set_cmd_buf(cmd_info, cmdq->hwdev, buf_in, NULL);
- memcpy(&saved_cmd_info, cmd_info, sizeof(*cmd_info));
+ memcpy(&saved_cmd_info, cmd_info, sizeof(struct hinic3_cmdq_cmd_info));
cmdq_set_lcmd_wqe(&wqe, SYNC_CMD_DIRECT_RESP, buf_in, NULL,
wrapped, mod, cmd, curr_prod_idx);
@@ -745,7 +745,7 @@ static int cmdq_sync_cmd_detail_resp(struct hinic3_cmdq *cmdq, u8 mod, u8 cmd,
cmd_info->channel = channel;
cmdq_set_cmd_buf(cmd_info, cmdq->hwdev, buf_in, buf_out);
- memcpy(&saved_cmd_info, cmd_info, sizeof(*cmd_info));
+ memcpy(&saved_cmd_info, cmd_info, sizeof(struct hinic3_cmdq_cmd_info));
cmdq_set_lcmd_wqe(&wqe, SYNC_CMD_SGE_RESP, buf_in, buf_out,
wrapped, mod, cmd, curr_prod_idx);
@@ -994,9 +994,11 @@ int hinic3_cmdq_async(void *hwdev, u8 mod, u8 cmd, struct hinic3_cmd_buf *buf_in
return cmdq_async_cmd(&cmdqs->cmdq[HINIC3_CMDQ_SYNC], mod,
cmd, buf_in, channel);
}
+EXPORT_SYMBOL(hinic3_cmdq_async);
int hinic3_cmdq_async_cos(void *hwdev, u8 mod, u8 cmd,
- u8 cos_id, struct hinic3_cmd_buf *buf_in, u16 channel)
+ u8 cos_id, struct hinic3_cmd_buf *buf_in,
+ u16 channel)
{
struct hinic3_cmdqs *cmdqs = NULL;
int err;
@@ -1136,7 +1138,7 @@ void hinic3_cmdq_ceq_handler(void *handle, u32 ceqe_data)
break;
case HINIC3_CMD_TYPE_SET_ARM:
/* arm_bit was set until here */
- if (cmdq_arm_ceq_handler(cmdq, wqe, ci))
+ if (cmdq_arm_ceq_handler(cmdq, wqe, ci) != 0)
return;
break;
default:
@@ -1221,6 +1223,7 @@ cmd_infos_err:
static void free_cmdq(struct hinic3_cmdq *cmdq)
{
kfree(cmdq->cmd_infos);
+ cmdq->cmd_infos = NULL;
spin_lock_deinit(&cmdq->cmdq_lock);
}
@@ -1425,7 +1428,7 @@ static int create_cmdq_wq(struct hinic3_cmdqs *cmdqs)
type = HINIC3_CMDQ_SYNC;
for (; type < cmdqs->cmdq_num; type++)
memcpy((u8 *)cmdqs->wq_block_vaddr +
- CMDQ_WQ_CLA_SIZE * type,
+ ((u64)type * CMDQ_WQ_CLA_SIZE),
cmdqs->cmdq[type].wq.wq_block_vaddr,
cmdqs->cmdq[type].wq.num_wq_pages * sizeof(u64));
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
index b0344ea..b174ad2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
@@ -14,11 +14,6 @@
#include "hinic3_common.h"
#include "hinic3_hwdev.h"
-struct dma_pool {
- unsigned int size;
- void *dev_hdl;
-};
-
#define HINIC3_SCMD_DATA_LEN 16
#define HINIC3_CMDQ_DEPTH 4096
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
index 4c13a2e..af336f2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
@@ -22,11 +22,15 @@
#include "hinic3_sriov.h"
#include "hinic3_nictool.h"
#include "hinic3_pci_id_tbl.h"
+#include "hinic3_hwdev.h"
+#include "cfg_mgmt_mpu_cmd_defs.h"
+#include "mpu_cmd_base_defs.h"
#include "hinic3_dev_mgmt.h"
#define HINIC3_WAIT_TOOL_CNT_TIMEOUT 10000
#define HINIC3_WAIT_TOOL_MIN_USLEEP_TIME 9900
#define HINIC3_WAIT_TOOL_MAX_USLEEP_TIME 10000
+#define HIGHT_BDF 8
static unsigned long card_bit_map;
@@ -60,15 +64,23 @@ void lld_dev_cnt_init(struct hinic3_pcidev *pci_adapter)
void lld_dev_hold(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_inc(&pci_adapter->ref_cnt);
}
void lld_dev_put(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_dec(&pci_adapter->ref_cnt);
}
@@ -236,6 +248,40 @@ void hinic3_get_all_chip_id(void *id_info)
card_id->num = (u32)i;
}
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+ u64 bar1_phy_addr = 0;
+ u64 bar3_phy_addr = 0;
+ u64 bar1_size = 0;
+ u64 bar3_size = 0;
+
+ lld_hold();
+
+ /* get PF bar1 or bar3 physical address to verify */
+ list_for_each_entry(chip_node, &g_hinic3_chip_list, node) {
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (hinic3_func_type(dev->hwdev) == TYPE_VF)
+ continue;
+
+ bar1_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+ bar1_size = pci_resource_len(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+
+ bar3_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ bar3_size = pci_resource_len(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ if ((phy_addr == bar1_phy_addr && vmsize <= bar1_size) ||
+ (phy_addr == bar3_phy_addr && vmsize <= bar3_size)) {
+ lld_put();
+ return 0;
+ }
+ }
+ }
+
+ lld_put();
+ return -EINVAL;
+}
+
void hinic3_get_card_func_info_by_card_name(const char *chip_name,
struct hinic3_card_func_info *card_func)
{
@@ -328,7 +374,6 @@ out:
if (dev)
lld_dev_hold(dev);
lld_put();
-
return dev;
}
@@ -422,6 +467,28 @@ struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name
return NULL;
}
+void *hinic3_get_ppf_dev(void)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct list_head *chip_list = NULL;
+
+ lld_hold();
+ chip_list = get_hinic3_chip_list();
+
+ list_for_each_entry(chip_node, chip_list, node)
+ list_for_each_entry(pci_adapter, &chip_node->func_list, node)
+ if (hinic3_func_type(pci_adapter->hwdev) == TYPE_PPF) {
+ pr_info("Get ppf_func_id:%u", hinic3_global_func_id(pci_adapter->hwdev));
+ lld_put();
+ return pci_adapter->lld_dev.hwdev;
+ }
+
+ lld_put();
+ return NULL;
+}
+EXPORT_SYMBOL(hinic3_get_ppf_dev);
+
struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
enum hinic3_service_type type)
{
@@ -518,6 +585,7 @@ EXPORT_SYMBOL(hinic3_get_ppf_lld_dev_unsafe);
int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len)
{
struct hinic3_pcidev *pci_adapter = NULL;
+ int ret = 0;
if (!lld_dev || !chip_name || !max_len)
return -EINVAL;
@@ -527,12 +595,18 @@ int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 ma
return -EFAULT;
lld_hold();
- strncpy(chip_name, pci_adapter->chip_node->chip_name, max_len);
+ if (strscpy(chip_name, pci_adapter->chip_node->chip_name, max_len) < 0)
+ goto RELEASE;
chip_name[max_len - 1] = '\0';
lld_put();
return 0;
+
+RELEASE:
+ lld_put();
+
+ return ret;
}
EXPORT_SYMBOL(hinic3_get_chip_name);
@@ -541,6 +615,81 @@ struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev)
return lld_dev->hwdev;
}
+void hinic3_write_oshr_info(struct os_hot_replace_info *out_oshr_info,
+ struct hw_pf_info *info,
+ struct hinic3_board_info *board_info,
+ struct card_node *chip_node, u32 serivce_enable,
+ u32 func_info_idx)
+{
+ out_oshr_info->func_infos[func_info_idx].pf_idx = info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].backup_pf =
+ (((info->glb_func_idx) / (board_info->port_num)) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ ((info->glb_func_idx) + (board_info->port_num)) :
+ ((info->glb_func_idx) - (board_info->port_num));
+ out_oshr_info->func_infos[func_info_idx].partition =
+ ((info->glb_func_idx) / (board_info->port_num)) % HOT_REPLACE_PARTITION_NUM;
+ out_oshr_info->func_infos[func_info_idx].port_id = info->port_id;
+ out_oshr_info->func_infos[func_info_idx].bdf = (info->bus_num << HIGHT_BDF) + info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].bus_num = chip_node->bus_num;
+ out_oshr_info->func_infos[func_info_idx].valid = serivce_enable;
+ memcpy(out_oshr_info->func_infos[func_info_idx].card_name,
+ chip_node->chip_name, IFNAMSIZ);
+}
+
+void hinic3_get_os_hot_replace_info(void *oshr_info)
+{
+ struct os_hot_replace_info *out_oshr_info = (struct os_hot_replace_info *)oshr_info;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dst_dev = NULL;
+ struct hinic3_board_info *board_info = NULL;
+ struct hw_pf_info *infos = NULL;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ u32 func_info_idx = 0, func_id = 0, func_num, serivce_enable = 0;
+ struct list_head *hinic3_chip_list = get_hinic3_chip_list();
+ int err;
+
+ lld_hold();
+ pf_infos = kzalloc(sizeof(struct hinic3_hw_pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ pr_err("kzalloc pf_infos fail\n");
+ lld_put();
+ return;
+ }
+ list_for_each_entry(chip_node, hinic3_chip_list, node) {
+ list_for_each_entry(dst_dev, &chip_node->func_list, node) { // get all pf infos in one time by one pf_id
+ err = hinic3_get_hw_pf_infos(dst_dev->hwdev, pf_infos, HINIC3_CHANNEL_COMM);
+ if (err != 0) {
+ pr_err("get pf info failed\n");
+ break;
+ }
+
+ serivce_enable = 0;
+ infos = pf_infos->infos;
+ board_info = &((struct hinic3_hwdev *)(dst_dev->hwdev))->board_info;
+ if (((struct hinic3_hwdev *)(dst_dev->hwdev))->hot_replace_mode == HOT_REPLACE_ENABLE) {
+ serivce_enable = 1;
+ }
+ break;
+ }
+
+ func_num = pf_infos->num_pfs;
+ if (func_num <= 0) {
+ pr_err("get pf num failed\n");
+ break;
+ }
+
+ for (func_id = 0; func_id < func_num; func_id++) {
+ hinic3_write_oshr_info(out_oshr_info, &infos[func_id],
+ board_info, chip_node,
+ serivce_enable, func_info_idx);
+ func_info_idx++;
+ }
+ }
+ out_oshr_info->func_cnt = func_info_idx;
+ kfree(pf_infos);
+ lld_put();
+}
+
struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(lld_dev->pdev);
@@ -620,9 +769,13 @@ void hinic3_get_card_info(const void *hwdev, void *bufin)
}
if (hinic3_func_for_mgmt(fun_hwdev))
- strlcpy(info->pf[i].name, "FOR_MGMT", IFNAMSIZ);
+ strscpy(info->pf[i].name, "FOR_MGMT", IFNAMSIZ);
+
+ if (dev->lld_dev.pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID) {
+ strscpy(info->pf[i].name, "bifur", IFNAMSIZ);
+ }
- strlcpy(info->pf[i].bus_info, pci_name(dev->pcidev),
+ strscpy(info->pf[i].bus_info, pci_name(dev->pcidev),
sizeof(info->pf[i].bus_info));
info->pf_num++;
i = info->pf_num;
@@ -719,6 +872,7 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
struct card_node *chip_node = NULL;
unsigned char i;
unsigned char bus_number = 0;
+ int err;
if (chip_node_is_exist(pci_adapter, &bus_number))
return 0;
@@ -750,6 +904,13 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
return -EINVAL;
}
+ err = sscanf(chip_node->chip_name, HINIC3_CHIP_NAME "%d", &(chip_node->chip_id));
+ if (err <= 0) {
+ clear_bit(i, &card_bit_map);
+ kfree(chip_node);
+ return -EINVAL;
+ }
+
sdk_info(&pci_adapter->pcidev->dev,
"Add new chip %s to global list succeed\n",
chip_node->chip_name);
@@ -801,3 +962,36 @@ int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *
return 0;
}
+
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin)
+{
+ struct card_node *chip_node = NULL;
+ struct card_mbox_cnt_info *info = (struct card_mbox_cnt_info *)bufin;
+ struct hinic3_pcidev *dev = NULL;
+ struct hinic3_hwdev *func_hwdev = NULL;
+ u32 i = 0;
+
+ info->func_num = 0;
+ chip_node = hinic3_get_chip_node_by_hwdev(hwdev);
+ if (chip_node == NULL)
+ return;
+
+ lld_hold();
+
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ func_hwdev = (struct hinic3_hwdev *)dev->hwdev;
+ strscpy(info->func_info[i].bus_info, pci_name(dev->pcidev),
+ sizeof(info->func_info[i].bus_info));
+
+ info->func_info[i].send_cnt = func_hwdev->mbox_send_cnt;
+ info->func_info[i].ack_cnt = func_hwdev->mbox_ack_cnt;
+ info->func_num++;
+ i = info->func_num;
+ if (i >= ARRAY_SIZE(info->func_info)) {
+ sdk_err(&dev->pcidev->dev, "chip_node->func_list bigger than pf_max + vf_max\n");
+ break;
+ }
+ }
+
+ lld_put();
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
index a327c4a..bfa8f3e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
@@ -19,8 +19,10 @@
#define PRINT_ULD_DETACH_TIMEOUT_INTERVAL 1000 /* 1 second */
#define ULD_LOCK_MIN_USLEEP_TIME 900
#define ULD_LOCK_MAX_USLEEP_TIME 1000
+#define BIFUR_RESOURCE_PF_SSID 0x05a1
-#define HINIC3_IS_VF_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_VF)
+#define HINIC3_IS_VF_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_VF || \
+ (pdev)->device == HINIC3_DEV_SDI_5_1_ID_VF)
#define HINIC3_IS_SPU_DEV(pdev) \
(((pdev)->device == HINIC3_DEV_ID_SPU) || ((pdev)->device == HINIC3_DEV_ID_SDI_5_0_PF) || \
(((pdev)->device == HINIC3_DEV_ID_DPU_PF)))
@@ -79,6 +81,13 @@ struct hinic3_pcidev {
u16 probe_fault_level;
u16 rsvd2;
u64 rsvd4;
+
+ struct workqueue_struct *multi_host_mgmt_workq;
+ struct work_struct slave_nic_work;
+ struct work_struct slave_vroce_work;
+
+ struct workqueue_struct *migration_probe_workq;
+ struct delayed_work migration_probe_dwork;
};
struct hinic_chip_info {
@@ -104,4 +113,6 @@ void wait_lld_dev_unused(struct hinic3_pcidev *pci_adapter);
void *hinic3_get_hwdev_by_pcidev(struct pci_dev *pdev);
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
index 1949ab8..8f9d00a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
@@ -101,7 +101,8 @@ static bool check_image_device_type(struct hinic3_hwdev *hwdev, u32 device_type)
static void encapsulate_update_cmd(struct hinic3_cmd_update_firmware *msg,
struct firmware_section *section_info,
- int *remain_len, u32 *send_len, u32 *send_pos)
+ const int *remain_len, u32 *send_len,
+ u32 *send_pos)
{
memset(msg->data, 0, sizeof(msg->data));
msg->ctl_info.sf = (*remain_len == section_info->section_len) ? true : false;
@@ -380,6 +381,7 @@ int hinic3_init_devlink(struct hinic3_hwdev *hwdev)
struct pci_dev *pdev = NULL;
int err;
+ pdev = hwdev->hwif->pdev;
devlink = devlink_alloc(&hinic3_devlink_ops, sizeof(struct hinic3_devlink));
if (!devlink) {
sdk_err(hwdev->dev_hdl, "Failed to alloc devlink\n");
@@ -391,7 +393,6 @@ int hinic3_init_devlink(struct hinic3_hwdev *hwdev)
hwdev->devlink_dev->activate_fw = FW_CFG_DEFAULT_INDEX;
hwdev->devlink_dev->switch_cfg = FW_CFG_DEFAULT_INDEX;
- pdev = hwdev->hwif->pdev;
err = devlink_register(devlink, &pdev->dev);
if (err) {
sdk_err(hwdev->dev_hdl, "Failed to register devlink\n");
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
index 4b08aa0..caa99e3 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
@@ -26,6 +26,8 @@
#include "hinic3_prof_adap.h"
#include "hinic3_eqs.h"
+#include "vram_common.h"
+
#define HINIC3_EQS_WQ_NAME "hinic3_eqs"
#define AEQ_CTRL_0_INTR_IDX_SHIFT 0
@@ -66,7 +68,6 @@
#define HINIC3_TASK_PROCESS_EQE_LIMIT 1024
#define HINIC3_EQ_UPDATE_CI_STEP 64
-/*lint -e806*/
static uint g_aeq_len = HINIC3_DEFAULT_AEQ_LEN;
module_param(g_aeq_len, uint, 0444);
MODULE_PARM_DESC(g_aeq_len,
@@ -83,7 +84,6 @@ static uint g_num_ceqe_in_tasklet = HINIC3_TASK_PROCESS_EQE_LIMIT;
module_param(g_num_ceqe_in_tasklet, uint, 0444);
MODULE_PARM_DESC(g_num_ceqe_in_tasklet,
"The max number of ceqe can be processed in tasklet, default = 1024");
-/*lint +e806*/
#define CEQ_CTRL_0_INTR_IDX_SHIFT 0
#define CEQ_CTRL_0_DMA_ATTR_SHIFT 12
@@ -801,6 +801,7 @@ static int alloc_eq_pages(struct hinic3_eq *eq)
u32 reg, init_val;
u16 pg_idx, i;
int err;
+ gfp_t gfp_vram;
eq->eq_pages = kcalloc(eq->num_pages, sizeof(*eq->eq_pages),
GFP_KERNEL);
@@ -809,12 +810,15 @@ static int alloc_eq_pages(struct hinic3_eq *eq)
return -ENOMEM;
}
+ gfp_vram = hi_vram_get_gfp_vram();
+
for (pg_idx = 0; pg_idx < eq->num_pages; pg_idx++) {
eq_page = &eq->eq_pages[pg_idx];
err = hinic3_dma_zalloc_coherent_align(eq->hwdev->dev_hdl,
eq->page_size,
HINIC3_MIN_EQ_PAGE_SIZE,
- GFP_KERNEL, eq_page);
+ GFP_KERNEL | gfp_vram,
+ eq_page);
if (err) {
sdk_err(eq->hwdev->dev_hdl, "Failed to alloc eq page, page index: %hu\n",
pg_idx);
@@ -865,6 +869,7 @@ static void free_eq_pages(struct hinic3_eq *eq)
&eq->eq_pages[pg_idx]);
kfree(eq->eq_pages);
+ eq->eq_pages = NULL;
}
static inline u32 get_page_size(const struct hinic3_eq *eq)
@@ -1104,7 +1109,8 @@ int hinic3_aeqs_init(struct hinic3_hwdev *hwdev, u16 num_aeqs,
hwdev->aeqs = aeqs;
aeqs->hwdev = hwdev;
aeqs->num_aeqs = num_aeqs;
- aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME, WQ_MEM_RECLAIM,
+ aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME,
+ WQ_MEM_RECLAIM | WQ_HIGHPRI,
HINIC3_MAX_AEQS);
if (!aeqs->workq) {
sdk_err(hwdev->dev_hdl, "Failed to initialize aeq workqueue\n");
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
index a4cbac8..6b96b87 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
@@ -82,6 +82,48 @@ int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id,
return 0;
}
+/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read and clear to zero
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
+ u16 *value)
+{
+ struct chipif_sml_ctr_rd_req req;
+ union ctr_rd_rsp rsp;
+ int ret;
+
+ if (!hwdev || !value)
+ return -EFAULT;
+
+ if (!COMM_SUPPORT_API_CHAIN((struct hinic3_hwdev *)hwdev))
+ return -EPERM;
+
+ memset(&req, 0, sizeof(req));
+
+ hinic3_sml_ctr_read_build_req(&req, instance,
+ CHIPIF_SM_CTR_OP_READ_CLEAR,
+ CHIPIF_ACK, ctr_id, 0);
+
+ ret = hinic3_api_cmd_read_ack(hwdev, node, (u8 *)&req,
+ (unsigned short)sizeof(req),
+ (void *)&rsp,
+ (unsigned short)sizeof(rsp));
+ if (ret) {
+ sdk_err(((struct hinic3_hwdev *)hwdev)->dev_hdl,
+ "Sm 16bit counter clear fail, err(%d)\n", ret);
+ return ret;
+ }
+ sml_ctr_htonl_n((u32 *)&rsp, sizeof(rsp) / sizeof(u32));
+ *value = rsp.bs_ss16_rsp.value1;
+
+ return 0;
+}
+
/**
* hinic3_sm_ctr_rd32 - small single 32 counter read
* @hwdev: the hardware device
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
index cea7581..2d4a9f6 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
@@ -34,13 +34,16 @@ static void parse_pub_res_cap_dfx(struct hinic3_hwdev *hwdev,
cap->max_vf);
sdk_info(hwdev->dev_hdl, "Host_pf_num: 0x%x, pf_id_start: 0x%x, host_vf_num: 0x%x, vf_id_start: 0x%x\n",
cap->pf_num, cap->pf_id_start, cap->vf_num, cap->vf_id_start);
- sdk_info(hwdev->dev_hdl, "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x\n",
- cap->host_valid_bitmap, cap->master_host_id, cap->srv_multi_host_mode);
sdk_info(hwdev->dev_hdl,
- "fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
- cap->fake_vf_start_id, cap->fake_vf_num, cap->fake_vf_max_pctx);
- sdk_info(hwdev->dev_hdl, "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x\n",
- cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len);
+ "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x, hot_plug_disable: 0x%x\n",
+ cap->host_valid_bitmap, cap->master_host_id, cap->srv_multi_host_mode,
+ cap->hot_plug_disable);
+ sdk_info(hwdev->dev_hdl,
+ "os_hot_replace: 0x%x, fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
+ cap->os_hot_replace, cap->fake_vf_start_id, cap->fake_vf_num, cap->fake_vf_max_pctx);
+ sdk_info(hwdev->dev_hdl,
+ "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x, bond_create_mode: 0x%x\n",
+ cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len, cap->bond_create_mode);
}
static void parse_cqm_res_cap(struct hinic3_hwdev *hwdev, struct service_cap *cap,
@@ -109,6 +112,9 @@ static void parse_pub_res_cap(struct hinic3_hwdev *hwdev,
cap->host_valid_bitmap = dev_cap->host_valid_bitmap;
cap->master_host_id = dev_cap->master_host_id;
cap->srv_multi_host_mode = dev_cap->srv_multi_host_mode;
+ cap->hot_plug_disable = dev_cap->hot_plug_disable;
+ cap->bond_create_mode = dev_cap->bond_create_mode;
+ cap->os_hot_replace = dev_cap->os_hot_replace;
cap->fake_vf_en = dev_cap->fake_vf_en;
cap->fake_vf_start_bit = dev_cap->fake_vf_start_bit;
cap->fake_vf_end_bit = dev_cap->fake_vf_end_bit;
@@ -148,18 +154,27 @@ static void parse_l2nic_res_cap(struct hinic3_hwdev *hwdev,
nic_cap->max_sqs = dev_cap->nic_max_sq_id + 1;
nic_cap->max_rqs = dev_cap->nic_max_rq_id + 1;
nic_cap->default_num_queues = dev_cap->nic_default_num_queues;
+ nic_cap->outband_vlan_cfg_en = dev_cap->outband_vlan_cfg_en;
+ nic_cap->lro_enable = dev_cap->lro_enable;
sdk_info(hwdev->dev_hdl, "L2nic resource capbility, max_sqs: 0x%x, max_rqs: 0x%x\n",
nic_cap->max_sqs, nic_cap->max_rqs);
/* Check parameters from firmware */
- if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP ||
- nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
- sdk_info(hwdev->dev_hdl, "Number of qp exceed limit[1-%d]: sq: %u, rq: %u\n",
- HINIC3_CFG_MAX_QP, nic_cap->max_sqs, nic_cap->max_rqs);
+ if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of sq exceed limit[1-%d]: sq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_sqs);
nic_cap->max_sqs = HINIC3_CFG_MAX_QP;
+ }
+
+ if (nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of rq exceed limit[1-%d]: rq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_rqs);
nic_cap->max_rqs = HINIC3_CFG_MAX_QP;
}
+
+ if (nic_cap->outband_vlan_cfg_en)
+ sdk_info(hwdev->dev_hdl, "L2nic outband vlan cfg enabled\n");
}
static void parse_fc_res_cap(struct hinic3_hwdev *hwdev,
@@ -333,6 +348,28 @@ static void parse_ipsec_res_cap(struct hinic3_hwdev *hwdev,
dev_cap->ipsec_max_sactx, dev_cap->ipsec_max_cq);
}
+static void parse_vbs_res_cap(struct hinic3_hwdev *hwdev,
+ struct service_cap *cap,
+ struct cfg_cmd_dev_cap *dev_cap,
+ enum func_type type)
+{
+ struct vbs_service_cap *vbs_cap = &cap->vbs_cap;
+
+ vbs_cap->vbs_max_volq = dev_cap->vbs_max_volq;
+ vbs_cap->vbs_main_pf_enable = dev_cap->vbs_main_pf_enable;
+ vbs_cap->vbs_vsock_pf_enable = dev_cap->vbs_vsock_pf_enable;
+ vbs_cap->vbs_fushion_queue_pf_enable = dev_cap->vbs_fushion_queue_pf_enable;
+
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS resource capbility, vbs_max_volq: 0x%x\n",
+ dev_cap->vbs_max_volq);
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS pf info, vbs_main_pf_enable: 0x%x, vbs_vsock_pf_enable: 0x%x, vbs_fushion_queue_pf_enable: 0x%x\n",
+ dev_cap->vbs_main_pf_enable,
+ dev_cap->vbs_vsock_pf_enable,
+ dev_cap->vbs_fushion_queue_pf_enable);
+}
+
static void parse_dev_cap(struct hinic3_hwdev *dev,
struct cfg_cmd_dev_cap *dev_cap, enum func_type type)
{
@@ -375,6 +412,9 @@ static void parse_dev_cap(struct hinic3_hwdev *dev,
if (IS_PPA_TYPE(dev))
parse_ppa_res_cap(dev, cap, dev_cap, type);
+
+ if (IS_VBS_TYPE(dev))
+ parse_vbs_res_cap(dev, cap, dev_cap, type);
}
static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
@@ -404,6 +444,23 @@ static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
return 0;
}
+u8 hinic3_get_bond_create_mode(void *dev)
+{
+ struct hinic3_hwdev *hwdev = NULL;
+ struct service_cap *cap = NULL;
+
+ if (!dev) {
+ pr_err("pointer dev is NULL\n");
+ return -EINVAL;
+ }
+
+ hwdev = (struct hinic3_hwdev *)dev;
+ cap = &hwdev->cfg_mgmt->svc_cap;
+
+ return cap->bond_create_mode;
+}
+EXPORT_SYMBOL(hinic3_get_bond_create_mode);
+
int hinic3_get_dev_cap(void *dev)
{
enum func_type type;
@@ -1173,6 +1230,20 @@ bool hinic3_support_ppa(void *hwdev, struct ppa_service_cap *cap)
}
EXPORT_SYMBOL(hinic3_support_ppa);
+bool hinic3_support_bifur(void *hwdev, struct bifur_service_cap *cap)
+{
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)hwdev;
+
+ if (!hwdev)
+ return false;
+
+ if (!IS_BIFUR_TYPE(dev))
+ return false;
+
+ return true;
+}
+EXPORT_SYMBOL(hinic3_support_bifur);
+
bool hinic3_support_migr(void *hwdev, struct migr_service_cap *cap)
{
struct hinic3_hwdev *dev = hwdev;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
index db6e3ca..7157e97 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
@@ -166,6 +166,11 @@ struct service_cap {
u8 srv_multi_host_mode;
u16 virtio_vq_size;
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 os_hot_replace;
+ u8 rsvd1;
+
u8 timer_pf_num;
u8 timer_pf_id_start;
u16 timer_vf_num;
@@ -319,9 +324,11 @@ struct cfg_mgmt_info {
#define IS_RDMA_ENABLE(dev) \
((dev)->cfg_mgmt->svc_cap.sf_svc_attr.rdma_en)
#define IS_PPA_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_PPA)
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_PPA)
#define IS_MIGR_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_MIGRATE)
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_MIGRATE)
+#define IS_BIFUR_TYPE(dev) \
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_BIFUR)
int init_cfg_mgmt(struct hinic3_hwdev *dev);
@@ -333,5 +340,7 @@ void free_capability(struct hinic3_hwdev *dev);
int hinic3_init_vf_dev_cap(void *hwdev);
+u8 hinic3_get_bond_create_mode(void *dev);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
index d8a1a28..47264f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
@@ -21,7 +21,9 @@
#include "hinic3_hw_cfg.h"
#include "hinic3_cmdq.h"
#include "mpu_inband_cmd_defs.h"
+#include "mpu_board_defs.h"
#include "hinic3_hw_comm.h"
+#include "vram_common.h"
#define HINIC3_MSIX_CNT_LLI_TIMER_SHIFT 0
#define HINIC3_MSIX_CNT_LLI_CREDIT_SHIFT 8
@@ -242,12 +244,19 @@ int hinic3_func_reset(void *dev, u16 func_id, u64 reset_flag, u16 channel)
struct hinic3_hwdev *hwdev = dev;
u16 out_size = sizeof(func_reset);
int err = 0;
+ int is_in_kexec;
if (!dev) {
pr_err("Invalid para: dev is null.\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ sdk_info(hwdev->dev_hdl, "Skip function reset!\n");
+ return 0;
+ }
+
sdk_info(hwdev->dev_hdl, "Function is reset, flag: 0x%llx, channel:0x%x\n",
reset_flag, channel);
@@ -523,7 +532,7 @@ EXPORT_SYMBOL(hinic3_set_ppf_flr_type);
int hinic3_set_ppf_tbl_hotreplace_flag(void *hwdev, u8 flag)
{
- struct comm_cmd_ppf_tbl_htrp_config htr_info = {0};
+ struct comm_cmd_ppf_tbl_htrp_config htr_info = {};
u16 out_size = sizeof(struct comm_cmd_ppf_tbl_htrp_config);
struct hinic3_hwdev *dev = hwdev;
int ret;
@@ -868,11 +877,19 @@ static int set_ppf_tmr_status(struct hinic3_hwdev *hwdev,
int hinic3_ppf_tmr_start(void *hwdev)
{
+ int is_in_kexec;
+
if (!hwdev) {
pr_err("Hwdev pointer is NULL for starting ppf timer\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ pr_info("Skip starting ppt timer during kexec");
+ return 0;
+ }
+
return set_ppf_tmr_status(hwdev, HINIC_PPF_TMR_FLAG_START);
}
EXPORT_SYMBOL(hinic3_ppf_tmr_start);
@@ -888,18 +905,110 @@ int hinic3_ppf_tmr_stop(void *hwdev)
}
EXPORT_SYMBOL(hinic3_ppf_tmr_stop);
+static int hi_vram_kalloc_align(struct hinic3_hwdev *hwdev, char *name,
+ u32 page_size, u32 page_num,
+ struct hinic3_dma_addr_align *mem_align)
+{
+ void *vaddr = NULL, *align_vaddr = NULL;
+ dma_addr_t paddr, align_paddr;
+ u64 real_size = page_size;
+ u64 align = page_size;
+
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ /* align */
+ if (align_paddr == paddr) {
+ align_vaddr = vaddr;
+ goto out;
+ }
+
+ hi_vram_kfree((void *)vaddr, name, real_size);
+
+ /* realloc memory for align */
+ real_size = page_size + align;
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc align failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ align_vaddr = (void *)((u64)vaddr + (align_paddr - paddr));
+
+out:
+ mem_align->real_size = (u32)real_size;
+ mem_align->ori_vaddr = vaddr;
+ mem_align->ori_paddr = paddr;
+ mem_align->align_vaddr = align_vaddr;
+ mem_align->align_paddr = align_paddr;
+
+ return 0;
+}
+
+static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
+{
+ u32 i;
+ struct hinic3_dma_addr_align *page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = hwdev->mqm_eqm_vram_name;
+
+ page_addr = hwdev->mqm_att.brm_srch_page_addr;
+
+ for (i = 0; i < hwdev->mqm_att.page_num; i++) {
+ if (is_use_vram != 0) {
+ hi_vram_kfree(page_addr->ori_vaddr, mqm_eqm_vram_name[i].vram_name,
+ page_addr->real_size);
+ } else {
+ hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
+ }
+ page_addr->ori_vaddr = NULL;
+ page_addr++;
+ }
+
+ kfree(mqm_eqm_vram_name);
+ hwdev->mqm_eqm_vram_name = NULL;
+}
+
static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
u32 page_num)
{
struct hinic3_dma_addr_align *page_addr = hwdev->mqm_att.brm_srch_page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = NULL;
u32 valid_num = 0;
u32 flag = 1;
u32 i = 0;
int err;
+ u16 func_id;
+
+ mqm_eqm_vram_name = kzalloc(sizeof(struct mqm_eqm_vram_name_s) * page_num, GFP_KERNEL);
+ if (mqm_eqm_vram_name == NULL) {
+ sdk_err(hwdev->dev_hdl, "mqm eqm alloc vram name failed.\n");
+ return -ENOMEM;
+ }
+
+ hwdev->mqm_eqm_vram_name = mqm_eqm_vram_name;
+ func_id = hinic3_global_func_id(hwdev);
for (i = 0; i < page_num; i++) {
- err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl, page_size,
- page_size, GFP_KERNEL, page_addr);
+ if (is_use_vram != 0) {
+ snprintf(mqm_eqm_vram_name[i].vram_name,
+ VRAM_NAME_MAX_LEN, "%s%u%s%u",
+ VRAM_CQM_GLB_FUNC_BASE, func_id, VRAM_NIC_MQM, i);
+ err = hi_vram_kalloc_align(
+ hwdev, mqm_eqm_vram_name[i].vram_name,
+ page_size, page_num, page_addr);
+ } else {
+ err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl, page_size,
+ page_size, GFP_KERNEL, page_addr);
+ }
if (err) {
flag = 0;
break;
@@ -908,15 +1017,12 @@ static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
page_addr++;
}
+ hwdev->mqm_att.page_num = valid_num;
+
if (flag == 1) {
hwdev->mqm_att.page_size = page_size;
- hwdev->mqm_att.page_num = page_num;
} else {
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
- for (i = 0; i < valid_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
+ mqm_eqm_free_page_mem(hwdev);
return -EFAULT;
}
@@ -955,19 +1061,6 @@ static int mqm_eqm_alloc_page_mem(struct hinic3_hwdev *hwdev)
return ret;
}
-static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
-{
- u32 i;
- struct hinic3_dma_addr_align *page_addr;
-
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
-
- for (i = 0; i < hwdev->mqm_att.page_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
-}
-
static int mqm_eqm_set_cfg_2_hw(struct hinic3_hwdev *hwdev, u8 valid)
{
struct comm_cmd_eqm_cfg info_eqm_cfg;
@@ -1098,6 +1191,7 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
{
struct comm_cmd_get_eqm_num info_eqm_fix;
int ret;
+ int is_in_kexec;
if (hwdev->hwif->attr.func_type != TYPE_PPF)
return 0;
@@ -1127,10 +1221,15 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
goto err_page;
}
- ret = mqm_eqm_set_page_2_hw(hwdev);
- if (ret) {
- sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
- goto err_ecmd;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ ret = mqm_eqm_set_page_2_hw(hwdev);
+ if (ret) {
+ sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
+ goto err_ecmd;
+ }
+ } else {
+ sdk_info(hwdev->dev_hdl, "Mqm db don't set to chip when os hot replace.\r\n");
}
ret = mqm_eqm_set_cfg_2_hw(hwdev, 1);
@@ -1568,3 +1667,15 @@ int hinic3_switch_config(void *hwdev, u8 cfg_index)
return 0;
}
+
+bool hinic3_is_optical_module_mode(void *hwdev)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (dev->board_info.board_type == BOARD_TYPE_STRG_4X25G_COMSTORAGE ||
+ dev->board_info.board_type == BOARD_TYPE_CAL_4X25G_COMSTORAGE ||
+ dev->board_info.board_type == BOARD_TYPE_CAL_2X100G_TCE_BACKPLANE)
+ return false;
+
+ return true;
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
index baa1ce0..722fecd 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
@@ -252,98 +252,6 @@ static u32 get_up_timeout_val(enum hinic3_mod_type mod, u16 cmd)
return 0; /* use default mbox/apichain timeout time */
}
-static int api_csr_read(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
-{
- struct up_log_msg_st *up_log_msg = (struct up_log_msg_st *)buf_in;
- u8 *buf_out_tmp = (u8 *)buf_out;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
-
- if (!buf_in || !buf_out || in_size != sizeof(*up_log_msg) ||
- *out_size != up_log_msg->rd_len || up_log_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = up_log_msg->rd_len;
- rd_addr = up_log_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_rd32(hwdev, node_id,
- rd_addr + offset,
- (u32 *)(buf_out_tmp + offset));
- if (ret) {
- pr_err("Csr rd fail, err: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, node_id, rd_addr + offset);
- return ret;
- }
- offset += DW_WIDTH;
- }
- *out_size = rd_len;
-
- return ret;
-}
-
-static int api_csr_write(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out,
- u32 *out_size)
-{
- struct csr_write_st *csr_write_msg = (struct csr_write_st *)buf_in;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
- u8 *data = NULL;
-
- if (!buf_in || in_size != sizeof(*csr_write_msg) || csr_write_msg->rd_len == 0 ||
- csr_write_msg->rd_len > API_CSR_MAX_RD_LEN || csr_write_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = csr_write_msg->rd_len;
- rd_addr = csr_write_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- data = kzalloc(rd_len, GFP_KERNEL);
- if (!data) {
- pr_err("No more memory\n");
- return -EFAULT;
- }
- if (copy_from_user(data, (void *)csr_write_msg->data, rd_len)) {
- pr_err("Copy information from user failed\n");
- kfree(data);
- return -EFAULT;
- }
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_wr32(hwdev, node_id,
- rd_addr + offset,
- *((u32 *)(data + offset)));
- if (ret) {
- pr_err("Csr wr fail, ret: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, rd_addr + offset, node_id);
- kfree(data);
- return ret;
- }
- offset += DW_WIDTH;
- }
-
- *out_size = 0;
- kfree(data);
- return ret;
-}
-
int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
@@ -370,10 +278,8 @@ int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
return ret;
}
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_BYPASS) {
- if (nt_msg->mpu_cmd.cmd == API_CSR_WRITE)
- return api_csr_write(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
-
- ret = api_csr_read(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
+ pr_err("Unsupported api_type %u\n", nt_msg->mpu_cmd.api_type);
+ return -EINVAL;
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_TO_MPU) {
timeout = get_up_timeout_val(mod, cmd);
if (hinic3_pcie_itf_id(hwdev) != SPU_HOST_ID)
@@ -440,6 +346,23 @@ static int sm_rd16(void *hwdev, u32 id, u8 instance,
return ret;
}
+static int sm_rd16_clear(void *hwdev, u32 id, u8 instance,
+ u8 node, struct sm_out_st *buf_out)
+{
+ u16 val1;
+ int ret;
+
+ ret = hinic3_sm_ctr_rd16_clear(hwdev, node, instance, id, &val1);
+ if (ret != 0) {
+ pr_err("Get sm ctr clear information (16 bits)failed!\n");
+ val1 = 0xffff;
+ }
+
+ buf_out->val1 = val1;
+
+ return ret;
+}
+
static int sm_rd32(void *hwdev, u32 id, u8 instance,
u8 node, struct sm_out_st *buf_out)
{
@@ -559,6 +482,7 @@ const struct sm_module_handle sm_module_cmd_handle[] = {
{SM_CTR_RD32, sm_rd32},
{SM_CTR_RD64_PAIR, sm_rd64_pair},
{SM_CTR_RD64, sm_rd64},
+ {SM_CTR_RD16_CLEAR, sm_rd16_clear},
{SM_CTR_RD32_CLEAR, sm_rd32_clear},
{SM_CTR_RD64_PAIR_CLEAR, sm_rd64_pair_clear},
{SM_CTR_RD64_CLEAR, sm_rd64_clear}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
index 620136a..ac80b63 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
@@ -101,6 +101,12 @@ enum hinic3_pcie_tph {
#define SLAVE_HOST_STATUS_SET(host_id, enable) (((u8)(enable) & 1U) << (host_id))
#define SLAVE_HOST_STATUS_GET(host_id, val) (!!((val) & (1U << (host_id))))
+#ifdef HAVE_HOT_REPLACE_FUNC
+ extern int get_partition_id(void);
+#else
+ static int get_partition_id(void) { return 0; }
+#endif
+
void set_slave_host_enable(void *hwdev, u8 host_id, bool enable)
{
u32 reg_val;
@@ -207,6 +213,28 @@ static void hinic3_init_host_mode_pre(struct hinic3_hwdev *hwdev)
}
}
+static void hinic3_init_hot_plug_status(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->hot_plug_disable) {
+ hwdev->hot_plug_mode = HOT_PLUG_DISABLE;
+ } else {
+ hwdev->hot_plug_mode = HOT_PLUG_ENABLE;
+ }
+}
+
+static void hinic3_init_os_hot_replace(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->os_hot_replace) {
+ hwdev->hot_replace_mode = HOT_REPLACE_ENABLE;
+ } else {
+ hwdev->hot_replace_mode = HOT_REPLACE_DISABLE;
+ }
+}
+
static u8 hinic3_nic_sw_aeqe_handler(void *hwdev, u8 event, u8 *data)
{
struct hinic3_hwdev *dev = hwdev;
@@ -270,14 +298,20 @@ static void chip_fault_show(struct hinic3_hwdev *hwdev,
"fatal", "reset", "host", "flr", "general", "suggestion"};
char level_str[FAULT_SHOW_STR_LEN + 1];
u8 level;
+ int ret;
memset(level_str, 0, FAULT_SHOW_STR_LEN + 1);
level = event->event.chip.err_level;
- if (level < FAULT_LEVEL_MAX)
- strncpy(level_str, fault_level[level],
- FAULT_SHOW_STR_LEN);
- else
- strncpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (level < FAULT_LEVEL_MAX) {
+ ret = strscpy(level_str, fault_level[level],
+ FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ } else {
+ ret = strscpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ }
if (level == FAULT_LEVEL_SERIOUS_FLR)
dev_err(hwdev->dev_hdl, "err_level: %u [%s], flr func_id: %u\n",
@@ -299,6 +333,7 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
"reg rd timeout", "reg wr timeout", "phy fault", "tsensor fault"};
char type_str[FAULT_SHOW_STR_LEN + 1] = {0};
struct fault_event_stats *fault = NULL;
+ int ret;
sdk_err(hwdev->dev_hdl, "Fault event report received, func_id: %u\n",
hinic3_global_func_id(hwdev));
@@ -306,10 +341,14 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
fault = &hwdev->hw_stats.fault_event_stats;
if (event->type < FAULT_TYPE_MAX) {
- strncpy(type_str, fault_type[event->type], sizeof(type_str));
+ ret = strscpy(type_str, fault_type[event->type], sizeof(type_str));
+ if (ret < 0)
+ return;
atomic_inc(&fault->fault_type_stat[event->type]);
} else {
- strncpy(type_str, "Unknown", sizeof(type_str));
+ ret = strscpy(type_str, "Unknown", sizeof(type_str));
+ if (ret < 0)
+ return;
}
sdk_err(hwdev->dev_hdl, "Fault type: %u [%s]\n", event->type, type_str);
@@ -1536,15 +1575,30 @@ int hinic3_init_hwdev(struct hinic3_init_para *para)
hinic3_init_host_mode_pre(hwdev);
+ hinic3_init_hot_plug_status(hwdev);
+
+ hinic3_init_os_hot_replace(hwdev);
+
err = hinic3_multi_host_mgmt_init(hwdev);
if (err != 0) {
sdk_err(hwdev->dev_hdl, "Failed to init function mode\n");
goto init_multi_host_fail;
}
- err = hinic3_init_ppf_work(hwdev);
- if (err != 0)
- goto init_ppf_work_fail;
+ // hot_replace_mode is enable, run ppf function only when partition_id is 0
+ // or run ppf function directly
+ if (hwdev->hot_replace_mode == HOT_REPLACE_ENABLE) {
+ if (get_partition_id() == 0) {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0) {
+ goto init_ppf_work_fail;
+ }
+ }
+ } else {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0)
+ goto init_ppf_work_fail;
+ }
err = hinic3_set_comm_features(hwdev, hwdev->features, COMM_MAX_FEATURE_QWORD);
if (err != 0) {
@@ -1948,6 +2002,19 @@ void hinic3_link_event_stats(void *dev, u8 link)
}
EXPORT_SYMBOL(hinic3_link_event_stats);
+int hinic3_get_link_event_stats(void *dev, int *link_state)
+{
+ struct hinic3_hwdev *hwdev = dev;
+
+ if (!hwdev || !link_state)
+ return -EINVAL;
+
+ *link_state = hwdev->hw_stats.link_event_stats.link_down_stats.counter;
+
+ return 0;
+}
+EXPORT_SYMBOL(hinic3_get_link_event_stats);
+
u8 hinic3_max_pf_num(void *hwdev)
{
if (!hwdev)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
index e739767..7c2cfc2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
@@ -10,6 +10,7 @@
#include "hinic3_hw.h"
#include "mpu_inband_cmd_defs.h"
#include "hinic3_profile.h"
+#include "vram_common.h"
struct cfg_mgmt_info;
@@ -82,6 +83,22 @@ enum hinic3_host_mode_e {
HINIC3_SDI_MODE_MAX,
};
+enum hinic3_hot_plug_mode {
+ HOT_PLUG_ENABLE,
+ HOT_PLUG_DISABLE,
+};
+
+enum hinic3_os_hot_replace_mode {
+ HOT_REPLACE_DISABLE,
+ HOT_REPLACE_ENABLE,
+};
+
+#define UNSUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_DISABLE)
+
+#define SUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_ENABLE)
+
#define MULTI_HOST_CHIP_MODE_SHIFT 0
#define MULTI_HOST_MASTER_MBX_STS_SHIFT 17
#define MULTI_HOST_PRIV_DATA_SHIFT 0x8
@@ -100,6 +117,10 @@ enum hinic3_host_mode_e {
((val) & (~(MULTI_HOST_##member##_MASK \
<< MULTI_HOST_##member##_SHIFT)))
+struct mqm_eqm_vram_name_s {
+ char vram_name[VRAM_NAME_MAX_LEN];
+};
+
struct hinic3_hwdev {
void *adapter_hdl; /* pointer to hinic3_pcidev or NDIS_Adapter */
void *pcidev_hdl; /* pointer to pcidev or Handler */
@@ -138,6 +159,9 @@ struct hinic3_hwdev {
u32 rsvd2;
struct hinic3_multi_host_mgmt *mhost_mgmt;
+ char mhost_mgmt_name[VRAM_NAME_MAX_LEN];
+
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name;
struct mutex stateful_mutex; /* protect cqm init and deinit */
@@ -170,7 +194,10 @@ struct hinic3_hwdev {
struct hinic3_devlink *devlink_dev;
enum hinic3_func_mode func_mode;
- u32 rsvd3;
+ enum hinic3_hot_plug_mode hot_plug_mode;
+
+ enum hinic3_os_hot_replace_mode hot_replace_mode;
+ u32 rsvd5;
DECLARE_BITMAP(func_probe_in_host, MAX_FUNCTION_NUM);
DECLARE_BITMAP(netdev_setup_state, MAX_FUNCTION_NUM);
@@ -179,7 +206,10 @@ struct hinic3_hwdev {
u64 last_recv_aeq_cnt;
u16 aeq_busy_cnt;
- u64 rsvd4[8];
+ u64 mbox_send_cnt;
+ u64 mbox_ack_cnt;
+
+ u64 rsvd4[5];
};
#define HINIC3_DRV_FEATURE_QW0 \
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
index 33f1210..8590f70 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
@@ -544,6 +544,7 @@ static void free_db_area(struct hinic3_free_db_area *free_db_area)
{
spin_lock_deinit(&free_db_area->idx_lock);
kfree(free_db_area->db_bitmap_array);
+ free_db_area->db_bitmap_array = NULL;
}
static int get_db_idx(struct hinic3_hwif *hwif, u32 *idx)
@@ -841,6 +842,7 @@ void hinic3_free_hwif(struct hinic3_hwdev *hwdev)
free_db_area(&hwdev->hwif->free_db_area);
enable_all_msix(hwdev);
kfree(hwdev->hwif);
+ hwdev->hwif = NULL;
}
u16 hinic3_global_func_id(void *hwdev)
@@ -856,6 +858,44 @@ u16 hinic3_global_func_id(void *hwdev)
}
EXPORT_SYMBOL(hinic3_global_func_id);
+/**
+ * get function id from register,used by sriov hot migration process
+ * @hwdev: the pointer to hw device
+ */
+u16 hinic3_global_func_id_hw(void *hwdev)
+{
+ u32 addr, attr0;
+ struct hinic3_hwdev *dev;
+
+ dev = (struct hinic3_hwdev *)hwdev;
+ addr = HINIC3_CSR_FUNC_ATTR0_ADDR;
+ attr0 = hinic3_hwif_read_reg(dev->hwif, addr);
+
+ return HINIC3_AF0_GET(attr0, FUNC_GLOBAL_IDX);
+}
+
+/**
+ * get function id, used by sriov hot migratition process.
+ * @hwdev: the pointer to hw device
+ * @func_id: function id
+ */
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id)
+{
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)hwdev;
+
+ if (!hwdev || !func_id)
+ return -EINVAL;
+
+ /* only vf get func_id from chip reg for sriov migrate */
+ if (!HINIC3_IS_VF(dev)) {
+ *func_id = hinic3_global_func_id(hwdev);
+ return 0;
+ }
+
+ *func_id = hinic3_global_func_id_hw(dev);
+ return 0;
+}
+
u16 hinic3_intr_num(void *hwdev)
{
struct hinic3_hwif *hwif = NULL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
index 321a3b7..82a26ae 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
@@ -16,6 +16,7 @@
#include <linux/rtc.h>
#include <linux/aer.h>
#include <linux/debugfs.h>
+#include <linux/notifier.h>
#include "ossl_knl.h"
#include "hinic3_mt.h"
@@ -29,26 +30,41 @@
#include "hinic3_lld.h"
#include "hinic3_profile.h"
+#include "hinic3_hw_cfg.h"
+#include "hinic3_multi_host_mgmt.h"
#include "hinic3_hwdev.h"
#include "hinic3_prof_adap.h"
-#include "comm_msg_intf.h"
+#include "hinic3_devlink.h"
+
+#include "vram_common.h"
+
+enum partition_dev_type {
+ PARTITION_DEV_NONE = 0,
+ PARTITION_DEV_SHARED,
+ PARTITION_DEV_EXCLUSIVE,
+ PARTITION_DEV_BACKUP,
+};
+
+#ifdef HAVE_HOT_REPLACE_FUNC
+extern int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type, unsigned int partition_id);
+extern int get_partition_id(void);
+#else
+static int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type, unsigned int partition_id) { return 0; }
+static int get_partition_id(void) { return 0; }
+#endif
static bool disable_vf_load;
module_param(disable_vf_load, bool, 0444);
MODULE_PARM_DESC(disable_vf_load,
"Disable virtual functions probe or not - default is false");
+static bool g_is_pf_migrated;
static bool disable_attach;
module_param(disable_attach, bool, 0444);
MODULE_PARM_DESC(disable_attach, "disable_attach or not - default is false");
#define HINIC3_WAIT_SRIOV_CFG_TIMEOUT 15000
-MODULE_AUTHOR("Huawei Technologies CO., Ltd");
-MODULE_DESCRIPTION(HINIC3_DRV_DESC);
-MODULE_VERSION(HINIC3_DRV_VERSION);
-MODULE_LICENSE("GPL");
-
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
static DEVICE_ATTR(sriov_numvfs, 0664,
hinic3_sriov_numvfs_show, hinic3_sriov_numvfs_store);
@@ -71,7 +87,18 @@ static const struct attribute_group hinic3_attr_group = {
struct hinic3_uld_info g_uld_info[SERVICE_T_MAX] = { {0} };
#define HINIC3_EVENT_PROCESS_TIMEOUT 10000
+#define HINIC3_WAIT_EVENT_PROCESS_TIMEOUT 100
struct mutex g_uld_mutex;
+#define BUS_MAX_DEV_NUM 256
+#define HINIC3_SLAVE_WORK_MAX_NUM 20
+
+typedef struct vf_offset_info {
+ u8 valid;
+ u16 vf_offset_from_pf[CMD_MAX_MAX_PF_NUM];
+} VF_OFFSET_INFO_S;
+
+static VF_OFFSET_INFO_S g_vf_offset;
+DEFINE_MUTEX(g_vf_offset_lock);
void hinic3_uld_lock_init(void)
{
@@ -80,13 +107,23 @@ void hinic3_uld_lock_init(void)
static const char *s_uld_name[SERVICE_T_MAX] = {
"nic", "ovs", "roce", "toe", "ioe",
- "fc", "vbs", "ipsec", "virtio", "migrate", "ppa", "custom"};
+ "fc", "vbs", "ipsec", "virtio", "migrate",
+ "ppa", "custom", "vroce", "crypt", "vsock", "bifur"};
const char **hinic3_get_uld_names(void)
{
return s_uld_name;
}
+#ifdef CONFIG_PCI_IOV
+static int hinic3_get_pf_device_id(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_dev = pci_physfn(pdev);
+
+ return pf_dev->device;
+}
+#endif
+
static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
const struct hinic3_uld_info *uld_info)
{
@@ -105,6 +142,10 @@ static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
atomic_set(&dev->uld_ref_cnt[type], 0);
+ if (!uld_info->probe) {
+ err = 0;
+ goto out_unlock;
+ }
err = uld_info->probe(&dev->lld_dev, &uld_dev, dev->uld_dev_name[type]);
if (err) {
sdk_err(&dev->pcidev->dev,
@@ -173,6 +214,10 @@ static void detach_uld(struct hinic3_pcidev *dev,
wait_uld_unused(dev, type);
+ if (!uld_info->remove) {
+ mutex_unlock(&dev->pdev_mutex);
+ return;
+ }
uld_info->remove(&dev->lld_dev, dev->uld_dev[type]);
dev->uld_dev[type] = NULL;
@@ -190,10 +235,15 @@ static void attach_ulds(struct hinic3_pcidev *dev)
enum hinic3_service_type type;
struct pci_dev *pdev = dev->pcidev;
- lld_hold();
+ int is_in_kexec = vram_get_kexec_flag();
+ /* don't need hold when driver parallel load during spu hot replace */
+ if (is_in_kexec == 0) {
+ lld_hold();
+ }
+
mutex_lock(&g_uld_mutex);
- for (type = SERVICE_T_NIC; type < SERVICE_T_MAX; type++) {
+ for (type = SERVICE_T_OVS; type < SERVICE_T_MAX; type++) {
if (g_uld_info[type].probe) {
if (pdev->is_virtfn &&
(!hinic3_get_vf_service_load(pdev, (u16)type))) {
@@ -205,7 +255,10 @@ static void attach_ulds(struct hinic3_pcidev *dev)
}
}
mutex_unlock(&g_uld_mutex);
- lld_put();
+
+ if (is_in_kexec == 0) {
+ lld_put();
+ }
}
static void detach_ulds(struct hinic3_pcidev *dev)
@@ -255,10 +308,10 @@ int hinic3_register_uld(enum hinic3_service_type type,
}
chip_list = get_hinic3_chip_list();
- memcpy(&g_uld_info[type], uld_info, sizeof(*uld_info));
+ memcpy(&g_uld_info[type], uld_info, sizeof(struct hinic3_uld_info));
list_for_each_entry(chip_node, chip_list, node) {
list_for_each_entry(dev, &chip_node->func_list, node) {
- if (attach_uld(dev, type, uld_info)) {
+ if (attach_uld(dev, type, uld_info) != 0) {
sdk_err(&dev->pcidev->dev,
"Attach %s driver to pcie device failed\n",
s_uld_name[type]);
@@ -312,7 +365,7 @@ void hinic3_unregister_uld(enum hinic3_service_type type)
}
uld_info = &g_uld_info[type];
- memset(uld_info, 0, sizeof(*uld_info));
+ memset(uld_info, 0, sizeof(struct hinic3_uld_info));
mutex_unlock(&g_uld_mutex);
lld_put();
}
@@ -366,6 +419,26 @@ void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_ser
}
EXPORT_SYMBOL(hinic3_detach_service);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ __module_get(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_get);
+
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ module_put(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_put);
+
static void hinic3_sync_time_to_fmw(struct hinic3_pcidev *pdev_pri)
{
struct timeval tv = {0};
@@ -382,7 +455,8 @@ static void hinic3_sync_time_to_fmw(struct hinic3_pcidev *pdev_pri)
err);
} else {
rtc_time_to_tm((unsigned long)(tv.tv_sec), &rt_time);
- sdk_info(&pdev_pri->pcidev->dev, "Synchronize UTC time to firmware succeed. UTC time %d-%02d-%02d %02d:%02d:%02d.\n",
+ sdk_info(&pdev_pri->pcidev->dev,
+ "Synchronize UTC time to firmware succeed. UTC time %d-%02d-%02d %02d:%02d:%02d.\n",
rt_time.tm_year + HINIC3_SYNC_YEAR_OFFSET,
rt_time.tm_mon + HINIC3_SYNC_MONTH_OFFSET,
rt_time.tm_mday, rt_time.tm_hour,
@@ -448,23 +522,434 @@ static void send_event_to_all_pf(struct hinic3_pcidev *dev,
lld_put();
}
+u32 hinic3_pdev_is_virtfn(struct pci_dev *pdev)
+{
+#ifdef CONFIG_PCI_IOV
+ return pdev->is_virtfn;
+#else
+ return 0;
+#endif
+}
+
+static int hinic3_get_function_enable(struct pci_dev *pdev, bool *en)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+ int err;
+
+ /* PF in host os or function in guest os, probe sdk in default */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev) {
+ *en = true;
+ return 0;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev) {
+ /* vf in host and pf sdk not probed */
+ return -EFAULT;
+ }
+ pf_hwdev = pci_adapter->hwdev;
+
+ err = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (err) {
+ sdk_err(&pci_adapter->pcidev->dev, "Func hinic3_get_vfid_by_vfpci fail %d \n", err);
+ return err;
+ }
+
+ err = hinic3_get_func_nic_enable(pf_hwdev, global_func_id, en);
+ if (!!err) {
+ sdk_info(&pdev->dev, "Failed to get function nic status, err %d.\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+int hinic3_set_func_probe_in_host(void *hwdev, u16 func_id, bool probe)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (hinic3_func_type(hwdev) != TYPE_PPF)
+ return -EINVAL;
+
+ if (probe)
+ set_bit(func_id, dev->func_probe_in_host);
+ else
+ clear_bit(func_id, dev->func_probe_in_host);
+
+ return 0;
+}
+
+bool hinic3_get_func_probe_in_host(void *hwdev, u16 func_id)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+ bool probed = false;
+
+ if (!hwdev)
+ return false;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return false;
+ }
+
+ probed = !!test_bit(func_id, ppf_dev->func_probe_in_host);
+ up(&dev->ppf_sem);
+
+ return probed;
+}
+
+void *hinic3_get_ppf_hwdev_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ chip_node = pci_adapter->chip_node;
+ lld_dev_hold(&pci_adapter->lld_dev);
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (dev->lld_state == HINIC3_IN_REMOVE)
+ continue;
+
+ if (dev->hwdev && hinic3_func_type(dev->hwdev) == TYPE_PPF) {
+ lld_dev_put(&pci_adapter->lld_dev);
+ return dev->hwdev;
+ }
+ }
+ lld_dev_put(&pci_adapter->lld_dev);
+
+ return NULL;
+}
+
+static int hinic3_set_vf_nic_used_state(void *hwdev, u16 func_id, bool opened)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+
+ if (!dev || func_id >= MAX_FUNCTION_NUM)
+ return -EINVAL;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return -EINVAL;
+ }
+
+ if (opened)
+ set_bit(func_id, ppf_dev->netdev_setup_state);
+ else
+ clear_bit(func_id, ppf_dev->netdev_setup_state);
+
+ up(&dev->ppf_sem);
+
+ return 0;
+}
+
+static void set_vf_func_in_use(struct pci_dev *pdev, bool in_use)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+
+ /* only need to be set when VF is on the host */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev)
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev)
+ return;
+
+ pf_hwdev = pci_adapter->hwdev;
+
+ global_func_id = (u16)pdev->devfn + hinic3_glb_pf_vf_offset(pf_hwdev);
+ (void)hinic3_set_vf_nic_used_state(pf_hwdev, global_func_id, in_use);
+}
+
+static int hinic3_pf_get_vf_offset_info(struct hinic3_pcidev *des_dev, u16 *vf_offset)
+{
+ int err, i;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ u16 pf_func_id;
+ struct hinic3_pcidev *pf_pci_adapter = NULL;
+
+ pf_pci_adapter = (hinic3_pdev_is_virtfn(des_dev->pcidev)) ? pci_get_drvdata(des_dev->pcidev->physfn) : des_dev;
+ pf_func_id = hinic3_global_func_id(pf_pci_adapter->hwdev);
+ if (pf_func_id >= CMD_MAX_MAX_PF_NUM || !vf_offset)
+ return -EINVAL;
+
+ mutex_lock(&g_vf_offset_lock);
+ if (g_vf_offset.valid == 0) {
+ pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ sdk_err(&pf_pci_adapter->pcidev->dev, "Malloc pf_infos fail\n");
+ err = -ENOMEM;
+ goto err_malloc;
+ }
+
+ err = hinic3_get_hw_pf_infos(pf_pci_adapter->hwdev, pf_infos, HINIC3_CHANNEL_COMM);
+ if (err) {
+ sdk_warn(&pf_pci_adapter->pcidev->dev, "Hinic3_get_hw_pf_infos fail err %d\n", err);
+ err = -EFAULT;
+ goto err_out;
+ }
+
+ g_vf_offset.valid = 1;
+ for (i = 0; i < CMD_MAX_MAX_PF_NUM; i++) {
+ g_vf_offset.vf_offset_from_pf[i] = pf_infos->infos[i].vf_offset;
+ }
+
+ kfree(pf_infos);
+ }
+
+ *vf_offset = g_vf_offset.vf_offset_from_pf[pf_func_id];
+
+ mutex_unlock(&g_vf_offset_lock);
+
+ return 0;
+
+err_out:
+ kfree(pf_infos);
+err_malloc:
+ mutex_unlock(&g_vf_offset_lock);
+ return err;
+}
+
+static struct pci_dev *get_vf_pdev_by_pf(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ int err;
+ u16 bus_num;
+ u16 vf_start, vf_end;
+ u16 des_fn, pf_func_id, vf_offset;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ pf_func_id = hinic3_global_func_id(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end || pf_func_id >= CMD_MAX_MAX_PF_NUM)
+ return NULL;
+
+ err = hinic3_pf_get_vf_offset_info(des_dev, &vf_offset);
+ if (err) {
+ sdk_warn(&des_dev->pcidev->dev, "Hinic3_pf_get_vf_offset_info fail\n");
+ return NULL;
+ }
+
+ des_fn = ((func_id - vf_start) - 1) + pf_func_id + vf_offset;
+ bus_num = des_dev->pcidev->bus->number + des_fn / BUS_MAX_DEV_NUM;
+
+ return pci_get_domain_bus_and_slot(0, bus_num, (des_fn % BUS_MAX_DEV_NUM));
+}
+
+static struct hinic3_pcidev *get_des_pci_adapter(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ struct pci_dev *des_pdev = NULL;
+ u16 vf_start, vf_end;
+ bool probe_in_host = false;
+
+ if (hinic3_global_func_id(des_dev->hwdev) == func_id)
+ return des_dev;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end)
+ return NULL;
+
+ des_pdev = get_vf_pdev_by_pf(des_dev, func_id);
+ if (!des_pdev)
+ return NULL;
+
+ pci_dev_put(des_pdev);
+
+ probe_in_host = hinic3_get_func_probe_in_host(des_dev->hwdev, func_id);
+ if (!probe_in_host)
+ return NULL;
+
+ return pci_get_drvdata(des_pdev);
+}
+
+int __set_vroce_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ u8 enable_vroce = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_vroce_enable(pci_adapter->hwdev, func_id, &enable_vroce);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Failed to get vroce state.\n");
+ return err;
+ }
+
+ mutex_lock(&g_uld_mutex);
+
+ if (!!enable_vroce) {
+ if (!g_uld_info[SERVICE_T_ROCE].probe) {
+ sdk_info(&pdev->dev, "Uld(roce_info) has not been registered!\n");
+ mutex_unlock(&g_uld_mutex);
+ return 0;
+ }
+
+ err = attach_uld(pci_adapter, SERVICE_T_ROCE, &g_uld_info[SERVICE_T_ROCE]);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Failed to initialize VROCE.\n");
+ mutex_unlock(&g_uld_mutex);
+ return err;
+ }
+ } else {
+ sdk_info(&pdev->dev, "Func %hu vroce state: disable.\n", func_id);
+ if (g_uld_info[SERVICE_T_ROCE].remove)
+ detach_uld(pci_adapter, SERVICE_T_ROCE);
+ }
+
+ mutex_unlock(&g_uld_mutex);
+
+ return 0;
+}
+
+void slave_host_mgmt_vroce_work(struct work_struct *work)
+{
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_vroce_work);
+
+ __set_vroce_func_state(pci_adapter);
+}
+
+void *hinic3_get_roce_uld_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ return pci_adapter->uld_dev[SERVICE_T_ROCE];
+}
+
+static int __func_service_state_process(struct hinic3_pcidev *event_dev,
+ struct hinic3_pcidev *des_dev,
+ struct hinic3_mhost_nic_func_state *state, u16 cmd)
+{
+ int err = 0;
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)event_dev->hwdev;
+
+ switch (cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ state->enable = hinic3_get_roce_uld_by_pdev(des_dev->pcidev) ? 1 : 0;
+ break;
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive nic[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ if (event_dev->multi_host_mgmt_workq) {
+ queue_work(event_dev->multi_host_mgmt_workq, &des_dev->slave_nic_work);
+ } else {
+ sdk_err(&des_dev->pcidev->dev, "Can not schedule slave nic work\n");
+ err = -EFAULT;
+ }
+ break;
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive vroce[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ queue_work_on(hisdk3_get_work_cpu_affinity(dev, WORK_TYPE_MBOX),
+ event_dev->multi_host_mgmt_workq,
+ &des_dev->slave_vroce_work);
+ break;
+ default:
+ sdk_warn(&des_dev->pcidev->dev, "Service state process with unknown cmd: %u\n", cmd);
+ err = -EFAULT;
+ break;
+ }
+
+ return err;
+}
+
+static void __multi_host_mgmt(struct hinic3_pcidev *dev,
+ struct hinic3_multi_host_mgmt_event *mhost_mgmt)
+{
+ struct hinic3_pcidev *cur_dev = NULL;
+ struct hinic3_pcidev *des_dev = NULL;
+ struct hinic3_mhost_nic_func_state *nic_state = NULL;
+ u16 sub_cmd = mhost_mgmt->sub_cmd;
+
+ switch (sub_cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ nic_state = mhost_mgmt->data;
+ nic_state->status = 0;
+ if (!dev->hwdev)
+ return;
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)dev->hwdev))
+ return;
+
+ /* find func_idx pci_adapter and disable or enable nic */
+ lld_dev_hold(&dev->lld_dev);
+ list_for_each_entry(cur_dev, &dev->chip_node->func_list, node) {
+ if (cur_dev->lld_state == HINIC3_IN_REMOVE || hinic3_pdev_is_virtfn(cur_dev->pcidev))
+ continue;
+
+ des_dev = get_des_pci_adapter(cur_dev, nic_state->func_idx);
+ if (!des_dev)
+ continue;
+
+ if (__func_service_state_process(dev, des_dev, nic_state, sub_cmd))
+ nic_state->status = 1;
+ break;
+ }
+ lld_dev_put(&dev->lld_dev);
+ break;
+ default:
+ sdk_warn(&dev->pcidev->dev, "Received unknown multi-host mgmt event: %u\n",
+ mhost_mgmt->sub_cmd);
+ break;
+ }
+}
+
static void hinic3_event_process(void *adapter, struct hinic3_event_info *event)
{
struct hinic3_pcidev *dev = adapter;
struct hinic3_fault_event *fault = (void *)event->event_data;
+ struct hinic3_multi_host_mgmt_event *mhost_event = (void *)event->event_data;
u16 func_id;
- if ((event->service == EVENT_SRV_COMM && event->type == EVENT_COMM_FAULT) &&
- fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
- fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
- func_id = fault->event.chip.func_id;
- return send_event_to_dst_pf(adapter, func_id, event);
- }
-
- if (event->type == EVENT_COMM_MGMT_WATCHDOG)
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MULTI_HOST_MGMT):
+ __multi_host_mgmt(dev, mhost_event);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_FAULT):
+ if (fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
+ fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
+ func_id = fault->event.chip.func_id;
+ return send_event_to_dst_pf(adapter, func_id, event);
+ }
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MGMT_WATCHDOG):
send_event_to_all_pf(adapter, event);
- else
+ break;
+ default:
send_uld_dev_event(adapter, event);
+ break;
+ }
}
static void uld_def_init(struct hinic3_pcidev *pci_adapter)
@@ -631,36 +1116,75 @@ static void hinic3_pci_deinit(struct pci_dev *pdev)
kfree(pci_adapter);
}
-#ifdef CONFIG_X86
-/**
- * cfg_order_reg - when cpu model is haswell or broadwell, should configure dma
- * order register to zero
- * @pci_adapter: pci_adapter
- **/
-/*lint -save -e40 */
-static void cfg_order_reg(struct hinic3_pcidev *pci_adapter)
+static void set_vf_load_state(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
{
- u8 cpu_model[] = {0x3c, 0x3f, 0x45, 0x46, 0x3d, 0x47, 0x4f, 0x56};
- struct cpuinfo_x86 *cpuinfo = NULL;
- u32 i;
-
- if (hinic3_func_type(pci_adapter->hwdev) == TYPE_VF)
- return;
+ /* In bm mode, slave host will load vfs in default */
+ if (IS_BMGW_SLAVE_HOST(((struct hinic3_hwdev *)pci_adapter->hwdev)) &&
+ hinic3_func_type(pci_adapter->hwdev) != TYPE_VF)
+ hinic3_set_vf_load_state(pdev, false);
- cpuinfo = &cpu_data(0);
- for (i = 0; i < sizeof(cpu_model); i++) {
- if (cpu_model[i] == cpuinfo->x86_model)
- hinic3_set_pcie_order_cfg(pci_adapter->hwdev);
+ if (!disable_attach) {
+ if ((hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) &&
+ hinic3_is_bm_slave_host(pci_adapter->hwdev)) {
+ if (hinic3_func_max_vf(pci_adapter->hwdev) == 0) {
+ sdk_warn(&pdev->dev, "The sriov enabling process is skipped, vfs_num: 0.\n");
+ return;
+ }
+ hinic3_pci_sriov_enable(pdev, hinic3_func_max_vf(pci_adapter->hwdev));
+ }
}
}
-/*lint -restore*/
-#endif
-
-static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+static void hinic3_init_ppf_hwdev(struct hinic3_hwdev *hwdev)
{
- struct hinic3_init_para init_para = {0};
- bool cqm_init_en = false;
+ if (!hwdev) {
+ pr_err("[%s:%d] null hwdev pointer\n", __FILE__, __LINE__);
+ return;
+ }
+
+ hwdev->ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(hwdev->pcidev_hdl);
+ return;
+}
+
+static int set_nic_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ bool enable_nic = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_nic_enable(pci_adapter->hwdev, func_id, &enable_nic);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Failed to get nic state.\n");
+ return err;
+ }
+
+ if (!enable_nic) {
+ sdk_info(&pdev->dev, "Func %hu nic state: disable.\n", func_id);
+ detach_uld(pci_adapter, SERVICE_T_NIC);
+ return 0;
+ }
+
+ if (IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ (void)hinic3_init_vf_dev_cap(pci_adapter->hwdev);
+
+ if (g_uld_info[SERVICE_T_NIC].probe) {
+ err = attach_uld(pci_adapter, SERVICE_T_NIC, &g_uld_info[SERVICE_T_NIC]);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Initialize NIC failed\n");
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_init_para init_para = {0};
+ bool cqm_init_en = false;
int err;
init_para.adapter_hdl = pci_adapter;
@@ -715,7 +1239,16 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
list_add_tail(&pci_adapter->node, &pci_adapter->chip_node->func_list);
lld_unlock_chip_node();
+ hinic3_init_ppf_hwdev((struct hinic3_hwdev *)pci_adapter->hwdev);
+
+ set_vf_load_state(pdev, pci_adapter);
+
if (!disable_attach) {
+ /* NIC is base driver, probe firstly */
+ err = set_nic_func_state(pci_adapter);
+ if (err)
+ goto set_nic_func_state_err;
+
attach_ulds(pci_adapter);
if (hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) {
@@ -726,10 +1259,6 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
goto create_sysfs_err;
}
}
-
-#ifdef CONFIG_X86
- cfg_order_reg(pci_adapter);
-#endif
}
return 0;
@@ -737,6 +1266,7 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
create_sysfs_err:
detach_ulds(pci_adapter);
+set_nic_func_state_err:
lld_lock_chip_node();
list_del(&pci_adapter->node);
lld_unlock_chip_node();
@@ -785,6 +1315,7 @@ static void hinic3_func_deinit(struct pci_dev *pdev)
hinic3_free_stateful(pci_adapter->hwdev);
hinic3_free_hwdev(pci_adapter->hwdev);
+ pci_adapter->hwdev = NULL;
}
static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
@@ -806,6 +1337,49 @@ static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
} while (time_before(jiffies, end));
}
+static bool hinic3_get_vf_nic_en_status(struct pci_dev *pdev)
+{
+ bool nic_en = false;
+ u16 global_func_id;
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev) {
+ pr_err("pdev is null.\n");
+ return false;
+ }
+
+ if (pdev->is_virtfn)
+ pf_pdev = pdev->physfn;
+ else
+ return false;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return false;
+ }
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ return false;
+
+ if (hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id)) {
+ sdk_err(&pdev->dev, "Get vf id by vfpci failed\n");
+ return false;
+ }
+
+ if (hinic3_get_mhost_func_nic_enable(pci_adapter->hwdev,
+ global_func_id, &nic_en)) {
+ sdk_err(&pdev->dev, "Get function nic status failed\n");
+ return false;
+ }
+
+ sdk_info(&pdev->dev, "Func %hu %s default probe in host\n",
+ global_func_id, (nic_en) ? "enable" : "disable");
+
+ return nic_en;
+}
+
bool hinic3_get_vf_load_state(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = NULL;
@@ -860,6 +1434,8 @@ int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state)
}
EXPORT_SYMBOL(hinic3_set_vf_load_state);
+
+
bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service)
{
struct hinic3_pcidev *pci_adapter = NULL;
@@ -923,6 +1499,33 @@ int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
}
EXPORT_SYMBOL(hinic3_set_vf_service_load);
+static bool hinic3_is_host_vmsec_enable(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct pci_dev *pf_pdev = NULL;
+
+ if (pdev->is_virtfn) {
+ pf_pdev = pdev->physfn;
+ } else {
+ pf_pdev = pdev;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ pr_err("Pci_adapter is null.\n");
+ return false;
+ }
+
+ /* pf/vf used in host */
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ (hinic3_func_type(pci_adapter->hwdev) == TYPE_PF) &&
+ IS_RDMA_TYPE((struct hinic3_hwdev *)pci_adapter->hwdev)) {
+ return true;
+ }
+
+ return false;
+}
+
static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
@@ -936,6 +1539,13 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
pci_adapter->lld_state = HINIC3_IN_REMOVE;
mutex_unlock(&pci_adapter->pdev_mutex);
+ if (!(pdev->is_virtfn) && (hinic3_is_host_vmsec_enable(pdev) == true) &&
+ (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF)) {
+ cancel_delayed_work_sync(&pci_adapter->migration_probe_dwork);
+ flush_workqueue(pci_adapter->migration_probe_workq);
+ destroy_workqueue(pci_adapter->migration_probe_workq);
+ }
+
hinic3_detect_hw_present(pci_adapter->hwdev);
hisdk3_remove_pre_process(pci_adapter->hwdev);
@@ -960,23 +1570,129 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
sdk_info(&pdev->dev, "Pcie device removed function\n");
+ set_vf_func_in_use(pdev, false);
+
+ return 0;
+}
+
+int hinic3_get_vfid_by_vfpci(void *hwdev, struct pci_dev *pdev, u16 *global_func_id)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ u16 pf_bus, vf_bus, vf_offset;
+ int err;
+
+ if (!pdev || !global_func_id || !hinic3_pdev_is_virtfn(pdev))
+ return -EINVAL;
+ (void)hwdev;
+ pf_pdev = pdev->physfn;
+
+ vf_bus = pdev->bus->number;
+ pf_bus = pf_pdev->bus->number;
+
+ if (pdev->vendor == HINIC3_VIRTIO_VNEDER_ID) {
+ return -EPERM;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return -EINVAL;
+ }
+
+ err = hinic3_pf_get_vf_offset_info(pci_adapter, &vf_offset);
+ if (err) {
+ sdk_err(&pdev->dev, "Func hinic3_pf_get_vf_offset_info fail\n");
+ return -EFAULT;
+ }
+
+ *global_func_id = (u16)((vf_bus - pf_bus) * BUS_MAX_DEV_NUM) + (u16)pdev->devfn +
+ (u16)(CMD_MAX_MAX_PF_NUM - g_vf_offset.vf_offset_from_pf[0]);
+
return 0;
}
+EXPORT_SYMBOL(hinic3_get_vfid_by_vfpci);
+
+static void hinic3_set_vf_status_in_host(struct pci_dev *pdev, bool status)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ void *ppf_hwdev = NULL;
+ u16 global_func_id;
+ int ret;
+
+ if (!pf_pdev)
+ return;
+
+ if (!hinic3_pdev_is_virtfn(pdev))
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ pf_hwdev = pci_adapter->hwdev;
+ ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(pf_pdev);
+ if (!pf_hwdev || !ppf_hwdev)
+ return;
+
+ ret = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (ret) {
+ sdk_err(&pci_adapter->pcidev->dev, "Func hinic3_get_vfid_by_vfpci fail %d \n", ret);
+ return;
+ }
+
+ ret = hinic3_set_func_probe_in_host(ppf_hwdev, global_func_id, status);
+ if (ret)
+ sdk_err(&pci_adapter->pcidev->dev, "Set the function probe status in host failed\n");
+}
+#ifdef CONFIG_PCI_IOV
+static bool check_pdev_type_and_state(struct pci_dev *pdev)
+{
+ if (!(pdev->is_virtfn)) {
+ return false;
+ }
+
+ if ((hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_1_PF) &&
+ (hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_0_PF)) {
+ return false;
+ }
+
+ if (!hinic3_get_vf_load_state(pdev)) {
+ return false;
+ }
+
+ return true;
+}
+#endif
static void hinic3_remove(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
+ sdk_info(&pdev->dev, "Pcie device remove begin\n");
+
if (!pci_adapter)
- return;
+ goto out;
+#ifdef CONFIG_PCI_IOV
+ if (check_pdev_type_and_state(pdev)) {
+ goto out;
+ }
+#endif
- sdk_info(&pdev->dev, "Pcie device remove begin\n");
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
hinic3_remove_func(pci_adapter);
+ if (!pci_adapter->pcidev->is_virtfn &&
+ pci_adapter->multi_host_mgmt_workq)
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
+
hinic3_pci_deinit(pdev);
hinic3_probe_pre_unprocess(pdev);
+out:
+ hinic3_set_vf_status_in_host(pdev, false);
+
sdk_info(&pdev->dev, "Pcie device removed\n");
}
@@ -995,7 +1711,7 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
if (pci_adapter->lld_state >= HINIC3_PROBE_START) {
sdk_warn(&pdev->dev, "Don not probe repeat\n");
mutex_unlock(&pci_adapter->pdev_mutex);
- return 0;
+ return -EEXIST;
}
pci_adapter->lld_state = HINIC3_PROBE_START;
mutex_unlock(&pci_adapter->pdev_mutex);
@@ -1003,15 +1719,28 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
return 0;
}
+static void hinic3_probe_success_process(struct hinic3_pcidev *pci_adapter)
+{
+ hinic3_probe_success(pci_adapter->hwdev);
+
+ mutex_lock(&pci_adapter->pdev_mutex);
+ pci_adapter->lld_state = HINIC3_PROBE_OK;
+ mutex_unlock(&pci_adapter->pdev_mutex);
+}
+
static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
int err;
err = probe_func_param_init(pci_adapter);
- if (err)
+ if (err == -EEXIST)
+ return 0;
+ else if (err)
return err;
+ set_vf_func_in_use(pdev, true);
+
err = mapping_bar(pdev, pci_adapter);
if (err) {
sdk_err(&pdev->dev, "Failed to map bar\n");
@@ -1043,11 +1772,7 @@ static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
}
}
- hinic3_probe_success(pci_adapter->hwdev);
-
- mutex_lock(&pci_adapter->pdev_mutex);
- pci_adapter->lld_state = HINIC3_PROBE_OK;
- mutex_unlock(&pci_adapter->pdev_mutex);
+ hinic3_probe_success_process(pci_adapter);
return 0;
@@ -1063,18 +1788,299 @@ alloc_chip_node_fail:
unmapping_bar(pci_adapter);
map_bar_failed:
+ set_vf_func_in_use(pdev, false);
sdk_err(&pdev->dev, "Pcie device probe function failed\n");
return err;
}
+void hinic3_set_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int err;
+ bool enable_func = false;
+
+ err = hinic3_get_function_enable(pdev, &enable_func);
+ if (err) {
+ sdk_info(&pdev->dev, "Get function enable failed\n");
+ return;
+ }
+
+ sdk_info(&pdev->dev, "%s function resource start\n",
+ enable_func ? "Initialize" : "Free");
+ if (enable_func) {
+ err = hinic3_probe_func(pci_adapter);
+ if (err)
+ sdk_info(&pdev->dev, "Function probe failed\n");
+ } else {
+ hinic3_remove_func(pci_adapter);
+ }
+ if (err == 0)
+ sdk_info(&pdev->dev, "%s function resource end\n",
+ enable_func ? "Initialize" : "Free");
+}
+
+void slave_host_mgmt_work(struct work_struct *work)
+{
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_nic_work);
+
+ if (hinic3_pdev_is_virtfn(pci_adapter->pcidev))
+ hinic3_set_func_state(pci_adapter);
+ else
+ set_nic_func_state(pci_adapter);
+}
+
+static int pci_adapter_assign_val(struct hinic3_pcidev **ppci_adapter,
+ struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ *ppci_adapter = pci_get_drvdata(pdev);
+ (*ppci_adapter)->disable_vf_load = disable_vf_load;
+ (*ppci_adapter)->id = *id;
+ (*ppci_adapter)->lld_state = HINIC3_NOT_PROBE;
+ (*ppci_adapter)->probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ lld_dev_cnt_init(*ppci_adapter);
+
+ (*ppci_adapter)->multi_host_mgmt_workq =
+ alloc_workqueue("hinic_mhost_mgmt", WQ_UNBOUND,
+ HINIC3_SLAVE_WORK_MAX_NUM);
+ if (!(*ppci_adapter)->multi_host_mgmt_workq) {
+ hinic3_pci_deinit(pdev);
+ sdk_err(&pdev->dev, "Alloc multi host mgmt workqueue failed\n");
+ return -ENOMEM;
+ }
+
+ INIT_WORK(&(*ppci_adapter)->slave_nic_work, slave_host_mgmt_work);
+ INIT_WORK(&(*ppci_adapter)->slave_vroce_work,
+ slave_host_mgmt_vroce_work);
+
+ return 0;
+}
+
+static void slave_host_vfio_probe_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_pcidev *pci_adapter = container_of(delay, struct hinic3_pcidev, migration_probe_dwork);
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int (*dev_migration_probe)(struct pci_dev *);
+ int rc;
+
+ if (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) != TYPE_PF) {
+ return;
+ }
+
+ dev_migration_probe = __symbol_get("migration_dev_migration_probe");
+ if (!(dev_migration_probe)) {
+ sdk_err(&pdev->dev,
+ "Failed to find: migration_dev_migration_probe");
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork, WAIT_TIME * HZ);
+ } else {
+ rc = dev_migration_probe(pdev);
+ __symbol_put("migration_dev_migration_probe");
+ if (rc) {
+ sdk_err(&pdev->dev,
+ "Failed to __dev_migration_probe, rc:0x%x, pf migrated(%d).\n",
+ rc, g_is_pf_migrated);
+ } else {
+ g_is_pf_migrated = true;
+ sdk_info(&pdev->dev,
+ "Successed in __dev_migration_probe, pf migrated(%d).\n",
+ g_is_pf_migrated);
+ }
+ }
+
+ return;
+}
+
+struct vf_add_delaywork {
+ struct pci_dev *vf_pdev;
+ struct delayed_work migration_vf_add_dwork;
+};
+
+static void slave_host_migration_vf_add_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct vf_add_delaywork *vf_add = container_of(delay, struct vf_add_delaywork, migration_vf_add_dwork);
+ struct pci_dev *vf_pdev = vf_add->vf_pdev;
+ struct pci_dev *pf_pdev = NULL;
+ int (*migration_dev_add_vf)(struct pci_dev *);
+ int ret;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!vf_pdev) {
+ pr_err("vf pdev is null.\n");
+ goto err1;
+ }
+ if (!vf_pdev->is_virtfn) {
+ sdk_err(&vf_pdev->dev, "Pdev is not virtfn.\n");
+ goto err1;
+ }
+
+ pf_pdev = vf_pdev->physfn;
+ if (!pf_pdev) {
+ sdk_err(&vf_pdev->dev, "pf_pdev is null.\n");
+ goto err1;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&vf_pdev->dev, "Pci_adapter is null.\n");
+ goto err1;
+ }
+
+ if (!g_is_pf_migrated) {
+ sdk_info(&vf_pdev->dev, "pf is not migrated yet, so vf continues to try again.\n");
+ goto delay_work;
+ }
+
+ migration_dev_add_vf = __symbol_get("migration_dev_add_vf");
+ if (migration_dev_add_vf) {
+ ret = migration_dev_add_vf(vf_pdev);
+ __symbol_put("migration_dev_add_vf");
+ if (ret) {
+ sdk_err(&vf_pdev->dev,
+ "vf get migration symbol successed, but dev add vf failed, ret:%d.\n",
+ ret);
+ } else {
+ sdk_info(&vf_pdev->dev,
+ "vf get migration symbol successed, and dev add vf success.\n");
+ }
+ goto err1;
+ }
+ sdk_info(&vf_pdev->dev, "pf is migrated, but vf get migration symbol failed.\n");
+
+delay_work:
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork, WAIT_TIME * HZ);
+ return;
+
+err1:
+ kfree(vf_add);
+ return;
+}
+
+static void hinic3_probe_vf_add_dwork(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!hinic3_is_host_vmsec_enable(pdev)) {
+ return;
+ }
+
+#if defined(CONFIG_SP_VID_DID)
+ if ((pdev->vendor == PCI_VENDOR_ID_SPNIC) && (pdev->device == HINIC3_DEV_SDI_5_1_ID_VF)) {
+#elif defined(CONFIG_NF_VID_DID)
+ if ((pdev->vendor == PCI_VENDOR_ID_NF) && (pdev->device == NFNIC_DEV_ID_VF)) {
+#else
+ if ((pdev->vendor == PCI_VENDOR_ID_HUAWEI) && (pdev->device == HINIC3_DEV_SDI_5_0_ID_VF)) {
+#endif
+ struct vf_add_delaywork *vf_add = kmalloc(sizeof(struct vf_add_delaywork), GFP_ATOMIC);
+ if (!vf_add) {
+ sdk_info(&pdev->dev, "vf_add is null.\n");
+ return;
+ }
+ vf_add->vf_pdev = pdev;
+
+ pf_pdev = pdev->physfn;
+
+ if (!pf_pdev) {
+ sdk_info(&pdev->dev, "Vf-pf_pdev is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_info(&pdev->dev, "Pci_adapter is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ INIT_DELAYED_WORK(&vf_add->migration_vf_add_dwork,
+ slave_host_migration_vf_add_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork,
+ WAIT_TIME * HZ);
+ }
+
+ return;
+}
+
+static int hinic3_probe_migration_dwork(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+{
+ if (!hinic3_is_host_vmsec_enable(pdev)) {
+ sdk_info(&pdev->dev, "Probe_migration : hinic3_is_host_vmsec_enable is (0).\n");
+ return 0;
+ }
+
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF) {
+ pci_adapter->migration_probe_workq =
+ create_singlethread_workqueue("hinic3_migration_probe_delay");
+ if (!pci_adapter->migration_probe_workq) {
+ sdk_err(&pdev->dev, "Failed to create work queue:%s\n",
+ "hinic3_migration_probe_delay");
+ return -EINVAL;
+ }
+
+ INIT_DELAYED_WORK(&pci_adapter->migration_probe_dwork,
+ slave_host_vfio_probe_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork, WAIT_TIME * HZ);
+ }
+
+ return 0;
+}
+
+static bool hinic3_os_hot_replace_allow(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_hwdev *hwdev = (struct hinic3_hwdev *)pci_adapter->hwdev;
+ // check service enable and dev is not VF
+ if (hinic3_func_type(hwdev) == TYPE_VF || hwdev->hot_replace_mode == HOT_REPLACE_DISABLE)
+ return false;
+
+ return true;
+}
+
+static bool hinic3_os_hot_replace_process(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_board_info *board_info;
+ u16 cur_pf_id = hinic3_global_func_id(pci_adapter->hwdev);
+ u8 cur_partion_id;
+ board_info = &((struct hinic3_hwdev *)(pci_adapter->hwdev))->board_info;
+ // probe to os
+ vpci_set_partition_attrs(pci_adapter->pcidev, PARTITION_DEV_EXCLUSIVE,
+ get_function_partition(cur_pf_id, board_info->port_num));
+
+ // check pf_id is in the right partition_id
+ cur_partion_id = get_partition_id();
+ if (get_function_partition(cur_pf_id, board_info->port_num) == cur_partion_id) {
+ return true;
+ }
+
+ pci_adapter->probe_fault_level = FAULT_LEVEL_SUGGESTION;
+ return false;
+}
+
static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct hinic3_pcidev *pci_adapter = NULL;
u16 probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ u32 device_id, function_id;
int err;
sdk_info(&pdev->dev, "Pcie device probe begin\n");
-
+#ifdef CONFIG_PCI_IOV
+ hinic3_set_vf_status_in_host(pdev, true);
+ if (check_pdev_type_and_state(pdev)) {
+ sdk_info(&pdev->dev, "VFs are not binded to hinic\n");
+ hinic3_probe_vf_add_dwork(pdev);
+ return -EINVAL;
+ }
+#endif
err = hinic3_probe_pre_process(pdev);
if (err != 0 && err != HINIC3_NOT_PROBE)
goto out;
@@ -1082,33 +2088,53 @@ static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (err == HINIC3_NOT_PROBE)
return 0;
- err = hinic3_pci_init(pdev);
- if (err)
+ if (hinic3_pci_init(pdev))
goto pci_init_err;
- pci_adapter = pci_get_drvdata(pdev);
- pci_adapter->disable_vf_load = disable_vf_load;
- pci_adapter->id = *id;
- pci_adapter->lld_state = HINIC3_NOT_PROBE;
- pci_adapter->probe_fault_level = probe_fault_level;
- lld_dev_cnt_init(pci_adapter);
+ if (pci_adapter_assign_val(&pci_adapter, pdev, id))
+ goto allco_queue_err;
- if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev))) {
+ if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev)) &&
+ (!hinic3_get_vf_nic_en_status(pdev))) {
sdk_info(&pdev->dev, "VF device disable load in host\n");
return 0;
}
- err = hinic3_probe_func(pci_adapter);
- if (err)
+ if (hinic3_probe_func(pci_adapter))
+ goto hinic3_probe_func_fail;
+
+ if (hinic3_os_hot_replace_allow(pci_adapter)) {
+ if (!hinic3_os_hot_replace_process(pci_adapter)) {
+ device_id = PCI_SLOT(pdev->devfn);
+ function_id = PCI_FUNC(pdev->devfn);
+ sdk_info(&pdev->dev,
+ "os hot replace: skip function %d:%d for partition %d",
+ device_id, function_id, get_partition_id());
+ goto os_hot_repalce_not_allow;
+ }
+ }
+
+ if (hinic3_probe_migration_dwork(pdev, pci_adapter))
goto hinic3_probe_func_fail;
sdk_info(&pdev->dev, "Pcie device probed\n");
return 0;
+os_hot_repalce_not_allow:
+ hinic3_func_deinit(pdev);
+ lld_lock_chip_node();
+ free_chip_node(pci_adapter);
+ lld_unlock_chip_node();
+ unmapping_bar(pci_adapter);
+ set_vf_func_in_use(pdev, false);
+
hinic3_probe_func_fail:
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
+allco_queue_err:
probe_fault_level = pci_adapter->probe_fault_level;
hinic3_pci_deinit(pdev);
-
pci_init_err:
hinic3_probe_pre_unprocess(pdev);
@@ -1131,6 +2157,10 @@ static int hinic3_get_pf_info(struct pci_dev *pdev, u16 service,
}
*pf_infos = kzalloc(sizeof(struct hinic3_hw_pf_infos), GFP_KERNEL);
+ if (*pf_infos == NULL) {
+ sdk_err(&pdev->dev, "pf_infos kzalloc failed\n");
+ return -EFAULT;
+ }
err = hinic3_get_hw_pf_infos(dev->hwdev, *pf_infos, HINIC3_CHANNEL_COMM);
if (err) {
kfree(*pf_infos);
@@ -1146,6 +2176,7 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
{
int err;
+ mutex_lock(&dst_dev->pdev_mutex);
/* unload invalid vf func id */
if (!en && vf_func_id != hinic3_global_func_id(dst_dev->hwdev) &&
!strcmp(des_pdev->driver->name, HINIC3_DRV_NAME)) {
@@ -1163,6 +2194,8 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
err = hinic3_probe_func(dst_dev);
if (err)
return -EFAULT;
+ } else {
+ mutex_unlock(&dst_dev->pdev_mutex);
}
return 0;
@@ -1187,7 +2220,6 @@ static int get_vf_service_state_param(struct pci_dev *pdev, struct hinic3_pcidev
return 0;
}
-#define BUS_MAX_DEV_NUM 256
static int hinic3_dst_pdev_valid(struct hinic3_pcidev *dst_dev, struct pci_dev **des_pdev_ptr,
u16 vf_devfn, bool en)
{
@@ -1245,7 +2277,7 @@ int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id, u16 servic
lld_hold();
list_for_each_entry(dst_dev, &dev->chip_node->func_list, node) {
- if (paramerter_is_unexpected(dst_dev, &func_id, &vf_start, &vf_end, vf_func_id))
+ if (paramerter_is_unexpected(dst_dev, &func_id, &vf_start, &vf_end, vf_func_id) != 0)
continue;
vf_devfn = pf_infos->infos[func_id].vf_offset + (vf_func_id - vf_start) +
@@ -1269,7 +2301,6 @@ int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id, u16 servic
if (en)
pci_dev_put(des_pdev);
- mutex_lock(&dst_dev->pdev_mutex);
find_dst_dev = true;
break;
}
@@ -1289,19 +2320,18 @@ free_pf_info:
}
EXPORT_SYMBOL(hinic3_set_vf_service_state);
-/*lint -save -e133 -e10*/
static const struct pci_device_id hinic3_pci_table[] = {
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SPU), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_STANDARD), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_1_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_SDI_5_1_ID_VF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_VF), 0},
{0, 0}
};
-/*lint -restore*/
-
MODULE_DEVICE_TABLE(pci, hinic3_pci_table);
/**
@@ -1333,14 +2363,27 @@ static pci_ers_result_t hinic3_io_error_detected(struct pci_dev *pdev,
return PCI_ERS_RESULT_CAN_RECOVER;
}
+static void hinic3_timer_disable(void *hwdev)
+{
+ if (!hwdev)
+ return;
+
+ if (hinic3_get_stateful_enable(hwdev) && hinic3_get_timer_enable(hwdev))
+ (void)hinic3_func_tmr_bitmap_set(hwdev, hinic3_global_func_id(hwdev), false);
+
+ return;
+}
+
static void hinic3_shutdown(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
sdk_info(&pdev->dev, "Shutdown device\n");
- if (pci_adapter)
+ if (pci_adapter) {
+ hinic3_timer_disable(pci_adapter->hwdev);
hinic3_shutdown_hwdev(pci_adapter->hwdev);
+ }
pci_disable_device(pdev);
@@ -1367,6 +2410,9 @@ static struct pci_driver hinic3_driver = {
.probe = hinic3_probe,
.remove = hinic3_remove,
.shutdown = hinic3_shutdown,
+#ifdef CONFIG_PARTITION_DEVICE
+ .driver.probe_concurrency = true,
+#endif
#if defined(HAVE_SRIOV_CONFIGURE)
.sriov_configure = hinic3_pci_sriov_configure,
#elif defined(HAVE_RHEL6_SRIOV_CONFIGURE)
@@ -1388,16 +2434,21 @@ int hinic3_lld_init(void)
err = hinic3_module_pre_init();
if (err) {
pr_err("Init custom failed\n");
- return err;
+ goto module_pre_init_err;
}
err = pci_register_driver(&hinic3_driver);
if (err) {
- hinic3_module_post_exit();
- return err;
+ pr_err("sdk3 pci register driver failed\n");
+ goto register_pci_driver_err;
}
return 0;
+
+register_pci_driver_err:
+ hinic3_module_post_exit();
+module_pre_init_err:
+ return err;
}
void hinic3_lld_exit(void)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
index d2a7dd7..5398a34 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
@@ -584,6 +584,7 @@ static void free_recv_mbox(struct hinic3_recv_mbox *recv_msg)
kfree(recv_msg->resp_buff);
kfree(recv_msg->msg);
kfree(recv_msg);
+ recv_msg = NULL;
}
static void recv_func_mbox_work_handler(struct work_struct *work)
@@ -1233,6 +1234,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
set_mbox_to_func_event(func_to_func, EVENT_FAIL);
goto send_err;
}
+ func_to_func->hwdev->mbox_send_cnt++;
if (wait_mbox_msg_completion(func_to_func, timeout) != 0) {
sdk_err(func_to_func->hwdev->dev_hdl,
@@ -1241,6 +1243,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
err = -ETIMEDOUT;
goto send_err;
}
+ func_to_func->hwdev->mbox_ack_cnt++;
if (mod != msg_desc->mod || cmd != msg_desc->cmd) {
sdk_err(func_to_func->hwdev->dev_hdl,
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
index 3ad9a77..0d75177 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
@@ -348,7 +348,7 @@ int hinic3_pf_to_mgmt_sync(void *hwdev, u8 mod, u16 cmd, void *buf_in,
if (!COMM_SUPPORT_API_CHAIN((struct hinic3_hwdev *)hwdev))
return -EPERM;
- if (!buf_in || in_size == 0)
+ if ((buf_in == NULL) || (in_size == 0))
return -EINVAL;
ret = msg_to_mgmt_pre(mod, buf_in, in_size);
@@ -864,6 +864,7 @@ static int alloc_recv_msg(struct hinic3_recv_msg *recv_msg)
static void free_recv_msg(struct hinic3_recv_msg *recv_msg)
{
kfree(recv_msg->msg);
+ recv_msg->msg = NULL;
}
/**
@@ -935,6 +936,9 @@ static void free_msg_buf(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt)
free_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
+ pf_to_mgmt->mgmt_ack_buf = NULL;
+ pf_to_mgmt->sync_msg_buf = NULL;
+ pf_to_mgmt->async_msg_buf = NULL;
}
/**
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
index 3548410..b619800 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
@@ -676,6 +676,11 @@ static int hinic3_register_slave_ppf(struct hinic3_hwdev *hwdev, bool registered
if (!IS_SLAVE_HOST(hwdev))
return -EINVAL;
+ /* if unsupport hot plug, return true. */
+ if (UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev)) {
+ return 0;
+ }
+
host_info = kcalloc(1, sizeof(struct register_slave_host), GFP_KERNEL);
if (!host_info)
return -ENOMEM;
@@ -1074,8 +1079,9 @@ int hinic3_get_func_nic_enable(void *hwdev, u16 glb_func_idx, bool *en)
if (!hwdev || !en)
return -EINVAL;
- /* if single host, return true. */
- if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev)) {
+ /* if single host or unsupport hot plug, return true. */
+ if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev) ||
+ UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev)) {
*en = true;
return 0;
}
@@ -1145,11 +1151,18 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
{
int err;
struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+ int is_use_vram, is_in_kexec;
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
- hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0) {
+ snprintf(hwdev->mhost_mgmt_name, VRAM_NAME_MAX_LEN, "%s", VRAM_NIC_MHOST_MGMT);
+ hwdev->mhost_mgmt = hi_vram_kalloc(hwdev->mhost_mgmt_name, sizeof(*hwdev->mhost_mgmt));
+ } else {
+ hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ }
if (!hwdev->mhost_mgmt)
return -ENOMEM;
@@ -1165,8 +1178,11 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK, hwdev, hilink_ppf_mbox_handler);
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC, hwdev, sw_func_ppf_mbox_handler);
- bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
- bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ }
/* Slave host:
* register slave host ppf functions
@@ -1179,7 +1195,13 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
return 0;
out_free_mhost_mgmt:
- kfree(hwdev->mhost_mgmt);
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)hwdev->mhost_mgmt,
+ hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ } else {
+ kfree(hwdev->mhost_mgmt);
+ }
hwdev->mhost_mgmt = NULL;
return err;
@@ -1187,6 +1209,7 @@ out_free_mhost_mgmt:
int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
{
+ int is_use_vram;
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
@@ -1203,7 +1226,14 @@ int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC);
- kfree(hwdev->mhost_mgmt);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)hwdev->mhost_mgmt,
+ hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ } else {
+ kfree(hwdev->mhost_mgmt);
+ }
hwdev->mhost_mgmt = NULL;
return 0;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
index f7d350c..ee7afef 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
@@ -14,6 +14,7 @@
#include "hinic3_crm.h"
#include "hinic3_hw.h"
#include "hinic3_hw_cfg.h"
+#include "hinic3_dev_mgmt.h"
#include "hinic3_hwdev.h"
#include "hinic3_lld.h"
#include "hinic3_hw_mt.h"
@@ -22,9 +23,7 @@
static int g_nictool_ref_cnt;
static dev_t g_dev_id = {0};
-/*lint -save -e104 -e808*/
static struct class *g_nictool_class;
-/*lint -restore*/
static struct cdev g_nictool_cdev;
#define HINIC3_MAX_BUF_SIZE (2048 * 1024)
@@ -92,6 +91,21 @@ static int get_all_chip_id_cmd(struct hinic3_lld_dev *lld_dev, const void *buf_i
return 0;
}
+static int get_os_hot_replace_info(struct hinic3_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ if (*out_size != sizeof(struct os_hot_replace_info) || !buf_out) {
+ pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
+ *out_size, sizeof(struct os_hot_replace_info));
+ return -EFAULT;
+ }
+
+ hinic3_get_os_hot_replace_info(buf_out);
+
+ return 0;
+}
+
static int get_card_usr_api_chain_mem(int card_idx)
{
unsigned char *tmp = NULL;
@@ -100,8 +114,8 @@ static int get_card_usr_api_chain_mem(int card_idx)
card_id = card_idx;
if (!g_card_vir_addr[card_idx]) {
g_card_vir_addr[card_idx] =
- (void *)__get_free_pages(GFP_KERNEL,
- DBGTOOL_PAGE_ORDER);
+ (void *)ossl_get_free_pages(GFP_KERNEL,
+ DBGTOOL_PAGE_ORDER);
if (!g_card_vir_addr[card_idx]) {
pr_err("Alloc api chain memory fail for card %d!\n", card_idx);
return -EFAULT;
@@ -166,7 +180,7 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
if (!buf_out || *out_size != sizeof(struct pf_dev_info) * PF_DEV_INFO_NUM) {
pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
- *out_size, sizeof(dev_info) * PF_DEV_INFO_NUM);
+ *out_size, sizeof(*dev_info) * PF_DEV_INFO_NUM);
return -EFAULT;
}
@@ -193,13 +207,18 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
return 0;
}
-static long dbgtool_knl_free_mem(int id)
+static void dbgtool_knl_free_mem(int id)
{
unsigned char *tmp = NULL;
int i;
+ if (id < 0 || id >= MAX_CARD_NUM) {
+ pr_err("Invalid card id\n");
+ return;
+ }
+
if (!g_card_vir_addr[id])
- return 0;
+ return;
tmp = g_card_vir_addr[id];
for (i = 0; i < (1 << DBGTOOL_PAGE_ORDER); i++) {
@@ -210,8 +229,6 @@ static long dbgtool_knl_free_mem(int id)
free_pages((unsigned long)g_card_vir_addr[id], DBGTOOL_PAGE_ORDER);
g_card_vir_addr[id] = NULL;
g_card_phy_addr[id] = 0;
-
- return 0;
}
static int free_knl_mem(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_size,
@@ -236,7 +253,8 @@ static int free_knl_mem(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32
return 0;
}
-static int card_info_param_valid(char *dev_name, const void *buf_out, u32 buf_out_size, int *id)
+static int card_info_param_valid(const char *dev_name, const void *buf_out,
+ u32 buf_out_size, int *id)
{
int err;
@@ -351,7 +369,7 @@ static int get_hw_drv_version(struct hinic3_lld_dev *lld_dev, const void *buf_in
}
err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s", HINIC3_DRV_VERSION,
- "2023-05-17_19:56:38");
+ "2025-05-01_00:00:03");
if (err < 0)
return -EINVAL;
@@ -386,22 +404,38 @@ static int get_pf_id(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_
return 0;
}
+static int get_mbox_cnt(struct hinic3_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ if (buf_out == NULL || *out_size != sizeof(struct card_mbox_cnt_info)) {
+ pr_err("buf_out is NULL, or out_size != %lu\n",
+ sizeof(struct card_info));
+ return -EINVAL;
+ }
+
+ hinic3_get_mbox_cnt(hinic3_get_sdk_hwdev_by_lld(lld_dev), buf_out);
+
+ return 0;
+}
+
struct hw_drv_module_handle hw_driv_module_cmd_handle[] = {
- {FUNC_TYPE, get_func_type},
- {GET_FUNC_IDX, get_func_id},
- {GET_HW_STATS, (hw_driv_module)get_hw_driver_stats},
- {CLEAR_HW_STATS, clear_hw_driver_stats},
- {GET_SELF_TEST_RES, get_self_test_result},
- {GET_CHIP_FAULT_STATS, (hw_driv_module)get_chip_faults_stats},
- {GET_SINGLE_CARD_INFO, (hw_driv_module)get_single_card_info},
- {IS_DRV_IN_VM, is_driver_in_vm},
- {GET_CHIP_ID, get_all_chip_id_cmd},
- {GET_PF_DEV_INFO, get_pf_dev_info},
- {CMD_FREE_MEM, free_knl_mem},
- {GET_CHIP_INFO, get_card_func_info},
- {GET_FUNC_CAP, get_pf_cap_info},
- {GET_DRV_VERSION, get_hw_drv_version},
- {GET_PF_ID, get_pf_id},
+ {FUNC_TYPE, get_func_type},
+ {GET_FUNC_IDX, get_func_id},
+ {GET_HW_STATS, (hw_driv_module)get_hw_driver_stats},
+ {CLEAR_HW_STATS, clear_hw_driver_stats},
+ {GET_SELF_TEST_RES, get_self_test_result},
+ {GET_CHIP_FAULT_STATS, (hw_driv_module)get_chip_faults_stats},
+ {GET_SINGLE_CARD_INFO, (hw_driv_module)get_single_card_info},
+ {IS_DRV_IN_VM, is_driver_in_vm},
+ {GET_CHIP_ID, get_all_chip_id_cmd},
+ {GET_PF_DEV_INFO, get_pf_dev_info},
+ {CMD_FREE_MEM, free_knl_mem},
+ {GET_CHIP_INFO, get_card_func_info},
+ {GET_FUNC_CAP, get_pf_cap_info},
+ {GET_DRV_VERSION, get_hw_drv_version},
+ {GET_PF_ID, get_pf_id},
+ {GET_OS_HOT_REPLACE_INFO, get_os_hot_replace_info},
+ {GET_MBOX_CNT, (hw_driv_module)get_mbox_cnt},
};
static int alloc_tmp_buf(void *hwdev, struct msg_module *nt_msg, u32 in_size,
@@ -439,8 +473,8 @@ static void free_tmp_buf(void *hwdev, struct msg_module *nt_msg,
static int send_to_hw_driver(struct hinic3_lld_dev *lld_dev, struct msg_module *nt_msg,
const void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(hw_driv_module_cmd_handle) /
- sizeof(hw_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(hw_driv_module_cmd_handle) /
+ sizeof(hw_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type =
(enum driver_cmd_type)(nt_msg->msg_formate);
int err = 0;
@@ -482,8 +516,8 @@ static int send_to_service_driver(struct hinic3_lld_dev *lld_dev, struct msg_mod
if (nt_msg->msg_formate == GET_DRV_VERSION)
return 0;
- pr_err("Can not get the uld dev correctly: %s, %s driver may be not register\n",
- nt_msg->device_name, service_name[type]);
+ pr_err("Can not get the uld dev correctly: %s driver may be not register\n",
+ service_name[type]);
return -EINVAL;
}
@@ -550,26 +584,29 @@ static struct hinic3_lld_dev *get_lld_dev_by_nt_msg(struct msg_module *nt_msg)
{
struct hinic3_lld_dev *lld_dev = NULL;
- if (nt_msg->module >= SEND_TO_SRV_DRV_BASE && nt_msg->module < SEND_TO_DRIVER_MAX &&
- nt_msg->module != SEND_TO_HW_DRIVER && nt_msg->msg_formate != GET_DRV_VERSION) {
+ if (nt_msg->module == SEND_TO_NIC_DRIVER &&
+ (nt_msg->msg_formate == GET_XSFP_INFO ||
+ nt_msg->msg_formate == GET_XSFP_PRESENT ||
+ nt_msg->msg_formate == GET_XSFP_INFO_COMP_CMIS)) {
+ lld_dev = hinic3_get_lld_dev_by_chip_and_port(nt_msg->device_name, nt_msg->port_id);
+ } else if (nt_msg->module == SEND_TO_CUSTOM_DRIVER &&
+ nt_msg->msg_formate == CMD_CUSTOM_BOND_GET_CHIP_NAME) {
+ lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
+ SERVICE_T_MAX);
+ } else if (nt_msg->module == SEND_TO_VBS_DRIVER ||
+ nt_msg->module == SEND_TO_BIFUR_DRIVER) {
+ lld_dev = hinic3_get_lld_dev_by_chip_name(nt_msg->device_name);
+ } else if (nt_msg->module >= SEND_TO_SRV_DRV_BASE &&
+ nt_msg->module < SEND_TO_DRIVER_MAX &&
+ nt_msg->msg_formate != GET_DRV_VERSION) {
lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
nt_msg->module - SEND_TO_SRV_DRV_BASE);
} else {
lld_dev = hinic3_get_lld_dev_by_chip_name(nt_msg->device_name);
if (!lld_dev)
- lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
- SERVICE_T_MAX);
+ lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name, SERVICE_T_MAX);
}
- if (nt_msg->module == SEND_TO_NIC_DRIVER && (nt_msg->msg_formate == GET_XSFP_INFO ||
- nt_msg->msg_formate == GET_XSFP_PRESENT))
- lld_dev = hinic3_get_lld_dev_by_chip_and_port(nt_msg->device_name,
- nt_msg->port_id);
-
- if (nt_msg->module == SEND_TO_CUSTOM_DRIVER &&
- nt_msg->msg_formate == CMD_CUSTOM_BOND_GET_CHIP_NAME)
- lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name, SERVICE_T_MAX);
-
return lld_dev;
}
@@ -591,14 +628,16 @@ static long hinicadm_k_unlocked_ioctl(struct file *pfile, unsigned long arg)
lld_dev = get_lld_dev_by_nt_msg(&nt_msg);
if (!lld_dev) {
if (nt_msg.msg_formate != DEV_NAME_TEST)
- pr_err("Can not find device %s for module %d\n",
+ pr_err("Can not find device %s for module %u\n",
nt_msg.device_name, nt_msg.module);
return -ENODEV;
}
- if (nt_msg.msg_formate == DEV_NAME_TEST)
+ if (nt_msg.msg_formate == DEV_NAME_TEST) {
+ lld_dev_put(lld_dev);
return 0;
+ }
ret = alloc_tmp_buf(hinic3_get_sdk_hwdev_by_lld(lld_dev), &nt_msg,
in_size, &buf_in, out_size_expect, &buf_out);
@@ -642,6 +681,9 @@ out_free_lock:
static long dbgtool_knl_ffm_info_rd(struct dbgtool_param *para,
struct dbgtool_k_glb_info *dbgtool_info)
{
+ if (!para->param.ffm_rd || !dbgtool_info->ffm)
+ return -EINVAL;
+
/* Copy the ffm_info to user mode */
if (copy_to_user(para->param.ffm_rd, dbgtool_info->ffm,
(unsigned int)sizeof(struct ffm_record_info))) {
@@ -674,13 +716,14 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
card_info = (struct card_node *)g_card_node_array[i];
if (!card_info)
continue;
- if (!strncmp(param.chip_name, card_info->chip_name, IFNAMSIZ))
+ if (memcmp(param.chip_name, card_info->chip_name,
+ strlen(card_info->chip_name) + 1) == 0)
break;
}
if (i == MAX_CARD_NUM || !card_info) {
lld_put();
- pr_err("Can't find this card %s\n", param.chip_name);
+ pr_err("Can't find this card.\n");
return -EFAULT;
}
@@ -701,6 +744,7 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
default:
pr_err("Dbgtool cmd(0x%x) not support now\n", real_cmd);
ret = -EFAULT;
+ break;
}
up(&dbgtool_info->dbgtool_sem);
@@ -746,9 +790,11 @@ static long nictool_k_unlocked_ioctl(struct file *pfile,
static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
{
+ pgprot_t vm_page_prot;
unsigned long vmsize = vma->vm_end - vma->vm_start;
phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
phys_addr_t phy_addr;
+ int err = 0;
if (vmsize > (PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER))) {
pr_err("Map size = %lu is bigger than alloc\n", vmsize);
@@ -757,14 +803,18 @@ static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
/* old version of tool set vma->vm_pgoff to 0 */
phy_addr = offset ? offset : g_card_phy_addr[card_id];
-
- if (!phy_addr) {
- pr_err("Card_id = %d physical address is 0\n", card_id);
- return -EAGAIN;
+ /* check phy_addr valid */
+ if (phy_addr != g_card_phy_addr[card_id]) {
+ err = hinic3_bar_mmap_param_valid(phy_addr, vmsize);
+ if (err != 0) {
+ pr_err("mmap param invalid, err: %d\n", err);
+ return err;
+ }
}
/* Disable cache and write buffer in the mapping area */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_page_prot = vm_page_prot;
if (remap_pfn_range(vma, vma->vm_start, (phy_addr >> PAGE_SHIFT),
vmsize, vma->vm_page_prot)) {
pr_err("Remap pfn range failed.\n");
@@ -787,7 +837,6 @@ static const struct file_operations fifo_operations = {
static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
{
struct dbgtool_k_glb_info *dbgtool_info = NULL;
- int err, id;
if (hinic3_func_type(hwdev) != TYPE_VF)
chip_info->func_handle_array[hinic3_global_func_id(hwdev)] = NULL;
@@ -795,23 +844,23 @@ static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
if (--chip_info->func_num)
return;
- err = sscanf(chip_info->chip_name, HINIC3_CHIP_NAME "%d", &id);
- if (err < 0)
- pr_err("Failed to get card id\n");
-
- if (id < MAX_CARD_NUM)
- g_card_node_array[id] = NULL;
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ g_card_node_array[chip_info->chip_id] = NULL;
dbgtool_info = chip_info->dbgtool_info;
/* FFM deinit */
- kfree(dbgtool_info->ffm);
- dbgtool_info->ffm = NULL;
+ if (dbgtool_info && dbgtool_info->ffm) {
+ kfree(dbgtool_info->ffm);
+ dbgtool_info->ffm = NULL;
+ }
+
+ if (dbgtool_info)
+ kfree(dbgtool_info);
- kfree(dbgtool_info);
chip_info->dbgtool_info = NULL;
- if (id < MAX_CARD_NUM)
- (void)dbgtool_knl_free_mem(id);
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ dbgtool_knl_free_mem(chip_info->chip_id);
}
static int alloc_dbgtool_info(void *hwdev, struct card_node *chip_info)
@@ -872,7 +921,6 @@ dbgtool_info_fail:
* nictool_k_init - initialize the hw interface
**/
/* temp for dbgtool_info */
-/*lint -e438*/
int nictool_k_init(void *hwdev, void *chip_node)
{
struct card_node *chip_info = (struct card_node *)chip_node;
@@ -895,9 +943,7 @@ int nictool_k_init(void *hwdev, void *chip_node)
}
/* Create equipment */
- /*lint -save -e160*/
g_nictool_class = class_create(THIS_MODULE, HIADM3_DEV_CLASS);
- /*lint -restore*/
if (IS_ERR(g_nictool_class)) {
pr_err("Create nictool_class fail\n");
err = -EFAULT;
@@ -944,7 +990,7 @@ alloc_chdev_fail:
free_dbgtool_info(hwdev, chip_info);
return err;
-} /*lint +e438*/
+}
void nictool_k_uninit(void *hwdev, void *chip_node)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
index f368133..c943dfc 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
@@ -18,6 +18,8 @@
int nictool_k_init(void *hwdev, void *chip_node);
void nictool_k_uninit(void *hwdev, void *chip_node);
+void hinic3_get_os_hot_replace_info(void *oshr_info);
+
void hinic3_get_all_chip_id(void *id_info);
void hinic3_get_card_func_info_by_card_name
@@ -29,6 +31,8 @@ bool hinic3_is_in_host(void);
int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *isvalid);
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin);
+
extern struct hinic3_uld_info g_uld_info[SERVICE_T_MAX];
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
index 2d5423e..6f145a0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
@@ -19,6 +19,20 @@
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
+#elif defined(CONFIG_NF_VID_DID)
+#define PCI_VENDOR_ID_NF 0x2036
+#define NFNIC_DEV_ID_STANDARD 0x1618
+#define NFNIC_DEV_ID_SDI_5_1_PF 0x0226
+#define NFNIC_DEV_ID_SDI_5_0_PF 0x0225
+#define NFNIC_DEV_ID_DPU_PF 0x0224
+#define NFNIC_DEV_ID_VF 0x1619
+#define NFNIC_DEV_ID_VF_HV 0x379F
+#define NFNIC_DEV_SDI_5_1_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_0_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_1_ID_VF_HV 0x379F
+#define NFNIC_DEV_ID_SPU 0xAC00
+#define NFNIC_DEV_SDI_5_1_SSDID_VF 0x1000
+#define NFNIC_DEV_SDI_V100_SSDID_MASK (3 << 12)
#else
#define PCI_VENDOR_ID_HUAWEI 0x19e5
#define HINIC3_DEV_ID_STANDARD 0x0222
@@ -28,16 +42,33 @@
#define HINIC3_DEV_ID_VF 0x375F
#define HINIC3_DEV_ID_VF_HV 0x379F
#define HINIC3_DEV_SDI_5_1_ID_VF 0x375F
+#define HINIC3_DEV_SDI_5_0_ID_VF 0x375F
#define HINIC3_DEV_SDI_5_1_ID_VF_HV 0x379F
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
#endif
+#define NFNIC_DEV_SSID_2X25G_NF 0x0860
+#define NFNIC_DEV_SSID_4X25G_NF 0x0861
+#define NFNIC_DEV_SSID_2x100G_NF 0x0862
+#define NFNIC_DEV_SSID_2x200G_NF 0x0863
+
+#define HINIC3_DEV_SSID_2X10G 0x0035
#define HINIC3_DEV_SSID_2X25G 0x0051
#define HINIC3_DEV_SSID_4X25G 0x0052
+#define HINIC3_DEV_SSID_4X25G_BD 0x0252
+#define HINIC3_DEV_SSID_4X25G_SMARTNIC 0x0152
+#define HINIC3_DEV_SSID_6X25G_VL 0x0356
#define HINIC3_DEV_SSID_2X100G 0x00A1
+#define HINIC3_DEV_SSID_2X100G_SMARTNIC 0x01A1
+#define HINIC3_DEV_SSID_2X200G 0x04B1
#define HINIC3_DEV_SSID_2X100G_VF 0x1000
+#define HINIC3_DEV_SSID_HPC_4_HOST_NIC 0x005A
+#define HINIC3_DEV_SSID_2X200G_VL 0x00B1
+#define HINIC3_DEV_SSID_1X100G 0x02A4
+
+#define BIFUR_RESOURCE_PF_SSID 0x05a1
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
index b23b69f..c8258ff 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
@@ -68,7 +68,6 @@ ssize_t hinic3_sriov_numvfs_show(struct device *dev,
return sprintf(buf, "%d\n", pci_num_vf(pdev));
}
-/*lint -save -e713*/
ssize_t hinic3_sriov_numvfs_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -116,7 +115,6 @@ ssize_t hinic3_sriov_numvfs_store(struct device *dev,
return count;
}
-/*lint -restore*/
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
int hinic3_pci_sriov_disable(struct pci_dev *dev)
@@ -174,24 +172,15 @@ int hinic3_pci_sriov_disable(struct pci_dev *dev)
return 0;
}
-int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
-{
#ifdef CONFIG_PCI_IOV
- struct hinic3_sriov_info *sriov_info = NULL;
- struct hinic3_event_info event = {0};
- void *hwdev = NULL;
- int pre_existing_vfs = 0;
- int err = 0;
-
- sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
- hwdev = hinic3_get_hwdev_by_pcidev(dev);
- if (!hwdev) {
- sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
- return -EPERM;
- }
+int hinic3_pci_sriov_check(struct hinic3_sriov_info *sriov_info, struct pci_dev *dev, int num_vfs)
+{
+ int pre_existing_vfs;
+ int err;
if (test_and_set_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state)) {
- sdk_err(&dev->dev, "SR-IOV enable in process, please wait, num_vfs %d\n",
+ sdk_err(&dev->dev,
+ "SR-IOV enable in process, please wait, num_vfs %d\n",
num_vfs);
return -EPERM;
}
@@ -202,6 +191,7 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
clear_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state);
return -ERANGE;
}
+
if (pre_existing_vfs && pre_existing_vfs != num_vfs) {
err = hinic3_pci_sriov_disable(dev);
if (err) {
@@ -213,6 +203,31 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
return num_vfs;
}
+ return 0;
+}
+#endif
+
+
+int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
+{
+#ifdef CONFIG_PCI_IOV
+ struct hinic3_sriov_info *sriov_info = NULL;
+ struct hinic3_event_info event = {0};
+ void *hwdev = NULL;
+ int err = 0;
+
+ sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
+ hwdev = hinic3_get_hwdev_by_pcidev(dev);
+ if (!hwdev) {
+ sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
+ return -EPERM;
+ }
+
+ err = hinic3_pci_sriov_check(sriov_info, dev, num_vfs);
+ if (err != 0) {
+ return err;
+ }
+
err = hinic3_init_vf_hw(hwdev, 1, (u16)num_vfs);
if (err) {
sdk_err(&dev->dev, "Failed to init vf in hardware before enable sriov, error %d\n",
@@ -262,6 +277,3 @@ int hinic3_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
else
return hinic3_pci_sriov_enable(dev, num_vfs);
}
-
-/*lint -restore*/
-
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c
index 2f5e098..4f8acd6 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c
@@ -128,7 +128,7 @@ int hinic3_wq_create(void *hwdev, struct hinic3_wq *wq, u32 q_depth,
wq_page_size = ALIGN(dev->wq_page_size, PAGE_SIZE);
- memset(wq, 0, sizeof(*wq));
+ memset(wq, 0, sizeof(struct hinic3_wq));
wq->dev_hdl = dev->dev_hdl;
wq->q_depth = q_depth;
wq->idx_mask = (u16)(q_depth - 1);
diff --git a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
index 9e8fc75..bfb4499 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
@@ -10,6 +10,10 @@
#define OVS_PORT_NUM_MAX BOND_PORT_MAX_NUM
#define DEFAULT_ROCE_BOND_FUNC 0xFFFFFFFF
+#define BOND_ID_IS_VALID(_id) \
+ (((_id) >= BOND_FIRST_ID) && ((_id) <= BOND_MAX_ID))
+#define BOND_ID_IS_INVALID(_id) (!(BOND_ID_IS_VALID(_id)))
+
enum bond_group_id {
BOND_FIRST_ID = 1,
BOND_MAX_ID = 4,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
index f56df08..f9737ea 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
@@ -21,6 +21,7 @@ enum servic_bit_define {
SERVICE_BIT_PPA = 11,
SERVICE_BIT_MIGRATE = 12,
SERVICE_BIT_VROCE = 13,
+ SERVICE_BIT_BIFUR = 14,
SERVICE_BIT_MAX
};
@@ -38,6 +39,7 @@ enum servic_bit_define {
#define CFG_SERVICE_MASK_PPA (0x1 << SERVICE_BIT_PPA)
#define CFG_SERVICE_MASK_MIGRATE (0x1 << SERVICE_BIT_MIGRATE)
#define CFG_SERVICE_MASK_VROCE (0x1 << SERVICE_BIT_VROCE)
+#define CFG_SERVICE_MASK_BIFUR (0x1 << SERVICE_BIT_BIFUR)
/* Definition of the scenario ID in the cfg_data, which is used for SML memory allocation. */
enum scenes_id_define {
@@ -50,6 +52,8 @@ enum scenes_id_define {
SCENES_ID_STORAGE_ROCE = 6,
SCENES_ID_COMPUTE_ROCE = 7,
SCENES_ID_STORAGE_TOE = 8,
+ SCENES_ID_COMPUTE_DPU = 100,
+ SCENES_ID_COMPUTE_SMART_NIC = 101,
SCENES_ID_MAX
};
@@ -120,13 +124,18 @@ struct cfg_cmd_dev_cap {
u8 srv_multi_host_mode;
u8 virtio_vq_size;
- u32 rsvd_func3[5];
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 lro_enable;
+ u8 os_hot_replace;
+
+ u32 rsvd_func3[4];
/* l2nic */
u16 nic_max_sq_id;
u16 nic_max_rq_id;
u16 nic_default_num_queues;
- u16 rsvd1_nic;
+ u16 outband_vlan_cfg_en;
u32 rsvd2_nic[2];
/* RoCE */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
index d9f67e2..6c5b995 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
@@ -37,7 +37,7 @@ static inline void hinic3_cpu_to_be32(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -59,7 +59,7 @@ static inline void hinic3_be32_to_cpu(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -86,52 +86,16 @@ static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
sge->len = (u32)len;
}
-#ifdef HW_CONVERT_ENDIAN
#define hinic3_hw_be32(val) (val)
#define hinic3_hw_cpu32(val) (val)
#define hinic3_hw_cpu16(val) (val)
-#else
-#define hinic3_hw_be32(val) cpu_to_be32(val)
-#define hinic3_hw_cpu32(val) be32_to_cpu(val)
-#define hinic3_hw_cpu16(val) be16_to_cpu(val)
-#endif
static inline void hinic3_hw_be32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_be32(*mem);
- mem++;
- }
-#endif
}
static inline void hinic3_hw_cpu32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_cpu32(*mem);
- mem++;
- }
-#endif
}
int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
@@ -149,6 +113,8 @@ int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
/* func_attr.glb_func_idx, global function index */
u16 hinic3_global_func_id(void *hwdev);
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id);
+
/* func_attr.p2p_idx, belongs to which pf */
u8 hinic3_pf_id_of_vf(void *hwdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
index 9a9bfe2..e36ba1d 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
@@ -219,5 +219,7 @@ void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
const char **hinic3_get_uld_names(void);
+int hinic3_lld_init(void);
+void hinic3_lld_exit(void);
#endif
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
index 97d34f0..199f17a 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
@@ -43,6 +43,10 @@ enum mag_cmd {
MAG_CMD_GET_XSFP_PRESENT = 62, /* get xsfp present status @see mag_cmd_get_xsfp_present */
MAG_CMD_SET_XSFP_RW = 63, /* sfp/qsfp single byte read/write, @see mag_cmd_set_xsfp_rw */
MAG_CMD_CFG_XSFP_TEMPERATURE = 64, /* get xsfp temp @see mag_cmd_sfp_temp_out_info */
+ /**< set xsfp tlv info @see struct mag_cmd_set_xsfp_tlv_req */
+ MAG_CMD_SET_XSFP_TLV_INFO = 65,
+ /**< get xsfp tlv info @see struct drv_mag_cmd_get_xsfp_tlv_rsp */
+ MAG_CMD_GET_XSFP_TLV_INFO = 66,
/* Event reported 100-149 */
MAG_CMD_WIRE_EVENT = 100,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
index caaba5d..88a9c0d 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
@@ -16,32 +16,43 @@
#define BOARD_TYPE_RSVD_RANGE_END 255
enum board_type_define_e {
- BOARD_TYPE_MPU_DEFAULT = 0, /* Default config */
- BOARD_TYPE_TEST_EVB_4X25G = 1, /* EVB Board */
- BOARD_TYPE_TEST_CEM_2X100G = 2, /* 2X100G CEM Card */
- BOARD_TYPE_STRG_SMARTIO_4X32G_FC = 30, /* 4X32G SmartIO FC Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_TIOE = 31, /* 4X25GE SmartIO TIOE Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE = 32, /* 4X25GE SmartIO ROCE Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE_AA = 33, /* 4X25GE SmartIO ROCE_AA Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV = 34, /* 4X25GE SmartIO container Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV_SW = 35, /* 4X25GE SmartIO container switch Card */
- BOARD_TYPE_STRG_4X25G_COMSTORAGE = 36, /* 4X25GE compute storage Onboard Card */
- BOARD_TYPE_STRG_2X100G_TIOE = 40, /* 2X100G SmartIO TIOE Card */
- BOARD_TYPE_STRG_2X100G_ROCE = 41, /* 2X100G SmartIO ROCE Card */
- BOARD_TYPE_STRG_2X100G_ROCE_AA = 42, /* 2X100G SmartIO ROCE_AA Card */
- BOARD_TYPE_CAL_2X25G_NIC_75MPPS = 100, /* 2X25G ETH Standard card 75MPPS */
- BOARD_TYPE_CAL_2X25G_NIC_40MPPS = 101, /* 2X25G ETH Standard card 40MPPS */
- BOARD_TYPE_CAL_2X100G_DPU = 102, /* 2x100G DPU Card */
- BOARD_TYPE_CAL_4X25G_NIC_120MPPS = 105, /* 4X25G ETH Standard card 120MPPS */
- BOARD_TYPE_CAL_4X25G_COMSTORAGE = 106, /* 4X25GE compute storage Onboard Card */
- BOARD_TYPE_CAL_2X32G_FC_HBA = 110, /* 2X32G FC HBA card */
- BOARD_TYPE_CAL_2X16G_FC_HBA = 111, /* 2X16G FC HBA card */
- BOARD_TYPE_CAL_2X100G_NIC_120MPPS = 115, /* 2X100G ETH Standard card 120MPPS */
- BOARD_TYPE_CAL_2X25G_DPU = 116, /* 2x25G DPU Card */
- BOARD_TYPE_CAL_4X25G_DPU = 118, /* 4x25G DPU Card */
- BOARD_TYPE_CLD_2X100G_SDI5_1 = 170, /* 2X100G SDI 5.1 Card */
- BOARD_TYPE_CLD_2X25G_SDI5_0_LITE = 171, /* 2x25G SDI5.0 Lite Card */
- BOARD_TYPE_CLD_2X100G_SDI5_0 = 172, /* 2x100G SDI5.0 Card */
+ BOARD_TYPE_MPU_DEFAULT = 0,
+ BOARD_TYPE_TEST_EVB_4X25G = 1,
+ BOARD_TYPE_TEST_CEM_2X100G = 2,
+ BOARD_TYPE_STRG_SMARTIO_4X32G_FC = 30,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_TIOE = 31,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE = 32,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE_AA = 33,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV = 34,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV_SW = 35,
+ BOARD_TYPE_STRG_4X25G_COMSTORAGE = 36,
+ BOARD_TYPE_STRG_2X100G_TIOE = 40,
+ BOARD_TYPE_STRG_2X100G_ROCE = 41,
+ BOARD_TYPE_STRG_2X100G_ROCE_AA = 42,
+ BOARD_TYPE_CAL_2X25G_NIC_75MPPS = 100,
+ BOARD_TYPE_CAL_2X25G_NIC_40MPPS = 101,
+ BOARD_TYPE_CAL_2X100G_DPU_VL = 102,
+ BOARD_TYPE_CAL_4X25G_NIC_120MPPS = 105,
+ BOARD_TYPE_CAL_4X25G_COMSTORAGE = 106,
+ BOARD_TYPE_CAL_2X32G_FC_HBA = 110,
+ BOARD_TYPE_CAL_2X16G_FC_HBA = 111,
+ BOARD_TYPE_CAL_2X100G_NIC_120MPPS = 115,
+ BOARD_TYPE_CAL_2X25G_DPU_BD = 116,
+ BOARD_TYPE_CAL_2X100G_TCE_BACKPLANE = 117,
+ BOARD_TYPE_CAL_4X25G_DPU_VL = 118,
+ BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS = 119,
+ BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS = 120,
+ BOARD_TYPE_CAL_6X25G_DPU_VL = 121,
+ BOARD_TYPE_CAL_4X25G_DPU_BD = 122,
+ BOARD_TYPE_CAL_2X25G_NIC_4HOST = 123,
+ BOARD_TYPE_CAL_2X10G_LOW_POWER = 125,
+ BOARD_TYPE_CAL_2X200G_NIC_INTERNET = 127,
+ BOARD_TYPE_CAL_1X100GR2_OCP = 129,
+ BOARD_TYPE_CAL_2X200G_DPU_VL = 130,
+ BOARD_TYPE_CLD_2X100G_SDI5_1 = 170,
+ BOARD_TYPE_CLD_2X25G_SDI5_0_LITE = 171,
+ BOARD_TYPE_CLD_2X100G_SDI5_0 = 172,
+ BOARD_TYPE_CLD_4X25G_SDI5_0_C = 175,
BOARD_TYPE_MAX_INDEX = 0xFF
};
@@ -49,23 +60,76 @@ static inline u32 spu_board_type_valid(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
- ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
+}
+
+static inline int board_type_is_sdi_50(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
+ ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C);
}
static inline int board_type_is_sdi(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_1) ||
((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
- ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0);
+ ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C);
+}
+
+static inline int board_type_is_dpu_spu(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
}
static inline int board_type_is_dpu(u32 board_type)
{
- return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_6X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
+}
+
+static inline int board_type_is_smartnic(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS);
+}
+
+/* 此接口判断是否是分布式存储的标卡以及计算的标卡(含ROCE特性),
+ * 仅用于LLDP TX功能冲突命令字处理的判断
+ */
+static inline int board_type_is_compute(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_75MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_40MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_NIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_COMSTORAGE) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_NIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X10G_LOW_POWER) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_NIC_INTERNET) ||
+ ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_4HOST) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS);
+}
+
+/* 此接口判断服务器输入reboot网卡是否需要复位 */
+static inline int board_type_is_multi_socket(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP);
}
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
index 89d5cc4..e65c206 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
@@ -1,11 +1,11 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ * Description : common definitions
+ */
#ifndef COMM_DEFS_H
#define COMM_DEFS_H
-#include "mgmt_msg_base.h"
-
/** MPU CMD MODULE TYPE */
enum hinic3_mod_type {
HINIC3_MOD_COMM = 0, /* HW communication module */
@@ -33,16 +33,16 @@ enum hinic3_mod_type {
HINIC3_MOD_MAX,
};
-/* Func reset flag, Specifies the resource to be cleaned.*/
-enum func_reset_flag_e {
+/* func reset的flag ,用于指示清理哪种资源 */
+enum func_reset_flag_e{
RES_TYPE_FLUSH_BIT = 0,
RES_TYPE_MQM,
RES_TYPE_SMF,
RES_TYPE_PF_BW_CFG,
RES_TYPE_COMM = 10,
- RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
RES_TYPE_NIC,
RES_TYPE_OVS,
RES_TYPE_VBS,
@@ -53,33 +53,48 @@ enum func_reset_flag_e {
RES_TYPE_MAX,
};
-#define HINIC3_COMM_RES \
- ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
- (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
- (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
+#define HINIC3_COMM_RES \
+ ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
+ (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
+ (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
-#define HINIC3_NIC_RES BIT(RES_TYPE_NIC)
-#define HINIC3_OVS_RES BIT(RES_TYPE_OVS)
-#define HINIC3_VBS_RES BIT(RES_TYPE_VBS)
-#define HINIC3_ROCE_RES BIT(RES_TYPE_ROCE)
-#define HINIC3_FC_RES BIT(RES_TYPE_FC)
-#define HINIC3_TOE_RES BIT(RES_TYPE_TOE)
-#define HINIC3_IPSEC_RES BIT(RES_TYPE_IPSEC)
+#define HINIC3_NIC_RES (1 << RES_TYPE_NIC)
+#define HINIC3_OVS_RES (1 << RES_TYPE_OVS)
+#define HINIC3_VBS_RES (1 << RES_TYPE_VBS)
+#define HINIC3_ROCE_RES (1 << RES_TYPE_ROCE)
+#define HINIC3_FC_RES (1 << RES_TYPE_FC)
+#define HINIC3_TOE_RES (1 << RES_TYPE_TOE)
+#define HINIC3_IPSEC_RES (1 << RES_TYPE_IPSEC)
/* MODE OVS、NIC、UNKNOWN */
#define HINIC3_WORK_MODE_OVS 0
#define HINIC3_WORK_MODE_UNKNOWN 1
#define HINIC3_WORK_MODE_NIC 2
-#define DEVICE_TYPE_L2NIC 0
-#define DEVICE_TYPE_NVME 1
-#define DEVICE_TYPE_VIRTIO_NET 2
-#define DEVICE_TYPE_VIRTIO_BLK 3
-#define DEVICE_TYPE_VIRTIO_VSOCK 4
-#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
-#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
-#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
-#define DEVICE_TYPE_VIRTIO_HPC 8
+#define DEVICE_TYPE_L2NIC 0
+#define DEVICE_TYPE_NVME 1
+#define DEVICE_TYPE_VIRTIO_NET 2
+#define DEVICE_TYPE_VIRTIO_BLK 3
+#define DEVICE_TYPE_VIRTIO_VSOCK 4
+#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
+#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
+#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
+#define DEVICE_TYPE_VIRTIO_HPC 8
+#define DEVICE_TYPE_VIRTIO_FS 9
+
+#define IS_STORAGE_DEVICE_TYPE(dev_type) \
+ ((dev_type) == DEVICE_TYPE_VIRTIO_BLK || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_BLK_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_SCSI_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_FS)
+
+#define MGMT_MSG_CMD_OP_SET 1
+#define MGMT_MSG_CMD_OP_GET 0
+
+#define MGMT_MSG_CMD_OP_START 1
+#define MGMT_MSG_CMD_OP_STOP 0
+
+#define HOT_REPLACE_PARTITION_NUM 2
enum hinic3_svc_type {
SVC_T_COMM = 0,
@@ -98,8 +113,17 @@ enum hinic3_svc_type {
};
/**
- * Common header control information of the COMM message interaction command word
- * between the driver and PF.
+ * Common header control information of the COMM message interaction command word between the driver and PF
+ * stuct mgmt_msg_head and struct comm_info_head are the same stucture
+ */
+struct mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+/**
+ * Common header control information of the COMM message interaction command word between the driver and PF
*/
struct comm_info_head {
/** response status code, 0: success, others: error code */
@@ -113,4 +137,29 @@ struct comm_info_head {
u8 rsvd[5];
};
+
+static inline u32 get_function_partition(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM;
+}
+
+static inline u32 is_primary_function(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0;
+}
+
+static inline u32 mpu_nic_get_primary_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ function_id : (function_id - port_num);
+}
+
+// when func_id is in partition 0/1, it will get its another func_id in partition 1/0
+static inline u32 mpu_nic_get_backup_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ (function_id + port_num) : (function_id - port_num);
+}
+
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
index b24e729..fd0401f 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
@@ -89,6 +89,10 @@ enum hinic3_mgmt_cmd {
* @see comm_read_ucode_sm_resp
*/
COMM_MGMT_CMD_CLEAR_LOG, /**< clear log @see comm_cmd_clear_log_s */
+ COMM_MGMT_CMD_UCODE_SM_COUNTER_PER,
+ /**< get ucode sm counter @see struct comm_read_ucode_sm_per_req
+ * @see struct comm_read_ucode_sm_per_resp
+ */
COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140, /* check if switch workmode reserved
* @see comm_cmd_check_if_switch_workmode
@@ -101,6 +105,7 @@ enum hinic3_mgmt_cmd {
COMM_MGMT_CMD_CPI_TCAM_DBG, /* enable or disable the scheduled cpi tcam task,
* set task interval time @see comm_cmd_cpi_tcam_dbg_s
*/
+ COMM_MGMT_CMD_LLDP_TX_FUNC_SET,
COMM_MGMT_CMD_SECTION_RSVD_0 = 160, /**< rsvd0 section */
COMM_MGMT_CMD_SECTION_RSVD_1 = 170, /**< rsvd1 section */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
index f535777..fd3a7dd 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
@@ -313,7 +313,8 @@ struct comm_cmd_get_fw_version {
struct mgmt_msg_head head;
u16 fw_type; /**< firmware type @see enum hinic3_fw_ver_type */
- u16 rsvd1;
+ u16 fw_dfx_vld : 1; /**< 0: release, 1: debug */
+ u16 rsvd1 : 15;
u8 ver[HINIC3_FW_VERSION_LEN]; /**< firmware version */
u8 time[HINIC3_FW_COMPILE_TIME_LEN]; /**< firmware compile time */
};
@@ -558,6 +559,7 @@ struct nic_log_info_request {
#define MPU_TEMP_OP_GET 0
#define MPU_TEMP_THRESHOLD_OP_CFG 1
+#define MPU_TEMP_MCTP_DFX_INFO_GET 2
struct comm_temp_in_info {
struct comm_info_head head;
u8 opt_type; /**< operation type 0:read operation 1:cfg operation */
@@ -660,6 +662,28 @@ struct comm_read_ucode_sm_resp {
u64 val2;
};
+#define PER_REQ_MAX_DATA_LEN 0x600
+
+struct comm_read_ucode_sm_per_req {
+ struct mgmt_msg_head msg_head;
+
+ u32 tbl_type;
+ u32 count_id;
+};
+
+struct comm_read_ucode_sm_per_resp {
+ struct mgmt_msg_head msg_head;
+
+ u8 data[PER_REQ_MAX_DATA_LEN];
+};
+
+struct ucode_sm_counter_get_info {
+ u32 width_type;
+ u32 tbl_type;
+ unsigned int base_count;
+ unsigned int count_num;
+};
+
enum log_type {
MPU_LOG_CLEAR = 0,
SMU_LOG_CLEAR = 1,
@@ -1057,7 +1081,9 @@ struct comm_cmd_ncsi_settings {
u8 lldp_over_ncsi_enable;
u8 lldp_over_mctp_enable;
u32 magicwd;
- u8 rsvd[8];
+ u8 lldp_tx_enable;
+ u8 rsvd[3];
+ u32 crc;
struct tag_ncsi_chan_info ncsi_chan_info;
};
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
index fde8617..767f886 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
@@ -114,6 +114,14 @@ struct tag_ncsi_client_info {
#define AEN_CTRL_CONFIG_REQ_SHIFT 1
#define AEN_CTRL_DRV_CHANGE_SHIFT 2
+/* AEN Type */
+enum aen_type_e{
+ AEN_LINK_STATUS_CHANGE_TYPE = 0x0,
+ AEN_CONFIG_REQUIRED_TYPE = 0x1,
+ OEM_AEN_CONFIG_REQUEST_TYPE = 0x80,
+ AEN_TYPE_MAX = 0x100
+} ;
+
/* get link status 0x0A */
#define GET_LINK_STATUS_REQ_LEN 0
#define GET_LINK_STATUS_RSP_LEN 16
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
index fe663e1..83b75f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
@@ -1,5 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+/*
+ * Copyright (C), 2001-2021, Huawei Tech. Co., Ltd.
+ * File Name : nic_cfg_comm.h
+ * Version : Initial Draft
+ * Description : nic config common header file
+ * Function List :
+ * History :
+ * Modification: Created file
+ */
#ifndef NIC_CFG_COMM_H
#define NIC_CFG_COMM_H
@@ -26,7 +34,7 @@ enum nic_rss_hash_type {
};
#define NIC_RSS_INDIR_SIZE 256
-#define NIC_RSS_KEY_SIZE 40
+#define NIC_RSS_KEY_SIZE 40
/* *
* Definition of the NIC receiving mode
@@ -36,6 +44,7 @@ enum nic_rss_hash_type {
#define NIC_RX_MODE_BC 0x04
#define NIC_RX_MODE_MC_ALL 0x08
#define NIC_RX_MODE_PROMISC 0x10
+#define NIC_RX_DB_COS_MAX 0x4
/* IEEE 802.1Qaz std */
#define NIC_DCB_COS_MAX 0x8
@@ -52,4 +61,7 @@ enum nic_rss_hash_type {
#define NIC_DCB_PRIO_STRICT 0x1
#define NIC_DCB_MAX_PFC_NUM 0x4
+
+#define NIC_ETS_PERCENT_WEIGHT 100
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
index 801aeed..9f93f7e 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
@@ -23,7 +23,11 @@
#define VRAM_CQM_BITMAP_BASE "B"
#define VRAM_NIC_DCB "DCB"
+#define VRAM_NIC_MHOST_MGMT "MHOST_MGMT"
#define VRAM_NIC_VRAM "NIC_VRAM"
+#define VRAM_NIC_IRQ_VRAM "NIC_IRQ"
+
+#define VRAM_NIC_MQM "NM"
#define VRAM_VBS_BASE_IOCB "BASE_IOCB"
#define VRAM_VBS_EX_IOCB "EX_IOCB"
@@ -55,11 +59,16 @@ enum KUP_HOOK_POINT {
PRE_FREEZE,
FREEZE_TO_KILL,
PRE_UPDATE_KERNEL,
- FLUSH_DURING_KUP,
POST_UPDATE_KERNEL,
UNFREEZE_TO_RUN,
POST_RUN,
KUP_HOOK_MAX,
};
+#define hi_vram_kalloc(name, size) 0
+#define hi_vram_kfree(vaddr, name, size)
+#define get_use_vram_flag(void) 0
+#define vram_get_kexec_flag(void) 0
+#define hi_vram_get_gfp_vram(void) 0
+
#endif /* VRAM_COMMON_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
similarity index 79%
rename from drivers/net/ethernet/huawei/hinic3/mag_cmd.h
rename to drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
index 9649503..e77d7d5 100644
--- a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
@@ -9,6 +9,7 @@
/* serdes cmd struct define */
#define CMD_ARRAY_BUF_SIZE 64
#define SERDES_CMD_DATA_BUF_SIZE 512
+#define RATE_MBPS_TO_GBPS 1000
struct serdes_in_info {
u32 chip_id : 16;
u32 macro_id : 16;
@@ -127,6 +128,7 @@ enum mag_cmd_cnt_type {
MAG_RX_PCS_E_BLK_CNT = 5,
MAG_RX_PCS_DEC_ERR_BLK_CNT = 6,
MAG_RX_PCS_LANE_BIP_ERR_CNT = 7,
+ MAG_RX_RSFEC_ERR_CW_CNT = 8,
MAG_CNT_NUM
};
@@ -208,7 +210,9 @@ struct mag_cmd_get_port_info {
u32 supported_mode;
u32 advertised_mode;
- u8 rsvd2[8];
+ u32 supported_fec_mode;
+ u16 bond_speed;
+ u8 rsvd2[2];
};
#define MAG_CMD_OPCODE_GET 0
@@ -330,8 +334,8 @@ struct mag_cmd_cfg_fec_mode {
u8 port_id;
u8 opcode; /* 0:get fec mode 1:set fec mode */
- u8 fec;
- u8 rsvd0;
+ u8 advertised_fec;
+ u8 supported_fec;
};
/* speed */
@@ -641,7 +645,7 @@ struct mag_cmd_event_port_info {
u32 cable_length; /* 1/3/5m */
u8 cable_temp; /* temp */
u8 max_speed; /* Maximum rate of an optical module */
- u8 sfp_type; /* sfp/qsfp */
+ u8 sfp_type; /* sfp/qsfp/dsfp */
u8 rsvd1;
u32 power[4]; /* Optical Power */
@@ -678,6 +682,10 @@ struct mag_cmd_event_port_info {
u8 rsvd3[360];
};
+struct mag_cmd_rsfec_stats {
+ u32 rx_err_lane_phy;
+};
+
struct mag_cmd_port_stats {
u64 mac_tx_fragment_pkt_num;
u64 mac_tx_undersize_pkt_num;
@@ -913,10 +921,223 @@ struct mag_cmd_sfp_temp_in_info {
};
struct mag_cmd_sfp_temp_out_info {
- struct mgmt_msg_head head; /* 8B */
- s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
- s32 max_temp; /* Chip optical module threshold */
- s32 min_temp; /* Chip optical module threshold */
+ struct mgmt_msg_head head; /* 8B */
+ s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
+ s32 max_temp; /* Chip optical module threshold */
+ s32 min_temp; /* Chip optical module threshold */
+};
+
+#define XSFP_CMIS_PARSE_PAGE_NUM 6
+#define XSFP_CMIS_INFO_MAX_SIZE 1536
+#define QSFP_CMIS_PAGE_SIZE 128
+#define QSFP_CMIS_MAX_CHANNEL_NUM 0x8
+
+/* Lower: Control and Essentials, Upper: Administrative Information */
+#define QSFP_CMIS_PAGE_00H 0x00
+/* Advertising */
+#define QSFP_CMIS_PAGE_01H 0x01
+/* Module and lane Thresholds */
+#define QSFP_CMIS_PAGE_02H 0x02
+/* User EEPROM */
+#define QSFP_CMIS_PAGE_03H 0x03
+/* Laser Capabilities Advertising (Page 04h, Optional) */
+#define QSFP_CMIS_PAGE_04H 0x04
+#define QSFP_CMIS_PAGE_05H 0x05
+/* Lane and Data Path Control */
+#define QSFP_CMIS_PAGE_10H 0x10
+/* Lane Status */
+#define QSFP_CMIS_PAGE_11H 0x11
+#define QSFP_CMIS_PAGE_12H 0x12
+
+#define MGMT_TLV_U8_SIZE 1
+#define MGMT_TLV_U16_SIZE 2
+#define MGMT_TLV_U32_SIZE 4
+
+#define MGMT_TLV_GET_U8(addr) (*((u8 *)(void *)(addr)))
+#define MGMT_TLV_SET_U8(addr, value) \
+ ((*((u8 *)(void *)(addr))) = ((u8)(value)))
+
+#define MGMT_TLV_GET_U16(addr) (*((u16 *)(void *)(addr)))
+#define MGMT_TLV_SET_U16(addr, value) \
+ ((*((u16 *)(void *)(addr))) = ((u16)(value)))
+
+#define MGMT_TLV_GET_U32(addr) (*((u32 *)(void *)(addr)))
+#define MGMT_TLV_SET_U32(addr, value) \
+ ((*((u32 *)(void *)(addr))) = ((u32)(value)))
+
+#define MGMT_TLV_TYPE_END 0xFFFF
+
+enum mag_xsfp_type {
+ MAG_XSFP_TYPE_PAGE = 0x01,
+ MAG_XSFP_TYPE_WIRE_TYPE = 0x02,
+ MAG_XSFP_TYPE_END = MGMT_TLV_TYPE_END
+};
+
+struct qsfp_cmis_lower_page_00_s {
+ u8 resv0[14];
+ u8 temperature_msb;
+ u8 temperature_lsb;
+ u8 volt_supply[2];
+ u8 resv1[67];
+ u8 media_type;
+ u8 electrical_interface_id;
+ u8 media_interface_id;
+ u8 lane_count;
+ u8 resv2[39];
+};
+
+struct qsfp_cmis_upper_page_00_s {
+ u8 identifier;
+ u8 vendor_name[16];
+ u8 vendor_oui[3];
+ u8 vendor_pn[16];
+ u8 vendor_rev[2];
+ u8 vendor_sn[16];
+ u8 date_code[8];
+ u8 clei_code[10];
+ u8 power_character[2];
+ u8 cable_len;
+ u8 connector;
+ u8 copper_cable_attenuation[6];
+ u8 near_end_implementation;
+ u8 far_end_config;
+ u8 media_technology;
+ u8 resv0[43];
+};
+
+struct qsfp_cmis_upper_page_01_s {
+ u8 firmware_rev[2];
+ u8 hardware_rev[2];
+ u8 smf_len_km;
+ u8 om5_len;
+ u8 om4_len;
+ u8 om3_len;
+ u8 om2_len;
+ u8 resv0;
+ u8 wavelength[2];
+ u8 wavelength_tolerance[2];
+ u8 pages_implement;
+ u8 resv1[16];
+ u8 monitor_implement[2];
+ u8 resv2[95];
+};
+
+struct qsfp_cmis_upper_page_02_s {
+ u8 temperature_high_alarm[2];
+ u8 temperature_low_alarm[2];
+ u8 temperature_high_warn[2];
+ u8 temperature_low_warn[2];
+ u8 volt_high_alarm[2];
+ u8 volt_low_alarm[2];
+ u8 volt_high_warn[2];
+ u8 volt_low_warn[2];
+ u8 resv0[32];
+ u8 tx_power_high_alarm[2];
+ u8 tx_power_low_alarm[2];
+ u8 tx_power_high_warn[2];
+ u8 tx_power_low_warn[2];
+ u8 tx_bias_high_alarm[2];
+ u8 tx_bias_low_alarm[2];
+ u8 tx_bias_high_warn[2];
+ u8 tx_bias_low_warn[2];
+ u8 rx_power_high_alarm[2];
+ u8 rx_power_low_alarm[2];
+ u8 rx_power_high_warn[2];
+ u8 rx_power_low_warn[2];
+ u8 resv1[56];
+};
+
+struct qsfp_cmis_upper_page_03_s {
+ u8 resv0[QSFP_CMIS_PAGE_SIZE]; /* Reg 128-255: Upper Memory: Page 03H */
+};
+
+struct qsfp_cmis_upper_page_10_s {
+ u8 resv0[2]; /* Reg 128-129: Upper Memory: Page 10H */
+ u8 tx_disable; /* Reg 130: Tx disable, 0b=enabled, 1b=disabled */
+ u8 resv1[125]; /* Reg 131-255 */
+};
+
+struct qsfp_cmis_upper_page_11_s {
+ u8 resv0[7];
+ u8 tx_fault;
+ u8 tx_los;
+ u8 resv1[10];
+ u8 rx_los;
+ u8 resv2[6];
+ u8 tx_power[16];
+ u8 tx_bias[16];
+ u8 rx_power[16];
+ u8 resv3[54];
+};
+
+struct qsfp_cmis_info_s {
+ struct qsfp_cmis_lower_page_00_s lower_page_00;
+ struct qsfp_cmis_upper_page_00_s upper_page_00;
+ struct qsfp_cmis_upper_page_01_s upper_page_01;
+ struct qsfp_cmis_upper_page_02_s upper_page_02;
+ struct qsfp_cmis_upper_page_10_s upper_page_10;
+ struct qsfp_cmis_upper_page_11_s upper_page_11;
+};
+
+struct qsfp_cmis_comm_power_s {
+ u32 chl_power[QSFP_CMIS_MAX_CHANNEL_NUM];
+};
+
+struct qsfp_cmis_wire_info_s {
+ struct qsfp_cmis_comm_power_s rx_power;
+ u8 rx_los;
+ u8 resv0[3];
+};
+
+struct mgmt_tlv_info {
+ u16 type;
+ u16 length;
+ u8 value[];
+};
+
+struct mag_cmd_set_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 tlv_buf[];
+};
+
+struct mag_cmd_set_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+};
+
+struct mag_cmd_get_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd;
+ u16 rsp_buf_len;
+};
+
+struct mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[];
+};
+
+
+struct parse_tlv_info {
+ u8 tlv_page_info[XSFP_CMIS_INFO_MAX_SIZE + 1];
+ u32 tlv_page_info_len;
+ u32 tlv_page_num[XSFP_CMIS_PARSE_PAGE_NUM];
+ u32 wire_type;
+ u8 id;
+};
+
+struct drv_mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[XSFP_CMIS_INFO_MAX_SIZE];
};
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h b/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
deleted file mode 100644
index 257bf67..0000000
--- a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : mgmt_msg_base.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef MGMT_MSG_BASE_H
-#define MGMT_MSG_BASE_H
-
-#define MGMT_MSG_CMD_OP_SET 1
-#define MGMT_MSG_CMD_OP_GET 0
-
-#define MGMT_MSG_CMD_OP_START 1
-#define MGMT_MSG_CMD_OP_STOP 0
-
-struct mgmt_msg_head {
- u8 status;
- u8 version;
- u8 rsvd0[6];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
deleted file mode 100644
index 9fb4232..0000000
--- a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2001-2021, Huawei Tech. Co., Ltd.
- * File Name : nic_cfg_comm.h
- * Version : Initial Draft
- * Description : nic config common header file
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef NIC_CFG_COMM_H
-#define NIC_CFG_COMM_H
-
-/* rss */
-#define HINIC3_RSS_TYPE_VALID_SHIFT 23
-#define HINIC3_RSS_TYPE_TCP_IPV6_EXT_SHIFT 24
-#define HINIC3_RSS_TYPE_IPV6_EXT_SHIFT 25
-#define HINIC3_RSS_TYPE_TCP_IPV6_SHIFT 26
-#define HINIC3_RSS_TYPE_IPV6_SHIFT 27
-#define HINIC3_RSS_TYPE_TCP_IPV4_SHIFT 28
-#define HINIC3_RSS_TYPE_IPV4_SHIFT 29
-#define HINIC3_RSS_TYPE_UDP_IPV6_SHIFT 30
-#define HINIC3_RSS_TYPE_UDP_IPV4_SHIFT 31
-
-#define HINIC3_RSS_TYPE_SET(val, member) (((u32)(val) & 0x1) << HINIC3_RSS_TYPE_##member##_SHIFT)
-#define HINIC3_RSS_TYPE_GET(val, member) (((u32)(val) >> HINIC3_RSS_TYPE_##member##_SHIFT) & 0x1)
-
-enum nic_rss_hash_type {
- NIC_RSS_HASH_TYPE_XOR = 0,
- NIC_RSS_HASH_TYPE_TOEP,
-
- NIC_RSS_HASH_TYPE_MAX /* MUST BE THE LAST ONE */
-};
-
-#define NIC_RSS_INDIR_SIZE 256
-#define NIC_RSS_KEY_SIZE 40
-
-/* *
- * Definition of the NIC receiving mode
- */
-#define NIC_RX_MODE_UC 0x01
-#define NIC_RX_MODE_MC 0x02
-#define NIC_RX_MODE_BC 0x04
-#define NIC_RX_MODE_MC_ALL 0x08
-#define NIC_RX_MODE_PROMISC 0x10
-
-/* IEEE 802.1Qaz std */
-#define NIC_DCB_COS_MAX 0x8
-#define NIC_DCB_UP_MAX 0x8
-#define NIC_DCB_TC_MAX 0x8
-#define NIC_DCB_PG_MAX 0x8
-#define NIC_DCB_TSA_SP 0x0
-#define NIC_DCB_TSA_CBS 0x1 /* hi1822 do NOT support */
-#define NIC_DCB_TSA_ETS 0x2
-#define NIC_DCB_DSCP_NUM 0x8
-#define NIC_DCB_IP_PRI_MAX 0x40
-
-#define NIC_DCB_PRIO_DWRR 0x0
-#define NIC_DCB_PRIO_STRICT 0x1
-
-#define NIC_DCB_MAX_PFC_NUM 0x4
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
similarity index 77%
rename from drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
rename to drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
index 31e224a..8e0fa89 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
- * File Name : hinic3_comm_cmd.h
+ * File Name : nic_mpu_cmd.h
* Version : Initial Draft
* Created : 2019/4/25
* Last Modified :
@@ -9,8 +9,8 @@
* Function List :
*/
-#ifndef HINIC3_NIC_CMD_H
-#define HINIC3_NIC_CMD_H
+#ifndef NIC_MPU_CMD_H
+#define NIC_MPU_CMD_H
/* Commands between NIC to MPU
*/
@@ -33,8 +33,9 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_CFG_LOCAL_LRO_STATE,
HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
+ HINIC3_NIC_CMD_SET_FUNC_ER_FWD_ID,
- /* MAC & VLAN CFG */
+ /** MAC & VLAN CFG & VXLAN CFG */
HINIC3_NIC_CMD_GET_MAC = 20,
HINIC3_NIC_CMD_SET_MAC,
HINIC3_NIC_CMD_DEL_MAC,
@@ -45,6 +46,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_VLAN_FILTER_EN,
HINIC3_NIC_CMD_SET_RX_VLAN_OFFLOAD,
HINIC3_NIC_CMD_SMAC_CHECK_STATE,
+ HINIC3_NIC_CMD_OUTBAND_SET_FUNC_VLAN,
+
+ HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+ HINIC3_NIC_CMD_RX_RATE_CFG,
+ HINIC3_NIC_CMD_WR_ORDERING_CFG,
/* SR-IOV */
HINIC3_NIC_CMD_CFG_VF_VLAN = 40,
@@ -61,6 +67,7 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC,
/* IP checksum error packets, enable rss quadruple hash */
HINIC3_NIC_CMD_IPCS_ERR_RSS_ENABLE_OP = 66,
+ HINIC3_NIC_CMD_GTP_INNER_PARSE_STATUS,
/* PPA/FDIR */
HINIC3_NIC_CMD_ADD_TC_FLOW = 80,
@@ -76,6 +83,10 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_CFG_PPA_FLUSH,
HINIC3_NIC_CMD_SET_FDIR_STATUS,
HINIC3_NIC_CMD_GET_PPA_COUNTER,
+ HINIC3_NIC_CMD_SET_FUNC_FLOW_BIFUR_ENABLE,
+ HINIC3_NIC_CMD_SET_BOND_MASK,
+ HINIC3_NIC_CMD_GET_BLOCK_TC_FLOWS,
+ HINIC3_NIC_CMD_GET_BOND_MASK,
/* PORT CFG */
HINIC3_NIC_CMD_SET_PORT_ENABLE = 100,
@@ -94,6 +105,8 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_QOS_PORT_CFG,
HINIC3_NIC_CMD_QOS_MAP_CFG,
HINIC3_NIC_CMD_FORCE_PKT_DROP,
+ HINIC3_NIC_CMD_CFG_TX_PROMISC_SKIP = 114,
+ HINIC3_NIC_CMD_SET_PORT_FLOW_BIFUR_ENABLE = 117,
HINIC3_NIC_CMD_TX_PAUSE_EXCP_NOTICE = 118,
HINIC3_NIC_CMD_INQUIRT_PAUSE_CFG = 119,
@@ -116,6 +129,10 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_UCAPTURE_OPT = 160, /* TODO: move to roce */
HINIC3_NIC_CMD_SET_VHD_CFG,
+ /* OUT OF BAND */
+ HINIC3_NIC_CMD_GET_OUTBAND_CFG = 170,
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+
/* TODO: move to HILINK */
HINIC3_NIC_CMD_GET_PORT_STAT = 200,
HINIC3_NIC_CMD_CLEAN_PORT_STAT,
@@ -136,24 +153,22 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_LINK_ERR_EVENT,
HINIC3_NIC_CMD_SET_LED_STATUS,
- HINIC3_NIC_CMD_MAX = 256,
-};
+ /* mig */
+ HINIC3_NIC_CMD_MIG_SET_CEQ_CTRL = 230,
+ HINIC3_NIC_CMD_MIG_CFG_MSIX_INFO,
+ HINIC3_NIC_CMD_MIG_CFG_FUNC_VAT_TBL,
+ HINIC3_NIC_CMD_MIG_GET_VF_INFO,
+ HINIC3_NIC_CMD_MIG_CHK_MBX_EMPTY,
+ HINIC3_NIC_CMD_MIG_SET_VPORT_ENABLE,
+ HINIC3_NIC_CMD_MIG_CFG_SQ_CI,
+ HINIC3_NIC_CMD_MIG_CFG_RSS_TBL,
+ HINIC3_NIC_CMD_MIG_CFG_MAC_TBL,
+ HINIC3_NIC_CMD_MIG_TMP_SET_CMDQ_CTX,
+
+ HINIC3_OSHR_CMD_ACTIVE_FUNCTION = 240,
+ HINIC3_NIC_CMD_GET_RQ_INFO = 241,
-/* NIC CMDQ MODE */
-enum hinic3_ucode_cmd {
- HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
- HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
- HINIC3_UCODE_CMD_ARM_SQ,
- HINIC3_UCODE_CMD_ARM_RQ,
- HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_SET_IQ_ENABLE,
- HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
- HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
- HINIC3_UCODE_CMD_PPA_HASH_TABLE,
- HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_NIC_CMD_MAX = 256,
};
-#endif /* HINIC3_NIC_CMD_H */
+#endif /* NIC_MPU_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
new file mode 100644
index 0000000..ee6bf20
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
@@ -0,0 +1,1420 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+
+#ifndef NIC_MPU_CMD_DEFS_H
+#define NIC_MPU_CMD_DEFS_H
+
+#include "nic_cfg_comm.h"
+#include "mpu_cmd_base_defs.h"
+
+#ifndef ETH_ALEN
+#define ETH_ALEN 6
+#endif
+
+#define HINIC3_CMD_OP_SET 1
+#define HINIC3_CMD_OP_GET 0
+
+#define HINIC3_CMD_OP_ADD 1
+#define HINIC3_CMD_OP_DEL 0
+
+#define NIC_TCAM_BLOCK_LARGE_NUM 256
+#define NIC_TCAM_BLOCK_LARGE_SIZE 16
+
+#define TRAFFIC_BIFUR_MODEL_TYPE 2
+
+#define NIC_TCAM_FLOW_BIFUR_FLAG (1 << 0)
+
+#ifndef BIT
+#define BIT(n) (1UL << (n))
+#endif
+
+enum nic_feature_cap {
+ NIC_F_CSUM = BIT(0),
+ NIC_F_SCTP_CRC = BIT(1),
+ NIC_F_TSO = BIT(2),
+ NIC_F_LRO = BIT(3),
+ NIC_F_UFO = BIT(4),
+ NIC_F_RSS = BIT(5),
+ NIC_F_RX_VLAN_FILTER = BIT(6),
+ NIC_F_RX_VLAN_STRIP = BIT(7),
+ NIC_F_TX_VLAN_INSERT = BIT(8),
+ NIC_F_VXLAN_OFFLOAD = BIT(9),
+ NIC_F_IPSEC_OFFLOAD = BIT(10),
+ NIC_F_FDIR = BIT(11),
+ NIC_F_PROMISC = BIT(12),
+ NIC_F_ALLMULTI = BIT(13),
+ NIC_F_XSFP_REPORT = BIT(14),
+ NIC_F_VF_MAC = BIT(15),
+ NIC_F_RATE_LIMIT = BIT(16),
+ NIC_F_RXQ_RECOVERY = BIT(17),
+};
+
+#define NIC_F_ALL_MASK 0x3FFFF /* 使能所有属性 */
+
+struct hinic3_mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+#define NIC_MAX_FEATURE_QWORD 4
+struct hinic3_cmd_feature_nego {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 1: set, 0: get */
+ u8 rsvd;
+ u64 s_feature[NIC_MAX_FEATURE_QWORD];
+};
+
+struct hinic3_port_mac_set {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 rsvd1;
+ u8 mac[ETH_ALEN];
+};
+
+struct hinic3_port_mac_update {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 rsvd1;
+ u8 old_mac[ETH_ALEN];
+ u16 rsvd2;
+ u8 new_mac[ETH_ALEN];
+};
+
+struct hinic3_vport_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 state; /* 0--disable, 1--enable */
+ u8 rsvd2[3];
+};
+
+struct hinic3_port_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 state; /* 0--disable, 1--enable */
+ u8 rsvd2[3];
+};
+
+#define HINIC3_SET_PORT_CAR_PROFILE 0
+#define HINIC3_SET_PORT_CAR_STATE 1
+#define HINIC3_GET_PORT_CAR_LIMIT_SPEED 2
+
+struct hinic3_port_car_info {
+ u32 cir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
+ u32 xir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
+ u32 cbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
+ u32 xbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
+};
+
+struct hinic3_cmd_set_port_car {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode; /* 0--set car profile, 1--set car state */
+ u8 state; /* 0--disable, 1--enable */
+ u8 level;
+
+ struct hinic3_port_car_info car;
+};
+
+struct hinic3_cmd_clear_qp_resource {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_cmd_cache_out_qp_resource {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_port_stats_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_vport_stats {
+ u64 tx_unicast_pkts_vport;
+ u64 tx_unicast_bytes_vport;
+ u64 tx_multicast_pkts_vport;
+ u64 tx_multicast_bytes_vport;
+ u64 tx_broadcast_pkts_vport;
+ u64 tx_broadcast_bytes_vport;
+
+ u64 rx_unicast_pkts_vport;
+ u64 rx_unicast_bytes_vport;
+ u64 rx_multicast_pkts_vport;
+ u64 rx_multicast_bytes_vport;
+ u64 rx_broadcast_pkts_vport;
+ u64 rx_broadcast_bytes_vport;
+
+ u64 tx_discard_vport;
+ u64 rx_discard_vport;
+ u64 tx_err_vport;
+ u64 rx_err_vport;
+};
+
+struct hinic3_phy_fpga_port_stats {
+ u64 mac_rx_total_octs_port;
+ u64 mac_tx_total_octs_port;
+ u64 mac_rx_under_frame_pkts_port;
+ u64 mac_rx_frag_pkts_port;
+ u64 mac_rx_64_oct_pkts_port;
+ u64 mac_rx_127_oct_pkts_port;
+ u64 mac_rx_255_oct_pkts_port;
+ u64 mac_rx_511_oct_pkts_port;
+ u64 mac_rx_1023_oct_pkts_port;
+ u64 mac_rx_max_oct_pkts_port;
+ u64 mac_rx_over_oct_pkts_port;
+ u64 mac_tx_64_oct_pkts_port;
+ u64 mac_tx_127_oct_pkts_port;
+ u64 mac_tx_255_oct_pkts_port;
+ u64 mac_tx_511_oct_pkts_port;
+ u64 mac_tx_1023_oct_pkts_port;
+ u64 mac_tx_max_oct_pkts_port;
+ u64 mac_tx_over_oct_pkts_port;
+ u64 mac_rx_good_pkts_port;
+ u64 mac_rx_crc_error_pkts_port;
+ u64 mac_rx_broadcast_ok_port;
+ u64 mac_rx_multicast_ok_port;
+ u64 mac_rx_mac_frame_ok_port;
+ u64 mac_rx_length_err_pkts_port;
+ u64 mac_rx_vlan_pkts_port;
+ u64 mac_rx_pause_pkts_port;
+ u64 mac_rx_unknown_mac_frame_port;
+ u64 mac_tx_good_pkts_port;
+ u64 mac_tx_broadcast_ok_port;
+ u64 mac_tx_multicast_ok_port;
+ u64 mac_tx_underrun_pkts_port;
+ u64 mac_tx_mac_frame_ok_port;
+ u64 mac_tx_vlan_pkts_port;
+ u64 mac_tx_pause_pkts_port;
+};
+
+struct hinic3_port_stats {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ struct hinic3_phy_fpga_port_stats stats;
+};
+
+struct hinic3_cmd_vport_stats {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u32 stats_size;
+ u32 rsvd1;
+ struct hinic3_vport_stats stats;
+ u64 rsvd2[6];
+};
+
+struct hinic3_cmd_qpn {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 base_qpn;
+};
+
+enum hinic3_func_tbl_cfg_bitmap {
+ FUNC_CFG_INIT,
+ FUNC_CFG_RX_BUF_SIZE,
+ FUNC_CFG_MTU,
+};
+
+struct hinic3_func_tbl_cfg {
+ u16 rx_wqe_buf_size;
+ u16 mtu;
+ u32 rsvd[9];
+};
+
+struct hinic3_cmd_set_func_tbl {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd;
+
+ u32 cfg_bitmap;
+ struct hinic3_func_tbl_cfg tbl_cfg;
+};
+
+struct hinic3_cmd_cons_idx_attr {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_idx;
+ u8 dma_attr_off;
+ u8 pending_limit;
+ u8 coalescing_time;
+ u8 intr_en;
+ u16 intr_idx;
+ u32 l2nic_sqn;
+ u32 rsvd;
+ u64 ci_addr;
+};
+
+union sm_tbl_args {
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } mac_table_arg;
+ struct {
+ u32 er_id;
+ u32 vlan_id;
+ } vlan_elb_table_arg;
+ struct {
+ u32 func_id;
+ } vlan_filter_arg;
+ struct {
+ u32 mc_id;
+ } mc_elb_arg;
+ struct {
+ u32 func_id;
+ } func_tbl_arg;
+ struct {
+ u32 port_id;
+ } port_tbl_arg;
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } fdir_io_table_arg;
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } flexq_table_arg;
+ u32 args[4];
+};
+
+#define DFX_SM_TBL_BUF_MAX (768)
+
+struct nic_cmd_dfx_sm_table {
+ struct hinic3_mgmt_msg_head msg_head;
+ u32 tbl_type;
+ union sm_tbl_args args;
+ u8 tbl_buf[DFX_SM_TBL_BUF_MAX];
+};
+
+struct hinic3_cmd_vlan_offload {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 vlan_offload;
+ u8 rsvd1[5];
+};
+
+/* ucode capture cfg info */
+struct nic_cmd_capture_info {
+ struct hinic3_mgmt_msg_head msg_head;
+ u32 op_type;
+ u32 func_port;
+ u32 is_en_trx;
+ u32 offset_cos;
+ u32 data_vlan;
+};
+
+struct hinic3_cmd_lro_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u8 lro_ipv4_en;
+ u8 lro_ipv6_en;
+ u8 lro_max_pkt_len; /* unit is 1K */
+ u8 resv2[13];
+};
+
+struct hinic3_cmd_lro_timer {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 opcode; /* 1: set timer value, 0: get timer value */
+ u8 rsvd1;
+ u16 rsvd2;
+ u32 timer;
+};
+
+struct hinic3_cmd_local_lro_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 state; /* 0: disable, 1: enable */
+};
+
+struct hinic3_cmd_gtp_inner_parse_status {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 status; /* 0: disable, 1: enable */
+};
+
+struct hinic3_cmd_vf_vlan_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u16 vlan_id;
+ u8 qos;
+ u8 rsvd2[5];
+};
+
+struct hinic3_cmd_spoofchk_set {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 state;
+ u8 rsvd1;
+};
+
+struct hinic3_cmd_tx_rate_cfg {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 rsvd1;
+ u8 direct;
+ u32 min_rate;
+ u32 max_rate;
+ u8 rsvd2[8];
+};
+
+struct hinic3_cmd_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+ u8 port_type;
+ u8 autoneg_cap;
+ u8 autoneg_state;
+ u8 duplex;
+ u8 speed;
+ u8 fec;
+ u16 rsvd2;
+ u32 rsvd3[4];
+};
+
+struct hinic3_cmd_register_vf {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 op_register; /* 0 - unregister, 1 - register */
+ u8 rsvd1[3];
+ u32 support_extra_feature;
+ u8 rsvd2[32];
+};
+
+struct hinic3_cmd_link_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 state;
+ u16 rsvd1;
+};
+
+struct hinic3_cmd_vlan_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 outband_defvid_flag;
+ u16 vlan_id;
+ u8 blacklist_flag;
+ u8 rsvd2;
+};
+
+#define VLAN_BLACKLIST_ENABLE 1
+#define VLAN_BLACKLIST_DISABLE 0
+
+struct hinic3_cmd_vxlan_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 cfg_mode;
+ u16 vxlan_port;
+ u16 rsvd2;
+};
+
+/* set vlan filter */
+struct hinic3_cmd_set_vlan_filter {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 resvd[2];
+ u32 vlan_filter_ctrl; /* bit0:vlan filter en; bit1:broadcast_filter_en */
+};
+
+struct hinic3_cmd_link_ksettings_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+
+ u32 valid_bitmap;
+ u8 speed; /* enum nic_speed_level */
+ u8 autoneg; /* 0 - off, 1 - on */
+ u8 fec; /* 0 - RSFEC, 1 - BASEFEC, 2 - NOFEC */
+ u8 rsvd2[21]; /* reserved for duplex, port, etc. */
+};
+
+struct mpu_lt_info {
+ u8 node;
+ u8 inst;
+ u8 entry_size;
+ u8 rsvd;
+ u32 lt_index;
+ u32 offset;
+ u32 len;
+};
+
+struct nic_mpu_lt_opera {
+ struct hinic3_mgmt_msg_head msg_head;
+ struct mpu_lt_info net_lt_cmd;
+ u8 data[100];
+};
+
+struct hinic3_force_pkt_drop {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port;
+ u8 rsvd1[3];
+};
+
+struct hinic3_rx_mode_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u32 rx_mode;
+};
+
+/* rss */
+struct hinic3_rss_context_table {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u32 context;
+};
+
+struct hinic3_cmd_rss_engine_type {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 hash_engine;
+ u8 rsvd1[4];
+};
+
+struct hinic3_cmd_rss_hash_key {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u8 key[NIC_RSS_KEY_SIZE];
+};
+
+struct hinic3_rss_indir_table {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 indir[NIC_RSS_INDIR_SIZE];
+};
+
+#define NIC_RSS_CMD_TEMP_ALLOC 0x01
+#define NIC_RSS_CMD_TEMP_FREE 0x02
+
+struct hinic3_rss_template_mgmt {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 cmd;
+ u8 template_id;
+ u8 rsvd1[4];
+};
+
+struct hinic3_cmd_rss_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 rss_en;
+ u8 rq_priority_number;
+ u8 prio_tc[NIC_DCB_COS_MAX];
+ u16 num_qps;
+ u16 rsvd1;
+};
+
+struct hinic3_dcb_state {
+ u8 dcb_on;
+ u8 default_cos;
+ u8 trust;
+ u8 rsvd1;
+ u8 pcp2cos[NIC_DCB_UP_MAX];
+ u8 dscp2cos[64];
+ u32 rsvd2[7];
+};
+
+struct hinic3_cmd_vf_dcb_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ struct hinic3_dcb_state state;
+};
+
+struct hinic3_up_ets_cfg { /* delet */
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+
+ u8 cos_tc[NIC_DCB_COS_MAX];
+ u8 tc_bw[NIC_DCB_TC_MAX];
+ u8 cos_prio[NIC_DCB_COS_MAX];
+ u8 cos_bw[NIC_DCB_COS_MAX];
+ u8 tc_prio[NIC_DCB_TC_MAX];
+};
+
+#define CMD_QOS_ETS_COS_TC BIT(0)
+#define CMD_QOS_ETS_TC_BW BIT(1)
+#define CMD_QOS_ETS_COS_PRIO BIT(2)
+#define CMD_QOS_ETS_COS_BW BIT(3)
+#define CMD_QOS_ETS_TC_PRIO BIT(4)
+#define CMD_QOS_ETS_TC_RATELIMIT BIT(5)
+
+struct hinic3_cmd_ets_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 1 - set, 0 - get */
+ /* bit0 - cos_tc, bit1 - tc_bw, bit2 - cos_prio, bit3 - cos_bw, bit4 - tc_prio */
+ u8 cfg_bitmap;
+ u8 rsvd;
+
+ u8 cos_tc[NIC_DCB_COS_MAX];
+ u8 tc_bw[NIC_DCB_TC_MAX];
+ u8 cos_prio[NIC_DCB_COS_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 cos_bw[NIC_DCB_COS_MAX];
+ u8 tc_prio[NIC_DCB_TC_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 rate_limit[NIC_DCB_TC_MAX];
+};
+
+struct hinic3_cmd_set_dcb_state {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 op_code; /* 0 - get dcb state, 1 - set dcb state */
+ u8 state; /* 0 - disable, 1 - enable dcb */
+ u8 port_state; /* 0 - disable, 1 - enable dcb */
+ u8 rsvd[7];
+};
+
+#define PFC_BIT_MAP_NUM 8
+struct hinic3_cmd_set_pfc {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 0:get 1: set pfc_en 2: set pfc_bitmap 3: set all */
+ u8 pfc_en; /* pfc_en 和 pfc_bitmap 必须同时设置 */
+ u8 pfc_bitmap;
+ u8 rsvd[4];
+};
+
+#define CMD_QOS_PORT_TRUST BIT(0)
+#define CMD_QOS_PORT_DFT_COS BIT(1)
+struct hinic3_cmd_qos_port_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 0 - get, 1 - set */
+ u8 cfg_bitmap; /* bit0 - trust, bit1 - dft_cos */
+ u8 rsvd0;
+
+ u8 trust;
+ u8 dft_cos;
+ u8 rsvd1[18];
+};
+
+#define MAP_COS_MAX_NUM 8
+#define CMD_QOS_MAP_PCP2COS BIT(0)
+#define CMD_QOS_MAP_DSCP2COS BIT(1)
+struct hinic3_cmd_qos_map_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 op_code;
+ u8 cfg_bitmap; /* bit0 - pcp2cos, bit1 - dscp2cos */
+ u16 rsvd0;
+
+ u8 pcp2cos[8]; /* 8 must be configured together */
+ /* If the dscp2cos parameter is set to 0xFF, the MPU ignores the DSCP priority,
+ * Multiple mappings between DSCP values and CoS values can be configured at a time.
+ */
+ u8 dscp2cos[64];
+ u32 rsvd1[4];
+};
+
+struct hinic3_cos_up_map {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 cos_valid_mask; /* every bit indicate index of map is valid 1 or not 0 */
+ u16 rsvd1;
+
+ /* user priority in cos(index:cos, value: up pri) */
+ u8 map[NIC_DCB_UP_MAX];
+};
+
+struct hinic3_cmd_pause_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode;
+ u16 rsvd1;
+ u8 auto_neg;
+ u8 rx_pause;
+ u8 tx_pause;
+ u8 rsvd2[5];
+};
+
+struct nic_cmd_pause_inquiry_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 valid;
+
+ u32 type; /* 1: set, 2: get */
+
+ u32 cos_id;
+
+ u32 rx_inquiry_pause_drop_pkts_en;
+ u32 rx_inquiry_pause_period_ms;
+ u32 rx_inquiry_pause_times;
+ /* rx pause Detection Threshold, Default PAUSE_FRAME_THD_10G/25G/40G/100 */
+ u32 rx_inquiry_pause_frame_thd;
+ u32 rx_inquiry_tx_total_pkts;
+
+ u32 tx_inquiry_pause_en; /* tx pause detect enable */
+ u32 tx_inquiry_pause_period_ms; /* tx pause Default Detection Period 200ms */
+ u32 tx_inquiry_pause_times; /* tx pause Default Times Period 5 */
+ u32 tx_inquiry_pause_frame_thd; /* tx pause Detection Threshold */
+ u32 tx_inquiry_rx_total_pkts;
+ u32 rsvd[3];
+};
+
+/* pfc/pause Storm TX exception reporting */
+struct nic_cmd_tx_pause_notice {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 tx_pause_except; /* 1: abnormality,0: normal */
+ u32 except_level;
+ u32 rsvd;
+};
+
+#define HINIC3_CMD_OP_FREE 0
+#define HINIC3_CMD_OP_ALLOC 1
+
+struct hinic3_cmd_cfg_qps {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 1: alloc qp, 0: free qp */
+ u8 rsvd1;
+ u16 num_qps;
+ u16 rsvd2;
+};
+
+struct hinic3_cmd_led_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port;
+ u8 type;
+ u8 mode;
+ u8 rsvd1;
+};
+
+struct hinic3_cmd_port_loopback {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode;
+ u8 mode;
+ u8 en;
+ u32 rsvd1[2];
+};
+
+struct hinic3_cmd_get_light_module_abs {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 abs_status; /* 0:present, 1:absent */
+ u8 rsv[2];
+};
+
+#define STD_SFP_INFO_MAX_SIZE 640
+struct hinic3_cmd_get_std_sfp_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 wire_type;
+ u16 eeprom_len;
+ u32 rsvd;
+ u8 sfp_info[STD_SFP_INFO_MAX_SIZE];
+};
+
+struct hinic3_cable_plug_event {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 plugged; /* 0: unplugged, 1: plugged */
+ u8 port_id;
+};
+
+struct nic_cmd_mac_info {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 valid_bitmap;
+ u16 rsvd;
+
+ u8 host_id[32];
+ u8 port_id[32];
+ u8 mac_addr[192];
+};
+
+struct nic_cmd_set_tcam_enable {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 tcam_enable;
+ u8 rsvd1;
+ u32 rsvd2;
+};
+
+struct nic_cmd_set_fdir_status {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 pkt_type_en;
+ u8 pkt_type;
+ u8 qid;
+ u8 rsvd2;
+};
+
+#define HINIC3_TCAM_BLOCK_ENABLE 1
+#define HINIC3_TCAM_BLOCK_DISABLE 0
+#define HINIC3_MAX_TCAM_RULES_NUM 4096
+
+/* tcam block type, according to tcam block size */
+enum {
+ NIC_TCAM_BLOCK_TYPE_LARGE = 0, /* block_size: 16 */
+ NIC_TCAM_BLOCK_TYPE_SMALL, /* block_size: 0 */
+ NIC_TCAM_BLOCK_TYPE_MAX
+};
+
+/* alloc tcam block input struct */
+struct nic_cmd_ctrl_tcam_block_in {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
+ /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
+ u8 tcam_type;
+ u16 tcam_block_index;
+ /* Size of the block that the driver wants to allocate
+ * Interface returned by the UP to the driver,
+ * indicating the size of the allocated TCAM block supported by the UP
+ */
+ u16 alloc_block_num;
+};
+
+/* alloc tcam block output struct */
+struct nic_cmd_ctrl_tcam_block_out {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
+ /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
+ u8 tcam_type;
+ u16 tcam_block_index;
+ /* Size of the block that the driver wants to allocate
+ * Interface returned by the UP to the driver,
+ * indicating the size of the allocated TCAM block supported by the UP
+ */
+ u16 mpu_alloc_block_size;
+};
+
+struct nic_cmd_flush_tcam_rules {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u16 rsvd;
+};
+
+struct nic_cmd_dfx_fdir_tcam_block_table {
+ struct hinic3_mgmt_msg_head head;
+ u8 tcam_type;
+ u8 valid;
+ u16 tcam_block_index;
+ u16 use_function_id;
+ u16 rsvd;
+};
+
+struct tcam_result {
+ u32 qid;
+ u32 rsvd;
+};
+
+#define TCAM_FLOW_KEY_SIZE (44)
+
+struct tcam_key_x_y {
+ u8 x[TCAM_FLOW_KEY_SIZE];
+ u8 y[TCAM_FLOW_KEY_SIZE];
+};
+
+struct nic_tcam_cfg_rule {
+ u32 index;
+ struct tcam_result data;
+ struct tcam_key_x_y key;
+};
+
+#define TCAM_RULE_FDIR_TYPE 0
+#define TCAM_RULE_PPA_TYPE 1
+
+struct nic_cmd_fdir_add_rule {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 type;
+ u8 fdir_ext; /* 0x1: flow bifur en bit */
+ struct nic_tcam_cfg_rule rule;
+};
+
+struct nic_cmd_fdir_del_rules {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 type;
+ u8 rsvd;
+ u32 index_start;
+ u32 index_num;
+};
+
+struct nic_cmd_fdir_get_rule {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 index;
+ u8 valid;
+ u8 type;
+ u16 rsvd;
+ struct tcam_key_x_y key;
+ struct tcam_result data;
+ u64 packet_count;
+ u64 byte_count;
+};
+
+struct nic_cmd_fdir_get_block_rules {
+ struct hinic3_mgmt_msg_head head;
+ u8 tcam_block_type; // only NIC_TCAM_BLOCK_TYPE_LARGE
+ u8 tcam_table_type; // TCAM_RULE_PPA_TYPE or TCAM_RULE_FDIR_TYPE
+ u16 tcam_block_index;
+ u8 valid[NIC_TCAM_BLOCK_LARGE_SIZE];
+ struct tcam_key_x_y key[NIC_TCAM_BLOCK_LARGE_SIZE];
+ struct tcam_result data[NIC_TCAM_BLOCK_LARGE_SIZE];
+};
+
+struct hinic3_tcam_key_ipv4_mem {
+ u32 rsvd1 : 1;
+ u32 bifur_flag : 2;
+ u32 model : 1;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+ u32 sipv4_h : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+ u32 dipv4_h : 16;
+ u32 sipv4_l : 16;
+ u32 vlan_id : 15;
+ u32 vlan_flag : 1;
+ u32 dipv4_l : 16;
+ u32 rsvd3;
+ u32 dport : 16;
+ u32 rsvd4 : 16;
+ u32 rsvd5 : 16;
+ u32 sport : 16;
+ u32 outer_sipv4_h : 16;
+ u32 rsvd6 : 16;
+ u32 outer_dipv4_h : 16;
+ u32 outer_sipv4_l : 16;
+ u32 vni_h : 16;
+ u32 outer_dipv4_l : 16;
+ u32 rsvd7 : 16;
+ u32 vni_l : 16;
+};
+
+union hinic3_tag_tcam_ext_info {
+ struct {
+ u32 id : 16; /* id */
+ u32 type : 4; /* type: 0-func, 1-vmdq, 2-port, 3-rsvd, 4-trunk, 5-dp, 6-mc */
+ u32 host_id : 3;
+ u32 rss_q_num : 8; /* rss queue num */
+ u32 ext : 1;
+ } bs;
+ u32 value;
+};
+
+struct hinic3_tcam_key_ipv6_mem {
+ u32 bifur_flag : 2;
+ u32 vlan_flag : 1;
+ u32 outer_ip_type : 1;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+ u32 sipv6_key0 : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+ u32 sipv6_key2 : 16;
+ u32 sipv6_key1 : 16;
+ u32 sipv6_key4 : 16;
+ u32 sipv6_key3 : 16;
+ u32 sipv6_key6 : 16;
+ u32 sipv6_key5 : 16;
+ u32 dport : 16;
+ u32 sipv6_key7 : 16;
+ u32 dipv6_key0 : 16;
+ u32 sport : 16;
+ u32 dipv6_key2 : 16;
+ u32 dipv6_key1 : 16;
+ u32 dipv6_key4 : 16;
+ u32 dipv6_key3 : 16;
+ u32 dipv6_key6 : 16;
+ u32 dipv6_key5 : 16;
+ u32 rsvd2 : 16;
+ u32 dipv6_key7 : 16;
+};
+
+struct hinic3_tcam_key_vxlan_ipv6_mem {
+ u32 rsvd1 : 4;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+
+ u32 dipv6_key0 : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+
+ u32 dipv6_key2 : 16;
+ u32 dipv6_key1 : 16;
+
+ u32 dipv6_key4 : 16;
+ u32 dipv6_key3 : 16;
+
+ u32 dipv6_key6 : 16;
+ u32 dipv6_key5 : 16;
+
+ u32 dport : 16;
+ u32 dipv6_key7 : 16;
+
+ u32 rsvd2 : 16;
+ u32 sport : 16;
+
+ u32 outer_sipv4_h : 16;
+ u32 rsvd3 : 16;
+
+ u32 outer_dipv4_h : 16;
+ u32 outer_sipv4_l : 16;
+
+ u32 vni_h : 16;
+ u32 outer_dipv4_l : 16;
+
+ u32 rsvd4 : 16;
+ u32 vni_l : 16;
+};
+
+struct tag_tcam_key {
+ union {
+ struct hinic3_tcam_key_ipv4_mem key_info;
+ struct hinic3_tcam_key_ipv6_mem key_info_ipv6;
+ struct hinic3_tcam_key_vxlan_ipv6_mem key_info_vxlan_ipv6;
+ };
+
+ union {
+ struct hinic3_tcam_key_ipv4_mem key_mask;
+ struct hinic3_tcam_key_ipv6_mem key_mask_ipv6;
+ struct hinic3_tcam_key_vxlan_ipv6_mem key_mask_vxlan_ipv6;
+ };
+};
+
+enum {
+ PPA_TABLE_ID_CLEAN_CMD = 0,
+ PPA_TABLE_ID_ADD_CMD,
+ PPA_TABLE_ID_DEL_CMD,
+ FDIR_TABLE_ID_ADD_CMD,
+ FDIR_TABLE_ID_DEL_CMD,
+ PPA_TABEL_ID_MAX
+};
+
+struct hinic3_ppa_cfg_table_id_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u16 cmd;
+ u16 table_id;
+ u16 rsvd1;
+};
+
+struct hinic3_ppa_cfg_ppa_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 ppa_en;
+ u8 ppa_miss_drop_en;
+};
+
+struct hinic3_func_flow_bifur_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 func_id;
+ u8 flow_bifur_en;
+ u8 rsvd[5];
+};
+
+struct hinic3_port_flow_bifur_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 port_id;
+ u8 flow_bifur_en;
+ u8 flow_bifur_type; /* 0->vf bifur, 2->traffic bifur */
+ u8 rsvd[4];
+};
+
+struct hinic3_bond_mask_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 func_id;
+ u8 bond_mask;
+ u8 bond_en;
+ u8 func_valid;
+ u8 rsvd[3];
+};
+
+struct hinic3_func_er_value_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 vf_id;
+ u16 er_fwd_id;
+};
+
+#define HINIC3_TX_SET_PROMISC_SKIP 0
+#define HINIC3_TX_GET_PROMISC_SKIP 1
+
+#define HINIC3_GET_TRAFFIC_BIFUR_STATE 0
+#define HINIC3_SET_TRAFFIC_BIFUR_STATE 1
+
+struct hinic3_tx_promisc_cfg {
+ struct hinic3_mgmt_msg_head msg_head;
+ u8 port_id;
+ u8 promisc_skip_en; /* 0: disable tx promisc replication, 1: enable */
+ u8 opcode; /* 0: set, 1: get */
+ u8 rsvd1;
+};
+
+struct hinic3_ppa_cfg_mode_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u8 ppa_mode;
+ u8 qpc_func_nums;
+ u16 base_qpc_func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_ppa_flush_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u8 flush_en; /* 0 flush done, 1 in flush operation */
+ u8 rsvd1;
+};
+
+struct hinic3_ppa_fdir_query_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u32 index;
+ u32 rsvd;
+ u64 pkt_nums;
+ u64 pkt_bytes;
+};
+
+/* BIOS CONF */
+enum {
+ NIC_NVM_DATA_SET = BIT(0), /* 1-save, 0-read */
+ NIC_NVM_DATA_PXE = BIT(1),
+ NIC_NVM_DATA_VLAN = BIT(2),
+ NIC_NVM_DATA_VLAN_PRI = BIT(3),
+ NIC_NVM_DATA_VLAN_ID = BIT(4),
+ NIC_NVM_DATA_WORK_MODE = BIT(5),
+ NIC_NVM_DATA_PF_TX_SPEED_LIMIT = BIT(6),
+ NIC_NVM_DATA_GE_MODE = BIT(7),
+ NIC_NVM_DATA_AUTO_NEG = BIT(8),
+ NIC_NVM_DATA_LINK_FEC = BIT(9),
+ NIC_NVM_DATA_PF_ADAPTIVE_LINK = BIT(10),
+ NIC_NVM_DATA_SRIOV_CONTROL = BIT(11),
+ NIC_NVM_DATA_EXTEND_MODE = BIT(12),
+ NIC_NVM_DATA_LEGACY_VLAN = BIT(13),
+ NIC_NVM_DATA_LEGACY_VLAN_PRI = BIT(14),
+ NIC_NVM_DATA_LEGACY_VLAN_ID = BIT(15),
+ NIC_NVM_DATA_RESET = BIT(31),
+};
+
+#define BIOS_CFG_SIGNATURE 0x1923E518
+#define BIOS_OP_CFG_ALL(op_code_val) \
+ ((((op_code_val) >> 1) & (0xFFFFFFFF)) != 0)
+#define BIOS_OP_CFG_WRITE(op_code_val) \
+ ((((op_code_val) & NIC_NVM_DATA_SET)) != 0)
+#define BIOS_OP_CFG_PXE_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PXE) != 0)
+#define BIOS_OP_CFG_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN) != 0)
+#define BIOS_OP_CFG_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_ID) != 0)
+#define BIOS_OP_CFG_WORK_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_WORK_MODE) != 0)
+#define BIOS_OP_CFG_PF_BW(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_TX_SPEED_LIMIT) != 0)
+#define BIOS_OP_CFG_GE_SPEED(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_GE_MODE) != 0)
+#define BIOS_OP_CFG_AUTO_NEG(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_AUTO_NEG) != 0)
+#define BIOS_OP_CFG_LINK_FEC(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LINK_FEC) != 0)
+#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_ADAPTIVE_LINK) != 0)
+#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_SRIOV_CONTROL) != 0)
+#define BIOS_OP_CFG_EXTEND_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_EXTEND_MODE) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_ID) != 0)
+#define BIOS_OP_CFG_RST_DEF_SET(op_code_val) \
+ (((op_code_val) & (u32)NIC_NVM_DATA_RESET) != 0)
+
+
+#define NIC_BIOS_CFG_MAX_PF_BW 100
+
+struct nic_legacy_vlan_cfg {
+ /* Legacy mode PXE VLAN enable: 0 - disable 1 - enable */
+ u8 pxe_vlan_en : 1;
+ /* Legacy mode PXE VLAN priority: 0-7 */
+ u8 pxe_vlan_pri : 3;
+ /* Legacy mode PXE VLAN ID 1-4094 */
+ u16 pxe_vlan_id : 12;
+};
+
+/* Note: This structure must be 4-byte aligned. */
+struct nic_bios_cfg {
+ u32 signature;
+ u8 pxe_en;
+ u8 extend_mode;
+ struct nic_legacy_vlan_cfg nlvc;
+ u8 pxe_vlan_en;
+ u8 pxe_vlan_pri;
+ u16 pxe_vlan_id;
+ u32 service_mode;
+ u32 pf_tx_bw;
+ u8 speed;
+ u8 auto_neg;
+ u8 lanes;
+ u8 fec;
+ u8 auto_adapt;
+ u8 func_valid;
+ u8 func_id;
+ u8 sriov_en;
+};
+
+struct nic_cmd_bios_cfg {
+ struct hinic3_mgmt_msg_head head;
+ u32 op_code; /* Operation Code: Bit0[0: read 1:write, BIT1-6: cfg_mask */
+ struct nic_bios_cfg bios_cfg;
+};
+
+struct nic_rx_rate_bios_cfg {
+ struct mgmt_msg_head msg_head;
+
+ u32 op_code; /* Operation Code:[0:read 1:write] */
+ u8 rx_rate_limit;
+ u8 func_id;
+};
+
+struct nic_cmd_vhd_config {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 vhd_type;
+ u8 virtio_small_enable; /* 0: mergeable mode, 1: small mode */
+};
+
+/* BOND */
+struct hinic3_create_bond_info {
+ u32 bond_id;
+ u32 master_slave_port_id;
+ u32 slave_bitmap; /* bond port id bitmap */
+ u32 poll_timeout; /* Bond device link check time */
+ u32 up_delay; /* Temporarily reserved */
+ u32 down_delay; /* Temporarily reserved */
+ u32 bond_mode; /* Temporarily reserved */
+ u32 active_pf; /* bond use active pf id */
+ u32 active_port_max_num; /* Maximum number of active bond member interfaces */
+ u32 active_port_min_num; /* Minimum number of active bond member interfaces */
+ u32 xmit_hash_policy;
+ u32 default_param_flag;
+ u32 rsvd;
+};
+
+struct hinic3_cmd_create_bond {
+ struct hinic3_mgmt_msg_head head;
+ struct hinic3_create_bond_info create_bond_info;
+};
+
+struct hinic3_cmd_delete_bond {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 rsvd[2];
+};
+
+struct hinic3_open_close_bond_info {
+ u32 bond_id;
+ u32 open_close_flag; /* Bond flag. 1: open; 0: close. */
+ u32 rsvd[2];
+};
+
+struct hinic3_cmd_open_close_bond {
+ struct hinic3_mgmt_msg_head head;
+ struct hinic3_open_close_bond_info open_close_bond_info;
+};
+
+struct lacp_port_params {
+ u16 port_number;
+ u16 port_priority;
+ u16 key;
+ u16 system_priority;
+ u8 system[ETH_ALEN];
+ u8 port_state;
+ u8 rsvd;
+};
+
+struct lacp_port_info {
+ u32 selected;
+ u32 aggregator_port_id;
+
+ struct lacp_port_params actor;
+ struct lacp_port_params partner;
+
+ u64 tx_lacp_pkts;
+ u64 rx_lacp_pkts;
+ u64 rx_8023ad_drop;
+ u64 tx_8023ad_drop;
+ u64 unknown_pkt_drop;
+ u64 rx_marker_pkts;
+ u64 tx_marker_pkts;
+};
+
+struct hinic3_bond_status_info {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 bon_mmi_status;
+ u32 active_bitmap;
+ u32 port_count;
+
+ struct lacp_port_info port_info[4];
+
+ u64 success_report_cnt[4];
+ u64 fail_report_cnt[4];
+
+ u64 poll_timeout;
+ u64 fast_periodic_timeout;
+ u64 slow_periodic_timeout;
+ u64 short_timeout;
+ u64 long_timeout;
+ u64 aggregate_wait_timeout;
+ u64 tx_period_timeout;
+ u64 rx_marker_timer;
+};
+
+struct hinic3_bond_active_report_info {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 bon_mmi_status;
+ u32 active_bitmap;
+
+ u8 rsvd[16];
+};
+
+/* IP checksum error packets, enable rss quadruple hash. */
+struct hinic3_ipcs_err_rss_enable_operation_s {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 en_tag;
+ u8 type; /* 1: set 0: get */
+ u8 rsvd[2];
+};
+
+struct hinic3_smac_check_state {
+ struct hinic3_mgmt_msg_head head;
+ u8 smac_check_en; /* 1: enable 0: disable */
+ u8 op_code; /* 1: set 0: get */
+ u8 flash_en; /* 1: enable 0: disable */
+ u8 rsvd;
+};
+
+struct hinic3_clear_log_state {
+ struct hinic3_mgmt_msg_head head;
+ u32 type;
+};
+
+struct hinic3_outband_cfg_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 outband_default_vid;
+ u16 func_id;
+};
+
+struct hinic3_wr_ordering {
+ struct hinic3_mgmt_msg_head head;
+ u8 op_code; /* 1: set 0: get */
+ u8 wr_pkt_so_ro;
+ u8 rd_pkt_so_ro;
+ u8 rsvd;
+};
+
+struct hinic3_function_active_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_rq_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rq_depth;
+ u16 rq_num;
+ u16 pf_num;
+ u16 port_num;
+};
+
+#endif /* HINIC_MGMT_INTERFACE_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
new file mode 100644
index 0000000..97eda43
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
+ * File Name : nic_npu_cmd.h
+ * Version : Initial Draft
+ * Created : 2019/4/25
+ * Last Modified :
+ * Description : NIC Commands between Driver and NPU
+ * Function List :
+ */
+
+#ifndef NIC_NPU_CMD_H
+#define NIC_NPU_CMD_H
+
+/* NIC CMDQ MODE */
+enum hinic3_ucode_cmd {
+ HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
+ HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
+ HINIC3_UCODE_CMD_ARM_SQ, /**< Unused */
+ HINIC3_UCODE_CMD_ARM_RQ, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_IQ_ENABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
+ HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
+ HINIC3_UCODE_CMD_PPA_HASH_TABLE,
+ HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_UCODE_MIG_CFG_Q_CTX = 14,
+ HINIC3_UCODE_MIG_CHK_SQ_STOP,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ HINIC3_UCODE_MIG_CFG_BAT_INFO,
+};
+
+#endif /* NIC_NPU_CMD_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
index ee005a8..5f0f790 100644
--- a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
+++ b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
@@ -4,8 +4,8 @@
#ifndef OSSL_KNL_LINUX_H_
#define OSSL_KNL_LINUX_H_
-#include <net/checksum.h>
#include <net/ipv6.h>
+#include <net/devlink.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/device.h>
@@ -19,6 +19,12 @@
#include <linux/list.h>
#include <linux/bitmap.h>
#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/filter.h>
+#include <linux/aer.h>
+#include <linux/socket.h>
#ifndef NETIF_F_SCTP_CSUM
#define NETIF_F_SCTP_CSUM 0
@@ -37,6 +43,17 @@
#define ossl_get_free_pages __get_free_pages
+#ifndef ETHTOOL_LINK_MODE_100000baseKR_Full_BIT
+#define ETHTOOL_LINK_MODE_100000baseKR_Full_BIT 75
+#define ETHTOOL_LINK_MODE_100000baseCR_Full_BIT 78
+#define ETHTOOL_LINK_MODE_100000baseSR_Full_BIT 76
+#endif
+#ifndef ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT
+#define ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT 80
+#define ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT 81
+#define ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT 84
+#endif
+
#ifndef high_16_bits
#define low_16_bits(x) ((x) & 0xFFFF)
#define high_16_bits(x) (((x) & 0xFFFF0000) >> 16)
@@ -54,13 +71,11 @@
#endif
#define HAVE_INET6_IFADDR_LIST
-
#define HAVE_NDO_GET_STATS64
#ifndef HAVE_MQPRIO
#define HAVE_MQPRIO
#endif
-
#ifndef HAVE_SETUP_TC
#define HAVE_SETUP_TC
#endif
@@ -68,25 +83,20 @@
#ifndef HAVE_NDO_SET_FEATURES
#define HAVE_NDO_SET_FEATURES
#endif
-
#define HAVE_IRQ_AFFINITY_NOTIFY
-
#define HAVE_ETHTOOL_SET_PHYS_ID
-
#define HAVE_NETDEV_WANTED_FEAUTES
#ifndef HAVE_PCI_DEV_FLAGS_ASSIGNED
#define HAVE_PCI_DEV_FLAGS_ASSIGNED
#define HAVE_VF_SPOOFCHK_CONFIGURE
#endif
-
#ifndef HAVE_SKB_L4_RXHASH
#define HAVE_SKB_L4_RXHASH
#endif
#define HAVE_ETHTOOL_GRXFHINDIR_SIZE
#define HAVE_INT_NDO_VLAN_RX_ADD_VID
-
#ifdef ETHTOOL_SRXNTUPLE
#undef ETHTOOL_SRXNTUPLE
#endif
@@ -95,9 +105,9 @@
#define _kc_kunmap_atomic(addr) kunmap_atomic(addr)
#include <linux/of_net.h>
-
#define HAVE_FDB_OPS
#define HAVE_ETHTOOL_GET_TS_INFO
+
#define HAVE_NAPI_GRO_FLUSH_OLD
#ifndef HAVE_SRIOV_CONFIGURE
@@ -107,6 +117,7 @@
#define HAVE_ENCAP_TSO_OFFLOAD
#define HAVE_SKB_INNER_NETWORK_HEADER
+
#define HAVE_NDO_SET_VF_LINK_STATE
#define HAVE_SKB_INNER_PROTOCOL
#define HAVE_MPLS_FEATURES
@@ -115,12 +126,12 @@
#define HAVE_NETIF_SET_XPS_QUEUE_CONST_MASK
#define HAVE_VXLAN_CHECKS
-#define HAVE_NDO_SELECT_QUEUE_ACCEL
#define HAVE_NET_GET_RANDOM_ONCE
#define HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS
#define HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK
+
#define HAVE_NDO_SET_VF_MIN_MAX_TX_RATE
#define HAVE_VLAN_FIND_DEV_DEEP_RCU
@@ -128,8 +139,8 @@
#define HAVE_MULTI_VLAN_OFFLOAD_EN
#define HAVE_ETH_GET_HEADLEN_FUNC
-#define HAVE_RXFH_HASHFUNC
+#define HAVE_RXFH_HASHFUNC
#define HAVE_NDO_SET_VF_TRUST
#include <net/devlink.h>
@@ -138,6 +149,7 @@
#define HAVE_NETDEVICE_MIN_MAX_MTU
+
#define HAVE_VOID_NDO_GET_STATS64
#define HAVE_VM_OPS_FAULT_NO_VMA
@@ -146,9 +158,13 @@
#define HAVE_PCI_ERROR_HANDLER_RESET_PREPARE
#define HAVE_PTP_CLOCK_DO_AUX_WORK
+
#define HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV
#define HAVE_XDP_SUPPORT
+#if (KERNEL_VERSION(5, 9, 0) > LINUX_VERSION_CODE)
+#define HAVE_XDP_QUERY_PROG
+#endif
#define HAVE_NDO_BPF_NETDEV_BPF
#define HAVE_TIMER_SETUP
@@ -158,6 +174,7 @@
#define HAVE_NDO_SELECT_QUEUE_SB_DEV
+
#define dev_open(x) dev_open(x, NULL)
#define HAVE_NEW_ETHTOOL_LINK_SETTINGS_ONLY
@@ -180,12 +197,14 @@ static inline void *_hinic3_dma_zalloc_coherent(struct device *dev,
}
#endif
+#if (KERNEL_VERSION(5, 6, 0) <= LINUX_VERSION_CODE)
#ifndef DT_KNL_EMU
struct timeval {
__kernel_old_time_t tv_sec; /* seconds */
__kernel_suseconds_t tv_usec; /* microseconds */
};
#endif
+#endif
#ifndef do_gettimeofday
#define do_gettimeofday(time) _kc_do_gettimeofday(time)
@@ -199,6 +218,8 @@ static inline void _kc_do_gettimeofday(struct timeval *tv)
}
#endif
+
+
#define HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY
#define ETH_GET_HEADLEN_NEED_DEV
#define HAVE_GENL_OPS_FIELD_VALIDATE
@@ -207,32 +228,75 @@ static inline void _kc_do_gettimeofday(struct timeval *tv)
#define FIELD_SIZEOF(t, f) (sizeof(((t *)0)->f))
#endif
+/*****************************************************************************/
+#if (KERNEL_VERSION(5, 5, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.5.0 */
#define HAVE_DEVLINK_FLASH_UPDATE_PARAMS
+#endif /* 5.5.0 */
+/*****************************************************************************/
+#if (KERNEL_VERSION(5, 6, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.6.0 */
#ifndef rtc_time_to_tm
#define rtc_time_to_tm rtc_time64_to_tm
#endif
#define HAVE_NDO_TX_TIMEOUT_TXQ
#define HAVE_PROC_OPS
+#endif /* 5.6.0 */
+/*****************************************************************************/
+#if (KERNEL_VERSION(5, 7, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.7.0 */
#define SUPPORTED_COALESCE_PARAMS
#ifndef pci_cleanup_aer_uncorrect_error_status
#define pci_cleanup_aer_uncorrect_error_status pci_aer_clear_nonfatal_status
#endif
+#endif /* 5.7.0 */
+
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 9, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.9.0 */
#define HAVE_XDP_FRAME_SZ
+#endif /* 5.9.0 */
+
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE)
+#define HAVE_DEVLINK_FW_FILE_NAME_PARAM
+#else /* >= 5.10.0 */
+#endif /* 5.10.0 */
#define HAVE_DEVLINK_FW_FILE_NAME_MEMBER
-#define HAVE_ENCAPSULATION_TSO
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.10.0 */
+#if !defined(HAVE_ETHTOOL_COALESCE_EXTACK) && \
+ !defined(NO_ETHTOOL_COALESCE_EXTACK)
+#define HAVE_ETHTOOL_COALESCE_EXTACK
+#endif
+#endif /* 5.10.0 */
+
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE)
+
+#else /* >= 5.10.0 */
+#if !defined(HAVE_ETHTOOL_RINGPARAM_EXTACK) && \
+ !defined(NO_ETHTOOL_RINGPARAM_EXTACK)
+#define HAVE_ETHTOOL_RINGPARAM_EXTACK
+#endif
+#endif /* 5.10.0 */
+/* ************************************************************************ */
+#define HAVE_NDO_UDP_TUNNEL_ADD
+#define HAVE_ENCAPSULATION_TSO
#define HAVE_ENCAPSULATION_CSUM
#ifndef eth_zero_addr
static inline void hinic3_eth_zero_addr(u8 *addr)
{
- memset(addr, 0x00, ETH_ALEN);
+ (void)memset(addr, 0x00, ETH_ALEN);
}
#define eth_zero_addr(_addr) hinic3_eth_zero_addr(_addr)
@@ -273,13 +337,10 @@ int creat_thread(struct sdk_thread_info *thread_info);
void stop_thread(struct sdk_thread_info *thread_info);
#define destroy_work(work)
-
void utctime_to_localtime(u64 utctime, u64 *localtime);
-
#ifndef HAVE_TIMER_SETUP
void initialize_timer(const void *adapter_hdl, struct timer_list *timer);
#endif
-
void add_to_timer(struct timer_list *timer, u64 period);
void stop_timer(struct timer_list *timer);
void delete_timer(struct timer_list *timer);
@@ -304,3 +365,4 @@ u64 ossl_get_real_time(void);
#define tasklet_state(tasklet) ((tasklet)->state)
#endif
+/* ************************************************************************ */
--
2.45.1.windows.1
2
1

08 May '25
Binbin Zhou (1):
dt-bindings: pwm: Add Loongson PWM controller
Ming Wang (1):
LoongArch: Return NULL from huge_pte_offset() for invalid PMD
Tianyang Zhang (3):
mm/page_alloc.c: avoid infinite retries caused by cpuset race
nvme: Add udelay to avoid data error caused by dma sequence
megaraid: Add udelay to avoid data error caused by dma sequence
wanghongliang (5):
pwm: Add Loongson pwm driver support
LoongArch: CONFIG_NR_CPUS expanded to 2048
LoongArch: Enable IGC driver
LoongArch: Enable GPIO_PCA953X driver
LoongArch: support CONFIG_SCHED_MC
.../bindings/pwm/loongson,ls7a-pwm.yaml | 67 +++++
MAINTAINERS | 7 +
arch/loongarch/Kconfig | 16 +-
arch/loongarch/configs/loongson3_defconfig | 4 +-
arch/loongarch/include/asm/smp.h | 1 +
arch/loongarch/include/asm/topology.h | 9 +
arch/loongarch/kernel/smp.c | 46 +++
arch/loongarch/mm/hugetlbpage.c | 2 +-
drivers/nvme/host/pci.c | 10 +
drivers/pwm/Kconfig | 12 +
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-loongson.c | 280 ++++++++++++++++++
drivers/scsi/megaraid/megaraid_sas_fusion.c | 8 +-
mm/page_alloc.c | 8 +
14 files changed, 465 insertions(+), 6 deletions(-)
create mode 100644 Documentation/devicetree/bindings/pwm/loongson,ls7a-pwm.yaml
create mode 100644 drivers/pwm/pwm-loongson.c
--
2.33.0
2
11

08 May '25
From: fuguiming <fuguiming(a)huawei.com>
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IC5K0L?from=project-issue
CVE: NA
--------------------------------
Add optical module type adaptation.
Add ethtool fec function.
Add NIC XDP PASS function.
Add QoS persistence.
Add NIC out-of-band VLAN configuration function.
Fix NIC bifur bugs.
Fix performance test bugs.
Fix NIC RX bugs.
Fix NIC VF bugs.
Fix the bug of exiting when probing NIC.
Fix bond bugs.
Fix the bug of MAC address configuration failure in OS 6.6.
Fix the bug of reading NIC status incorrectly.
Fix and add some statistics.
Signed-off-by: fuguiming <fuguiming(a)huawei.com>
---
drivers/net/ethernet/huawei/hinic3/Makefile | 1 +
drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c | 3 +-
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c | 181 ++-
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h | 1 +
drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h | 212 ---
drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h | 239 ---
drivers/net/ethernet/huawei/hinic3/comm_defs.h | 100 --
drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h | 103 --
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c | 40 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h | 2 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c | 88 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c | 29 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c | 22 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h | 185 ---
drivers/net/ethernet/huawei/hinic3/hinic3_common.h | 118 --
drivers/net/ethernet/huawei/hinic3/hinic3_crm.h | 16 +-
drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c | 298 ++--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c | 264 +--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h | 7 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c | 252 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c | 456 +++---
drivers/net/ethernet/huawei/hinic3/hinic3_filter.c | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_hw.h | 19 +
drivers/net/ethernet/huawei/hinic3/hinic3_irq.c | 39 +-
drivers/net/ethernet/huawei/hinic3/hinic3_lld.h | 205 ---
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c | 831 +++++++++-
drivers/net/ethernet/huawei/hinic3/hinic3_main.c | 492 +++++-
drivers/net/ethernet/huawei/hinic3/hinic3_mt.h | 218 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c | 402 +++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic.h | 50 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c | 557 +++++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h | 54 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c | 186 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c | 10 +
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h | 114 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c | 105 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c | 50 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c | 15 +-
drivers/net/ethernet/huawei/hinic3/hinic3_profile.h | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rss.c | 139 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c | 41 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rx.c | 311 +++-
drivers/net/ethernet/huawei/hinic3/hinic3_rx.h | 41 +-
drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h | 7 +-
drivers/net/ethernet/huawei/hinic3/hinic3_tx.c | 79 +-
drivers/net/ethernet/huawei/hinic3/hinic3_wq.h | 4 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c | 11 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c | 6 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h | 5 -
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c | 1 -
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c | 213 ++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h | 18 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c | 3 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c | 14 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c | 42 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c | 79 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h | 7 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c | 155 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c | 115 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c | 85 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h | 31 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c | 40 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c | 1243 +++++++++++++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c | 3 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c | 4 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c | 41 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c | 126 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h | 4 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h | 31 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c | 56 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h | 6 +-
drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c | 1 +
drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h | 4 +
.../include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h | 11 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h | 42 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h | 2 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h | 70 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h | 141 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h | 5 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h | 88 +-
.../include/mpu/mpu_outband_ncsi_cmd_defs.h | 8 +
drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/vram_common.h | 25 +-
drivers/net/ethernet/huawei/hinic3/{mag_cmd.h => mag_mpu_cmd_defs.h} | 237 ++-
drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h | 27 -
drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h | 65 -
drivers/net/ethernet/huawei/hinic3/{hinic3_nic_cmd.h => nic_mpu_cmd.h} | 55 +-
drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h | 1440 +++++++++++++++++
drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h | 36 +
drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h | 29 +-
96 files changed, 8455 insertions(+), 2782 deletions(-)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_defs.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_common.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
rename drivers/net/ethernet/huawei/hinic3/{mag_cmd.h => mag_mpu_cmd_defs.h} (79%)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
rename drivers/net/ethernet/huawei/hinic3/{hinic3_nic_cmd.h => nic_mpu_cmd.h} (77%)
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
diff --git a/drivers/net/ethernet/huawei/hinic3/Makefile b/drivers/net/ethernet/huawei/hinic3/Makefile
index 6f9ed3f..457c920 100644
--- a/drivers/net/ethernet/huawei/hinic3/Makefile
+++ b/drivers/net/ethernet/huawei/hinic3/Makefile
@@ -11,6 +11,7 @@ ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/mpu/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/bond/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/vmsec/
+ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/bond/
obj-$(CONFIG_HINIC3) += hinic3.o
hinic3-objs := hw/hinic3_hwdev.o \
diff --git a/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c b/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c
index cc2e4b3..440fea6 100644
--- a/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_nic_cmdq.h"
#include "sw_cmdq_ops.h"
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
index e8c703b..cd6ea8e 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
@@ -9,6 +9,7 @@
#include <linux/net.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
+#include <linux/version.h>
#include "hinic3_lld.h"
#include "hinic3_srv_nic.h"
@@ -81,7 +82,7 @@ static u32 bond_gen_uplink_id(struct hinic3_bond_dev *bdev)
spin_lock(&bdev->lock);
for (i = 0; i < BOND_PORT_MAX_NUM; i++) {
if (BITMAP_JUDGE(bdev->bond_attr.slaves, i)) {
- if (!bdev->tracker.ndev[i])
+ if (bdev->tracker.ndev[i] == NULL)
continue;
nic_dev = netdev_priv(bdev->tracker.ndev[i]);
pdev = nic_dev->pdev;
@@ -109,7 +110,8 @@ static struct hinic3_nic_dev *get_nic_dev_safe(struct net_device *ndev)
return netdev_priv(ndev);
}
-static u8 bond_get_slaves_bitmap(struct hinic3_bond_dev *bdev, struct bonding *bond)
+static u8 bond_get_slaves_bitmap(struct hinic3_bond_dev *bdev,
+ struct bonding *bond)
{
struct slave *slave = NULL;
struct list_head *iter = NULL;
@@ -203,7 +205,8 @@ static u8 bond_dev_track_port(struct hinic3_bond_dev *bdev,
bdev->tracker.netdev_state[port_id].tx_enabled = 0;
if (!bdev->ppf_hwdev)
bdev->ppf_hwdev = ppf_hwdev;
- pr_info("TRACK cnt: %d, slave_name(%s)\n", bdev->tracker.cnt, ndev->name);
+ pr_info("TRACK cnt: %d, slave_name(%s)\n",
+ bdev->tracker.cnt, ndev->name);
spin_unlock(&bdev->lock);
return port_id;
@@ -268,11 +271,16 @@ static void bond_master_event(struct hinic3_bond_dev *bdev,
queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
}
-static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
+static struct hinic3_bond_dev *bond_get_bdev(struct bonding *bond)
{
struct hinic3_bond_dev *bdev = NULL;
int bid;
+ if (bond == NULL) {
+ pr_err("hinic3_bond: bond is NULL\n");
+ return NULL;
+ }
+
mutex_lock(&g_bond_mutex);
for (bid = BOND_FIRST_ID; bid <= BOND_MAX_ID; bid++) {
bdev = bond_mngr.bond_dev[bid];
@@ -283,38 +291,73 @@ static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
mutex_unlock(&g_bond_mutex);
return bdev;
}
+
+ if (strncmp(bond->dev->name,
+ bdev->name, BOND_NAME_MAX_LEN) == 0) {
+ bdev->bond = bond;
+ return bdev;
+ }
}
mutex_unlock(&g_bond_mutex);
return NULL;
}
-static void bond_handle_rtnl_event(struct net_device *ndev)
+static struct bonding *get_bonding_by_netdev(struct net_device *ndev)
{
- struct hinic3_bond_dev *bdev = NULL;
struct bonding *bond = NULL;
struct slave *slave = NULL;
if (netif_is_bond_master(ndev)) {
bond = netdev_priv(ndev);
- bdev = bond_get_bdev(bond);
} else if (netif_is_bond_slave(ndev)) {
- /*lint -e(160) */
slave = bond_slave_get_rtnl(ndev);
if (slave) {
bond = bond_get_bond_by_slave(slave);
- bdev = bond_get_bdev(bond);
}
}
- if (!bond || !bdev)
+ return bond;
+}
+/*lint -e580 -e546*/
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+
+ if (!ndev) {
+ pr_err("hinic3_bond: netdev is NULL\n");
+ return false;
+ }
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
+ return false;
+
+ return bdev->status == BOND_DEV_STATUS_ACTIVATED;
+}
+EXPORT_SYMBOL(hinic3_is_bond_dev_status_actived);
+/*lint +e580 +e546*/
+
+static void bond_handle_rtnl_event(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+ struct slave *slave = NULL;
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
return;
bond_update_attr(bdev, bond);
- if (slave)
+ if (netif_is_bond_slave(ndev)) {
+ slave = bond_slave_get_rtnl(ndev);
bond_slave_event(bdev, slave);
- else
+ } else {
bond_master_event(bdev, bond);
+ }
}
static void bond_rtnl_data_ready(struct sock *sk)
@@ -368,7 +411,8 @@ static int bond_enable_netdev_event(void)
(*rtnl_sock)->sk->sk_data_ready = bond_rtnl_data_ready;
(*rtnl_sock)->sk->sk_allocation = GFP_KERNEL;
- err = kernel_bind(*rtnl_sock, (struct sockaddr *)(u8 *)&addr, sizeof(addr));
+ err = kernel_bind(*rtnl_sock, (struct sockaddr *)(u8 *)&addr,
+ sizeof(addr));
if (err) {
pr_err("hinic3_bond: Couldn't bind rtnl socket.\n");
sock_release(*rtnl_sock);
@@ -387,7 +431,7 @@ static void bond_disable_netdev_event(void)
static int bond_send_upcmd(struct hinic3_bond_dev *bdev, struct bond_attr *attr,
u8 cmd_type)
{
- int err, len;
+ int err, ret, len;
struct hinic3_bond_cmd cmd = {0};
u16 out_size = sizeof(cmd);
@@ -403,7 +447,9 @@ static int bond_send_upcmd(struct hinic3_bond_dev *bdev, struct bond_attr *attr,
len = sizeof(cmd.bond_name);
if (cmd_type == MPU_CMD_BOND_CREATE) {
- strscpy(cmd.bond_name, bdev->name, len);
+ ret = strscpy(cmd.bond_name, bdev->name, len);
+ if (ret < 0)
+ pr_err("strscpy bond name failed\n");
cmd.bond_name[sizeof(cmd.bond_name) - 1] = '\0';
}
@@ -478,7 +524,11 @@ static void bond_update_slave_info(struct hinic3_bond_dev *bdev,
continue;
}
+ if (!bdev->tracker.ndev[i])
+ continue;
+
bond_pf_bitmap_set(bdev, i);
+
if (!bdev->tracker.netdev_state[i].tx_enabled)
continue;
@@ -516,6 +566,7 @@ static int bond_upcmd_config(struct hinic3_bond_dev *bdev,
attr->active_slaves,
attr->lacp_collect_slaves);
pr_info("bond_pf_bitmap: 0x%x\n", attr->bond_pf_bitmap);
+ pr_info("bond user_bitmap 0x%x\n", attr->user_bitmap);
err = bond_send_upcmd(bdev, attr, MPU_CMD_BOND_SET_ATTR);
if (!err)
@@ -544,8 +595,10 @@ static int bond_upcmd_activate(struct hinic3_bond_dev *bdev,
return err;
}
-static void bond_call_service_func(struct hinic3_bond_dev *bdev, struct bond_attr *attr,
- enum bond_service_proc_pos pos, int bond_status)
+static void bond_call_service_func(struct hinic3_bond_dev *bdev,
+ struct bond_attr *attr,
+ enum bond_service_proc_pos pos,
+ int bond_status)
{
int i;
@@ -560,6 +613,18 @@ static void bond_call_service_func(struct hinic3_bond_dev *bdev, struct bond_att
mutex_unlock(&g_bond_service_func_mutex);
}
+static u32 bond_get_user_bitmap(struct hinic3_bond_dev *bdev)
+{
+ u32 user_bitmap = 0;
+ u8 user;
+
+ for (user = HINIC3_BOND_USER_OVS; user < HINIC3_BOND_USER_NUM; user++) {
+ if (bdev->slot_used[user] == 1)
+ BITMAP_SET(user_bitmap, user);
+ }
+ return user_bitmap;
+}
+
static void bond_do_work(struct hinic3_bond_dev *bdev)
{
bool is_bonded = 0;
@@ -570,7 +635,7 @@ static void bond_do_work(struct hinic3_bond_dev *bdev)
is_bonded = bdev->tracker.is_bonded;
attr = bdev->new_attr;
spin_unlock(&bdev->lock);
- attr.user_bitmap = 0;
+ attr.user_bitmap = bond_get_user_bitmap(bdev);
/* is_bonded indicates whether bond should be activated. */
if (is_bonded && !bond_dev_is_activated(bdev)) {
@@ -597,15 +662,22 @@ static void bond_try_do_work(struct work_struct *work)
struct delayed_work *delayed_work = to_delayed_work(work);
struct hinic3_bond_dev *bdev =
container_of(delayed_work, struct hinic3_bond_dev, bond_work);
+ int status;
- if (g_bond_service_func[HINIC3_BOND_USER_ROCE] && bdev->tracker.cnt < MIN_BOND_SLAVE_CNT)
+ status = mutex_trylock(&g_bond_mutex);
+ if (status == 0) {
+ /* Delay 1 sec and retry */
queue_delayed_work(bdev->wq, &bdev->bond_work, HZ);
- else
+ } else {
bond_do_work(bdev);
+ mutex_unlock(&g_bond_mutex);
+ }
}
static int bond_dev_init(struct hinic3_bond_dev *bdev, const char *name)
{
+ int err = 0;
+
bdev->wq = create_singlethread_workqueue("hinic3_bond_wq");
if (!bdev->wq) {
pr_err("hinic3_bond: Failed to create workqueue\n");
@@ -614,7 +686,13 @@ static int bond_dev_init(struct hinic3_bond_dev *bdev, const char *name)
INIT_DELAYED_WORK(&bdev->bond_work, bond_try_do_work);
bdev->status = BOND_DEV_STATUS_IDLE;
- strscpy(bdev->name, name, sizeof(bdev->name));
+ err = strscpy(bdev->name, name, strlen(name));
+ if (err < 0) {
+ pr_err("hinic3_bond: Failed to init bond dev\n");
+ cancel_delayed_work_sync(&bdev->bond_work);
+ destroy_workqueue(bdev->wq);
+ return err;
+ }
spin_lock_init(&bdev->lock);
@@ -630,6 +708,7 @@ static int bond_dev_release(struct hinic3_bond_dev *bdev)
err = bond_upcmd_deactivate(bdev);
if (err) {
pr_err("hinic3_bond: Failed to deactivate dev\n");
+ mutex_unlock(&g_bond_mutex);
return err;
}
@@ -637,7 +716,8 @@ static int bond_dev_release(struct hinic3_bond_dev *bdev)
if (bond_mngr.bond_dev[i] == bdev) {
bond_mngr.bond_dev[i] = NULL;
bond_mngr.cnt--;
- pr_info("hinic3_bond: Free bond, id: %u mngr_cnt:%u\n", i, bond_mngr.cnt);
+ pr_info("hinic3_bond: Free bond, id: %u mngr_cnt:%u\n",
+ i, bond_mngr.cnt);
break;
}
}
@@ -694,7 +774,8 @@ static struct hinic3_bond_dev *bond_dev_alloc(const char *name)
bdev->bond_attr.bond_id = i;
bond_mngr.bond_dev[i] = bdev;
bond_mngr.cnt++;
- pr_info("hinic3_bond: Create bond dev, id:%u cnt:%u\n", i, bond_mngr.cnt);
+ pr_info("hinic3_bond: Create bond dev, id:%u cnt:%u\n",
+ i, bond_mngr.cnt);
break;
}
}
@@ -764,20 +845,28 @@ static struct hinic3_bond_dev *bond_dev_by_name(const char *name)
static void bond_dev_user_attach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user)
{
+ u32 user_bitmap;
+
+ if (user < 0 || user >= HINIC3_BOND_USER_NUM)
+ return;
+
if (bdev->slot_used[user])
return;
bdev->slot_used[user] = 1;
if (!kref_get_unless_zero(&bdev->ref))
kref_init(&bdev->ref);
+ else {
+ user_bitmap = bond_get_user_bitmap(bdev);
+ pr_info("hinic3_bond: user %u attach bond %s, user_bitmap %#x\n",
+ user, bdev->name, user_bitmap);
+ queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
+ }
}
static void bond_dev_user_detach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user, bool *freed)
{
- if (user < 0 || user >= HINIC3_BOND_USER_NUM)
- return;
-
if (bdev->slot_used[user]) {
bdev->slot_used[user] = 0;
if (kref_read(&bdev->ref) == 1)
@@ -790,16 +879,20 @@ static struct bonding *bond_get_knl_bonding(const char *name)
{
struct net_device *ndev_tmp = NULL;
+ rcu_read_lock();
for_each_netdev(&init_net, ndev_tmp) {
if (netif_is_bond_master(ndev_tmp) &&
- !strcmp(ndev_tmp->name, name))
+ !strcmp(ndev_tmp->name, name)) {
+ rcu_read_unlock();
return netdev_priv(ndev_tmp);
+ }
}
-
+ rcu_read_unlock();
return NULL;
}
-void hinic3_bond_set_user_bitmap(struct bond_attr *attr, enum hinic3_bond_user user)
+void hinic3_bond_set_user_bitmap(struct bond_attr *attr,
+ enum hinic3_bond_user user)
{
if (!BITMAP_JUDGE(attr->user_bitmap, user))
BITMAP_SET(attr->user_bitmap, user);
@@ -852,8 +945,9 @@ int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user)
int err = 0;
bool lock_freed = false;
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
- pr_warn("hinic3_bond: Invalid bond id:%u to delete\n", bond_id);
+ if (!BOND_ID_IS_VALID(bond_id) || user >= HINIC3_BOND_USER_NUM) {
+ pr_warn("hinic3_bond: Invalid bond id or user, bond_id: %u, user: %d\n",
+ bond_id, user);
return -EINVAL;
}
@@ -861,7 +955,8 @@ int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user)
if (!bond_mngr.bond_dev[bond_id])
err = -ENODEV;
else
- bond_dev_user_detach(bond_mngr.bond_dev[bond_id], user, &lock_freed);
+ bond_dev_user_detach(bond_mngr.bond_dev[bond_id],
+ user, &lock_freed);
if (!lock_freed)
mutex_unlock(&g_bond_mutex);
@@ -877,7 +972,8 @@ void hinic3_bond_clean_user(enum hinic3_bond_user user)
mutex_lock(&g_bond_mutex);
for (i = BOND_FIRST_ID; i <= BOND_MAX_ID; i++) {
if (bond_mngr.bond_dev[i]) {
- bond_dev_user_detach(bond_mngr.bond_dev[i], user, &lock_freed);
+ bond_dev_user_detach(bond_mngr.bond_dev[i],
+ user, &lock_freed);
if (lock_freed) {
mutex_lock(&g_bond_mutex);
lock_freed = false;
@@ -891,7 +987,7 @@ EXPORT_SYMBOL(hinic3_bond_clean_user);
int hinic3_bond_get_uplink_id(u16 bond_id, u32 *uplink_id)
{
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID || !uplink_id) {
+ if (!BOND_ID_IS_VALID(bond_id) || !uplink_id) {
pr_warn("hinic3_bond: Invalid args, id: %u, uplink: %d\n",
bond_id, !!uplink_id);
return -EINVAL;
@@ -941,7 +1037,7 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
int i;
int len;
- if (!info || bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
+ if (!info || !BOND_ID_IS_VALID(bond_id)) {
pr_warn("hinic3_bond: Invalid args, info: %d,id: %u\n",
!!info, bond_id);
return -EINVAL;
@@ -962,7 +1058,8 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
for (i = 0; i < BOND_PORT_MAX_NUM; i++) {
if (BITMAP_JUDGE(info->slaves, i) && tracker->ndev[i]) {
len = sizeof(info->slaves_name[0]);
- strscpy(info->slaves_name[info->cnt], tracker->ndev[i]->name, len);
+ strscpy(info->slaves_name[info->cnt],
+ tracker->ndev[i]->name, len);
info->cnt++;
}
}
@@ -972,7 +1069,8 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
}
EXPORT_SYMBOL(hinic3_bond_get_slaves);
-struct net_device *hinic3_bond_get_netdev_by_portid(const char *bond_name, u8 port_id)
+struct net_device *hinic3_bond_get_netdev_by_portid(const char *bond_name,
+ u8 port_id)
{
struct hinic3_bond_dev *bdev = NULL;
@@ -989,7 +1087,8 @@ struct net_device *hinic3_bond_get_netdev_by_portid(const char *bond_name, u8 po
}
EXPORT_SYMBOL(hinic3_bond_get_netdev_by_portid);
-int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos, u16 channel)
+int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos,
+ u16 channel)
{
struct comm_cmd_hw_bond_infos bond_infos;
u16 out_size = sizeof(bond_infos);
@@ -1002,7 +1101,8 @@ int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos, u1
bond_infos.infos.bond_id = infos->bond_id;
- err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_COMM, COMM_MGMT_CMD_GET_HW_BOND,
+ err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_COMM,
+ COMM_MGMT_CMD_GET_HW_BOND,
&bond_infos, sizeof(bond_infos),
&bond_infos, &out_size, 0, channel);
if (bond_infos.head.status || err || !out_size) {
@@ -1018,7 +1118,8 @@ int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos, u1
}
EXPORT_SYMBOL(hinic3_get_hw_bond_infos);
-int hinic3_get_bond_tracker_by_name(const char *name, struct bond_tracker *tracker)
+int hinic3_get_bond_tracker_by_name(const char *name,
+ struct bond_tracker *tracker)
{
struct hinic3_bond_dev *bdev = NULL;
int i;
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
index 024de95..5ab36f7 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
@@ -82,6 +82,7 @@ struct hinic3_bond_cmd {
char bond_name[16];
};
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev);
void hinic3_bond_set_user_bitmap(struct bond_attr *attr, enum hinic3_bond_user user);
int hinic3_bond_attach(const char *name, enum hinic3_bond_user user, u16 *bond_id);
int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user);
diff --git a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h b/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
deleted file mode 100644
index 557f326..0000000
--- a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2016-2022. All rights reserved.
- * File name: Cfg_mgt_comm_pub.h
- * Version No.: Draft
- * Generation date: 2016 year 05 month 07 day
- * Latest modification:
- * Function description: Header file for communication between the: Host and FW
- * Function list:
- * Modification history:
- * 1. Date: 2016 May 07
- * Modify content: Create a file.
- */
-#ifndef CFG_MGT_COMM_PUB_H
-#define CFG_MGT_COMM_PUB_H
-
-#include "mgmt_msg_base.h"
-
-enum servic_bit_define {
- SERVICE_BIT_NIC = 0,
- SERVICE_BIT_ROCE = 1,
- SERVICE_BIT_VBS = 2,
- SERVICE_BIT_TOE = 3,
- SERVICE_BIT_IPSEC = 4,
- SERVICE_BIT_FC = 5,
- SERVICE_BIT_VIRTIO = 6,
- SERVICE_BIT_OVS = 7,
- SERVICE_BIT_NVME = 8,
- SERVICE_BIT_ROCEAA = 9,
- SERVICE_BIT_CURRENET = 10,
- SERVICE_BIT_PPA = 11,
- SERVICE_BIT_MIGRATE = 12,
- SERVICE_BIT_MAX
-};
-
-#define CFG_SERVICE_MASK_NIC (0x1 << SERVICE_BIT_NIC)
-#define CFG_SERVICE_MASK_ROCE (0x1 << SERVICE_BIT_ROCE)
-#define CFG_SERVICE_MASK_VBS (0x1 << SERVICE_BIT_VBS)
-#define CFG_SERVICE_MASK_TOE (0x1 << SERVICE_BIT_TOE)
-#define CFG_SERVICE_MASK_IPSEC (0x1 << SERVICE_BIT_IPSEC)
-#define CFG_SERVICE_MASK_FC (0x1 << SERVICE_BIT_FC)
-#define CFG_SERVICE_MASK_VIRTIO (0x1 << SERVICE_BIT_VIRTIO)
-#define CFG_SERVICE_MASK_OVS (0x1 << SERVICE_BIT_OVS)
-#define CFG_SERVICE_MASK_NVME (0x1 << SERVICE_BIT_NVME)
-#define CFG_SERVICE_MASK_ROCEAA (0x1 << SERVICE_BIT_ROCEAA)
-#define CFG_SERVICE_MASK_CURRENET (0x1 << SERVICE_BIT_CURRENET)
-#define CFG_SERVICE_MASK_PPA (0x1 << SERVICE_BIT_PPA)
-#define CFG_SERVICE_MASK_MIGRATE (0x1 << SERVICE_BIT_MIGRATE)
-
-/* Definition of the scenario ID in the cfg_data, which is used for SML memory allocation. */
-enum scenes_id_define {
- SCENES_ID_FPGA_ETH = 0,
- SCENES_ID_FPGA_TIOE = 1, /* Discarded */
- SCENES_ID_STORAGE_ROCEAA_2x100 = 2,
- SCENES_ID_STORAGE_ROCEAA_4x25 = 3,
- SCENES_ID_CLOUD = 4,
- SCENES_ID_FC = 5,
- SCENES_ID_STORAGE_ROCE = 6,
- SCENES_ID_COMPUTE_ROCE = 7,
- SCENES_ID_STORAGE_TOE = 8,
- SCENES_ID_MAX
-};
-
-/* struct cfg_cmd_dev_cap.sf_svc_attr */
-enum {
- SF_SVC_FT_BIT = (1 << 0),
- SF_SVC_RDMA_BIT = (1 << 1),
-};
-
-enum cfg_cmd {
- CFG_CMD_GET_DEV_CAP = 0,
- CFG_CMD_GET_HOST_TIMER = 1,
-};
-
-struct cfg_cmd_host_timer {
- struct mgmt_msg_head head;
-
- u8 host_id;
- u8 rsvd1;
-
- u8 timer_pf_num;
- u8 timer_pf_id_start;
- u16 timer_vf_num;
- u16 timer_vf_id_start;
- u32 rsvd2[8];
-};
-
-struct cfg_cmd_dev_cap {
- struct mgmt_msg_head head;
-
- u16 func_id;
- u16 rsvd1;
-
- /* Public resources */
- u8 host_id;
- u8 ep_id;
- u8 er_id;
- u8 port_id;
-
- u16 host_total_func;
- u8 host_pf_num;
- u8 pf_id_start;
- u16 host_vf_num;
- u16 vf_id_start;
- u8 host_oq_id_mask_val;
- u8 timer_en;
- u8 host_valid_bitmap;
- u8 rsvd_host;
-
- u16 svc_cap_en;
- u16 max_vf;
- u8 flexq_en;
- u8 valid_cos_bitmap;
- /* Reserved for func_valid_cos_bitmap */
- u8 port_cos_valid_bitmap;
- u8 rsvd_func1;
- u32 rsvd_func2;
-
- u8 sf_svc_attr;
- u8 func_sf_en;
- u8 lb_mode;
- u8 smf_pg;
-
- u32 max_conn_num;
- u16 max_stick2cache_num;
- u16 max_bfilter_start_addr;
- u16 bfilter_len;
- u16 hash_bucket_num;
-
- /* shared resource */
- u8 host_sf_en;
- u8 master_host_id;
- u8 srv_multi_host_mode;
- u8 virtio_vq_size;
-
- u32 rsvd_func3[5];
-
- /* l2nic */
- u16 nic_max_sq_id;
- u16 nic_max_rq_id;
- u16 nic_default_num_queues;
- u16 rsvd1_nic;
- u32 rsvd2_nic[2];
-
- /* RoCE */
- u32 roce_max_qp;
- u32 roce_max_cq;
- u32 roce_max_srq;
- u32 roce_max_mpt;
- u32 roce_max_drc_qp;
-
- u32 roce_cmtt_cl_start;
- u32 roce_cmtt_cl_end;
- u32 roce_cmtt_cl_size;
-
- u32 roce_dmtt_cl_start;
- u32 roce_dmtt_cl_end;
- u32 roce_dmtt_cl_size;
-
- u32 roce_wqe_cl_start;
- u32 roce_wqe_cl_end;
- u32 roce_wqe_cl_size;
- u8 roce_srq_container_mode;
- u8 rsvd_roce1[3];
- u32 rsvd_roce2[5];
-
- /* IPsec */
- u32 ipsec_max_sactx;
- u16 ipsec_max_cq;
- u16 rsvd_ipsec1;
- u32 rsvd_ipsec[2];
-
- /* OVS */
- u32 ovs_max_qpc;
- u32 rsvd_ovs1[3];
-
- /* ToE */
- u32 toe_max_pctx;
- u32 toe_max_cq;
- u16 toe_max_srq;
- u16 toe_srq_id_start;
- u16 toe_max_mpt;
- u16 toe_max_cctxt;
- u32 rsvd_toe[2];
-
- /* FC */
- u32 fc_max_pctx;
- u32 fc_max_scq;
- u32 fc_max_srq;
-
- u32 fc_max_cctx;
- u32 fc_cctx_id_start;
-
- u8 fc_vp_id_start;
- u8 fc_vp_id_end;
- u8 rsvd_fc1[2];
- u32 rsvd_fc2[5];
-
- /* VBS */
- u16 vbs_max_volq;
- u16 rsvd0_vbs;
- u32 rsvd1_vbs[3];
-
- u16 fake_vf_start_id;
- u16 fake_vf_num;
- u32 fake_vf_max_pctx;
- u16 fake_vf_bfilter_start_addr;
- u16 fake_vf_bfilter_len;
- u32 rsvd_glb[8];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
deleted file mode 100644
index 59e20a1..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/******************************************************************************
- * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
- ******************************************************************************
- File Name : comm_cmdq_intf.h
- Version : Initial Draft
- Description : common command queue interface
- Function List :
- History :
- Modification: Created file
-
-******************************************************************************/
-
-#ifndef COMM_CMDQ_INTF_H
-#define COMM_CMDQ_INTF_H
-
-/* Cmdq ack type */
-enum hinic3_ack_type {
- HINIC3_ACK_TYPE_CMDQ,
- HINIC3_ACK_TYPE_SHARE_CQN,
- HINIC3_ACK_TYPE_APP_CQN,
-
- HINIC3_MOD_ACK_MAX = 15,
-};
-
-/* Defines the queue type of the set arm bit. */
-enum {
- SET_ARM_BIT_FOR_CMDQ = 0,
- SET_ARM_BIT_FOR_L2NIC_SQ,
- SET_ARM_BIT_FOR_L2NIC_RQ,
- SET_ARM_BIT_TYPE_NUM
-};
-
-/* Defines the type. Each function supports a maximum of eight CMDQ types. */
-enum {
- CMDQ_0 = 0,
- CMDQ_1 = 1, /* dedicated and non-blocking queues */
- CMDQ_NUM
-};
-
-/* *******************cmd common command data structure ************************ */
-// Func->ucode, which is used to set arm bit data,
-// The microcode needs to perform big-endian conversion.
-struct comm_info_ucode_set_arm_bit {
- u32 q_type;
- u32 q_id;
-};
-
-/* *******************WQE data structure ************************ */
-union cmdq_wqe_cs_dw0 {
- struct {
- u32 err_status : 29;
- u32 error_code : 2;
- u32 rsvd : 1;
- } bs;
- u32 val;
-};
-
-union cmdq_wqe_cs_dw1 {
- // This structure is used when the driver writes the wqe.
- struct {
- u32 token : 16; // [15:0]
- u32 cmd : 8; // [23:16]
- u32 mod : 5; // [28:24]
- u32 ack_type : 2; // [30:29]
- u32 obit : 1; // [31]
- } drv_wr;
-
- /* The uCode writes back the structure of the CS_DW1. */
- /* The driver reads and uses the structure. */
- struct {
- u32 mod : 5; // [4:0]
- u32 ack_type : 3; // [7:5]
- u32 cmd : 8; // [15:8]
- u32 arm : 1; // [16]
- u32 rsvd : 14; // [30:17]
- u32 obit : 1; // [31]
- } wb;
- u32 val;
-};
-
-/* CmdQ BD information or write back buffer information */
-struct cmdq_sge {
- u32 pa_h; // Upper 32 bits of the physical address
- u32 pa_l; // Upper 32 bits of the physical address
- u32 len; // Invalid bit[31].
- u32 resv;
-};
-
-/* Ctrls section definition of WQE */
-struct cmdq_wqe_ctrls {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
-};
-
-/* Complete section definition of WQE */
-struct cmdq_wqe_cs {
- union cmdq_wqe_cs_dw0 dw0;
- union cmdq_wqe_cs_dw1 dw1;
- union {
- struct cmdq_sge sge;
- u32 dw2_5[4];
- } ack;
-};
-
-/* Inline header in WQE inline, describing the length of inline data */
-union cmdq_wqe_inline_header {
- struct {
- u32 buf_len : 11; // [10:0] inline data len
- u32 rsv : 21; // [31:11]
- } bs;
- u32 val;
-};
-
-/* Definition of buffer descriptor section in WQE */
-union cmdq_wqe_bds {
- struct {
- struct cmdq_sge bds_sge;
- u32 rsvd[4]; /* Zwy is used to transfer the virtual address of the buffer. */
- } lcmd; /* Long command, non-inline, and SGE describe the buffer information. */
-};
-
-/* Definition of CMDQ WQE */
-/* (long cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(16B) |
- * | |
- * +----------------------------------------+
- * | driver section(16B) |
- * +----------------------------------------+
- *
- *
- * (middle cmd, 128B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(88B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- *
- *
- * (short cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(24B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- */
-struct cmdq_wqe {
- struct cmdq_wqe_ctrls ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds bds;
-};
-
-/* Definition of ctrls section in inline WQE */
-struct cmdq_wqe_ctrls_inline {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
- u64 db;
-};
-
-/* Buffer descriptor section definition of WQE */
-union cmdq_wqe_bds_inline {
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[80];
- } mcmd; /* Middle command, inline mode */
-
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[16];
- } scmd; /* Short command, inline mode */
-};
-
-struct cmdq_wqe_inline {
- struct cmdq_wqe_ctrls_inline ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds_inline bds;
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_defs.h b/drivers/net/ethernet/huawei/hinic3/comm_defs.h
deleted file mode 100644
index c5b1913..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_defs.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_defs.h
- * Version : Initial Draft
- * Description : common definitions
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef COMM_DEFS_H
-#define COMM_DEFS_H
-
-/* CMDQ MODULE_TYPE */
-enum hinic3_mod_type {
- HINIC3_MOD_COMM = 0, /* HW communication module */
- HINIC3_MOD_L2NIC = 1, /* L2NIC module */
- HINIC3_MOD_ROCE = 2,
- HINIC3_MOD_PLOG = 3,
- HINIC3_MOD_TOE = 4,
- HINIC3_MOD_FLR = 5,
- HINIC3_MOD_RSVD1 = 6,
- HINIC3_MOD_CFGM = 7, /* Configuration module */
- HINIC3_MOD_CQM = 8,
- HINIC3_MOD_VMSEC = 9,
- COMM_MOD_FC = 10,
- HINIC3_MOD_OVS = 11,
- HINIC3_MOD_DSW = 12,
- HINIC3_MOD_MIGRATE = 13,
- HINIC3_MOD_HILINK = 14,
- HINIC3_MOD_CRYPT = 15, /* secure crypto module */
- HINIC3_MOD_VIO = 16,
- HINIC3_MOD_IMU = 17,
- HINIC3_MOD_DFT = 18, /* DFT */
- HINIC3_MOD_HW_MAX = 19, /* hardware max module id */
- /* Software module id, for PF/VF and multi-host */
- HINIC3_MOD_SW_FUNC = 20,
- HINIC3_MOD_MAX,
-};
-
-/* func reset的flag ,用于指示清理哪种资源 */
-enum func_reset_flag {
- RES_TYPE_FLUSH_BIT = 0,
- RES_TYPE_MQM,
- RES_TYPE_SMF,
- RES_TYPE_PF_BW_CFG,
-
- RES_TYPE_COMM = 10,
- RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_NIC,
- RES_TYPE_OVS,
- RES_TYPE_VBS,
- RES_TYPE_ROCE,
- RES_TYPE_FC,
- RES_TYPE_TOE,
- RES_TYPE_IPSEC,
- RES_TYPE_MAX,
-};
-
-#define HINIC3_COMM_RES \
- ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
- (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
- (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
-
-#define HINIC3_NIC_RES BIT(RES_TYPE_NIC)
-#define HINIC3_OVS_RES BIT(RES_TYPE_OVS)
-#define HINIC3_VBS_RES BIT(RES_TYPE_VBS)
-#define HINIC3_ROCE_RES BIT(RES_TYPE_ROCE)
-#define HINIC3_FC_RES BIT(RES_TYPE_FC)
-#define HINIC3_TOE_RES BIT(RES_TYPE_TOE)
-#define HINIC3_IPSEC_RES BIT(RES_TYPE_IPSEC)
-
-/* MODE OVS、NIC、UNKNOWN */
-#define HINIC3_WORK_MODE_OVS 0
-#define HINIC3_WORK_MODE_UNKNOWN 1
-#define HINIC3_WORK_MODE_NIC 2
-
-#define DEVICE_TYPE_L2NIC 0
-#define DEVICE_TYPE_NVME 1
-#define DEVICE_TYPE_VIRTIO_NET 2
-#define DEVICE_TYPE_VIRTIO_BLK 3
-#define DEVICE_TYPE_VIRTIO_VSOCK 4
-#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
-#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
-#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
-#define DEVICE_TYPE_VIRTIO_HPC 8
-
-/* Common header control information of the COMM message
- * interaction command word between the driver and PF
- */
-struct comm_info_head {
- u8 status;
- u8 version;
- u8 rep_aeq_num;
- u8 rsvd[5];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
deleted file mode 100644
index ae998cf..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_msg_intf.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef COMM_MSG_INTF_H
-#define COMM_MSG_INTF_H
-
-#include "comm_defs.h"
-#include "mgmt_msg_base.h"
-#include "mpu_cmd_base_defs.h"
-#include "mpu_inband_cmd_defs.h"
-
-struct spu_cmd_freq_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: check */
- u8 rsvd[3];
- u32 freq;
-};
-
-struct spu_cmd_power_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: init */
- u8 slave_addr;
- u8 cmd_id;
- u8 size;
- u32 value;
-};
-
-struct spu_cmd_tsensor_operation {
- struct comm_info_head head;
-
- u8 op_code;
- u8 rsvd[3];
- s16 fabric_tsensor_temp_avg;
- s16 fabric_tsensor_temp;
- s16 sys_tsensor_temp_avg;
- s16 sys_tsensor_temp;
-};
-
-enum cfg_msix_operation {
- CFG_MSIX_OPERATION_FREE = 0,
- CFG_MSIX_OPERATION_ALLOC = 1,
-};
-
-struct comm_cmd_ffm_info {
- struct mgmt_msg_head head;
-
- u8 node_id;
- /* error level of the interrupt source */
- u8 err_level;
- /* Classification by interrupt source properties */
- u16 err_type;
- u32 err_csr_addr;
- u32 err_csr_value;
- u32 rsvd1;
-};
-
-struct hinic3_cmd_update_firmware {
- struct mgmt_msg_head msg_head;
-
- struct {
- u32 sl : 1;
- u32 sf : 1;
- u32 flag : 1;
- u32 bit_signed : 1;
- u32 reserved : 12;
- u32 fragment_len : 16;
- } ctl_info;
-
- struct {
- u32 section_crc;
- u32 section_type;
- } section_info;
-
- u32 total_len;
- u32 section_len;
- u32 section_version;
- u32 section_offset;
- u32 data[384];
-};
-
-struct hinic3_cmd_activate_firmware {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-struct hinic3_cmd_switch_config {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
index 8c95032..8c9f849 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
@@ -28,6 +28,8 @@
#include "cqm_npu_cmd.h"
#include "cqm_npu_cmd_defs.h"
+#include "vram_common.h"
+
static void cqm_bat_fill_cla_common_gpa(struct tag_cqm_handle *cqm_handle,
struct tag_cqm_cla_table *cla_table,
struct tag_cqm_bat_entry_standerd *bat_entry_standerd)
@@ -366,6 +368,13 @@ static s32 cqm_bat_update_cmd(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
struct hinic3_hwdev *handle = cqm_handle->ex_handle;
struct tag_cqm_cmdq_bat_update *bat_update_cmd = NULL;
s32 ret = CQM_FAIL;
+ int is_in_kexec;
+
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip updating the cqm_bat to chip during kexec!\n");
+ return CQM_SUCCESS;
+ }
bat_update_cmd = (struct tag_cqm_cmdq_bat_update *)(buf_in->buf);
bat_update_cmd->offset = 0;
@@ -768,8 +777,10 @@ static s32 cqm_cla_xyz_lvl1(struct tag_cqm_handle *cqm_handle,
/* Applying for CLA_Z_BUF Space */
cla_z_buf = &cla_table->cla_z_buf;
cla_z_buf->buf_size = trunk_size;
- cla_z_buf->buf_number = (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
- cla_z_buf->page_number = cla_z_buf->buf_number << cla_table->trunk_order;
+ cla_z_buf->buf_number =
+ (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
+ cla_z_buf->page_number = cla_z_buf->buf_number <<
+ cla_table->trunk_order;
/* All buffer space must be statically allocated. */
if (cla_table->alloc_static) {
@@ -840,6 +851,7 @@ static s32 cqm_cla_xyz_lvl2_xyz_apply(struct tag_cqm_handle *cqm_handle,
cla_x_buf->buf_size = trunk_size;
cla_x_buf->buf_number = 1;
cla_x_buf->page_number = cla_x_buf->buf_number << cla_table->trunk_order;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
ret = cqm_buf_alloc(cqm_handle, cla_x_buf, false);
if (ret != CQM_SUCCESS)
return CQM_FAIL;
@@ -869,14 +881,20 @@ static s32 cqm_cla_xyz_vram_name_init(struct tag_cqm_cla_table *cla_table,
cla_x_buf = &cla_table->cla_x_buf;
cla_z_buf = &cla_table->cla_z_buf;
cla_y_buf = &cla_table->cla_y_buf;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_x_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_X);
+ VRAM_NAME_MAX_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_X);
+ cla_y_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_y_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Y);
+ VRAM_NAME_MAX_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Y);
+ cla_z_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_z_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Z);
+ VRAM_NAME_MAX_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Z);
return CQM_SUCCESS;
}
@@ -1188,7 +1206,7 @@ static void cqm_cla_init_entry_extern(struct tag_cqm_handle *cqm_handle,
* exceed 128 x 4 KB. Otherwise, clearing the timer buffer of
* the function is complex.
*/
- cla_table->trunk_order = CQM_4K_PAGE_ORDER;
+ cla_table->trunk_order = CQM_8K_PAGE_ORDER;
cla_table->max_buffer_size = capability->timer_number *
capability->timer_basic_size;
cla_table->obj_size = capability->timer_basic_size;
@@ -1237,7 +1255,7 @@ static s32 cqm_cla_init_entry_condition(struct tag_cqm_handle *cqm_handle, u32 e
memcpy(cla_table_timer, cla_table, sizeof(struct tag_cqm_cla_table));
snprintf(cla_table_timer->name,
- VRAM_NAME_MAX_LEN - 1, "%s%s%01u", cla_table->name,
+ VRAM_NAME_MAX_LEN, "%s%s%01u", cla_table->name,
VRAM_CQM_CLA_SMF_BASE, i);
if (cqm_cla_xyz(cqm_handle, cla_table_timer) ==
@@ -1268,7 +1286,7 @@ static s32 cqm_cla_init_entry(struct tag_cqm_handle *cqm_handle,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
cla_table->type = bat_table->bat_entry_type[i];
- snprintf(cla_table->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(cla_table->name, VRAM_NAME_MAX_LEN,
"%s%s%s%02u", cqm_handle->name, VRAM_CQM_CLA_BASE,
VRAM_CQM_CLA_TYPE_BASE, cla_table->type);
@@ -1485,11 +1503,11 @@ static s32 cqm_cla_update(struct tag_cqm_handle *cqm_handle,
spu_en = 0;
pa = ((buf_node_parent->pa + (child_index * sizeof(dma_addr_t))) |
- (u32)spu_en);
+ spu_en);
cmd.gpa_h = CQM_ADDR_HI(pa);
cmd.gpa_l = CQM_ADDR_LW(pa);
- pa = (buf_node_child->pa | (u32)spu_en);
+ pa = (buf_node_child->pa | spu_en);
cmd.value_h = CQM_ADDR_HI(pa);
cmd.value_l = CQM_ADDR_LW(pa);
@@ -1979,7 +1997,7 @@ struct tag_cqm_cla_table *cqm_cla_table_get(struct tag_cqm_bat_table *bat_table,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
- if (cla_table && entry_type == cla_table->type)
+ if ((cla_table != NULL) && (entry_type == cla_table->type))
return cla_table;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
index dd0766e..a51c1dc 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
@@ -9,6 +9,7 @@
#include "cqm_bitmap_table.h"
#include "cqm_object.h"
+#include "vram_common.h"
/* When the connection check is enabled, the maximum number of connections
* supported by the chip is 1M - 63, which cannot reach 1M
@@ -19,6 +20,7 @@
#define CLA_TABLE_PAGE_ORDER 0
#define CQM_4K_PAGE_ORDER 0
#define CQM_4K_PAGE_SIZE 4096
+#define CQM_8K_PAGE_ORDER 1
#define CQM_BAT_ENTRY_MAX 16
#define CQM_BAT_ENTRY_SIZE 16
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
index d5fac94..5f095c8 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
@@ -254,8 +254,10 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
}
pages = vmalloc(sizeof(struct page *) * buf->page_number);
- if (!pages)
+ if (!pages) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(pages));
return CQM_FAIL;
+ }
for (i = 0; i < buf->buf_number; i++) {
for (j = 0; j < ((u32)1 << order); j++)
@@ -273,6 +275,11 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
return CQM_SUCCESS;
}
+static bool check_use_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ return buf->buf_info.use_vram ? true : false;
+}
+
static bool check_use_non_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
{
return buf->buf_info.use_vram ? false : true;
@@ -294,11 +301,46 @@ static bool check_for_nouse_node_alloc(struct hinic3_hwdev *handle, struct tag_c
return false;
}
+static s32 cqm_buf_vram_kalloc(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ void *vaddr = NULL;
+ int i;
+
+ vaddr = hi_vram_kalloc(buf->buf_info.buf_vram_name, (u64)buf->buf_size * buf->buf_number);
+ if (!vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
+ return CQM_FAIL;
+ }
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = (void *)((char *)vaddr + i * (u64)buf->buf_size);
+
+ return CQM_SUCCESS;
+}
+
+static void cqm_buf_vram_free(struct tag_cqm_buf *buf)
+{
+ s32 i;
+
+ if (buf->buf_list == NULL)
+ return;
+
+ if (buf->buf_list[0].va)
+ hi_vram_kfree(buf->buf_list[0].va, buf->buf_info.buf_vram_name,
+ (u64)buf->buf_size * buf->buf_number);
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = NULL;
+}
+
static void cqm_buf_free_page_common(struct tag_cqm_buf *buf)
{
u32 order;
s32 i;
+ if (buf->buf_list == NULL)
+ return;
+
order = (u32)get_order(buf->buf_size);
for (i = 0; i < (s32)buf->buf_number; i++) {
@@ -320,8 +362,10 @@ static s32 cqm_buf_use_node_alloc_page(struct hinic3_hwdev *handle, struct tag_c
node = dev_to_node(handle->dev_hdl);
for (i = 0; i < (s32)buf->buf_number; i++) {
newpage = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, order);
- if (!newpage)
+ if (!newpage) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
va = (void *)page_address(newpage);
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
@@ -349,8 +393,10 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
for (i = 0; i < (s32)buf->buf_number; i++) {
va = (void *)ossl_get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
- if (!va)
+ if (!va) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
* value must be 0.
@@ -367,21 +413,21 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
return CQM_SUCCESS;
}
-#define MALLOC_FUNCS_COUNT 2
-#define FREE_FUNCS_COUNT 1
-static const struct malloc_memory g_malloc_funcs[MALLOC_FUNCS_COUNT] = {
+static const struct malloc_memory g_malloc_funcs[] = {
+ {check_use_vram, cqm_buf_vram_kalloc},
{check_for_use_node_alloc, cqm_buf_use_node_alloc_page},
{check_for_nouse_node_alloc, cqm_buf_unused_node_alloc_page}
};
-static const struct free_memory g_free_funcs[FREE_FUNCS_COUNT] = {
+static const struct free_memory g_free_funcs[] = {
+ {check_use_vram, cqm_buf_vram_free},
{check_use_non_vram, cqm_buf_free_page_common}
};
static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *buf)
{
struct hinic3_hwdev *handle = cqm_handle->ex_handle;
- u32 malloc_funcs_num = MALLOC_FUNCS_COUNT;
+ u32 malloc_funcs_num = ARRAY_SIZE(g_malloc_funcs);
u32 i;
for (i = 0; i < malloc_funcs_num; i++) {
@@ -398,7 +444,7 @@ static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
static void cqm_buf_free_page(struct tag_cqm_buf *buf)
{
- u32 free_funcs_num = FREE_FUNCS_COUNT;
+ u32 free_funcs_num = ARRAY_SIZE(g_free_funcs);
u32 i;
for (i = 0; i < free_funcs_num; i++) {
@@ -447,8 +493,11 @@ static s32 cqm_buf_get_secure_mem_pages(struct tag_cqm_handle *cqm_handle, struc
cqm_get_secure_mem_pages(handle,
(u32)get_order(buf->buf_size),
&buf->buf_list[i].pa);
- if (!buf->buf_list[i].va)
+ if (!buf->buf_list[i].va) {
+ cqm_err(handle->dev_hdl,
+ CQM_ALLOC_FAIL(cqm_get_secure_mem_pages));
break;
+ }
}
if (i != buf->buf_number) {
@@ -777,7 +826,12 @@ static s32 cqm_single_bitmap_init(struct tag_cqm_bitmap *bitmap)
*/
bit_number = (ALIGN(bitmap->max_num, CQM_NUM_BIT_BYTE) >>
CQM_BYTE_BIT_SHIFT);
- bitmap->table = vmalloc(bit_number);
+ if (bitmap->bitmap_info.use_vram != 0)
+ bitmap->table = hi_vram_kalloc(
+ bitmap->bitmap_info.buf_vram_name,
+ bit_number);
+ else
+ bitmap->table = vmalloc(bit_number);
if (!bitmap->table)
return CQM_FAIL;
memset(bitmap->table, 0, bit_number);
@@ -856,7 +910,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
}
bitmap = &cla_table->bitmap;
- snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_MAX_LEN,
"%s%s%02d", cla_table->name,
VRAM_CQM_BITMAP_BASE, cla_table->type);
@@ -866,6 +920,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
bitmap->reserved_top = capability->qpc_reserved;
bitmap->reserved_back = capability->qpc_reserved_back;
bitmap->last = capability->qpc_reserved;
+ bitmap->bitmap_info.use_vram = get_use_vram_flag();
cqm_info(handle->dev_hdl,
"Bitmap init: cla_table_type=%u, max_num=0x%x\n",
cla_table->type, bitmap->max_num);
@@ -945,7 +1000,14 @@ void cqm_bitmap_uninit(struct tag_cqm_handle *cqm_handle)
if (cla_table->type != CQM_BAT_ENTRY_T_INVALID &&
bitmap->table) {
spin_lock_deinit(&bitmap->lock);
- vfree(bitmap->table);
+ if (bitmap->bitmap_info.use_vram != 0)
+ hi_vram_kfree(bitmap->table,
+ bitmap->bitmap_info.buf_vram_name,
+ ALIGN(bitmap->max_num,
+ CQM_NUM_BIT_BYTE) >>
+ CQM_BYTE_BIT_SHIFT);
+ else
+ vfree(bitmap->table);
bitmap->table = NULL;
}
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
index 7febf76..06b8661 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
@@ -9,6 +9,7 @@
#include <linux/spinlock.h>
#include "cqm_object.h"
+#include "vram_common.h"
struct tag_cqm_bitmap {
ulong *table;
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
index 9a13ae0..2a24e4a 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
@@ -196,6 +196,13 @@ void *cqm_get_db_addr(void *ex_handle, u32 service_type)
pr_err("[CQM]%s: ex_handle is null\n", __func__);
return NULL;
}
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return NULL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -218,6 +225,17 @@ s32 cqm_ring_hardware_db(void *ex_handle, u32 service_type, u8 db_count, u64 db)
struct tag_cqm_service *service = NULL;
struct hinic3_hwdev *handle = NULL;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -278,6 +296,17 @@ s32 cqm_ring_direct_wqe_db(void *ex_handle, u32 service_type, u8 db_count,
u64 *tmp = (u64 *)direct_wqe;
int i;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
index 19a8b56..1f1235c 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
@@ -23,6 +23,8 @@
#include "cqm_memsec.h"
#include "cqm_main.h"
+#include "vram_common.h"
+
static unsigned char roce_qpc_rsv_mode = CQM_QPC_ROCE_NORMAL;
module_param(roce_qpc_rsv_mode, byte, 0644);
MODULE_PARM_DESC(roce_qpc_rsv_mode,
@@ -98,10 +100,17 @@ static s32 cqm_set_timer_enable(void *ex_handle)
{
struct hinic3_hwdev *handle = (struct hinic3_hwdev *)ex_handle;
struct tag_cqm_handle *cqm_handle = NULL;
+ int is_in_kexec;
if (!ex_handle)
return CQM_FAIL;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip starting cqm timer during kexec\n");
+ return CQM_SUCCESS;
+ }
+
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
if (cqm_handle->func_capability.fake_func_type == CQM_FAKE_FUNC_PARENT &&
cqm_set_fake_vf_timer(cqm_handle) != CQM_SUCCESS)
@@ -473,7 +482,8 @@ static void cqm_service_capability_init_roce(struct tag_cqm_handle *cqm_handle,
func_cap->qpc_number += roce_own_cap->max_qps;
func_cap->qpc_basic_size = GET_MAX(roce_own_cap->qpc_entry_sz,
func_cap->qpc_basic_size);
- if (cqm_handle->func_attribute.func_type == CQM_PF && (IS_MASTER_HOST(handle))) {
+ if (cqm_handle->func_attribute.func_type == CQM_PF &&
+ (IS_MASTER_HOST(handle))) {
func_cap->hash_number = roce_own_cap->max_qps;
func_cap->hash_basic_size = CQM_HASH_BUCKET_SIZE_64;
}
@@ -1129,8 +1139,9 @@ static s32 cqm_fake_mem_init(struct tag_cqm_handle *cqm_handle)
for (i = 0; i < (u32)child_func_number; i++) {
fake_cqm_handle = cqm_handle->fake_cqm_handle[i];
- snprintf(fake_cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
- "%s%s%02u", cqm_handle->name, VRAM_CQM_FAKE_MEM_BASE, i);
+ snprintf(fake_cqm_handle->name, VRAM_NAME_MAX_LEN,
+ "%s%s%02u", cqm_handle->name,
+ VRAM_CQM_FAKE_MEM_BASE, i);
if (cqm_bat_init(fake_cqm_handle) != CQM_SUCCESS) {
cqm_err(handle->dev_hdl,
@@ -1174,8 +1185,9 @@ s32 cqm_mem_init(void *ex_handle)
struct tag_cqm_handle *cqm_handle = NULL;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
- snprintf(cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
- "%s%02u", VRAM_CQM_GLB_FUNC_BASE, hinic3_global_func_id(handle));
+ snprintf(cqm_handle->name, VRAM_NAME_MAX_LEN,
+ "%s%02u", VRAM_CQM_GLB_FUNC_BASE,
+ hinic3_global_func_id(handle));
if (cqm_fake_init(cqm_handle) != CQM_SUCCESS) {
cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_fake_init));
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
index 4f87bd1..8d1e481 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
@@ -362,6 +362,7 @@ s32 cqm_fake_vf_num_set(void *ex_handle, u16 fake_vf_num_cfg);
#define CQM_LOG_ID 0
#define CQM_PTR_NULL(x) "%s: " #x " is null\n", __func__
+#define CQM_ALLOC_FAIL(x) "%s: " #x " alloc fail\n", __func__
#define CQM_MAP_FAIL(x) "%s: " #x " map fail\n", __func__
#define CQM_FUNCTION_FAIL(x) "%s: " #x " return failure\n", __func__
#define CQM_WRONG_VALUE(x) "%s: " #x " %u is wrong\n", __func__, (u32)(x)
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
index 213803f..f5fce8f 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
@@ -378,7 +378,7 @@ static int hinic3_secure_mem_proc_node_remove(void *hwdev)
atomic_dec(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
@@ -401,7 +401,7 @@ static int hinic3_secure_mem_proc_node_add(void *hwdev)
atomic_inc(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
/* 0400 Read by owner */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h b/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
deleted file mode 100644
index ad732c3..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2019-2022. All rights reserved.
- * File Name : hinic3_comm_cmd.h
- * Version : Initial Draft
- * Created : 2019/4/25
- * Last Modified :
- * Description : COMM Commands between Driver and MPU
- * Function List :
- */
-
-#ifndef HINIC3_COMMON_CMD_H
-#define HINIC3_COMMON_CMD_H
-
-/* COMM Commands between Driver to MPU */
-enum hinic3_mgmt_cmd {
- /* flr及资源清理相关命令 */
- COMM_MGMT_CMD_FUNC_RESET = 0,
- COMM_MGMT_CMD_FEATURE_NEGO,
- COMM_MGMT_CMD_FLUSH_DOORBELL,
- COMM_MGMT_CMD_START_FLUSH,
- COMM_MGMT_CMD_SET_FUNC_FLR,
- COMM_MGMT_CMD_GET_GLOBAL_ATTR,
- COMM_MGMT_CMD_SET_PPF_FLR_TYPE,
- COMM_MGMT_CMD_SET_FUNC_SVC_USED_STATE,
-
- /* 分配msi-x中断资源 */
- COMM_MGMT_CMD_CFG_MSIX_NUM = 10,
-
- /* 驱动相关配置命令 */
- COMM_MGMT_CMD_SET_CMDQ_CTXT = 20,
- COMM_MGMT_CMD_SET_VAT,
- COMM_MGMT_CMD_CFG_PAGESIZE,
- COMM_MGMT_CMD_CFG_MSIX_CTRL_REG,
- COMM_MGMT_CMD_SET_CEQ_CTRL_REG,
- COMM_MGMT_CMD_SET_DMA_ATTR,
-
- /* INFRA配置相关命令字 */
- COMM_MGMT_CMD_GET_MQM_FIX_INFO = 40,
- COMM_MGMT_CMD_SET_MQM_CFG_INFO,
- COMM_MGMT_CMD_SET_MQM_SRCH_GPA,
- COMM_MGMT_CMD_SET_PPF_TMR,
- COMM_MGMT_CMD_SET_PPF_HT_GPA,
- COMM_MGMT_CMD_SET_FUNC_TMR_BITMAT,
- COMM_MGMT_CMD_SET_MBX_CRDT,
- COMM_MGMT_CMD_CFG_TEMPLATE,
- COMM_MGMT_CMD_SET_MQM_LIMIT,
-
- /* 信息获取相关命令字 */
- COMM_MGMT_CMD_GET_FW_VERSION = 60,
- COMM_MGMT_CMD_GET_BOARD_INFO,
- COMM_MGMT_CMD_SYNC_TIME,
- COMM_MGMT_CMD_GET_HW_PF_INFOS,
- COMM_MGMT_CMD_SEND_BDF_INFO,
- COMM_MGMT_CMD_GET_VIRTIO_BDF_INFO,
- COMM_MGMT_CMD_GET_SML_TABLE_INFO,
- COMM_MGMT_CMD_GET_SDI_INFO,
-
- /* 升级相关命令字 */
- COMM_MGMT_CMD_UPDATE_FW = 80,
- COMM_MGMT_CMD_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_DONE_NOTICE,
- COMM_MGMT_CMD_SWITCH_CFG,
- COMM_MGMT_CMD_CHECK_FLASH,
- COMM_MGMT_CMD_CHECK_FLASH_RW,
- COMM_MGMT_CMD_RESOURCE_CFG,
- COMM_MGMT_CMD_UPDATE_BIOS, /* TODO: merge to COMM_MGMT_CMD_UPDATE_FW */
- COMM_MGMT_CMD_MPU_GIT_CODE,
-
- /* chip reset相关 */
- COMM_MGMT_CMD_FAULT_REPORT = 100,
- COMM_MGMT_CMD_WATCHDOG_INFO,
- COMM_MGMT_CMD_MGMT_RESET,
- COMM_MGMT_CMD_FFM_SET, /* TODO: check if needed */
-
- /* chip info/log 相关 */
- COMM_MGMT_CMD_GET_LOG = 120,
- COMM_MGMT_CMD_TEMP_OP,
- COMM_MGMT_CMD_EN_AUTO_RST_CHIP,
- COMM_MGMT_CMD_CFG_REG,
- COMM_MGMT_CMD_GET_CHIP_ID,
- COMM_MGMT_CMD_SYSINFO_DFX,
- COMM_MGMT_CMD_PCIE_DFX_NTC,
- COMM_MGMT_CMD_DICT_LOG_STATUS, /* LOG STATUS 127 */
- COMM_MGMT_CMD_MSIX_INFO,
- COMM_MGMT_CMD_CHANNEL_DETECT,
- COMM_MGMT_CMD_DICT_COUNTER_STATUS,
-
- /* switch workmode 相关 */
- COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140,
- COMM_MGMT_CMD_SWITCH_WORKMODE,
-
- /* mpu 相关 */
- COMM_MGMT_CMD_MIGRATE_DFX_HPA = 150,
- COMM_MGMT_CMD_BDF_INFO,
- COMM_MGMT_CMD_NCSI_CFG_INFO_GET_PROC,
-
- /* rsvd0 section */
- COMM_MGMT_CMD_SECTION_RSVD_0 = 160,
-
- /* rsvd1 section */
- COMM_MGMT_CMD_SECTION_RSVD_1 = 170,
-
- /* rsvd2 section */
- COMM_MGMT_CMD_SECTION_RSVD_2 = 180,
-
- /* rsvd3 section */
- COMM_MGMT_CMD_SECTION_RSVD_3 = 190,
-
- /* TODO: move to DFT mode */
- COMM_MGMT_CMD_GET_DIE_ID = 200,
- COMM_MGMT_CMD_GET_EFUSE_TEST,
- COMM_MGMT_CMD_EFUSE_INFO_CFG,
- COMM_MGMT_CMD_GPIO_CTL,
- COMM_MGMT_CMD_HI30_SERLOOP_START, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_SERLOOP_STOP, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_SET_FLAG, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_GET_RESULT, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_ECC_TEST,
- COMM_MGMT_CMD_FUNC_BIST_TEST, /* 209 */
-
- COMM_MGMT_CMD_VPD_SET = 210,
- COMM_MGMT_CMD_VPD_GET,
-
- COMM_MGMT_CMD_ERASE_FLASH,
- COMM_MGMT_CMD_QUERY_FW_INFO,
- COMM_MGMT_CMD_GET_CFG_INFO,
- COMM_MGMT_CMD_GET_UART_LOG,
- COMM_MGMT_CMD_SET_UART_CMD,
- COMM_MGMT_CMD_SPI_TEST,
-
- /* TODO: ALL reg read/write merge to COMM_MGMT_CMD_CFG_REG */
- COMM_MGMT_CMD_UP_REG_GET,
- COMM_MGMT_CMD_UP_REG_SET, /* 219 */
-
- COMM_MGMT_CMD_REG_READ = 220,
- COMM_MGMT_CMD_REG_WRITE,
- COMM_MGMT_CMD_MAG_REG_WRITE,
- COMM_MGMT_CMD_ANLT_REG_WRITE,
-
- COMM_MGMT_CMD_HEART_EVENT, /* TODO: delete */
- COMM_MGMT_CMD_NCSI_OEM_GET_DRV_INFO, /* TODO: delete */
- COMM_MGMT_CMD_LASTWORD_GET,
- COMM_MGMT_CMD_READ_BIN_DATA, /* TODO: delete */
- /* COMM_MGMT_CMD_WWPN_GET, TODO: move to FC? */
- /* COMM_MGMT_CMD_WWPN_SET, TODO: move to FC? */ /* 229 */
-
- /* TODO: check if needed */
- COMM_MGMT_CMD_SET_VIRTIO_DEV = 230,
- COMM_MGMT_CMD_SET_MAC,
- /* MPU patch cmd */
- COMM_MGMT_CMD_LOAD_PATCH,
- COMM_MGMT_CMD_REMOVE_PATCH,
- COMM_MGMT_CMD_PATCH_ACTIVE,
- COMM_MGMT_CMD_PATCH_DEACTIVE,
- COMM_MGMT_CMD_PATCH_SRAM_OPTIMIZE,
- /* container host process */
- COMM_MGMT_CMD_CONTAINER_HOST_PROC,
- /* nsci counter */
- COMM_MGMT_CMD_NCSI_COUNTER_PROC,
- COMM_MGMT_CMD_CHANNEL_STATUS_CHECK, /* 239 */
-
- /* hot patch rsvd cmd */
- COMM_MGMT_CMD_RSVD_0 = 240,
- COMM_MGMT_CMD_RSVD_1,
- COMM_MGMT_CMD_RSVD_2,
- COMM_MGMT_CMD_RSVD_3,
- COMM_MGMT_CMD_RSVD_4,
- /* 无效字段,版本收编删除,编译使用 */
- COMM_MGMT_CMD_SEND_API_ACK_BY_UP,
-
- /* 注:添加cmd,不能修改已有命令字的值,请在前方rsvd
- * section中添加;原则上所有分支cmd表完全一致
- */
- COMM_MGMT_CMD_MAX = 255,
-};
-
-/* CmdQ Common subtype */
-enum comm_cmdq_cmd {
- COMM_CMD_UCODE_ARM_BIT_SET = 2,
- COMM_CMD_SEND_NPU_DFT_CMD,
-};
-
-#endif /* HINIC3_COMMON_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
deleted file mode 100644
index 9ce908e..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_COMMON_H
-#define HINIC3_COMMON_H
-
-#include <linux/types.h>
-
-struct hinic3_dma_addr_align {
- u32 real_size;
-
- void *ori_vaddr;
- dma_addr_t ori_paddr;
-
- void *align_vaddr;
- dma_addr_t align_paddr;
-};
-
-enum hinic3_wait_return {
- WAIT_PROCESS_CPL = 0,
- WAIT_PROCESS_WAITING = 1,
- WAIT_PROCESS_ERR = 2,
-};
-
-struct hinic3_sge {
- u32 hi_addr;
- u32 lo_addr;
- u32 len;
-};
-
-#ifdef static
-#undef static
-#define LLT_STATIC_DEF_SAVED
-#endif
-
-/* *
- * hinic_cpu_to_be32 - convert data to big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert, must be Multiple of 4B
- */
-static inline void hinic3_cpu_to_be32(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = cpu_to_be32(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_cpu_to_be32 - convert data from big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert
- */
-static inline void hinic3_be32_to_cpu(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = be32_to_cpu(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_set_sge - set dma area in scatter gather entry
- * @sge: scatter gather entry
- * @addr: dma address
- * @len: length of relevant data in the dma address
- */
-static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
- int len)
-{
- sge->hi_addr = upper_32_bits(addr);
- sge->lo_addr = lower_32_bits(addr);
- sge->len = len;
-}
-
-#define hinic3_hw_be32(val) (val)
-#define hinic3_hw_cpu32(val) (val)
-#define hinic3_hw_cpu16(val) (val)
-
-static inline void hinic3_hw_be32_len(void *data, int len)
-{
-}
-
-static inline void hinic3_hw_cpu32_len(void *data, int len)
-{
-}
-
-int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
- unsigned int flag,
- struct hinic3_dma_addr_align *mem_align);
-
-void hinic3_dma_free_coherent_align(void *dev_hdl,
- struct hinic3_dma_addr_align *mem_align);
-
-typedef enum hinic3_wait_return (*wait_cpl_handler)(void *priv_data);
-
-int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
- u32 wait_total_ms, u32 wait_once_us);
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
index 64139c4..4f5792f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
@@ -8,7 +8,7 @@
#include "mpu_cmd_base_defs.h"
-#define HINIC3_DRV_VERSION "15.17.1.2"
+#define HINIC3_DRV_VERSION "17.7.8.1"
#define HINIC3_DRV_DESC "Intelligent Network Interface Card Driver"
#define HIUDK_DRV_DESC "Intelligent Network Unified Driver"
@@ -45,6 +45,7 @@ enum hinic3_service_type {
SERVICE_T_CUSTOM,
SERVICE_T_VROCE,
SERVICE_T_CRYPT,
+ SERVICE_T_VSOCK,
SERVICE_T_BIFUR,
SERVICE_T_MAX,
@@ -64,6 +65,9 @@ struct nic_service_cap {
u16 max_sqs;
u16 max_rqs;
u16 default_num_queues;
+ u16 outband_vlan_cfg_en;
+ u8 lro_enable;
+ u8 rsvd1[3];
};
struct ppa_service_cap {
@@ -909,6 +913,13 @@ int hinic3_get_mgmt_version(void *hwdev, u8 *mgmt_ver, u8 version_size,
int hinic3_get_fw_version(void *hwdev, struct hinic3_fw_version *fw_ver,
u16 channel);
+/* *
+ * @brief hinic3_get_bond_create_mode - get bond create mode
+ * @param hwdev: device pointer to hwdev
+ * @retval global function id
+ */
+u8 hinic3_get_bond_create_mode(void *udkdev);
+
/* *
* @brief hinic3_global_func_id - get global function id
* @param hwdev: device pointer to hwdev
@@ -1263,4 +1274,7 @@ int hinic3_mbox_to_host_sync(void *hwdev, enum hinic3_mod_type mod,
int hinic3_get_func_vroce_enable(void *hwdev, u16 glb_func_idx, u8 *en);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type);
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
index 40ff473..8f5bb32 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
@@ -18,9 +18,10 @@
#include "hinic3_tx.h"
#include "hinic3_dcb.h"
#include "hinic3_nic.h"
-#include "hinic3_mgmt_interface.h"
+#include "hinic3_bond.h"
+#include "nic_mpu_cmd_defs.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
typedef int (*nic_driv_module)(struct hinic3_nic_dev *nic_dev,
const void *buf_in, u32 in_size,
@@ -34,7 +35,6 @@ struct nic_drv_module_handle {
static int get_nic_drv_version(void *buf_out, const u32 *out_size)
{
struct drv_version_info *ver_info = buf_out;
- int err;
if (!buf_out) {
pr_err("Buf_out is NULL.\n");
@@ -47,10 +47,8 @@ static int get_nic_drv_version(void *buf_out, const u32 *out_size)
return -EINVAL;
}
- err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
- HINIC3_NIC_DRV_VERSION, "2023-05-17_19:56:38");
- if (err < 0)
- return -EINVAL;
+ snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
+ HINIC3_NIC_DRV_VERSION, "2025-05-08_00:00:08");
return 0;
}
@@ -126,7 +124,8 @@ static int get_tx_wqe_info(struct hinic3_nic_dev *nic_dev,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -178,7 +177,8 @@ static int get_rx_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
rq_info->delta = (u16)nic_dev->rxqs[q_id].delta;
- rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx & nic_dev->rxqs[q_id].q_mask);
+ rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx &
+ nic_dev->rxqs[q_id].q_mask);
rq_info->sw_pi = nic_dev->rxqs[q_id].next_to_update;
rq_info->msix_vector = nic_dev->rxqs[q_id].irq_id;
@@ -201,7 +201,8 @@ static int get_rx_wqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -230,7 +231,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EFAULT;
}
- if (!buf_in || !buf_out) {
+ if (!buf_in || !buf_out || !out_size) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Buf_in or buf_out is NULL.\n");
return -EINVAL;
@@ -243,7 +244,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EINVAL;
}
- if (!out_size || *out_size != sizeof(struct hinic3_rq_cqe)) {
+ if (*out_size != sizeof(struct hinic3_rq_cqe)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(struct hinic3_rq_cqe));
@@ -252,10 +253,12 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
q_id = (u16)info->q_id;
idx = (u16)info->wqe_id;
- if (q_id >= nic_dev->q_params.num_qps || idx >= nic_dev->rxqs[q_id].q_depth) {
+ if (q_id >= nic_dev->q_params.num_qps ||
+ idx >= nic_dev->rxqs[q_id].q_depth) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid q_id[%u] >= %u, or wqe idx[%u] >= %u.\n",
- q_id, nic_dev->q_params.num_qps, idx, nic_dev->rxqs[q_id].q_depth);
+ q_id, nic_dev->q_params.num_qps, idx,
+ nic_dev->rxqs[q_id].q_depth);
return -EFAULT;
}
@@ -338,7 +341,8 @@ static int set_loopback_mode(struct hinic3_nic_dev *nic_dev, const void *buf_in,
err = hinic3_set_loopback_mode(nic_dev->hwdev, (u8)mode->loop_mode,
(u8)mode->loop_ctrl);
if (err == 0)
- nicif_info(nic_dev, drv, nic_dev->netdev, "Set loopback mode %u en %u succeed\n",
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Set loopback mode %u en %u succeed\n",
mode->loop_mode, mode->loop_ctrl);
return err;
@@ -417,6 +421,59 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
{
u32 pf_bw_limit;
int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
+
+ if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To set VF bandwidth rate, please use ip link cmd\n");
+ return -EINVAL;
+ }
+
+ if (!buf_in || !buf_out || in_size != sizeof(u32) ||
+ !out_size || *out_size != sizeof(u8))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_TX;
+ pf_bw_limit = *((u32 *)buf_in);
+
+ err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
+ if (err) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %u%%\n",
+ pf_bw_limit);
+ if (err < 0)
+ return err;
+ }
+
+ *((u8 *)buf_out) = (u8)err;
+
+ return 0;
+}
+
+static int set_rx_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ u32 pf_bw_limit;
+ int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
nicif_err(nic_dev, drv, nic_dev->netdev, "To set VF bandwidth rate, please use ip link cmd\n");
@@ -426,11 +483,16 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || !buf_out || in_size != sizeof(u32) || !out_size || *out_size != sizeof(u8))
return -EINVAL;
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_RX;
pf_bw_limit = *((u32 *)buf_in);
err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %d%%\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to set pf bandwidth limit to %d%%\n",
pf_bw_limit);
if (err < 0)
return err;
@@ -445,19 +507,21 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
struct hinic3_nic_io *nic_io = NULL;
+ u32 *rate_limit = (u32 *)buf_out;
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "To get VF bandwidth rate, please use ip link cmd\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To get VF bandwidth rate, please use ip link cmd\n");
return -EINVAL;
}
if (!buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(u32)) {
+ if (*out_size != sizeof(u32) * 2) { // 2:Stored in an array, TX and RX, both length are u32
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user: %d, expect: %lu\n",
- *out_size, sizeof(u32));
+ *out_size, sizeof(u32) * 2);
return -EFAULT;
}
@@ -465,8 +529,12 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!nic_io)
return -EINVAL;
- *((u32 *)buf_out) = nic_io->nic_cfg.pf_bw_limit;
+ rate_limit[HINIC3_NIC_RX] = nic_io->nic_cfg.pf_bw_rx_limit;
+ rate_limit[HINIC3_NIC_TX] = nic_io->nic_cfg.pf_bw_tx_limit;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "read rate cfg success rx rate is: %u, tx rate is : %u\n",
+ rate_limit[HINIC3_NIC_RX], rate_limit[HINIC3_NIC_TX]);
return 0;
}
@@ -477,8 +545,8 @@ static int get_sset_count(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || in_size != sizeof(u32) || !out_size ||
*out_size != sizeof(u32) || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
@@ -504,16 +572,16 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
int err;
if (!buf_in || in_size != sizeof(u32) || !out_size || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
size = sizeof(u32);
err = get_sset_count(nic_dev, buf_in, in_size, &count, &size);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Get sset count failed, ret=%d\n",
- err);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Get sset count failed, ret=%d\n", err);
return -EINVAL;
}
if (count * sizeof(*items) != *out_size) {
@@ -527,12 +595,14 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
switch (sset) {
case HINIC3_SHOW_SSET_IO_STATS:
- hinic3_get_io_stats(nic_dev, items);
+ err = hinic3_get_io_stats(nic_dev, items);
+ if (err < 0)
+ return -EINVAL;
break;
default:
- nicif_err(nic_dev, drv, nic_dev->netdev, "Unknown %u to get stats\n",
- sset);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unknown %u to get stats\n", sset);
err = -EINVAL;
break;
}
@@ -544,15 +614,18 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int i;
u8 cos_num = 0, valid_cos_bitmap = 0;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_PCP2COS) {
for (i = 0; i < NIC_DCB_UP_MAX; i++) {
- if (!(nic_dev->func_dft_cos_bitmap & BIT(qos_in->pcp2cos[i]))) {
+ if (!(dcb->func_dft_cos_bitmap &
+ BIT(qos_in->pcp2cos[i]))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- qos_in->pcp2cos[i], nic_dev->func_dft_cos_bitmap);
+ qos_in->pcp2cos[i],
+ dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -562,7 +635,8 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
}
- memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos, sizeof(qos_in->pcp2cos));
+ memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos,
+ sizeof(qos_in->pcp2cos));
wanted_dcb_cfg->pcp_user_cos_num = cos_num;
wanted_dcb_cfg->pcp_valid_cos_map = valid_cos_bitmap;
}
@@ -572,12 +646,14 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = 0;
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++) {
u8 cos = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->wanted_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ dcb->wanted_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
- if (cos >= NIC_DCB_UP_MAX || !(nic_dev->func_dft_cos_bitmap & BIT(cos))) {
+ if (cos >= NIC_DCB_UP_MAX ||
+ !(dcb->func_dft_cos_bitmap & BIT(cos))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- cos, nic_dev->func_dft_cos_bitmap);
+ cos, dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -588,8 +664,10 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- wanted_dcb_cfg->dscp2cos[i] = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->hw_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ wanted_dcb_cfg->dscp2cos[i] =
+ qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
+ dcb->hw_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
wanted_dcb_cfg->dscp_user_cos_num = cos_num;
wanted_dcb_cfg->dscp_valid_cos_map = valid_cos_bitmap;
}
@@ -601,11 +679,12 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int ret;
u8 cos_num, valid_cos_bitmap;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_TRUST) {
- if (qos_in->trust > DCB_DSCP) {
+ if (qos_in->trust > HINIC3_DCB_DSCP) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid trust=%u\n", qos_in->trust);
return -EINVAL;
@@ -615,7 +694,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
}
if (qos_in->cfg_bitmap & CMD_QOS_DEV_DFT_COS) {
- if (!(BIT(qos_in->dft_cos) & nic_dev->func_dft_cos_bitmap)) {
+ if (!(BIT(qos_in->dft_cos) & dcb->func_dft_cos_bitmap)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid dft_cos=%u\n", qos_in->dft_cos);
return -EINVAL;
@@ -628,7 +707,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
if (ret)
return ret;
- if (wanted_dcb_cfg->trust == DCB_PCP) {
+ if (wanted_dcb_cfg->trust == HINIC3_DCB_PCP) {
cos_num = wanted_dcb_cfg->pcp_user_cos_num;
valid_cos_bitmap = wanted_dcb_cfg->pcp_valid_cos_map;
} else {
@@ -636,18 +715,11 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = wanted_dcb_cfg->dscp_valid_cos_map;
}
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "DCB is on, cos num should not more than channel num:%u\n",
- nic_dev->q_params.num_qps);
- return -EOPNOTSUPP;
- }
- }
-
if (!(BIT(wanted_dcb_cfg->default_cos) & valid_cos_bitmap)) {
- nicif_info(nic_dev, drv, nic_dev->netdev, "Current default_cos=%u, change to %u\n",
- wanted_dcb_cfg->default_cos, (u8)fls(valid_cos_bitmap) - 1);
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Current default_cos=%u, change to %u\n",
+ wanted_dcb_cfg->default_cos,
+ (u8)fls(valid_cos_bitmap) - 1);
wanted_dcb_cfg->default_cos = (u8)fls(valid_cos_bitmap) - 1;
}
@@ -657,6 +729,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_dev_cfg *qos_in = buf_in;
struct hinic3_mt_qos_dev_cfg *qos_out = buf_out;
u8 i;
@@ -675,9 +748,10 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(qos_out, qos_in, sizeof(*qos_in));
qos_out->head.status = 0;
if (qos_in->op_code & MT_DCB_OPCODE_WR) {
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg,
+ memcpy(&dcb->wanted_dcb_cfg, &dcb->hw_dcb_cfg,
sizeof(struct hinic3_dcb_config));
- err = update_wanted_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg, qos_in);
+ err = update_wanted_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg,
+ qos_in);
if (err) {
qos_out->head.status = MT_EINVAL;
return 0;
@@ -687,12 +761,12 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
qos_out->head.status = MT_EIO;
} else {
- qos_out->dft_cos = nic_dev->hw_dcb_cfg.default_cos;
- qos_out->trust = nic_dev->hw_dcb_cfg.trust;
+ qos_out->dft_cos = dcb->hw_dcb_cfg.default_cos;
+ qos_out->trust = dcb->hw_dcb_cfg.trust;
for (i = 0; i < NIC_DCB_UP_MAX; i++)
- qos_out->pcp2cos[i] = nic_dev->hw_dcb_cfg.pcp2cos[i];
+ qos_out->pcp2cos[i] = dcb->hw_dcb_cfg.pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- qos_out->dscp2cos[i] = nic_dev->hw_dcb_cfg.dscp2cos[i];
+ qos_out->dscp2cos[i] = dcb->hw_dcb_cfg.dscp2cos[i];
}
return 0;
@@ -721,27 +795,17 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(dcb_out, dcb_in, sizeof(*dcb_in));
dcb_out->head.status = 0;
if (dcb_in->op_code & MT_DCB_OPCODE_WR) {
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) == dcb_in->state)
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ==
+ dcb_in->state)
return 0;
- if (dcb_in->state) {
- if (user_cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "cos num %u should not more than channel num %u\n",
- user_cos_num,
- nic_dev->q_params.num_qps);
-
- return -EOPNOTSUPP;
- }
- }
-
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? user_cos_num : 0,
+ err = hinic3_setup_cos(nic_dev->netdev,
+ dcb_in->state ? user_cos_num : 0,
netif_run);
if (err)
goto setup_cos_fail;
@@ -751,7 +815,6 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
goto vport_up_fail;
}
- rtnl_unlock();
} else {
dcb_out->state = !!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
}
@@ -759,12 +822,12 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
vport_up_fail:
- hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num,
+ netif_run);
setup_cos_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
return err;
}
@@ -772,13 +835,15 @@ setup_cos_fail:
static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_cos_cfg *cos_cfg_in = buf_in;
struct hinic3_mt_qos_cos_cfg *cos_cfg_out = buf_out;
if (!buf_in || !buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(*cos_cfg_out) || in_size != sizeof(*cos_cfg_in)) {
+ if (*out_size != sizeof(*cos_cfg_out) ||
+ in_size != sizeof(*cos_cfg_in)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
in_size, *out_size, sizeof(*cos_cfg_in));
@@ -789,9 +854,9 @@ static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
cos_cfg_out->head.status = 0;
cos_cfg_out->port_id = hinic3_physical_port_id(nic_dev->hwdev);
- cos_cfg_out->func_cos_bitmap = (u8)nic_dev->func_dft_cos_bitmap;
- cos_cfg_out->port_cos_bitmap = (u8)nic_dev->port_dft_cos_bitmap;
- cos_cfg_out->func_max_cos_num = nic_dev->cos_config_num_max;
+ cos_cfg_out->func_cos_bitmap = (u8)dcb->func_dft_cos_bitmap;
+ cos_cfg_out->port_cos_bitmap = (u8)dcb->port_dft_cos_bitmap;
+ cos_cfg_out->func_max_cos_num = dcb->cos_config_num_max;
return 0;
}
@@ -803,7 +868,13 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
intr_num = hinic3_intr_num(nic_dev->hwdev);
- if (!buf_out || !out_size || *out_size != sizeof(u16)) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != sizeof(u16)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(u16));
@@ -817,7 +888,13 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
static int get_netdev_name(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- if (!buf_out || !out_size || *out_size != IFNAMSIZ) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != IFNAMSIZ) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %u\n",
*out_size, IFNAMSIZ);
@@ -829,8 +906,9 @@ static int get_netdev_name(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
}
-static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
int *tx_timeout = buf_out;
@@ -839,7 +917,8 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (*out_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, out_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, out_size: %u, expect: %lu\n",
*out_size, sizeof(int));
return -EINVAL;
}
@@ -849,8 +928,9 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return 0;
}
-static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
const int *tx_timeout = buf_in;
@@ -859,13 +939,15 @@ static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (in_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, in_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, in_size: %u, expect: %lu\n",
in_size, sizeof(int));
return -EINVAL;
}
net_dev->watchdog_timeo = *tx_timeout * HZ;
- nicif_info(nic_dev, drv, net_dev, "Set tx timeout check period to %ds\n", *tx_timeout);
+ nicif_info(nic_dev, drv, net_dev,
+ "Set tx timeout check period to %ds\n", *tx_timeout);
return 0;
}
@@ -891,6 +973,34 @@ static int get_xsfp_present(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
}
+static int get_xsfp_tlv_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info = buf_out;
+ const struct tag_mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req = buf_in;
+ int err;
+
+ if ((buf_in == NULL) || (buf_out == NULL) || (out_size == NULL))
+ return -EINVAL;
+
+ if (*out_size != sizeof(*sfp_tlv_info) ||
+ in_size != sizeof(*sfp_tlv_info_req)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
+ in_size, *out_size, sizeof(*sfp_tlv_info));
+ return -EINVAL;
+ }
+
+ err = hinic3_get_sfp_tlv_info(nic_dev->hwdev,
+ sfp_tlv_info, sfp_tlv_info_req);
+ if (err != 0) {
+ sfp_tlv_info->head.status = MT_EIO;
+ return 0;
+ }
+
+ return 0;
+}
+
static int get_xsfp_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
@@ -928,7 +1038,7 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{GET_LOOPBACK_MODE, get_loopback_mode},
{SET_LOOPBACK_MODE, set_loopback_mode},
{SET_LINK_MODE, set_link_mode},
- {SET_PF_BW_LIMIT, set_pf_bw_limit},
+ {SET_TX_PF_BW_LIMIT, set_pf_bw_limit},
{GET_PF_BW_LIMIT, get_pf_bw_limit},
{GET_SSET_COUNT, get_sset_count},
{GET_SSET_ITEMS, get_sset_stats},
@@ -940,17 +1050,22 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{SET_TX_TIMEOUT, set_netdev_tx_timeout},
{GET_XSFP_PRESENT, get_xsfp_present},
{GET_XSFP_INFO, get_xsfp_info},
+ {GET_XSFP_INFO_COMP_CMIS, get_xsfp_tlv_info},
+ {SET_RX_PF_BW_LIMIT, set_rx_pf_bw_limit}
};
static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
u32 cmd, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(nic_driv_module_cmd_handle) /
- sizeof(nic_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(nic_driv_module_cmd_handle) /
+ sizeof(nic_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type = (enum driver_cmd_type)cmd;
int err = 0;
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_lock();
+
mutex_lock(&nic_dev->nic_mutex);
for (index = 0; index < num_cmds; index++) {
if (cmd_type ==
@@ -963,6 +1078,9 @@ static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
}
mutex_unlock(&nic_dev->nic_mutex);
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_unlock();
+
if (index == num_cmds) {
pr_err("Can't find callback for %d\n", cmd_type);
return -EINVAL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
index a1fb4af..ba4ec4d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
@@ -24,82 +24,80 @@
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_user_cos_num;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_user_cos_num;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_user_cos_num;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_user_cos_num;
return 0;
}
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_valid_cos_map;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_valid_cos_map;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_valid_cos_map;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_valid_cos_map;
return 0;
}
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
- u8 i, remainder, num_sq_per_cos, cur_cos_num = 0;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ struct hinic3_dcb_config *wanted_dcb_cfg =
+ &nic_dev->dcb->wanted_dcb_cfg;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
+ u8 cos_qp_num, cos_qp_offset = 0;
+ u8 i, remainder, num_qp_per_cos;
- if (num_cos == 0)
- return;
-
- num_sq_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
- if (num_sq_per_cos == 0)
+ if (num_cos == 0 || nic_dev->q_params.num_qps == 0)
return;
- remainder = nic_dev->q_params.num_qps % num_sq_per_cos;
+ num_qp_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
+ remainder = nic_dev->q_params.num_qps % num_cos;
- memset(dcb_cfg->cos_qp_offset, 0, sizeof(dcb_cfg->cos_qp_offset));
- memset(dcb_cfg->cos_qp_num, 0, sizeof(dcb_cfg->cos_qp_num));
+ memset(hw_dcb_cfg->cos_qp_offset, 0, sizeof(hw_dcb_cfg->cos_qp_offset));
+ memset(hw_dcb_cfg->cos_qp_num, 0, sizeof(hw_dcb_cfg->cos_qp_num));
for (i = 0; i < PCP_MAX_UP; i++) {
if (BIT(i) & valid_cos_map) {
- u8 cos_qp_num = num_sq_per_cos;
- u8 cos_qp_offset = (u8)(cur_cos_num * num_sq_per_cos);
-
- if (cur_cos_num < remainder) {
- cos_qp_num++;
- cos_qp_offset += cur_cos_num;
- } else {
- cos_qp_offset += remainder;
- }
-
- cur_cos_num++;
- valid_cos_map -= (u8)BIT(i);
+ cos_qp_num = num_qp_per_cos + ((remainder > 0) ?
+ (remainder--, 1) : 0);
- dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
- dcb_cfg->cos_qp_num[i] = cos_qp_num;
+ hw_dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
+ hw_dcb_cfg->cos_qp_num[i] = cos_qp_num;
hinic3_info(nic_dev, drv, "cos %u, cos_qp_offset=%u cos_qp_num=%u\n",
i, cos_qp_offset, cos_qp_num);
+
+ cos_qp_offset += cos_qp_num;
+ valid_cos_map -= (u8)BIT(i);
}
}
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_offset, dcb_cfg->cos_qp_offset,
- sizeof(dcb_cfg->cos_qp_offset));
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_num, dcb_cfg->cos_qp_num,
- sizeof(dcb_cfg->cos_qp_num));
+ memcpy(wanted_dcb_cfg->cos_qp_offset, hw_dcb_cfg->cos_qp_offset,
+ sizeof(hw_dcb_cfg->cos_qp_offset));
+ memcpy(wanted_dcb_cfg->cos_qp_num, hw_dcb_cfg->cos_qp_num,
+ sizeof(hw_dcb_cfg->cos_qp_num));
}
void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
u8 i;
u16 start_qid, q_num;
hinic3_set_txq_cos(nic_dev, 0, nic_dev->q_params.num_qps,
- nic_dev->hw_dcb_cfg.default_cos);
+ hw_dcb_cfg->default_cos);
if (!dcb_en)
return;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- q_num = (u16)nic_dev->hw_dcb_cfg.cos_qp_num[i];
+ q_num = (u16)hw_dcb_cfg->cos_qp_num[i];
if (q_num) {
- start_qid = (u16)nic_dev->hw_dcb_cfg.cos_qp_offset[i];
+ start_qid = (u16)hw_dcb_cfg->cos_qp_offset[i];
hinic3_set_txq_cos(nic_dev, start_qid, q_num, i);
hinic3_info(nic_dev, drv, "update tx db cos, start_qid %u, q_num=%u cos=%u\n",
@@ -110,30 +108,28 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ struct hinic3_dcb_config *hw_dcb_cfg = &dcb->hw_dcb_cfg;
struct hinic3_dcb_state dcb_state = {0};
u8 i;
int err;
-
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- /* VF does not support DCB, use the default cos */
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
-
- return 0;
- }
+ u32 pcp2cos_size = sizeof(dcb_state.pcp2cos);
+ u32 dscp2cos_size = sizeof(dcb_state.dscp2cos);
dcb_state.dcb_on = dcb_en;
- dcb_state.default_cos = dcb_cfg->default_cos;
- dcb_state.trust = dcb_cfg->trust;
+ dcb_state.default_cos = hw_dcb_cfg->default_cos;
+ dcb_state.trust = hw_dcb_cfg->trust;
if (dcb_en) {
for (i = 0; i < NIC_DCB_COS_MAX; i++)
- dcb_state.pcp2cos[i] = dcb_cfg->pcp2cos[i];
+ dcb_state.pcp2cos[i] = hw_dcb_cfg->pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- dcb_state.dscp2cos[i] = dcb_cfg->dscp2cos[i];
+ dcb_state.dscp2cos[i] = hw_dcb_cfg->dscp2cos[i];
} else {
- memset(dcb_state.pcp2cos, dcb_cfg->default_cos, sizeof(dcb_state.pcp2cos));
- memset(dcb_state.dscp2cos, dcb_cfg->default_cos, sizeof(dcb_state.dscp2cos));
+ memset(dcb_state.pcp2cos, hw_dcb_cfg->default_cos,
+ pcp2cos_size);
+ memset(dcb_state.dscp2cos, hw_dcb_cfg->default_cos,
+ dscp2cos_size);
}
err = hinic3_set_dcb_state(nic_dev->hwdev, &dcb_state);
@@ -143,7 +139,7 @@ static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
return err;
}
-static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
int err;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
@@ -169,11 +165,13 @@ static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
goto rx_configure_fail;
}
- if (dcb_en)
+ if (dcb_en) {
set_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
- else
+ set_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ } else {
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
-
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ }
return 0;
rx_configure_fail:
hinic3_set_tx_cos_state(nic_dev, dcb_en ? 0 : 1);
@@ -188,6 +186,7 @@ set_tx_cos_fail:
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err;
if (cos && test_bit(HINIC3_SAME_RXTX, &nic_dev->flags)) {
@@ -195,9 +194,10 @@ int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
return -EOPNOTSUPP;
}
- if (cos > nic_dev->cos_config_num_max) {
- nicif_err(nic_dev, drv, netdev, "Invalid num_tc: %u, max cos: %u\n",
- cos, nic_dev->cos_config_num_max);
+ if (cos > dcb->cos_config_num_max) {
+ nicif_err(nic_dev, drv, netdev,
+ "Invalid num_tc: %u, max cos: %u\n",
+ cos, dcb->cos_config_num_max);
return -EINVAL;
}
@@ -223,36 +223,48 @@ static u8 get_cos_num(u8 hw_valid_cos_bitmap)
static void hinic3_sync_dcb_cfg(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dcb_config *dcb_cfg)
{
- struct hinic3_dcb_config *hw_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
- memcpy(hw_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(hw_dcb_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
}
static int init_default_dcb_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *dcb_cfg)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 i, hw_dft_cos_map, port_cos_bitmap, dscp_ind;
int err;
+ int is_in_kexec;
- err = hinic3_cos_valid_bitmap(nic_dev->hwdev, &hw_dft_cos_map, &port_cos_bitmap);
+ err = hinic3_cos_valid_bitmap(nic_dev->hwdev,
+ &hw_dft_cos_map, &port_cos_bitmap);
if (err) {
hinic3_err(nic_dev, drv, "None cos supported\n");
return -EFAULT;
}
- nic_dev->func_dft_cos_bitmap = hw_dft_cos_map;
- nic_dev->port_dft_cos_bitmap = port_cos_bitmap;
- nic_dev->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+ is_in_kexec = vram_get_kexec_flag();
- dcb_cfg->trust = DCB_PCP;
- dcb_cfg->pcp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->dscp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
+ dcb->func_dft_cos_bitmap = hw_dft_cos_map;
+ dcb->port_dft_cos_bitmap = port_cos_bitmap;
+
+ dcb->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+
+ if (is_in_kexec == 0) {
+ dcb_cfg->trust = HINIC3_DCB_PCP;
+ dcb_cfg->default_cos = (u8)fls(dcb->func_dft_cos_bitmap) - 1;
+ } else {
+ dcb_cfg->trust = nic_dev->dcb->hw_dcb_cfg.trust;
+ dcb_cfg->default_cos = nic_dev->dcb->hw_dcb_cfg.default_cos;
+ }
+ dcb_cfg->pcp_user_cos_num = dcb->cos_config_num_max;
+ dcb_cfg->dscp_user_cos_num = dcb->cos_config_num_max;
dcb_cfg->pcp_valid_cos_map = hw_dft_cos_map;
dcb_cfg->dscp_valid_cos_map = hw_dft_cos_map;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i) ? i : dcb_cfg->default_cos;
+ dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i) ?
+ i : (u8)fls(dcb->func_dft_cos_bitmap) - 1;
for (dscp_ind = 0; dscp_ind < NIC_DCB_COS_MAX; dscp_ind++)
dcb_cfg->dscp2cos[i * NIC_DCB_DSCP_NUM + dscp_ind] = dcb_cfg->pcp2cos[i];
}
@@ -276,58 +288,117 @@ int hinic3_configure_dcb(struct net_device *netdev)
int err;
err = hinic3_sync_dcb_state(nic_dev->hwdev, 1,
- test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)
+ ? 1 : 0);
if (err) {
hinic3_err(nic_dev, drv, "Set dcb state failed\n");
return err;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ hinic3_sync_dcb_cfg(nic_dev, &nic_dev->dcb->wanted_dcb_cfg);
else
hinic3_dcb_reset_hw_config(nic_dev);
return 0;
}
+static int hinic3_dcb_alloc(struct hinic3_nic_dev *nic_dev)
+{
+ u16 func_id;
+ int is_use_vram;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(nic_dev->dcb_name, VRAM_NAME_MAX_LEN,
+ "%s%hu%s", VRAM_CQM_GLB_FUNC_BASE, func_id,
+ VRAM_NIC_DCB);
+
+ nic_dev->dcb = (struct hinic3_dcb *)hi_vram_kalloc(nic_dev->dcb_name,
+ sizeof(*nic_dev->dcb));
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to vram alloc dcb.\n");
+ return -EFAULT;
+ }
+ } else {
+ nic_dev->dcb = kzalloc(sizeof(*nic_dev->dcb), GFP_KERNEL);
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to create dcb.\n");
+ return -EFAULT;
+ }
+ }
+
+ return 0;
+}
+
+static void hinic3_dcb_free(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram)
+ hi_vram_kfree((void *)nic_dev->dcb, nic_dev->dcb_name,
+ sizeof(*nic_dev->dcb));
+ else
+ kfree(nic_dev->dcb);
+ nic_dev->dcb = NULL;
+}
+
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
+ hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+
+ hinic3_dcb_free(nic_dev);
+}
+
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = NULL;
int err;
u8 dcb_en = test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0;
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- return hinic3_set_tx_cos_state(nic_dev, dcb_en);
+ err = hinic3_dcb_alloc(nic_dev);
+ if (err != 0) {
+ hinic3_err(nic_dev, drv, "Dcb alloc failed.\n");
+ return err;
+ }
- err = init_default_dcb_cfg(nic_dev, dcb_cfg);
+ hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ err = init_default_dcb_cfg(nic_dev, hw_dcb_cfg);
if (err) {
- hinic3_err(nic_dev, drv, "Initialize dcb configuration failed\n");
+ hinic3_err(nic_dev, drv,
+ "Initialize dcb configuration failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&nic_dev->dcb->wanted_dcb_cfg, hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
hinic3_info(nic_dev, drv, "Support num cos %u, default cos %u\n",
- nic_dev->cos_config_num_max, dcb_cfg->default_cos);
+ nic_dev->dcb->cos_config_num_max, hw_dcb_cfg->default_cos);
err = hinic3_set_tx_cos_state(nic_dev, dcb_en);
if (err) {
hinic3_err(nic_dev, drv, "Set tx cos state failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- sema_init(&nic_dev->dcb_sem, 1);
-
return 0;
}
-static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dcb_config *dcb_cfg)
+static int change_qos_cfg(struct hinic3_nic_dev *nic_dev,
+ const struct hinic3_dcb_config *dcb_cfg)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err = 0;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags)) {
+ if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags)) {
nicif_warn(nic_dev, drv, netdev,
"Cos_up map setting in inprocess, please try again later\n");
return -EFAULT;
@@ -337,40 +408,44 @@ static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dc
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
- clear_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags);
+ clear_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags);
return err;
}
int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err, rollback_err;
u8 netif_run = 0;
struct hinic3_dcb_config old_dcb_cfg;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- memcpy(&old_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&old_dcb_cfg, &dcb->hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
- if (!memcmp(&nic_dev->wanted_dcb_cfg, &old_dcb_cfg, sizeof(struct hinic3_dcb_config))) {
+ if (!memcmp(&dcb->wanted_dcb_cfg, &old_dcb_cfg,
+ sizeof(struct hinic3_dcb_config))) {
nicif_info(nic_dev, drv, nic_dev->netdev,
"Same valid up bitmap, don't need to change anything\n");
return 0;
}
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = change_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ err = change_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Set cos_up map to hw failed\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Set cos_up map to hw failed\n");
goto change_qos_cfg_fail;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- err = hinic3_setup_cos(nic_dev->netdev, user_cos_num, netif_run);
+ err = hinic3_setup_cos(nic_dev->netdev,
+ user_cos_num, netif_run);
if (err)
goto set_err;
}
@@ -381,13 +456,12 @@ int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
goto vport_up_fail;
}
- rtnl_unlock();
-
return 0;
vport_up_fail:
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_setup_cos(nic_dev->netdev, user_cos_num ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, user_cos_num
+ ? 0 : user_cos_num, netif_run);
set_err:
rollback_err = change_qos_cfg(nic_dev, &old_dcb_cfg);
@@ -399,7 +473,5 @@ change_qos_cfg_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
-
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
index 7987f56..e0b35cb 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
@@ -24,11 +24,6 @@ struct hinic3_tc_cfg {
u16 rsvd;
};
-enum HINIC3_DCB_TRUST {
- DCB_PCP,
- DCB_DSCP,
-};
-
#define PCP_MAX_UP 8
#define DSCP_MAC_UP 64
#define DBG_DFLT_DSCP_VAL 0xFF
@@ -50,6 +45,7 @@ struct hinic3_dcb_config {
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev);
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev);
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev);
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev);
void hinic3_dcb_reset_hw_config(struct hinic3_nic_dev *nic_dev);
int hinic3_configure_dcb(struct net_device *netdev);
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run);
@@ -75,4 +71,5 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos);
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev);
int hinic3_vport_up(struct hinic3_nic_dev *nic_dev);
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
index 5a19959..ae41819 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
@@ -56,9 +56,8 @@ static void hinic3_get_drvinfo(struct net_device *netdev,
return;
}
- err = snprintf(info->fw_version, sizeof(info->fw_version), "%s", mgmt_ver);
- if (err < 0)
- nicif_err(nic_dev, drv, netdev, "Failed to snprintf fw version\n");
+ snprintf(info->fw_version, sizeof(info->fw_version),
+ "%s", mgmt_ver);
}
static u32 hinic3_get_msglevel(struct net_device *netdev)
@@ -86,7 +85,8 @@ static int hinic3_nway_reset(struct net_device *netdev)
while (test_and_set_bit(HINIC3_AUTONEG_RESET, &nic_dev->flags))
msleep(100); /* sleep 100 ms, waiting for another autoneg restart progress done */
- err = hinic3_get_port_info(nic_dev->hwdev, &port_info, HINIC3_CHANNEL_NIC);
+ err = hinic3_get_port_info(nic_dev->hwdev, &port_info,
+ HINIC3_CHANNEL_NIC);
if (err) {
nicif_err(nic_dev, drv, netdev, "Get port info failed\n");
err = -EFAULT;
@@ -273,7 +273,7 @@ static int get_coalesce(struct net_device *netdev,
static int set_queue_coalesce(struct hinic3_nic_dev *nic_dev, u16 q_id,
struct hinic3_intr_coal_info *coal)
{
- struct hinic3_intr_coal_info *intr_coal;
+ struct hinic3_intr_coal_info *intr_coal = NULL;
struct interrupt_info info = {0};
struct net_device *netdev = nic_dev->netdev;
int err;
@@ -367,24 +367,11 @@ static int is_coalesce_exceed_limit(struct net_device *netdev,
return 0;
}
-static int is_coalesce_legal(struct net_device *netdev,
- const struct ethtool_coalesce *coal)
+static int is_coalesce_allowed_change(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct ethtool_coalesce tmp_coal = {0};
- int err;
-
- if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
- nicif_err(nic_dev, drv, netdev,
- "tx-usecs must be equal to rx-usecs\n");
- return -EINVAL;
- }
-
- if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
- nicif_err(nic_dev, drv, netdev,
- "tx-frames must be equal to rx-frames\n");
- return -EINVAL;
- }
tmp_coal.cmd = coal->cmd;
tmp_coal.rx_coalesce_usecs = coal->rx_coalesce_usecs;
@@ -409,6 +396,31 @@ static int is_coalesce_legal(struct net_device *netdev,
return -EOPNOTSUPP;
}
+ return 0;
+}
+
+static int is_coalesce_legal(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-usecs must be equal to rx-usecs\n");
+ return -EINVAL;
+ }
+
+ if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-frames must be equal to rx-frames\n");
+ return -EINVAL;
+ }
+
+ err = is_coalesce_allowed_change(netdev, coal);
+ if (err)
+ return err;
+
err = is_coalesce_exceed_limit(netdev, coal);
if (err)
return err;
@@ -444,7 +456,8 @@ static int is_coalesce_legal(struct net_device *netdev,
return 0;
}
-static inline void check_coalesce_align(struct hinic3_nic_dev *nic_dev, struct net_device *netdev,
+static inline void check_coalesce_aligned(struct hinic3_nic_dev *nic_dev,
+ struct net_device *netdev,
u32 item, u32 unit, char *str)
{
if (item % unit)
@@ -453,10 +466,12 @@ static inline void check_coalesce_align(struct hinic3_nic_dev *nic_dev, struct n
}
#define CHECK_COALESCE_ALIGN(member, unit) \
- check_coalesce_align(nic_dev, netdev, member, unit, #member)
+ check_coalesce_aligned(nic_dev, netdev, member, unit, #member)
-static inline void check_coalesce_changed(struct hinic3_nic_dev *nic_dev, struct net_device *netdev,
- u32 item, u32 unit, u32 ori_val, char *obj_str, char *str)
+static inline void check_coalesce_changed(struct hinic3_nic_dev *nic_dev,
+ struct net_device *netdev,
+ u32 item, u32 unit, u32 ori_val,
+ char *obj_str, char *str)
{
if ((item / unit) != ori_val)
nicif_info(nic_dev, drv, netdev, "Change %s from %d to %u %s\n",
@@ -466,8 +481,10 @@ static inline void check_coalesce_changed(struct hinic3_nic_dev *nic_dev, struct
#define CHECK_COALESCE_CHANGED(member, unit, ori_val, obj_str) \
check_coalesce_changed(nic_dev, netdev, member, unit, ori_val, obj_str, #member)
-static inline void check_pkt_rate_changed(struct hinic3_nic_dev *nic_dev, struct net_device *netdev,
- u32 item, u32 ori_val, char *obj_str, char *str)
+static inline void check_pkt_rate_changed(struct hinic3_nic_dev *nic_dev,
+ struct net_device *netdev,
+ u32 item, u32 ori_val, char *obj_str,
+ char *str)
{
if (item != ori_val)
nicif_info(nic_dev, drv, netdev, "Change %s from %d to %u %s\n",
@@ -497,19 +514,10 @@ static int set_hw_coal_param(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static int set_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *coal, u16 queue)
+static void check_coalesce_align(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
- struct hinic3_intr_coal_info intr_coal = {0};
- struct hinic3_intr_coal_info *ori_intr_coal = NULL;
- u32 last_adaptive_rx;
- char obj_str[32] = {0};
- int err = 0;
-
- err = is_coalesce_legal(netdev, coal);
- if (err)
- return err;
CHECK_COALESCE_ALIGN(coal->rx_coalesce_usecs, COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal->rx_max_coalesced_frames,
@@ -522,6 +530,14 @@ static int set_coalesce(struct net_device *netdev,
COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal->rx_max_coalesced_frames_low,
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int check_coalesce_change(struct net_device *netdev,
+ u16 queue, struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info *ori_intr_coal = NULL;
+ char obj_str[32] = {0};
if (queue == COALESCE_ALL_QUEUE) {
ori_intr_coal = &nic_dev->intr_coalesce[0];
@@ -552,27 +568,54 @@ static int set_coalesce(struct net_device *netdev,
COALESCE_PENDING_LIMIT_UNIT,
ori_intr_coal->rx_pending_limt_low, obj_str);
- intr_coal.coalesce_timer_cfg =
+ return 0;
+}
+
+static void init_intr_coal_params(struct hinic3_intr_coal_info *intr_coal,
+ struct ethtool_coalesce *coal)
+{
+ intr_coal->coalesce_timer_cfg =
(u8)(coal->rx_coalesce_usecs / COALESCE_TIMER_CFG_UNIT);
- intr_coal.pending_limt = (u8)(coal->rx_max_coalesced_frames /
+ intr_coal->pending_limt = (u8)(coal->rx_max_coalesced_frames /
COALESCE_PENDING_LIMIT_UNIT);
- last_adaptive_rx = nic_dev->adaptive_rx_coal;
- nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
-
- intr_coal.pkt_rate_high = coal->pkt_rate_high;
- intr_coal.rx_usecs_high =
+ intr_coal->pkt_rate_high = coal->pkt_rate_high;
+ intr_coal->rx_usecs_high =
(u8)(coal->rx_coalesce_usecs_high / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_high =
+ intr_coal->rx_pending_limt_high =
(u8)(coal->rx_max_coalesced_frames_high /
COALESCE_PENDING_LIMIT_UNIT);
- intr_coal.pkt_rate_low = coal->pkt_rate_low;
- intr_coal.rx_usecs_low =
+ intr_coal->pkt_rate_low = coal->pkt_rate_low;
+ intr_coal->rx_usecs_low =
(u8)(coal->rx_coalesce_usecs_low / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_low =
+ intr_coal->rx_pending_limt_low =
(u8)(coal->rx_max_coalesced_frames_low /
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal, u16 queue)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info intr_coal = {0};
+ u32 last_adaptive_rx;
+ int err = 0;
+
+ err = is_coalesce_legal(netdev, coal);
+ if (err)
+ return err;
+
+ check_coalesce_align(netdev, coal);
+
+ err = check_coalesce_change(netdev, queue, coal);
+ if (err)
+ return err;
+
+ init_intr_coal_params(&intr_coal, coal);
+
+ last_adaptive_rx = nic_dev->adaptive_rx_coal;
+ nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
/* coalesce timer or pending set to zero will disable coalesce */
if (!nic_dev->adaptive_rx_coal &&
@@ -709,14 +752,16 @@ static int hinic3_set_pauseparam(struct net_device *netdev,
return -EFAULT;
}
- auto_neg = port_info.autoneg_state == PORT_CFG_AN_ON ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+ auto_neg = port_info.autoneg_state == PORT_CFG_AN_ON ?
+ AUTONEG_ENABLE : AUTONEG_DISABLE;
if (pause->autoneg != auto_neg) {
nicif_err(nic_dev, drv, netdev,
"To change autoneg please use: ethtool -s <dev> autoneg <on|off>\n");
return -EOPNOTSUPP;
}
- nic_pause.auto_neg = pause->autoneg == AUTONEG_ENABLE ? PORT_CFG_AN_ON : PORT_CFG_AN_OFF;
+ nic_pause.auto_neg = pause->autoneg == AUTONEG_ENABLE ?
+ PORT_CFG_AN_ON : PORT_CFG_AN_OFF;
nic_pause.rx_pause = (u8)pause->rx_pause;
nic_pause.tx_pause = (u8)pause->tx_pause;
@@ -768,6 +813,14 @@ static int hinic3_get_module_info(struct net_device *netdev,
modinfo->type = ETH_MODULE_SFF_8636;
modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
break;
+ case MODULE_TYPE_DSFP:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
+ case MODULE_TYPE_QSFP_CMIS:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
default:
nicif_warn(nic_dev, drv, netdev,
"Optical module unknown: 0x%x\n", sfp_type);
@@ -790,6 +843,11 @@ static int hinic3_get_module_eeprom(struct net_device *netdev,
memset(data, 0, ee->len);
err = hinic3_get_sfp_eeprom(nic_dev->hwdev, (u8 *)sfp_data, ee->len);
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(nic_dev->hwdev,
+ (u8 *)sfp_data,
+ sizeof(sfp_data));
+
if (err)
return err;
@@ -832,7 +890,8 @@ int hinic3_set_rxq_recovery_flag(struct net_device *netdev, u32 priv_flags)
if (test_and_set_bit(HINIC3_RXQ_RECOVERY, &nic_dev->flags))
return 0;
- queue_delayed_work(nic_dev->workq, &nic_dev->rxq_check_work, HZ);
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->rxq_check_work, HZ);
nicif_info(nic_dev, drv, netdev, "open rxq recovery\n");
} else {
if (!test_and_clear_bit(HINIC3_RXQ_RECOVERY, &nic_dev->flags))
@@ -888,7 +947,8 @@ static int hinic3_set_force_link_flag(struct net_device *netdev, u32 priv_flags)
nicif_info(nic_dev, link, netdev, "Set link up\n");
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, nic_dev->link_status);
+ hinic3_notify_all_vfs_link_changed(
+ nic_dev->hwdev, nic_dev->link_status);
} else {
if (!test_and_clear_bit(HINIC3_FORCE_LINK_UP, &nic_dev->flags))
return 0;
@@ -919,7 +979,8 @@ static int hinic3_set_force_link_flag(struct net_device *netdev, u32 priv_flags)
}
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, nic_dev->link_status);
+ hinic3_notify_all_vfs_link_changed(
+ nic_dev->hwdev, nic_dev->link_status);
}
return 0;
@@ -942,7 +1003,6 @@ static int hinic3_set_priv_flags(struct net_device *netdev, u32 priv_flags)
#define PORT_DOWN_ERR_IDX 0
#define LP_DEFAULT_TIME 5 /* seconds */
-#define LP_PKT_LEN 60
#define TEST_TIME_MULTIPLE 5
static int hinic3_run_lp_test(struct hinic3_nic_dev *nic_dev, u32 test_time)
@@ -958,8 +1018,11 @@ static int hinic3_run_lp_test(struct hinic3_nic_dev *nic_dev, u32 test_time)
u8 j;
skb_tmp = alloc_skb(LP_PKT_LEN, GFP_ATOMIC);
- if (!skb_tmp)
+ if (!skb_tmp) {
+ nicif_err(nic_dev, drv, netdev,
+ "Alloc xmit skb template failed for loopback test\n");
return -ENOMEM;
+ }
eth_hdr = __skb_put(skb_tmp, ETH_HLEN);
eth_hdr->h_proto = htons(ETH_P_ARP);
@@ -1057,6 +1120,8 @@ static int do_lp_test(struct hinic3_nic_dev *nic_dev, u32 *flags, u32 test_time,
lb_test_rx_buf = vmalloc(LP_PKT_CNT * LP_PKT_LEN);
if (!lb_test_rx_buf) {
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to alloc RX buffer for loopback test\n");
err = -ENOMEM;
} else {
nic_dev->lb_test_rx_buf = lb_test_rx_buf;
@@ -1086,7 +1151,8 @@ static int do_lp_test(struct hinic3_nic_dev *nic_dev, u32 *flags, u32 test_time,
return err;
}
-static void hinic3_lp_test(struct net_device *netdev, struct ethtool_test *eth_test,
+static void hinic3_lp_test(struct net_device *netdev,
+ struct ethtool_test *eth_test,
u64 *data, u32 test_time)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
@@ -1109,7 +1175,8 @@ static void hinic3_lp_test(struct net_device *netdev, struct ethtool_test *eth_t
netif_carrier_off(netdev);
netif_tx_disable(netdev);
- err = do_lp_test(nic_dev, ð_test->flags, test_time_real, &test_index);
+ err = do_lp_test(nic_dev, ð_test->flags,
+ test_time_real, &test_index);
if (err) {
eth_test->flags |= ETH_TEST_FL_FAILED;
data[test_index] = 1;
@@ -1130,10 +1197,65 @@ static void hinic3_diag_test(struct net_device *netdev,
hinic3_lp_test(netdev, eth_test, data, 0);
}
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+static int hinic3_get_fecparam(struct net_device *netdev,
+ struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u8 advertised_fec = 0;
+ u8 supported_fec = 0;
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_GFECPARAM) {
+ nicif_err(nic_dev, drv, netdev,
+ "get fecparam cmd err.exp:0x%x,real:0x%x\n",
+ ETHTOOL_GFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = get_fecparam(nic_dev->hwdev, &advertised_fec, &supported_fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Get fec param failed\n");
+ return err;
+ }
+ fecparam->active_fec = (u32)advertised_fec;
+ fecparam->fec = (u32)supported_fec;
+
+ nicif_info(nic_dev, drv, netdev, "Get fec param success\n");
+ return 0;
+}
+
+static int hinic3_set_fecparam(struct net_device *netdev,
+ struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_SFECPARAM) {
+ nicif_err(nic_dev, drv, netdev,
+ "Set fecparam cmd err.exp:0x%x,real:0x%x\n",
+ ETHTOOL_SFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = set_fecparam(nic_dev->hwdev, (u8)fecparam->fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Set fec param failed\n");
+ return err;
+ }
+
+ nicif_info(nic_dev, drv, netdev, "Set fec param success\n");
+ return 0;
+}
+#endif
+
static const struct ethtool_ops hinic3_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1180,6 +1302,10 @@ static const struct ethtool_ops hinic3_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
@@ -1240,7 +1366,10 @@ static const struct ethtool_ops_ext hinic3_ethtool_ops_ext = {
static const struct ethtool_ops hinic3vf_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1267,6 +1396,11 @@ static const struct ethtool_ops hinic3vf_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
+
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
index b0e6aad..938cf2c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
@@ -24,11 +24,29 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
-#define FPGA_PORT_COUNTER 0
-#define EVB_PORT_COUNTER 1
-u16 mag_support_mode = EVB_PORT_COUNTER;
-module_param(mag_support_mode, ushort, 0444);
-MODULE_PARM_DESC(mag_support_mode, "Set mag port counter support mode, 0:FPGA 1:EVB, default is 1");
+#define HINIC_SET_LINK_STR_LEN 128
+#define HINIC_ETHTOOL_FEC_INFO_LEN 6
+#define HINIC_SUPPORTED_FEC_CMD 0
+#define HINIC_ADVERTISED_FEC_CMD 1
+
+struct hinic3_ethtool_fec {
+ u8 hinic_fec_offset;
+ u8 ethtool_bit_offset;
+};
+
+static struct hinic3_ethtool_fec
+ hinic3_ethtool_fec_info[HINIC_ETHTOOL_FEC_INFO_LEN] = {
+ /* The ethtool does not have the corresponding enumeration variable */
+ {PORT_FEC_NOT_SET, 0xFF},
+ {PORT_FEC_RSFEC, 0x32}, /* ETHTOOL_LINK_MODE_FEC_RS_BIT */
+ /* ETHTOOL_LINK_MODE_FEC_BASER_BIT */
+ {PORT_FEC_BASEFEC, 0x33},
+ {PORT_FEC_NOFEC, 0x31}, /* ETHTOOL_LINK_MODE_FEC_NONE_BIT */
+ /* ETHTOOL_LINK_MODE_FEC_LLRS_BIT: Available only in later versions */
+ {PORT_FEC_LLRSFEC, 0x4A},
+ /* The ethtool does not have the corresponding enumeration variable */
+ {PORT_FEC_AUTO, 0XFF}
+};
struct hinic3_stats {
char name[ETH_GSTRING_LEN];
@@ -36,9 +54,23 @@ struct hinic3_stats {
int offset;
};
+struct hinic3_netdev_link_count_str {
+ u64 link_down_events_phy;
+};
+
+#define HINIC3_NETDEV_LINK_COUNT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic3_netdev_link_count_str, _stat_item), \
+ .offset = offsetof(struct hinic3_netdev_link_count_str, _stat_item) \
+}
+
+static struct hinic3_stats hinic3_netdev_link_count[] = {
+ HINIC3_NETDEV_LINK_COUNT(link_down_events_phy),
+};
+
#define HINIC3_NETDEV_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct rtnl_link_stats64, _stat_item), \
+ .size = FIELD_SIZEOF(struct rtnl_link_stats64, _stat_item), \
.offset = offsetof(struct rtnl_link_stats64, _stat_item) \
}
@@ -67,7 +99,7 @@ static struct hinic3_stats hinic3_netdev_stats[] = {
#define HINIC3_NIC_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct hinic3_nic_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_nic_stats, _stat_item), \
.offset = offsetof(struct hinic3_nic_stats, _stat_item) \
}
@@ -84,17 +116,16 @@ static struct hinic3_stats hinic3_nic_dev_stats_extern[] = {
#define HINIC3_RXQ_STAT(_stat_item) { \
.name = "rxq%d_"#_stat_item, \
- .size = sizeof_field(struct hinic3_rxq_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_rxq_stats, _stat_item), \
.offset = offsetof(struct hinic3_rxq_stats, _stat_item) \
}
#define HINIC3_TXQ_STAT(_stat_item) { \
.name = "txq%d_"#_stat_item, \
- .size = sizeof_field(struct hinic3_txq_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_txq_stats, _stat_item), \
.offset = offsetof(struct hinic3_txq_stats, _stat_item) \
}
-/*lint -save -e786*/
static struct hinic3_stats hinic3_rx_queue_stats[] = {
HINIC3_RXQ_STAT(packets),
HINIC3_RXQ_STAT(bytes),
@@ -135,11 +166,9 @@ static struct hinic3_stats hinic3_tx_queue_stats_extern[] = {
HINIC3_TXQ_STAT(rsvd2),
};
-/*lint -restore*/
-
#define HINIC3_FUNC_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct hinic3_vport_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_vport_stats, _stat_item), \
.offset = offsetof(struct hinic3_vport_stats, _stat_item) \
}
@@ -166,7 +195,7 @@ static struct hinic3_stats hinic3_function_stats[] = {
#define HINIC3_PORT_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct mag_cmd_port_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct mag_cmd_port_stats, _stat_item), \
.offset = offsetof(struct mag_cmd_port_stats, _stat_item) \
}
@@ -260,49 +289,22 @@ static struct hinic3_stats hinic3_port_stats[] = {
HINIC3_PORT_STAT(mac_rx_unfilter_pkt_num),
};
-#define HINIC3_FGPA_PORT_STAT(_stat_item) { \
+#define HINIC3_RSFEC_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct hinic3_phy_fpga_port_stats, _stat_item), \
- .offset = offsetof(struct hinic3_phy_fpga_port_stats, _stat_item) \
+ .size = FIELD_SIZEOF(struct mag_cmd_rsfec_stats, _stat_item), \
+ .offset = offsetof(struct mag_cmd_rsfec_stats, _stat_item) \
}
-static struct hinic3_stats g_hinic3_fpga_port_stats[] = {
- HINIC3_FGPA_PORT_STAT(mac_rx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_under_frame_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_frag_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_crc_error_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_length_err_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_pause_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_unknown_mac_frame_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_underrun_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_pause_pkts_port),
+static struct hinic3_stats g_hinic3_rsfec_stats[] = {
+ HINIC3_RSFEC_STAT(rx_err_lane_phy),
};
+#define HINIC3_FGPA_PORT_STAT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic3_phy_fpga_port_stats, _stat_item), \
+ .offset = offsetof(struct hinic3_phy_fpga_port_stats, _stat_item) \
+}
+
static char g_hinic_priv_flags_strings[][ETH_GSTRING_LEN] = {
"Symmetric-RSS",
"Force-Link-up",
@@ -318,8 +320,7 @@ u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev)
(ARRAY_LEN(hinic3_tx_queue_stats) +
ARRAY_LEN(hinic3_tx_queue_stats_extern) +
ARRAY_LEN(hinic3_rx_queue_stats) +
- ARRAY_LEN(hinic3_rx_queue_stats_extern)) *
- nic_dev->max_qps;
+ ARRAY_LEN(hinic3_rx_queue_stats_extern)) * nic_dev->max_qps;
return count;
}
@@ -343,72 +344,87 @@ static int dev_stats_pack(struct hinic3_show_item *items, int len,
memcpy(items[item_idx].name, array[j].name,
HINIC3_SHOW_ITEM_LEN);
items[item_idx].hexadecimal = 0;
- items[item_idx].value = get_value_of_ptr(array[j].size,
- stats_ptr + array[j].offset);
+ items[item_idx].value =
+ get_value_of_ptr(array[j].size,
+ stats_ptr + array[j].offset);
item_idx++;
}
return item_idx;
}
-static int queue_stats_pack(struct hinic3_show_item *items, int len,
- struct hinic3_stats *array, void *stats_ptr,
- u16 qid)
+int hinic3_rx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat, struct hinic3_rxq_stats *rxq_stats, u16 qid)
{
- int j;
- int item_idx = 0;
+ snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
- for (j = 0; j < len; j++) {
- memcpy(items[item_idx].name, array[j].name,
- HINIC3_SHOW_ITEM_LEN);
- snprintf(items[item_idx].name, HINIC3_SHOW_ITEM_LEN,
- array[j].name, qid);
- items[item_idx].hexadecimal = 0;
- items[item_idx].value = get_value_of_ptr(array[j].size,
- stats_ptr + array[j].offset);
- item_idx++;
- }
+ item->hexadecimal = 0;
+ item->value = get_value_of_ptr(stat->size, (char *)(rxq_stats) +
+ stat->offset);
- return item_idx;
+ return 0;
+}
+
+int hinic3_tx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat, struct hinic3_txq_stats *txq_stats, u16 qid)
+{
+ snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
+
+ item->hexadecimal = 0;
+ item->value = get_value_of_ptr(stat->size, (char *)(txq_stats) +
+ stat->offset);
+
+ return 0;
}
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
{
struct hinic3_show_item *items = stats;
int item_idx = 0;
u16 qid;
+ int idx;
+ int ret;
- item_idx += dev_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_nic_dev_stats),
- hinic3_nic_dev_stats, &nic_dev->stats);
- item_idx += dev_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_nic_dev_stats_extern),
- hinic3_nic_dev_stats_extern,
- &nic_dev->stats);
+ dev_stats_pack(items, item_idx, hinic3_nic_dev_stats, &nic_dev->stats);
+ dev_stats_pack(items, item_idx, hinic3_nic_dev_stats_extern, &nic_dev->stats);
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_tx_queue_stats),
- hinic3_tx_queue_stats,
- &nic_dev->txqs[qid].txq_stats,
- qid);
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_tx_queue_stats_extern),
- hinic3_tx_queue_stats_extern,
- &nic_dev->txqs[qid].txq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++],
+ &hinic3_tx_queue_stats[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats_extern); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++],
+ &hinic3_tx_queue_stats_extern[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
}
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_rx_queue_stats),
- hinic3_rx_queue_stats,
- &nic_dev->rxqs[qid].rxq_stats,
- qid);
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_rx_queue_stats_extern),
- hinic3_rx_queue_stats_extern,
- &nic_dev->rxqs[qid].rxq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++],
+ &hinic3_rx_queue_stats[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats_extern); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++],
+ &hinic3_rx_queue_stats_extern[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
}
+
+ return 0;
}
static char g_hinic3_test_strings[][ETH_GSTRING_LEN] = {
@@ -428,16 +444,14 @@ int hinic3_get_sset_count(struct net_device *netdev, int sset)
q_num = nic_dev->q_params.num_qps;
count = ARRAY_LEN(hinic3_netdev_stats) +
ARRAY_LEN(hinic3_nic_dev_stats) +
+ ARRAY_LEN(hinic3_netdev_link_count) +
ARRAY_LEN(hinic3_function_stats) +
(ARRAY_LEN(hinic3_tx_queue_stats) +
- ARRAY_LEN(hinic3_rx_queue_stats)) *
- q_num;
+ ARRAY_LEN(hinic3_rx_queue_stats)) * q_num;
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER)
- count += ARRAY_LEN(g_hinic3_fpga_port_stats);
- else
- count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(g_hinic3_rsfec_stats);
}
return count;
@@ -486,9 +500,9 @@ static void get_drv_queue_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
}
}
-static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct hinic3_phy_fpga_port_stats *port_stats = NULL;
+ struct mag_cmd_port_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
@@ -496,19 +510,19 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
if (!port_stats) {
memset(&data[i], 0,
- ARRAY_LEN(g_hinic3_fpga_port_stats) * sizeof(*data));
- i += ARRAY_LEN(g_hinic3_fpga_port_stats);
+ ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
+ i += ARRAY_LEN(hinic3_port_stats);
return i;
}
- err = hinic3_get_fpga_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to get port stats from fw\n");
- for (j = 0; j < ARRAY_LEN(g_hinic3_fpga_port_stats); j++, i++) {
- p = (char *)(port_stats) + g_hinic3_fpga_port_stats[j].offset;
- data[i] = (g_hinic3_fpga_port_stats[j].size == sizeof(u64)) ?
+ for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
+ p = (char *)(port_stats) + hinic3_port_stats[j].offset;
+ data[i] = (hinic3_port_stats[j].size == sizeof(u64)) ?
*(u64 *)p :
*(u32 *)p;
}
@@ -518,34 +532,32 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
return i;
}
-static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_rsfec_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct mag_cmd_port_stats *port_stats = NULL;
+ struct mag_cmd_rsfec_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
- if (mag_support_mode == FPGA_PORT_COUNTER)
- return get_fpga_port_stats(nic_dev, data);
-
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
if (!port_stats) {
- memset(&data[i], 0,
- ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
- i += ARRAY_LEN(hinic3_port_stats);
- return i;
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to malloc port stats\n");
+ memset(&data[i], 0,
+ ARRAY_LEN(g_hinic3_rsfec_stats) * sizeof(*data));
+ i += ARRAY_LEN(g_hinic3_rsfec_stats);
+ return i;
}
- err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_rsfec_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to get port stats from fw\n");
+ "Failed to get rsfec stats from fw\n");
- for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
- p = (char *)(port_stats) + hinic3_port_stats[j].offset;
- data[i] = (hinic3_port_stats[j].size == sizeof(u64)) ?
- *(u64 *)p :
- *(u32 *)p;
+ for (j = 0; j < ARRAY_LEN(g_hinic3_rsfec_stats); j++, i++) {
+ p = (char *)(port_stats) + g_hinic3_rsfec_stats[j].offset;
+ data[i] = (g_hinic3_rsfec_stats[j].size ==
+ sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
kfree(port_stats);
@@ -569,6 +581,8 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
u16 i = 0, j = 0;
char *p = NULL;
int err;
+ int link_down_events_phy_tmp = 0;
+ struct hinic3_netdev_link_count_str link_count = {0};
#ifdef HAVE_NDO_GET_STATS64
net_stats = dev_get_stats(netdev, &temp);
@@ -586,6 +600,15 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = get_value_of_ptr(hinic3_nic_dev_stats[j].size, p);
}
+ err = hinic3_get_link_event_stats(nic_dev->hwdev,
+ &link_down_events_phy_tmp);
+
+ link_count.link_down_events_phy = (u64)link_down_events_phy_tmp;
+ for (j = 0; j < ARRAY_LEN(hinic3_netdev_link_count); j++, i++) {
+ p = (char *)(&link_count) + hinic3_netdev_link_count[j].offset;
+ data[i] = get_value_of_ptr(hinic3_netdev_link_count[j].size, p);
+ }
+
err = hinic3_get_vport_stats(nic_dev->hwdev,
hinic3_global_func_id(nic_dev->hwdev),
&vport_stats);
@@ -598,8 +621,10 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = get_value_of_ptr(hinic3_function_stats[j].size, p);
}
- if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
i += get_ethtool_port_stats(nic_dev, data + i);
+ i += get_ethtool_rsfec_stats(nic_dev, data + i);
+ }
get_drv_queue_stats(nic_dev, data + i);
}
@@ -620,6 +645,12 @@ static u16 get_drv_dev_strings(struct hinic3_nic_dev *nic_dev, char *p)
cnt++;
}
+ for (i = 0; i < ARRAY_LEN(hinic3_netdev_link_count); i++) {
+ memcpy(p, hinic3_netdev_link_count[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+
return cnt;
}
@@ -634,21 +665,16 @@ static u16 get_hw_stats_strings(struct hinic3_nic_dev *nic_dev, char *p)
}
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER) {
- for (i = 0; i < ARRAY_LEN(g_hinic3_fpga_port_stats);
- i++) {
- memcpy(p, g_hinic3_fpga_port_stats[i].name,
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
- } else {
- for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
- memcpy(p, hinic3_port_stats[i].name,
+ for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
+ memcpy(p, hinic3_port_stats[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+ for (i = 0; i < ARRAY_LEN(g_hinic3_rsfec_stats); i++) {
+ memcpy(p, g_hinic3_rsfec_stats[i].name,
ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
+ p += ETH_GSTRING_LEN;
+ cnt++;
}
}
@@ -664,7 +690,8 @@ static u16 get_qp_stats_strings(const struct hinic3_nic_dev *nic_dev, char *p)
for (j = 0; j < ARRAY_LEN(hinic3_tx_queue_stats); j++) {
err = sprintf(p, hinic3_tx_queue_stats[j].name, i);
if (err < 0)
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to sprintf tx queue stats name, idx_qps: %u, idx_stats: %u\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to sprintf tx queue stats name, idx_qps: %u, idx_stats: %u\n",
i, j);
p += ETH_GSTRING_LEN;
cnt++;
@@ -675,7 +702,8 @@ static u16 get_qp_stats_strings(const struct hinic3_nic_dev *nic_dev, char *p)
for (j = 0; j < ARRAY_LEN(hinic3_rx_queue_stats); j++) {
err = sprintf(p, hinic3_rx_queue_stats[j].name, i);
if (err < 0)
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to sprintf rx queue stats name, idx_qps: %u, idx_stats: %u\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to sprintf rx queue stats name, idx_qps: %u, idx_stats: %u\n",
i, j);
p += ETH_GSTRING_LEN;
cnt++;
@@ -791,7 +819,6 @@ struct hw2ethtool_link_mode {
u32 speed;
};
-/*lint -save -e26 */
static const struct hw2ethtool_link_mode
hw2ethtool_link_mode_table[LINK_MODE_MAX_NUMBERS] = {
[LINK_MODE_GE] = {
@@ -851,8 +878,6 @@ static const struct hw2ethtool_link_mode
},
};
-/*lint -restore */
-
#define GET_SUPPORTED_MODE 0
#define GET_ADVERTISED_MODE 1
@@ -867,21 +892,37 @@ struct cmd_link_settings {
};
#define ETHTOOL_ADD_SUPPORTED_LINK_MODE(ecmd, mode) \
- set_bit(ETHTOOL_LINK_##mode##_BIT, (ecmd)->supported)
+ set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->supported)
#define ETHTOOL_ADD_ADVERTISED_LINK_MODE(ecmd, mode) \
- set_bit(ETHTOOL_LINK_##mode##_BIT, (ecmd)->advertising)
+ set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->advertising)
-static void ethtool_add_speed_link_mode(__ETHTOOL_DECLARE_LINK_MODE_MASK(bitmap), u32 mode)
+static void ethtool_add_supported_speed_link_mode(
+ struct cmd_link_settings *link_settings,
+ u32 mode)
{
u32 i;
for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
- __ETHTOOL_LINK_MODE_MASK_NBITS)
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
continue;
+ set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
+ link_settings->supported);
+ }
+}
+static void ethtool_add_advertised_speed_link_mode(
+ struct cmd_link_settings *link_settings,
+ u32 mode)
+{
+ u32 i;
+
+ for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
+ if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
+ continue;
set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
- bitmap);
+ link_settings->advertising);
}
}
@@ -912,9 +953,11 @@ hinic3_add_ethtool_link_mode(struct cmd_link_settings *link_settings,
for (link_mode = 0; link_mode < LINK_MODE_MAX_NUMBERS; link_mode++) {
if (hw_link_mode & BIT(link_mode)) {
if (name == GET_SUPPORTED_MODE)
- ethtool_add_speed_link_mode(link_settings->supported, link_mode);
+ ethtool_add_supported_speed_link_mode(
+ link_settings, link_mode);
else
- ethtool_add_speed_link_mode(link_settings->advertising, link_mode);
+ ethtool_add_advertised_speed_link_mode(
+ link_settings, link_mode);
}
}
}
@@ -937,10 +980,15 @@ static int hinic3_link_speed_set(struct hinic3_nic_dev *nic_dev,
err = hinic3_get_link_state(nic_dev->hwdev, &link_state);
if (!err && link_state) {
- link_settings->speed =
- port_info->speed < ARRAY_LEN(hw_to_ethtool_speed) ?
+ if (hinic3_get_bond_create_mode(nic_dev->hwdev)) {
+ link_settings->speed = port_info->bond_speed;
+ } else {
+ link_settings->speed =
+ port_info->speed <
+ ARRAY_LEN(hw_to_ethtool_speed) ?
hw_to_ethtool_speed[port_info->speed] :
(u32)SPEED_UNKNOWN;
+ }
link_settings->duplex = port_info->duplex;
} else {
@@ -956,28 +1004,28 @@ static void hinic3_link_port_type(struct cmd_link_settings *link_settings,
{
switch (port_type) {
case MAG_CMD_WIRE_TYPE_ELECTRIC:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_TP);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_TP);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, TP);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, TP);
link_settings->port = PORT_TP;
break;
case MAG_CMD_WIRE_TYPE_AOC:
case MAG_CMD_WIRE_TYPE_MM:
case MAG_CMD_WIRE_TYPE_SM:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_FIBRE);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_FIBRE);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, FIBRE);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, FIBRE);
link_settings->port = PORT_FIBRE;
break;
case MAG_CMD_WIRE_TYPE_COPPER:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_FIBRE);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_FIBRE);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, FIBRE);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, FIBRE);
link_settings->port = PORT_DA;
break;
case MAG_CMD_WIRE_TYPE_BACKPLANE:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_Backplane);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Backplane);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Backplane);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Backplane);
link_settings->port = PORT_NONE;
break;
@@ -1000,19 +1048,58 @@ static int get_link_pause_settings(struct hinic3_nic_dev *nic_dev,
return err;
}
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_Pause);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Pause);
if (nic_pause.rx_pause && nic_pause.tx_pause) {
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Pause);
} else if (nic_pause.tx_pause) {
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Asym_Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Asym_Pause);
} else if (nic_pause.rx_pause) {
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Pause);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Asym_Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Asym_Pause);
}
return 0;
}
+static bool is_bit_offset_defined(u8 bit_offset)
+{
+ if (bit_offset < __ETHTOOL_LINK_MODE_MASK_NBITS)
+ return true;
+ return false;
+}
+
+static void ethtool_add_supported_advertised_fec(
+ struct cmd_link_settings *link_settings, u32 fec, u8 cmd)
+{
+ u8 i;
+
+ for (i = 0; i < HINIC_ETHTOOL_FEC_INFO_LEN; i++) {
+ if ((fec & BIT(hinic3_ethtool_fec_info[i].hinic_fec_offset)) == 0)
+ continue;
+ if ((is_bit_offset_defined(
+ hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true) &&
+ (cmd == HINIC_ADVERTISED_FEC_CMD)) {
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset,
+ link_settings->advertising);
+ return; /* There can be only one advertised fec mode. */
+ }
+ if ((is_bit_offset_defined(
+ hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true) &&
+ (cmd == HINIC_SUPPORTED_FEC_CMD))
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset,
+ link_settings->supported);
+ }
+}
+
+static void hinic3_link_fec_type(struct cmd_link_settings *link_settings,
+ u32 fec, u32 supported_fec)
+{
+ ethtool_add_supported_advertised_fec(link_settings, supported_fec,
+ HINIC_SUPPORTED_FEC_CMD);
+ ethtool_add_supported_advertised_fec(link_settings, fec,
+ HINIC_ADVERTISED_FEC_CMD);
+}
+
static int get_link_settings(struct net_device *netdev,
struct cmd_link_settings *link_settings)
{
@@ -1033,13 +1120,19 @@ static int get_link_settings(struct net_device *netdev,
hinic3_link_port_type(link_settings, port_info.port_type);
+ /* port_info.fec is bit offset, value is BIT(port_info.fec);
+ * but port_info.supported_fec_mode is bit value
+ */
+ hinic3_link_fec_type(link_settings, BIT(port_info.fec),
+ port_info.supported_fec_mode);
+
link_settings->autoneg = port_info.autoneg_state == PORT_CFG_AN_ON ?
AUTONEG_ENABLE :
AUTONEG_DISABLE;
if (port_info.autoneg_cap)
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_Autoneg);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Autoneg);
if (port_info.autoneg_state == PORT_CFG_AN_ON)
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Autoneg);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Autoneg);
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
err = get_link_pause_settings(nic_dev, link_settings);
@@ -1163,23 +1256,19 @@ static int hinic3_set_settings_to_hw(struct hinic3_nic_dev *nic_dev,
struct net_device *netdev = nic_dev->netdev;
struct hinic3_link_ksettings settings = { 0 };
int speed_level = 0;
- char set_link_str[128] = { 0 };
+ char set_link_str[HINIC_SET_LINK_STR_LEN] = {0};
+ char link_info[HINIC_SET_LINK_STR_LEN] = {0};
int err = 0;
- err = snprintf(set_link_str, sizeof(set_link_str) - 1, "%s",
+ snprintf(link_info, sizeof(link_info), "%s",
(bool)(set_settings & HILINK_LINK_SET_AUTONEG) ?
((bool)autoneg ? "autong enable " :
- "autong disable ") :
- "");
- if (err < 0)
- return -EINVAL;
+ "autong disable ") : "");
if (set_settings & HILINK_LINK_SET_SPEED) {
speed_level = hinic3_ethtool_to_hw_speed_level(speed);
- err = snprintf(set_link_str, sizeof(set_link_str) - 1,
- "%sspeed %u ", set_link_str, speed);
- if (err < 0)
- return -EINVAL;
+ snprintf(set_link_str, sizeof(set_link_str),
+ "%sspeed %u ", link_info, speed);
}
settings.valid_bitmap = set_settings;
@@ -1218,7 +1307,8 @@ static int set_link_settings(struct net_device *netdev, u8 autoneg, u32 speed)
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
int hinic3_set_link_ksettings(struct net_device *netdev,
- const struct ethtool_link_ksettings *link_settings)
+ const
+ struct ethtool_link_ksettings *link_settings)
{
/* Only support to set autoneg and speed */
return set_link_settings(netdev, link_settings->base.autoneg,
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
index 70346d6..2daa7f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
@@ -82,7 +82,7 @@ static struct hinic3_mac_filter *hinic3_add_filter(struct hinic3_nic_dev *nic_de
struct list_head *mac_filter_list,
u8 *addr)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
@@ -117,7 +117,7 @@ static void hinic3_del_filter(struct hinic3_nic_dev *nic_dev,
static struct hinic3_mac_filter *hinic3_mac_filter_entry_clone(const struct hinic3_mac_filter *src)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
index ef8c62b..a3136ce 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
@@ -40,6 +40,7 @@ enum hinic3_channel_id {
HINIC3_CHANNEL_DSW,
HINIC3_CHANNEL_MIG,
HINIC3_CHANNEL_CRYPT,
+ HINIC3_CHANNEL_VROCE,
HINIC3_CHANNEL_MAX = 32,
};
@@ -397,6 +398,16 @@ void hinic3_free_cmd_buf(void *hwdev, struct hinic3_cmd_buf *cmd_buf);
**/
int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read clear
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+
/**
* @brief hinic3_sm_ctr_rd32 - small single 32 counter read
* @param hwdev: device pointer to hwdev
@@ -810,6 +821,13 @@ int hinic3_dbg_lt_wr_16byte_mask(void *hwdev, u8 dest, u8 instance,
*/
void hinic3_link_event_stats(void *dev, u8 link);
+/**
+ * @brief hinic3_get_link_event_stats - link event stats
+ * @param hwdev: device pointer to hwdev
+ * @param link: link status
+ */
+int hinic3_get_link_event_stats(void *dev, int *link_state);
+
/**
* @brief hinic3_get_hw_pf_infos - get pf infos
* @param hwdev: device pointer to hwdev
@@ -856,4 +874,5 @@ void hinic3_set_api_stop(void *hwdev);
int hinic3_activate_firmware(void *hwdev, u8 cfg_index);
int hinic3_switch_config(void *hwdev, u8 cfg_index);
+bool hinic3_is_optical_module_mode(void *hwdev);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
index 7e59c81..6525b76 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
@@ -47,12 +47,16 @@ static void qp_add_napi(struct hinic3_irq *irq_cfg)
netif_napi_add_weight(nic_dev->netdev, &irq_cfg->napi,
hinic3_poll, nic_dev->poll_weight);
napi_enable(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_IS_REGIN;
}
-static void qp_del_napi(struct hinic3_irq *irq_cfg)
+void qp_del_napi(struct hinic3_irq *irq_cfg)
{
- napi_disable(&irq_cfg->napi);
- netif_napi_del(&irq_cfg->napi);
+ if (irq_cfg->napi_reign == NAPI_IS_REGIN) {
+ napi_disable(&irq_cfg->napi);
+ netif_napi_del(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_NOT_REGIN;
+ }
}
static irqreturn_t qp_irq(int irq, void *data)
@@ -60,7 +64,8 @@ static irqreturn_t qp_irq(int irq, void *data)
struct hinic3_irq *irq_cfg = (struct hinic3_irq *)data;
struct hinic3_nic_dev *nic_dev = netdev_priv(irq_cfg->netdev);
- hinic3_misx_intr_clear_resend_bit(nic_dev->hwdev, irq_cfg->msix_entry_idx, 1);
+ hinic3_misx_intr_clear_resend_bit(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx, 1);
napi_schedule(&irq_cfg->napi);
@@ -95,7 +100,8 @@ static int hinic3_request_irq(struct hinic3_irq *irq_cfg, u16 q_id)
return err;
}
- err = request_irq(irq_cfg->irq_id, &qp_irq, 0, irq_cfg->irq_name, irq_cfg);
+ err = request_irq(irq_cfg->irq_id, &qp_irq, 0,
+ irq_cfg->irq_name, irq_cfg);
if (err) {
nicif_err(nic_dev, drv, irq_cfg->netdev, "Failed to request Rx irq\n");
qp_del_napi(irq_cfg);
@@ -138,12 +144,8 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev)
local_cpu = cpumask_local_spread(q_id, dev_to_node(&pdev->dev));
cpumask_set_cpu(local_cpu, &irq_cfg->affinity_mask);
- err = snprintf(irq_cfg->irq_name, sizeof(irq_cfg->irq_name),
- "%s_qp%u", nic_dev->netdev->name, q_id);
- if (err < 0) {
- err = -EINVAL;
- goto req_tx_irq_err;
- }
+ snprintf(irq_cfg->irq_name, sizeof(irq_cfg->irq_name),
+ "%s_qp%u", nic_dev->netdev->name, q_id);
err = hinic3_request_irq(irq_cfg, q_id);
if (err) {
@@ -151,20 +153,25 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev)
goto req_tx_irq_err;
}
- hinic3_set_msix_auto_mask_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ hinic3_set_msix_auto_mask_state(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx,
HINIC3_SET_MSIX_AUTO_MASK);
- hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx, HINIC3_MSIX_ENABLE);
+ hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ HINIC3_MSIX_ENABLE);
}
- INIT_DELAYED_WORK(&nic_dev->moderation_task, hinic3_auto_moderation_work);
+ INIT_DELAYED_WORK(&nic_dev->moderation_task,
+ hinic3_auto_moderation_work);
return 0;
req_tx_irq_err:
for (i = 0; i < q_id; i++) {
irq_cfg = &nic_dev->q_params.irq_cfg[i];
- hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx, HINIC3_MSIX_DISABLE);
- hinic3_set_msix_auto_mask_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ HINIC3_MSIX_DISABLE);
+ hinic3_set_msix_auto_mask_state(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx,
HINIC3_CLR_MSIX_AUTO_MASK);
hinic3_release_irq(irq_cfg);
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
deleted file mode 100644
index 2482c5f..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_LLD_H
-#define HINIC3_LLD_H
-
-#include "hinic3_crm.h"
-
-struct hinic3_lld_dev {
- struct pci_dev *pdev;
- void *hwdev;
-};
-
-struct hinic3_uld_info {
- /* When the function does not need to initialize the corresponding uld,
- * @probe needs to return 0 and uld_dev is set to NULL;
- * if uld_dev is NULL, @remove will not be called when uninstalling
- */
- int (*probe)(struct hinic3_lld_dev *lld_dev, void **uld_dev, char *uld_dev_name);
- void (*remove)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- int (*suspend)(struct hinic3_lld_dev *lld_dev, void *uld_dev, pm_message_t state);
- int (*resume)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- void (*event)(struct hinic3_lld_dev *lld_dev, void *uld_dev,
- struct hinic3_event_info *event);
- int (*ioctl)(void *uld_dev, u32 cmd, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size);
-};
-
-/* hinic3_register_uld - register an upper-layer driver
- * @type: uld service type
- * @uld_info: uld callback
- *
- * Registers an upper-layer driver.
- * Traverse existing devices and call @probe to initialize the uld device.
- */
-int hinic3_register_uld(enum hinic3_service_type type, struct hinic3_uld_info *uld_info);
-
-/**
- * hinic3_unregister_uld - unregister an upper-layer driver
- * @type: uld service type
- *
- * Traverse existing devices and call @remove to uninstall the uld device.
- * Unregisters an existing upper-layer driver.
- */
-void hinic3_unregister_uld(enum hinic3_service_type type);
-
-void lld_hold(void);
-void lld_put(void);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_name - get lld device by chip name
- * @param chip_name: chip name
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_name(const char *chip_name);
-
-/**
- * @brief lld_dev_hold - get reference to lld_dev
- * @param dev: lld device
- *
- * Hold reference to device to keep it from being freed
- **/
-void lld_dev_hold(struct hinic3_lld_dev *dev);
-
-/**
- * @brief lld_dev_put - release reference to lld_dev
- * @param dev: lld device
- *
- * Release reference to device to allow it to be freed
- **/
-void lld_dev_put(struct hinic3_lld_dev *dev);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name_unsafe - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * hinic3_get_lld_dev_by_dev_name_unsafe() is completely analogous to
- * hinic3_get_lld_dev_by_dev_name(), The only difference is that the reference
- * of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that lld_dev will not be freed during the remove process
- * when using lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name_unsafe(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_and_port - get lld device by chip name and port id
- * @param chip_name: chip name
- * @param port_id: port id
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name, u8 port_id);
-
-/**
- * @brief hinic3_get_ppf_lld_dev - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief hinic3_get_ppf_lld_dev_unsafe - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * hinic3_get_ppf_lld_dev_unsafe() is completely analogous to hinic3_get_ppf_lld_dev(),
- * The only difference is that the reference of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that ppf's lld_dev will not be freed during the remove process
- * when using ppf lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev_unsafe(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief uld_dev_hold - get reference to uld_dev
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * Hold reference to uld device to keep it from being freed
- **/
-void uld_dev_hold(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief uld_dev_put - release reference to lld_dev
- * @param dev: lld device
- * @param type: uld service type
- *
- * Release reference to uld device to allow it to be freed
- **/
-void uld_dev_put(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * The value of uld_dev reference increases when uld_dev is obtained. The caller needs
- * to release the reference by calling uld_dev_put.
- **/
-void *hinic3_get_uld_dev(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev_unsafe - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * hinic3_get_uld_dev_unsafe() is completely analogous to hinic3_get_uld_dev(),
- * The only difference is that the reference of uld_dev is not increased when uld_dev is obtained.
- *
- * The caller must ensure that uld_dev will not be freed during the remove process
- * when using uld_dev.
- **/
-void *hinic3_get_uld_dev_unsafe(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_chip_name - get chip name by lld device
- * @param lld_dev: lld device
- * @param chip_name: String for storing the chip name
- * @param max_len: Maximum number of characters to be copied for chip_name
- **/
-int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len);
-
-struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev);
-
-struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev);
-
-bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service);
-
-int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
- bool vf_srv_load);
-
-int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id,
- u16 service, bool en);
-
-bool hinic3_get_vf_load_state(struct pci_dev *pdev);
-
-int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state);
-
-int hinic3_attach_nic(struct hinic3_lld_dev *lld_dev);
-
-void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
-
-int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-const char **hinic3_get_uld_names(void);
-int hinic3_lld_init(void);
-void hinic3_lld_exit(void);
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
index 2fe808b..5e4e184 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
@@ -17,11 +17,22 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_hw.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_common.h"
+#include "mag_mpu_cmd_defs.h"
+
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
+#define CAP_INFO_MAX_LEN 512
+#define DEVICE_VENDOR_MAX_LEN 17
+#define READ_RSFEC_REGISTER_DELAY_TIME_MS 500
+
+struct parse_tlv_info g_page_info = {0};
+struct drv_tag_mag_cmd_get_xsfp_tlv_rsp g_xsfp_tlv_info = {0};
static int mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
@@ -78,8 +89,10 @@ int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats)
return -ENOMEM;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
memset(&stats_info, 0, sizeof(stats_info));
stats_info.port_id = hinic3_physical_port_id(hwdev);
@@ -104,6 +117,64 @@ out:
}
EXPORT_SYMBOL(hinic3_get_phy_port_stats);
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats)
+{
+ struct mag_cmd_get_mag_cnt *port_stats = NULL;
+ struct mag_cmd_get_mag_cnt stats_info;
+ u16 out_size = sizeof(*port_stats);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !stats)
+ return -EINVAL;
+
+ port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
+ if (!port_stats)
+ return -ENOMEM;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ memset(&stats_info, 0, sizeof(stats_info));
+ stats_info.port_id = hinic3_physical_port_id(hwdev);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT,
+ &stats_info, sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+ /* 读2遍, 清除误码残留 */
+ msleep(READ_RSFEC_REGISTER_DELAY_TIME_MS);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT, &stats_info,
+ sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+
+ memcpy(stats, &port_stats->mag_csr[MAG_RX_RSFEC_ERR_CW_CNT],
+ sizeof(u32));
+
+out:
+ kfree(port_stats);
+
+ return err;
+}
+EXPORT_SYMBOL(hinic3_get_phy_rsfec_stats);
+
int hinic3_set_port_funcs_state(void *hwdev, bool enable)
{
return 0;
@@ -180,6 +251,8 @@ int hinic3_get_loopback_mode(void *hwdev, u8 *mode, u8 *enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_cfg_loopback_mode(nic_io, MGMT_MSG_CMD_OP_GET, mode,
enable);
@@ -195,6 +268,8 @@ int hinic3_set_loopback_mode(void *hwdev, u8 mode, u8 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) {
nic_err(nic_io->dev_hdl, "Invalid loopback mode %u to set\n",
@@ -218,6 +293,9 @@ int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&led_info, 0, sizeof(led_info));
led_info.function_id = hinic3_global_func_id(hwdev);
@@ -249,6 +327,8 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
memset(&port_msg, 0, sizeof(port_msg));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
port_msg.port_id = hinic3_physical_port_id(hwdev);
@@ -268,9 +348,12 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
port_info->port_type = port_msg.wire_type;
port_info->speed = port_msg.speed;
port_info->fec = port_msg.fec;
+ port_info->lanes = port_msg.lanes;
port_info->supported_mode = port_msg.supported_mode;
port_info->advertised_mode = port_msg.advertised_mode;
-
+ port_info->supported_fec_mode = port_msg.supported_fec_mode;
+ /* switch Gbps to Mbps */
+ port_info->bond_speed = (u32)port_msg.bond_speed * RATE_MBPS_TO_GBPS;
return 0;
}
@@ -306,6 +389,8 @@ int hinic3_set_link_settings(void *hwdev,
memset(&info, 0, sizeof(info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
info.port_id = hinic3_physical_port_id(hwdev);
info.config_bitmap = settings->valid_bitmap;
@@ -335,6 +420,8 @@ int hinic3_get_link_state(void *hwdev, u8 *link_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&get_link, 0, sizeof(get_link));
get_link.port_id = hinic3_physical_port_id(hwdev);
@@ -364,9 +451,10 @@ void hinic3_notify_vf_link_status(struct hinic3_nic_io *nic_io,
if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
link.status = link_status;
link.port_id = hinic3_physical_port_id(nic_io->hwdev);
- err = hinic3_mbox_to_vf(nic_io->hwdev, vf_id, HINIC3_MOD_HILINK,
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
MAG_CMD_GET_LINK_STATUS, &link,
- sizeof(link), &link, &out_size, 0,
+ sizeof(link), &link, &out_size,
HINIC3_CHANNEL_NIC);
if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
@@ -387,6 +475,8 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
u16 i;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
nic_io->link_status = link_status;
for (i = 1; i <= nic_io->max_vfs; i++) {
if (!nic_io->vf_infos[HW_VF_ID_TO_OS(i)].link_forced)
@@ -394,6 +484,165 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
}
}
+static char *g_hw_to_char_fec[HILINK_FEC_MAX_TYPE] = {
+ "not set", "rsfec", "basefec",
+ "nofec", "llrsfec"};
+static char *g_hw_to_speed_info[PORT_SPEED_UNKNOWN] = {
+ "not set", "10MB", "100MB", "1GB", "10GB",
+ "25GB", "40GB", "50GB", "100GB", "200GB"};
+static char *g_hw_to_an_state_info[PORT_CFG_AN_OFF + 1] = {
+ "not set", "on", "off"};
+
+struct port_type_table {
+ u32 port_type;
+ char *port_type_name;
+};
+
+static const struct port_type_table port_optical_type_table_s[] = {
+ {LINK_PORT_UNKNOWN, "UNKNOWN"},
+ {LINK_PORT_OPTICAL_MM, "optical_sr"},
+ {LINK_PORT_OPTICAL_SM, "optical_lr"},
+ {LINK_PORT_PAS_COPPER, "copper"},
+ {LINK_PORT_ACC, "ACC"},
+ {LINK_PORT_BASET, "baset"},
+ {LINK_PORT_AOC, "AOC"},
+ {LINK_PORT_ELECTRIC, "electric"},
+ {LINK_PORT_BACKBOARD_INTERFACE, "interface"},
+};
+
+static char *get_port_type_name(u32 type)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(port_optical_type_table_s); i++) {
+ if (type == port_optical_type_table_s[i].port_type)
+ return port_optical_type_table_s[i].port_type_name;
+ }
+ return "UNKNOWN TYPE";
+}
+
+static void get_port_type(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ char **port_type)
+{
+ if (info->port_type <= LINK_PORT_BACKBOARD_INTERFACE)
+ *port_type = get_port_type_name(info->port_type);
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown port type: %u\n", info->port_type);
+}
+
+static int get_port_temperature_power(struct mag_cmd_event_port_info *info,
+ char *str)
+{
+ char cap_info[CAP_INFO_MAX_LEN];
+
+ memset(cap_info, 0, sizeof(cap_info));
+ snprintf(cap_info, CAP_INFO_MAX_LEN, "%s, %s, Temperature: %u", str,
+ info->sfp_type ? "QSFP" : "SFP", info->cable_temp);
+
+ if (info->sfp_type)
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuw %uuW %uuW %uuW",
+ cap_info, info->power[0x0], info->power[0x1],
+ info->power[0x2], info->power[0x3]);
+ else
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuW, tx power: %uuW",
+ cap_info, info->power[0x0], info->power[0x1]);
+
+ return 0;
+}
+
+static void print_cable_info(struct hinic3_nic_io *nic_io, struct mag_cmd_event_port_info *info)
+{
+ char tmp_str[CAP_INFO_MAX_LEN] = {0};
+ char tmp_vendor[DEVICE_VENDOR_MAX_LEN] = {0};
+ char *port_type = "Unknown port type";
+ int i;
+ int err = 0;
+
+ if (info->gpio_insert) {
+ sdk_info(nic_io->dev_hdl, "Cable unpresent\n");
+ return;
+ }
+
+ get_port_type(nic_io, info, &port_type);
+
+ for (i = sizeof(info->vendor_name) - 1; i >= 0; i--) {
+ if (info->vendor_name[i] == ' ')
+ info->vendor_name[i] = '\0';
+ else
+ break;
+ }
+
+ memcpy(tmp_vendor, info->vendor_name, sizeof(info->vendor_name));
+ snprintf(tmp_str, CAP_INFO_MAX_LEN, "Vendor: %s, %s, length: %um, max_speed: %uGbps",
+ tmp_vendor, port_type, info->cable_length, info->max_speed);
+
+ if (info->port_type == LINK_PORT_OPTICAL_MM ||
+ info->port_type == LINK_PORT_AOC) {
+ err = get_port_temperature_power(info, tmp_str);
+ if (err)
+ return;
+ }
+
+ sdk_info(nic_io->dev_hdl, "Cable information: %s\n", tmp_str);
+}
+
+static void print_link_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ enum hinic3_nic_event_type type)
+{
+ char *fec = "None";
+ char *speed = "None";
+ char *an_state = "None";
+
+ if (info->fec < HILINK_FEC_MAX_TYPE)
+ fec = g_hw_to_char_fec[info->fec];
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown fec type: %u\n", info->fec);
+
+ if (info->an_state > PORT_CFG_AN_OFF) {
+ sdk_info(nic_io->dev_hdl, "an_state %d is invalid",
+ info->an_state);
+ return;
+ }
+
+ an_state = g_hw_to_an_state_info[info->an_state];
+
+ if (info->speed >= PORT_SPEED_UNKNOWN) {
+ sdk_info(nic_io->dev_hdl, "speed %u is invalid", info->speed);
+ return;
+ }
+
+ speed = g_hw_to_speed_info[info->speed];
+ sdk_info(nic_io->dev_hdl, "Link information: speed %s, %s, autoneg %s",
+ speed, fec, an_state);
+}
+
+void print_port_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *port_info,
+ enum hinic3_nic_event_type type)
+{
+ print_cable_info(nic_io, port_info);
+
+ print_link_info(nic_io, port_info, type);
+
+ if (type == EVENT_NIC_LINK_UP)
+ return;
+
+ sdk_info(nic_io->dev_hdl, "PMA ctrl: %s, tx %s, rx %s, PMA fifo reg: 0x%x, PMA signal ok reg: 0x%x, RF/LF status reg: 0x%x\n",
+ port_info->pma_ctrl == 1 ? "off" : "on",
+ port_info->tx_enable ? "enable" : "disable",
+ port_info->rx_enable ? "enable" : "disable", port_info->pma_fifo_reg,
+ port_info->pma_signal_ok_reg, port_info->rf_lf);
+ sdk_info(nic_io->dev_hdl, "alos: %u, rx_los: %u, PCS 64 66b reg: 0x%x, PCS link: 0x%x, MAC link: 0x%x PCS_err_cnt: 0x%x\n",
+ port_info->alos, port_info->rx_los, port_info->pcs_64_66b_reg,
+ port_info->pcs_link, port_info->pcs_mac_link,
+ port_info->pcs_err_cnt);
+ sdk_info(nic_io->dev_hdl, "his_link_machine_state = 0x%08x, cur_link_machine_state = 0x%08x\n",
+ port_info->his_link_machine_state,
+ port_info->cur_link_machine_state);
+}
+
static int hinic3_get_vf_link_status_msg_handler(struct hinic3_nic_io *nic_io,
u16 vf_id, void *buf_in,
u16 in_size, void *buf_out,
@@ -433,6 +682,10 @@ static void get_port_info(void *hwdev,
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (hinic3_func_type(hwdev) != TYPE_VF && link_status->status) {
err = hinic3_get_port_info(hwdev, &port_info, HINIC3_CHANNEL_NIC);
if (err) {
@@ -457,8 +710,18 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
struct hinic3_event_info event_info = {0};
struct hinic3_event_link_info *link_info = (void *)event_info.event_data;
struct hinic3_nic_io *nic_io = NULL;
+#ifndef __UEFI__
+ struct pci_dev *pdev = NULL;
+#endif
+ /* Ignore link change event */
+ if (hinic3_is_bm_slave_host(hwdev))
+ return;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
link_status = buf_in;
sdk_info(nic_io->dev_hdl, "Link status report received, func_id: %u, status: %u\n",
@@ -475,6 +738,15 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
hinic3_event_callback(hwdev, &event_info);
+#ifndef __UEFI__
+ if (nic_io->pcidev_hdl != NULL) {
+ pdev = nic_io->pcidev_hdl;
+ if (pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID) {
+ return;
+ }
+ }
+#endif
+
if (hinic3_func_type(hwdev) != TYPE_VF) {
hinic3_notify_all_vfs_link_changed(hwdev, link_status->status);
ret_link_status = buf_out;
@@ -483,20 +755,142 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
}
}
+static void port_info_event_printf(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_event_port_info *port_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info;
+ enum hinic3_nic_event_type type;
+
+ if (!hwdev) {
+ pr_err("hwdev is NULL\n");
+ return;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ if (in_size != sizeof(*port_info)) {
+ sdk_info(nic_io->dev_hdl, "Invalid port info message size %d, should be %ld\n",
+ in_size, sizeof(*port_info));
+ return;
+ }
+
+ ((struct mag_cmd_event_port_info *)buf_out)->head.status = 0;
+
+ type = port_info->event_type;
+ if (type < EVENT_NIC_LINK_DOWN || type > EVENT_NIC_LINK_UP) {
+ sdk_info(nic_io->dev_hdl, "Invalid hilink info report, type: %d\n",
+ type);
+ return;
+ }
+
+ print_port_info(nic_io, port_info, type);
+
+ memset(&event_info, 0, sizeof(event_info));
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = type;
+
+ *out_size = sizeof(*port_info);
+
+ hinic3_event_callback(hwdev, &event_info);
+}
+
+void hinic3_notify_vf_bond_status(struct hinic3_nic_io *nic_io,
+ u16 vf_id, u8 bond_status)
+{
+ struct mag_cmd_get_bond_status bond;
+ struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ u16 out_size = sizeof(bond);
+ int err;
+
+ memset(&bond, 0, sizeof(bond));
+ if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
+ bond.status = bond_status;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
+ MAG_CMD_GET_BOND_STATUS, &bond,
+ sizeof(bond), &bond, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF %u not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return;
+ }
+ if (err || !out_size || bond.head.status)
+ nic_err(nic_io->dev_hdl,
+ "Send bond change event to VF %hu failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err, bond.head.status,
+ out_size);
+ }
+}
+
+void hinic3_notify_all_vfs_bond_changed(void *hwdev, u8 bond_status)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 i;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ nic_io->link_status = bond_status;
+ for (i = 1; i <= nic_io->max_vfs; i++)
+ hinic3_notify_vf_bond_status(nic_io, i, bond_status);
+}
+
+static void bond_status_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_get_bond_status *bond_status = NULL;
+ struct hinic3_event_info event_info = {};
+ struct hinic3_nic_io *nic_io = NULL;
+ struct mag_cmd_get_bond_status *ret_bond_status = NULL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+
+ bond_status = (struct mag_cmd_get_bond_status *)buf_in;
+ sdk_info(nic_io->dev_hdl, "bond status report received, func_id: %u, status: %u\n",
+ hinic3_global_func_id(hwdev), bond_status->status);
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = bond_status->status ?
+ EVENT_NIC_BOND_UP : EVENT_NIC_BOND_DOWN;
+
+ hinic3_event_callback(hwdev, &event_info);
+
+ if (hinic3_func_type(hwdev) != TYPE_VF) {
+ hinic3_notify_all_vfs_bond_changed(hwdev, bond_status->status);
+ ret_bond_status = buf_out;
+ ret_bond_status->head.status = 0;
+ *out_size = sizeof(*ret_bond_status);
+ }
+}
+
static void cable_plug_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct mag_cmd_wire_event *plug_event = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_event_info event_info;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
rt_cmd->mpu_send_sfp_abs = false;
rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
memset(&event_info, 0, sizeof(event_info));
@@ -518,9 +912,12 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
{
struct mag_cmd_get_xsfp_info *sfp_info = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_info)) {
sdk_err(nic_io->dev_hdl, "Invalid sfp info cmd, length: %u, should be %ld\n",
in_size, sizeof(*sfp_info));
@@ -528,10 +925,41 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
}
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
memcpy(&rt_cmd->std_sfp_info, sfp_info,
sizeof(struct mag_cmd_get_xsfp_info));
rt_cmd->mpu_send_sfp_info = true;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+}
+
+static void port_xsfp_tlv_info_event(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *xsfp_tlv_info = buf_in;
+ struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
+ size_t cpy_len = in_size - sizeof(struct mgmt_msg_head) -
+ XSFP_TLV_PRE_INFO_LEN;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL)
+ return;
+
+ if (cpy_len > XSFP_CMIS_INFO_MAX_SIZE) {
+ sdk_err(nic_io->dev_hdl, "invalid cpy_len(%lu)\n", cpy_len);
+ return;
+ }
+ rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ rt_cmd_ext->std_xsfp_tlv_info.port_id = xsfp_tlv_info->port_id;
+ memcpy(&(rt_cmd_ext->std_xsfp_tlv_info.tlv_buf[0]),
+ &(xsfp_tlv_info->tlv_buf[0]), cpy_len);
+ rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = true;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
}
@@ -543,6 +971,8 @@ static void port_sfp_abs_event(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_abs)) {
sdk_err(nic_io->dev_hdl, "Invalid sfp absent cmd, length: %u, should be %ld\n",
in_size, sizeof(*sfp_abs));
@@ -564,9 +994,11 @@ bool hinic3_if_sfp_absent(void *hwdev)
u8 port_id = hinic3_physical_port_id(hwdev);
u16 out_size = sizeof(sfp_abs);
int err;
- bool sfp_abs_status;
+ bool sfp_abs_status = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return true;
memset(&sfp_abs, 0, sizeof(sfp_abs));
rt_cmd = &nic_io->nic_cfg.rt_cmd;
@@ -597,10 +1029,185 @@ bool hinic3_if_sfp_absent(void *hwdev)
return (sfp_abs.abs_status == 0 ? false : true);
}
+int hinic3_get_sfp_tlv_info(void *hwdev, struct drv_tag_mag_cmd_get_xsfp_tlv_rsp
+ *sfp_tlv_info,
+ const struct tag_mag_cmd_get_xsfp_tlv_req
+ *sfp_tlv_info_req)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ u16 out_size = sizeof(*sfp_tlv_info);
+ int err;
+
+ if ((hwdev == NULL) || (sfp_tlv_info == NULL))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL)
+ return -EINVAL;
+
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ if (rt_cmd_ext->mpu_send_xsfp_tlv_info == true) {
+ if (rt_cmd_ext->std_xsfp_tlv_info.head.status != 0) {
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return -EIO;
+ }
+
+ memcpy(sfp_tlv_info, &rt_cmd_ext->std_xsfp_tlv_info,
+ sizeof(*sfp_tlv_info));
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_TLV_INFO,
+ (void *)sfp_tlv_info_req,
+ sizeof(*sfp_tlv_info_req),
+ sfp_tlv_info, &out_size);
+ if ((sfp_tlv_info->head.status != 0) || (err != 0) || (out_size == 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get port%u tlv sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
+ hinic3_physical_port_id(hwdev), err,
+ sfp_tlv_info->head.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_get_page_pos(u32 page_id, u32 content_len, u32 *pos)
+{
+ if (page_id <= QSFP_CMIS_PAGE_03H) {
+ *pos = (page_id * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_11H) {
+ *pos = (QSFP_CMIS_PAGE_04H * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_12H) {
+ *pos = (QSFP_CMIS_PAGE_05H * content_len);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int hinic3_get_page_key_info(struct mgmt_tlv_info *tlv_info,
+ struct parse_tlv_info *page_info, u8 idx,
+ u32 *total_len)
+{
+ u8 *src_addr = NULL;
+ u8 *dst_addr = NULL;
+ u8 *tmp_addr = NULL;
+ u32 page_id = 0;
+ u32 content_len = 0;
+ u32 src_pos = 0;
+ int ret;
+
+ page_id = MGMT_TLV_GET_U32(tlv_info->value);
+ content_len = tlv_info->length - MGMT_TLV_U32_SIZE;
+ if (page_id == QSFP_CMIS_PAGE_00H) {
+ tmp_addr = (u8 *)(tlv_info + 1);
+ page_info->id = *(tmp_addr + MGMT_TLV_U32_SIZE);
+ }
+
+ ret = hinic3_trans_cmis_get_page_pos(page_id, content_len, &src_pos);
+ if (ret != 0)
+ return ret;
+
+ src_addr = page_info->tlv_page_info + src_pos;
+ tmp_addr = (u8 *)(tlv_info + 1);
+ dst_addr = tmp_addr + MGMT_TLV_U32_SIZE;
+ memcpy(src_addr, dst_addr, content_len);
+
+ if (idx < XSFP_CMIS_PARSE_PAGE_NUM)
+ page_info->tlv_page_num[idx] = page_id;
+
+ *total_len += content_len;
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_tlv_info_to_buf(u8 *sfp_tlv_info,
+ struct parse_tlv_info *page_info)
+{
+ struct mgmt_tlv_info *tlv_info = NULL;
+ u8 *tlv_buf = sfp_tlv_info;
+ u8 idx = 0;
+ u32 total_len = 0;
+ int ret = 0;
+ bool need_continue = true;
+
+ if ((sfp_tlv_info == NULL) || (page_info == NULL))
+ return -EIO;
+
+ while (need_continue) {
+ tlv_info = (struct mgmt_tlv_info *)tlv_buf;
+ switch (tlv_info->type) {
+ case MAG_XSFP_TYPE_PAGE:
+ ret = hinic3_get_page_key_info(
+ tlv_info, page_info, idx, &total_len);
+ if (ret != 0) {
+ pr_err("lib_get_page_key_info fail,ret:0x%x.\n",
+ ret);
+ break;
+ }
+ idx++;
+ break;
+
+ case MAG_XSFP_TYPE_WIRE_TYPE:
+ page_info->wire_type =
+ MGMT_TLV_GET_U32(&(tlv_info->value));
+ break;
+
+ case MAG_XSFP_TYPE_END:
+ need_continue = false;
+ break;
+
+ default:
+ break;
+ }
+
+ tlv_buf += (sizeof(struct mgmt_tlv_info) + tlv_info->length);
+ }
+
+ page_info->tlv_page_info_len = total_len;
+
+ return 0;
+}
+
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len)
+{
+ int err = 0;
+ struct tag_mag_cmd_get_xsfp_tlv_req xsfp_tlv_info_req = {0};
+
+ xsfp_tlv_info_req.rsp_buf_len = XSFP_CMIS_INFO_MAX_SIZE;
+ xsfp_tlv_info_req.port_id = hinic3_physical_port_id(hwdev);
+ err = hinic3_get_sfp_tlv_info(hwdev, &g_xsfp_tlv_info,
+ &xsfp_tlv_info_req);
+ if (err != 0)
+ return err;
+
+ err = hinic3_trans_cmis_tlv_info_to_buf(g_xsfp_tlv_info.tlv_buf,
+ &g_page_info);
+ if (err)
+ return -ENOMEM;
+
+ memcpy(data, g_page_info.tlv_page_info, len);
+
+ return (err == 0) ? 0 : -ENOMEM;
+}
+
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
{
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ u8 sfp_info_status = 0;
u16 out_size = sizeof(*sfp_info);
int err;
@@ -608,13 +1215,17 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ sfp_info_status = rt_cmd->std_sfp_info.head.status;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (sfp_info_status != 0) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return -EIO;
+ return (sfp_info_status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ ? HINIC3_MGMT_CMD_UNSUPPORTED : -EIO;
}
memcpy(sfp_info, &rt_cmd->std_sfp_info, sizeof(*sfp_info));
@@ -626,7 +1237,12 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
sfp_info->port_id = hinic3_physical_port_id(hwdev);
err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_INFO, sfp_info,
sizeof(*sfp_info), sfp_info, &out_size);
- if (sfp_info->head.status || err || !out_size) {
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ return HINIC3_MGMT_CMD_UNSUPPORTED;
+
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ return -EOPNOTSUPP;
+ if ((sfp_info->head.status != 0) || (err != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Failed to get port%u sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
hinic3_physical_port_id(hwdev), err,
@@ -642,7 +1258,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
struct mag_cmd_get_xsfp_info sfp_info;
int err;
- if (!hwdev || !data)
+ if (!hwdev || !data || len > PAGE_SIZE)
return -EINVAL;
if (hinic3_if_sfp_absent(hwdev))
@@ -654,7 +1270,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
if (err)
return err;
- memcpy(data, sfp_info.sfp_info, len);
+ memcpy(data, sfp_info.sfp_info, sizeof(sfp_info.sfp_info));
return 0;
}
@@ -664,7 +1280,7 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
- int err;
+ int err = 0;
if (!hwdev || !sfp_type || !sfp_type_ext)
return -EINVAL;
@@ -677,20 +1293,35 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (rt_cmd->std_sfp_info.head.status == 0) {
+ *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
+ *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ if (rt_cmd->std_sfp_info.head.status != HINIC3_MGMT_CMD_UNSUPPORTED) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
return -EIO;
}
- *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
- *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
- mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return 0;
+ err = HINIC3_MGMT_CMD_UNSUPPORTED; /* cmis */
}
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
- STD_SFP_INFO_MAX_SIZE);
+ if (err == 0) {
+ err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ } else {
+ /* mpu_send_sfp_info is false */
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ }
+
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+
if (err)
return err;
@@ -796,16 +1427,23 @@ int hinic3_set_pf_bw_limit(void *hwdev, u32 bw_limit)
return -EINVAL;
}
- old_bw_limit = nic_io->nic_cfg.pf_bw_limit;
- nic_io->nic_cfg.pf_bw_limit = bw_limit;
+ if (nic_io->direct == HINIC3_NIC_TX) {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_tx_limit;
+ nic_io->nic_cfg.pf_bw_tx_limit = bw_limit;
+ } else {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_rx_limit;
+ nic_io->nic_cfg.pf_bw_rx_limit = bw_limit;
+ }
err = hinic3_update_pf_bw(hwdev);
if (err) {
- nic_io->nic_cfg.pf_bw_limit = old_bw_limit;
- return err;
+ if (nic_io->direct == HINIC3_NIC_TX)
+ nic_io->nic_cfg.pf_bw_tx_limit = old_bw_limit;
+ else
+ nic_io->nic_cfg.pf_bw_rx_limit = old_bw_limit;
}
- return 0;
+ return err;
}
static const struct vf_msg_handler vf_mag_cmd_handler[] = {
@@ -828,6 +1466,9 @@ int hinic3_pf_mag_mbox_handler(void *hwdev, u16 vf_id,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
for (index = 0; index < cmd_size; index++) {
handler = &vf_mag_cmd_handler[index];
@@ -848,6 +1489,11 @@ static struct nic_event_handler mag_cmd_handler[] = {
.handler = link_status_event_handler,
},
+ {
+ .cmd = MAG_CMD_EVENT_PORT_INFO,
+ .handler = port_info_event_printf,
+ },
+
{
.cmd = MAG_CMD_WIRE_EVENT,
.handler = cable_plug_event,
@@ -862,6 +1508,16 @@ static struct nic_event_handler mag_cmd_handler[] = {
.cmd = MAG_CMD_GET_XSFP_PRESENT,
.handler = port_sfp_abs_event,
},
+
+ {
+ .cmd = MAG_CMD_GET_BOND_STATUS,
+ .handler = bond_status_event_handler,
+ },
+
+ {
+ .cmd = MAG_CMD_GET_XSFP_TLV_INFO,
+ .handler = port_xsfp_tlv_info_event,
+ },
};
static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
@@ -877,6 +1533,9 @@ static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
for (i = 0; i < size; i++) {
if (cmd == mag_cmd_handler[i].cmd) {
mag_cmd_handler[i].handler(hwdev, buf_in, in_size,
@@ -917,7 +1576,8 @@ static int _mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u32 i, cmd_cnt = ARRAY_LEN(vf_mag_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_mag_cmd_handler[i].cmd) {
cmd_to_pf = true;
@@ -949,3 +1609,124 @@ static int mag_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in,
return _mag_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out,
out_size, channel);
}
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+struct fecparam_value_map {
+ u8 hinic3_fec_offset;
+ u8 hinic3_fec_value;
+ u8 ethtool_fec_value;
+};
+
+static void fecparam_convert(u32 opcode, u8 in_fec_param, u8 *out_fec_param)
+{
+ u8 i;
+ u8 fec_value_table_lenth;
+ struct fecparam_value_map fec_value_table[] = {
+ {PORT_FEC_NOT_SET, BIT(PORT_FEC_NOT_SET), ETHTOOL_FEC_NONE},
+ {PORT_FEC_RSFEC, BIT(PORT_FEC_RSFEC), ETHTOOL_FEC_RS},
+ {PORT_FEC_BASEFEC, BIT(PORT_FEC_BASEFEC), ETHTOOL_FEC_BASER},
+ {PORT_FEC_NOFEC, BIT(PORT_FEC_NOFEC), ETHTOOL_FEC_OFF},
+#ifdef ETHTOOL_FEC_LLRS
+ {PORT_FEC_LLRSFEC, BIT(PORT_FEC_LLRSFEC), ETHTOOL_FEC_LLRS},
+#endif
+ {PORT_FEC_AUTO, BIT(PORT_FEC_AUTO), ETHTOOL_FEC_AUTO}
+ };
+
+ *out_fec_param = 0;
+ fec_value_table_lenth = (u8)(sizeof(fec_value_table) / sizeof(struct fecparam_value_map));
+
+ if (opcode == MAG_CMD_OPCODE_SET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].ethtool_fec_value) != 0)
+ /* The MPU uses the offset to determine the FEC mode. */
+ *out_fec_param =
+ fec_value_table[i].hinic3_fec_offset;
+ }
+ }
+
+ if (opcode == MAG_CMD_OPCODE_GET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].hinic3_fec_value) != 0)
+ *out_fec_param |=
+ fec_value_table[i].ethtool_fec_value;
+ }
+ }
+}
+
+/* When the ethtool is used to set the FEC mode */
+static bool check_fecparam_is_valid(u8 fec_param)
+{
+ if (
+#ifdef ETHTOOL_FEC_LLRS
+ (fec_param == ETHTOOL_FEC_LLRS) ||
+#endif
+ (fec_param == ETHTOOL_FEC_RS) ||
+ (fec_param == ETHTOOL_FEC_BASER) ||
+ (fec_param == ETHTOOL_FEC_OFF)) {
+ return true;
+ }
+ return false;
+}
+
+int set_fecparam(void *hwdev, u8 fecparam)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ u8 advertised_fec = 0;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (check_fecparam_is_valid(fecparam) == false) {
+ nic_err(nic_io->dev_hdl, "fec param is invalid, failed to set fec param\n");
+ return -EINVAL;
+ }
+ fecparam_convert(MAG_CMD_OPCODE_SET, fecparam, &advertised_fec);
+ fec_msg.opcode = MAG_CMD_OPCODE_SET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ fec_msg.advertised_fec = advertised_fec;
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0))
+ return -EINVAL;
+ return 0;
+}
+
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ fec_msg.opcode = MAG_CMD_OPCODE_GET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0))
+ return -EINVAL;
+
+ /* fec_msg.advertised_fec: bit offset,
+ *value is BIT(fec_msg.advertised_fec); fec_msg.supported_fec: value
+ */
+ fecparam_convert(MAG_CMD_OPCODE_GET, BIT(fec_msg.advertised_fec),
+ advertised_fec);
+ fecparam_convert(MAG_CMD_OPCODE_GET, fec_msg.supported_fec,
+ supported_fec);
+ return 0;
+}
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
index 6f90c86..9d14e0f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
@@ -20,6 +20,9 @@
#include <linux/debugfs.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#include "hinic3_hw.h"
#include "hinic3_crm.h"
#include "hinic3_mt.h"
@@ -35,8 +38,8 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
#include "hinic3_profile.h"
+#include "hinic3_bond.h"
-/*lint -e806*/
#define DEFAULT_POLL_WEIGHT 64
static unsigned int poll_weight = DEFAULT_POLL_WEIGHT;
module_param(poll_weight, uint, 0444);
@@ -68,7 +71,9 @@ static unsigned char set_link_status_follow = HINIC3_LINK_FOLLOW_STATUS_MAX;
module_param(set_link_status_follow, byte, 0444);
MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=default,1=follow,2=separate,3=unset");
-/*lint +e806*/
+static bool page_pool_enabled = true;
+module_param(page_pool_enabled, bool, 0444);
+MODULE_PARM_DESC(page_pool_enabled, "enable/disable page_pool feature for rxq page management (default enable)");
#define HINIC3_NIC_DEV_WQ_NAME "hinic3_nic_dev_wq"
@@ -80,6 +85,8 @@ MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=
#define HINIC3_SQ_DEPTH 1024
#define HINIC3_RQ_DEPTH 1024
+#define LRO_ENABLE 1
+
enum hinic3_rx_buff_len {
RX_BUFF_VALID_2KB = 2,
RX_BUFF_VALID_4KB = 4,
@@ -87,12 +94,15 @@ enum hinic3_rx_buff_len {
RX_BUFF_VALID_16KB = 16,
};
+#define NIC_MAX_PF_NUM 32
+
#define CONVERT_UNIT 1024
-#define BIFUR_RESOURCE_PF_SSID 0x5a1
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
-static int hinic3_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr);
+static int hinic3_netdev_event(struct notifier_block *notifier,
+ unsigned long event, void *ptr);
/* used for netdev notifier register/unregister */
static DEFINE_MUTEX(hinic3_netdev_notifiers_mutex);
@@ -101,6 +111,17 @@ static struct notifier_block hinic3_netdev_notifier = {
.notifier_call = hinic3_netdev_event,
};
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+static const struct udp_tunnel_nic_info hinic3_udp_tunnels = {
+ .set_port = hinic3_udp_tunnel_set_port,
+ .unset_port = hinic3_udp_tunnel_unset_port,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static void hinic3_register_notifier(struct hinic3_nic_dev *nic_dev)
{
int err;
@@ -134,7 +155,8 @@ static void hinic3_unregister_notifier(struct hinic3_nic_dev *nic_dev)
NETIF_F_SCTP_CRC | NETIF_F_RXCSUM | \
NETIF_F_ALL_TSO)
-static int hinic3_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr)
+static int hinic3_netdev_event(struct notifier_block *notifier,
+ unsigned long event, void *ptr)
{
struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
struct net_device *real_dev = NULL;
@@ -266,6 +288,11 @@ static void netdev_feature_init(struct net_device *netdev)
netdev->features |= dft_fts | cso_fts | tso_fts | vlan_fts;
netdev->vlan_features |= dft_fts | cso_fts | tso_fts;
+ if (nic_dev->nic_cap.lro_enable == LRO_ENABLE) {
+ netdev->features |= NETIF_F_LRO;
+ netdev->vlan_features |= NETIF_F_LRO;
+ }
+
#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT
hw_features |= get_netdev_hw_features(netdev);
#else
@@ -306,7 +333,8 @@ static void init_intr_coal_param(struct hinic3_nic_dev *nic_dev)
info->pending_limt = qp_pending_limit;
info->coalesce_timer_cfg = qp_coalesc_timer_cfg;
- info->resend_timer_cfg = HINIC3_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG;
+ info->resend_timer_cfg =
+ HINIC3_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG;
info->pkt_rate_high = HINIC3_RX_RATE_HIGH;
info->rx_usecs_high = HINIC3_RX_COAL_TIME_HIGH;
@@ -350,6 +378,7 @@ static int hinic3_init_intr_coalesce(struct hinic3_nic_dev *nic_dev)
static void hinic3_free_intr_coalesce(struct hinic3_nic_dev *nic_dev)
{
kfree(nic_dev->intr_coalesce);
+ nic_dev->intr_coalesce = NULL;
}
static int hinic3_alloc_txrxqs(struct hinic3_nic_dev *nic_dev)
@@ -396,15 +425,18 @@ static void hinic3_free_txrxqs(struct hinic3_nic_dev *nic_dev)
static void hinic3_tx_rx_ops_init(struct hinic3_nic_dev *nic_dev)
{
if (HINIC3_SUPPORT_TX_COMPACT_WQE_OL(nic_dev->hwdev)) {
- nic_dev->tx_rx_ops.tx_set_wqebb_cnt = hinic3_tx_set_compact_offload_wqebb_cnt;
- nic_dev->tx_rx_ops.tx_set_wqe_task = hinic3_tx_set_compact_offload_wqe_task;
+ nic_dev->tx_rx_ops.tx_set_wqebb_cnt =
+ hinic3_tx_set_compact_offload_wqebb_cnt;
+ nic_dev->tx_rx_ops.tx_set_wqe_task =
+ hinic3_tx_set_compact_offload_wqe_task;
} else {
nic_dev->tx_rx_ops.tx_set_wqebb_cnt = hinic3_tx_set_wqebb_cnt;
nic_dev->tx_rx_ops.tx_set_wqe_task = hinic3_tx_set_wqe_task;
}
if (HINIC3_SUPPORT_RX_COMPACT_CQE(nic_dev->hwdev))
- nic_dev->tx_rx_ops.rx_get_cqe_info = hinic3_rx_get_compact_cqe_info;
+ nic_dev->tx_rx_ops.rx_get_cqe_info =
+ hinic3_rx_get_compact_cqe_info;
else
nic_dev->tx_rx_ops.rx_get_cqe_info = hinic3_rx_get_cqe_info;
}
@@ -420,53 +452,47 @@ static void hinic3_sw_deinit(struct hinic3_nic_dev *nic_dev)
HINIC3_CHANNEL_NIC);
hinic3_clear_rss_config(nic_dev);
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+
+ hinic3_dcb_deinit(nic_dev);
}
-static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
+static void hinic3_netdev_mtu_init(struct net_device *netdev)
+{
+ /* MTU range: 384 - 9600 */
+#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
+ netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+
+#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
+ netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+}
+
+static int hinic3_set_default_mac(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
u8 mac_addr[ETH_ALEN];
- u64 nic_features;
int err = 0;
- nic_features = hinic3_get_feature_cap(nic_dev->hwdev);
- /* You can update the features supported by the driver according to the
- * scenario here
- */
- nic_features &= NIC_DRV_DEFAULT_FEATURE;
- hinic3_update_nic_feature(nic_dev->hwdev, nic_features);
-
- sema_init(&nic_dev->port_state_sem, 1);
-
- err = hinic3_dcb_init(nic_dev);
- if (err) {
- nic_err(&nic_dev->pdev->dev, "Failed to init dcb\n");
- return -EFAULT;
- }
-
- nic_dev->q_params.sq_depth = HINIC3_SQ_DEPTH;
- nic_dev->q_params.rq_depth = HINIC3_RQ_DEPTH;
-
- hinic3_try_to_enable_rss(nic_dev);
-
err = hinic3_get_default_mac(nic_dev->hwdev, mac_addr);
if (err) {
nic_err(&nic_dev->pdev->dev, "Failed to get MAC address\n");
- goto get_mac_err;
+ return err;
}
+
eth_hw_addr_set(netdev, mac_addr);
if (!is_valid_ether_addr(netdev->dev_addr)) {
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
nic_err(&nic_dev->pdev->dev, "Invalid MAC address %pM\n",
- netdev->dev_addr);
- err = -EIO;
- goto err_mac;
- }
+ netdev->dev_addr);
+ return -EIO;
+ }
- nic_info(&nic_dev->pdev->dev, "Invalid MAC address %pM, using random\n",
+ nic_info(&nic_dev->pdev->dev,
+ "Invalid MAC address %pM, using random\n",
netdev->dev_addr);
eth_hw_addr_random(netdev);
}
@@ -478,21 +504,62 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
* MAC, and we can't consider this condition is error status during
* driver probe procedure.
*/
- if (err && err != HINIC3_PF_SET_VF_ALREADY) {
+ if (err && err != HINIC3_PF_SET_VF_ALREADY)
nic_err(&nic_dev->pdev->dev, "Failed to set default MAC\n");
- goto set_mac_err;
+
+ if (err == HINIC3_PF_SET_VF_ALREADY)
+ return 0;
+
+ return err;
+}
+
+static void hinic3_outband_cfg_init(struct hinic3_nic_dev *nic_dev)
+{
+ u16 outband_default_vid = 0;
+ int err = 0;
+
+ if (!nic_dev->nic_cap.outband_vlan_cfg_en)
+ return;
+
+ err = hinic3_get_outband_vlan_cfg(nic_dev->hwdev, &outband_default_vid);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev,
+ "Failed to get_outband_cfg, err: %d\n", err);
+ return;
}
- /* MTU range: 384 - 9600 */
-#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
- netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
+ nic_dev->outband_cfg.outband_default_vid = outband_default_vid;
+}
-#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
- netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
+static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
+{
+ struct net_device *netdev = nic_dev->netdev;
+ u64 nic_features;
+ int err = 0;
+
+ nic_features = hinic3_get_feature_cap(nic_dev->hwdev);
+ /* You can update the features supported by the driver according to the
+ * scenario here
+ */
+ nic_features &= NIC_DRV_DEFAULT_FEATURE;
+ hinic3_update_nic_feature(nic_dev->hwdev, nic_features);
+
+ err = hinic3_dcb_init(nic_dev);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev, "Failed to init dcb\n");
+ return -EFAULT;
+ }
+
+ nic_dev->q_params.sq_depth = HINIC3_SQ_DEPTH;
+ nic_dev->q_params.rq_depth = HINIC3_RQ_DEPTH;
+
+ hinic3_try_to_enable_rss(nic_dev);
+
+ err = hinic3_set_default_mac(nic_dev);
+ if (err)
+ goto set_mac_err;
+
+ hinic3_netdev_mtu_init(netdev);
err = hinic3_alloc_txrxqs(nic_dev);
if (err) {
@@ -500,6 +567,8 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
goto alloc_qps_err;
}
+ hinic3_outband_cfg_init(nic_dev);
+
hinic3_tx_rx_ops_init(nic_dev);
return 0;
@@ -510,8 +579,6 @@ alloc_qps_err:
HINIC3_CHANNEL_NIC);
set_mac_err:
-err_mac:
-get_mac_err:
hinic3_clear_rss_config(nic_dev);
return err;
@@ -623,7 +690,8 @@ static void calc_coal_para(struct hinic3_nic_dev *nic_dev,
*pending_limt =
(u8)((rx_rate - q_coal->pkt_rate_low) *
- (q_coal->rx_pending_limt_high - q_coal->rx_pending_limt_low) /
+ (q_coal->rx_pending_limt_high -
+ q_coal->rx_pending_limt_low) /
(q_coal->pkt_rate_high - q_coal->pkt_rate_low) +
q_coal->rx_pending_limt_low);
}
@@ -637,8 +705,10 @@ static void update_queue_coal(struct hinic3_nic_dev *nic_dev, u16 qid,
q_coal = &nic_dev->intr_coalesce[qid];
- if (rx_rate > HINIC3_RX_RATE_THRESH && avg_pkt_size > HINIC3_AVG_PKT_SMALL) {
- calc_coal_para(nic_dev, q_coal, rx_rate, &coalesc_timer_cfg, &pending_limt);
+ if (rx_rate > HINIC3_RX_RATE_THRESH &&
+ avg_pkt_size > HINIC3_AVG_PKT_SMALL) {
+ calc_coal_para(nic_dev, q_coal, rx_rate,
+ &coalesc_timer_cfg, &pending_limt);
} else {
coalesc_timer_cfg = HINIC3_LOWEST_LATENCY;
pending_limt = q_coal->rx_pending_limt_low;
@@ -701,20 +771,55 @@ void hinic3_auto_moderation_work(struct work_struct *work)
static void hinic3_periodic_work_handler(struct work_struct *work)
{
struct delayed_work *delay = to_delayed_work(work);
- struct hinic3_nic_dev *nic_dev = container_of(delay, struct hinic3_nic_dev, periodic_work);
+ struct hinic3_nic_dev *nic_dev =
+ container_of(delay, struct hinic3_nic_dev, periodic_work);
if (test_and_clear_bit(EVENT_WORK_TX_TIMEOUT, &nic_dev->event_flag))
- hinic3_fault_event_report(nic_dev->hwdev, HINIC3_FAULT_SRC_TX_TIMEOUT,
+ hinic3_fault_event_report(nic_dev->hwdev,
+ HINIC3_FAULT_SRC_TX_TIMEOUT,
FAULT_LEVEL_SERIOUS_FLR);
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
}
+static void hinic3_vport_stats_work_handler(struct work_struct *work)
+{
+ int err;
+ struct hinic3_vport_stats vport_stats = {0};
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_nic_dev *nic_dev = container_of(delay,
+ struct hinic3_nic_dev,
+ vport_stats_work);
+ err = hinic3_get_vport_stats(nic_dev->hwdev,
+ hinic3_global_func_id(nic_dev->hwdev),
+ &vport_stats);
+ if (err)
+ nic_err(&nic_dev->pdev->dev, "Failed to get dropped stats from fw\n");
+ else
+ nic_dev->vport_stats.rx_discard_vport =
+ vport_stats.rx_discard_vport;
+ queue_delayed_work(nic_dev->workq, &nic_dev->vport_stats_work, HZ);
+}
+
+static void free_nic_dev_vram(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram = get_use_vram_flag();
+
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)nic_dev->nic_vram, nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ else
+ kfree(nic_dev->nic_vram);
+ nic_dev->nic_vram = NULL;
+}
+
static void free_nic_dev(struct hinic3_nic_dev *nic_dev)
{
hinic3_deinit_nic_prof_adapter(nic_dev);
destroy_workqueue(nic_dev->workq);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+ free_nic_dev_vram(nic_dev);
}
static int setup_nic_dev(struct net_device *netdev,
@@ -724,6 +829,10 @@ static int setup_nic_dev(struct net_device *netdev,
struct hinic3_nic_dev *nic_dev;
char *netdev_name_fmt;
u32 page_num;
+ u16 func_id;
+ int ret;
+ int is_in_kexec = vram_get_kexec_flag();
+ int is_use_vram = get_use_vram_flag();
nic_dev = (struct hinic3_nic_dev *)netdev_priv(netdev);
nic_dev->netdev = netdev;
@@ -738,22 +847,60 @@ static int setup_nic_dev(struct net_device *netdev,
nic_dev->dma_rx_buff_size = RX_BUFF_NUM_PER_PAGE * nic_dev->rx_buff_len;
page_num = nic_dev->dma_rx_buff_size / PAGE_SIZE;
nic_dev->page_order = page_num > 0 ? ilog2(page_num) : 0;
+ nic_dev->page_pool_enabled = page_pool_enabled;
+ nic_dev->outband_cfg.outband_default_vid = 0;
+
+ // value other than 0 indicates hot replace
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(nic_dev->nic_vram_name, VRAM_NAME_MAX_LEN,
+ "%s%hu", VRAM_NIC_VRAM, func_id);
+
+ nic_dev->nic_vram = (struct hinic3_vram *)hi_vram_kalloc(
+ nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+
+ if (is_in_kexec == 0)
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ else
+ netdev->mtu = nic_dev->nic_vram->vram_mtu;
+ } else {
+ nic_dev->nic_vram = kzalloc(sizeof(struct hinic3_vram),
+ GFP_KERNEL);
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ }
mutex_init(&nic_dev->nic_mutex);
nic_dev->vlan_bitmap = kzalloc(VLAN_BITMAP_SIZE(nic_dev), GFP_KERNEL);
- if (!nic_dev->vlan_bitmap)
- return -ENOMEM;
+ if (!nic_dev->vlan_bitmap) {
+ nic_err(&pdev->dev, "Failed to allocate vlan bitmap\n");
+ ret = -ENOMEM;
+ goto vlan_bitmap_error;
+ }
nic_dev->workq = create_singlethread_workqueue(HINIC3_NIC_DEV_WQ_NAME);
if (!nic_dev->workq) {
nic_err(&pdev->dev, "Failed to initialize nic workqueue\n");
- kfree(nic_dev->vlan_bitmap);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto create_workq_error;
}
- INIT_DELAYED_WORK(&nic_dev->periodic_work, hinic3_periodic_work_handler);
- INIT_DELAYED_WORK(&nic_dev->rxq_check_work, hinic3_rxq_check_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->periodic_work,
+ hinic3_periodic_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->rxq_check_work,
+ hinic3_rxq_check_work_handler);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ INIT_DELAYED_WORK(&nic_dev->vport_stats_work,
+ hinic3_vport_stats_work_handler);
INIT_LIST_HEAD(&nic_dev->uc_filter_list);
INIT_LIST_HEAD(&nic_dev->mc_filter_list);
@@ -766,10 +913,23 @@ static int setup_nic_dev(struct net_device *netdev,
hinic3_init_nic_prof_adapter(nic_dev);
netdev_name_fmt = hinic3_get_dft_netdev_name_fmt(nic_dev);
- if (netdev_name_fmt)
- strscpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (netdev_name_fmt) {
+ ret = strscpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (ret < 0)
+ goto get_netdev_name_error;
+ }
return 0;
+
+get_netdev_name_error:
+ hinic3_deinit_nic_prof_adapter(nic_dev);
+ destroy_workqueue(nic_dev->workq);
+create_workq_error:
+ kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+vlan_bitmap_error:
+ free_nic_dev_vram(nic_dev);
+ return ret;
}
static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
@@ -808,6 +968,31 @@ static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
return 0;
}
+static void hinic3_bond_init(struct hinic3_nic_dev *nic_dev)
+{
+ u32 bond_id = HINIC3_INVALID_BOND_ID;
+ int err = hinic3_create_bond(nic_dev->hwdev, &bond_id);
+
+ if (err != 0)
+ goto bond_init_failed;
+
+ /* bond id does not change, means this pf is not bond active pf, no log is generated */
+ if (bond_id == HINIC3_INVALID_BOND_ID)
+ return;
+
+ err = hinic3_open_close_bond(nic_dev->hwdev, true);
+ if (err != 0) {
+ hinic3_delete_bond(nic_dev->hwdev);
+ goto bond_init_failed;
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Bond %d init success\n", bond_id);
+ return;
+
+bond_init_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond init failed\n");
+}
+
static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
char *uld_dev_name)
{
@@ -838,6 +1023,12 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
goto err_out;
}
+ err = hinic3_get_dev_cap(lld_dev->hwdev);
+ if (err != 0) {
+ nic_err(&pdev->dev, "Failed to get dev cap\n");
+ goto err_out;
+ }
+
max_qps = hinic3_func_max_nic_qnum(lld_dev->hwdev);
netdev = alloc_etherdev_mq(sizeof(*nic_dev), max_qps);
if (!netdev) {
@@ -870,10 +1061,17 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
hinic3_assign_netdev_ops(nic_dev);
netdev_feature_init(netdev);
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+ netdev->udp_tunnel_nic_info = &hinic3_udp_tunnels;
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
err = hinic3_set_default_hw_feature(nic_dev);
if (err)
goto set_features_err;
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0)
+ hinic3_bond_init(nic_dev);
+
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
hinic3_register_notifier(nic_dev);
#endif
@@ -888,6 +1086,9 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
}
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->vport_stats_work, HZ);
netif_carrier_off(netdev);
*uld_dev = nic_dev;
@@ -920,6 +1121,25 @@ err_out:
return err;
}
+static void hinic3_bond_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ int ret = 0;
+
+ ret = hinic3_open_close_bond(nic_dev->hwdev, false);
+ if (ret != 0)
+ goto bond_deinit_failed;
+
+ ret = hinic3_delete_bond(nic_dev->hwdev);
+ if (ret != 0)
+ goto bond_deinit_failed;
+
+ nic_info(&nic_dev->pdev->dev, "Bond deinit success\n");
+ return;
+
+bond_deinit_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond deinit failed\n");
+}
+
static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
{
struct hinic3_nic_dev *nic_dev = adapter;
@@ -939,6 +1159,8 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_unregister_notifier(nic_dev);
#endif
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ cancel_delayed_work_sync(&nic_dev->vport_stats_work);
cancel_delayed_work_sync(&nic_dev->periodic_work);
cancel_delayed_work_sync(&nic_dev->rxq_check_work);
cancel_work_sync(&nic_dev->rx_mode_work);
@@ -946,6 +1168,9 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_flush_rx_flow_rule(nic_dev);
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0)
+ hinic3_bond_deinit(nic_dev);
+
hinic3_update_nic_feature(nic_dev->hwdev, 0);
hinic3_set_nic_feature_to_hw(nic_dev->hwdev);
@@ -955,6 +1180,7 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_deinit_nic_prof_adapter(nic_dev);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
free_netdev(netdev);
@@ -971,8 +1197,10 @@ static void sriov_state_change(struct hinic3_nic_dev *nic_dev,
static void hinic3_port_module_event_handler(struct hinic3_nic_dev *nic_dev,
struct hinic3_event_info *event)
{
- const char *g_hinic3_module_link_err[LINK_ERR_NUM] = { "Unrecognized module" };
- struct hinic3_port_module_event *module_event = (void *)event->event_data;
+ const char *g_hinic3_module_link_err[LINK_ERR_NUM] = {
+ "Unrecognized module" };
+ struct hinic3_port_module_event *module_event =
+ (void *)event->event_data;
enum port_module_event_type type = module_event->type;
enum link_err_type err_type = module_event->err_type;
@@ -1003,6 +1231,116 @@ static void hinic3_port_module_event_handler(struct hinic3_nic_dev *nic_dev,
}
}
+bool hinic3_need_proc_link_event(struct hinic3_lld_dev *lld_dev)
+{
+ int ret = 0;
+ u16 func_id;
+ u8 roce_enable = false;
+ bool is_slave_func = false;
+ struct hinic3_hw_bond_infos hw_bond_infos = {0};
+
+ if (!lld_dev)
+ return false;
+
+ /* 非slave设备需要处理link down事件 */
+ ret = hinic3_is_slave_func(lld_dev->hwdev, &is_slave_func);
+ if (ret != 0) {
+ nic_err(&lld_dev->pdev->dev, "NIC get info, lld_dev is null\n");
+ return true;
+ }
+
+ if (!is_slave_func)
+ return true;
+
+ /* 未使能了vroce功能,需处理link down事件 */
+ func_id = hinic3_global_func_id(lld_dev->hwdev);
+ ret = hinic3_get_func_vroce_enable(lld_dev->hwdev, func_id, &roce_enable);
+ if (ret != 0)
+ return true;
+
+ if (!roce_enable)
+ return true;
+
+ /* 未创建bond,需要处理link down事件 */
+ hw_bond_infos.bond_id = HINIC_OVS_BOND_DEFAULT_ID;
+
+ ret = hinic3_get_hw_bond_infos(lld_dev->hwdev, &hw_bond_infos, HINIC3_CHANNEL_COMM);
+ if (ret != 0) {
+ pr_err("[ROCE, ERR] Get chipf bond info failed (%d)\n", ret);
+ return true;
+ }
+
+ if (!hw_bond_infos.valid)
+ return true;
+
+ return false;
+}
+
+bool hinic3_need_proc_bond_event(struct hinic3_lld_dev *lld_dev)
+{
+ return !hinic3_need_proc_link_event(lld_dev);
+}
+
+static void hinic_porc_bond_state_change(struct hinic3_lld_dev *lld_dev, void *adapter,
+ struct hinic3_event_info *event)
+{
+ struct hinic3_nic_dev *nic_dev = adapter;
+
+ if (!nic_dev || !event || !hinic3_support_nic(lld_dev->hwdev, NULL))
+ return;
+
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond down\n");
+ hinic3_link_status_change(nic_dev, false);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond up\n");
+ hinic3_link_status_change(nic_dev, true);
+ break;
+ default:
+ break;
+ }
+}
+
+static void hinic3_outband_cfg_event_handler(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_outband_cfg_info *info)
+{
+ int err = 0;
+
+ if (!nic_dev || !info || !hinic3_support_nic(nic_dev->hwdev, NULL)) {
+ pr_err("Outband cfg event invalid param\n");
+ return;
+ }
+
+ if (hinic3_func_type(nic_dev->hwdev) != TYPE_VF &&
+ info->func_id >= NIC_MAX_PF_NUM) {
+ err = hinic3_notify_vf_outband_cfg(nic_dev->hwdev,
+ info->func_id,
+ info->outband_default_vid);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev,
+ "Outband cfg event notify vf err: %d, func_id: 0x%x, vid: 0x%x\n",
+ err, info->func_id, info->outband_default_vid);
+ return;
+ }
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Change outband default vid from %u to %u\n",
+ nic_dev->outband_cfg.outband_default_vid,
+ info->outband_default_vid);
+
+ nic_dev->outband_cfg.outband_default_vid = info->outband_default_vid;
+}
+
static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
struct hinic3_event_info *event)
{
@@ -1014,21 +1352,35 @@ static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_DOWN):
+ if (!hinic3_need_proc_link_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc link event\n");
+ return;
+ }
hinic3_link_status_change(nic_dev, false);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_UP):
hinic3_link_status_change(nic_dev, true);
break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ hinic_porc_bond_state_change(lld_dev, adapter, event);
+ break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_PORT_MODULE_EVENT):
hinic3_port_module_event_handler(nic_dev, event);
break;
- case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_SRIOV_STATE_CHANGE):
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_OUTBAND_CFG):
+ hinic3_outband_cfg_event_handler(nic_dev,
+ (void *)event->event_data);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM,
+ EVENT_COMM_SRIOV_STATE_CHANGE):
sriov_state_change(nic_dev, (void *)event->event_data);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_FAULT):
fault = (void *)event->event_data;
if (fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
- fault->event.chip.func_id == hinic3_global_func_id(lld_dev->hwdev))
+ fault->event.chip.func_id ==
+ hinic3_global_func_id(lld_dev->hwdev))
hinic3_link_status_change(nic_dev, false);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_PCIE_LINK_DOWN):
@@ -1081,7 +1433,7 @@ struct hinic3_uld_info g_nic_uld_info = {
.resume = NULL,
.event = nic_event,
.ioctl = nic_ioctl,
-}; /*lint -e766*/
+};
struct hinic3_uld_info *get_nic_uld_info(void)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
index 94e606e..668f30e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
@@ -9,6 +9,7 @@
/* Interrupt at most records, interrupt will be recorded in the FFM */
#define NICTOOL_CMD_TYPE (0x18)
+#define HINIC3_CARD_NAME_MAX_LEN (128)
struct api_cmd_rd {
u32 pf_id;
@@ -110,7 +111,8 @@ enum dbgtool_cmd {
DBGTOOL_CMD_NUM
};
-#define PF_MAX_SIZE (16)
+#define HINIC_PF_MAX_SIZE (16)
+#define HINIC_VF_MAX_SIZE (4096)
#define BUSINFO_LEN (32)
enum module_name {
@@ -132,7 +134,8 @@ enum module_name {
SEND_TO_MIGRATE_DRIVER,
SEND_TO_PPA_DRIVER,
SEND_TO_CUSTOM_DRIVER = SEND_TO_SRV_DRV_BASE + 11,
- SEND_TO_BIFUR_DRIVER = SEND_TO_SRV_DRV_BASE + 15,
+ SEND_TO_VSOCK_DRIVER = SEND_TO_SRV_DRV_BASE + 14,
+ SEND_TO_BIFUR_DRIVER,
SEND_TO_DRIVER_MAX = SEND_TO_SRV_DRV_BASE + 16, /* reserved */
};
@@ -160,7 +163,7 @@ enum driver_cmd_type {
GET_CHIP_FAULT_STATS,
NIC_RSVD1,
NIC_RSVD2,
- NIC_RSVD3,
+ GET_OS_HOT_REPLACE_INFO,
GET_CHIP_ID,
GET_SINGLE_CARD_INFO,
GET_FIRMWARE_ACTIVE_STATUS,
@@ -171,7 +174,7 @@ enum driver_cmd_type {
GET_LOOPBACK_MODE = 32,
SET_LOOPBACK_MODE,
SET_LINK_MODE,
- SET_PF_BW_LIMIT,
+ SET_TX_PF_BW_LIMIT,
GET_PF_BW_LIMIT,
ROCE_CMD,
GET_POLL_WEIGHT,
@@ -189,6 +192,7 @@ enum driver_cmd_type {
GET_NIC_STATS_STRING,
GET_NIC_STATS_INFO,
GET_PF_ID,
+ GET_MBOX_CNT,
NIC_RSVD4,
NIC_RSVD5,
DCB_QOS_INFO,
@@ -205,6 +209,8 @@ enum driver_cmd_type {
RSS_INDIR,
PORT_ID,
+ SET_RX_PF_BW_LIMIT = 0x43,
+
GET_FUNC_CAP = 0x50,
GET_XSFP_PRESENT = 0x51,
GET_XSFP_INFO = 0x52,
@@ -216,6 +222,38 @@ enum driver_cmd_type {
WIN_CSR_WRITE = 0x62,
WIN_API_CMD_RD = 0x63,
+ GET_FUSION_Q = 0x64,
+ ROCE_CMD_SET_LDCP_PARAM = 0x70,
+
+ ROCE_CMD_GET_QPC_FROM_CACHE = 0x80,
+ ROCE_CMD_GET_QPC_FROM_HOST = 0x81,
+ ROCE_CMD_GET_CQC_FROM_CACHE = 0x82,
+ ROCE_CMD_GET_CQC_FROM_HOST = 0x83,
+ ROCE_CMD_GET_SRQC_FROM_CACHE = 0x84,
+ ROCE_CMD_GET_SRQC_FROM_HOST = 0x85,
+ ROCE_CMD_GET_MPT_FROM_CACHE = 0x86,
+ ROCE_CMD_GET_MPT_FROM_HOST = 0x87,
+ ROCE_CMD_GET_GID_FROM_CACHE = 0x88,
+ ROCE_CMD_GET_QPC_CQC_PI_CI = 0x89,
+ ROCE_CMD_GET_QP_COUNT = 0x8a,
+ ROCE_CMD_GET_DEV_ALGO = 0x8b,
+
+ ROCE_CMD_START_CAP_PACKET = 0x90,
+ ROCE_CMD_STOP_CAP_PACKET = 0x91,
+ ROCE_CMD_QUERY_CAP_INFO = 0x92,
+ ROCE_CMD_ENABLE_QP_CAP_PACKET = 0x93,
+ ROCE_CMD_DISABLE_QP_CAP_PACKET = 0x94,
+ ROCE_CMD_QUERY_QP_CAP_INFO = 0x95,
+
+ ROCE_CMD_ENABLE_BW_CTRL = 0xa0,
+ ROCE_CMD_DISABLE_BW_CTRL = 0xa1,
+ ROCE_CMD_CHANGE_BW_CTRL_PARAM = 0xa2,
+ ROCE_CMD_QUERY_BW_CTRL_PARAM = 0xa3,
+
+ ROCE_CMD_TIMEOUT_ALARM = 0xb0,
+ ROCE_CMD_PORT_TRAFFIC = 0Xb1,
+ ROCE_CMD_BOND_HASH_TYPE_SET = 0xb2,
+
BIFUR_SET_ENABLE = 0xc0,
BIFUR_GET_ENABLE = 0xc1,
@@ -234,7 +272,8 @@ enum sm_cmd_type {
SM_CTR_RD64,
SM_CTR_RD32_CLEAR,
SM_CTR_RD64_PAIR_CLEAR,
- SM_CTR_RD64_CLEAR
+ SM_CTR_RD64_CLEAR,
+ SM_CTR_RD16_CLEAR,
};
struct cqm_stats {
@@ -321,10 +360,22 @@ struct pf_info {
};
struct card_info {
- struct pf_info pf[PF_MAX_SIZE];
+ struct pf_info pf[HINIC_PF_MAX_SIZE];
u32 pf_num;
};
+struct func_mbox_cnt_info {
+ char bus_info[BUSINFO_LEN];
+ u64 send_cnt;
+ u64 ack_cnt;
+};
+
+struct card_mbox_cnt_info {
+ struct func_mbox_cnt_info func_info[HINIC_PF_MAX_SIZE +
+ HINIC_VF_MAX_SIZE];
+ u32 func_num;
+};
+
struct hinic3_nic_loop_mode {
u32 loop_mode;
u32 loop_ctrl;
@@ -665,6 +716,161 @@ struct get_card_bond_msg_s {
struct bond_all_msg_s all_msg[MAX_BONDING_CNT_PER_CARD];
};
+#define MAX_FUSION_Q_STATS_STR_LEN 16
+#define MAX_FUSION_Q_NUM 256
+struct queue_status_s {
+ pid_t tgid;
+ char status[MAX_FUSION_Q_STATS_STR_LEN];
+};
+struct fusion_q_status_s {
+ u16 queue_num;
+ struct queue_status_s queue[MAX_FUSION_Q_NUM];
+};
+
+struct fusion_q_tx_hw_page {
+ u64 phy_addr;
+ u64 *map_addr;
+};
+
+struct fusion_sq_info {
+ u16 q_id;
+ u16 pi;
+ u16 ci; /* sw_ci */
+ u16 fi; /* hw_ci */
+ u32 q_depth;
+ u16 pi_reverse;
+ u16 wqebb_size;
+ u8 priority;
+ u16 *ci_addr;
+ u64 cla_addr;
+ void *slq_handle;
+ struct fusion_q_tx_hw_page direct_wqe;
+ struct fusion_q_tx_hw_page doorbell;
+ u32 page_idx;
+ u32 glb_sq_id;
+};
+
+struct fusion_q_tx_wqe {
+ u32 data[4];
+};
+
+struct fusion_rq_info {
+ u16 q_id;
+ u16 delta;
+ u16 hw_pi;
+ u16 ci; /* sw_ci */
+ u16 sw_pi;
+ u16 wqebb_size;
+ u16 q_depth;
+ u16 buf_len;
+
+ void *slq_handle;
+ u64 ci_wqe_page_addr;
+ u64 ci_cla_tbl_addr;
+
+ u8 coalesc_timer_cfg;
+ u8 pending_limt;
+ u16 msix_idx;
+ u32 msix_vector;
+};
+
+struct fusion_q_rx_wqe {
+ u32 data[8];
+};
+
+struct fusion_q_rx_cqe {
+ union {
+ struct {
+ unsigned int checksum_err : 16;
+ unsigned int lro_num : 8;
+ unsigned int rsvd1 : 7;
+ unsigned int rx_done : 1;
+ } bs;
+ unsigned int value;
+ } dw0;
+
+ union {
+ struct {
+ unsigned int vlan : 16;
+ unsigned int length : 16;
+ } bs;
+ unsigned int value;
+ } dw1;
+
+ union {
+ struct {
+ unsigned int pkt_types : 12;
+ unsigned int rsvd : 4;
+ unsigned int udp_0 : 1;
+ unsigned int ipv6_ex_add : 1;
+ unsigned int loopback : 1;
+ unsigned int umbcast : 2;
+ unsigned int vlan_offload_en : 1;
+ unsigned int tag_num : 2;
+ unsigned int rss_type : 8;
+ } bs;
+ unsigned int value;
+ } dw2;
+
+ union {
+ struct {
+ unsigned int rss_hash_value;
+ } bs;
+ unsigned int value;
+ } dw3;
+
+ union {
+ struct {
+ unsigned int tx_ts_seq : 16;
+ unsigned int message_1588_offset : 8;
+ unsigned int message_1588_type : 4;
+ unsigned int rsvd : 1;
+ unsigned int if_rx_ts : 1;
+ unsigned int if_tx_ts : 1;
+ unsigned int if_1588 : 1;
+ } bs;
+ unsigned int value;
+ } dw4;
+
+ union {
+ struct {
+ unsigned int ts;
+ } bs;
+ unsigned int value;
+ } dw5;
+
+ union {
+ struct {
+ unsigned int lro_ts;
+ } bs;
+ unsigned int value;
+ } dw6;
+
+ union {
+ struct {
+ unsigned int rsvd0;
+ } bs;
+ unsigned int value;
+ } dw7; /* 16Bytes Align */
+};
+
+struct os_hot_repalce_func_info {
+ char card_name[HINIC3_CARD_NAME_MAX_LEN];
+ u32 bus_num;
+ u32 valid;
+ u32 bdf;
+ int partition;
+ u16 backup_pf;
+ u16 pf_idx;
+ int port_id;
+};
+
+#define ALL_CARD_PF_NUM 2048 /* 64 card * 32 pf */
+struct os_hot_replace_info {
+ struct os_hot_repalce_func_info func_infos[ALL_CARD_PF_NUM];
+ u32 func_cnt;
+};
+
int alloc_buff_in(void *hwdev, struct msg_module *nt_msg, u32 in_size, void **buf_in);
int alloc_buff_out(void *hwdev, struct msg_module *nt_msg, u32 out_size, void **buf_out);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
index ea1d506..66c41f8 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
@@ -15,6 +15,9 @@
#include <linux/ip.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#ifdef HAVE_XDP_SUPPORT
#include <linux/bpf.h>
#endif
@@ -28,6 +31,10 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
+#include "nic_npu_cmd.h"
+
+#include "vram_common.h"
+
#define HINIC3_DEFAULT_RX_CSUM_OFFLOAD 0xFFF
#define HINIC3_LRO_DEFAULT_COAL_PKT_SIZE 32
@@ -47,8 +54,63 @@ static void hinic3_nic_set_rx_mode(struct net_device *netdev)
queue_work(nic_dev->workq, &nic_dev->rx_mode_work);
}
+static void hinic3_free_irq_vram(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_dyna_txrxq_params *in_q_params)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ struct hinic3_dyna_txrxq_params q_params = nic_dev->q_params;
+
+ if (q_params.irq_cfg == NULL)
+ return;
+
+ size = sizeof(struct hinic3_irq) * (q_params.num_qps);
+
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)q_params.irq_cfg, q_params.irq_cfg_vram_name, size);
+ q_params.irq_cfg = NULL;
+ } else {
+ kfree(in_q_params->irq_cfg);
+ in_q_params->irq_cfg = NULL;
+ }
+}
+
+static int hinic3_alloc_irq_vram(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_dyna_txrxq_params *q_params, bool is_up_eth)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ u16 func_id;
+
+ size = sizeof(struct hinic3_irq) * q_params->num_qps;
+
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(q_params->irq_cfg_vram_name, VRAM_NAME_MAX_LEN,
+ "%s%hu", VRAM_NIC_IRQ_VRAM, func_id);
+ q_params->irq_cfg = (struct hinic3_irq *)hi_vram_kalloc(
+ q_params->irq_cfg_vram_name, size);
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq vram alloc failed.\n");
+ return -ENOMEM;
+ }
+ /* in order to clear napi stored in vram, irq need to init when eth up */
+ if (is_up_eth)
+ memset(q_params->irq_cfg, 0, size);
+ } else {
+ q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq alloc failed.\n");
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_txrxq_params *q_params)
+ struct hinic3_dyna_txrxq_params *q_params,
+ bool is_up_eth)
{
u32 size;
int err;
@@ -70,12 +132,9 @@ static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
goto alloc_rxqs_res_arr_err;
}
- size = sizeof(*q_params->irq_cfg) * q_params->num_qps;
- q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
- if (!q_params->irq_cfg) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to alloc irq resource array\n");
- err = -ENOMEM;
+ err = hinic3_alloc_irq_vram(nic_dev, q_params, is_up_eth);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc irq resource array\n");
goto alloc_irq_cfg_err;
}
@@ -102,8 +161,7 @@ alloc_rxqs_res_err:
q_params->txqs_res);
alloc_txqs_res_err:
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ hinic3_free_irq_vram(nic_dev, q_params);
alloc_irq_cfg_err:
kfree(q_params->rxqs_res);
@@ -117,15 +175,17 @@ alloc_rxqs_res_arr_err:
}
static void hinic3_free_txrxq_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_txrxq_params *q_params)
+ struct hinic3_dyna_txrxq_params *q_params)
{
+ int is_in_kexec = vram_get_kexec_flag();
+
hinic3_free_rxqs_res(nic_dev, q_params->num_qps, q_params->rq_depth,
q_params->rxqs_res);
hinic3_free_txqs_res(nic_dev, q_params->num_qps, q_params->sq_depth,
q_params->txqs_res);
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ if (is_in_kexec == 0)
+ hinic3_free_irq_vram(nic_dev, q_params);
kfree(q_params->rxqs_res);
q_params->rxqs_res = NULL;
@@ -161,6 +221,7 @@ static int hinic3_configure_txrxqs(struct hinic3_nic_dev *nic_dev,
static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos;
if (!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
@@ -171,12 +232,13 @@ static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
num_cos = hinic3_get_dev_user_cos_num(nic_dev);
hinic3_update_qp_cos_cfg(nic_dev, num_cos);
/* For now, we don't support to change num_cos */
- if (num_cos > nic_dev->cos_config_num_max ||
+ if (num_cos > dcb->cos_config_num_max ||
nic_dev->q_params.num_qps < num_cos) {
nicif_err(nic_dev, drv, netdev, "Invalid num_cos: %u or num_qps: %u, disable DCB\n",
num_cos, nic_dev->q_params.num_qps);
nic_dev->q_params.num_cos = 0;
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
/* if we can't enable rss or get enough num_qps,
* need to sync default configure to hw
*/
@@ -190,17 +252,22 @@ static int hinic3_configure(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
- err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
- if (err) {
- nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
- return err;
+ if (is_in_kexec == 0) {
+ err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
+ return err;
+ }
}
config_dcb_qps_map(nic_dev);
/* rx rss init */
- err = hinic3_rx_configure(netdev, test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ err = hinic3_rx_configure(netdev,
+ test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)
+ ? 1 : 0);
if (err) {
nicif_err(nic_dev, drv, netdev, "Failed to configure rx\n");
return err;
@@ -256,10 +323,11 @@ static void config_dcb_num_qps(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dyna_txrxq_params *q_params,
u16 max_qps)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos = q_params->num_cos;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (!num_cos || num_cos > nic_dev->cos_config_num_max || num_cos > max_qps)
+ if (!num_cos || num_cos > dcb->cos_config_num_max || num_cos > max_qps)
return; /* will disable DCB in config_dcb_qps_map() */
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
@@ -313,8 +381,10 @@ static int hinic3_setup_num_qps(struct hinic3_nic_dev *nic_dev)
return -EINVAL;
}
nic_dev->qps_irq_info = kzalloc(irq_size, GFP_KERNEL);
- if (!nic_dev->qps_irq_info)
+ if (!nic_dev->qps_irq_info) {
+ nicif_err(nic_dev, drv, netdev, "Failed to alloc qps_irq_info\n");
return -ENOMEM;
+ }
hinic3_config_num_qps(nic_dev, &nic_dev->q_params);
@@ -332,57 +402,10 @@ static void hinic3_destroy_num_qps(struct hinic3_nic_dev *nic_dev)
kfree(nic_dev->qps_irq_info);
}
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev)
-{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- err = hinic3_set_port_enable(nic_dev->hwdev, false, HINIC3_CHANNEL_NIC);
- if (!err)
- nic_dev->force_port_disable = true;
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
-{
- int err = 0;
-
- down(&nic_dev->port_state_sem);
-
- nic_dev->force_port_disable = false;
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
- HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- /* Do nothing when force disable
- * Port will disable when call force port disable
- * and should not enable port when in force mode
- */
- if (nic_dev->force_port_disable) {
- up(&nic_dev->port_state_sem);
- return 0;
- }
-
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
- HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
+ return hinic3_set_port_enable(nic_dev->hwdev, enable,
+ HINIC3_CHANNEL_NIC);
}
static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
@@ -398,8 +421,8 @@ static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
}
static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+ struct hinic3_dyna_qp_params *qp_params,
+ struct hinic3_dyna_txrxq_params *trxq_params, bool is_up_eth)
{
int err;
@@ -414,7 +437,7 @@ static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
return err;
}
- err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params);
+ err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params, is_up_eth);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc txrxq resources\n");
hinic3_free_qps(nic_dev->hwdev, qp_params);
@@ -425,8 +448,8 @@ static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
}
static void hinic3_free_channel_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+ struct hinic3_dyna_qp_params *qp_params,
+ struct hinic3_dyna_txrxq_params *trxq_params)
{
mutex_lock(&nic_dev->nic_mutex);
hinic3_free_txrxq_resources(nic_dev, trxq_params);
@@ -521,7 +544,8 @@ int hinic3_vport_up(struct hinic3_nic_dev *nic_dev)
queue_delayed_work(nic_dev->workq, &nic_dev->moderation_task,
HINIC3_MODERATONE_DELAY);
if (test_bit(HINIC3_RXQ_RECOVERY, &nic_dev->flags))
- queue_delayed_work(nic_dev->workq, &nic_dev->rxq_check_work, HZ);
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->rxq_check_work, HZ);
hinic3_print_link_message(nic_dev, link_status);
@@ -542,9 +566,52 @@ vport_enable_err:
return err;
}
+static int hinic3_flush_rq_and_check(struct hinic3_nic_dev *nic_dev, u16 glb_func_id)
+{
+ struct hinic3_flush_rq *rq_flush_msg = NULL;
+ struct hinic3_cmd_buf *cmd_buf = NULL;
+ int out_buf_len = sizeof(struct hinic3_flush_rq);
+ u16 rq_id;
+ u64 out_param = 0;
+ int ret;
+
+ cmd_buf = hinic3_alloc_cmd_buf(nic_dev->hwdev);
+ if (!cmd_buf) {
+ nic_err(&nic_dev->pdev->dev, "Failed to allocate cmd buf\n");
+ return -ENOMEM;
+ }
+
+ cmd_buf->size = sizeof(struct hinic3_flush_rq);
+ rq_flush_msg = (struct hinic3_flush_rq *)cmd_buf->buf;
+ rq_flush_msg->dw.bs.func_id = glb_func_id;
+ for (rq_id = 0; rq_id < nic_dev->q_params.num_qps; rq_id++) {
+ rq_flush_msg->dw.bs.rq_id = rq_id;
+ hinic3_cpu_to_be32(rq_flush_msg, out_buf_len);
+ ret = hinic3_cmdq_direct_resp(nic_dev->hwdev, HINIC3_MOD_L2NIC,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ cmd_buf, &out_param, 0,
+ HINIC3_CHANNEL_NIC);
+ if (ret != 0 || out_param != 0) {
+ nic_err(&nic_dev->pdev->dev, "Failed to flush rq, ret:%d, func:%u, rq:%u\n",
+ ret, glb_func_id, rq_id);
+ goto err;
+ }
+ hinic3_be32_to_cpu(rq_flush_msg, out_buf_len);
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Func:%u rq_num:%u flush rq success\n",
+ glb_func_id, nic_dev->q_params.num_qps);
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return 0;
+err:
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return -1;
+}
+
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
{
u16 glb_func_id;
+ int is_in_kexec = vram_get_kexec_flag();
netif_carrier_off(nic_dev->netdev);
netif_tx_disable(nic_dev->netdev);
@@ -557,18 +624,21 @@ void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, 0);
- hinic3_maybe_set_port_state(nic_dev, false);
+ if (is_in_kexec != 0)
+ nicif_info(nic_dev, drv, nic_dev->netdev, "Skip changing mag status!\n");
+ else
+ hinic3_maybe_set_port_state(nic_dev, false);
glb_func_id = hinic3_global_func_id(nic_dev->hwdev);
hinic3_set_vport_enable(nic_dev->hwdev, glb_func_id, false,
HINIC3_CHANNEL_NIC);
hinic3_flush_txqs(nic_dev->netdev);
- /* After set vport disable 100ms,
- * no packets will be send to host
- * FPGA set 2000ms
- */
- msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+
+ if (is_in_kexec == 0)
+ msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+ else
+ (void)hinic3_flush_rq_and_check(nic_dev, glb_func_id);
hinic3_flush_qps_res(nic_dev->hwdev);
}
}
@@ -581,11 +651,12 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_qp_params new_qp_params = {0};
struct hinic3_dyna_qp_params cur_qp_params = {0};
int err;
+ bool is_free_resources = false;
hinic3_config_num_qps(nic_dev, trxq_params);
err = hinic3_alloc_channel_resources(nic_dev, &new_qp_params,
- trxq_params);
+ trxq_params, false);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc channel resources\n");
@@ -597,10 +668,19 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
hinic3_close_channel(nic_dev, &cur_qp_params);
hinic3_free_channel_resources(nic_dev, &cur_qp_params,
&nic_dev->q_params);
+ is_free_resources = true;
}
if (nic_dev->num_qp_irq > trxq_params->num_qps)
hinic3_qp_irq_change(nic_dev, trxq_params->num_qps);
+
+ if (is_free_resources) {
+ err = hinic3_alloc_irq_vram(nic_dev, trxq_params, false);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Change chl alloc irq failed\n");
+ goto alloc_irq_err;
+ }
+ }
nic_dev->q_params = *trxq_params;
if (reopen_handler)
@@ -621,7 +701,7 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
vport_up_err:
hinic3_close_channel(nic_dev, &new_qp_params);
-
+alloc_irq_err:
open_channel_err:
hinic3_free_channel_resources(nic_dev, &new_qp_params, trxq_params);
@@ -652,7 +732,7 @@ int hinic3_open(struct net_device *netdev)
}
err = hinic3_alloc_channel_resources(nic_dev, &qp_params,
- &nic_dev->q_params);
+ &nic_dev->q_params, true);
if (err)
goto alloc_channel_res_err;
@@ -691,12 +771,31 @@ setup_qps_err:
return err;
}
+static void hinic3_delete_napi(struct hinic3_nic_dev *nic_dev)
+{
+ u16 q_id;
+ int is_in_kexec = vram_get_kexec_flag();
+ struct hinic3_irq *irq_cfg = NULL;
+
+ if (is_in_kexec == 0 || nic_dev->q_params.irq_cfg == NULL)
+ return;
+
+ for (q_id = 0; q_id < nic_dev->q_params.num_qps; q_id++) {
+ irq_cfg = &(nic_dev->q_params.irq_cfg[q_id]);
+ qp_del_napi(irq_cfg);
+ }
+
+ hinic3_free_irq_vram(nic_dev, &nic_dev->q_params);
+}
+
int hinic3_close(struct net_device *netdev)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic3_dyna_qp_params qp_params = {0};
if (!test_and_clear_bit(HINIC3_INTF_UP, &nic_dev->flags)) {
+ /* delete napi in os hotreplace rollback */
+ hinic3_delete_napi(nic_dev);
nicif_info(nic_dev, drv, netdev, "Netdev already close, do nothing\n");
return 0;
}
@@ -776,7 +875,8 @@ static u8 parse_ipv6_info(struct sk_buff *skb, u32 *rss_tunple,
return 0;
}
-static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb,
+static u16 select_queue_by_hash_func(struct net_device *dev,
+ struct sk_buff *skb,
unsigned int num_tx_queues)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(dev);
@@ -831,17 +931,20 @@ static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb
}
#define GET_DSCP_PRI_OFFSET 2
-static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev, struct sk_buff *skb)
+static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev,
+ struct sk_buff *skb)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int dscp_cp;
if (skb->protocol == htons(ETH_P_IP))
dscp_cp = ipv4_get_dsfield(ip_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
else if (skb->protocol == htons(ETH_P_IPV6))
- dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
+ dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >>
+ GET_DSCP_PRI_OFFSET;
else
- return nic_dev->hw_dcb_cfg.default_cos;
- return nic_dev->hw_dcb_cfg.dscp2cos[dscp_cp];
+ return dcb->hw_dcb_cfg.default_cos;
+ return dcb->hw_dcb_cfg.dscp2cos[dscp_cp];
}
#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY)
@@ -867,11 +970,13 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif /* end of HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK */
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u16 txq;
u8 cos, qp_num;
if (test_bit(HINIC3_SAME_RXTX, &nic_dev->flags))
- return select_queue_by_hash_func(netdev, skb, netdev->real_num_tx_queues);
+ return select_queue_by_hash_func(netdev, skb,
+ netdev->real_num_tx_queues);
txq =
#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY)
@@ -887,18 +992,19 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (nic_dev->hw_dcb_cfg.trust == DCB_PCP) {
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP) {
if (skb->vlan_tci)
- cos = nic_dev->hw_dcb_cfg.pcp2cos[skb->vlan_tci >> VLAN_PRIO_SHIFT];
+ cos = dcb->hw_dcb_cfg.pcp2cos[skb->vlan_tci >>
+ VLAN_PRIO_SHIFT];
else
- cos = nic_dev->hw_dcb_cfg.default_cos;
+ cos = dcb->hw_dcb_cfg.default_cos;
} else {
cos = hinic3_get_dscp_up(nic_dev, skb);
}
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cos] ?
- txq % nic_dev->hw_dcb_cfg.cos_qp_num[cos] : 0;
- txq = nic_dev->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
+ qp_num = dcb->hw_dcb_cfg.cos_qp_num[cos] ?
+ txq % dcb->hw_dcb_cfg.cos_qp_num[cos] : 0;
+ txq = dcb->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
}
return txq;
@@ -976,7 +1082,7 @@ static struct net_device_stats *hinic3_get_stats(struct net_device *netdev)
stats->rx_packets = packets;
stats->rx_bytes = bytes;
stats->rx_errors = errors;
- stats->rx_dropped = dropped;
+ stats->rx_dropped = dropped + nic_dev->vport_stats.rx_discard_vport;
#ifndef HAVE_VOID_NDO_GET_STATS64
return stats;
@@ -1023,10 +1129,18 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
u32 mtu = (u32)new_mtu;
int err = 0;
+ int is_in_kexec = vram_get_kexec_flag();
#ifdef HAVE_XDP_SUPPORT
u32 xdp_max_mtu;
+#endif
+ if (is_in_kexec != 0) {
+ nicif_info(nic_dev, drv, netdev, "Hotreplace skip change mtu\n");
+ return err;
+ }
+
+#ifdef HAVE_XDP_SUPPORT
if (hinic3_is_xdp_enable(nic_dev)) {
xdp_max_mtu = hinic3_xdp_max_mtu(nic_dev);
if (mtu > xdp_max_mtu) {
@@ -1045,6 +1159,7 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
nicif_info(nic_dev, drv, nic_dev->netdev, "Change mtu from %u to %d\n",
netdev->mtu, new_mtu);
netdev->mtu = mtu;
+ nic_dev->nic_vram->vram_mtu = mtu;
}
return err;
@@ -1078,6 +1193,76 @@ static int hinic3_set_mac_addr(struct net_device *netdev, void *addr)
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+static int hinic3_udp_tunnel_port_config(struct net_device *netdev,
+ struct udp_tunnel_info *ti,
+ u8 action)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u16 func_id = hinic3_global_func_id(nic_dev->hwdev);
+ u16 dst_port;
+ int ret = 0;
+
+ switch (ti->type) {
+ case UDP_TUNNEL_TYPE_VXLAN:
+ dst_port = ntohs(ti->port);
+ ret = hinic3_vlxan_port_config(nic_dev->hwdev,
+ func_id, dst_port, action);
+ if (ret != 0) {
+ nicif_warn(nic_dev, drv, netdev,
+ "Failed to set vxlan port %u to device\n",
+ dst_port);
+ break;
+ }
+ nicif_info(nic_dev, link, netdev, "Vxlan dst port set to %u\n",
+ action == HINIC3_CMD_OP_ADD
+ ? dst_port : ntohs(VXLAN_OFFLOAD_PORT_LE));
+ break;
+ default:
+ nicif_err(nic_dev, drv, netdev, "Failed to add port, only vxlan dst port is supported\n");
+ ret = -EINVAL;
+ }
+ return ret;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+static void hinic3_udp_tunnel_add(struct net_device *netdev,
+ struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+static void hinic3_udp_tunnel_del(struct net_device *netdev,
+ struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD */
+
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev,
+ __always_unused unsigned int table,
+ __always_unused unsigned int entry,
+ struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev,
+ __always_unused unsigned int table,
+ __always_unused unsigned int entry,
+ struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static int
hinic3_vlan_rx_add_vid(struct net_device *netdev,
__always_unused __be16 proto,
@@ -1124,7 +1309,7 @@ hinic3_vlan_rx_kill_vid(struct net_device *netdev,
int err = 0;
col = VID_COL(nic_dev, vid);
- line = VID_LINE(nic_dev, vid);
+ line = (int)VID_LINE(nic_dev, vid);
/* In the broadcast scenario, ucode finds the corresponding function
* based on VLAN 0 of vlan table. If we delete VLAN 0, the VLAN function
@@ -1163,14 +1348,12 @@ static int hinic3_vlan_restore(struct net_device *netdev)
return -EFAULT;
rcu_read_lock();
for (i = 0; i < VLAN_N_VID; i++) {
-/* lint -e778 */
#ifdef HAVE_VLAN_FIND_DEV_DEEP_RCU
vlandev =
__vlan_find_dev_deep_rcu(netdev, htons(ETH_P_8021Q), i);
#else
vlandev = __vlan_find_dev_deep(netdev, htons(ETH_P_8021Q), i);
#endif
-/* lint +e778 */
col = VID_COL(nic_dev, i);
line = VID_LINE(nic_dev, i);
if (!vlandev && (vlan_bitmap[line] & (1UL << col)) != 0) {
@@ -1328,12 +1511,17 @@ static int set_feature_vlan_filter(struct hinic3_nic_dev *nic_dev,
return 0;
#ifdef NEED_VLAN_RESTORE
- if (en)
+ if (en) {
err = hinic3_vlan_restore(nic_dev->netdev);
+ if (err) {
+ hinic3_err(nic_dev, drv, "vlan restore failed\n");
+ *failed_features |= vlan_filter_feature;
+ return err;
+ }
+ }
#endif
- if (err == 0)
- err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
+ err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
if (err) {
hinic3_err(nic_dev, drv, "%s rx vlan filter failed\n",
SET_FEATURES_OP_STR(en));
@@ -1427,8 +1615,8 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
struct hinic3_nic_dev *adapter = netdev_priv(netdev);
int err;
- if (is_multicast_ether_addr(mac) || /*lint !e574*/
- vf >= pci_num_vf(adapter->pdev)) /*lint !e574*/
+ if (is_multicast_ether_addr(mac) ||
+ vf >= pci_num_vf(adapter->pdev))
return -EINVAL;
err = hinic3_set_vf_mac(adapter->hwdev, OS_VF_ID_TO_HW(vf), mac);
@@ -1446,7 +1634,6 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
return 0;
}
-/*lint -save -e574 -e734*/
#ifdef IFLA_VF_MAX
static int set_hw_vf_vlan(void *hwdev, u16 cur_vlanprio, int vf,
u16 vlan, u8 qos)
@@ -1529,7 +1716,8 @@ static int hinic3_ndo_set_vf_spoofchk(struct net_device *netdev, int vf,
#endif
#ifdef HAVE_NDO_SET_VF_TRUST
-static int hinic3_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting)
+static int hinic3_ndo_set_vf_trust(struct net_device *netdev, int vf,
+ bool setting)
{
struct hinic3_nic_dev *adapter = netdev_priv(netdev);
int err;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
index 11c1731..7288c5c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
@@ -10,6 +10,8 @@
#include "hinic3_common.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
/* ************************ array index define ********************* */
#define ARRAY_INDEX_0 0
@@ -21,6 +23,36 @@
#define ARRAY_INDEX_6 6
#define ARRAY_INDEX_7 7
+#define XSFP_TLV_PRE_INFO_LEN 4
+
+enum hinic3_link_port_type {
+ LINK_PORT_UNKNOWN,
+ LINK_PORT_OPTICAL_MM,
+ LINK_PORT_OPTICAL_SM,
+ LINK_PORT_PAS_COPPER,
+ LINK_PORT_ACC,
+ LINK_PORT_BASET,
+ LINK_PORT_AOC = 0x40,
+ LINK_PORT_ELECTRIC,
+ LINK_PORT_BACKBOARD_INTERFACE,
+};
+
+enum hilink_fibre_subtype {
+ FIBRE_SUBTYPE_SR = 1,
+ FIBRE_SUBTYPE_LR,
+ FIBRE_SUBTYPE_MAX,
+};
+
+enum hilink_fec_type {
+ HILINK_FEC_NOT_SET,
+ HILINK_FEC_RSFEC,
+ HILINK_FEC_BASEFEC,
+ HILINK_FEC_NOFEC,
+ HILINK_FEC_LLRSFE,
+ HILINK_FEC_MAX_TYPE,
+};
+
+
#define SQ_CI_ADDR_SHIFT 2
#define RQ_CI_ADDR_SHIFT 4
@@ -71,6 +103,12 @@ struct hinic3_port_routine_cmd {
struct mag_cmd_get_xsfp_present abs;
};
+struct hinic3_port_routine_cmd_extern {
+ bool mpu_send_xsfp_tlv_info;
+
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp std_xsfp_tlv_info;
+};
+
struct hinic3_nic_cfg {
struct semaphore cfg_lock;
@@ -84,11 +122,13 @@ struct hinic3_nic_cfg {
struct nic_port_info port_info;
/* percentage of pf link bandwidth */
- u32 pf_bw_limit;
- u32 rsvd2;
+ u32 pf_bw_tx_limit;
+ u32 pf_bw_rx_limit;
- struct hinic3_port_routine_cmd rt_cmd;
- struct mutex sfp_mutex; /* mutex used for copy sfp info */
+ struct hinic3_port_routine_cmd rt_cmd;
+ struct hinic3_port_routine_cmd_extern rt_cmd_ext;
+ /* mutex used for copy sfp info */
+ struct mutex sfp_mutex;
};
struct hinic3_nic_cmdq_ops;
@@ -98,7 +138,7 @@ struct hinic3_nic_io {
void *dev_hdl;
u8 link_status;
- u8 rsvd1;
+ u8 direct;
u32 rsvd2;
struct hinic3_io_queue *sq;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
index 747ac03..f136893 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
@@ -21,11 +21,132 @@
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_nic_cmdq.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_common.h"
#include "hinic3_nic_cfg.h"
-int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_sq_attr *attr)
+#include "vram_common.h"
+
+int hinic3_delete_bond(void *hwdev)
+{
+ struct hinic3_cmd_delete_bond cmd_delete_bond;
+ u16 out_size = sizeof(cmd_delete_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_delete_bond, 0, sizeof(cmd_delete_bond));
+ cmd_delete_bond.bond_id = HINIC3_INVALID_BOND_ID;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_DELETE,
+ &cmd_delete_bond, sizeof(cmd_delete_bond),
+ &cmd_delete_bond, &out_size);
+ if (err || !out_size || cmd_delete_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to delete bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_delete_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_delete_bond.bond_id != HINIC3_INVALID_BOND_ID)
+ nic_info(nic_io->dev_hdl, "Delete bond success\n");
+
+ return 0;
+}
+
+int hinic3_open_close_bond(void *hwdev, u32 bond_en)
+{
+ struct hinic3_cmd_open_close_bond cmd_open_close_bond;
+ u16 out_size = sizeof(cmd_open_close_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_open_close_bond, 0, sizeof(cmd_open_close_bond));
+ cmd_open_close_bond.open_close_bond_info.bond_id =
+ HINIC3_INVALID_BOND_ID;
+ cmd_open_close_bond.open_close_bond_info.open_close_flag = bond_en;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_OPEN_CLOSE,
+ &cmd_open_close_bond,
+ sizeof(cmd_open_close_bond),
+ &cmd_open_close_bond, &out_size);
+ if (err || !out_size || cmd_open_close_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to %s bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ bond_en == true ? "open" : "close", err,
+ cmd_open_close_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_open_close_bond.open_close_bond_info.bond_id !=
+ HINIC3_INVALID_BOND_ID) {
+ nic_info(nic_io->dev_hdl, "%s bond success\n", bond_en == true ? "Open" : "Close");
+ }
+
+ return 0;
+}
+
+int hinic3_create_bond(void *hwdev, u32 *bond_id)
+{
+ struct hinic3_cmd_create_bond cmd_create_bond;
+ u16 out_size = sizeof(cmd_create_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_create_bond, 0, sizeof(cmd_create_bond));
+ cmd_create_bond.create_bond_info.default_param_flag = true;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_CREATE,
+ &cmd_create_bond, sizeof(cmd_create_bond),
+ &cmd_create_bond, &out_size);
+ if (err || !out_size || cmd_create_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to create default bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_create_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_create_bond.create_bond_info.bond_id !=
+ HINIC3_INVALID_BOND_ID) {
+ *bond_id = cmd_create_bond.create_bond_info.bond_id;
+ nic_info(nic_io->dev_hdl, "Create bond success\n");
+ }
+
+ return 0;
+}
+
+int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io,
+ struct hinic3_sq_attr *attr)
{
struct hinic3_cmd_cons_idx_attr cons_idx_attr;
u16 out_size = sizeof(cons_idx_attr);
@@ -48,7 +169,8 @@ int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_sq_attr *at
cons_idx_attr.l2nic_sqn = attr->l2nic_sqn;
cons_idx_attr.ci_addr = attr->ci_dma_base >> SQ_CI_ADDR_SHIFT;
- err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_SQ_CI_ATTR_SET,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC3_NIC_CMD_SQ_CI_ATTR_SET,
&cons_idx_attr, sizeof(cons_idx_attr),
&cons_idx_attr, &out_size);
if (err || !out_size || cons_idx_attr.msg_head.status) {
@@ -61,7 +183,8 @@ int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_sq_attr *at
return 0;
}
-int hinic3_set_rq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_rq_attr *attr)
+int hinic3_set_rq_ci_ctx(struct hinic3_nic_io *nic_io,
+ struct hinic3_rq_attr *attr)
{
struct hinic3_rq_cqe_ctx cons_idx_ctx;
u16 out_size = sizeof(cons_idx_ctx);
@@ -76,15 +199,19 @@ int hinic3_set_rq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_rq_attr *at
cons_idx_ctx.timer_loop = attr->coalescing_time;
cons_idx_ctx.threshold_cqe_num = attr->pending_limit;
cons_idx_ctx.msix_entry_idx = attr->intr_idx;
- cons_idx_ctx.ci_addr_hi = upper_32_bits(attr->ci_dma_base >> RQ_CI_ADDR_SHIFT);
- cons_idx_ctx.ci_addr_lo = lower_32_bits(attr->ci_dma_base >> RQ_CI_ADDR_SHIFT);
+ cons_idx_ctx.ci_addr_hi = upper_32_bits(attr->ci_dma_base >>
+ RQ_CI_ADDR_SHIFT);
+ cons_idx_ctx.ci_addr_lo = lower_32_bits(attr->ci_dma_base >>
+ RQ_CI_ADDR_SHIFT);
- err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_SET_RQ_CI_CTX,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC3_NIC_CMD_SET_RQ_CI_CTX,
&cons_idx_ctx, sizeof(cons_idx_ctx),
&cons_idx_ctx, &out_size);
if (err || !out_size || cons_idx_ctx.msg_head.status) {
nic_err(nic_io->dev_hdl, "Set rq cqe ctx fail, qid: %d, err: %d, status: 0x%x, out_size: 0x%x",
- attr->l2nic_rqn, err, cons_idx_ctx.msg_head.status, out_size);
+ attr->l2nic_rqn, err,
+ cons_idx_ctx.msg_head.status, out_size);
return -EFAULT;
}
@@ -142,8 +269,8 @@ int hinic3_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
&mac_info, sizeof(mac_info),
&mac_info, &out_size, channel);
if (err || !out_size ||
- hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
- mac_info.vlan_id)) {
+ (hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
+ mac_info.vlan_id) != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, mac_info.msg_head.status, out_size, channel);
@@ -178,6 +305,8 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -193,7 +322,8 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
&mac_info, sizeof(mac_info), &mac_info,
&out_size, channel);
if (err || !out_size ||
- (mac_info.msg_head.status && !PF_SET_VF_MAC(hwdev, mac_info.msg_head.status))) {
+ (mac_info.msg_head.status &&
+ !PF_SET_VF_MAC(hwdev, mac_info.msg_head.status))) {
nic_err(nic_io->dev_hdl,
"Failed to delete MAC, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, mac_info.msg_head.status, out_size, channel);
@@ -223,6 +353,8 @@ int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -239,8 +371,8 @@ int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
&mac_info, sizeof(mac_info),
&mac_info, &out_size);
if (err || !out_size ||
- hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
- mac_info.vlan_id)) {
+ (hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
+ mac_info.vlan_id) != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x\n",
err, mac_info.msg_head.status, out_size);
@@ -273,6 +405,8 @@ int hinic3_get_default_mac(void *hwdev, u8 *mac_addr)
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
mac_info.func_id = hinic3_global_func_id(hwdev);
@@ -318,6 +452,44 @@ static int hinic3_config_vlan(struct hinic3_nic_io *nic_io, u8 opcode,
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action)
+{
+ struct hinic3_cmd_vxlan_port_info vxlan_port_info;
+ u16 out_size = sizeof(vxlan_port_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ memset(&vxlan_port_info, 0, sizeof(vxlan_port_info));
+ vxlan_port_info.opcode = action;
+ vxlan_port_info.cfg_mode = 0; // other tool set
+ vxlan_port_info.func_id = func_id;
+ vxlan_port_info.vxlan_port = port;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+ &vxlan_port_info, sizeof(vxlan_port_info), &vxlan_port_info, &out_size);
+ if (err || !out_size || vxlan_port_info.msg_head.status) {
+ if (vxlan_port_info.msg_head.status == 0x2) // other tool set failed
+ nic_warn(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port because it has already been set by hinicadm\n",
+ action == HINIC3_CMD_OP_ADD
+ ? "add" : "delete");
+ else
+ nic_err(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port, err: %d, status: 0x%x, out size: 0x%x\n",
+ action == HINIC3_CMD_OP_ADD ? "add" : "delete",
+ err, vxlan_port_info.msg_head.status, out_size);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
{
struct hinic3_nic_io *nic_io = NULL;
@@ -326,6 +498,8 @@ int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan_id, func_id);
}
@@ -337,6 +511,8 @@ int hinic3_del_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_DEL, vlan_id, func_id);
}
@@ -380,6 +556,8 @@ int hinic3_set_dcb_state(void *hwdev, struct hinic3_dcb_state *dcb_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (!memcmp(&nic_io->dcb_state, dcb_state, sizeof(nic_io->dcb_state)))
return 0;
@@ -423,7 +601,8 @@ int hinic3_get_cos_by_pri(void *hwdev, u8 pri, u8 *cos)
if (pri >= NIC_DCB_UP_MAX && nic_io->dcb_state.trust == HINIC3_DCB_PCP)
return -EINVAL;
- if (pri >= NIC_DCB_IP_PRI_MAX && nic_io->dcb_state.trust == HINIC3_DCB_DSCP)
+ if (pri >= NIC_DCB_IP_PRI_MAX &&
+ nic_io->dcb_state.trust == HINIC3_DCB_DSCP)
return -EINVAL;
/*lint -e662*/
@@ -541,13 +720,15 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_cfg = &nic_io->nic_cfg;
down(&nic_cfg->cfg_lock);
err = hinic3_cfg_hw_pause(nic_io, HINIC3_CMD_OP_SET, &nic_pause);
- if (err) {
+ if (err != 0) {
up(&nic_cfg->cfg_lock);
return err;
}
@@ -566,7 +747,6 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
{
- struct hinic3_nic_cfg *nic_cfg = NULL;
struct hinic3_nic_io *nic_io = NULL;
int err = 0;
@@ -574,17 +754,13 @@ int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- nic_cfg = &nic_io->nic_cfg;
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_hw_pause(nic_io, HINIC3_CMD_OP_GET, nic_pause);
- if (err)
+ if (err != 0)
return err;
- if (nic_cfg->pause_set || !nic_pause->auto_neg) {
- nic_pause->rx_pause = nic_cfg->nic_pause.rx_pause;
- nic_pause->tx_pause = nic_cfg->nic_pause.tx_pause;
- }
-
return 0;
}
@@ -599,6 +775,8 @@ int hinic3_sync_dcb_state(void *hwdev, u8 op_code, u8 state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&dcb_state, 0, sizeof(dcb_state));
@@ -607,7 +785,8 @@ int hinic3_sync_dcb_state(void *hwdev, u8 op_code, u8 state)
dcb_state.func_id = hinic3_global_func_id(hwdev);
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_QOS_DCB_STATE,
- &dcb_state, sizeof(dcb_state), &dcb_state, &out_size);
+ &dcb_state, sizeof(dcb_state),
+ &dcb_state, &out_size);
if (err || dcb_state.head.status || !out_size) {
nic_err(nic_io->dev_hdl,
"Failed to set dcb state, err: %d, status: 0x%x, out size: 0x%x\n",
@@ -675,7 +854,8 @@ int hinic3_cache_out_qps_res(void *hwdev)
qp_res.func_id = hinic3_global_func_id(hwdev);
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
- &qp_res, sizeof(qp_res), &qp_res, &out_size);
+ &qp_res, sizeof(qp_res),
+ &qp_res, &out_size);
if (err || !out_size || qp_res.msg_head.status) {
nic_err(nic_io->dev_hdl, "Failed to cache out qp resources, err: %d, status: 0x%x, out size: 0x%x\n",
err, qp_res.msg_head.status, out_size);
@@ -685,45 +865,8 @@ int hinic3_cache_out_qps_res(void *hwdev)
return 0;
}
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats)
-{
- struct hinic3_port_stats *port_stats = NULL;
- struct hinic3_port_stats_info stats_info;
- u16 out_size = sizeof(*port_stats);
- struct hinic3_nic_io *nic_io = NULL;
- int err;
-
- port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
- if (!port_stats)
- return -ENOMEM;
-
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
-
- memset(&stats_info, 0, sizeof(stats_info));
-
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_PORT_STAT,
- &stats_info, sizeof(stats_info),
- port_stats, &out_size);
- if (err || !out_size || port_stats->msg_head.status) {
- nic_err(nic_io->dev_hdl,
- "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
- err, port_stats->msg_head.status, out_size);
- err = -EIO;
- goto out;
- }
-
- memcpy(stats, &port_stats->stats, sizeof(*stats));
-
-out:
- kfree(port_stats);
-
- return err;
-}
-EXPORT_SYMBOL(hinic3_get_fpga_phy_port_stats);
-
-int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *stats)
+int hinic3_get_vport_stats(void *hwdev, u16 func_id,
+ struct hinic3_vport_stats *stats)
{
struct hinic3_port_stats_info stats_info;
struct hinic3_cmd_vport_stats vport_stats;
@@ -738,6 +881,8 @@ int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *
memset(&vport_stats, 0, sizeof(vport_stats));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
stats_info.func_id = func_id;
@@ -756,7 +901,8 @@ int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *
return 0;
}
-static int hinic3_set_function_table(struct hinic3_nic_io *nic_io, u32 cfg_bitmap,
+static int hinic3_set_function_table(struct hinic3_nic_io *nic_io,
+ u32 cfg_bitmap,
const struct hinic3_func_tbl_cfg *cfg)
{
struct hinic3_cmd_set_func_tbl cmd_func_tbl;
@@ -804,6 +950,8 @@ int hinic3_set_port_mtu(void *hwdev, u16 new_mtu)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (new_mtu < HINIC3_MIN_MTU_SIZE) {
nic_err(nic_io->dev_hdl,
@@ -834,6 +982,8 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&feature_nego, 0, sizeof(feature_nego));
feature_nego.func_id = hinic3_global_func_id(hwdev);
feature_nego.opcode = opcode;
@@ -855,29 +1005,24 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return 0;
}
-static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
+static int hinic3_get_bios_pf_bw_tx_limit(void *hwdev,
+ struct hinic3_nic_io *nic_io,
+ u16 func_id, u32 *pf_rate)
{
- struct hinic3_nic_io *nic_io = NULL;
+ int err = 0; // default success
struct nic_cmd_bios_cfg cfg = {{0}};
u16 out_size = sizeof(cfg);
- int err;
-
- if (!hwdev || !pf_bw_limit)
- return -EINVAL;
-
- if (hinic3_func_type(hwdev) == TYPE_VF || !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
- return 0;
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- cfg.bios_cfg.func_id = (u8)hinic3_global_func_id(hwdev);
+ cfg.bios_cfg.func_id = (u8)func_id;
cfg.bios_cfg.func_valid = 1;
- cfg.op_code = 0 | NIC_NVM_DATA_PF_SPEED_LIMIT;
+ cfg.op_code = 0 | NIC_NVM_DATA_PF_TX_SPEED_LIMIT;
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BIOS_CFG, &cfg, sizeof(cfg),
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BIOS_CFG,
+ &cfg, sizeof(cfg),
&cfg, &out_size);
if (err || !out_size || cfg.head.status) {
nic_err(nic_io->dev_hdl,
- "Failed to get bios pf bandwidth limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ "Failed to get bios pf bandwidth tx limit, err: %d, status: 0x%x, out size: 0x%x\n",
err, cfg.head.status, out_size);
return -EIO;
}
@@ -887,13 +1032,86 @@ static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
nic_warn(nic_io->dev_hdl, "Invalid bios configuration data, signature: 0x%x\n",
cfg.bios_cfg.signature);
- if (cfg.bios_cfg.pf_bw > MAX_LIMIT_BW) {
+ if (cfg.bios_cfg.pf_tx_bw > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
+ cfg.bios_cfg.pf_tx_bw);
+ return -EINVAL;
+ }
+
+ (*pf_rate) = cfg.bios_cfg.pf_tx_bw;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_rx_limit(void *hwdev,
+ struct hinic3_nic_io *nic_io,
+ u16 func_id, u32 *pf_rate)
+{
+ int err = 0; // default success
+ struct nic_rx_rate_bios_cfg rx_bios_conf = {{0}};
+ u16 out_size = sizeof(rx_bios_conf);
+
+ rx_bios_conf.func_id = (u8)func_id;
+ rx_bios_conf.op_code = 0; /* 1-save, 0-read */
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_RX_RATE_CFG,
+ &rx_bios_conf, sizeof(rx_bios_conf),
+ &rx_bios_conf, &out_size);
+ if (rx_bios_conf.msg_head.status == HINIC3_MGMT_CMD_UNSUPPORTED &&
+ err == 0) { // Compatible older firmware
+ nic_warn(nic_io->dev_hdl, "Not support get bios pf bandwidth rx limit\n");
+ return 0;
+ } else if (err || !out_size || rx_bios_conf.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get bios pf bandwidth rx limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, rx_bios_conf.msg_head.status, out_size);
+ return -EIO;
+ }
+ if (rx_bios_conf.rx_rate_limit > MAX_LIMIT_BW) {
nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
- cfg.bios_cfg.pf_bw);
+ rx_bios_conf.rx_rate_limit);
return -EINVAL;
}
- *pf_bw_limit = cfg.bios_cfg.pf_bw;
+ (*pf_rate) = rx_bios_conf.rx_rate_limit;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit, u8 direct)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u32 pf_rate = 0;
+ int err = 0;
+ u16 func_id;
+
+ func_id = hinic3_global_func_id(hwdev);
+
+ if (!hwdev || !pf_bw_limit)
+ return -EINVAL;
+
+ if (hinic3_func_type(hwdev) == TYPE_VF ||
+ !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
+ return 0;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (direct == HINIC3_NIC_TX)
+ err = hinic3_get_bios_pf_bw_tx_limit(hwdev, nic_io,
+ func_id, &pf_rate);
+ else if (direct == HINIC3_NIC_RX)
+ err = hinic3_get_bios_pf_bw_rx_limit(hwdev, nic_io,
+ func_id, &pf_rate);
+
+ if (err != 0)
+ return err;
+
+ if (pf_rate > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl,
+ "Invalid bios cfg pf bandwidth limit: %u\n", pf_rate);
+ return -EINVAL;
+ }
+
+ *pf_bw_limit = pf_rate;
return 0;
}
@@ -902,8 +1120,9 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
{
struct hinic3_cmd_tx_rate_cfg rate_cfg = {{0}};
struct hinic3_nic_io *nic_io = NULL;
+ u32 rate_limit;
u16 out_size = sizeof(rate_cfg);
- u32 pf_rate;
+ u32 pf_rate = 0;
int err;
u32 speed_convert[PORT_SPEED_UNKNOWN] = {
0, 10, 100, 1000, 10000, 25000, 40000, 50000, 100000, 200000
@@ -914,30 +1133,34 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
return -EINVAL;
if (speed_level >= PORT_SPEED_UNKNOWN) {
- nic_err(nic_io->dev_hdl, "Invalid speed level: %u\n", speed_level);
+ nic_err(nic_io->dev_hdl,
+ "Invalid speed level: %u\n", speed_level);
return -EINVAL;
}
- if (nic_io->nic_cfg.pf_bw_limit == MAX_LIMIT_BW) {
- pf_rate = 0;
- } else {
+ rate_limit = (nic_io->direct == HINIC3_NIC_TX) ?
+ nic_io->nic_cfg.pf_bw_tx_limit : nic_io->nic_cfg.pf_bw_rx_limit;
+ if (rate_limit != MAX_LIMIT_BW) {
/* divided by 100 to convert to percentage */
- pf_rate = (speed_convert[speed_level] / 100) * nic_io->nic_cfg.pf_bw_limit;
+ pf_rate = (speed_convert[speed_level] / 100) * rate_limit;
/* bandwidth limit is very small but not unlimit in this case */
- if (pf_rate == 0 && speed_level != PORT_SPEED_NOT_SET)
+ if ((pf_rate == 0) && (speed_level != PORT_SPEED_NOT_SET))
pf_rate = 1;
}
rate_cfg.func_id = hinic3_global_func_id(hwdev);
rate_cfg.min_rate = 0;
rate_cfg.max_rate = pf_rate;
+ rate_cfg.direct = nic_io->direct;
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_MAX_MIN_RATE, &rate_cfg,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
+ &rate_cfg,
sizeof(rate_cfg), &rate_cfg, &out_size);
if (err || !out_size || rate_cfg.msg_head.status) {
nic_err(nic_io->dev_hdl, "Failed to set rate(%u), err: %d, status: 0x%x, out size: 0x%x\n",
pf_rate, err, rate_cfg.msg_head.status, out_size);
- return rate_cfg.msg_head.status ? rate_cfg.msg_head.status : -EIO;
+ return rate_cfg.msg_head.status
+ ? rate_cfg.msg_head.status : -EIO;
}
return 0;
@@ -954,7 +1177,8 @@ int hinic3_set_nic_feature_to_hw(void *hwdev)
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- return nic_feature_nego(hwdev, HINIC3_CMD_OP_SET, &nic_io->feature_cap, 1);
+ return nic_feature_nego(hwdev, HINIC3_CMD_OP_SET,
+ &nic_io->feature_cap, 1);
}
u64 hinic3_get_feature_cap(void *hwdev)
@@ -962,6 +1186,8 @@ u64 hinic3_get_feature_cap(void *hwdev)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
return nic_io->feature_cap;
}
@@ -971,12 +1197,17 @@ void hinic3_update_nic_feature(void *hwdev, u64 s_feature)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
nic_io->feature_cap = s_feature;
- nic_info(nic_io->dev_hdl, "Update nic feature to 0x%llx\n", nic_io->feature_cap);
+ nic_info(nic_io->dev_hdl,
+ "Update nic feature to 0x%llx\n",
+ nic_io->feature_cap);
}
-static inline int init_nic_hwdev_param_valid(const void *hwdev, const void *pcidev_hdl,
+static inline int init_nic_hwdev_param_valid(const void *hwdev,
+ const void *pcidev_hdl,
const void *dev_hdl)
{
if (!hwdev || !pcidev_hdl || !dev_hdl)
@@ -1004,6 +1235,7 @@ static int hinic3_init_nic_io(void *hwdev, void *pcidev_hdl, void *dev_hdl,
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_abs = false;
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_info = false;
+ (*nic_io)->nic_cfg.rt_cmd_ext.mpu_send_xsfp_tlv_info = false;
return 0;
}
@@ -1020,27 +1252,34 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
{
struct hinic3_nic_io *nic_io = NULL;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
err = hinic3_init_nic_io(hwdev, pcidev_hdl, dev_hdl, &nic_io);
- if (err)
+ if (err != 0)
return err;
+ nic_io->rx_buff_len = rx_buff_len;
+
err = hinic3_register_service_adapter(hwdev, nic_io, SERVICE_T_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to register service adapter\n");
goto register_sa_err;
}
- err = hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 1, HINIC3_CHANNEL_NIC);
- if (err) {
+ err = hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC,
+ 1, HINIC3_CHANNEL_NIC);
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set function svc used state\n");
goto set_used_state_err;
}
- err = hinic3_init_function_table(nic_io);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to init function table\n");
- goto err_out;
+ if (is_in_kexec == 0) {
+ err = hinic3_init_function_table(nic_io);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to init function table\n");
+ goto err_out;
+ }
}
err = hinic3_get_nic_feature_from_hw(hwdev, &nic_io->feature_cap, 1);
@@ -1052,24 +1291,35 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
sdk_info(dev_hdl, "nic features: 0x%llx\n", nic_io->feature_cap);
hinic3_nic_cmdq_adapt_init(nic_io);
- err = hinic3_get_bios_pf_bw_limit(hwdev, &nic_io->nic_cfg.pf_bw_limit);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to get pf bandwidth limit\n");
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_tx_limit,
+ HINIC3_NIC_TX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf tx bandwidth limit\n");
+ goto err_out;
+ }
+
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_rx_limit,
+ HINIC3_NIC_RX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf rx bandwidth limit\n");
goto err_out;
}
err = hinic3_vf_func_init(nic_io);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to init vf info\n");
goto err_out;
}
- nic_io->rx_buff_len = rx_buff_len;
-
return 0;
err_out:
- hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 0, HINIC3_CHANNEL_NIC);
+ if (hinic3_set_func_svc_used_state(
+ hwdev, SVC_T_NIC, 0, HINIC3_CHANNEL_NIC) != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to set function svc used state\n");
+ }
set_used_state_err:
hinic3_unregister_service_adapter(hwdev, SERVICE_T_NIC);
@@ -1119,6 +1369,8 @@ int hinic3_force_drop_tx_pkt(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&pkt_drop, 0, sizeof(pkt_drop));
pkt_drop.port = hinic3_physical_port_id(hwdev);
@@ -1147,6 +1399,8 @@ int hinic3_set_rx_mode(void *hwdev, u32 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&rx_mode_cfg, 0, sizeof(rx_mode_cfg));
rx_mode_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1175,6 +1429,8 @@ int hinic3_set_rx_vlan_offload(void *hwdev, u8 en)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_cfg, 0, sizeof(vlan_cfg));
vlan_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1192,7 +1448,8 @@ int hinic3_set_rx_vlan_offload(void *hwdev, u8 en)
return 0;
}
-int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
+int hinic3_update_mac_vlan(void *hwdev, const u16 old_vlan,
+ u16 new_vlan, int vf_id)
{
struct vf_data_storage *vf_info = NULL;
struct hinic3_nic_io *nic_io = NULL;
@@ -1203,6 +1460,8 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
if (!nic_io->vf_infos || is_zero_ether_addr(vf_info->drv_mac_addr))
return 0;
@@ -1211,7 +1470,7 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
err = hinic3_del_mac(nic_io->hwdev, vf_info->drv_mac_addr,
old_vlan, func_id, HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to delete VF %d MAC %pM vlan %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->drv_mac_addr, old_vlan);
return err;
@@ -1219,7 +1478,7 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
err = hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
new_vlan, func_id, HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to add VF %d MAC %pM vlan %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->drv_mac_addr, new_vlan);
hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
@@ -1242,6 +1501,8 @@ static int hinic3_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en,
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_cfg, 0, sizeof(lro_cfg));
lro_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1273,6 +1534,8 @@ static int hinic3_set_rx_lro_timer(void *hwdev, u32 timer_value)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_timer, 0, sizeof(lro_timer));
lro_timer.opcode = HINIC3_CMD_OP_SET;
@@ -1305,12 +1568,14 @@ int hinic3_set_rx_lro_state(void *hwdev, u8 lro_en, u32 lro_timer,
ipv6_en = lro_en ? 1 : 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_info(nic_io->dev_hdl, "Set LRO max coalesce packet size to %uK\n",
lro_max_pkt_len);
err = hinic3_set_rx_lro(hwdev, ipv4_en, ipv6_en, (u8)lro_max_pkt_len);
- if (err)
+ if (err != 0)
return err;
/* we don't set LRO timer for VF */
@@ -1333,6 +1598,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_filter, 0, sizeof(vlan_filter));
vlan_filter.func_id = hinic3_global_func_id(hwdev);
@@ -1352,7 +1619,6 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
{
- // struct hinic_hwdev *dev = hwdev;
struct nic_cmd_capture_info cap_info = {{0}};
u16 out_size = sizeof(cap_info);
int err;
@@ -1361,7 +1627,6 @@ int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
return -EINVAL;
/* 2 function capture types */
- // cap_info.op_type = UP_UCAPTURE_OP_TYPE_FUNC;
cap_info.is_en_trx = cap_en;
cap_info.func_port = func_id;
@@ -1386,6 +1651,8 @@ int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (tcam_rule->index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to add is invalid\n");
return -EINVAL;
@@ -1421,6 +1688,8 @@ int hinic3_del_tcam_rule(void *hwdev, u32 index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to del is invalid\n");
return -EINVAL;
@@ -1470,6 +1739,8 @@ static int hinic3_mgmt_tcam_block(void *hwdev, u8 alloc_en, u16 *index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&tcam_block_info, 0,
sizeof(struct nic_cmd_ctrl_tcam_block_out));
@@ -1515,6 +1786,8 @@ int hinic3_set_fdir_tcam_rule_filter(void *hwdev, bool enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
port_tcam_cmd.func_id = hinic3_global_func_id(hwdev);
port_tcam_cmd.tcam_enable = (u8)enable;
@@ -1543,6 +1816,8 @@ int hinic3_flush_tcam_rule(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&tcam_flush, 0, sizeof(struct nic_cmd_flush_tcam_rules));
tcam_flush.func_id = hinic3_global_func_id(hwdev);
@@ -1560,7 +1835,8 @@ int hinic3_flush_tcam_rule(void *hwdev)
return 0;
}
-int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type)
+int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info,
+ u16 num_qps, u16 wqe_type)
{
struct hinic3_cmd_buf *cmd_buf = NULL;
struct hinic3_nic_io *nic_io = NULL;
@@ -1573,6 +1849,8 @@ int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -1587,9 +1865,11 @@ int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
cmd_buf->size = sizeof(struct hinic3_rxq_hw);
- err = hinic3_cmdq_detail_resp(hwdev, HINIC3_MOD_L2NIC, HINIC3_UCODE_CMD_RXQ_INFO_GET,
- cmd_buf, cmd_buf, NULL, 0, HINIC3_CHANNEL_NIC);
- if (err)
+ err = hinic3_cmdq_detail_resp(hwdev, HINIC3_MOD_L2NIC,
+ HINIC3_UCODE_CMD_RXQ_INFO_GET,
+ cmd_buf, cmd_buf, NULL, 0,
+ HINIC3_CHANNEL_NIC);
+ if (err != 0)
goto get_rxq_info_failed;
rxq_info_out = cmd_buf->buf;
@@ -1604,7 +1884,8 @@ get_rxq_info_failed:
return err;
}
-int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_state)
+int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced,
+ bool link_state)
{
struct hinic3_nic_io *nic_io = NULL;
struct vf_data_storage *vf_infos = NULL;
@@ -1615,8 +1896,10 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return -EINVAL;
}
- if (hinic3_func_type(hwdev) == TYPE_VF)
+ if (hinic3_func_type(hwdev) == TYPE_VF) {
+ pr_err("VF are not supported to set link state.\n");
return -EINVAL;
+ }
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
if (!nic_io) {
@@ -1633,3 +1916,35 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return 0;
}
EXPORT_SYMBOL(hinic3_pf_set_vf_link_state);
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid)
+{
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ u16 out_size = sizeof(outband_cfg_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !outband_default_vid)
+ return -EINVAL;
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_OUTBAND_CFG,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size);
+ if (err || !out_size || outband_cfg_info.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get outband cfg, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, outband_cfg_info.msg_head.status, out_size);
+ return -EINVAL;
+ }
+
+ *outband_default_vid = outband_cfg_info.outband_default_vid;
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
index dd2c2fd..e0350e3 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
@@ -7,9 +7,10 @@
#include <linux/types.h>
#include <linux/netdevice.h>
-#include "hinic3_mgmt_interface.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
+#include "nic_cfg_comm.h"
+#include "nic_mpu_cmd_defs.h"
#define OS_VF_ID_TO_HW(os_vf_id) ((os_vf_id) + 1)
#define HW_VF_ID_TO_OS(hw_vf_id) ((hw_vf_id) - 1)
@@ -54,6 +55,8 @@
#define MAX_LIMIT_BW 100
+#define HINIC3_INVALID_BOND_ID 0xffffffff
+
enum hinic3_valid_link_settings {
HILINK_LINK_SET_SPEED = 0x1,
HILINK_LINK_SET_AUTONEG = 0x2,
@@ -67,6 +70,11 @@ enum hinic3_link_follow_status {
HINIC3_LINK_FOLLOW_STATUS_MAX,
};
+enum hinic3_nic_pf_direct {
+ HINIC3_NIC_RX = 0,
+ HINIC3_NIC_TX,
+};
+
struct hinic3_link_ksettings {
u32 valid_bitmap;
u8 speed; /* enum nic_speed_level */
@@ -152,8 +160,12 @@ struct nic_port_info {
u8 duplex;
u8 speed;
u8 fec;
+ u8 lanes;
+ u8 rsvd;
u32 supported_mode;
u32 advertised_mode;
+ u32 supported_fec_mode;
+ u32 bond_speed;
};
struct nic_pause_config {
@@ -178,11 +190,17 @@ struct hinic3_rxq_hw {
#define MODULE_TYPE_QSFP28 0x11
#define MODULE_TYPE_QSFP 0x0C
#define MODULE_TYPE_QSFP_PLUS 0x0D
+#define MODULE_TYPE_DSFP 0x1B
+#define MODULE_TYPE_QSFP_CMIS 0x1E
#define TCAM_IP_TYPE_MASK 0x1
#define TCAM_TUNNEL_TYPE_MASK 0xF
#define TCAM_FUNC_ID_MASK 0x7FFF
+int hinic3_delete_bond(void *hwdev);
+int hinic3_open_close_bond(void *hwdev, u32 bond_en);
+int hinic3_create_bond(void *hwdev, u32 *bond_id);
+
int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule);
int hinic3_del_tcam_rule(void *hwdev, u32 index);
@@ -335,7 +353,7 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr);
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr);
/* *
* @brief hinic3_vf_info_vlanprio - get vf vlan priority
@@ -510,7 +528,14 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table);
*/
int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats);
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats);
+/* *
+ * @brief hinic3_get_phy_rsfec_stats - get rsfec stats
+ * @param hwdev: device pointer to hwdev
+ * @param stats: rsfec(Reed-Solomon Forward Error Correction) stats
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats);
int hinic3_set_port_funcs_state(void *hwdev, bool enable);
@@ -546,6 +571,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl);
void hinic3_clear_vfs_info(void *hwdev);
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id);
+
int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id);
int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
@@ -565,9 +592,13 @@ int hinic3_set_autoneg(void *hwdev, bool enable);
int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext);
int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len);
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len);
bool hinic3_if_sfp_absent(void *hwdev);
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info);
+int hinic3_get_sfp_tlv_info(void *hwdev,
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info,
+ const struct tag_mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req);
/* *
* @brief hinic3_set_nic_feature_to_hw - sync nic feature to hardware
@@ -620,4 +651,19 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level);
int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type);
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+/* *
+ * @brief hinic3_vlxan_port_config - add/del vxlan dst port
+ * @param hwdev: device pointer to hwdev
+ * @param func_id: function id
+ * @param port: vxlan dst port
+ * @param action: add or del, del will set to default value (0x12B5)
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action);
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
index 15d081b..c0e0a61 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
@@ -22,7 +22,8 @@
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_nic_cmdq.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
/*lint -e806*/
static unsigned char set_vf_link_state;
@@ -59,7 +60,8 @@ static int hinic3_set_vlan_ctx(struct hinic3_nic_io *nic_io, u16 func_id,
vlan_tag, q_id, vlan_mode);
err = hinic3_cmdq_direct_resp(nic_io->hwdev, HINIC3_MOD_L2NIC,
- cmd, cmd_buf, &out_param, 0, HINIC3_CHANNEL_NIC);
+ cmd, cmd_buf, &out_param,
+ 0, HINIC3_CHANNEL_NIC);
hinic3_free_cmd_buf(nic_io->hwdev, cmd_buf);
@@ -108,7 +110,7 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
err = hinic3_set_vlan_ctx(nic_io, glb_func_id, vlan_tag,
NIC_CONFIG_ALL_QUEUE_VLAN_CTX,
opcode == HINIC3_CMD_OP_ADD);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d vlan ctx, err: %d\n",
HW_VF_ID_TO_OS(vf_id), err);
@@ -129,12 +131,15 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
/* this function just be called by hinic3_ndo_set_vf_mac,
* others are not permitted.
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr)
{
- struct vf_data_storage *vf_info;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_info = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
#ifndef __VMWARE__
/* duplicate request, so just return success */
@@ -152,13 +157,15 @@ int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan, qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan = vlan;
@@ -172,17 +179,19 @@ int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
vf_infos = nic_io->vf_infos;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_DEL,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_info(nic_io->dev_hdl, "Remove VLAN %u on VF %d\n",
@@ -197,11 +206,13 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
u16 hinic3_vf_info_vlanprio(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
u16 pf_vlan, vlanprio;
u8 pf_qos;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
pf_vlan = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan;
pf_qos = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos;
@@ -214,9 +225,14 @@ int hinic3_set_vf_link_state(void *hwdev, u16 vf_id, int link)
{
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ struct vf_data_storage *vf_infos = NULL;
u8 link_status = 0;
+ if (!nic_io)
+ return -EINVAL;
+
+ vf_infos = nic_io->vf_infos;
+
switch (link) {
case HINIC3_IFLA_VF_LINK_STATE_AUTO:
vf_infos[HW_VF_ID_TO_OS(vf_id)].link_forced = false;
@@ -256,6 +272,8 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
vf_infos = nic_io->vf_infos;
memset(&spoofchk_cfg, 0, sizeof(spoofchk_cfg));
@@ -280,9 +298,11 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
bool hinic3_vf_info_spoofchk(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].spoofchk;
}
@@ -296,7 +316,7 @@ int hinic3_set_vf_trust(void *hwdev, u16 vf_id, bool trust)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
+ if (!nic_io || vf_id > nic_io->max_vfs)
return -EINVAL;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust = trust;
@@ -309,11 +329,11 @@ bool hinic3_get_vf_trust(void *hwdev, int vf_id)
struct hinic3_nic_io *nic_io = NULL;
if (!hwdev)
- return -EINVAL;
+ return false;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
- return -EINVAL;
+ if (!nic_io || vf_id > nic_io->max_vfs)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust;
}
@@ -331,6 +351,7 @@ static int hinic3_set_vf_tx_rate_max_min(struct hinic3_nic_io *nic_io,
rate_cfg.func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf_id;
rate_cfg.max_rate = max_rate;
rate_cfg.min_rate = min_rate;
+ rate_cfg.direct = HINIC3_NIC_TX;
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
&rate_cfg, sizeof(rate_cfg), &rate_cfg,
@@ -351,13 +372,15 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (!HINIC3_SUPPORT_RATE_LIMIT(hwdev)) {
nic_err(nic_io->dev_hdl, "Current function doesn't support to set vf rate limit\n");
return -EOPNOTSUPP;
}
err = hinic3_set_vf_tx_rate_max_min(nic_io, vf_id, max_rate, min_rate);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].max_rate = max_rate;
@@ -368,12 +391,16 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
void hinic3_get_vf_config(void *hwdev, u16 vf_id, struct ifla_vf_info *ivi)
{
- struct vf_data_storage *vfinfo;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vfinfo = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
vfinfo = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vfinfo)
+ return;
ivi->vf = HW_VF_ID_TO_OS(vf_id);
ether_addr_copy(ivi->mac, vfinfo->user_mac_addr);
@@ -446,13 +473,15 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
int err;
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
- nic_io->hwdev, hinic3_vf_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_vf_event_handler);
+ if (err != 0)
return err;
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
- nic_io->hwdev, hinic3_vf_mag_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_vf_mag_event_handler);
+ if (err != 0)
goto reg_hilink_err;
memset(®ister_info, 0, sizeof(register_info));
@@ -464,6 +493,11 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
®ister_info, &out_size, 0,
HINIC3_CHANNEL_NIC);
if (err || !out_size || register_info.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev)) {
+ nic_warn(nic_io->dev_hdl, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, register_info.msg_head.status, out_size);
+ return 0;
+ }
nic_err(nic_io->dev_hdl, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
err, register_info.msg_head.status, out_size);
err = -EIO;
@@ -498,18 +532,20 @@ static int pf_init_vf_infos(struct hinic3_nic_io *nic_io)
for (i = 0; i < nic_io->max_vfs; i++) {
err = hinic3_init_vf_infos(nic_io, i);
- if (err)
+ if (err != 0)
goto init_vf_infos_err;
}
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
- nic_io->hwdev, hinic3_pf_mbox_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_mbox_handler);
+ if (err != 0)
goto register_pf_mbox_cb_err;
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
- nic_io->hwdev, hinic3_pf_mag_mbox_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_mag_mbox_handler);
+ if (err != 0)
goto register_pf_mag_mbox_cb_err;
return 0;
@@ -531,17 +567,19 @@ int hinic3_vf_func_init(struct hinic3_nic_io *nic_io)
return vf_func_register(nic_io);
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
- nic_io->hwdev, hinic3_pf_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_event_handler);
+ if (err != 0)
return err;
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
- nic_io->hwdev, hinic3_pf_mag_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_mag_event_handler);
+ if (err != 0)
goto register_mgmt_msg_cb_err;
err = pf_init_vf_infos(nic_io);
- if (err)
+ if (err != 0)
goto pf_init_vf_infos_err;
return 0;
@@ -568,17 +606,24 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
&unregister, sizeof(unregister),
&unregister, &out_size, 0,
HINIC3_CHANNEL_NIC);
- if (err || !out_size || unregister.msg_head.status)
- nic_err(nic_io->dev_hdl, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
- err, unregister.msg_head.status, out_size);
-
+ if (err || !out_size || unregister.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev)) {
+ nic_info(nic_io->dev_hdl, "vRoCE VF notify PF unsuccessful is allowed");
+ } else {
+ nic_err(nic_io->dev_hdl, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, unregister.msg_head.status, out_size);
+ }
+ }
hinic3_unregister_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
} else {
if (nic_io->vf_infos) {
- hinic3_unregister_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK);
- hinic3_unregister_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
+ hinic3_unregister_pf_mbox_cb(nic_io->hwdev,
+ HINIC3_MOD_HILINK);
+ hinic3_unregister_pf_mbox_cb(nic_io->hwdev,
+ HINIC3_MOD_L2NIC);
hinic3_clear_vfs_info(nic_io->hwdev);
kfree(nic_io->vf_infos);
+ nic_io->vf_infos = NULL;
}
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
@@ -587,11 +632,15 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
static void clear_vf_infos(void *hwdev, u16 vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
u16 func_id;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
func_id = hinic3_glb_pf_vf_offset(hwdev) + vf_id;
vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
@@ -620,10 +669,59 @@ static void clear_vf_infos(void *hwdev, u16 vf_id)
void hinic3_clear_vfs_info(void *hwdev)
{
+ u16 i;
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- u16 i;
+
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
for (i = 0; i < nic_io->max_vfs; i++)
clear_vf_infos(hwdev, OS_VF_ID_TO_HW(i));
}
+
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id)
+{
+ int err = 0;
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ struct vf_data_storage *vf_infos = NULL;
+ u16 out_size = sizeof(outband_cfg_info);
+ u16 vf_id;
+ struct hinic3_nic_io *nic_io =
+ hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return 0;
+ }
+
+ vf_id = func_id - hinic3_glb_pf_vf_offset(nic_io->hwdev);
+ vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+ if (vf_infos->registered) {
+ outband_cfg_info.func_id = func_id;
+ outband_cfg_info.outband_default_vid = vlan_id;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_L2NIC,
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return 0;
+ }
+ if (err || !out_size || outband_cfg_info.msg_head.status)
+ nic_err(nic_io->dev_hdl,
+ "outband cfg event to VF %d failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err,
+ outband_cfg_info.msg_head.status, out_size);
+ }
+
+ return err;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
index 0ec4b32..b45c875 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
@@ -30,6 +30,8 @@ int hinic3_dbg_get_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (q_id >= nic_io->num_qps) {
pr_err("q_id[%u] > num_qps_cfg[%u].\n", q_id, nic_io->num_qps);
return -EINVAL;
@@ -69,6 +71,8 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -82,6 +86,8 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
sq = &nic_io->sq[q_id];
+ if (!sq)
+ return -EINVAL;
sq_info->q_id = q_id;
sq_info->pi = hinic3_get_sq_local_pi(sq);
@@ -112,6 +118,8 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -125,6 +133,8 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
rq = &nic_io->rq[q_id];
+ if (!rq)
+ return -EINVAL;
rq_info->q_id = q_id;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
index e76a66b..38aa8f7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
@@ -15,9 +15,10 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
#include "hinic3_dcb.h"
+#include "vram_common.h"
#define HINIC3_NIC_DRV_NAME "hinic3"
-#define HINIC3_NIC_DRV_VERSION HINIC3_DRV_VERSION
+#define HINIC3_NIC_DRV_VERSION "17.7.8.1"
#define HINIC3_FUNC_IS_VF(hwdev) (hinic3_func_type(hwdev) == TYPE_VF)
@@ -25,6 +26,10 @@
#define HINIC3_MODERATONE_DELAY HZ
#define LP_PKT_CNT 64
+#define LP_PKT_LEN 60
+
+#define NAPI_IS_REGIN 1
+#define NAPI_NOT_REGIN 0
enum hinic3_flags {
HINIC3_INTF_UP,
@@ -91,6 +96,8 @@ struct hinic3_irq {
u16 rsvd1;
u32 irq_id; /* The IRQ number from OS */
+ u32 napi_reign;
+
char irq_name[IFNAMSIZ + 16];
struct napi_struct napi;
cpumask_t affinity_mask;
@@ -123,6 +130,41 @@ struct hinic3_dyna_txrxq_params {
struct hinic3_dyna_txq_res *txqs_res;
struct hinic3_dyna_rxq_res *rxqs_res;
struct hinic3_irq *irq_cfg;
+ char irq_cfg_vram_name[VRAM_NAME_MAX_LEN];
+};
+
+struct hinic3_flush_rq {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 lb_proc : 1;
+ u32 rsvd : 10;
+ u32 rq_id : 8;
+ u32 func_id : 13;
+#else
+ u32 func_id : 13;
+ u32 rq_id : 8;
+ u32 rsvd : 10;
+ u32 lb_proc : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd2 : 2;
+ u32 src_chnl : 12;
+ u32 pkt_len : 18;
+#else
+ u32 pkt_len : 18;
+ u32 src_chnl : 12;
+ u32 rsvd2 : 2;
+#endif
+ } bs;
+ u32 value;
+ } lb_info0; /* loop back information, used by uCode */
};
#define HINIC3_NIC_STATS_INC(nic_dev, field) \
@@ -147,6 +189,11 @@ struct hinic3_nic_stats {
#endif
};
+struct hinic3_nic_vport_stats {
+ u64 rx_discard_vport;
+};
+
+
#define HINIC3_TCAM_DYNAMIC_BLOCK_SIZE 16
#define HINIC3_MAX_TCAM_FILTERS 512
@@ -185,6 +232,29 @@ struct hinic3_tcam_info {
struct hinic3_tcam_dynamic_block_info tcam_dynamic_info;
};
+struct hinic3_dcb {
+ u8 cos_config_num_max;
+ u8 func_dft_cos_bitmap;
+ /* used to tool validity check */
+ u16 port_dft_cos_bitmap;
+
+ struct hinic3_dcb_config hw_dcb_cfg;
+ struct hinic3_dcb_config wanted_dcb_cfg;
+ unsigned long dcb_flags;
+};
+
+struct hinic3_vram {
+ u32 vram_mtu;
+ u16 vram_num_qps;
+ unsigned long flags;
+};
+
+struct hinic3_outband_cfg {
+ u16 outband_default_vid;
+ u16 rsvd;
+};
+
+
struct hinic3_nic_dev {
struct pci_dev *pdev;
struct net_device *netdev;
@@ -204,6 +274,7 @@ struct hinic3_nic_dev {
u32 dma_rx_buff_size;
u16 rx_buff_len;
u32 page_order;
+ bool page_pool_enabled;
/* Rss related varibles */
u8 rss_hash_engine;
@@ -213,17 +284,13 @@ struct hinic3_nic_dev {
u32 *rss_hkey_be;
u32 *rss_indir;
- u8 cos_config_num_max;
- u8 func_dft_cos_bitmap;
- u16 port_dft_cos_bitmap; /* used to tool validity check */
+ struct hinic3_dcb *dcb;
+ char dcb_name[VRAM_NAME_MAX_LEN];
+
+ struct hinic3_vram *nic_vram;
+ char nic_vram_name[VRAM_NAME_MAX_LEN];
- struct hinic3_dcb_config hw_dcb_cfg;
- struct hinic3_dcb_config wanted_dcb_cfg;
- struct hinic3_dcb_config dcb_cfg;
- unsigned long dcb_flags;
int disable_port_cnt;
- /* lock for disable or enable traffic flow */
- struct semaphore dcb_sem;
struct hinic3_intr_coal_info *intr_coalesce;
unsigned long last_moder_jiffies;
@@ -235,11 +302,10 @@ struct hinic3_nic_dev {
#endif
struct hinic3_nic_stats stats;
+ struct hinic3_nic_vport_stats vport_stats;
/* lock for nic resource */
struct mutex nic_mutex;
- bool force_port_disable;
- struct semaphore port_state_sem;
u8 link_status;
struct nic_service_cap nic_cap;
@@ -281,9 +347,10 @@ struct hinic3_nic_dev {
struct hinic3_nic_prof_attr *prof_attr;
struct hinic3_prof_adapter *prof_adap;
u64 rsvd8[7];
- u32 rsvd9;
+ struct hinic3_outband_cfg outband_cfg;
u32 rxq_get_err_times;
struct delayed_work rxq_check_work;
+ struct delayed_work vport_stats_work;
struct hinic3_tx_rx_ops tx_rx_ops;
};
@@ -312,7 +379,7 @@ struct hinic3_uld_info *get_nic_uld_info(void);
u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev);
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
int hinic3_open(struct net_device *netdev);
@@ -331,6 +398,8 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev);
void hinic3_qps_irq_deinit(struct hinic3_nic_dev *nic_dev);
+void qp_del_napi(struct hinic3_irq *irq_cfg);
+
void hinic3_set_netdev_ops(struct hinic3_nic_dev *nic_dev);
bool hinic3_is_netdev_ops_match(const struct net_device *netdev);
@@ -348,10 +417,6 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
int hinic3_get_sset_count(struct net_device *netdev, int sset);
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev);
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
#ifdef ETHTOOL_GLINKSETTINGS
@@ -386,5 +451,18 @@ bool hinic3_is_xdp_enable(struct hinic3_nic_dev *nic_dev);
int hinic3_xdp_max_mtu(struct hinic3_nic_dev *nic_dev);
#endif
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+int set_fecparam(void *hwdev, u8 fecparam);
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec);
+#endif
+
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
index 57cf07c..c53c125 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
@@ -21,11 +21,12 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
{
- struct vf_data_storage *vf_info;
+ struct vf_data_storage *vf_info = NULL;
u16 func_id;
int err = 0;
@@ -38,7 +39,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
vf_info->pf_vlan, func_id,
HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d MAC\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -51,7 +52,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD,
vf_info->pf_vlan, vf_info->pf_qos,
vf_id);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to add VF %d VLAN_QOS\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -62,7 +63,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_vf_tx_rate(nic_io->hwdev, vf_id,
vf_info->max_rate,
vf_info->min_rate);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d max rate %u, min rate %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->max_rate,
vf_info->min_rate);
@@ -84,7 +85,7 @@ static int register_vf_msg_handler(struct hinic3_nic_io *nic_io, u16 vf_id)
}
err = hinic3_init_vf_config(nic_io, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].registered = true;
@@ -137,6 +138,9 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
int err;
+ if (!vf_info)
+ return -EINVAL;
+
if (register_vf->op_register) {
vf_info->support_extra_feature = register_vf->support_extra_feature;
err = register_vf_msg_handler(nic_io, vf_id);
@@ -145,7 +149,7 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
vf_info->support_extra_feature = 0;
}
- if (err)
+ if (err != 0)
register_info->msg_head.status = EFAULT;
*out_size = sizeof(*register_info);
@@ -157,6 +161,8 @@ void hinic3_unregister_vf(struct hinic3_nic_io *nic_io, u16 vf_id)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vf_info)
+ return;
unregister_vf_msg_handler(nic_io, vf_id);
vf_info->support_extra_feature = 0;
}
@@ -181,14 +187,21 @@ static int hinic3_get_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
void *buf_out, u16 *out_size)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf);
+ struct hinic3_port_mac_set *mac_in =
+ (struct hinic3_port_mac_set *)buf_in;
struct hinic3_port_mac_set *mac_info = buf_out;
int err;
+ if (!mac_info || !vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (HINIC3_SUPPORT_VF_MAC(nic_io->hwdev)) {
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_GET_MAC, buf_in,
in_size, buf_out, out_size);
- if (!err) {
+ if (err == 0) {
if (is_zero_ether_addr(mac_info->mac))
ether_addr_copy(mac_info->mac, vf_info->drv_mac_addr);
}
@@ -211,6 +224,11 @@ static int hinic3_set_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -247,6 +265,10 @@ static int hinic3_del_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -283,10 +305,13 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
struct hinic3_port_mac_update *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
if (!is_valid_ether_addr(mac_in->new_mac)) {
nic_err(nic_io->dev_hdl, "Update VF MAC is invalid.\n");
return -EINVAL;
}
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
#ifndef __VMWARE__
if (vf_info->use_specified_mac && !vf_info->trust) {
@@ -301,7 +326,7 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
HW_VF_ID_TO_OS(vf),
HINIC_CFG_VF_MAC_CHANGED,
(void *)mac_in->new_mac);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to config VF %d MAC request, err: %d\n",
HW_VF_ID_TO_OS(vf), err);
return err;
@@ -359,10 +384,11 @@ static int _l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u16 in_size, void *buf_out, u16 *out_size,
u16 channel)
{
- u32 i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
+ int i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_cmd_handler[i].cmd)
cmd_to_pf = true;
@@ -397,13 +423,15 @@ int hinic3_pf_mbox_handler(void *hwdev,
u16 vf_id, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- u32 index, cmd_size = ARRAY_LEN(vf_cmd_handler);
+ int index, cmd_size = ARRAY_LEN(vf_cmd_handler);
struct hinic3_nic_io *nic_io = NULL;
if (!hwdev)
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (index = 0; index < cmd_size; index++) {
if (cmd == vf_cmd_handler[index].cmd)
@@ -460,10 +488,14 @@ void hinic3_notify_dcb_state_event(struct hinic3_nic_io *nic_io,
static void dcb_state_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- struct hinic3_cmd_vf_dcb_state *vf_dcb;
- struct hinic3_nic_io *nic_io;
+ struct hinic3_cmd_vf_dcb_state *vf_dcb = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
vf_dcb = buf_in;
if (!vf_dcb)
@@ -479,6 +511,10 @@ static void tx_pause_excp_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*excp_info)) {
nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
@@ -501,6 +537,10 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_event_info event_info = {0};
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*active_info)) {
nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
@@ -515,6 +555,36 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
hinic3_event_callback(nic_io->hwdev, &event_info);
}
+static void outband_vlan_cfg_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out,
+ u16 *out_size)
+{
+ struct hinic3_outband_cfg_info *outband_cfg_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info = {0};
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ nic_info(nic_io->dev_hdl, "outband vlan cfg event received\n");
+
+ if (in_size != sizeof(*outband_cfg_info)) {
+ nic_err(nic_io->dev_hdl, "outband cfg info invalid in_size: %u, should be %lu\n",
+ in_size, sizeof(*outband_cfg_info));
+ return;
+ }
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = EVENT_NIC_OUTBAND_CFG;
+ memcpy((void *)event_info.event_data,
+ outband_cfg_info, sizeof(*outband_cfg_info));
+
+ hinic3_event_callback(nic_io->hwdev, &event_info);
+}
+
static const struct nic_event_handler nic_cmd_handler[] = {
{
.cmd = HINIC3_NIC_CMD_VF_COS,
@@ -529,6 +599,11 @@ static const struct nic_event_handler nic_cmd_handler[] = {
.cmd = HINIC3_NIC_CMD_BOND_ACTIVE_NOTICE,
.handler = bond_active_event_handler,
},
+
+ {
+ .cmd = HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ .handler = outband_vlan_cfg_event_handler,
+ },
};
static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
@@ -543,6 +618,8 @@ static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (i = 0; i < size; i++) {
if (cmd == nic_cmd_handler[i].cmd) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
index a827f44..f3bb4c5 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
@@ -16,9 +16,10 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
-#include "hinic3_nic_io.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_nic_cmdq.h"
+#include "hinic3_nic_io.h"
#define HINIC3_DEAULT_TX_CI_PENDING_LIMIT 1
#define HINIC3_DEAULT_TX_CI_COALESCING_TIME 1
@@ -35,7 +36,7 @@ MODULE_PARM_DESC(tx_coalescing_time, "TX CI coalescing parameter coalescing_time
static unsigned char rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
module_param(rq_wqe_type, byte, 0444);
-MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 0-8Bytes, 1-16Bytes, 2-32Bytes (default=1)");
+MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 1-16Bytes, 2-32Bytes (default=2)");
/*lint +e806*/
static u32 tx_drop_thd_on = HINIC3_DEAULT_DROP_THD_ON;
@@ -46,7 +47,7 @@ static u32 tx_drop_thd_off = HINIC3_DEAULT_DROP_THD_OFF;
module_param(tx_drop_thd_off, uint, 0644);
MODULE_PARM_DESC(tx_drop_thd_off, "TX parameter drop_thd_off (default=0)");
/* performance: ci addr RTE_CACHE_SIZE(64B) alignment */
-#define HINIC3_CI_Q_ADDR_SIZE (64)
+#define HINIC3_CI_Q_ADDR_SIZE (64U)
#define CI_TABLE_SIZE(num_qps, pg_sz) \
(ALIGN((num_qps) * HINIC3_CI_Q_ADDR_SIZE, pg_sz))
@@ -255,7 +256,7 @@ static int hinic3_create_sq(struct hinic3_nic_io *nic_io, struct hinic3_io_queue
err = hinic3_wq_create(nic_io->hwdev, &sq->wq, sq_depth,
(u16)BIT(HINIC3_SQ_WQEBB_SHIFT));
- if (err) {
+ if (err != 0) {
sdk_err(nic_io->dev_hdl, "Failed to create tx queue(%u) wq\n",
q_id);
return err;
@@ -291,13 +292,22 @@ static int hinic3_create_rq(struct hinic3_nic_io *nic_io, struct hinic3_io_queue
{
int err;
- rq->wqe_type = (u8)(hinic3_get_rq_wqe_type(nic_io->hwdev));
+ /* rq_wqe_type Only support type 1-16Bytes, 2-32Bytes */
+ if (rq_wqe_type != HINIC3_NORMAL_RQ_WQE &&
+ rq_wqe_type != HINIC3_EXTEND_RQ_WQE) {
+ sdk_warn(nic_io->dev_hdl, "Module Parameter rq_wqe_type value %d is out of range: [%d, %d].",
+ rq_wqe_type, HINIC3_NORMAL_RQ_WQE,
+ HINIC3_EXTEND_RQ_WQE);
+ rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
+ }
+
+ rq->wqe_type = rq_wqe_type;
rq->q_id = q_id;
rq->msix_entry_idx = rq_msix_idx;
err = hinic3_wq_create(nic_io->hwdev, &rq->wq, rq_depth,
(u16)BIT(HINIC3_RQ_WQEBB_SHIFT + rq->wqe_type));
- if (err) {
+ if (err != 0) {
sdk_err(nic_io->dev_hdl, "Failed to create rx queue(%u) wq\n",
q_id);
return err;
@@ -318,14 +328,14 @@ static int create_qp(struct hinic3_nic_io *nic_io, struct hinic3_io_queue *sq,
int err;
err = hinic3_create_sq(nic_io, sq, q_id, sq_depth, qp_msix_idx);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to create sq, qid: %u\n",
q_id);
return err;
}
err = hinic3_create_rq(nic_io, rq, q_id, rq_depth, qp_msix_idx);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to create rq, qid: %u\n",
q_id);
goto create_rq_err;
@@ -364,14 +374,14 @@ int hinic3_init_nicio_res(void *hwdev)
nic_io->max_qps = hinic3_func_max_qnum(hwdev);
err = hinic3_alloc_db_addr(hwdev, &db_base, NULL);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to allocate doorbell for sqs\n");
goto alloc_sq_db_fail;
}
nic_io->sqs_db_addr = (u8 *)db_base;
err = hinic3_alloc_db_addr(hwdev, &db_base, NULL);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to allocate doorbell for rqs\n");
goto alloc_rq_db_fail;
}
@@ -474,7 +484,7 @@ int hinic3_alloc_qps(void *hwdev, struct irq_info *qps_msix_arry,
for (q_id = 0; q_id < num_qps; q_id++) {
err = create_qp(nic_io, &sqs[q_id], &rqs[q_id], q_id, qp_params->sq_depth,
qp_params->rq_depth, qps_msix_arry[q_id].msix_entry_idx);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to allocate qp %u, err: %d\n", q_id, err);
goto create_qp_err;
}
@@ -599,14 +609,14 @@ int hinic3_create_qps(void *hwdev, u16 num_qp, u32 sq_depth, u32 rq_depth,
}
err = hinic3_init_nicio_res(hwdev);
- if (err)
+ if (err != 0)
return err;
qp_params.num_qps = num_qp;
qp_params.sq_depth = sq_depth;
qp_params.rq_depth = rq_depth;
err = hinic3_alloc_qps(hwdev, qps_msix_arry, &qp_params);
- if (err) {
+ if (err != 0) {
hinic3_deinit_nicio_res(hwdev);
nic_err(nic_io->dev_hdl,
"Failed to allocate qps, err: %d\n", err);
@@ -906,11 +916,11 @@ static int init_qp_ctxts(struct hinic3_nic_io *nic_io)
int err;
err = init_sq_ctxts(nic_io);
- if (err)
+ if (err != 0)
return err;
err = init_rq_ctxts(nic_io);
- if (err)
+ if (err != 0)
return err;
return 0;
@@ -1026,14 +1036,14 @@ int hinic3_init_qp_ctxts(void *hwdev)
return -EFAULT;
err = init_qp_ctxts(nic_io);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to init QP ctxts\n");
return err;
}
/* clean LRO/TSO context space */
err = clean_qp_offload_ctxt(nic_io);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to clean qp offload ctxts\n");
return err;
}
@@ -1042,13 +1052,13 @@ int hinic3_init_qp_ctxts(void *hwdev)
err = hinic3_set_root_ctxt(hwdev, rq_depth, nic_io->sq[0].wq.q_depth,
nic_io->rx_buff_len, HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set root context\n");
return err;
}
err = init_sq_ci_ctxts(nic_io);
- if (err)
+ if (err != 0)
goto clean_root_ctxt;
if (HINIC3_SUPPORT_RX_COMPACT_CQE(hwdev)) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
index 37f923d..c5e02ad 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
@@ -317,7 +317,7 @@ static inline void hinic3_write_db(struct hinic3_io_queue *queue, int cos,
wmb(); /* Write all before the doorbell */
- writeq(*((u64 *)&db), DB_ADDR(queue, pi));
+ writeq(*((u64 *)(u8 *)&db), DB_ADDR(queue, pi));
}
struct hinic3_dyna_qp_params {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
index 78d943d..9ea93a0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
@@ -32,7 +32,7 @@ struct hinic3_prof_adapter nic_prof_adap_objs[] = {
void hinic3_init_nic_prof_adapter(struct hinic3_nic_dev *nic_dev)
{
- u16 num_adap = ARRAY_SIZE(nic_prof_adap_objs);
+ int num_adap = ARRAY_LEN(nic_prof_adap_objs);
nic_dev->prof_adap = hinic3_prof_init(nic_dev, nic_prof_adap_objs, num_adap,
(void *)&nic_dev->prof_attr);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
index 6302fb8..dc4bb9e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
@@ -430,7 +430,8 @@ hinic3_dynamic_lookup_tcam_filter(struct hinic3_nic_dev *nic_dev,
list_for_each_entry(tmp,
&tcam_info->tcam_dynamic_info.tcam_dynamic_list,
block_list)
- if (tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)
+ if (tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE ||
+ !tmp)
break;
if (!tmp || tmp->dynamic_index_cnt >= HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) {
@@ -512,7 +513,7 @@ static int hinic3_add_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, queue: %d, tcam_rule_nums: %d succeed\n",
+ "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, queue: %u, tcam_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev),
tcam_filter->dynamic_block_id, index, fdir_tcam_rule->index,
fdir_tcam_rule->data.qid, tcam_info->tcam_rule_nums + 1);
@@ -579,7 +580,7 @@ static int hinic3_del_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, local_rules_nums: %d, global_rule_nums: %d succeed\n",
+ "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, local_rules_nums: %u, global_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev), dynamic_block_id,
tcam_filter->index, index, tmp->dynamic_index_cnt - 1,
tcam_info->tcam_rule_nums - 1);
@@ -605,7 +606,7 @@ static inline struct hinic3_tcam_filter *
hinic3_tcam_filter_lookup(const struct list_head *filter_list,
struct tag_tcam_key *key)
{
- struct hinic3_tcam_filter *iter;
+ struct hinic3_tcam_filter *iter = NULL;
list_for_each_entry(iter, filter_list, tcam_filter_list) {
if (memcmp(key, &iter->tcam_key,
@@ -630,7 +631,7 @@ static int hinic3_remove_one_rule(struct hinic3_nic_dev *nic_dev,
struct hinic3_ethtool_rx_flow_rule *eth_rule)
{
struct hinic3_tcam_info *tcam_info = &nic_dev->tcam;
- struct hinic3_tcam_filter *tcam_filter;
+ struct hinic3_tcam_filter *tcam_filter = NULL;
struct nic_tcam_cfg_rule fdir_tcam_rule;
struct tag_tcam_key tcam_key;
int err;
@@ -751,7 +752,7 @@ static int validate_flow(struct hinic3_nic_dev *nic_dev,
{
if (fs->location >= MAX_NUM_OF_ETHTOOL_NTUPLE_RULES) {
nicif_err(nic_dev, drv, nic_dev->netdev, "loc exceed limit[0,%lu]\n",
- MAX_NUM_OF_ETHTOOL_NTUPLE_RULES);
+ MAX_NUM_OF_ETHTOOL_NTUPLE_RULES - 1);
return -EINVAL;
}
@@ -872,7 +873,7 @@ int hinic3_ethtool_get_flow(const struct hinic3_nic_dev *nic_dev,
int hinic3_ethtool_get_all_flows(const struct hinic3_nic_dev *nic_dev,
struct ethtool_rxnfc *info, u32 *rule_locs)
{
- int idx = 0;
+ u32 idx = 0;
struct hinic3_ethtool_rx_flow_rule *eth_rule = NULL;
if (!HINIC3_SUPPORT_FDIR(nic_dev->hwdev)) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h b/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
index a93f3b6..9202218 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
@@ -38,13 +38,12 @@ struct hinic3_prof_adapter {
#define LLT_STATIC_DEF_SAVED
#endif
-/*lint -save -e661 */
static inline struct hinic3_prof_adapter *
hinic3_prof_init(void *device, struct hinic3_prof_adapter *adap_objs, int num_adap,
void **prof_attr)
{
struct hinic3_prof_adapter *prof_obj = NULL;
- u16 i;
+ int i;
for (i = 0; i < num_adap; i++) {
prof_obj = &adap_objs[i];
@@ -68,7 +67,6 @@ static inline void hinic3_prof_deinit(struct hinic3_prof_adapter *prof_obj, void
prof_obj->deinit(prof_attr);
}
-/*lint -restore*/
/* module-level interface */
#ifdef CONFIG_MODULE_PROF
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
index e4705c2..2a909d8 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/dcbnl.h>
+#include <linux/init.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -23,7 +24,6 @@
#include "hinic3_hw.h"
#include "hinic3_rss.h"
-/*lint -e806*/
static u16 num_qps;
module_param(num_qps, ushort, 0444);
MODULE_PARM_DESC(num_qps, "Number of Queue Pairs (default=0)");
@@ -104,88 +104,84 @@ static int hinic3_get_rq2iq_map(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev, u8 num_cos, u32 *indir)
+static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev,
+ u8 group_num, u32 *indir)
{
- u16 k, group_size, start_qid = 0, qp_num = 0;
- int i = 0;
- u8 j, cur_cos = 0, default_cos;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ u16 k, group_size, start_qid = 0, cur_cos_qnum = 0;
+ u32 i = 0;
+ u8 j, cur_cos = 0, group = 0;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
- if (num_cos == 0) {
+ if (group_num == 0) {
for (i = 0; i < NIC_RSS_INDIR_SIZE; i++)
indir[i] = i % nic_dev->q_params.num_qps;
} else {
- group_size = NIC_RSS_INDIR_SIZE / num_cos;
-
- for (j = 0; j < num_cos; j++) {
- while (cur_cos < NIC_DCB_COS_MAX &&
- nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos] == 0)
- cur_cos++;
-
- if (cur_cos >= NIC_DCB_COS_MAX) {
- if (BIT(nic_dev->hw_dcb_cfg.default_cos) & valid_cos_map)
- default_cos = nic_dev->hw_dcb_cfg.default_cos;
- else
- default_cos = (u8)fls(valid_cos_map) - 1;
+ group_size = NIC_RSS_INDIR_SIZE / group_num;
+
+ for (group = 0; group < group_num; group++) {
+ cur_cos = dcb->hw_dcb_cfg.default_cos;
+ for (j = 0; j < NIC_DCB_COS_MAX; j++) {
+ if ((BIT(j) & valid_cos_map) != 0) {
+ cur_cos = j;
+ valid_cos_map -= (u8)BIT(j);
+ break;
+ }
+ }
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[default_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[default_cos];
+ cur_cos_qnum = dcb->hw_dcb_cfg.cos_qp_num[cur_cos];
+ if (cur_cos_qnum > 0) {
+ start_qid =
+ dcb->hw_dcb_cfg.cos_qp_offset[cur_cos];
} else {
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[cur_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos];
+ start_qid = cur_cos % nic_dev->q_params.num_qps;
+ /* Ensure that the offset of start_id is 0. */
+ cur_cos_qnum = 1;
}
for (k = 0; k < group_size; k++)
- indir[i++] = start_qid + k % qp_num;
-
- cur_cos++;
+ indir[i++] = start_qid + k % cur_cos_qnum;
}
}
}
-/*lint -e528*/
int hinic3_rss_init(struct hinic3_nic_dev *nic_dev, u8 *rq2iq_map, u32 map_size, u8 dcb_en)
{
struct net_device *netdev = nic_dev->netdev;
- u8 i, cos_num;
- u8 cos_map[NIC_DCB_UP_MAX] = {0};
- u8 cfg_map[NIC_DCB_UP_MAX] = {0};
+ u8 i, group_num, cos_bitmap, group = 0;
+ u8 cos_group[NIC_DCB_UP_MAX] = {0};
int err;
- if (dcb_en) {
- cos_num = hinic3_get_dev_user_cos_num(nic_dev);
+ if (dcb_en != 0) {
+ group_num = (u8)roundup_pow_of_two(
+ hinic3_get_dev_user_cos_num(nic_dev));
- if (nic_dev->hw_dcb_cfg.trust == 0) {
- memcpy(cfg_map, nic_dev->hw_dcb_cfg.pcp2cos, sizeof(cfg_map));
- } else if (nic_dev->hw_dcb_cfg.trust == 1) {
- for (i = 0; i < NIC_DCB_UP_MAX; i++)
- cfg_map[i] = nic_dev->hw_dcb_cfg.dscp2cos[i * NIC_DCB_DSCP_NUM];
- }
-#define COS_CHANGE_OFFSET 4
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[COS_CHANGE_OFFSET + i] = cfg_map[i];
-
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[i] = cfg_map[NIC_DCB_UP_MAX - (i + 1)];
+ cos_bitmap = hinic3_get_dev_valid_cos_map(nic_dev);
- while (cos_num & (cos_num - 1))
- cos_num++;
+ for (i = 0; i < NIC_DCB_UP_MAX; i++) {
+ if ((BIT(i) & cos_bitmap) != 0)
+ cos_group[NIC_DCB_UP_MAX - i - 1] = group++;
+ else
+ cos_group[NIC_DCB_UP_MAX - i - 1] =
+ group_num - 1;
+ }
} else {
- cos_num = 0;
+ group_num = 0;
}
- err = hinic3_set_hw_rss_parameters(netdev, 1, cos_num, cos_map, dcb_en);
+ err = hinic3_set_hw_rss_parameters(netdev, 1, group_num,
+ cos_group, dcb_en);
if (err)
return err;
- err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps, cos_num, cos_map,
- NIC_DCB_UP_MAX, nic_dev->rss_indir, rq2iq_map, map_size);
+ err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps,
+ group_num, cos_group, NIC_DCB_UP_MAX,
+ nic_dev->rss_indir, rq2iq_map, map_size);
if (err)
nicif_err(nic_dev, drv, netdev, "Failed to get rq map\n");
return err;
}
-/*lint -e528*/
void hinic3_rss_deinit(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -246,11 +242,28 @@ discard_user_rss_indir:
hinic3_set_default_rss_indir(netdev);
}
+#ifdef HAVE_HOT_REPLACE_FUNC
+bool partition_slave_doing_hotupgrade(void)
+{
+ return get_partition_role() && partition_doing_hotupgrade();
+}
+#endif
+
static void decide_num_qps(struct hinic3_nic_dev *nic_dev)
{
u16 tmp_num_qps = nic_dev->max_qps;
u16 num_cpus = 0;
+ u16 max_num_cpus;
int i, node;
+ int is_in_kexec = vram_get_kexec_flag();
+
+ if (is_in_kexec != 0) {
+ nic_dev->q_params.num_qps = nic_dev->nic_vram->vram_num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Os hotreplace use vram to init num qps 1:%u 2:%u\n",
+ nic_dev->q_params.num_qps, nic_dev->nic_vram->vram_num_qps);
+ return;
+ }
if (nic_dev->nic_cap.default_num_queues != 0 &&
nic_dev->nic_cap.default_num_queues < nic_dev->max_qps)
@@ -258,16 +271,29 @@ static void decide_num_qps(struct hinic3_nic_dev *nic_dev)
MOD_PARA_VALIDATE_NUM_QPS(nic_dev, num_qps, tmp_num_qps);
- for (i = 0; i < (int)num_online_cpus(); i++) {
+#ifdef HAVE_HOT_REPLACE_FUNC
+ if (partition_slave_doing_hotupgrade())
+ max_num_cpus = (u16)num_present_cpus();
+ else
+ max_num_cpus = (u16)num_online_cpus();
+#else
+ max_num_cpus = (u16)num_online_cpus();
+#endif
+
+ for (i = 0; i < max_num_cpus; i++) {
node = (int)cpu_to_node(i);
if (node == dev_to_node(&nic_dev->pdev->dev))
num_cpus++;
}
if (!num_cpus)
- num_cpus = (u16)num_online_cpus();
+ num_cpus = max_num_cpus;
nic_dev->q_params.num_qps = (u16)min_t(u16, tmp_num_qps, num_cpus);
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "init num qps 1:%u 2:%u\n",
+ nic_dev->q_params.num_qps, nic_dev->nic_vram->vram_num_qps);
}
static void copy_value_to_rss_hkey(struct hinic3_nic_dev *nic_dev,
@@ -312,6 +338,8 @@ static int alloc_rss_resource(struct hinic3_nic_dev *nic_dev)
nic_dev->rss_indir = kzalloc(sizeof(u32) * NIC_RSS_INDIR_SIZE, GFP_KERNEL);
if (!nic_dev->rss_indir) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to alloc memory for rss_indir\n");
kfree(nic_dev->rss_hkey);
nic_dev->rss_hkey = NULL;
return -ENOMEM;
@@ -322,7 +350,6 @@ static int alloc_rss_resource(struct hinic3_nic_dev *nic_dev)
return 0;
}
-/*lint -e528*/
void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -361,6 +388,7 @@ void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
set_q_params:
clear_bit(HINIC3_RSS_ENABLE, &nic_dev->flags);
nic_dev->q_params.num_qps = nic_dev->max_qps;
+ nic_dev->nic_vram->vram_num_qps = nic_dev->max_qps;
}
static int hinic3_config_rss_hw_resource(struct hinic3_nic_dev *nic_dev,
@@ -754,6 +782,7 @@ int hinic3_set_channels(struct net_device *netdev,
nic_dev->q_params.num_qps = (u16)count;
}
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
return 0;
}
@@ -814,7 +843,7 @@ int hinic3_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
int err = 0;
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
@@ -921,7 +950,7 @@ int hinic3_get_rxfh_indir(struct net_device *netdev, u32 *indir)
indir = indir1->ring_index;
#endif
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
index 071418d..4f4b18c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
@@ -15,14 +15,15 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_nic_cfg.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_hw.h"
#include "hinic3_nic.h"
#include "hinic3_nic_cmdq.h"
#include "hinic3_common.h"
static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
- u8 *key)
+ u8 *key, u16 key_size)
{
struct hinic3_cmd_rss_hash_key hash_key;
u16 out_size = sizeof(hash_key);
@@ -33,7 +34,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
hash_key.opcode = opcode;
if (opcode == HINIC3_CMD_OP_SET)
- memcpy(hash_key.key, key, NIC_RSS_KEY_SIZE);
+ memcpy(hash_key.key, key, key_size);
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_CFG_RSS_HASH_KEY,
@@ -47,7 +48,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
}
if (opcode == HINIC3_CMD_OP_GET)
- memcpy(key, hash_key.key, NIC_RSS_KEY_SIZE);
+ memcpy(key, hash_key.key, key_size);
return 0;
}
@@ -61,8 +62,12 @@ int hinic3_rss_set_hash_key(void *hwdev, const u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memcpy(hash_key, key, NIC_RSS_KEY_SIZE);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET, hash_key);
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET,
+ hash_key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
@@ -73,7 +78,11 @@ int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET, key);
+ if (!nic_io)
+ return -EINVAL;
+
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET,
+ key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
@@ -89,6 +98,7 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
if (nic_io == NULL)
return -EINVAL;
+
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (cmd_buf == NULL) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -159,6 +169,8 @@ static int hinic3_cmdq_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
@@ -210,6 +222,9 @@ static int hinic3_mgmt_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&ctx_tbl, 0, sizeof(ctx_tbl));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
ctx |= HINIC3_RSS_TYPE_SET(1, VALID) |
@@ -259,6 +274,8 @@ int hinic3_get_rss_type(void *hwdev, struct nic_rss_type *rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&ctx_tbl, 0, sizeof(struct hinic3_rss_context_table));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
@@ -292,6 +309,9 @@ static int hinic3_rss_cfg_hash_engine(struct hinic3_nic_io *nic_io, u8 opcode,
u16 out_size = sizeof(hash_type);
int err;
+ if (!nic_io)
+ return -EINVAL;
+
memset(&hash_type, 0, sizeof(struct hinic3_cmd_rss_engine_type));
hash_type.func_id = hinic3_global_func_id(nic_io->hwdev);
@@ -325,6 +345,9 @@ int hinic3_rss_set_hash_engine(void *hwdev, u8 type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_SET, &type);
}
@@ -336,6 +359,9 @@ int hinic3_rss_get_hash_engine(void *hwdev, u8 *type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_GET, type);
}
@@ -351,6 +377,9 @@ int hinic3_rss_cfg(void *hwdev, u8 rss_en, u8 cos_num, u8 *prio_tc, u16 num_qps)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&rss_cfg, 0, sizeof(struct hinic3_cmd_rss_config));
rss_cfg.func_id = hinic3_global_func_id(hwdev);
rss_cfg.rss_en = rss_en;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
index f8a866d..9027a3d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
@@ -21,6 +21,7 @@
#include <linux/ipv6.h>
#include <linux/module.h>
#include <linux/compiler.h>
+#include <linux/filter.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -63,19 +64,31 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
struct pci_dev *pdev = nic_dev->pdev;
struct page *page = rx_info->page;
dma_addr_t dma = rx_info->buf_dma_addr;
+ u32 page_offset = 0;
if (likely(dma))
return true;
/* alloc new page for storage */
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page = page_pool_alloc_frag(rx_info->page_pool, &page_offset,
+ nic_dev->rx_buff_len,
+ GFP_ATOMIC | __GFP_COLD | __GFP_COMP);
+ if (unlikely(!page))
+ return false;
+ dma = page_pool_get_dma_addr(page);
+ goto set_rx_info;
+ }
+#endif
page = alloc_pages_node(NUMA_NO_NODE, GFP_ATOMIC | __GFP_COLD |
__GFP_COMP, nic_dev->page_order);
if (unlikely(!page))
return false;
/* map page for use */
- dma = dma_map_page(&pdev->dev, page, 0, nic_dev->dma_rx_buff_size,
- DMA_FROM_DEVICE);
+ dma = dma_map_page(&pdev->dev, page, page_offset,
+ nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
/* if mapping failed free memory back to system since
* there isn't much point in holding memory we can't use
*/
@@ -83,10 +96,12 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
__free_pages(page, nic_dev->page_order);
return false;
}
+ goto set_rx_info;
+set_rx_info:
rx_info->page = page;
rx_info->buf_dma_addr = dma;
- rx_info->page_offset = 0;
+ rx_info->page_offset = page_offset;
return true;
}
@@ -108,7 +123,7 @@ static u32 hinic3_rx_fill_wqe(struct hinic3_rxq *rxq)
/* unit of cqe length is 16B */
hinic3_set_sge(&rq_wqe->extend_wqe.cqe_sect.sge,
rx_info->cqe_dma,
- (sizeof(struct hinic3_rq_cqe) >>
+ (HINIC3_CQE_LEN >>
HINIC3_CQE_SIZE_SHIFT));
/* use fixed len */
rq_wqe->extend_wqe.buf_desc.sge.len =
@@ -169,7 +184,7 @@ static u32 hinic3_rx_fill_buffers(struct hinic3_rxq *rxq)
if (likely(i)) {
hinic3_write_db(rxq->rq,
- rxq->q_id & 3,
+ rxq->q_id & (NIC_RX_DB_COS_MAX - 1),
RQ_CFLAG_DP,
(u16)((u32)rxq->next_to_update <<
rxq->rq->wqe_type));
@@ -206,6 +221,18 @@ static void hinic3_rx_free_buffers(struct hinic3_nic_dev *nic_dev, u32 q_depth,
for (i = 0; i < q_depth; i++) {
rx_info = &rx_info_arr[i];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ if (rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool,
+ rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ }
+ continue;
+ }
+#endif
+
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev,
rx_info->buf_dma_addr,
@@ -265,8 +292,15 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
DMA_FROM_DEVICE);
if (size <= HINIC3_RX_HDR_SIZE && !skb_is_nonlinear(skb)) {
- memcpy(__skb_put(skb, size), va + offset,
- ALIGN(size, sizeof(long))); /*lint !e666*/
+ __skb_put_data(skb, va + offset, size);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool,
+ page, false);
+ return false;
+ }
+#endif
/* page is not reserved, we can reuse buffer as-is */
if (likely(page_to_nid(page) == numa_node_id()))
@@ -274,25 +308,38 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
/* this page cannot be reused so discard it */
put_page(page);
- return false;
+ goto discard_page;
}
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
- (int)(rx_info->page_offset + offset), (int)size, rxq->buf_len);
+ (int)(rx_info->page_offset + offset), (int)size,
+ rxq->buf_len);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
/* avoid re-using remote pages */
if (unlikely(page_to_nid(page) != numa_node_id()))
- return false;
+ goto discard_page;
/* if we are only owner of page we can reuse it */
if (unlikely(page_count(page) != 1))
- return false;
+ goto discard_page;
/* flip page offset to other buffer */
rx_info->page_offset ^= rxq->buf_len;
get_page(page);
return true;
+
+discard_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
}
static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
@@ -338,10 +385,6 @@ static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
if (likely(hinic3_add_rx_frag(rxq, rx_info, skb, frag_size, tmp_pkt_offset))) {
hinic3_reuse_rx_page(rxq, rx_info);
- } else {
- /* we are not reusing the buffer so unmap it */
- dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
- rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
}
/* clear contents of buffer_info */
rx_info->buf_dma_addr = 0;
@@ -486,9 +529,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
protocol = hdr.eth->h_proto;
/* L2 header */
- /*lint -save -e778*/
if (protocol == htons(ETH_P_8021_AD) ||
- protocol == htons(ETH_P_8021_Q)) { /*lint -restore*/
+ protocol == htons(ETH_P_8021_Q)) {
if (unlikely(max_len < ETH_HLEN + VLAN_HLEN))
return max_len;
@@ -500,9 +542,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
}
/* L3 header */
- /*lint -save -e778*/
switch (protocol) {
- case htons(ETH_P_IP): /*lint -restore*/
+ case htons(ETH_P_IP):
if ((int)(hdr.data - data) >
(int)(max_len - sizeof(struct iphdr)))
return max_len;
@@ -713,7 +754,10 @@ static inline void hinic3_lro_set_gso_params(struct sk_buff *skb, u16 num_lro)
}
#ifdef HAVE_XDP_SUPPORT
-enum hinic3_xdp_pkt {
+enum hinic3_xdp_status {
+ // bpf_prog status
+ HINIC3_XDP_PROG_EMPTY,
+ // pkt action
HINIC3_XDP_PKT_PASS,
HINIC3_XDP_PKT_DROP,
};
@@ -724,9 +768,15 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
while (weqbb_num) {
rx_info = &rxq->rx_info[rxq->cons_idx & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool)
+ goto discard_direct;
+#endif
if (likely(page_to_nid(rx_info->page) == numa_node_id()))
hinic3_reuse_rx_page(rxq, rx_info);
+ goto discard_direct;
+discard_direct:
rx_info->buf_dma_addr = 0;
rx_info->page = NULL;
rxq->cons_idx++;
@@ -736,11 +786,11 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
}
}
-int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
+int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len, struct xdp_buff *xdp)
{
struct bpf_prog *xdp_prog = NULL;
struct hinic3_rx_info *rx_info = NULL;
- struct xdp_buff xdp;
+ struct net_device *netdev = rxq->netdev;
int result = HINIC3_XDP_PKT_PASS;
u16 weqbb_num = 1; /* xdp can only use one rx_buff */
u8 *va = NULL;
@@ -748,13 +798,14 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
rcu_read_lock();
xdp_prog = READ_ONCE(rxq->xdp_prog);
- if (!xdp_prog)
+ if (!xdp_prog) {
+ result = HINIC3_XDP_PROG_EMPTY;
goto unlock_rcu;
+ }
if (unlikely(pkt_len > rxq->buf_len)) {
RXQ_STATS_INC(rxq, xdp_large_pkt);
- weqbb_num = (u16)(pkt_len >> rxq->rx_buff_shift) +
- ((pkt_len & (rxq->buf_len - 1)) ? 1 : 0);
+ weqbb_num = HINIC3_GET_SGE_NUM(pkt_len, rxq);
result = HINIC3_XDP_PKT_DROP;
goto xdp_out;
}
@@ -765,26 +816,27 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
dma_sync_single_range_for_cpu(rxq->dev, rx_info->buf_dma_addr,
rx_info->page_offset,
rxq->buf_len, DMA_FROM_DEVICE);
- xdp.data = va;
- xdp.data_hard_start = xdp.data;
- xdp.data_end = xdp.data + pkt_len;
+ xdp->data = va;
+ xdp->data_hard_start = xdp->data;
+ xdp->data_end = xdp->data + pkt_len;
#ifdef HAVE_XDP_FRAME_SZ
- xdp.frame_sz = rxq->buf_len;
+ xdp->frame_sz = rxq->buf_len;
#endif
#ifdef HAVE_XDP_DATA_META
- xdp_set_data_meta_invalid(&xdp);
+ xdp_set_data_meta_invalid(xdp);
#endif
- prefetchw(xdp.data_hard_start);
- act = bpf_prog_run_xdp(xdp_prog, &xdp);
+ prefetchw(xdp->data_hard_start);
+ act = bpf_prog_run_xdp(xdp_prog, xdp);
switch (act) {
case XDP_PASS:
+ result = HINIC3_XDP_PKT_PASS;
break;
case XDP_DROP:
result = HINIC3_XDP_PKT_DROP;
break;
default:
result = HINIC3_XDP_PKT_DROP;
- bpf_warn_invalid_xdp_action(rxq->netdev, xdp_prog, act);
+ bpf_warn_invalid_xdp_action(netdev, xdp_prog, act);
}
xdp_out:
@@ -798,9 +850,86 @@ unlock_rcu:
return result;
}
+
+static bool hinic3_add_rx_frag_with_xdp(struct hinic3_rxq *rxq, u32 pkt_len,
+ struct hinic3_rx_info *rx_info,
+ struct sk_buff *skb, struct xdp_buff *xdp)
+{
+ struct page *page = rx_info->page;
+
+ if (pkt_len <= HINIC3_RX_HDR_SIZE) {
+ __skb_put_data(skb, xdp->data, pkt_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool, page, false);
+ return false;
+ }
+#endif
+ if (likely(page_to_nid(page) == numa_node_id()))
+ return true;
+
+ put_page(page);
+ goto umap_page;
+ }
+
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
+ (int)(rx_info->page_offset +
+ (xdp->data - xdp->data_hard_start)),
+ (int)pkt_len, rxq->buf_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
+ if (unlikely(page_to_nid(page) != numa_node_id()))
+ goto umap_page;
+ if (unlikely(page_count(page) != 1))
+ goto umap_page;
+
+ rx_info->page_offset ^= rxq->buf_len;
+ get_page(page);
+
+ return true;
+umap_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
+}
+
+static struct sk_buff *hinic3_fetch_rx_buffer_xdp(struct hinic3_rxq *rxq,
+ u32 pkt_len,
+ struct xdp_buff *xdp)
+{
+ struct sk_buff *skb;
+ struct hinic3_rx_info *rx_info;
+ u32 sw_ci;
+ bool reuse;
+
+ sw_ci = rxq->cons_idx & rxq->q_mask;
+ rx_info = &rxq->rx_info[sw_ci];
+
+ skb = netdev_alloc_skb_ip_align(rxq->netdev, HINIC3_RX_HDR_SIZE);
+ if (unlikely(!skb))
+ return NULL;
+
+ reuse = hinic3_add_rx_frag_with_xdp(rxq, pkt_len, rx_info, skb, xdp);
+ if (likely(reuse))
+ hinic3_reuse_rx_page(rxq, rx_info);
+
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+
+ rxq->cons_idx += 1;
+ rxq->delta += 1;
+
+ return skb;
+}
+
#endif
-static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_cqe_info *cqe_info)
+static int recv_one_pkt(struct hinic3_rxq *rxq,
+ struct hinic3_cqe_info *cqe_info)
{
struct sk_buff *skb = NULL;
struct net_device *netdev = rxq->netdev;
@@ -808,13 +937,25 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_cqe_info *cqe_info
#ifdef HAVE_XDP_SUPPORT
u32 xdp_status;
+ struct xdp_buff xdp = { 0 };
- xdp_status = (u32)(hinic3_run_xdp(rxq, cqe_info->pkt_len));
+ xdp_status = (u32)(hinic3_run_xdp(rxq, cqe_info->pkt_len, &xdp));
if (xdp_status == HINIC3_XDP_PKT_DROP)
return 0;
-#endif
+ // build skb
+ if (xdp_status != HINIC3_XDP_PROG_EMPTY) {
+ // xdp_prog configured, build skb with xdp
+ skb = hinic3_fetch_rx_buffer_xdp(rxq, cqe_info->pkt_len, &xdp);
+ } else {
+ // xdp_prog not configured, build skb
+ skb = hinic3_fetch_rx_buffer(rxq, cqe_info);
+ }
+#else
+
+ // xdp is not supported
skb = hinic3_fetch_rx_buffer(rxq, cqe_info);
+#endif
if (unlikely(!skb)) {
RXQ_STATS_INC(rxq, alloc_skb_err);
return -ENOMEM;
@@ -842,7 +983,7 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_cqe_info *cqe_info
if (unlikely(test_bit(HINIC3_LP_TEST, &nic_dev->flags)))
hinic3_copy_lp_data(nic_dev, skb);
- if (cqe_info->lro_num)
+ if (cqe_info->lro_num > 1)
hinic3_lro_set_gso_params(skb, cqe_info->lro_num);
skb_record_rx_queue(skb, rxq->q_id);
@@ -1021,12 +1162,39 @@ int hinic3_rx_poll(struct hinic3_rxq *rxq, int budget)
return pkts;
}
+#ifdef HAVE_PAGE_POOL_SUPPORT
+static struct page_pool *hinic3_create_page_pool(struct hinic3_nic_dev *nic_dev,
+ u32 rq_depth,
+ struct hinic3_rx_info *rx_info_arr)
+{
+ struct page_pool_params pp_params = {
+ .flags = PP_FLAG_DMA_MAP | PP_FLAG_PAGE_FRAG | PP_FLAG_DMA_SYNC_DEV,
+ .order = nic_dev->page_order,
+ .pool_size = rq_depth * nic_dev->rx_buff_len /
+ (PAGE_SIZE << nic_dev->page_order),
+ .nid = dev_to_node(&(nic_dev->pdev->dev)),
+ .dev = &(nic_dev->pdev->dev),
+ .dma_dir = DMA_FROM_DEVICE,
+ .offset = 0,
+ .max_len = PAGE_SIZE << nic_dev->page_order,
+ };
+ struct page_pool *page_pool;
+ int i;
+
+ page_pool = nic_dev->page_pool_enabled ?
+ page_pool_create(&pp_params) : NULL;
+ for (i = 0; i < rq_depth; i++)
+ rx_info_arr[i].page_pool = page_pool;
+ return page_pool;
+}
+#endif
+
int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
u32 rq_depth, struct hinic3_dyna_rxq_res *rxqs_res)
{
struct hinic3_dyna_rxq_res *rqres = NULL;
u64 cqe_mem_size = sizeof(struct hinic3_rq_cqe) * rq_depth;
- int idx, i;
+ int idx;
u32 pkts;
u64 size;
@@ -1045,51 +1213,53 @@ int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
if (!rqres->rx_info) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx info\n", idx);
- goto err_out;
+ goto err_alloc_rx_info;
}
-
if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
rqres->cqe_start_vaddr =
- dma_zalloc_coherent(&nic_dev->pdev->dev, cqe_mem_size,
+ dma_zalloc_coherent(&nic_dev->pdev->dev,
+ cqe_mem_size,
&rqres->cqe_start_paddr,
GFP_KERNEL);
if (!rqres->cqe_start_vaddr) {
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d cqe\n", idx);
- goto err_out;
+ goto err_alloc_cqe;
}
}
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ rqres->page_pool = hinic3_create_page_pool(nic_dev, rq_depth,
+ rqres->rx_info);
+ if (nic_dev->page_pool_enabled && !rqres->page_pool) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to create rxq%d page pool\n", idx);
+ goto err_create_page_pool;
+ }
+#endif
pkts = hinic3_rx_alloc_buffers(nic_dev, rq_depth,
rqres->rx_info);
if (!pkts) {
- if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- }
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx buffers\n", idx);
- goto err_out;
+ goto err_alloc_buffers;
}
rqres->next_to_alloc = (u16)pkts;
}
return 0;
-err_out:
- for (i = 0; i < idx; i++) {
- rqres = &rxqs_res[i];
-
- hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
- if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- }
- kfree(rqres->rx_info);
- }
-
+err_alloc_buffers:
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ page_pool_destroy(rqres->page_pool);
+err_create_page_pool:
+#endif
+ dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
+ rqres->cqe_start_vaddr,
+ rqres->cqe_start_paddr);
+err_alloc_cqe:
+ kfree(rqres->rx_info);
+err_alloc_rx_info:
+ hinic3_free_rxqs_res(nic_dev, idx, rq_depth, rxqs_res);
return -ENOMEM;
}
@@ -1104,6 +1274,10 @@ void hinic3_free_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
rqres = &rxqs_res[idx];
hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rqres->page_pool)
+ page_pool_destroy(rqres->page_pool);
+#endif
if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
rqres->cqe_start_vaddr,
@@ -1191,6 +1365,7 @@ void hinic3_free_rxqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->rxqs);
+ nic_dev->rxqs = NULL;
}
int hinic3_alloc_rxqs(struct net_device *netdev)
@@ -1312,6 +1487,14 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
nic_info(&nic_dev->pdev->dev, "rxq %u restore_buf_num:%u\n", q_id, rxq->restore_buf_num);
rx_info = &rxq->rx_info[(hw_ci + rxq->q_depth - 1) & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool && rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool, rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ goto reset_rxq;
+ }
+#endif
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev, rx_info->buf_dma_addr,
nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
@@ -1322,7 +1505,9 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
__free_pages(rx_info->page, nic_dev->page_order);
rx_info->page = NULL;
}
+ goto reset_rxq;
+reset_rxq:
rxq->delta = 1;
rxq->next_to_update = (u16)((hw_ci + rxq->q_depth - 1) & rxq->q_mask);
rxq->cons_idx = (u16)((rxq->next_to_update + 1) & rxq->q_mask);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
index 586a221..480f787 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
@@ -4,6 +4,10 @@
#ifndef HINIC3_RX_H
#define HINIC3_RX_H
+#ifdef HAVE_PAGE_POOL_SUPPORT
+#include <net/page_pool/helpers.h>
+#endif
+
#include <linux/types.h>
#include <linux/device.h>
#include <linux/mm_types.h>
@@ -27,6 +31,7 @@
#define HINIC3_RX_CSUM_IPSU_OTHER_ERR BIT(8)
#define HINIC3_HEADER_DATA_UNIT 2
+#define HINIC3_CQE_LEN 32
#define HINIC3_COMPACT_CQE_8B 8
#define HINIC3_COMPACT_CQE_16B 16
@@ -35,20 +40,20 @@
#define HINIC3_RQ_CQE_INTEGRATE 1
struct hinic3_rxq_stats {
- u64 packets;
- u64 bytes;
- u64 errors;
- u64 csum_errors;
- u64 other_errors;
- u64 dropped;
- u64 xdp_dropped;
- u64 rx_buf_empty;
-
- u64 alloc_skb_err;
- u64 alloc_rx_buf_err;
- u64 xdp_large_pkt;
- u64 restore_drop_sge;
- u64 rsvd2;
+ u64 packets;
+ u64 bytes;
+ u64 errors;
+ u64 csum_errors;
+ u64 other_errors;
+ u64 dropped;
+ u64 xdp_dropped;
+ u64 rx_buf_empty;
+
+ u64 alloc_skb_err;
+ u64 alloc_rx_buf_err;
+ u64 xdp_large_pkt;
+ u64 restore_drop_sge;
+ u64 rsvd2;
#ifdef HAVE_NDO_GET_STATS64
struct u64_stats_sync syncp;
#else
@@ -62,6 +67,9 @@ struct hinic3_rx_info {
struct hinic3_rq_cqe *cqe;
dma_addr_t cqe_dma;
struct page *page;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
u32 page_offset;
u32 rsvd1;
struct hinic3_rq_wqe *rq_wqe;
@@ -102,7 +110,7 @@ struct hinic3_rxq {
u16 next_to_update;
struct device *dev; /* device for DMA mapping */
- unsigned long status;
+ u64 status;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
@@ -130,6 +138,9 @@ struct hinic3_dyna_rxq_res {
struct hinic3_rx_info *rx_info;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
};
int hinic3_alloc_rxqs(struct net_device *netdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
index bdd5a8e..d816609 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
@@ -11,10 +11,12 @@
#ifndef HINIC3_SRV_NIC_H
#define HINIC3_SRV_NIC_H
-#include "hinic3_mgmt_interface.h"
+#include <linux/netdevice.h>
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_lld.h"
+#include "nic_cfg_comm.h"
+#include "nic_mpu_cmd_defs.h"
enum hinic3_queue_type {
HINIC3_SQ,
@@ -64,6 +66,7 @@ enum hinic3_nic_event_type {
EVENT_NIC_DCB_STATE_CHANGE,
EVENT_NIC_BOND_DOWN,
EVENT_NIC_BOND_UP,
+ EVENT_NIC_OUTBAND_CFG,
};
/* *
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
index bc1a8ef..d05813e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
@@ -223,24 +223,72 @@ static void get_inner_l3_l4_type(struct sk_buff *skb, union hinic3_ip *ip,
enum sq_l3_type *l3_type, u8 *l4_proto)
{
unsigned char *exthdr = NULL;
- __be16 frag_off = 0;
if (ip->v4->version == IP4_VERSION) {
*l3_type = IPV4_PKT_WITH_CHKSUM_OFFLOAD;
*l4_proto = ip->v4->protocol;
+
+#ifdef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
+ /* inner_transport_header is wrong in centos7.0 and suse12.1 */
+ l4->hdr = ip->hdr + ((u8)ip->v4->ihl << IP_HDR_IHL_UNIT_SHIFT);
+#endif
} else if (ip->v4->version == IP6_VERSION) {
*l3_type = IPV6_PKT;
exthdr = ip->hdr + sizeof(*ip->v6);
*l4_proto = ip->v6->nexthdr;
- if (exthdr != l4->hdr)
+ if (exthdr != l4->hdr) {
+ __be16 frag_off = 0;
+#ifndef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
ipv6_skip_exthdr(skb, (int)(exthdr - skb->data),
- l4_proto, &frag_off);
+ l4_proto, &frag_off);
+#else
+ int pld_off = 0;
+
+ pld_off = ipv6_skip_exthdr(skb,
+ (int)(exthdr - skb->data),
+ l4_proto, &frag_off);
+ l4->hdr = skb->data + pld_off;
+#endif
+ }
} else {
*l3_type = UNKNOWN_L3TYPE;
*l4_proto = 0;
}
}
+static u8 hinic3_get_inner_l4_type(struct sk_buff *skb)
+{
+ enum sq_l3_type l3_type;
+ u8 l4_proto;
+ union hinic3_ip ip;
+ union hinic3_l4 l4;
+
+ ip.hdr = skb_inner_network_header(skb);
+ l4.hdr = skb_inner_transport_header(skb);
+
+ get_inner_l3_l4_type(skb, &ip, &l4, &l3_type, &l4_proto);
+
+ return l4_proto;
+}
+
+static void hinic3_set_unknown_tunnel_csum(struct sk_buff *skb)
+{
+ int csum_offset;
+ __sum16 skb_csum;
+ u8 l4_proto;
+
+ l4_proto = hinic3_get_inner_l4_type(skb);
+ /* Unsupport tunnel packet, disable csum offload */
+ skb_checksum_help(skb);
+ /* The value of csum is changed from 0xffff to 0 according to RFC1624. */
+ if (skb->ip_summed == CHECKSUM_NONE && l4_proto != IPPROTO_UDP) {
+ csum_offset = skb_checksum_start_offset(skb) + skb->csum_offset;
+ skb_csum = *(__sum16 *)(skb->data + csum_offset);
+ if (skb_csum == 0xffff)
+ *(__sum16 *)(skb->data + csum_offset) = 0;
+ }
+}
+
static int hinic3_tx_csum(struct hinic3_txq *txq, struct sk_buff *skb,
struct hinic3_offload_info *offload_info,
struct hinic3_queue_info *queue_info)
@@ -276,10 +324,9 @@ static int hinic3_tx_csum(struct hinic3_txq *txq, struct sk_buff *skb,
if (l4_proto == IPPROTO_UDP)
queue_info->udp_dp_en = 1;
- if (l4_proto != IPPROTO_UDP ||
- ((struct udphdr *)skb_transport_header(skb))->dest != VXLAN_OFFLOAD_PORT_LE) {
+ if (l4_proto != IPPROTO_UDP) {
TXQ_STATS_INC(txq, unknown_tunnel_pkt);
- skb_checksum_help(skb);
+ hinic3_set_unknown_tunnel_csum(skb);
return 0;
}
}
@@ -682,6 +729,14 @@ static netdev_tx_t hinic3_send_one_skb(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
+ /* l2nic outband vlan cfg enable */
+ if ((!skb_vlan_tag_present(skb)) &&
+ (nic_dev->nic_cap.outband_vlan_cfg_en == 1) &&
+ nic_dev->outband_cfg.outband_default_vid != 0) {
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+ (u16)nic_dev->outband_cfg.outband_default_vid);
+ }
+
offload = hinic3_tx_offload(skb, &offload_info, &queue_info, txq);
if (unlikely(offload == TX_OFFLOAD_INVALID)) {
TXQ_STATS_INC(txq, offload_cow_skb_err);
@@ -880,6 +935,7 @@ int hinic3_alloc_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
tqres->bds = kzalloc(size, GFP_KERNEL);
if (!tqres->bds) {
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc txq%d bds info\n", idx);
goto err_out;
@@ -893,7 +949,9 @@ err_out:
tqres = &txqs_res[i];
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
return -ENOMEM;
@@ -910,7 +968,9 @@ void hinic3_free_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
free_all_tx_skbs(nic_dev, sq_depth, tqres->tx_info);
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
}
@@ -982,6 +1042,7 @@ void hinic3_free_txqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->txqs);
+ nic_dev->txqs = NULL;
}
static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
@@ -998,7 +1059,7 @@ static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
static int hinic3_stop_sq(struct hinic3_txq *txq)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(txq->netdev);
- unsigned long timeout;
+ u64 timeout;
int err;
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -1007,7 +1068,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
return 0;
usleep_range(900, 1000); /* sleep 900 us ~ 1000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* force hardware to drop packets */
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -1020,7 +1081,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
break;
usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* Avoid msleep takes too long and get a fake result */
if (is_hw_complete_sq_process(txq->sq))
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
index 1b9e509..7ae029b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
@@ -29,7 +29,7 @@ struct hinic3_wq {
#define WQ_MASK_IDX(wq, idx) ((idx) & (wq)->idx_mask)
#define WQ_MASK_PAGE(wq, pg_idx) \
- ((pg_idx) < (wq)->num_wq_pages ? (pg_idx) : 0)
+ (((pg_idx) < ((wq)->num_wq_pages)) ? (pg_idx) : 0)
#define WQ_PAGE_IDX(wq, idx) ((idx) >> (wq)->wqebbs_per_page_shift)
#define WQ_OFFSET_IN_PAGE(wq, idx) ((idx) & (wq)->wqebbs_per_page_mask)
#define WQ_GET_WQEBB_ADDR(wq, pg_idx, idx_in_pg) \
@@ -75,7 +75,7 @@ static inline void *hinic3_wq_get_multi_wqebbs(struct hinic3_wq *wq,
pg_idx = WQ_PAGE_IDX(wq, *prod_idx);
off_in_page = WQ_OFFSET_IN_PAGE(wq, *prod_idx);
- if (off_in_page + num_wqebbs > wq->wqebbs_per_page) {
+ if ((off_in_page + num_wqebbs) > wq->wqebbs_per_page) {
/* wqe across wq page boundary */
*second_part_wqebbs_addr =
WQ_GET_WQEBB_ADDR(wq, WQ_MASK_PAGE(wq, pg_idx + 1), 0);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
index 597d3fe..468351f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
@@ -400,12 +400,15 @@ static int wait_for_status_poll(struct hinic3_api_cmd_chain *chain)
API_CMD_STATUS_TIMEOUT, 100); /* wait 100 us once */
}
-static void copy_resp_data(struct hinic3_api_cmd_cell_ctxt *ctxt, void *ack,
+static void copy_resp_data(struct hinic3_api_cmd_chain *chain,
+ struct hinic3_api_cmd_cell_ctxt *ctxt, void *ack,
u16 ack_size)
{
struct hinic3_api_cmd_resp_fmt *resp = ctxt->resp;
+ int rsp_size_align = chain->rsp_size_align - 0x8;
+ int rsp_size = (ack_size > rsp_size_align) ? rsp_size_align : ack_size;
- memcpy(ack, &resp->resp_data, ack_size);
+ memcpy(ack, &resp->resp_data, rsp_size);
ctxt->status = 0;
}
@@ -464,7 +467,7 @@ static int wait_for_api_cmd_completion(struct hinic3_api_cmd_chain *chain,
case HINIC3_API_CMD_POLL_READ:
err = wait_for_resp_polling(ctxt);
if (err == 0)
- copy_resp_data(ctxt, ack, ack_size);
+ copy_resp_data(chain, ctxt, ack, ack_size);
else
sdk_err(dev, "API CMD poll response timeout\n");
break;
@@ -1054,13 +1057,11 @@ alloc_cells_buf_err:
alloc_wb_status_err:
kfree(chain->cell_ctxt);
-/*lint -save -e548*/
alloc_cell_ctxt_err:
if (chain->chain_type == HINIC3_API_CMD_WRITE_ASYNC_TO_MGMT_CPU)
spin_lock_deinit(&chain->async_lock);
else
sema_deinit(&chain->sem);
-/*lint -restore*/
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
index 38474ba..9f10131 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
@@ -801,7 +801,7 @@ static int cmdq_sync_cmd(struct hinic3_cmdq *cmdq, u8 mod, u8 cmd,
hinic3_cmdq_fill_completion_info(cmd_info, &cmpt_code, &done, &errcode, out_param);
cmdq_set_cmd_buf(cmd_info, cmdq->hwdev, buf_in, buf_out);
- memcpy(&saved_cmd_info, cmd_info, sizeof(*cmd_info));
+ memcpy(&saved_cmd_info, cmd_info, sizeof(struct hinic3_cmdq_cmd_info));
cmdq_sync_wqe_prepare(cmdq, mod, cmd, buf_in, buf_out, curr_wqe, curr_pi, nic_cmd_type);
@@ -1075,6 +1075,7 @@ int hinic3_cmdq_async(void *hwdev, u8 mod, u8 cmd, struct hinic3_cmd_buf *buf_in
return cmdq_async_cmd(&cmdqs->cmdq[HINIC3_CMDQ_SYNC], mod,
cmd, buf_in, channel);
}
+EXPORT_SYMBOL(hinic3_cmdq_async);
int hinic3_cmdq_async_cos(void *hwdev, u8 mod, u8 cmd,
u8 cos_id, struct hinic3_cmd_buf *buf_in, u16 channel)
@@ -1320,6 +1321,7 @@ cmd_infos_err:
static void free_cmdq(struct hinic3_cmdq *cmdq)
{
kfree(cmdq->cmd_infos);
+ cmdq->cmd_infos = NULL;
spin_lock_deinit(&cmdq->cmdq_lock);
}
@@ -1530,7 +1532,7 @@ static int create_cmdq_wq(struct hinic3_cmdqs *cmdqs)
type = HINIC3_CMDQ_SYNC;
for (; type < cmdqs->cmdq_num; type++)
memcpy((u8 *)cmdqs->wq_block_vaddr +
- CMDQ_WQ_CLA_SIZE * type,
+ ((u64)type * CMDQ_WQ_CLA_SIZE),
cmdqs->cmdq[type].wq.wq_block_vaddr,
cmdqs->cmdq[type].wq.num_wq_pages * sizeof(u64));
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
index b9b884f..4f4639d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
@@ -15,11 +15,6 @@
#include "hinic3_common.h"
#include "hinic3_hwdev.h"
-struct dma_pool {
- unsigned int size;
- void *dev_hdl;
-};
-
#define HINIC3_SCMD_DATA_LEN 16
#define HINIC3_CMDQ_DEPTH 4096
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c
index c212bcc..d7e4985 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c
@@ -16,7 +16,6 @@
#include "ossl_knl.h"
#include "npu_cmdq_base_defs.h"
-#include "comm_defs.h"
#include "hinic3_crm.h"
#include "hinic3_hw.h"
#include "hinic3_hwdev.h"
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
index 5e0139a..f0b2b1a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
@@ -22,11 +22,15 @@
#include "hinic3_sriov.h"
#include "hinic3_nictool.h"
#include "hinic3_pci_id_tbl.h"
+#include "hinic3_hwdev.h"
+#include "cfg_mgmt_mpu_cmd_defs.h"
+#include "mpu_cmd_base_defs.h"
#include "hinic3_dev_mgmt.h"
#define HINIC3_WAIT_TOOL_CNT_TIMEOUT 10000
#define HINIC3_WAIT_TOOL_MIN_USLEEP_TIME 9900
#define HINIC3_WAIT_TOOL_MAX_USLEEP_TIME 10000
+#define HIGHT_BDF 8
static unsigned long card_bit_map;
@@ -60,14 +64,24 @@ void lld_dev_cnt_init(struct hinic3_pcidev *pci_adapter)
void lld_dev_hold(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_inc(&pci_adapter->ref_cnt);
}
void lld_dev_put(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_dec(&pci_adapter->ref_cnt);
}
@@ -236,6 +250,40 @@ void hinic3_get_all_chip_id(void *id_info)
card_id->num = (u32)i;
}
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+ u64 bar1_phy_addr = 0;
+ u64 bar3_phy_addr = 0;
+ u64 bar1_size = 0;
+ u64 bar3_size = 0;
+
+ lld_hold();
+
+ /* get PF bar1 or bar3 physical address to verify */
+ list_for_each_entry(chip_node, &g_hinic3_chip_list, node) {
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (hinic3_func_type(dev->hwdev) == TYPE_VF)
+ continue;
+
+ bar1_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+ bar1_size = pci_resource_len(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+
+ bar3_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ bar3_size = pci_resource_len(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ if ((phy_addr == bar1_phy_addr && vmsize <= bar1_size) ||
+ (phy_addr == bar3_phy_addr && vmsize <= bar3_size)) {
+ lld_put();
+ return 0;
+ }
+ }
+ }
+
+ lld_put();
+ return -EINVAL;
+}
+
void hinic3_get_card_func_info_by_card_name(const char *chip_name,
struct hinic3_card_func_info *card_func)
{
@@ -422,6 +470,29 @@ struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name
return NULL;
}
+void *hinic3_get_ppf_dev(void)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct list_head *chip_list = NULL;
+
+ lld_hold();
+ chip_list = get_hinic3_chip_list();
+
+ list_for_each_entry(chip_node, chip_list, node)
+ list_for_each_entry(pci_adapter, &chip_node->func_list, node)
+ if (hinic3_func_type(pci_adapter->hwdev) == TYPE_PPF) {
+ pr_info("Get ppf_func_id:%u",
+ hinic3_global_func_id(pci_adapter->hwdev));
+ lld_put();
+ return pci_adapter->lld_dev.hwdev;
+ }
+
+ lld_put();
+ return NULL;
+}
+EXPORT_SYMBOL(hinic3_get_ppf_dev);
+
struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
enum hinic3_service_type type)
{
@@ -518,6 +589,7 @@ EXPORT_SYMBOL(hinic3_get_ppf_lld_dev_unsafe);
int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len)
{
struct hinic3_pcidev *pci_adapter = NULL;
+ int ret = 0;
if (!lld_dev || !chip_name || !max_len)
return -EINVAL;
@@ -527,12 +599,18 @@ int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 ma
return -EFAULT;
lld_hold();
- strscpy(chip_name, pci_adapter->chip_node->chip_name, max_len);
+ if (strscpy(chip_name, pci_adapter->chip_node->chip_name, max_len) < 0)
+ goto RELEASE;
chip_name[max_len - 1] = '\0';
lld_put();
return 0;
+
+RELEASE:
+ lld_put();
+
+ return ret;
}
EXPORT_SYMBOL(hinic3_get_chip_name);
@@ -541,6 +619,87 @@ struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev)
return lld_dev->hwdev;
}
+void hinic3_write_oshr_info(struct os_hot_replace_info *out_oshr_info,
+ struct hw_pf_info *info,
+ struct hinic3_board_info *board_info,
+ struct card_node *chip_node, u32 serivce_enable,
+ u32 func_info_idx)
+{
+ out_oshr_info->func_infos[func_info_idx].pf_idx = info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].backup_pf =
+ (((info->glb_func_idx) / (board_info->port_num)) %
+ HOT_REPLACE_PARTITION_NUM == 0) ?
+ ((info->glb_func_idx) + (board_info->port_num)) :
+ ((info->glb_func_idx) - (board_info->port_num));
+ out_oshr_info->func_infos[func_info_idx].partition =
+ ((info->glb_func_idx) / (board_info->port_num)) %
+ HOT_REPLACE_PARTITION_NUM;
+ out_oshr_info->func_infos[func_info_idx].port_id = info->port_id;
+ out_oshr_info->func_infos[func_info_idx].bdf =
+ (info->bus_num << HIGHT_BDF) + info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].bus_num = chip_node->bus_num;
+ out_oshr_info->func_infos[func_info_idx].valid = serivce_enable;
+ memcpy(out_oshr_info->func_infos[func_info_idx].card_name,
+ chip_node->chip_name, IFNAMSIZ);
+}
+
+void hinic3_get_os_hot_replace_info(void *oshr_info)
+{
+ struct os_hot_replace_info *out_oshr_info =
+ (struct os_hot_replace_info *)oshr_info;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dst_dev = NULL;
+ struct hinic3_board_info *board_info = NULL;
+ struct hw_pf_info *infos = NULL;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ struct hinic3_hwdev *hwdev = NULL;
+ u32 func_info_idx = 0, func_id = 0, func_num, serivce_enable = 0;
+ struct list_head *hinic3_chip_list = get_hinic3_chip_list();
+ int err;
+
+ lld_hold();
+ pf_infos = kzalloc(sizeof(struct hinic3_hw_pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ pr_err("kzalloc pf_infos fail\n");
+ lld_put();
+ return;
+ }
+ list_for_each_entry(chip_node, hinic3_chip_list, node) {
+ list_for_each_entry(dst_dev, &chip_node->func_list, node) {
+ err = hinic3_get_hw_pf_infos(dst_dev->hwdev,
+ pf_infos,
+ HINIC3_CHANNEL_COMM);
+ if (err != 0) {
+ pr_err("get pf info failed\n");
+ break;
+ }
+ hwdev = (struct hinic3_hwdev *)dst_dev->hwdev;
+ serivce_enable = 0;
+ infos = pf_infos->infos;
+ board_info = &hwdev->board_info;
+ if (hwdev->hot_replace_mode == HOT_REPLACE_ENABLE)
+ serivce_enable = 1;
+ break;
+ }
+
+ func_num = pf_infos->num_pfs;
+ if (func_num <= 0) {
+ pr_err("get pf num failed\n");
+ break;
+ }
+
+ for (func_id = 0; func_id < func_num; func_id++) {
+ hinic3_write_oshr_info(out_oshr_info, &infos[func_id],
+ board_info, chip_node,
+ serivce_enable, func_info_idx);
+ func_info_idx++;
+ }
+ }
+ out_oshr_info->func_cnt = func_info_idx;
+ kfree(pf_infos);
+ lld_put();
+}
+
struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(lld_dev->pdev);
@@ -608,21 +767,24 @@ void hinic3_get_card_info(const void *hwdev, void *bufin)
if (hinic3_support_nic(fun_hwdev, NULL)) {
if (dev->uld_dev[SERVICE_T_NIC]) {
info->pf[i].pf_type |= (u32)BIT(SERVICE_T_NIC);
- get_dynamic_uld_dev_name(dev, SERVICE_T_NIC, info->pf[i].name);
+ get_dynamic_uld_dev_name(dev, SERVICE_T_NIC,
+ info->pf[i].name);
}
}
if (hinic3_support_ppa(fun_hwdev, NULL)) {
if (dev->uld_dev[SERVICE_T_PPA]) {
info->pf[i].pf_type |= (u32)BIT(SERVICE_T_PPA);
- get_dynamic_uld_dev_name(dev, SERVICE_T_PPA, info->pf[i].name);
+ get_dynamic_uld_dev_name(dev, SERVICE_T_PPA,
+ info->pf[i].name);
}
}
if (hinic3_func_for_mgmt(fun_hwdev))
strscpy(info->pf[i].name, "FOR_MGMT", IFNAMSIZ);
- if (dev->lld_dev.pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID)
+ if (dev->lld_dev.pdev->subsystem_device ==
+ BIFUR_RESOURCE_PF_SSID)
strscpy(info->pf[i].name, "bifur", IFNAMSIZ);
strscpy(info->pf[i].bus_info, pci_name(dev->pcidev),
@@ -721,6 +883,7 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
struct card_node *chip_node = NULL;
unsigned char i;
unsigned char bus_number = 0;
+ int err;
if (chip_node_is_exist(pci_adapter, &bus_number))
return 0;
@@ -746,7 +909,10 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
/* bus number */
chip_node->bus_num = bus_number;
- if (snprintf(chip_node->chip_name, IFNAMSIZ, "%s%u", HINIC3_CHIP_NAME, i) < 0) {
+ snprintf(chip_node->chip_name, IFNAMSIZ, "%s%u", HINIC3_CHIP_NAME, i);
+
+ err = sscanf(chip_node->chip_name, HINIC3_CHIP_NAME "%d", &(chip_node->chip_id));
+ if (err <= 0) {
clear_bit(i, &card_bit_map);
kfree(chip_node);
return -EINVAL;
@@ -803,3 +969,36 @@ int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *
return 0;
}
+
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin)
+{
+ struct card_node *chip_node = NULL;
+ struct card_mbox_cnt_info *info = (struct card_mbox_cnt_info *)bufin;
+ struct hinic3_pcidev *dev = NULL;
+ struct hinic3_hwdev *func_hwdev = NULL;
+ u32 i = 0;
+
+ info->func_num = 0;
+ chip_node = hinic3_get_chip_node_by_hwdev(hwdev);
+ if (chip_node == NULL)
+ return;
+
+ lld_hold();
+
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ func_hwdev = (struct hinic3_hwdev *)dev->hwdev;
+ strscpy(info->func_info[i].bus_info, pci_name(dev->pcidev),
+ sizeof(info->func_info[i].bus_info));
+
+ info->func_info[i].send_cnt = func_hwdev->mbox_send_cnt;
+ info->func_info[i].ack_cnt = func_hwdev->mbox_ack_cnt;
+ info->func_num++;
+ i = info->func_num;
+ if (i >= ARRAY_SIZE(info->func_info)) {
+ sdk_err(&dev->pcidev->dev, "chip_node->func_list bigger than pf_max + vf_max\n");
+ break;
+ }
+ }
+
+ lld_put();
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
index 5c7c7cd..9815082 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
@@ -22,8 +22,13 @@
#define BIFUR_RESOURCE_PF_SSID 0x05a1
-#define HINIC3_IS_VF_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_VF)
-#define HINIC3_IS_SPU_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_SPU)
+#define HINIC3_IS_VF_DEV(pdev) \
+ ((pdev)->device == HINIC3_DEV_ID_VF || \
+ (pdev)->device == HINIC3_DEV_SDI_5_1_ID_VF)
+#define HINIC3_IS_SPU_DEV(pdev) \
+ (((pdev)->device == HINIC3_DEV_ID_SPU) || \
+ ((pdev)->device == HINIC3_DEV_ID_SDI_5_0_PF) || \
+ (((pdev)->device == HINIC3_DEV_ID_DPU_PF)))
enum {
HINIC3_NOT_PROBE = 1,
@@ -79,6 +84,13 @@ struct hinic3_pcidev {
u16 probe_fault_level;
u16 rsvd2;
u64 rsvd4;
+
+ struct workqueue_struct *multi_host_mgmt_workq;
+ struct work_struct slave_nic_work;
+ struct work_struct slave_vroce_work;
+
+ struct workqueue_struct *migration_probe_workq;
+ struct delayed_work migration_probe_dwork;
};
struct hinic_chip_info {
@@ -104,4 +116,6 @@ void wait_lld_dev_unused(struct hinic3_pcidev *pci_adapter);
void *hinic3_get_hwdev_by_pcidev(struct pci_dev *pdev);
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
index 11561a0..59ff722 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
@@ -101,7 +101,8 @@ static bool check_image_device_type(struct hinic3_hwdev *hwdev, u32 device_type)
static void encapsulate_update_cmd(struct hinic3_cmd_update_firmware *msg,
struct firmware_section *section_info,
- int *remain_len, u32 *send_len, u32 *send_pos)
+ const int *remain_len, u32 *send_len,
+ u32 *send_pos)
{
memset(msg->data, 0, sizeof(msg->data));
msg->ctl_info.sf = (*remain_len == section_info->section_len) ? true : false;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
index 937d699..be7c82b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
@@ -26,6 +26,8 @@
#include "hinic3_prof_adap.h"
#include "hinic3_eqs.h"
+#include "vram_common.h"
+
#define HINIC3_EQS_WQ_NAME "hinic3_eqs"
#define AEQ_CTRL_0_INTR_IDX_SHIFT 0
@@ -66,7 +68,6 @@
#define HINIC3_TASK_PROCESS_EQE_LIMIT 1024
#define HINIC3_EQ_UPDATE_CI_STEP 64
-/*lint -e806*/
static uint g_aeq_len = HINIC3_DEFAULT_AEQ_LEN;
module_param(g_aeq_len, uint, 0444);
MODULE_PARM_DESC(g_aeq_len,
@@ -83,7 +84,6 @@ static uint g_num_ceqe_in_tasklet = HINIC3_TASK_PROCESS_EQE_LIMIT;
module_param(g_num_ceqe_in_tasklet, uint, 0444);
MODULE_PARM_DESC(g_num_ceqe_in_tasklet,
"The max number of ceqe can be processed in tasklet, default = 1024");
-/*lint +e806*/
#define CEQ_CTRL_0_INTR_IDX_SHIFT 0
#define CEQ_CTRL_0_DMA_ATTR_SHIFT 12
@@ -819,18 +819,22 @@ static int alloc_eq_pages(struct hinic3_eq *eq)
u32 reg, init_val;
u16 pg_idx, i;
int err;
+ gfp_t gfp_vram;
eq->eq_pages = kcalloc(eq->num_pages, sizeof(*eq->eq_pages),
GFP_KERNEL);
if (!eq->eq_pages)
return -ENOMEM;
+ gfp_vram = hi_vram_get_gfp_vram();
+
for (pg_idx = 0; pg_idx < eq->num_pages; pg_idx++) {
eq_page = &eq->eq_pages[pg_idx];
err = hinic3_dma_zalloc_coherent_align(eq->hwdev->dev_hdl,
eq->page_size,
HINIC3_MIN_EQ_PAGE_SIZE,
- GFP_KERNEL, eq_page);
+ GFP_KERNEL | gfp_vram,
+ eq_page);
if (err) {
sdk_err(eq->hwdev->dev_hdl, "Failed to alloc eq page, page index: %u\n",
pg_idx);
@@ -881,6 +885,7 @@ static void free_eq_pages(struct hinic3_eq *eq)
&eq->eq_pages[pg_idx]);
kfree(eq->eq_pages);
+ eq->eq_pages = NULL;
}
static inline u32 get_page_size(const struct hinic3_eq *eq)
@@ -1120,7 +1125,8 @@ int hinic3_aeqs_init(struct hinic3_hwdev *hwdev, u16 num_aeqs,
hwdev->aeqs = aeqs;
aeqs->hwdev = hwdev;
aeqs->num_aeqs = num_aeqs;
- aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME, WQ_MEM_RECLAIM,
+ aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME,
+ WQ_MEM_RECLAIM | WQ_HIGHPRI,
HINIC3_MAX_AEQS);
if (!aeqs->workq) {
sdk_err(hwdev->dev_hdl, "Failed to initialize aeq workqueue\n");
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
index a4cbac8..6b96b87 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
@@ -82,6 +82,48 @@ int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id,
return 0;
}
+/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read and clear to zero
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
+ u16 *value)
+{
+ struct chipif_sml_ctr_rd_req req;
+ union ctr_rd_rsp rsp;
+ int ret;
+
+ if (!hwdev || !value)
+ return -EFAULT;
+
+ if (!COMM_SUPPORT_API_CHAIN((struct hinic3_hwdev *)hwdev))
+ return -EPERM;
+
+ memset(&req, 0, sizeof(req));
+
+ hinic3_sml_ctr_read_build_req(&req, instance,
+ CHIPIF_SM_CTR_OP_READ_CLEAR,
+ CHIPIF_ACK, ctr_id, 0);
+
+ ret = hinic3_api_cmd_read_ack(hwdev, node, (u8 *)&req,
+ (unsigned short)sizeof(req),
+ (void *)&rsp,
+ (unsigned short)sizeof(rsp));
+ if (ret) {
+ sdk_err(((struct hinic3_hwdev *)hwdev)->dev_hdl,
+ "Sm 16bit counter clear fail, err(%d)\n", ret);
+ return ret;
+ }
+ sml_ctr_htonl_n((u32 *)&rsp, sizeof(rsp) / sizeof(u32));
+ *value = rsp.bs_ss16_rsp.value1;
+
+ return 0;
+}
+
/**
* hinic3_sm_ctr_rd32 - small single 32 counter read
* @hwdev: the hardware device
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
index 030ef6d..5a8d2a4 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
@@ -34,13 +34,18 @@ static void parse_pub_res_cap_dfx(struct hinic3_hwdev *hwdev,
cap->max_vf);
sdk_info(hwdev->dev_hdl, "Host_pf_num: 0x%x, pf_id_start: 0x%x, host_vf_num: 0x%x, vf_id_start: 0x%x\n",
cap->pf_num, cap->pf_id_start, cap->vf_num, cap->vf_id_start);
- sdk_info(hwdev->dev_hdl, "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x\n",
- cap->host_valid_bitmap, cap->master_host_id, cap->srv_multi_host_mode);
sdk_info(hwdev->dev_hdl,
- "fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
- cap->fake_vf_start_id, cap->fake_vf_num, cap->fake_vf_max_pctx);
- sdk_info(hwdev->dev_hdl, "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x\n",
- cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len);
+ "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x, hot_plug_disable: 0x%x\n",
+ cap->host_valid_bitmap, cap->master_host_id,
+ cap->srv_multi_host_mode, cap->hot_plug_disable);
+ sdk_info(hwdev->dev_hdl,
+ "os_hot_replace: 0x%x, fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
+ cap->os_hot_replace, cap->fake_vf_start_id,
+ cap->fake_vf_num, cap->fake_vf_max_pctx);
+ sdk_info(hwdev->dev_hdl,
+ "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x, bond_create_mode: 0x%x\n",
+ cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len,
+ cap->bond_create_mode);
}
static void parse_cqm_res_cap(struct hinic3_hwdev *hwdev, struct service_cap *cap,
@@ -109,6 +114,9 @@ static void parse_pub_res_cap(struct hinic3_hwdev *hwdev,
cap->host_valid_bitmap = dev_cap->host_valid_bitmap;
cap->master_host_id = dev_cap->master_host_id;
cap->srv_multi_host_mode = dev_cap->srv_multi_host_mode;
+ cap->hot_plug_disable = dev_cap->hot_plug_disable;
+ cap->bond_create_mode = dev_cap->bond_create_mode;
+ cap->os_hot_replace = dev_cap->os_hot_replace;
cap->fake_vf_en = dev_cap->fake_vf_en;
cap->fake_vf_start_bit = dev_cap->fake_vf_start_bit;
cap->fake_vf_end_bit = dev_cap->fake_vf_end_bit;
@@ -148,18 +156,27 @@ static void parse_l2nic_res_cap(struct hinic3_hwdev *hwdev,
nic_cap->max_sqs = dev_cap->nic_max_sq_id + 1;
nic_cap->max_rqs = dev_cap->nic_max_rq_id + 1;
nic_cap->default_num_queues = dev_cap->nic_default_num_queues;
+ nic_cap->outband_vlan_cfg_en = dev_cap->outband_vlan_cfg_en;
+ nic_cap->lro_enable = dev_cap->lro_enable;
sdk_info(hwdev->dev_hdl, "L2nic resource capbility, max_sqs: 0x%x, max_rqs: 0x%x\n",
nic_cap->max_sqs, nic_cap->max_rqs);
/* Check parameters from firmware */
- if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP ||
- nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
- sdk_info(hwdev->dev_hdl, "Number of qp exceed limit[1-%d]: sq: %u, rq: %u\n",
- HINIC3_CFG_MAX_QP, nic_cap->max_sqs, nic_cap->max_rqs);
+ if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of sq exceed limit[1-%d]: sq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_sqs);
nic_cap->max_sqs = HINIC3_CFG_MAX_QP;
+ }
+
+ if (nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of rq exceed limit[1-%d]: rq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_rqs);
nic_cap->max_rqs = HINIC3_CFG_MAX_QP;
}
+
+ if (nic_cap->outband_vlan_cfg_en)
+ sdk_info(hwdev->dev_hdl, "L2nic outband vlan cfg enabled\n");
}
static void parse_fc_res_cap(struct hinic3_hwdev *hwdev,
@@ -333,6 +350,28 @@ static void parse_ipsec_res_cap(struct hinic3_hwdev *hwdev,
dev_cap->ipsec_max_sactx, dev_cap->ipsec_max_cq);
}
+static void parse_vbs_res_cap(struct hinic3_hwdev *hwdev,
+ struct service_cap *cap,
+ struct cfg_cmd_dev_cap *dev_cap,
+ enum func_type type)
+{
+ struct vbs_service_cap *vbs_cap = &cap->vbs_cap;
+
+ vbs_cap->vbs_max_volq = dev_cap->vbs_max_volq;
+ vbs_cap->vbs_main_pf_enable = dev_cap->vbs_main_pf_enable;
+ vbs_cap->vbs_vsock_pf_enable = dev_cap->vbs_vsock_pf_enable;
+ vbs_cap->vbs_fushion_queue_pf_enable = dev_cap->vbs_fushion_queue_pf_enable;
+
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS resource capbility, vbs_max_volq: 0x%x\n",
+ dev_cap->vbs_max_volq);
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS pf info, vbs_main_pf_enable: 0x%x, vbs_vsock_pf_enable: 0x%x, vbs_fushion_queue_pf_enable: 0x%x\n",
+ dev_cap->vbs_main_pf_enable,
+ dev_cap->vbs_vsock_pf_enable,
+ dev_cap->vbs_fushion_queue_pf_enable);
+}
+
static void parse_dev_cap(struct hinic3_hwdev *dev,
struct cfg_cmd_dev_cap *dev_cap, enum func_type type)
{
@@ -375,6 +414,9 @@ static void parse_dev_cap(struct hinic3_hwdev *dev,
if (IS_PPA_TYPE(dev))
parse_ppa_res_cap(dev, cap, dev_cap, type);
+
+ if (IS_VBS_TYPE(dev))
+ parse_vbs_res_cap(dev, cap, dev_cap, type);
}
static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
@@ -404,6 +446,23 @@ static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
return 0;
}
+u8 hinic3_get_bond_create_mode(void *dev)
+{
+ struct hinic3_hwdev *hwdev = NULL;
+ struct service_cap *cap = NULL;
+
+ if (!dev) {
+ pr_err("pointer dev is NULL\n");
+ return -EINVAL;
+ }
+
+ hwdev = (struct hinic3_hwdev *)dev;
+ cap = &hwdev->cfg_mgmt->svc_cap;
+
+ return cap->bond_create_mode;
+}
+EXPORT_SYMBOL(hinic3_get_bond_create_mode);
+
int hinic3_get_dev_cap(void *dev)
{
enum func_type type;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
index 671eed6..2f2310a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
@@ -166,6 +166,11 @@ struct service_cap {
u8 srv_multi_host_mode;
u16 virtio_vq_size;
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 os_hot_replace;
+ u8 rsvd1;
+
u8 timer_pf_num;
u8 timer_pf_id_start;
u16 timer_vf_num;
@@ -335,5 +340,7 @@ void free_capability(struct hinic3_hwdev *dev);
int hinic3_init_vf_dev_cap(void *hwdev);
+u8 hinic3_get_bond_create_mode(void *dev);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
index 8a87d25..cb3b609 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
@@ -21,6 +21,7 @@
#include "hinic3_hw_cfg.h"
#include "hinic3_cmdq.h"
#include "mpu_inband_cmd_defs.h"
+#include "vram_common.h"
#include "hinic3_hw_comm.h"
#define HINIC3_MSIX_CNT_LLI_TIMER_SHIFT 0
@@ -242,12 +243,19 @@ int hinic3_func_reset(void *dev, u16 func_id, u64 reset_flag, u16 channel)
struct hinic3_hwdev *hwdev = dev;
u16 out_size = sizeof(func_reset);
int err = 0;
+ int is_in_kexec;
if (!dev) {
pr_err("Invalid para: dev is null.\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ sdk_info(hwdev->dev_hdl, "Skip function reset!\n");
+ return 0;
+ }
+
sdk_info(hwdev->dev_hdl, "Function is reset, flag: 0x%llx, channel:0x%x\n",
reset_flag, channel);
@@ -554,7 +562,7 @@ EXPORT_SYMBOL(hinic3_set_ppf_flr_type);
int hinic3_set_ppf_tbl_hotreplace_flag(void *hwdev, u8 flag)
{
- struct comm_cmd_ppf_tbl_htrp_config htr_info = {0};
+ struct comm_cmd_ppf_tbl_htrp_config htr_info = {};
u16 out_size = sizeof(struct comm_cmd_ppf_tbl_htrp_config);
struct hinic3_hwdev *dev = hwdev;
int ret;
@@ -899,11 +907,19 @@ static int set_ppf_tmr_status(struct hinic3_hwdev *hwdev,
int hinic3_ppf_tmr_start(void *hwdev)
{
+ int is_in_kexec;
+
if (!hwdev) {
pr_err("Hwdev pointer is NULL for starting ppf timer\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ pr_info("Skip starting ppt timer during kexec");
+ return 0;
+ }
+
return set_ppf_tmr_status(hwdev, HINIC_PPF_TMR_FLAG_START);
}
EXPORT_SYMBOL(hinic3_ppf_tmr_start);
@@ -919,18 +935,114 @@ int hinic3_ppf_tmr_stop(void *hwdev)
}
EXPORT_SYMBOL(hinic3_ppf_tmr_stop);
+static int hi_vram_kalloc_align(struct hinic3_hwdev *hwdev, char *name, u32 page_size, u32 page_num,
+ struct hinic3_dma_addr_align *mem_align)
+{
+ void *vaddr = NULL, *align_vaddr = NULL;
+ dma_addr_t paddr, align_paddr;
+ u64 real_size = page_size;
+ u64 align = page_size;
+
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ /* align */
+ if (align_paddr == paddr) {
+ align_vaddr = vaddr;
+ goto out;
+ }
+
+ hi_vram_kfree((void *)vaddr, name, real_size);
+
+ /* realloc memory for align */
+ real_size = page_size + align;
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc align failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ align_vaddr = (void *)((u64)vaddr + (align_paddr - paddr));
+
+out:
+ mem_align->real_size = (u32)real_size;
+ mem_align->ori_vaddr = vaddr;
+ mem_align->ori_paddr = paddr;
+ mem_align->align_vaddr = align_vaddr;
+ mem_align->align_paddr = align_paddr;
+
+ return 0;
+}
+
+static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
+{
+ u32 i;
+ struct hinic3_dma_addr_align *page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = hwdev->mqm_eqm_vram_name;
+
+ page_addr = hwdev->mqm_att.brm_srch_page_addr;
+
+ for (i = 0; i < hwdev->mqm_att.page_num; i++) {
+ if (is_use_vram != 0) {
+ hi_vram_kfree(page_addr->ori_vaddr, mqm_eqm_vram_name[i].vram_name,
+ page_addr->real_size);
+ } else {
+ hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
+ }
+ page_addr->ori_vaddr = NULL;
+ page_addr++;
+ }
+
+ kfree(mqm_eqm_vram_name);
+ hwdev->mqm_eqm_vram_name = NULL;
+}
+
static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
u32 page_num)
{
struct hinic3_dma_addr_align *page_addr = hwdev->mqm_att.brm_srch_page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = NULL;
u32 valid_num = 0;
u32 flag = 1;
u32 i = 0;
int err;
+ u16 func_id;
+
+ mqm_eqm_vram_name = kcalloc(page_num, sizeof(struct mqm_eqm_vram_name_s), GFP_KERNEL);
+ if (mqm_eqm_vram_name == NULL) {
+ sdk_err(hwdev->dev_hdl, "mqm eqm alloc vram name failed.\n");
+ return -ENOMEM;
+ }
+
+ hwdev->mqm_eqm_vram_name = mqm_eqm_vram_name;
+ func_id = hinic3_global_func_id(hwdev);
for (i = 0; i < page_num; i++) {
- err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl, page_size,
- page_size, GFP_KERNEL, page_addr);
+ if (is_use_vram != 0) {
+ snprintf(mqm_eqm_vram_name[i].vram_name,
+ VRAM_NAME_MAX_LEN, "%s%hu%s%u",
+ VRAM_CQM_GLB_FUNC_BASE, func_id,
+ VRAM_NIC_MQM, i);
+ err = hi_vram_kalloc_align(hwdev,
+ mqm_eqm_vram_name[i].vram_name,
+ page_size, page_num,
+ page_addr);
+ } else {
+ err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl,
+ page_size,
+ page_size,
+ GFP_KERNEL,
+ page_addr);
+ }
if (err) {
flag = 0;
break;
@@ -939,15 +1051,12 @@ static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
page_addr++;
}
+ hwdev->mqm_att.page_num = valid_num;
+
if (flag == 1) {
hwdev->mqm_att.page_size = page_size;
- hwdev->mqm_att.page_num = page_num;
} else {
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
- for (i = 0; i < valid_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
+ mqm_eqm_free_page_mem(hwdev);
return -EFAULT;
}
@@ -986,19 +1095,6 @@ static int mqm_eqm_alloc_page_mem(struct hinic3_hwdev *hwdev)
return ret;
}
-static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
-{
- u32 i;
- struct hinic3_dma_addr_align *page_addr;
-
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
-
- for (i = 0; i < hwdev->mqm_att.page_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
-}
-
static int mqm_eqm_set_cfg_2_hw(struct hinic3_hwdev *hwdev, u8 valid)
{
struct comm_cmd_eqm_cfg info_eqm_cfg;
@@ -1129,6 +1225,7 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
{
struct comm_cmd_get_eqm_num info_eqm_fix;
int ret;
+ int is_in_kexec;
if (hwdev->hwif->attr.func_type != TYPE_PPF)
return 0;
@@ -1158,10 +1255,16 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
goto err_page;
}
- ret = mqm_eqm_set_page_2_hw(hwdev);
- if (ret) {
- sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
- goto err_ecmd;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ ret = mqm_eqm_set_page_2_hw(hwdev);
+ if (ret) {
+ sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
+ goto err_ecmd;
+ }
+ } else {
+ sdk_info(hwdev->dev_hdl,
+ "Mqm db don't set to chip when os hot replace.\r\n");
}
ret = mqm_eqm_set_cfg_2_hw(hwdev, 1);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
index e8aa7ef..722fecd 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
@@ -252,97 +252,6 @@ static u32 get_up_timeout_val(enum hinic3_mod_type mod, u16 cmd)
return 0; /* use default mbox/apichain timeout time */
}
-static int api_csr_read(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
-{
- struct up_log_msg_st *up_log_msg = (struct up_log_msg_st *)buf_in;
- u8 *buf_out_tmp = (u8 *)buf_out;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
-
- if (!buf_in || !buf_out || in_size != sizeof(*up_log_msg) ||
- *out_size != up_log_msg->rd_len || up_log_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = up_log_msg->rd_len;
- rd_addr = up_log_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_rd32(hwdev, node_id,
- rd_addr + offset,
- (u32 *)(buf_out_tmp + offset));
- if (ret) {
- pr_err("Csr rd fail, err: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, node_id, rd_addr + offset);
- return ret;
- }
- offset += DW_WIDTH;
- }
- *out_size = rd_len;
-
- return ret;
-}
-
-static int api_csr_write(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out,
- u32 *out_size)
-{
- struct csr_write_st *csr_write_msg = (struct csr_write_st *)buf_in;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
- u8 *data = NULL;
-
- if (!buf_in || in_size != sizeof(*csr_write_msg) || csr_write_msg->rd_len == 0 ||
- csr_write_msg->rd_len > API_CSR_MAX_RD_LEN || csr_write_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = csr_write_msg->rd_len;
- rd_addr = csr_write_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- data = kzalloc(rd_len, GFP_KERNEL);
- if (!data)
- return -EFAULT;
-
- if (copy_from_user(data, (void *)csr_write_msg->data, rd_len)) {
- pr_err("Copy information from user failed\n");
- kfree(data);
- return -EFAULT;
- }
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_wr32(hwdev, node_id,
- rd_addr + offset,
- *((u32 *)(data + offset)));
- if (ret) {
- pr_err("Csr wr fail, ret: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, rd_addr + offset, node_id);
- kfree(data);
- return ret;
- }
- offset += DW_WIDTH;
- }
-
- *out_size = 0;
- kfree(data);
- return ret;
-}
-
int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
@@ -369,10 +278,8 @@ int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
return ret;
}
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_BYPASS) {
- if (nt_msg->mpu_cmd.cmd == API_CSR_WRITE)
- return api_csr_write(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
-
- ret = api_csr_read(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
+ pr_err("Unsupported api_type %u\n", nt_msg->mpu_cmd.api_type);
+ return -EINVAL;
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_TO_MPU) {
timeout = get_up_timeout_val(mod, cmd);
if (hinic3_pcie_itf_id(hwdev) != SPU_HOST_ID)
@@ -439,6 +346,23 @@ static int sm_rd16(void *hwdev, u32 id, u8 instance,
return ret;
}
+static int sm_rd16_clear(void *hwdev, u32 id, u8 instance,
+ u8 node, struct sm_out_st *buf_out)
+{
+ u16 val1;
+ int ret;
+
+ ret = hinic3_sm_ctr_rd16_clear(hwdev, node, instance, id, &val1);
+ if (ret != 0) {
+ pr_err("Get sm ctr clear information (16 bits)failed!\n");
+ val1 = 0xffff;
+ }
+
+ buf_out->val1 = val1;
+
+ return ret;
+}
+
static int sm_rd32(void *hwdev, u32 id, u8 instance,
u8 node, struct sm_out_st *buf_out)
{
@@ -558,6 +482,7 @@ const struct sm_module_handle sm_module_cmd_handle[] = {
{SM_CTR_RD32, sm_rd32},
{SM_CTR_RD64_PAIR, sm_rd64_pair},
{SM_CTR_RD64, sm_rd64},
+ {SM_CTR_RD16_CLEAR, sm_rd16_clear},
{SM_CTR_RD32_CLEAR, sm_rd32_clear},
{SM_CTR_RD64_PAIR_CLEAR, sm_rd64_pair_clear},
{SM_CTR_RD64_CLEAR, sm_rd64_clear}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
index 83e7b63..c317f4a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
@@ -101,6 +101,12 @@ enum hinic3_pcie_tph {
#define SLAVE_HOST_STATUS_SET(host_id, enable) (((u8)(enable) & 1U) << (host_id))
#define SLAVE_HOST_STATUS_GET(host_id, val) (!!((val) & (1U << (host_id))))
+#ifdef HAVE_HOT_REPLACE_FUNC
+ extern int get_partition_id(void);
+#else
+ static int get_partition_id(void) {return 0; }
+#endif
+
void set_slave_host_enable(void *hwdev, u8 host_id, bool enable)
{
u32 reg_val;
@@ -207,6 +213,27 @@ static void hinic3_init_host_mode_pre(struct hinic3_hwdev *hwdev)
}
}
+static void hinic3_init_hot_plug_status(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->hot_plug_disable)
+ hwdev->hot_plug_mode = HOT_PLUG_DISABLE;
+ else
+ hwdev->hot_plug_mode = HOT_PLUG_ENABLE;
+}
+
+static void hinic3_init_os_hot_replace(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->os_hot_replace) {
+ hwdev->hot_replace_mode = HOT_REPLACE_ENABLE;
+ } else {
+ hwdev->hot_replace_mode = HOT_REPLACE_DISABLE;
+ }
+}
+
static u8 hinic3_nic_sw_aeqe_handler(void *hwdev, u8 event, u8 *data)
{
struct hinic3_hwdev *dev = hwdev;
@@ -270,14 +297,20 @@ static void chip_fault_show(struct hinic3_hwdev *hwdev,
"fatal", "reset", "host", "flr", "general", "suggestion"};
char level_str[FAULT_SHOW_STR_LEN + 1];
u8 level;
+ int ret;
memset(level_str, 0, FAULT_SHOW_STR_LEN + 1);
level = event->event.chip.err_level;
- if (level < FAULT_LEVEL_MAX)
- strscpy(level_str, fault_level[level],
- FAULT_SHOW_STR_LEN);
- else
- strscpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (level < FAULT_LEVEL_MAX) {
+ ret = strscpy(level_str, fault_level[level],
+ FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ } else {
+ ret = strscpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ }
if (level == FAULT_LEVEL_SERIOUS_FLR)
dev_err(hwdev->dev_hdl, "err_level: %u [%s], flr func_id: %u\n",
@@ -299,6 +332,7 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
"reg rd timeout", "reg wr timeout", "phy fault", "tsensor fault"};
char type_str[FAULT_SHOW_STR_LEN + 1] = {0};
struct fault_event_stats *fault = NULL;
+ int ret;
sdk_err(hwdev->dev_hdl, "Fault event report received, func_id: %u\n",
hinic3_global_func_id(hwdev));
@@ -306,10 +340,14 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
fault = &hwdev->hw_stats.fault_event_stats;
if (event->type < FAULT_TYPE_MAX) {
- strscpy(type_str, fault_type[event->type], sizeof(type_str));
+ ret = strscpy(type_str, fault_type[event->type], sizeof(type_str));
+ if (ret < 0)
+ return;
atomic_inc(&fault->fault_type_stat[event->type]);
} else {
- strscpy(type_str, "Unknown", sizeof(type_str));
+ ret = strscpy(type_str, "Unknown", sizeof(type_str));
+ if (ret < 0)
+ return;
}
sdk_err(hwdev->dev_hdl, "Fault type: %u [%s]\n", event->type, type_str);
@@ -1536,15 +1574,29 @@ int hinic3_init_hwdev(struct hinic3_init_para *para)
hinic3_init_host_mode_pre(hwdev);
+ hinic3_init_hot_plug_status(hwdev);
+
+ hinic3_init_os_hot_replace(hwdev);
+
err = hinic3_multi_host_mgmt_init(hwdev);
if (err != 0) {
sdk_err(hwdev->dev_hdl, "Failed to init function mode\n");
goto init_multi_host_fail;
}
- err = hinic3_init_ppf_work(hwdev);
- if (err != 0)
- goto init_ppf_work_fail;
+ // hot_replace_mode is enable, run ppf function only when partition_id is 0
+ // or run ppf function directly
+ if (hwdev->hot_replace_mode == HOT_REPLACE_ENABLE) {
+ if (get_partition_id() == 0) {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0)
+ goto init_ppf_work_fail;
+ }
+ } else {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0)
+ goto init_ppf_work_fail;
+ }
err = hinic3_set_comm_features(hwdev, hwdev->features, COMM_MAX_FEATURE_QWORD);
if (err != 0) {
@@ -1948,6 +2000,19 @@ void hinic3_link_event_stats(void *dev, u8 link)
}
EXPORT_SYMBOL(hinic3_link_event_stats);
+int hinic3_get_link_event_stats(void *dev, int *link_state)
+{
+ struct hinic3_hwdev *hwdev = dev;
+
+ if (!hwdev || !link_state)
+ return -EINVAL;
+
+ *link_state = hwdev->hw_stats.link_event_stats.link_down_stats.counter;
+
+ return 0;
+}
+EXPORT_SYMBOL(hinic3_get_link_event_stats);
+
u8 hinic3_max_pf_num(void *hwdev)
{
if (!hwdev)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
index b8a3356..0ca639f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
@@ -10,6 +10,7 @@
#include "hinic3_hw.h"
#include "mpu_inband_cmd_defs.h"
#include "hinic3_profile.h"
+#include "vram_common.h"
struct cfg_mgmt_info;
@@ -82,6 +83,22 @@ enum hinic3_host_mode_e {
HINIC3_SDI_MODE_MAX,
};
+enum hinic3_hot_plug_mode {
+ HOT_PLUG_ENABLE,
+ HOT_PLUG_DISABLE,
+};
+
+enum hinic3_os_hot_replace_mode {
+ HOT_REPLACE_DISABLE,
+ HOT_REPLACE_ENABLE,
+};
+
+#define UNSUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_DISABLE)
+
+#define SUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_ENABLE)
+
#define MULTI_HOST_CHIP_MODE_SHIFT 0
#define MULTI_HOST_MASTER_MBX_STS_SHIFT 17
#define MULTI_HOST_PRIV_DATA_SHIFT 0x8
@@ -100,6 +117,10 @@ enum hinic3_host_mode_e {
((val) & (~(MULTI_HOST_##member##_MASK \
<< MULTI_HOST_##member##_SHIFT)))
+struct mqm_eqm_vram_name_s {
+ char vram_name[VRAM_NAME_MAX_LEN];
+};
+
struct hinic3_hwdev {
void *adapter_hdl; /* pointer to hinic3_pcidev or NDIS_Adapter */
void *pcidev_hdl; /* pointer to pcidev or Handler */
@@ -138,6 +159,9 @@ struct hinic3_hwdev {
u32 rsvd2;
struct hinic3_multi_host_mgmt *mhost_mgmt;
+ char mhost_mgmt_name[VRAM_NAME_MAX_LEN];
+
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name;
struct mutex stateful_mutex; /* protect cqm init and deinit */
@@ -170,6 +194,8 @@ struct hinic3_hwdev {
struct hinic3_devlink *devlink_dev;
enum hinic3_func_mode func_mode;
+ enum hinic3_hot_plug_mode hot_plug_mode;
+ enum hinic3_os_hot_replace_mode hot_replace_mode;
u32 rsvd3;
DECLARE_BITMAP(func_probe_in_host, MAX_FUNCTION_NUM);
@@ -179,7 +205,10 @@ struct hinic3_hwdev {
u64 last_recv_aeq_cnt;
u16 aeq_busy_cnt;
- u64 rsvd4[8];
+ u64 mbox_send_cnt;
+ u64 mbox_ack_cnt;
+
+ u64 rsvd4[5];
u8 cmdq_mode;
};
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
index 33f1210..8590f70 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
@@ -544,6 +544,7 @@ static void free_db_area(struct hinic3_free_db_area *free_db_area)
{
spin_lock_deinit(&free_db_area->idx_lock);
kfree(free_db_area->db_bitmap_array);
+ free_db_area->db_bitmap_array = NULL;
}
static int get_db_idx(struct hinic3_hwif *hwif, u32 *idx)
@@ -841,6 +842,7 @@ void hinic3_free_hwif(struct hinic3_hwdev *hwdev)
free_db_area(&hwdev->hwif->free_db_area);
enable_all_msix(hwdev);
kfree(hwdev->hwif);
+ hwdev->hwif = NULL;
}
u16 hinic3_global_func_id(void *hwdev)
@@ -856,6 +858,44 @@ u16 hinic3_global_func_id(void *hwdev)
}
EXPORT_SYMBOL(hinic3_global_func_id);
+/**
+ * get function id from register,used by sriov hot migration process
+ * @hwdev: the pointer to hw device
+ */
+u16 hinic3_global_func_id_hw(void *hwdev)
+{
+ u32 addr, attr0;
+ struct hinic3_hwdev *dev;
+
+ dev = (struct hinic3_hwdev *)hwdev;
+ addr = HINIC3_CSR_FUNC_ATTR0_ADDR;
+ attr0 = hinic3_hwif_read_reg(dev->hwif, addr);
+
+ return HINIC3_AF0_GET(attr0, FUNC_GLOBAL_IDX);
+}
+
+/**
+ * get function id, used by sriov hot migratition process.
+ * @hwdev: the pointer to hw device
+ * @func_id: function id
+ */
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id)
+{
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)hwdev;
+
+ if (!hwdev || !func_id)
+ return -EINVAL;
+
+ /* only vf get func_id from chip reg for sriov migrate */
+ if (!HINIC3_IS_VF(dev)) {
+ *func_id = hinic3_global_func_id(hwdev);
+ return 0;
+ }
+
+ *func_id = hinic3_global_func_id_hw(dev);
+ return 0;
+}
+
u16 hinic3_intr_num(void *hwdev)
{
struct hinic3_hwif *hwif = NULL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
index 6ab1b92..6650572 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
@@ -16,6 +16,7 @@
#include <linux/rtc.h>
#include <linux/aer.h>
#include <linux/debugfs.h>
+#include <linux/notifier.h>
#include "ossl_knl.h"
#include "hinic3_mt.h"
@@ -26,13 +27,38 @@
#include "hinic3_dev_mgmt.h"
#include "hinic3_nictool.h"
#include "hinic3_hw.h"
+#include "hinic3_multi_host_mgmt.h"
+#include "hinic3_hw_cfg.h"
#include "hinic3_lld.h"
#include "hinic3_profile.h"
#include "hinic3_hwdev.h"
#include "hinic3_prof_adap.h"
-#include "comm_msg_intf.h"
+#include "hinic3_devlink.h"
+#include "vram_common.h"
+
+enum partition_dev_type {
+ PARTITION_DEV_NONE = 0,
+ PARTITION_DEV_SHARED,
+ PARTITION_DEV_EXCLUSIVE,
+ PARTITION_DEV_BACKUP,
+};
+
+#ifdef HAVE_HOT_REPLACE_FUNC
+static int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type,
+ unsigned int partition_id);
+static int get_partition_id(void);
+#else
+static int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type,
+ unsigned int partition_id)
+{
+ return 0;
+}
+static int get_partition_id(void) { return 0; }
+#endif
+
+static bool g_is_pf_migrated;
static bool disable_vf_load;
module_param(disable_vf_load, bool, 0444);
MODULE_PARM_DESC(disable_vf_load,
@@ -44,10 +70,12 @@ MODULE_PARM_DESC(disable_attach, "disable_attach or not - default is false");
#define HINIC3_WAIT_SRIOV_CFG_TIMEOUT 15000
-MODULE_AUTHOR("Huawei Technologies CO., Ltd");
-MODULE_DESCRIPTION(HINIC3_DRV_DESC);
-MODULE_VERSION(HINIC3_DRV_VERSION);
-MODULE_LICENSE("GPL");
+#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
+static DEVICE_ATTR_RW(sriov_numvfs, 0644,
+ sriov_numvfs_show, sriov_numvfs_store);
+static DEVICE_ATTR_RO(sriov_totalvfs, 0444,
+ sriov_totalvfs_show, NULL);
+#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
static struct attribute *hinic3_attributes[] = {
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
@@ -64,7 +92,18 @@ static const struct attribute_group hinic3_attr_group = {
struct hinic3_uld_info g_uld_info[SERVICE_T_MAX] = { {0} };
#define HINIC3_EVENT_PROCESS_TIMEOUT 10000
+#define HINIC3_WAIT_EVENT_PROCESS_TIMEOUT 100
struct mutex g_uld_mutex; /* g_uld_info lock */
+#define BUS_MAX_DEV_NUM 256
+#define HINIC3_SLAVE_WORK_MAX_NUM 20
+
+struct vf_offset_info {
+ u8 valid;
+ u16 vf_offset_from_pf[CMD_MAX_MAX_PF_NUM];
+};
+
+static struct vf_offset_info g_vf_offset;
+DEFINE_MUTEX(g_vf_offset_lock);
void hinic3_uld_lock_init(void)
{
@@ -73,13 +112,23 @@ void hinic3_uld_lock_init(void)
static const char *s_uld_name[SERVICE_T_MAX] = {
"nic", "ovs", "roce", "toe", "ioe",
- "fc", "vbs", "ipsec", "virtio", "migrate", "ppa", "bifur", "custom"};
+ "fc", "vbs", "ipsec", "virtio", "migrate",
+ "ppa", "custom", "vroce", "crypt", "vsock", "bifur"};
const char **hinic3_get_uld_names(void)
{
return s_uld_name;
}
+#ifdef CONFIG_PCI_IOV
+static int hinic3_get_pf_device_id(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_dev = pci_physfn(pdev);
+
+ return pf_dev->device;
+}
+#endif
+
static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
const struct hinic3_uld_info *uld_info)
{
@@ -98,6 +147,10 @@ static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
atomic_set(&dev->uld_ref_cnt[type], 0);
+ if (!uld_info->probe) {
+ err = 0;
+ goto out_unlock;
+ }
err = uld_info->probe(&dev->lld_dev, &uld_dev, dev->uld_dev_name[type]);
if (err) {
sdk_err(&dev->pcidev->dev,
@@ -166,6 +219,10 @@ static void detach_uld(struct hinic3_pcidev *dev,
wait_uld_unused(dev, type);
+ if (!uld_info->remove) {
+ mutex_unlock(&dev->pdev_mutex);
+ return;
+ }
uld_info->remove(&dev->lld_dev, dev->uld_dev[type]);
dev->uld_dev[type] = NULL;
@@ -182,11 +239,14 @@ static void attach_ulds(struct hinic3_pcidev *dev)
{
enum hinic3_service_type type;
struct pci_dev *pdev = dev->pcidev;
+ int is_in_kexec = vram_get_kexec_flag();
+
+ if (is_in_kexec == 0)
+ lld_hold();
- lld_hold();
mutex_lock(&g_uld_mutex);
- for (type = SERVICE_T_NIC; type < SERVICE_T_MAX; type++) {
+ for (type = SERVICE_T_OVS; type < SERVICE_T_MAX; type++) {
if (g_uld_info[type].probe) {
if (pdev->is_virtfn &&
(!hinic3_get_vf_service_load(pdev, (u16)type))) {
@@ -198,7 +258,9 @@ static void attach_ulds(struct hinic3_pcidev *dev)
}
}
mutex_unlock(&g_uld_mutex);
- lld_put();
+
+ if (is_in_kexec == 0)
+ lld_put();
}
static void detach_ulds(struct hinic3_pcidev *dev)
@@ -305,7 +367,7 @@ void hinic3_unregister_uld(enum hinic3_service_type type)
}
uld_info = &g_uld_info[type];
- memset(uld_info, 0, sizeof(*uld_info));
+ memset(uld_info, 0, sizeof(struct hinic3_uld_info));
mutex_unlock(&g_uld_mutex);
lld_put();
}
@@ -359,6 +421,26 @@ void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_ser
}
EXPORT_SYMBOL(hinic3_detach_service);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ __module_get(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_get);
+
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ module_put(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_put);
+
static void hinic3_sync_time_to_fmw(struct hinic3_pcidev *pdev_pri)
{
struct timeval tv = {0};
@@ -441,23 +523,447 @@ static void send_event_to_all_pf(struct hinic3_pcidev *dev,
lld_put();
}
+u32 hinic3_pdev_is_virtfn(struct pci_dev *pdev)
+{
+#ifdef CONFIG_PCI_IOV
+ return pdev->is_virtfn;
+#else
+ return 0;
+#endif
+}
+
+static int hinic3_get_function_enable(struct pci_dev *pdev, bool *en)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+ int err;
+
+ /* PF in host os or function in guest os, probe sdk in default */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev) {
+ *en = true;
+ return 0;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev) {
+ /* vf in host and pf sdk not probed */
+ return -EFAULT;
+ }
+ pf_hwdev = pci_adapter->hwdev;
+
+ err = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (err) {
+ sdk_err(&pci_adapter->pcidev->dev,
+ "Func hinic3_get_vfid_by_vfpci fail %d\n", err);
+ return err;
+ }
+
+ err = hinic3_get_func_nic_enable(pf_hwdev, global_func_id, en);
+ if (!!err) {
+ sdk_info(&pdev->dev, "Failed to get function nic status, err %d.\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+int hinic3_set_func_probe_in_host(void *hwdev, u16 func_id, bool probe)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (hinic3_func_type(hwdev) != TYPE_PPF)
+ return -EINVAL;
+
+ if (probe)
+ set_bit(func_id, dev->func_probe_in_host);
+ else
+ clear_bit(func_id, dev->func_probe_in_host);
+
+ return 0;
+}
+
+bool hinic3_get_func_probe_in_host(void *hwdev, u16 func_id)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+ bool probed = false;
+
+ if (!hwdev)
+ return false;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return false;
+ }
+
+ probed = !!test_bit(func_id, ppf_dev->func_probe_in_host);
+ up(&dev->ppf_sem);
+
+ return probed;
+}
+
+void *hinic3_get_ppf_hwdev_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ chip_node = pci_adapter->chip_node;
+ lld_dev_hold(&pci_adapter->lld_dev);
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (dev->lld_state == HINIC3_IN_REMOVE)
+ continue;
+
+ if (dev->hwdev && hinic3_func_type(dev->hwdev) == TYPE_PPF) {
+ lld_dev_put(&pci_adapter->lld_dev);
+ return dev->hwdev;
+ }
+ }
+ lld_dev_put(&pci_adapter->lld_dev);
+
+ return NULL;
+}
+
+static int hinic3_set_vf_nic_used_state(void *hwdev, u16 func_id, bool opened)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+
+ if (!dev || func_id >= MAX_FUNCTION_NUM)
+ return -EINVAL;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return -EINVAL;
+ }
+
+ if (opened)
+ set_bit(func_id, ppf_dev->netdev_setup_state);
+ else
+ clear_bit(func_id, ppf_dev->netdev_setup_state);
+
+ up(&dev->ppf_sem);
+
+ return 0;
+}
+
+static void set_vf_func_in_use(struct pci_dev *pdev, bool in_use)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+
+ /* only need to be set when VF is on the host */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev)
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev)
+ return;
+
+ pf_hwdev = pci_adapter->hwdev;
+
+ global_func_id = (u16)pdev->devfn + hinic3_glb_pf_vf_offset(pf_hwdev);
+ (void)hinic3_set_vf_nic_used_state(pf_hwdev, global_func_id, in_use);
+}
+
+
+static int hinic3_pf_get_vf_offset_info(struct hinic3_pcidev *des_dev, u16 *vf_offset)
+{
+ int err, i;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ u16 pf_func_id;
+ struct hinic3_pcidev *pf_pci_adapter = NULL;
+
+ pf_pci_adapter = (hinic3_pdev_is_virtfn(des_dev->pcidev)) ?
+ pci_get_drvdata(des_dev->pcidev->physfn) : des_dev;
+ pf_func_id = hinic3_global_func_id(pf_pci_adapter->hwdev);
+ if (pf_func_id >= CMD_MAX_MAX_PF_NUM || !vf_offset)
+ return -EINVAL;
+
+ mutex_lock(&g_vf_offset_lock);
+ if (g_vf_offset.valid == 0) {
+ pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ sdk_err(&pf_pci_adapter->pcidev->dev, "Malloc pf_infos fail\n");
+ err = -ENOMEM;
+ goto err_malloc;
+ }
+
+ err = hinic3_get_hw_pf_infos(pf_pci_adapter->hwdev,
+ pf_infos, HINIC3_CHANNEL_COMM);
+ if (err) {
+ sdk_warn(&pf_pci_adapter->pcidev->dev,
+ "Hinic3_get_hw_pf_infos fail err %d\n", err);
+ err = -EFAULT;
+ goto err_out;
+ }
+
+ g_vf_offset.valid = 1;
+ for (i = 0; i < CMD_MAX_MAX_PF_NUM; i++)
+ g_vf_offset.vf_offset_from_pf[i] = pf_infos->infos[i].vf_offset;
+
+ kfree(pf_infos);
+ }
+
+ *vf_offset = g_vf_offset.vf_offset_from_pf[pf_func_id];
+
+ mutex_unlock(&g_vf_offset_lock);
+
+ return 0;
+
+err_out:
+ kfree(pf_infos);
+err_malloc:
+ mutex_unlock(&g_vf_offset_lock);
+ return err;
+}
+
+static struct pci_dev *get_vf_pdev_by_pf(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ int err;
+ u16 bus_num;
+ u16 vf_start, vf_end;
+ u16 des_fn, pf_func_id, vf_offset;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ pf_func_id = hinic3_global_func_id(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end || pf_func_id >= CMD_MAX_MAX_PF_NUM)
+ return NULL;
+
+ err = hinic3_pf_get_vf_offset_info(des_dev, &vf_offset);
+ if (err) {
+ sdk_warn(&des_dev->pcidev->dev, "Hinic3_pf_get_vf_offset_info fail\n");
+ return NULL;
+ }
+
+ des_fn = ((func_id - vf_start) - 1) + pf_func_id + vf_offset;
+ bus_num = des_dev->pcidev->bus->number + des_fn / BUS_MAX_DEV_NUM;
+
+ return pci_get_domain_bus_and_slot(0, bus_num, (des_fn % BUS_MAX_DEV_NUM));
+}
+
+static struct hinic3_pcidev *get_des_pci_adapter(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ struct pci_dev *des_pdev = NULL;
+ u16 vf_start, vf_end;
+ bool probe_in_host = false;
+
+ if (hinic3_global_func_id(des_dev->hwdev) == func_id)
+ return des_dev;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end)
+ return NULL;
+
+ des_pdev = get_vf_pdev_by_pf(des_dev, func_id);
+ if (!des_pdev)
+ return NULL;
+
+ pci_dev_put(des_pdev);
+
+ probe_in_host = hinic3_get_func_probe_in_host(des_dev->hwdev, func_id);
+ if (!probe_in_host)
+ return NULL;
+
+ return pci_get_drvdata(des_pdev);
+}
+
+int __set_vroce_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ u8 enable_vroce = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_vroce_enable(pci_adapter->hwdev,
+ func_id, &enable_vroce);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Failed to get vroce state.\n");
+ return err;
+ }
+
+ mutex_lock(&g_uld_mutex);
+
+ if (!!enable_vroce) {
+ if (!g_uld_info[SERVICE_T_ROCE].probe) {
+ sdk_info(&pdev->dev, "Uld(roce_info) has not been registered!\n");
+ mutex_unlock(&g_uld_mutex);
+ return 0;
+ }
+
+ err = attach_uld(pci_adapter, SERVICE_T_ROCE,
+ &g_uld_info[SERVICE_T_ROCE]);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Failed to initialize VROCE.\n");
+ mutex_unlock(&g_uld_mutex);
+ return err;
+ }
+ } else {
+ sdk_info(&pdev->dev, "Func %u vroce state: disable.\n", func_id);
+ if (g_uld_info[SERVICE_T_ROCE].remove)
+ detach_uld(pci_adapter, SERVICE_T_ROCE);
+ }
+
+ mutex_unlock(&g_uld_mutex);
+
+ return 0;
+}
+
+void slave_host_mgmt_vroce_work(struct work_struct *work)
+{
+#ifndef __HIFC__
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_vroce_work);
+
+ __set_vroce_func_state(pci_adapter);
+#endif
+}
+
+void *hinic3_get_roce_uld_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ return pci_adapter->uld_dev[SERVICE_T_ROCE];
+}
+
+static int func_service_state_process(struct hinic3_pcidev *event_dev,
+ struct hinic3_pcidev *des_dev,
+ struct hinic3_mhost_nic_func_state *state,
+ u16 cmd)
+{
+ int err = 0;
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)event_dev->hwdev;
+
+ switch (cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ state->enable = hinic3_get_roce_uld_by_pdev(des_dev->pcidev) ? 1 : 0;
+ break;
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive nic[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ if (event_dev->multi_host_mgmt_workq) {
+ queue_work(event_dev->multi_host_mgmt_workq,
+ &des_dev->slave_nic_work);
+ } else {
+ sdk_err(&des_dev->pcidev->dev, "Can not schedule slave nic work\n");
+ err = -EFAULT;
+ }
+ break;
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive vroce[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ queue_work_on(hisdk3_get_work_cpu_affinity(dev, WORK_TYPE_MBOX),
+ event_dev->multi_host_mgmt_workq,
+ &des_dev->slave_vroce_work);
+ break;
+ default:
+ sdk_warn(&des_dev->pcidev->dev,
+ "Service state process with unknown cmd: %u\n", cmd);
+ err = -EFAULT;
+ break;
+ }
+
+ return err;
+}
+
+static void multi_host_mgmt(struct hinic3_pcidev *dev,
+ struct hinic3_multi_host_mgmt_event *mhost_mgmt)
+{
+ struct hinic3_pcidev *cur_dev = NULL;
+ struct hinic3_pcidev *des_dev = NULL;
+ struct hinic3_mhost_nic_func_state *nic_state = NULL;
+ u16 sub_cmd = mhost_mgmt->sub_cmd;
+
+ switch (sub_cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ nic_state = mhost_mgmt->data;
+ nic_state->status = 0;
+ if (!dev->hwdev)
+ return;
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)dev->hwdev))
+ return;
+
+ /* find func_idx pci_adapter and disable or enable nic */
+ lld_dev_hold(&dev->lld_dev);
+ list_for_each_entry(cur_dev, &dev->chip_node->func_list, node) {
+ if (cur_dev->lld_state == HINIC3_IN_REMOVE ||
+ hinic3_pdev_is_virtfn(cur_dev->pcidev))
+ continue;
+
+ des_dev = get_des_pci_adapter(cur_dev, nic_state->func_idx);
+ if (!des_dev)
+ continue;
+
+ if (func_service_state_process(dev, des_dev, nic_state, sub_cmd))
+ nic_state->status = 1;
+ break;
+ }
+ lld_dev_put(&dev->lld_dev);
+ break;
+ default:
+ sdk_warn(&dev->pcidev->dev, "Received unknown multi-host mgmt event: %u\n",
+ mhost_mgmt->sub_cmd);
+ break;
+ }
+}
+
static void hinic3_event_process(void *adapter, struct hinic3_event_info *event)
{
struct hinic3_pcidev *dev = adapter;
struct hinic3_fault_event *fault = (void *)event->event_data;
+ struct hinic3_multi_host_mgmt_event *mhost_event =
+ (void *)event->event_data;
u16 func_id;
- if ((event->service == EVENT_SRV_COMM && event->type == EVENT_COMM_FAULT) &&
- fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
- fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
- func_id = fault->event.chip.func_id;
- return send_event_to_dst_pf(adapter, func_id, event);
- }
-
- if (event->type == EVENT_COMM_MGMT_WATCHDOG)
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MULTI_HOST_MGMT):
+ multi_host_mgmt(dev, mhost_event);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_FAULT):
+ if (fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
+ fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
+ func_id = fault->event.chip.func_id;
+ return send_event_to_dst_pf(adapter, func_id, event);
+ }
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MGMT_WATCHDOG):
send_event_to_all_pf(adapter, event);
- else
+ break;
+ default:
send_uld_dev_event(adapter, event);
+ break;
+ }
}
static void uld_def_init(struct hinic3_pcidev *pci_adapter)
@@ -605,31 +1111,70 @@ static void hinic3_pci_deinit(struct pci_dev *pdev)
kfree(pci_adapter);
}
-#ifdef CONFIG_X86
-/**
- * cfg_order_reg - when cpu model is haswell or broadwell, should configure dma
- * order register to zero
- * @pci_adapter: pci_adapter
- **/
-/*lint -save -e40 */
-static void cfg_order_reg(struct hinic3_pcidev *pci_adapter)
+static void set_vf_load_state(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
{
- u8 cpu_model[] = {0x3c, 0x3f, 0x45, 0x46, 0x3d, 0x47, 0x4f, 0x56};
- struct cpuinfo_x86 *cpuinfo = NULL;
- u32 i;
+ /* In bm mode, slave host will load vfs in default */
+ if (IS_BMGW_SLAVE_HOST(((struct hinic3_hwdev *)pci_adapter->hwdev)) &&
+ hinic3_func_type(pci_adapter->hwdev) != TYPE_VF)
+ hinic3_set_vf_load_state(pdev, false);
- if (hinic3_func_type(pci_adapter->hwdev) == TYPE_VF)
- return;
+ if (!disable_attach) {
+ if ((hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) &&
+ hinic3_is_bm_slave_host(pci_adapter->hwdev)) {
+ if (hinic3_func_max_vf(pci_adapter->hwdev) == 0) {
+ sdk_warn(&pdev->dev, "The sriov enabling process is skipped, vfs_num: 0.\n");
+ return;
+ }
+ hinic3_pci_sriov_enable(
+ pdev, hinic3_func_max_vf(pci_adapter->hwdev));
+ }
+ }
+}
- cpuinfo = &cpu_data(0);
- for (i = 0; i < sizeof(cpu_model); i++) {
- if (cpu_model[i] == cpuinfo->x86_model)
- hinic3_set_pcie_order_cfg(pci_adapter->hwdev);
+static void hinic3_init_ppf_hwdev(struct hinic3_hwdev *hwdev)
+{
+ if (!hwdev) {
+ pr_err("[%s:%d] null hwdev pointer\n", __FILE__, __LINE__);
+ return;
}
+
+ hwdev->ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(hwdev->pcidev_hdl);
}
-/*lint -restore*/
-#endif
+static int set_nic_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ bool enable_nic = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_nic_enable(pci_adapter->hwdev, func_id, &enable_nic);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Failed to get nic state.\n");
+ return err;
+ }
+
+ if (!enable_nic) {
+ sdk_info(&pdev->dev, "Func %u nic state: disable.\n", func_id);
+ detach_uld(pci_adapter, SERVICE_T_NIC);
+ return 0;
+ }
+
+ if (IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ (void)hinic3_init_vf_dev_cap(pci_adapter->hwdev);
+
+ if (g_uld_info[SERVICE_T_NIC].probe) {
+ err = attach_uld(pci_adapter, SERVICE_T_NIC, &g_uld_info[SERVICE_T_NIC]);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Initialize NIC failed\n");
+ return err;
+ }
+ }
+
+ return 0;
+}
static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
{
@@ -689,7 +1234,16 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
list_add_tail(&pci_adapter->node, &pci_adapter->chip_node->func_list);
lld_unlock_chip_node();
+ hinic3_init_ppf_hwdev((struct hinic3_hwdev *)pci_adapter->hwdev);
+
+ set_vf_load_state(pdev, pci_adapter);
+
if (!disable_attach) {
+ /* NIC is base driver, probe firstly */
+ err = set_nic_func_state(pci_adapter);
+ if (err)
+ goto set_nic_func_state_err;
+
attach_ulds(pci_adapter);
if (hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) {
@@ -700,10 +1254,6 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
goto create_sysfs_err;
}
}
-
-#ifdef CONFIG_X86
- cfg_order_reg(pci_adapter);
-#endif
}
return 0;
@@ -711,6 +1261,8 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
create_sysfs_err:
detach_ulds(pci_adapter);
+
+set_nic_func_state_err:
lld_lock_chip_node();
list_del(&pci_adapter->node);
lld_unlock_chip_node();
@@ -759,6 +1311,7 @@ static void hinic3_func_deinit(struct pci_dev *pdev)
hinic3_free_stateful(pci_adapter->hwdev);
hinic3_free_hwdev(pci_adapter->hwdev);
+ pci_adapter->hwdev = NULL;
}
static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
@@ -770,14 +1323,57 @@ static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
clear_bit(HINIC3_FUNC_PERSENT, &sriov_info->state);
usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- end = jiffies + msecs_to_jiffies(HINIC3_WAIT_SRIOV_CFG_TIMEOUT);
- do {
- if (!test_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state) &&
- !test_bit(HINIC3_SRIOV_DISABLE, &sriov_info->state))
- return;
+ end = jiffies + msecs_to_jiffies(HINIC3_WAIT_SRIOV_CFG_TIMEOUT);
+ do {
+ if (!test_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state) &&
+ !test_bit(HINIC3_SRIOV_DISABLE, &sriov_info->state))
+ return;
+
+ usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
+ } while (time_before(jiffies, end));
+}
+
+static bool hinic3_get_vf_nic_en_status(struct pci_dev *pdev)
+{
+ bool nic_en = false;
+ u16 global_func_id;
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev) {
+ pr_err("pdev is null.\n");
+ return false;
+ }
+
+ if (pdev->is_virtfn)
+ pf_pdev = pdev->physfn;
+ else
+ return false;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return false;
+ }
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ return false;
+
+ if (hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id)) {
+ sdk_err(&pdev->dev, "Get vf id by vfpci failed\n");
+ return false;
+ }
+
+ if (hinic3_get_mhost_func_nic_enable(pci_adapter->hwdev,
+ global_func_id, &nic_en)) {
+ sdk_err(&pdev->dev, "Get function nic status failed\n");
+ return false;
+ }
+
+ sdk_info(&pdev->dev, "Func %hu %s default probe in host\n",
+ global_func_id, (nic_en) ? "enable" : "disable");
- usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- } while (time_before(jiffies, end));
+ return nic_en;
}
bool hinic3_get_vf_load_state(struct pci_dev *pdev)
@@ -834,6 +1430,8 @@ int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state)
}
EXPORT_SYMBOL(hinic3_set_vf_load_state);
+
+
bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service)
{
struct hinic3_pcidev *pci_adapter = NULL;
@@ -897,6 +1495,32 @@ int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
}
EXPORT_SYMBOL(hinic3_set_vf_service_load);
+static bool hinic3_is_host_vmsec_enable(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct pci_dev *pf_pdev = NULL;
+
+ if (pdev->is_virtfn)
+ pf_pdev = pdev->physfn;
+ else
+ pf_pdev = pdev;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ pr_err("Pci_adapter is null.\n");
+ return false;
+ }
+
+ /* pf/vf used in host */
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ (hinic3_func_type(pci_adapter->hwdev) == TYPE_PF) &&
+ IS_RDMA_TYPE((struct hinic3_hwdev *)pci_adapter->hwdev)) {
+ return true;
+ }
+
+ return false;
+}
+
static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
@@ -910,6 +1534,13 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
pci_adapter->lld_state = HINIC3_IN_REMOVE;
mutex_unlock(&pci_adapter->pdev_mutex);
+ if (!(pdev->is_virtfn) && (hinic3_is_host_vmsec_enable(pdev) == true) &&
+ (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF)) {
+ cancel_delayed_work_sync(&pci_adapter->migration_probe_dwork);
+ flush_workqueue(pci_adapter->migration_probe_workq);
+ destroy_workqueue(pci_adapter->migration_probe_workq);
+ }
+
hinic3_detect_hw_present(pci_adapter->hwdev);
hisdk3_remove_pre_process(pci_adapter->hwdev);
@@ -934,23 +1565,128 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
sdk_info(&pdev->dev, "Pcie device removed function\n");
+ set_vf_func_in_use(pdev, false);
+
return 0;
}
+int hinic3_get_vfid_by_vfpci(void *hwdev, struct pci_dev *pdev, u16 *global_func_id)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ u16 pf_bus, vf_bus, vf_offset;
+ int err;
+
+ if (!pdev || !global_func_id || !hinic3_pdev_is_virtfn(pdev))
+ return -EINVAL;
+ (void)hwdev;
+ pf_pdev = pdev->physfn;
+
+ vf_bus = pdev->bus->number;
+ pf_bus = pf_pdev->bus->number;
+
+ if (pdev->vendor == HINIC3_VIRTIO_VNEDER_ID)
+ return -EPERM;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return -EINVAL;
+ }
+
+ err = hinic3_pf_get_vf_offset_info(pci_adapter, &vf_offset);
+ if (err) {
+ sdk_err(&pdev->dev, "Func hinic3_pf_get_vf_offset_info fail\n");
+ return -EFAULT;
+ }
+
+ *global_func_id = (u16)((vf_bus - pf_bus) * BUS_MAX_DEV_NUM) + (u16)pdev->devfn +
+ (u16)(CMD_MAX_MAX_PF_NUM - g_vf_offset.vf_offset_from_pf[0]);
+
+ return 0;
+}
+EXPORT_SYMBOL(hinic3_get_vfid_by_vfpci);
+
+static void hinic3_set_vf_status_in_host(struct pci_dev *pdev, bool status)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ void *ppf_hwdev = NULL;
+ u16 global_func_id;
+ int ret;
+
+ if (!pf_pdev)
+ return;
+
+ if (!hinic3_pdev_is_virtfn(pdev))
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ pf_hwdev = pci_adapter->hwdev;
+ ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(pf_pdev);
+ if (!pf_hwdev || !ppf_hwdev)
+ return;
+
+ ret = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (ret) {
+ sdk_err(&pci_adapter->pcidev->dev,
+ "Func hinic3_get_vfid_by_vfpci fail %d\n", ret);
+ return;
+ }
+
+ ret = hinic3_set_func_probe_in_host(ppf_hwdev, global_func_id, status);
+ if (ret)
+ sdk_err(&pci_adapter->pcidev->dev,
+ "Set the function probe status in host failed\n");
+}
+
+#ifdef CONFIG_PCI_IOV
+/* Check whether pdev is a VF and whether it belongs to the PF of the SDI card */
+static bool check_pdev_type_and_state(struct pci_dev *pdev)
+{
+ if (!(pdev->is_virtfn))
+ return false;
+
+ if ((hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_1_PF) &&
+ (hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_0_PF)) {
+ return false;
+ }
+
+ if (!hinic3_get_vf_load_state(pdev))
+ return false;
+
+ return true;
+}
+#endif
+
static void hinic3_remove(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
+ sdk_info(&pdev->dev, "Pcie device remove begin\n");
+
if (!pci_adapter)
- return;
+ goto out;
- sdk_info(&pdev->dev, "Pcie device remove begin\n");
+
+#ifdef CONFIG_PCI_IOV
+ if (check_pdev_type_and_state(pdev))
+ goto out;
+#endif
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
hinic3_remove_func(pci_adapter);
+ if (!pci_adapter->pcidev->is_virtfn &&
+ pci_adapter->multi_host_mgmt_workq)
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
hinic3_pci_deinit(pdev);
hinic3_probe_pre_unprocess(pdev);
+out:
+ hinic3_set_vf_status_in_host(pdev, false);
sdk_info(&pdev->dev, "Pcie device removed\n");
}
@@ -969,7 +1705,7 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
if (pci_adapter->lld_state >= HINIC3_PROBE_START) {
sdk_warn(&pdev->dev, "Don not probe repeat\n");
mutex_unlock(&pci_adapter->pdev_mutex);
- return 0;
+ return -EEXIST;
}
pci_adapter->lld_state = HINIC3_PROBE_START;
mutex_unlock(&pci_adapter->pdev_mutex);
@@ -977,15 +1713,28 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
return 0;
}
+static void hinic3_probe_success_process(struct hinic3_pcidev *pci_adapter)
+{
+ hinic3_probe_success(pci_adapter->hwdev);
+
+ mutex_lock(&pci_adapter->pdev_mutex);
+ pci_adapter->lld_state = HINIC3_PROBE_OK;
+ mutex_unlock(&pci_adapter->pdev_mutex);
+}
+
static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
int err;
err = probe_func_param_init(pci_adapter);
- if (err)
+ if (err == -EEXIST)
+ return 0;
+ else if (err)
return err;
+ set_vf_func_in_use(pdev, true);
+
err = mapping_bar(pdev, pci_adapter);
if (err) {
sdk_err(&pdev->dev, "Failed to map bar\n");
@@ -1017,11 +1766,7 @@ static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
}
}
- hinic3_probe_success(pci_adapter->hwdev);
-
- mutex_lock(&pci_adapter->pdev_mutex);
- pci_adapter->lld_state = HINIC3_PROBE_OK;
- mutex_unlock(&pci_adapter->pdev_mutex);
+ hinic3_probe_success_process(pci_adapter);
return 0;
@@ -1037,18 +1782,298 @@ alloc_chip_node_fail:
unmapping_bar(pci_adapter);
map_bar_failed:
+ set_vf_func_in_use(pdev, false);
sdk_err(&pdev->dev, "Pcie device probe function failed\n");
return err;
}
+void hinic3_set_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int err;
+ bool enable_func = false;
+
+ err = hinic3_get_function_enable(pdev, &enable_func);
+ if (err) {
+ sdk_info(&pdev->dev, "Get function enable failed\n");
+ return;
+ }
+
+ sdk_info(&pdev->dev, "%s function resource start\n",
+ enable_func ? "Initialize" : "Free");
+ if (enable_func) {
+ err = hinic3_probe_func(pci_adapter);
+ if (err)
+ sdk_info(&pdev->dev, "Function probe failed\n");
+ } else {
+ hinic3_remove_func(pci_adapter);
+ }
+ if (err == 0)
+ sdk_info(&pdev->dev, "%s function resource end\n",
+ enable_func ? "Initialize" : "Free");
+}
+
+void slave_host_mgmt_work(struct work_struct *work)
+{
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_nic_work);
+
+ if (hinic3_pdev_is_virtfn(pci_adapter->pcidev))
+ hinic3_set_func_state(pci_adapter);
+ else
+ set_nic_func_state(pci_adapter);
+}
+
+static int pci_adapter_assign_val(struct hinic3_pcidev **ppci_adapter,
+ struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ *ppci_adapter = pci_get_drvdata(pdev);
+ (*ppci_adapter)->disable_vf_load = disable_vf_load;
+ (*ppci_adapter)->id = *id;
+ (*ppci_adapter)->lld_state = HINIC3_NOT_PROBE;
+ (*ppci_adapter)->probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ lld_dev_cnt_init(*ppci_adapter);
+
+ (*ppci_adapter)->multi_host_mgmt_workq = alloc_workqueue(
+ "hinic_mhost_mgmt",
+ WQ_UNBOUND,
+ HINIC3_SLAVE_WORK_MAX_NUM);
+ if (!(*ppci_adapter)->multi_host_mgmt_workq) {
+ hinic3_pci_deinit(pdev);
+ sdk_err(&pdev->dev, "Alloc multi host mgmt workqueue failed\n");
+ return -ENOMEM;
+ }
+
+ INIT_WORK(&(*ppci_adapter)->slave_nic_work, slave_host_mgmt_work);
+ INIT_WORK(&(*ppci_adapter)->slave_vroce_work,
+ slave_host_mgmt_vroce_work);
+
+ return 0;
+}
+
+static void slave_host_vfio_probe_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_pcidev *pci_adapter = container_of(delay, struct hinic3_pcidev,
+ migration_probe_dwork);
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int (*dev_migration_probe)(struct pci_dev *pdev);
+ int rc;
+
+ if (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) != TYPE_PF)
+ return;
+
+ dev_migration_probe = __symbol_get("migration_dev_migration_probe");
+ if (!(dev_migration_probe)) {
+ sdk_err(&pdev->dev,
+ "Failed to find: migration_dev_migration_probe");
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork,
+ WAIT_TIME * HZ);
+ } else {
+ rc = dev_migration_probe(pdev);
+ __symbol_put("migration_dev_migration_probe");
+ if (rc) {
+ sdk_err(&pdev->dev,
+ "Failed to __dev_migration_probe, rc:0x%x, pf migrated(%d).\n",
+ rc, g_is_pf_migrated);
+ } else {
+ g_is_pf_migrated = true;
+ sdk_info(&pdev->dev,
+ "Succeeded in __dev_migration_probe, pf migrated(%d).\n",
+ g_is_pf_migrated);
+ }
+ }
+}
+
+struct vf_add_delaywork {
+ struct pci_dev *vf_pdev;
+ struct delayed_work migration_vf_add_dwork;
+};
+
+static void slave_host_migration_vf_add_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct vf_add_delaywork *vf_add = container_of(delay, struct vf_add_delaywork,
+ migration_vf_add_dwork);
+ struct pci_dev *vf_pdev = vf_add->vf_pdev;
+ struct pci_dev *pf_pdev = NULL;
+ int (*migration_dev_add_vf)(struct pci_dev *vf_pdev);
+ int ret;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!vf_pdev) {
+ pr_err("vf pdev is null.\n");
+ goto err1;
+ }
+ if (!vf_pdev->is_virtfn) {
+ sdk_err(&vf_pdev->dev, "Pdev is not virtfn.\n");
+ goto err1;
+ }
+
+ pf_pdev = vf_pdev->physfn;
+ if (!pf_pdev) {
+ sdk_err(&vf_pdev->dev, "pf_pdev is null.\n");
+ goto err1;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&vf_pdev->dev, "Pci_adapter is null.\n");
+ goto err1;
+ }
+
+ if (!g_is_pf_migrated) {
+ sdk_info(&vf_pdev->dev, "pf is not migrated yet, so vf continues to try again.\n");
+ goto delay_work;
+ }
+
+ migration_dev_add_vf = __symbol_get("migration_dev_add_vf");
+ if (migration_dev_add_vf) {
+ ret = migration_dev_add_vf(vf_pdev);
+ __symbol_put("migration_dev_add_vf");
+ if (ret)
+ sdk_err(&vf_pdev->dev, "vf get migration symbol succeeded, but dev add vf failed, ret:%d.\n",
+ ret);
+ else
+ sdk_info(&vf_pdev->dev, "vf get migration symbol succeeded, and dev add vf success.\n");
+ goto err1;
+ }
+ sdk_info(&vf_pdev->dev, "pf is migrated, but vf get migration symbol failed.\n");
+
+delay_work:
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork, WAIT_TIME * HZ);
+ return;
+
+err1:
+ kfree(vf_add);
+}
+
+static void hinic3_probe_vf_add_dwork(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!hinic3_is_host_vmsec_enable(pdev))
+ return;
+
+#if defined(CONFIG_SP_VID_DID)
+ if ((pdev->vendor == PCI_VENDOR_ID_SPNIC) && (pdev->device == HINIC3_DEV_SDI_5_1_ID_VF)) {
+#elif defined(CONFIG_NF_VID_DID)
+ if ((pdev->vendor == PCI_VENDOR_ID_NF) && (pdev->device == NFNIC_DEV_ID_VF)) {
+#else
+ if ((pdev->vendor == PCI_VENDOR_ID_HUAWEI) && (pdev->device == HINIC3_DEV_SDI_5_0_ID_VF)) {
+#endif
+ struct vf_add_delaywork *vf_add = kmalloc(sizeof(struct vf_add_delaywork),
+ GFP_ATOMIC);
+
+ if (!vf_add) {
+ sdk_info(&pdev->dev, "vf_add is null.\n");
+ return;
+ }
+ vf_add->vf_pdev = pdev;
+
+ pf_pdev = pdev->physfn;
+
+ if (!pf_pdev) {
+ sdk_info(&pdev->dev, "Vf-pf_pdev is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_info(&pdev->dev, "Pci_adapter is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ INIT_DELAYED_WORK(&vf_add->migration_vf_add_dwork,
+ slave_host_migration_vf_add_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork,
+ WAIT_TIME * HZ);
+ }
+}
+
+static int hinic3_probe_migration_dwork(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+{
+ if (!hinic3_is_host_vmsec_enable(pdev)) {
+ sdk_info(&pdev->dev, "Probe_migration : hinic3_is_host_vmsec_enable is (0).\n");
+ return 0;
+ }
+
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF) {
+ pci_adapter->migration_probe_workq =
+ create_singlethread_workqueue("hinic3_migration_probe_delay");
+ if (!pci_adapter->migration_probe_workq) {
+ sdk_err(&pdev->dev, "Failed to create work queue:%s\n",
+ "hinic3_migration_probe_delay");
+ return -EINVAL;
+ }
+
+ INIT_DELAYED_WORK(&pci_adapter->migration_probe_dwork,
+ slave_host_vfio_probe_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork, WAIT_TIME * HZ);
+ }
+
+ return 0;
+}
+
+static bool hinic3_os_hot_replace_allow(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_hwdev *hwdev = (struct hinic3_hwdev *)pci_adapter->hwdev;
+ // check service enable and dev is not VF
+ if (hinic3_func_type(hwdev) == TYPE_VF || hwdev->hot_replace_mode == HOT_REPLACE_DISABLE)
+ return false;
+
+ return true;
+}
+
+static bool hinic3_os_hot_replace_process(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_board_info *board_info;
+ u16 cur_pf_id = hinic3_global_func_id(pci_adapter->hwdev);
+ u8 cur_partion_id;
+
+ board_info = &((struct hinic3_hwdev *)(pci_adapter->hwdev))->board_info;
+ // probe to os
+ vpci_set_partition_attrs(pci_adapter->pcidev, PARTITION_DEV_EXCLUSIVE,
+ get_function_partition(cur_pf_id, board_info->port_num));
+
+ // check pf_id is in the right partition_id
+ cur_partion_id = get_partition_id();
+ if (get_function_partition(cur_pf_id, board_info->port_num) ==
+ cur_partion_id)
+ return true;
+
+ pci_adapter->probe_fault_level = FAULT_LEVEL_SUGGESTION;
+ return false;
+}
+
static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct hinic3_pcidev *pci_adapter = NULL;
u16 probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ u32 device_id, function_id;
int err;
sdk_info(&pdev->dev, "Pcie device probe begin\n");
+#ifdef CONFIG_PCI_IOV
+ hinic3_set_vf_status_in_host(pdev, true);
+ if (check_pdev_type_and_state(pdev)) {
+ sdk_info(&pdev->dev, "VFs are not binded to hinic\n");
+ hinic3_probe_vf_add_dwork(pdev);
+ return -EINVAL;
+ }
+#endif
+
err = hinic3_probe_pre_process(pdev);
if (err != 0 && err != HINIC3_NOT_PROBE)
goto out;
@@ -1060,26 +2085,48 @@ static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (err)
goto pci_init_err;
- pci_adapter = pci_get_drvdata(pdev);
- pci_adapter->disable_vf_load = disable_vf_load;
- pci_adapter->id = *id;
- pci_adapter->lld_state = HINIC3_NOT_PROBE;
- pci_adapter->probe_fault_level = probe_fault_level;
- lld_dev_cnt_init(pci_adapter);
+ err = pci_adapter_assign_val(&pci_adapter, pdev, id);
+ if (err)
+ goto allco_queue_err;
- if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev))) {
+ if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev)) &&
+ (!hinic3_get_vf_nic_en_status(pdev))) {
sdk_info(&pdev->dev, "VF device disable load in host\n");
return 0;
}
- err = hinic3_probe_func(pci_adapter);
- if (err)
+ if (hinic3_probe_func(pci_adapter))
+ goto hinic3_probe_func_fail;
+
+ if (hinic3_os_hot_replace_allow(pci_adapter)) {
+ if (!hinic3_os_hot_replace_process(pci_adapter)) {
+ device_id = PCI_SLOT(pdev->devfn);
+ function_id = PCI_FUNC(pdev->devfn);
+ sdk_info(&pdev->dev,
+ "os hot replace: skip function %d:%d for partition %d",
+ device_id, function_id, get_partition_id());
+ goto os_hot_repalce_not_allow;
+ }
+ }
+
+ if (hinic3_probe_migration_dwork(pdev, pci_adapter))
goto hinic3_probe_func_fail;
sdk_info(&pdev->dev, "Pcie device probed\n");
return 0;
+os_hot_repalce_not_allow:
+ hinic3_func_deinit(pdev);
+ lld_lock_chip_node();
+ free_chip_node(pci_adapter);
+ lld_unlock_chip_node();
+ unmapping_bar(pci_adapter);
+ set_vf_func_in_use(pdev, false);
hinic3_probe_func_fail:
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
+allco_queue_err:
probe_fault_level = pci_adapter->probe_fault_level;
hinic3_pci_deinit(pdev);
@@ -1105,6 +2152,11 @@ static int hinic3_get_pf_info(struct pci_dev *pdev, u16 service,
}
*pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (*pf_infos == NULL) {
+ sdk_err(&pdev->dev, "pf_infos kzalloc failed\n");
+ return -EFAULT;
+ }
+
err = hinic3_get_hw_pf_infos(dev->hwdev, *pf_infos, HINIC3_CHANNEL_COMM);
if (err) {
kfree(*pf_infos);
@@ -1120,6 +2172,7 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
{
int err;
+ mutex_lock(&dst_dev->pdev_mutex);
/* unload invalid vf func id */
if (!en && vf_func_id != hinic3_global_func_id(dst_dev->hwdev) &&
!strcmp(des_pdev->driver->name, HINIC3_DRV_NAME)) {
@@ -1137,6 +2190,8 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
err = hinic3_probe_func(dst_dev);
if (err)
return -EFAULT;
+ } else {
+ mutex_unlock(&dst_dev->pdev_mutex);
}
return 0;
@@ -1161,7 +2216,6 @@ static int get_vf_service_state_param(struct pci_dev *pdev, struct hinic3_pcidev
return 0;
}
-#define BUS_MAX_DEV_NUM 256
static int hinic3_dst_pdev_valid(struct hinic3_pcidev *dst_dev, struct pci_dev **des_pdev_ptr,
u16 vf_devfn, bool en)
{
@@ -1175,7 +2229,7 @@ static int hinic3_dst_pdev_valid(struct hinic3_pcidev *dst_dev, struct pci_dev
return -EFAULT;
}
- if (!(*des_pdev_ptr)->driver) {
+ if ((*des_pdev_ptr)->driver == NULL) {
pr_err("des_pdev_ptr->driver is NULL\n");
return -EFAULT;
}
@@ -1243,7 +2297,6 @@ int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id, u16 servic
if (en)
pci_dev_put(des_pdev);
- mutex_lock(&dst_dev->pdev_mutex);
find_dst_dev = true;
break;
}
@@ -1263,19 +2316,30 @@ free_pf_info:
}
EXPORT_SYMBOL(hinic3_set_vf_service_state);
-/*lint -save -e133 -e10*/
static const struct pci_device_id hinic3_pci_table[] = {
+#if defined(CONFIG_SP_VID_DID)
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_STANDARD), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_SDI_5_1_PF), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_SDI_5_0_PF), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_SPN120), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_VF), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_SDI_5_1_ID_VF), 0},
+#elif defined(CONFIG_NF_VID_DID)
+ {PCI_VDEVICE(NF, NFNIC_DEV_ID_STANDARD), 0},
+ {PCI_VDEVICE(NF, NFNIC_DEV_ID_VF), 0},
+#else
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SPU), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_STANDARD), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_1_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_SDI_5_1_ID_VF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_VF), 0},
+#endif
{0, 0}
};
-/*lint -restore*/
-
MODULE_DEVICE_TABLE(pci, hinic3_pci_table);
/**
@@ -1307,14 +2371,27 @@ static pci_ers_result_t hinic3_io_error_detected(struct pci_dev *pdev,
return PCI_ERS_RESULT_CAN_RECOVER;
}
+static void hinic3_timer_disable(void *hwdev)
+{
+ if (!hwdev)
+ return;
+
+ if (hinic3_get_stateful_enable(hwdev) && hinic3_get_timer_enable(hwdev))
+ (void)hinic3_func_tmr_bitmap_set(hwdev,
+ hinic3_global_func_id(hwdev),
+ false);
+}
+
static void hinic3_shutdown(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
sdk_info(&pdev->dev, "Shutdown device\n");
- if (pci_adapter)
+ if (pci_adapter) {
+ hinic3_timer_disable(pci_adapter->hwdev);
hinic3_shutdown_hwdev(pci_adapter->hwdev);
+ }
pci_disable_device(pdev);
@@ -1341,6 +2418,9 @@ static struct pci_driver hinic3_driver = {
.probe = hinic3_probe,
.remove = hinic3_remove,
.shutdown = hinic3_shutdown,
+#ifdef CONFIG_PARTITION_DEVICE
+ .driver.probe_concurrency = true,
+#endif
#if defined(HAVE_SRIOV_CONFIGURE)
.sriov_configure = hinic3_pci_sriov_configure,
#elif defined(HAVE_RHEL6_SRIOV_CONFIGURE)
@@ -1362,16 +2442,21 @@ int hinic3_lld_init(void)
err = hinic3_module_pre_init();
if (err) {
pr_err("Init custom failed\n");
- return err;
+ goto module_pre_init_err;
}
err = pci_register_driver(&hinic3_driver);
if (err) {
- hinic3_module_post_exit();
- return err;
+ pr_err("sdk3 pci register driver failed\n");
+ goto register_pci_driver_err;
}
return 0;
+
+register_pci_driver_err:
+ hinic3_module_post_exit();
+module_pre_init_err:
+ return err;
}
void hinic3_lld_exit(void)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
index b2851c6..3626262 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
@@ -584,6 +584,7 @@ static void free_recv_mbox(struct hinic3_recv_mbox *recv_msg)
kfree(recv_msg->resp_buff);
kfree(recv_msg->msg);
kfree(recv_msg);
+ recv_msg = NULL;
}
static void recv_func_mbox_work_handler(struct work_struct *work)
@@ -1232,6 +1233,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
set_mbox_to_func_event(func_to_func, EVENT_FAIL);
goto send_err;
}
+ func_to_func->hwdev->mbox_send_cnt++;
if (wait_mbox_msg_completion(func_to_func, timeout) != 0) {
sdk_err(func_to_func->hwdev->dev_hdl,
@@ -1240,6 +1242,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
err = -ETIMEDOUT;
goto send_err;
}
+ func_to_func->hwdev->mbox_ack_cnt++;
if (mod != msg_desc->mod || cmd != msg_desc->cmd) {
sdk_err(func_to_func->hwdev->dev_hdl,
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
index 2bd63f1..4718458 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
@@ -861,6 +861,7 @@ static int alloc_recv_msg(struct hinic3_recv_msg *recv_msg)
static void free_recv_msg(struct hinic3_recv_msg *recv_msg)
{
kfree(recv_msg->msg);
+ recv_msg->msg = NULL;
}
/**
@@ -932,6 +933,9 @@ static void free_msg_buf(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt)
free_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
+ pf_to_mgmt->mgmt_ack_buf = NULL;
+ pf_to_mgmt->sync_msg_buf = NULL;
+ pf_to_mgmt->async_msg_buf = NULL;
}
/**
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
index 3548410..a0f5e73 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
@@ -676,6 +676,9 @@ static int hinic3_register_slave_ppf(struct hinic3_hwdev *hwdev, bool registered
if (!IS_SLAVE_HOST(hwdev))
return -EINVAL;
+ if (UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev))
+ return 0;
+
host_info = kcalloc(1, sizeof(struct register_slave_host), GFP_KERNEL);
if (!host_info)
return -ENOMEM;
@@ -1075,7 +1078,8 @@ int hinic3_get_func_nic_enable(void *hwdev, u16 glb_func_idx, bool *en)
return -EINVAL;
/* if single host, return true. */
- if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev)) {
+ if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev) ||
+ UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev)) {
*en = true;
return 0;
}
@@ -1145,11 +1149,21 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
{
int err;
struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+ int is_use_vram, is_in_kexec;
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
- hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0) {
+ snprintf(hwdev->mhost_mgmt_name, VRAM_NAME_MAX_LEN, "%s",
+ VRAM_NIC_MHOST_MGMT);
+ hwdev->mhost_mgmt = hi_vram_kalloc(hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ } else {
+ hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ }
+
if (!hwdev->mhost_mgmt)
return -ENOMEM;
@@ -1165,8 +1179,11 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK, hwdev, hilink_ppf_mbox_handler);
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC, hwdev, sw_func_ppf_mbox_handler);
- bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
- bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ }
/* Slave host:
* register slave host ppf functions
@@ -1179,7 +1196,11 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
return 0;
out_free_mhost_mgmt:
- kfree(hwdev->mhost_mgmt);
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)hwdev->mhost_mgmt, hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ else
+ kfree(hwdev->mhost_mgmt);
hwdev->mhost_mgmt = NULL;
return err;
@@ -1187,6 +1208,8 @@ out_free_mhost_mgmt:
int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
{
+ int is_use_vram;
+
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
@@ -1203,7 +1226,13 @@ int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC);
- kfree(hwdev->mhost_mgmt);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)hwdev->mhost_mgmt, hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ else
+ kfree(hwdev->mhost_mgmt);
+
hwdev->mhost_mgmt = NULL;
return 0;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
index 5e4804a..a0340d9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
@@ -17,14 +17,13 @@
#include "hinic3_hwdev.h"
#include "hinic3_lld.h"
#include "hinic3_hw_mt.h"
+#include "hinic3_dev_mgmt.h"
#include "hinic3_nictool.h"
static int g_nictool_ref_cnt;
static dev_t g_dev_id = {0};
-/*lint -save -e104 -e808*/
static struct class *g_nictool_class;
-/*lint -restore*/
static struct cdev g_nictool_cdev;
#define HINIC3_MAX_BUF_SIZE (2048 * 1024)
@@ -92,6 +91,23 @@ static int get_all_chip_id_cmd(struct hinic3_lld_dev *lld_dev, const void *buf_i
return 0;
}
+#ifndef __HIFC__
+static int get_os_hot_replace_info(struct hinic3_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ if (*out_size != sizeof(struct os_hot_replace_info) || !buf_out) {
+ pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
+ *out_size, sizeof(struct os_hot_replace_info));
+ return -EFAULT;
+ }
+
+ hinic3_get_os_hot_replace_info(buf_out);
+
+ return 0;
+}
+#endif
+
static int get_card_usr_api_chain_mem(int card_idx)
{
unsigned char *tmp = NULL;
@@ -166,7 +182,7 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
if (!buf_out || *out_size != sizeof(struct pf_dev_info) * PF_DEV_INFO_NUM) {
pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
- *out_size, sizeof(dev_info) * PF_DEV_INFO_NUM);
+ *out_size, sizeof(*dev_info) * PF_DEV_INFO_NUM);
return -EFAULT;
}
@@ -193,13 +209,18 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
return 0;
}
-static long dbgtool_knl_free_mem(int id)
+static void dbgtool_knl_free_mem(int id)
{
unsigned char *tmp = NULL;
int i;
+ if (id < 0 || id >= MAX_CARD_NUM) {
+ pr_err("Invalid card id\n");
+ return;
+ }
+
if (!g_card_vir_addr[id])
- return 0;
+ return;
tmp = g_card_vir_addr[id];
for (i = 0; i < (1 << DBGTOOL_PAGE_ORDER); i++) {
@@ -211,7 +232,6 @@ static long dbgtool_knl_free_mem(int id)
g_card_vir_addr[id] = NULL;
g_card_phy_addr[id] = 0;
- return 0;
}
static int free_knl_mem(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_size,
@@ -337,7 +357,6 @@ static int get_hw_drv_version(struct hinic3_lld_dev *lld_dev, const void *buf_in
void *buf_out, u32 *out_size)
{
struct drv_version_info *ver_info = buf_out;
- int err;
if (!buf_out) {
pr_err("Buf_out is NULL.\n");
@@ -350,10 +369,8 @@ static int get_hw_drv_version(struct hinic3_lld_dev *lld_dev, const void *buf_in
return -EINVAL;
}
- err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s", HINIC3_DRV_VERSION,
- "2023-05-17_19:56:38");
- if (err < 0)
- return -EINVAL;
+ snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s", HINIC3_DRV_VERSION,
+ "2025-05-08_00:00:08");
return 0;
}
@@ -386,6 +403,22 @@ static int get_pf_id(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_
return 0;
}
+#ifndef __HIFC__
+/* not support fc yet */
+static int get_mbox_cnt(struct hinic3_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ if (buf_out == NULL || *out_size != sizeof(struct card_mbox_cnt_info)) {
+ pr_err("buf_out is NULL, or out_size != %lu\n", sizeof(struct card_info));
+ return -EINVAL;
+ }
+
+ hinic3_get_mbox_cnt(hinic3_get_sdk_hwdev_by_lld(lld_dev), buf_out);
+
+ return 0;
+}
+#endif
+
struct hw_drv_module_handle hw_driv_module_cmd_handle[] = {
{FUNC_TYPE, get_func_type},
{GET_FUNC_IDX, get_func_id},
@@ -402,6 +435,10 @@ struct hw_drv_module_handle hw_driv_module_cmd_handle[] = {
{GET_FUNC_CAP, get_pf_cap_info},
{GET_DRV_VERSION, get_hw_drv_version},
{GET_PF_ID, get_pf_id},
+#ifndef __HIFC__
+ {GET_OS_HOT_REPLACE_INFO, get_os_hot_replace_info},
+ {GET_MBOX_CNT, (hw_driv_module)get_mbox_cnt},
+#endif
};
static int alloc_tmp_buf(void *hwdev, struct msg_module *nt_msg, u32 in_size,
@@ -439,8 +476,8 @@ static void free_tmp_buf(void *hwdev, struct msg_module *nt_msg,
static int send_to_hw_driver(struct hinic3_lld_dev *lld_dev, struct msg_module *nt_msg,
const void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(hw_driv_module_cmd_handle) /
- sizeof(hw_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(hw_driv_module_cmd_handle) /
+ sizeof(hw_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type =
(enum driver_cmd_type)(nt_msg->msg_formate);
int err = 0;
@@ -482,8 +519,8 @@ static int send_to_service_driver(struct hinic3_lld_dev *lld_dev, struct msg_mod
if (nt_msg->msg_formate == GET_DRV_VERSION)
return 0;
- pr_err("Can not get the uld dev correctly: %s, %s driver may be not register\n",
- nt_msg->device_name, service_name[type]);
+ pr_err("Can not get the uld dev correctly: %s driver may be not register\n",
+ service_name[type]);
return -EINVAL;
}
@@ -566,8 +603,8 @@ static struct hinic3_lld_dev *get_lld_dev_by_nt_msg(struct msg_module *nt_msg)
} else {
lld_dev = hinic3_get_lld_dev_by_chip_name(nt_msg->device_name);
if (!lld_dev)
- lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
- SERVICE_T_MAX);
+ lld_dev = hinic3_get_lld_dev_by_dev_name(
+ nt_msg->device_name, SERVICE_T_MAX);
}
return lld_dev;
@@ -597,8 +634,10 @@ static long hinicadm_k_unlocked_ioctl(struct file *pfile, unsigned long arg)
return -ENODEV;
}
- if (nt_msg.msg_formate == DEV_NAME_TEST)
+ if (nt_msg.msg_formate == DEV_NAME_TEST) {
+ lld_dev_put(lld_dev);
return 0;
+ }
ret = alloc_tmp_buf(hinic3_get_sdk_hwdev_by_lld(lld_dev), &nt_msg,
in_size, &buf_in, out_size_expect, &buf_out);
@@ -642,6 +681,9 @@ out_free_lock:
static long dbgtool_knl_ffm_info_rd(struct dbgtool_param *para,
struct dbgtool_k_glb_info *dbgtool_info)
{
+ if (!para->param.ffm_rd || !dbgtool_info->ffm)
+ return -EINVAL;
+
/* Copy the ffm_info to user mode */
if (copy_to_user(para->param.ffm_rd, dbgtool_info->ffm,
(unsigned int)sizeof(struct ffm_record_info))) {
@@ -674,13 +716,14 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
card_info = (struct card_node *)g_card_node_array[i];
if (!card_info)
continue;
- if (!strncmp(param.chip_name, card_info->chip_name, IFNAMSIZ))
+ if (memcmp(param.chip_name, card_info->chip_name,
+ strlen(card_info->chip_name) + 1) == 0)
break;
}
if (i == MAX_CARD_NUM || !card_info) {
lld_put();
- pr_err("Can't find this card %s\n", param.chip_name);
+ pr_err("Can't find this card.\n");
return -EFAULT;
}
@@ -697,10 +740,10 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
pr_err("Not suppose to use this cmd(0x%x).\n", real_cmd);
ret = 0;
break;
-
default:
pr_err("Dbgtool cmd(0x%x) not support now\n", real_cmd);
ret = -EFAULT;
+ break;
}
up(&dbgtool_info->dbgtool_sem);
@@ -746,9 +789,11 @@ static long nictool_k_unlocked_ioctl(struct file *pfile,
static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
{
+ pgprot_t vm_page_prot;
unsigned long vmsize = vma->vm_end - vma->vm_start;
phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
phys_addr_t phy_addr;
+ int err = 0;
if (vmsize > (PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER))) {
pr_err("Map size = %lu is bigger than alloc\n", vmsize);
@@ -758,13 +803,18 @@ static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
/* old version of tool set vma->vm_pgoff to 0 */
phy_addr = offset ? offset : g_card_phy_addr[card_id];
- if (!phy_addr) {
- pr_err("Card_id = %d physical address is 0\n", card_id);
- return -EAGAIN;
+ /* check phy_addr valid */
+ if (phy_addr != g_card_phy_addr[card_id]) {
+ err = hinic3_bar_mmap_param_valid(phy_addr, vmsize);
+ if (err != 0) {
+ pr_err("mmap param invalid, err: %d\n", err);
+ return err;
+ }
}
/* Disable cache and write buffer in the mapping area */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_page_prot = vm_page_prot;
if (remap_pfn_range(vma, vma->vm_start, (phy_addr >> PAGE_SHIFT),
vmsize, vma->vm_page_prot)) {
pr_err("Remap pfn range failed.\n");
@@ -787,7 +837,6 @@ static const struct file_operations fifo_operations = {
static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
{
struct dbgtool_k_glb_info *dbgtool_info = NULL;
- int err, id;
if (hinic3_func_type(hwdev) != TYPE_VF)
chip_info->func_handle_array[hinic3_global_func_id(hwdev)] = NULL;
@@ -795,23 +844,22 @@ static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
if (--chip_info->func_num)
return;
- err = sscanf(chip_info->chip_name, HINIC3_CHIP_NAME "%d", &id);
- if (err < 0)
- pr_err("Failed to get card id\n");
-
- if (id < MAX_CARD_NUM)
- g_card_node_array[id] = NULL;
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ g_card_node_array[chip_info->chip_id] = NULL;
dbgtool_info = chip_info->dbgtool_info;
/* FFM deinit */
- kfree(dbgtool_info->ffm);
- dbgtool_info->ffm = NULL;
+ if (dbgtool_info && dbgtool_info->ffm) {
+ kfree(dbgtool_info->ffm);
+ dbgtool_info->ffm = NULL;
+ }
kfree(dbgtool_info);
+
chip_info->dbgtool_info = NULL;
- if (id < MAX_CARD_NUM)
- (void)dbgtool_knl_free_mem(id);
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ dbgtool_knl_free_mem(chip_info->chip_id);
}
static int alloc_dbgtool_info(void *hwdev, struct card_node *chip_info)
@@ -872,7 +920,7 @@ dbgtool_info_fail:
* nictool_k_init - initialize the hw interface
**/
/* temp for dbgtool_info */
-/*lint -e438*/
+
int nictool_k_init(void *hwdev, void *chip_node)
{
struct card_node *chip_info = (struct card_node *)chip_node;
@@ -895,9 +943,7 @@ int nictool_k_init(void *hwdev, void *chip_node)
}
/* Create equipment */
- /*lint -save -e160*/
g_nictool_class = class_create(HIADM3_DEV_CLASS);
- /*lint -restore*/
if (IS_ERR(g_nictool_class)) {
pr_err("Create nictool_class fail\n");
err = -EFAULT;
@@ -944,7 +990,7 @@ alloc_chdev_fail:
free_dbgtool_info(hwdev, chip_info);
return err;
-} /*lint +e438*/
+}
void nictool_k_uninit(void *hwdev, void *chip_node)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
index f368133..c943dfc 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
@@ -18,6 +18,8 @@
int nictool_k_init(void *hwdev, void *chip_node);
void nictool_k_uninit(void *hwdev, void *chip_node);
+void hinic3_get_os_hot_replace_info(void *oshr_info);
+
void hinic3_get_all_chip_id(void *id_info);
void hinic3_get_card_func_info_by_card_name
@@ -29,6 +31,8 @@ bool hinic3_is_in_host(void);
int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *isvalid);
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin);
+
extern struct hinic3_uld_info g_uld_info[SERVICE_T_MAX];
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
index 2d5423e..e961ef7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
@@ -19,6 +19,20 @@
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
+#elif defined(CONFIG_NF_VID_DID)
+#define PCI_VENDOR_ID_NF 0x2036
+#define NFNIC_DEV_ID_STANDARD 0x1618
+#define NFNIC_DEV_ID_SDI_5_1_PF 0x0226
+#define NFNIC_DEV_ID_SDI_5_0_PF 0x0225
+#define NFNIC_DEV_ID_DPU_PF 0x0224
+#define NFNIC_DEV_ID_VF 0x1619
+#define NFNIC_DEV_ID_VF_HV 0x379F
+#define NFNIC_DEV_SDI_5_1_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_0_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_1_ID_VF_HV 0x379F
+#define NFNIC_DEV_ID_SPU 0xAC00
+#define NFNIC_DEV_SDI_5_1_SSDID_VF 0x1000
+#define NFNIC_DEV_SDI_V100_SSDID_MASK (3 << 12)
#else
#define PCI_VENDOR_ID_HUAWEI 0x19e5
#define HINIC3_DEV_ID_STANDARD 0x0222
@@ -28,16 +42,33 @@
#define HINIC3_DEV_ID_VF 0x375F
#define HINIC3_DEV_ID_VF_HV 0x379F
#define HINIC3_DEV_SDI_5_1_ID_VF 0x375F
+#define HINIC3_DEV_SDI_5_0_ID_VF 0x375F
#define HINIC3_DEV_SDI_5_1_ID_VF_HV 0x379F
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
#endif
+#define NFNIC_DEV_SSID_2X25G_NF 0x0860
+#define NFNIC_DEV_SSID_4X25G_NF 0x0861
+#define NFNIC_DEV_SSID_2x100G_NF 0x0862
+#define NFNIC_DEV_SSID_2x200G_NF 0x0863
+
+#define HINIC3_DEV_SSID_2X10G 0x0035
#define HINIC3_DEV_SSID_2X25G 0x0051
#define HINIC3_DEV_SSID_4X25G 0x0052
+#define HINIC3_DEV_SSID_4X25G_BD 0x0252
+#define HINIC3_DEV_SSID_4X25G_SMARTNIC 0x0152
+#define HINIC3_DEV_SSID_6X25G_VL 0x0356
#define HINIC3_DEV_SSID_2X100G 0x00A1
+#define HINIC3_DEV_SSID_2X100G_SMARTNIC 0x01A1
+#define HINIC3_DEV_SSID_2X200G 0x04B1
#define HINIC3_DEV_SSID_2X100G_VF 0x1000
+#define HINIC3_DEV_SSID_HPC_4_HOST_NIC 0x005A
+#define HINIC3_DEV_SSID_2X200G_VL 0x00B1
+#define HINIC3_DEV_SSID_1X100G 0x02A4
+
+#define BIFUR_RESOURCE_PF_SSID 0x05a1
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
index b23b69f..056397f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
@@ -52,7 +52,7 @@ static int hinic3_deinit_vf_hw(void *hwdev, u16 start_vf_id, u16 end_vf_id)
}
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
-ssize_t hinic3_sriov_totalvfs_show(struct device *dev,
+ssize_t sriov_totalvfs_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
@@ -60,7 +60,7 @@ ssize_t hinic3_sriov_totalvfs_show(struct device *dev,
return sprintf(buf, "%d\n", pci_sriov_get_totalvfs(pdev));
}
-ssize_t hinic3_sriov_numvfs_show(struct device *dev,
+ssize_t sriov_numvfs_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
@@ -68,8 +68,7 @@ ssize_t hinic3_sriov_numvfs_show(struct device *dev,
return sprintf(buf, "%d\n", pci_num_vf(pdev));
}
-/*lint -save -e713*/
-ssize_t hinic3_sriov_numvfs_store(struct device *dev,
+ssize_t sriov_numvfs_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
@@ -116,7 +115,6 @@ ssize_t hinic3_sriov_numvfs_store(struct device *dev,
return count;
}
-/*lint -restore*/
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
int hinic3_pci_sriov_disable(struct pci_dev *dev)
@@ -174,24 +172,15 @@ int hinic3_pci_sriov_disable(struct pci_dev *dev)
return 0;
}
-int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
-{
#ifdef CONFIG_PCI_IOV
- struct hinic3_sriov_info *sriov_info = NULL;
- struct hinic3_event_info event = {0};
- void *hwdev = NULL;
- int pre_existing_vfs = 0;
- int err = 0;
-
- sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
- hwdev = hinic3_get_hwdev_by_pcidev(dev);
- if (!hwdev) {
- sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
- return -EPERM;
- }
+int hinic3_pci_sriov_check(struct hinic3_sriov_info *sriov_info, struct pci_dev *dev, int num_vfs)
+{
+ int pre_existing_vfs;
+ int err;
if (test_and_set_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state)) {
- sdk_err(&dev->dev, "SR-IOV enable in process, please wait, num_vfs %d\n",
+ sdk_err(&dev->dev,
+ "SR-IOV enable in process, please wait, num_vfs %d\n",
num_vfs);
return -EPERM;
}
@@ -202,6 +191,7 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
clear_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state);
return -ERANGE;
}
+
if (pre_existing_vfs && pre_existing_vfs != num_vfs) {
err = hinic3_pci_sriov_disable(dev);
if (err) {
@@ -213,6 +203,29 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
return num_vfs;
}
+ return 0;
+}
+#endif
+
+int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
+{
+#ifdef CONFIG_PCI_IOV
+ struct hinic3_sriov_info *sriov_info = NULL;
+ struct hinic3_event_info event = {0};
+ void *hwdev = NULL;
+ int err = 0;
+
+ sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
+ hwdev = hinic3_get_hwdev_by_pcidev(dev);
+ if (!hwdev) {
+ sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
+ return -EPERM;
+ }
+
+ err = hinic3_pci_sriov_check(sriov_info, dev, num_vfs);
+ if (err != 0)
+ return err;
+
err = hinic3_init_vf_hw(hwdev, 1, (u16)num_vfs);
if (err) {
sdk_err(&dev->dev, "Failed to init vf in hardware before enable sriov, error %d\n",
@@ -262,6 +275,3 @@ int hinic3_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
else
return hinic3_pci_sriov_enable(dev, num_vfs);
}
-
-/*lint -restore*/
-
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h
index 4a640ad..20eb728 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h
@@ -7,11 +7,11 @@
#include <linux/pci.h>
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
-ssize_t hinic3_sriov_totalvfs_show(struct device *dev,
+ssize_t sriov_totalvfs_show(struct device *dev,
struct device_attribute *attr, char *buf);
-ssize_t hinic3_sriov_numvfs_show(struct device *dev,
+ssize_t sriov_numvfs_show(struct device *dev,
struct device_attribute *attr, char *buf);
-ssize_t hinic3_sriov_numvfs_store(struct device *dev,
+ssize_t sriov_numvfs_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count);
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c b/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c
index f8aea696..be83022 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c
@@ -117,3 +117,4 @@ u64 ossl_get_real_time(void)
tv_msec = (u64)tv.tv_sec * MSEC_PER_SEC + (u64)tv.tv_usec / USEC_PER_MSEC;
return tv_msec;
}
+
diff --git a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
index 9e8fc75..01ab739 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
@@ -10,6 +10,10 @@
#define OVS_PORT_NUM_MAX BOND_PORT_MAX_NUM
#define DEFAULT_ROCE_BOND_FUNC 0xFFFFFFFF
+#define BOND_ID_IS_VALID(_id) \
+ (((_id) >= BOND_FIRST_ID) && ((_id) <= BOND_MAX_ID))
+#define BOND_ID_IS_INVALID(_id) (!(BOND_ID_IS_VALID(_id)))
+
enum bond_group_id {
BOND_FIRST_ID = 1,
BOND_MAX_ID = 4,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
index e7e16fc..f9737ea 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
@@ -52,6 +52,8 @@ enum scenes_id_define {
SCENES_ID_STORAGE_ROCE = 6,
SCENES_ID_COMPUTE_ROCE = 7,
SCENES_ID_STORAGE_TOE = 8,
+ SCENES_ID_COMPUTE_DPU = 100,
+ SCENES_ID_COMPUTE_SMART_NIC = 101,
SCENES_ID_MAX
};
@@ -122,13 +124,18 @@ struct cfg_cmd_dev_cap {
u8 srv_multi_host_mode;
u8 virtio_vq_size;
- u32 rsvd_func3[5];
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 lro_enable;
+ u8 os_hot_replace;
+
+ u32 rsvd_func3[4];
/* l2nic */
u16 nic_max_sq_id;
u16 nic_max_rq_id;
u16 nic_default_num_queues;
- u16 rsvd1_nic;
+ u16 outband_vlan_cfg_en;
u32 rsvd2_nic[2];
/* RoCE */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
index d9f67e2..6c5b995 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
@@ -37,7 +37,7 @@ static inline void hinic3_cpu_to_be32(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -59,7 +59,7 @@ static inline void hinic3_be32_to_cpu(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -86,52 +86,16 @@ static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
sge->len = (u32)len;
}
-#ifdef HW_CONVERT_ENDIAN
#define hinic3_hw_be32(val) (val)
#define hinic3_hw_cpu32(val) (val)
#define hinic3_hw_cpu16(val) (val)
-#else
-#define hinic3_hw_be32(val) cpu_to_be32(val)
-#define hinic3_hw_cpu32(val) be32_to_cpu(val)
-#define hinic3_hw_cpu16(val) be16_to_cpu(val)
-#endif
static inline void hinic3_hw_be32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_be32(*mem);
- mem++;
- }
-#endif
}
static inline void hinic3_hw_cpu32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_cpu32(*mem);
- mem++;
- }
-#endif
}
int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
@@ -149,6 +113,8 @@ int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
/* func_attr.glb_func_idx, global function index */
u16 hinic3_global_func_id(void *hwdev);
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id);
+
/* func_attr.p2p_idx, belongs to which pf */
u8 hinic3_pf_id_of_vf(void *hwdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
index 9a9bfe2..e36ba1d 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
@@ -219,5 +219,7 @@ void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
const char **hinic3_get_uld_names(void);
+int hinic3_lld_init(void);
+void hinic3_lld_exit(void);
#endif
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
index 97d34f0..4cd6f94 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
@@ -43,6 +43,10 @@ enum mag_cmd {
MAG_CMD_GET_XSFP_PRESENT = 62, /* get xsfp present status @see mag_cmd_get_xsfp_present */
MAG_CMD_SET_XSFP_RW = 63, /* sfp/qsfp single byte read/write, @see mag_cmd_set_xsfp_rw */
MAG_CMD_CFG_XSFP_TEMPERATURE = 64, /* get xsfp temp @see mag_cmd_sfp_temp_out_info */
+ /**< set xsfp tlv info @see struct mag_cmd_set_xsfp_tlv_req */
+ MAG_CMD_SET_XSFP_TLV_INFO = 65,
+ /**< get xsfp tlv info @see struct drv_tag_mag_cmd_get_xsfp_tlv_rsp */
+ MAG_CMD_GET_XSFP_TLV_INFO = 66,
/* Event reported 100-149 */
MAG_CMD_WIRE_EVENT = 100,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
index caaba5d..d33b9f4 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
@@ -31,17 +31,28 @@ enum board_type_define_e {
BOARD_TYPE_STRG_2X100G_ROCE_AA = 42, /* 2X100G SmartIO ROCE_AA Card */
BOARD_TYPE_CAL_2X25G_NIC_75MPPS = 100, /* 2X25G ETH Standard card 75MPPS */
BOARD_TYPE_CAL_2X25G_NIC_40MPPS = 101, /* 2X25G ETH Standard card 40MPPS */
- BOARD_TYPE_CAL_2X100G_DPU = 102, /* 2x100G DPU Card */
+ BOARD_TYPE_CAL_2X100G_DPU_VL = 102, /* 2x100G DPU Card */
BOARD_TYPE_CAL_4X25G_NIC_120MPPS = 105, /* 4X25G ETH Standard card 120MPPS */
BOARD_TYPE_CAL_4X25G_COMSTORAGE = 106, /* 4X25GE compute storage Onboard Card */
BOARD_TYPE_CAL_2X32G_FC_HBA = 110, /* 2X32G FC HBA card */
BOARD_TYPE_CAL_2X16G_FC_HBA = 111, /* 2X16G FC HBA card */
BOARD_TYPE_CAL_2X100G_NIC_120MPPS = 115, /* 2X100G ETH Standard card 120MPPS */
- BOARD_TYPE_CAL_2X25G_DPU = 116, /* 2x25G DPU Card */
- BOARD_TYPE_CAL_4X25G_DPU = 118, /* 4x25G DPU Card */
+ BOARD_TYPE_CAL_2X25G_DPU_BD = 116, /* 2x25G DPU Card */
+ BOARD_TYPE_CAL_2X100G_TCE_BACKPLANE = 117,
+ BOARD_TYPE_CAL_4X25G_DPU_VL = 118, /* 4x25G DPU Card */
+ BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS = 119,
+ BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS = 120,
+ BOARD_TYPE_CAL_6X25G_DPU_VL = 121, /* 6x25G DPU Card */
+ BOARD_TYPE_CAL_4X25G_DPU_BD = 122,
+ BOARD_TYPE_CAL_2X25G_NIC_4HOST = 123,
+ BOARD_TYPE_CAL_2X10G_LOW_POWER = 125,
+ BOARD_TYPE_CAL_2X200G_NIC_INTERNET = 127,
+ BOARD_TYPE_CAL_1X100GR2_OCP = 129, /* 1X100G ETH Standard card */
+ BOARD_TYPE_CAL_2X200G_DPU_VL = 130,
BOARD_TYPE_CLD_2X100G_SDI5_1 = 170, /* 2X100G SDI 5.1 Card */
BOARD_TYPE_CLD_2X25G_SDI5_0_LITE = 171, /* 2x25G SDI5.0 Lite Card */
BOARD_TYPE_CLD_2X100G_SDI5_0 = 172, /* 2x100G SDI5.0 Card */
+ BOARD_TYPE_CLD_4X25G_SDI5_0_C = 175,
BOARD_TYPE_MAX_INDEX = 0xFF
};
@@ -49,23 +60,62 @@ static inline u32 spu_board_type_valid(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
- ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
}
static inline int board_type_is_sdi(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_1) ||
((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
- ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0);
+ ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C);
+}
+
+static inline int board_type_is_dpu_spu(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
}
static inline int board_type_is_dpu(u32 board_type)
{
- return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_6X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
+}
+
+/* 此接口判断是否是分布式存储的标卡以及计算的标卡(含ROCE特性),
+ * 仅用于LLDP TX功能冲突命令字处理的判断
+ */
+static inline int board_type_is_compute(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_75MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_40MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_NIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_COMSTORAGE) ||
+ ((board_type) == BOARD_TYPE_CAL_2X10G_LOW_POWER) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_NIC_INTERNET) ||
+ ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_4HOST) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_NIC_120MPPS);
+}
+
+/* 此接口判断服务器输入reboot网卡是否需要复位 */
+static inline int board_type_is_multi_socket(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP);
}
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
index 291e475..4d4d543 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
@@ -4,8 +4,95 @@
#ifndef MPU_CMD_BASE_DEFS_H
#define MPU_CMD_BASE_DEFS_H
-#include "mgmt_msg_base.h"
-#include "comm_defs.h"
+/** MPU CMD MODULE TYPE */
+enum hinic3_mod_type {
+ HINIC3_MOD_COMM = 0, /* HW communication module */
+ HINIC3_MOD_L2NIC = 1, /* L2NIC module */
+ HINIC3_MOD_ROCE = 2,
+ HINIC3_MOD_PLOG = 3,
+ HINIC3_MOD_TOE = 4,
+ HINIC3_MOD_FLR = 5,
+ HINIC3_MOD_VROCE = 6,
+ HINIC3_MOD_CFGM = 7, /* Configuration management */
+ HINIC3_MOD_CQM = 8,
+ HINIC3_MOD_VMSEC = 9,
+ COMM_MOD_FC = 10,
+ HINIC3_MOD_OVS = 11,
+ HINIC3_MOD_DSW = 12,
+ HINIC3_MOD_MIGRATE = 13,
+ HINIC3_MOD_HILINK = 14,
+ HINIC3_MOD_CRYPT = 15, /* secure crypto module */
+ HINIC3_MOD_VIO = 16,
+ HINIC3_MOD_IMU = 17,
+ HINIC3_MOD_DFX = 18, /* DFX */
+ HINIC3_MOD_HW_MAX = 19, /* hardware max module id */
+ /* Software module id, for PF/VF and multi-host */
+ HINIC3_MOD_SW_FUNC = 20,
+ HINIC3_MOD_MAX,
+};
+
+/* func reset的flag ,用于指示清理哪种资源 */
+enum func_reset_flag_e {
+ RES_TYPE_FLUSH_BIT = 0,
+ RES_TYPE_MQM,
+ RES_TYPE_SMF,
+ RES_TYPE_PF_BW_CFG,
+
+ RES_TYPE_COMM = 10,
+ RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_NIC,
+ RES_TYPE_OVS,
+ RES_TYPE_VBS,
+ RES_TYPE_ROCE,
+ RES_TYPE_FC,
+ RES_TYPE_TOE,
+ RES_TYPE_IPSEC,
+ RES_TYPE_MAX,
+};
+
+#define HINIC3_COMM_RES \
+ ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
+ (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
+ (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
+
+#define HINIC3_NIC_RES (1 << RES_TYPE_NIC)
+#define HINIC3_OVS_RES (1 << RES_TYPE_OVS)
+#define HINIC3_VBS_RES (1 << RES_TYPE_VBS)
+#define HINIC3_ROCE_RES (1 << RES_TYPE_ROCE)
+#define HINIC3_FC_RES (1 << RES_TYPE_FC)
+#define HINIC3_TOE_RES (1 << RES_TYPE_TOE)
+#define HINIC3_IPSEC_RES (1 << RES_TYPE_IPSEC)
+
+/* MODE OVS、NIC、UNKNOWN */
+#define HINIC3_WORK_MODE_OVS 0
+#define HINIC3_WORK_MODE_UNKNOWN 1
+#define HINIC3_WORK_MODE_NIC 2
+
+#define DEVICE_TYPE_L2NIC 0
+#define DEVICE_TYPE_NVME 1
+#define DEVICE_TYPE_VIRTIO_NET 2
+#define DEVICE_TYPE_VIRTIO_BLK 3
+#define DEVICE_TYPE_VIRTIO_VSOCK 4
+#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
+#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
+#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
+#define DEVICE_TYPE_VIRTIO_HPC 8
+#define DEVICE_TYPE_VIRTIO_FS 9
+
+#define IS_STORAGE_DEVICE_TYPE(dev_type) \
+ ((dev_type) == DEVICE_TYPE_VIRTIO_BLK || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_BLK_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_SCSI_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_FS)
+
+#define MGMT_MSG_CMD_OP_SET 1
+#define MGMT_MSG_CMD_OP_GET 0
+
+#define MGMT_MSG_CMD_OP_START 1
+#define MGMT_MSG_CMD_OP_STOP 0
+
+#define HOT_REPLACE_PARTITION_NUM 2
enum hinic3_svc_type {
SVC_T_COMM = 0,
@@ -23,4 +110,54 @@ enum hinic3_svc_type {
SVC_T_MAX,
};
+/**
+ * Common header control information of the COMM message interaction
+ * command word between the driver and PF
+ * struct mgmt_msg_head and struct comm_info_head are the same structure
+ */
+struct mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+/**
+ * Common header control information of the COMM message interaction
+ * command word between the driver and PF
+ */
+struct comm_info_head {
+ /** response status code, 0: success, others: error code */
+ u8 status;
+
+ /** firmware version for command */
+ u8 version;
+
+ /** response aeq number, unused for now */
+ u8 rep_aeq_num;
+ u8 rsvd[5];
+};
+
+static inline u32 get_function_partition(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM;
+}
+
+static inline u32 is_primary_function(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0;
+}
+
+static inline u32 mpu_nic_get_primary_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ function_id : (function_id - port_num);
+}
+
+// when func_id is in partition 0/1, it will get its another func_id in partition 1/0
+static inline u32 mpu_nic_get_backup_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ (function_id + port_num) : (function_id - port_num);
+}
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
index a8e2d63..3841bb5 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
@@ -91,6 +91,10 @@ enum hinic3_mgmt_cmd {
* @see comm_read_ucode_sm_resp
*/
COMM_MGMT_CMD_CLEAR_LOG, /**< clear log @see comm_cmd_clear_log_s */
+ COMM_MGMT_CMD_UCODE_SM_COUNTER_PER,
+ /**< get ucode sm counter @see struct comm_read_ucode_sm_per_req
+ * @see struct comm_read_ucode_sm_per_resp
+ */
COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140, /* check if switch workmode reserved
* @see comm_cmd_check_if_switch_workmode
@@ -103,6 +107,7 @@ enum hinic3_mgmt_cmd {
COMM_MGMT_CMD_CPI_TCAM_DBG, /* enable or disable the scheduled cpi tcam task,
* set task interval time @see comm_cmd_cpi_tcam_dbg_s
*/
+ COMM_MGMT_CMD_LLDP_TX_FUNC_SET,
COMM_MGMT_CMD_SECTION_RSVD_0 = 160, /**< rsvd0 section */
COMM_MGMT_CMD_SECTION_RSVD_1 = 170, /**< rsvd1 section */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
index 674603d..698730f 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
@@ -338,7 +338,8 @@ struct comm_cmd_get_fw_version {
struct mgmt_msg_head head;
u16 fw_type; /**< firmware type @see enum hinic3_fw_ver_type */
- u16 rsvd1;
+ u16 fw_dfx_vld : 1; /**< 0: release, 1: debug */
+ u16 rsvd1 : 15;
u8 ver[HINIC3_FW_VERSION_LEN]; /**< firmware version */
u8 time[HINIC3_FW_COMPILE_TIME_LEN]; /**< firmware compile time */
};
@@ -430,6 +431,22 @@ struct comm_cmd_bdf_info {
u8 rsvd2[5];
};
+struct mpu_pcie_pf_info {
+ u32 device_id; /**< device id */
+ u32 vendor_id; /**< vendor id */
+};
+
+struct mpu_pcie_device_info {
+ u8 status;
+ u8 version;
+ u8 rep_aeq_num;
+ u8 rsvd[5];
+
+ struct mpu_pcie_pf_info pf_info[32];
+ u32 bus_id; /**< bus id */
+ u32 pf_num; /**< pf index */
+};
+
#define TABLE_INDEX_MAX 129
struct sml_table_id_info {
u8 node_id;
@@ -446,6 +463,13 @@ struct comm_cmd_sdi_info {
u32 cfg_sdi_mode; /**< host mode, 0:normal 1:virtual machine 2:bare metal */
};
+struct comm_cmd_root_ctx_load_req {
+ struct comm_info_head head;
+ u32 func_id; /**< function id */
+ u32 smf_id; /**< smf id */
+ u32 queue_id; /**< queue id */
+};
+
#define HINIC_OVS_BOND_DEFAULT_ID 1
struct hinic3_hw_bond_infos {
u8 bond_id;
@@ -685,6 +709,28 @@ struct comm_read_ucode_sm_resp {
u64 val2;
};
+#define PER_REQ_MAX_DATA_LEN 0x600
+
+struct comm_read_ucode_sm_per_req {
+ struct mgmt_msg_head msg_head;
+
+ u32 tbl_type;
+ u32 count_id;
+};
+
+struct comm_read_ucode_sm_per_resp {
+ struct mgmt_msg_head msg_head;
+
+ u8 data[PER_REQ_MAX_DATA_LEN];
+};
+
+struct ucode_sm_counter_get_info {
+ u32 width_type;
+ u32 tbl_type;
+ unsigned int base_count;
+ unsigned int count_num;
+};
+
enum log_type {
MPU_LOG_CLEAR = 0,
SMU_LOG_CLEAR = 1,
@@ -693,6 +739,11 @@ enum log_type {
ALL_LOG_CLEAR = 4,
};
+struct comm_cmd_clear_log {
+ struct comm_info_head head;
+ u32 type; /**< log type @see enum log_type */
+};
+
#define ABLESWITCH 1
#define IMABLESWITCH 2
enum switch_workmode_op {
@@ -717,6 +768,14 @@ struct comm_cmd_check_if_switch_workmode {
u32 rsvd3[3];
};
+struct comm_cmd_switch_workmode {
+ struct mgmt_msg_head head;
+ u8 operation;
+ u8 work_mode;
+ u16 rsvd1[3];
+ u32 rsvd2[3];
+};
+
#define MIG_NOR_VM_ONE_MAX_SGE_MEM (64 * 8)
#define MIG_NOR_VM_ONE_MAX_MEM (MIG_NOR_VM_ONE_MAX_SGE_MEM + 16)
#define MIG_VM_MAX_SML_ENTRY_NUM 24
@@ -755,6 +814,15 @@ struct cmd_get_bdf_info_s {
#define CPI_TCAM_DBG_CMD_TYPE_SET 0
#define CPI_TCAM_DBG_CMD_TYPE_GET 1
+struct comm_cmd_cpi_tcam_dbg {
+ struct comm_info_head head;
+ u8 type;
+ u8 set_bitmap;
+ u8 enable;
+ u8 rsvd;
+ u32 time_interval;
+};
+
#define UDIE_ID_DATA_LEN 8
#define TDIE_ID_DATA_LEN 18
struct comm_cmd_get_die_id {
@@ -808,6 +876,12 @@ struct cmd_query_fw {
u32 len; /**< length */
};
+struct comm_cmd_get_cfg_info_t {
+ struct comm_info_head head;
+ u8 rsvd[8];
+ u8 info[64]; /**< flash config info */
+};
+
struct nic_cmd_get_uart_log_info {
struct comm_info_head head;
struct {
@@ -969,6 +1043,7 @@ enum comm_virtio_dev_type {
COMM_VIRTIO_NET_TYPE = 0,
COMM_VIRTIO_BLK_TYPE = 1,
COMM_VIRTIO_SCSI_TYPE = 4,
+ COMM_VIRTIO_FS_TYPE = 5,
};
struct comm_virtio_dev_cmd {
@@ -1030,6 +1105,13 @@ struct cmd_patch_sram_optimize {
u32 data[4]; /**< reserved */
};
+struct comm_cmd_con_sel_sta {
+ struct comm_info_head head;
+ u8 valid;
+ u8 host_id; /**< host id, range[0,3] */
+ u8 rsvd[2];
+};
+
/* ncsi counter */
struct nsci_counter_in_info_s {
struct comm_info_head head;
@@ -1082,7 +1164,9 @@ struct comm_cmd_ncsi_settings {
u8 lldp_over_ncsi_enable;
u8 lldp_over_mctp_enable;
u32 magicwd;
- u8 rsvd[8];
+ u8 lldp_tx_enable;
+ u8 rsvd[3];
+ u32 crc;
struct tag_ncsi_chan_info ncsi_chan_info;
};
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
index fde8617..1ee44a8 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
@@ -114,6 +114,14 @@ struct tag_ncsi_client_info {
#define AEN_CTRL_CONFIG_REQ_SHIFT 1
#define AEN_CTRL_DRV_CHANGE_SHIFT 2
+/* AEN Type */
+enum aen_type_e {
+ AEN_LINK_STATUS_CHANGE_TYPE = 0x0,
+ AEN_CONFIG_REQUIRED_TYPE = 0x1,
+ OEM_AEN_CONFIG_REQUEST_TYPE = 0x80,
+ AEN_TYPE_MAX = 0x100
+};
+
/* get link status 0x0A */
#define GET_LINK_STATUS_REQ_LEN 0
#define GET_LINK_STATUS_RSP_LEN 16
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
index 0bd168c..5b2bdc8 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
@@ -36,6 +36,7 @@ enum nic_rss_hash_type {
#define NIC_RX_MODE_BC 0x04
#define NIC_RX_MODE_MC_ALL 0x08
#define NIC_RX_MODE_PROMISC 0x10
+#define NIC_RX_DB_COS_MAX 0x4
/* IEEE 802.1Qaz std */
#define NIC_DCB_COS_MAX 0x8
@@ -52,4 +53,7 @@ enum nic_rss_hash_type {
#define NIC_DCB_PRIO_STRICT 0x1
#define NIC_DCB_MAX_PFC_NUM 0x4
+
+#define NIC_ETS_PERCENT_WEIGHT 100
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
index 801aeed..5476287 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
@@ -23,7 +23,11 @@
#define VRAM_CQM_BITMAP_BASE "B"
#define VRAM_NIC_DCB "DCB"
+#define VRAM_NIC_MHOST_MGMT "MHOST_MGMT"
#define VRAM_NIC_VRAM "NIC_VRAM"
+#define VRAM_NIC_IRQ_VRAM "NIC_IRQ"
+
+#define VRAM_NIC_MQM "NM"
#define VRAM_VBS_BASE_IOCB "BASE_IOCB"
#define VRAM_VBS_EX_IOCB "EX_IOCB"
@@ -32,6 +36,9 @@
#define VRAM_VBS_VOLQ_MTT "VOLQ_MTT"
#define VRAM_VBS_VOLQ_MTT_PAGE "MTT_PAGE"
+#define VRAM_OVS_PORT_CONF "OVS_PORT_CONF"
+#define VRAM_OVS_DFX_MGR "OVS_DFX_MGR"
+
#define VRAM_VROCE_ENTRY_POOL "VROCE_ENTRY"
#define VRAM_VROCE_GROUP_POOL "VROCE_GROUP"
#define VRAM_VROCE_UUID "VROCE_UUID"
@@ -42,6 +49,17 @@
#define VRAM_VROCE_DEV "VROCE_DEV"
#define VRAM_VROCE_RGROUP_HT_CNT "RGROUP_CNT"
#define VRAM_VROCE_RACL_HT_CNT "RACL_CNT"
+#define VRAM_VROCE_MQM_ENQC "VROCE_MQM_ENQC"
+
+#define VRAM_DTOE_NUMA_MEM "DTOE_NUMA"
+#define VRAM_DTOE_CARD_MEM "DTOE_CARD"
+#define VRAM_DTOE_CONN_MEM "DTOE_CONN"
+#define VRAM_DTOE_SUB_LEN 10
+
+#define VRAM_VROCE_MIG_ENTRY_POOL "VROCE_MIG_ENTRY"
+#define VRAM_VROCE_MIG_ENTRY_HT_CNT "MIG_ENTRY_CNT"
+
+#define VRAM_VBS_DEV_INDEX "VBS_INDEX"
#define VRAM_NAME_APPLY_LEN 64
@@ -55,11 +73,16 @@ enum KUP_HOOK_POINT {
PRE_FREEZE,
FREEZE_TO_KILL,
PRE_UPDATE_KERNEL,
- FLUSH_DURING_KUP,
POST_UPDATE_KERNEL,
UNFREEZE_TO_RUN,
POST_RUN,
KUP_HOOK_MAX,
};
+#define hi_vram_kalloc(name, size) 0
+#define hi_vram_kfree(vaddr, name, size)
+#define get_use_vram_flag(void) 0
+#define vram_get_kexec_flag(void) 0
+#define hi_vram_get_gfp_vram(void) 0
+
#endif /* VRAM_COMMON_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
similarity index 79%
rename from drivers/net/ethernet/huawei/hinic3/mag_cmd.h
rename to drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
index 9649503..ead8e69 100644
--- a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
@@ -9,6 +9,7 @@
/* serdes cmd struct define */
#define CMD_ARRAY_BUF_SIZE 64
#define SERDES_CMD_DATA_BUF_SIZE 512
+#define RATE_MBPS_TO_GBPS 1000
struct serdes_in_info {
u32 chip_id : 16;
u32 macro_id : 16;
@@ -127,6 +128,7 @@ enum mag_cmd_cnt_type {
MAG_RX_PCS_E_BLK_CNT = 5,
MAG_RX_PCS_DEC_ERR_BLK_CNT = 6,
MAG_RX_PCS_LANE_BIP_ERR_CNT = 7,
+ MAG_RX_RSFEC_ERR_CW_CNT = 8,
MAG_CNT_NUM
};
@@ -208,7 +210,9 @@ struct mag_cmd_get_port_info {
u32 supported_mode;
u32 advertised_mode;
- u8 rsvd2[8];
+ u32 supported_fec_mode;
+ u16 bond_speed;
+ u8 rsvd2[2];
};
#define MAG_CMD_OPCODE_GET 0
@@ -330,8 +334,8 @@ struct mag_cmd_cfg_fec_mode {
u8 port_id;
u8 opcode; /* 0:get fec mode 1:set fec mode */
- u8 fec;
- u8 rsvd0;
+ u8 advertised_fec;
+ u8 supported_fec;
};
/* speed */
@@ -641,7 +645,7 @@ struct mag_cmd_event_port_info {
u32 cable_length; /* 1/3/5m */
u8 cable_temp; /* temp */
u8 max_speed; /* Maximum rate of an optical module */
- u8 sfp_type; /* sfp/qsfp */
+ u8 sfp_type; /* sfp/qsfp/dsfp */
u8 rsvd1;
u32 power[4]; /* Optical Power */
@@ -678,6 +682,10 @@ struct mag_cmd_event_port_info {
u8 rsvd3[360];
};
+struct mag_cmd_rsfec_stats {
+ u32 rx_err_lane_phy;
+};
+
struct mag_cmd_port_stats {
u64 mac_tx_fragment_pkt_num;
u64 mac_tx_undersize_pkt_num;
@@ -913,10 +921,223 @@ struct mag_cmd_sfp_temp_in_info {
};
struct mag_cmd_sfp_temp_out_info {
- struct mgmt_msg_head head; /* 8B */
- s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
- s32 max_temp; /* Chip optical module threshold */
- s32 min_temp; /* Chip optical module threshold */
+ struct mgmt_msg_head head; /* 8B */
+ s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
+ s32 max_temp; /* Chip optical module threshold */
+ s32 min_temp; /* Chip optical module threshold */
+};
+
+#define XSFP_CMIS_PARSE_PAGE_NUM 6
+#define XSFP_CMIS_INFO_MAX_SIZE 1536
+#define QSFP_CMIS_PAGE_SIZE 128
+#define QSFP_CMIS_MAX_CHANNEL_NUM 0x8
+
+/* Lower: Control and Essentials, Upper: Administrative Information */
+#define QSFP_CMIS_PAGE_00H 0x00
+/* Advertising */
+#define QSFP_CMIS_PAGE_01H 0x01
+/* Module and lane Thresholds */
+#define QSFP_CMIS_PAGE_02H 0x02
+/* User EEPROM */
+#define QSFP_CMIS_PAGE_03H 0x03
+/* Laser Capabilities Advertising (Page 04h, Optional) */
+#define QSFP_CMIS_PAGE_04H 0x04
+#define QSFP_CMIS_PAGE_05H 0x05
+/* Lane and Data Path Control */
+#define QSFP_CMIS_PAGE_10H 0x10
+/* Lane Status */
+#define QSFP_CMIS_PAGE_11H 0x11
+#define QSFP_CMIS_PAGE_12H 0x12
+
+#define MGMT_TLV_U8_SIZE 1
+#define MGMT_TLV_U16_SIZE 2
+#define MGMT_TLV_U32_SIZE 4
+
+#define MGMT_TLV_GET_U8(addr) (*((u8 *)(void *)(addr)))
+#define MGMT_TLV_SET_U8(addr, value) \
+ ((*((u8 *)(void *)(addr))) = ((u8)(value)))
+
+#define MGMT_TLV_GET_U16(addr) (*((u16 *)(void *)(addr)))
+#define MGMT_TLV_SET_U16(addr, value) \
+ ((*((u16 *)(void *)(addr))) = ((u16)(value)))
+
+#define MGMT_TLV_GET_U32(addr) (*((u32 *)(void *)(addr)))
+#define MGMT_TLV_SET_U32(addr, value) \
+ ((*((u32 *)(void *)(addr))) = ((u32)(value)))
+
+#define MGMT_TLV_TYPE_END 0xFFFF
+
+enum mag_xsfp_type {
+ MAG_XSFP_TYPE_PAGE = 0x01,
+ MAG_XSFP_TYPE_WIRE_TYPE = 0x02,
+ MAG_XSFP_TYPE_END = MGMT_TLV_TYPE_END
+};
+
+struct qsfp_cmis_lower_page_00_s {
+ u8 resv0[14];
+ u8 temperature_msb;
+ u8 temperature_lsb;
+ u8 volt_supply[2];
+ u8 resv1[67];
+ u8 media_type;
+ u8 electrical_interface_id;
+ u8 media_interface_id;
+ u8 lane_count;
+ u8 resv2[39];
+};
+
+struct qsfp_cmis_upper_page_00_s {
+ u8 identifier;
+ u8 vendor_name[16];
+ u8 vendor_oui[3];
+ u8 vendor_pn[16];
+ u8 vendor_rev[2];
+ u8 vendor_sn[16];
+ u8 date_code[8];
+ u8 clei_code[10];
+ u8 power_character[2];
+ u8 cable_len;
+ u8 connector;
+ u8 copper_cable_attenuation[6];
+ u8 near_end_implementation;
+ u8 far_end_config;
+ u8 media_technology;
+ u8 resv0[43];
+};
+
+struct qsfp_cmis_upper_page_01_s {
+ u8 firmware_rev[2];
+ u8 hardware_rev[2];
+ u8 smf_len_km;
+ u8 om5_len;
+ u8 om4_len;
+ u8 om3_len;
+ u8 om2_len;
+ u8 resv0;
+ u8 wavelength[2];
+ u8 wavelength_tolerance[2];
+ u8 pages_implement;
+ u8 resv1[16];
+ u8 monitor_implement[2];
+ u8 resv2[95];
+};
+
+struct qsfp_cmis_upper_page_02_s {
+ u8 temperature_high_alarm[2];
+ u8 temperature_low_alarm[2];
+ u8 temperature_high_warn[2];
+ u8 temperature_low_warn[2];
+ u8 volt_high_alarm[2];
+ u8 volt_low_alarm[2];
+ u8 volt_high_warn[2];
+ u8 volt_low_warn[2];
+ u8 resv0[32];
+ u8 tx_power_high_alarm[2];
+ u8 tx_power_low_alarm[2];
+ u8 tx_power_high_warn[2];
+ u8 tx_power_low_warn[2];
+ u8 tx_bias_high_alarm[2];
+ u8 tx_bias_low_alarm[2];
+ u8 tx_bias_high_warn[2];
+ u8 tx_bias_low_warn[2];
+ u8 rx_power_high_alarm[2];
+ u8 rx_power_low_alarm[2];
+ u8 rx_power_high_warn[2];
+ u8 rx_power_low_warn[2];
+ u8 resv1[56];
+};
+
+struct qsfp_cmis_upper_page_03_s {
+ u8 resv0[QSFP_CMIS_PAGE_SIZE]; /* Reg 128-255: Upper Memory: Page 03H */
+};
+
+struct qsfp_cmis_upper_page_10_s {
+ u8 resv0[2]; /* Reg 128-129: Upper Memory: Page 10H */
+ u8 tx_disable; /* Reg 130: Tx disable, 0b=enabled, 1b=disabled */
+ u8 resv1[125]; /* Reg 131-255 */
+};
+
+struct qsfp_cmis_upper_page_11_s {
+ u8 resv0[7];
+ u8 tx_fault;
+ u8 tx_los;
+ u8 resv1[10];
+ u8 rx_los;
+ u8 resv2[6];
+ u8 tx_power[16];
+ u8 tx_bias[16];
+ u8 rx_power[16];
+ u8 resv3[54];
+};
+
+struct qsfp_cmis_info_s {
+ struct qsfp_cmis_lower_page_00_s lower_page_00;
+ struct qsfp_cmis_upper_page_00_s upper_page_00;
+ struct qsfp_cmis_upper_page_01_s upper_page_01;
+ struct qsfp_cmis_upper_page_02_s upper_page_02;
+ struct qsfp_cmis_upper_page_10_s upper_page_10;
+ struct qsfp_cmis_upper_page_11_s upper_page_11;
+};
+
+struct qsfp_cmis_comm_power_s {
+ u32 chl_power[QSFP_CMIS_MAX_CHANNEL_NUM];
+};
+
+struct qsfp_cmis_wire_info_s {
+ struct qsfp_cmis_comm_power_s rx_power;
+ u8 rx_los;
+ u8 resv0[3];
+};
+
+struct mgmt_tlv_info {
+ u16 type;
+ u16 length;
+ u8 value[];
+};
+
+struct mag_cmd_set_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 tlv_buf[];
+};
+
+struct mag_cmd_set_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+};
+
+struct tag_mag_cmd_get_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd;
+ u16 rsp_buf_len;
+};
+
+struct mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[];
+};
+
+
+struct parse_tlv_info {
+ u8 tlv_page_info[XSFP_CMIS_INFO_MAX_SIZE + 1];
+ u32 tlv_page_info_len;
+ u32 tlv_page_num[XSFP_CMIS_PARSE_PAGE_NUM];
+ u32 wire_type;
+ u8 id;
+};
+
+struct drv_tag_mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[XSFP_CMIS_INFO_MAX_SIZE];
};
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h b/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
deleted file mode 100644
index 257bf67..0000000
--- a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : mgmt_msg_base.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef MGMT_MSG_BASE_H
-#define MGMT_MSG_BASE_H
-
-#define MGMT_MSG_CMD_OP_SET 1
-#define MGMT_MSG_CMD_OP_GET 0
-
-#define MGMT_MSG_CMD_OP_START 1
-#define MGMT_MSG_CMD_OP_STOP 0
-
-struct mgmt_msg_head {
- u8 status;
- u8 version;
- u8 rsvd0[6];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
deleted file mode 100644
index abcfa27..0000000
--- a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2001-2021, Huawei Tech. Co., Ltd.
- * File Name : nic_cfg_comm.h
- * Version : Initial Draft
- * Description : nic config common header file
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef NIC_CFG_COMM_H
-#define NIC_CFG_COMM_H
-
-#include <linux/types.h>
-
-/* rss */
-#define HINIC3_RSS_TYPE_VALID_SHIFT 23
-#define HINIC3_RSS_TYPE_TCP_IPV6_EXT_SHIFT 24
-#define HINIC3_RSS_TYPE_IPV6_EXT_SHIFT 25
-#define HINIC3_RSS_TYPE_TCP_IPV6_SHIFT 26
-#define HINIC3_RSS_TYPE_IPV6_SHIFT 27
-#define HINIC3_RSS_TYPE_TCP_IPV4_SHIFT 28
-#define HINIC3_RSS_TYPE_IPV4_SHIFT 29
-#define HINIC3_RSS_TYPE_UDP_IPV6_SHIFT 30
-#define HINIC3_RSS_TYPE_UDP_IPV4_SHIFT 31
-
-#define HINIC3_RSS_TYPE_SET(val, member) (((u32)(val) & 0x1) << HINIC3_RSS_TYPE_##member##_SHIFT)
-#define HINIC3_RSS_TYPE_GET(val, member) (((u32)(val) >> HINIC3_RSS_TYPE_##member##_SHIFT) & 0x1)
-
-enum nic_rss_hash_type {
- NIC_RSS_HASH_TYPE_XOR = 0,
- NIC_RSS_HASH_TYPE_TOEP,
-
- NIC_RSS_HASH_TYPE_MAX /* MUST BE THE LAST ONE */
-};
-
-#define NIC_RSS_INDIR_SIZE 256
-#define NIC_RSS_KEY_SIZE 40
-
-/* *
- * Definition of the NIC receiving mode
- */
-#define NIC_RX_MODE_UC 0x01
-#define NIC_RX_MODE_MC 0x02
-#define NIC_RX_MODE_BC 0x04
-#define NIC_RX_MODE_MC_ALL 0x08
-#define NIC_RX_MODE_PROMISC 0x10
-
-/* IEEE 802.1Qaz std */
-#define NIC_DCB_COS_MAX 0x8
-#define NIC_DCB_UP_MAX 0x8
-#define NIC_DCB_TC_MAX 0x8
-#define NIC_DCB_PG_MAX 0x8
-#define NIC_DCB_TSA_SP 0x0
-#define NIC_DCB_TSA_CBS 0x1
-#define NIC_DCB_TSA_ETS 0x2
-#define NIC_DCB_DSCP_NUM 0x8
-#define NIC_DCB_IP_PRI_MAX 0x40
-
-#define NIC_DCB_PRIO_DWRR 0x0
-#define NIC_DCB_PRIO_STRICT 0x1
-
-#define NIC_DCB_MAX_PFC_NUM 0x4
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
similarity index 77%
rename from drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
rename to drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
index c35bc82..a228522 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
- * File Name : hinic3_comm_cmd.h
+ * File Name : hinic3_nic_mpu_cmd.h
* Version : Initial Draft
* Created : 2019/4/25
* Last Modified :
@@ -33,10 +33,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_CFG_LOCAL_LRO_STATE,
HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
+ HINIC3_NIC_CMD_SET_FUNC_ER_FWD_ID,
HINIC3_NIC_CMD_SET_RQ_CI_CTX,
- /* MAC & VLAN CFG */
+ /* MAC & VLAN CFG & VXLAN CFG */
HINIC3_NIC_CMD_GET_MAC = 20,
HINIC3_NIC_CMD_SET_MAC,
HINIC3_NIC_CMD_DEL_MAC,
@@ -47,6 +48,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_VLAN_FILTER_EN,
HINIC3_NIC_CMD_SET_RX_VLAN_OFFLOAD,
HINIC3_NIC_CMD_SMAC_CHECK_STATE,
+ HINIC3_NIC_CMD_OUTBAND_SET_FUNC_VLAN,
+ HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+
+ HINIC3_NIC_CMD_RX_RATE_CFG,
+ HINIC3_NIC_CMD_WR_ORDERING_CFG,
/* SR-IOV */
HINIC3_NIC_CMD_CFG_VF_VLAN = 40,
@@ -63,6 +69,7 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC,
/* IP checksum error packets, enable rss quadruple hash */
HINIC3_NIC_CMD_IPCS_ERR_RSS_ENABLE_OP = 66,
+ HINIC3_NIC_CMD_GTP_INNER_PARSE_STATUS,
/* PPA/FDIR */
HINIC3_NIC_CMD_ADD_TC_FLOW = 80,
@@ -78,6 +85,10 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_CFG_PPA_FLUSH,
HINIC3_NIC_CMD_SET_FDIR_STATUS,
HINIC3_NIC_CMD_GET_PPA_COUNTER,
+ HINIC3_NIC_CMD_SET_FUNC_FLOW_BIFUR_ENABLE,
+ HINIC3_NIC_CMD_SET_BOND_MASK,
+ HINIC3_NIC_CMD_GET_BLOCK_TC_FLOWS,
+ HINIC3_NIC_CMD_GET_BOND_MASK,
/* PORT CFG */
HINIC3_NIC_CMD_SET_PORT_ENABLE = 100,
@@ -96,6 +107,8 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_QOS_PORT_CFG,
HINIC3_NIC_CMD_QOS_MAP_CFG,
HINIC3_NIC_CMD_FORCE_PKT_DROP,
+ HINIC3_NIC_CMD_CFG_TX_PROMISC_SKIP = 114,
+ HINIC3_NIC_CMD_SET_PORT_FLOW_BIFUR_ENABLE = 117,
HINIC3_NIC_CMD_TX_PAUSE_EXCP_NOTICE = 118,
HINIC3_NIC_CMD_INQUIRT_PAUSE_CFG = 119,
@@ -118,6 +131,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_UCAPTURE_OPT = 160, /* TODO: move to roce */
HINIC3_NIC_CMD_SET_VHD_CFG,
+ /* OUT OF BAND */
+ HINIC3_NIC_CMD_GET_OUTBAND_CFG = 170, /* Get outband vlan cfg info */
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE, /* Outband vlan cfg info report */
+
+
/* TODO: move to HILINK */
HINIC3_NIC_CMD_GET_PORT_STAT = 200,
HINIC3_NIC_CMD_CLEAN_PORT_STAT,
@@ -138,24 +156,23 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_LINK_ERR_EVENT,
HINIC3_NIC_CMD_SET_LED_STATUS,
- HINIC3_NIC_CMD_MAX = 256,
-};
+ /* mig */
+ HINIC3_NIC_CMD_MIG_SET_CEQ_CTRL = 230,
+ HINIC3_NIC_CMD_MIG_CFG_MSIX_INFO,
+ HINIC3_NIC_CMD_MIG_CFG_FUNC_VAT_TBL,
+ HINIC3_NIC_CMD_MIG_GET_VF_INFO,
+ HINIC3_NIC_CMD_MIG_CHK_MBX_EMPTY,
+ HINIC3_NIC_CMD_MIG_SET_VPORT_ENABLE,
+ HINIC3_NIC_CMD_MIG_CFG_SQ_CI,
+ HINIC3_NIC_CMD_MIG_CFG_RSS_TBL,
+ HINIC3_NIC_CMD_MIG_CFG_MAC_TBL,
+ HINIC3_NIC_CMD_MIG_TMP_SET_CMDQ_CTX,
+
+ HINIC3_OSHR_CMD_ACTIVE_FUNCTION = 240,
-/* NIC CMDQ MODE */
-enum hinic3_ucode_cmd {
- HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
- HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
- HINIC3_UCODE_CMD_ARM_SQ,
- HINIC3_UCODE_CMD_ARM_RQ,
- HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_SET_IQ_ENABLE,
- HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
- HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
- HINIC3_UCODE_CMD_PPA_HASH_TABLE,
- HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_NIC_CMD_GET_RQ_INFO = 241,
+
+ HINIC3_NIC_CMD_MAX = 256,
};
#endif /* HINIC3_NIC_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
new file mode 100644
index 0000000..5c28573
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
@@ -0,0 +1,1440 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+
+#ifndef NIC_MPU_CMD_DEFS_H
+#define NIC_MPU_CMD_DEFS_H
+
+#include "nic_cfg_comm.h"
+#include "mpu_cmd_base_defs.h"
+
+#ifndef ETH_ALEN
+#define ETH_ALEN 6
+#endif
+
+#define HINIC3_CMD_OP_SET 1
+#define HINIC3_CMD_OP_GET 0
+
+#define HINIC3_CMD_OP_ADD 1
+#define HINIC3_CMD_OP_DEL 0
+
+#define NIC_TCAM_BLOCK_LARGE_NUM 256
+#define NIC_TCAM_BLOCK_LARGE_SIZE 16
+
+#define TRAFFIC_BIFUR_MODEL_TYPE 2
+
+#define NIC_TCAM_FLOW_BIFUR_FLAG (1 << 0)
+
+#ifndef BIT
+#define BIT(n) (1UL << (n))
+#endif
+
+enum nic_feature_cap {
+ NIC_F_CSUM = BIT(0),
+ NIC_F_SCTP_CRC = BIT(1),
+ NIC_F_TSO = BIT(2),
+ NIC_F_LRO = BIT(3),
+ NIC_F_UFO = BIT(4),
+ NIC_F_RSS = BIT(5),
+ NIC_F_RX_VLAN_FILTER = BIT(6),
+ NIC_F_RX_VLAN_STRIP = BIT(7),
+ NIC_F_TX_VLAN_INSERT = BIT(8),
+ NIC_F_VXLAN_OFFLOAD = BIT(9),
+ NIC_F_IPSEC_OFFLOAD = BIT(10),
+ NIC_F_FDIR = BIT(11),
+ NIC_F_PROMISC = BIT(12),
+ NIC_F_ALLMULTI = BIT(13),
+ NIC_F_XSFP_REPORT = BIT(14),
+ NIC_F_VF_MAC = BIT(15),
+ NIC_F_RATE_LIMIT = BIT(16),
+ NIC_F_RXQ_RECOVERY = BIT(17),
+ NIC_F_TX_COMPACT_WQE_OL = BIT(19),
+ NIC_F_RX_COMPACT_CQE = BIT(20),
+ NIC_F_HTN_CMDQ = BIT(21),
+};
+
+#define NIC_F_ALL_MASK 0x7FBFFFF /* 使能所有属性 */
+
+struct hinic3_mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+#define NIC_MAX_FEATURE_QWORD 4
+struct hinic3_cmd_feature_nego {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 1: set, 0: get */
+ u8 rsvd;
+ u64 s_feature[NIC_MAX_FEATURE_QWORD];
+};
+
+struct hinic3_port_mac_set {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 rsvd1;
+ u8 mac[ETH_ALEN];
+};
+
+struct hinic3_port_mac_update {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 rsvd1;
+ u8 old_mac[ETH_ALEN];
+ u16 rsvd2;
+ u8 new_mac[ETH_ALEN];
+};
+
+struct hinic3_vport_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 state; /* 0--disable, 1--enable */
+ u8 rsvd2[3];
+};
+
+struct hinic3_port_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 state; /* 0--disable, 1--enable */
+ u8 rsvd2[3];
+};
+
+#define HINIC3_SET_PORT_CAR_PROFILE 0
+#define HINIC3_SET_PORT_CAR_STATE 1
+#define HINIC3_GET_PORT_CAR_LIMIT_SPEED 2
+
+struct hinic3_port_car_info {
+ u32 cir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
+ u32 xir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
+ u32 cbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
+ u32 xbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
+};
+
+struct hinic3_cmd_set_port_car {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode; /* 0--set car profile, 1--set car state */
+ u8 state; /* 0--disable, 1--enable */
+ u8 level;
+
+ struct hinic3_port_car_info car;
+};
+
+struct hinic3_cmd_clear_qp_resource {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_cmd_cache_out_qp_resource {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_port_stats_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_vport_stats {
+ u64 tx_unicast_pkts_vport;
+ u64 tx_unicast_bytes_vport;
+ u64 tx_multicast_pkts_vport;
+ u64 tx_multicast_bytes_vport;
+ u64 tx_broadcast_pkts_vport;
+ u64 tx_broadcast_bytes_vport;
+
+ u64 rx_unicast_pkts_vport;
+ u64 rx_unicast_bytes_vport;
+ u64 rx_multicast_pkts_vport;
+ u64 rx_multicast_bytes_vport;
+ u64 rx_broadcast_pkts_vport;
+ u64 rx_broadcast_bytes_vport;
+
+ u64 tx_discard_vport;
+ u64 rx_discard_vport;
+ u64 tx_err_vport;
+ u64 rx_err_vport;
+};
+
+struct hinic3_phy_fpga_port_stats {
+ u64 mac_rx_total_octs_port;
+ u64 mac_tx_total_octs_port;
+ u64 mac_rx_under_frame_pkts_port;
+ u64 mac_rx_frag_pkts_port;
+ u64 mac_rx_64_oct_pkts_port;
+ u64 mac_rx_127_oct_pkts_port;
+ u64 mac_rx_255_oct_pkts_port;
+ u64 mac_rx_511_oct_pkts_port;
+ u64 mac_rx_1023_oct_pkts_port;
+ u64 mac_rx_max_oct_pkts_port;
+ u64 mac_rx_over_oct_pkts_port;
+ u64 mac_tx_64_oct_pkts_port;
+ u64 mac_tx_127_oct_pkts_port;
+ u64 mac_tx_255_oct_pkts_port;
+ u64 mac_tx_511_oct_pkts_port;
+ u64 mac_tx_1023_oct_pkts_port;
+ u64 mac_tx_max_oct_pkts_port;
+ u64 mac_tx_over_oct_pkts_port;
+ u64 mac_rx_good_pkts_port;
+ u64 mac_rx_crc_error_pkts_port;
+ u64 mac_rx_broadcast_ok_port;
+ u64 mac_rx_multicast_ok_port;
+ u64 mac_rx_mac_frame_ok_port;
+ u64 mac_rx_length_err_pkts_port;
+ u64 mac_rx_vlan_pkts_port;
+ u64 mac_rx_pause_pkts_port;
+ u64 mac_rx_unknown_mac_frame_port;
+ u64 mac_tx_good_pkts_port;
+ u64 mac_tx_broadcast_ok_port;
+ u64 mac_tx_multicast_ok_port;
+ u64 mac_tx_underrun_pkts_port;
+ u64 mac_tx_mac_frame_ok_port;
+ u64 mac_tx_vlan_pkts_port;
+ u64 mac_tx_pause_pkts_port;
+};
+
+struct hinic3_port_stats {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ struct hinic3_phy_fpga_port_stats stats;
+};
+
+struct hinic3_cmd_vport_stats {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u32 stats_size;
+ u32 rsvd1;
+ struct hinic3_vport_stats stats;
+ u64 rsvd2[6];
+};
+
+struct hinic3_cmd_qpn {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 base_qpn;
+};
+
+enum hinic3_func_tbl_cfg_bitmap {
+ FUNC_CFG_INIT,
+ FUNC_CFG_RX_BUF_SIZE,
+ FUNC_CFG_MTU,
+};
+
+struct hinic3_func_tbl_cfg {
+ u16 rx_wqe_buf_size;
+ u16 mtu;
+ u32 rsvd[9];
+};
+
+struct hinic3_cmd_set_func_tbl {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd;
+
+ u32 cfg_bitmap;
+ struct hinic3_func_tbl_cfg tbl_cfg;
+};
+
+struct hinic3_cmd_cons_idx_attr {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_idx;
+ u8 dma_attr_off;
+ u8 pending_limit;
+ u8 coalescing_time;
+ u8 intr_en;
+ u16 intr_idx;
+ u32 l2nic_sqn;
+ u32 rsvd;
+ u64 ci_addr;
+};
+
+union sm_tbl_args {
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } mac_table_arg;
+ struct {
+ u32 er_id;
+ u32 vlan_id;
+ } vlan_elb_table_arg;
+ struct {
+ u32 func_id;
+ } vlan_filter_arg;
+ struct {
+ u32 mc_id;
+ } mc_elb_arg;
+ struct {
+ u32 func_id;
+ } func_tbl_arg;
+ struct {
+ u32 port_id;
+ } port_tbl_arg;
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } fdir_io_table_arg;
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } flexq_table_arg;
+ u32 args[4];
+};
+
+struct hinic3_rq_cqe_ctx {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 cqe_type;
+ u8 rq_id;
+ u8 threshold_cqe_num;
+ u8 rsvd1;
+
+ u16 msix_entry_idx;
+ u16 rsvd2;
+
+ u32 ci_addr_hi;
+ u32 ci_addr_lo;
+
+ u16 timer_loop;
+ u16 rsvd3;
+};
+
+#define DFX_SM_TBL_BUF_MAX (768)
+
+struct nic_cmd_dfx_sm_table {
+ struct hinic3_mgmt_msg_head msg_head;
+ u32 tbl_type;
+ union sm_tbl_args args;
+ u8 tbl_buf[DFX_SM_TBL_BUF_MAX];
+};
+
+struct hinic3_cmd_vlan_offload {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 vlan_offload;
+ u8 rsvd1[5];
+};
+
+/* ucode capture cfg info */
+struct nic_cmd_capture_info {
+ struct hinic3_mgmt_msg_head msg_head;
+ u32 op_type;
+ u32 func_port;
+ u32 is_en_trx;
+ u32 offset_cos;
+ u32 data_vlan;
+};
+
+struct hinic3_cmd_lro_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u8 lro_ipv4_en;
+ u8 lro_ipv6_en;
+ u8 lro_max_pkt_len; /* unit is 1K */
+ u8 resv2[13];
+};
+
+struct hinic3_cmd_lro_timer {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 opcode; /* 1: set timer value, 0: get timer value */
+ u8 rsvd1;
+ u16 rsvd2;
+ u32 timer;
+};
+
+struct hinic3_cmd_local_lro_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 state; /* 0: disable, 1: enable */
+};
+
+struct hinic3_cmd_gtp_inner_parse_status {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 status; /* 0: disable, 1: enable */
+};
+
+struct hinic3_cmd_vf_vlan_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u16 vlan_id;
+ u8 qos;
+ u8 rsvd2[5];
+};
+
+struct hinic3_cmd_spoofchk_set {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 state;
+ u8 rsvd1;
+};
+
+struct hinic3_cmd_tx_rate_cfg {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 rsvd1;
+ u8 direct;
+ u32 min_rate;
+ u32 max_rate;
+ u8 rsvd2[8];
+};
+
+struct hinic3_cmd_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+ u8 port_type;
+ u8 autoneg_cap;
+ u8 autoneg_state;
+ u8 duplex;
+ u8 speed;
+ u8 fec;
+ u16 rsvd2;
+ u32 rsvd3[4];
+};
+
+struct hinic3_cmd_register_vf {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 op_register; /* 0 - unregister, 1 - register */
+ u8 rsvd1[3];
+ u32 support_extra_feature;
+ u8 rsvd2[32];
+};
+
+struct hinic3_cmd_link_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 state;
+ u16 rsvd1;
+};
+
+struct hinic3_cmd_vlan_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 outband_defvid_flag;
+ u16 vlan_id;
+ u8 blacklist_flag;
+ u8 rsvd2;
+};
+
+#define VLAN_BLACKLIST_ENABLE 1
+#define VLAN_BLACKLIST_DISABLE 0
+
+struct hinic3_cmd_vxlan_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 cfg_mode;
+ u16 vxlan_port;
+ u16 rsvd2;
+};
+
+/* set vlan filter */
+struct hinic3_cmd_set_vlan_filter {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 resvd[2];
+ u32 vlan_filter_ctrl; /* bit0:vlan filter en; bit1:broadcast_filter_en */
+};
+
+struct hinic3_cmd_link_ksettings_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+
+ u32 valid_bitmap;
+ u8 speed; /* enum nic_speed_level */
+ u8 autoneg; /* 0 - off, 1 - on */
+ u8 fec; /* 0 - RSFEC, 1 - BASEFEC, 2 - NOFEC */
+ u8 rsvd2[21]; /* reserved for duplex, port, etc. */
+};
+
+struct mpu_lt_info {
+ u8 node;
+ u8 inst;
+ u8 entry_size;
+ u8 rsvd;
+ u32 lt_index;
+ u32 offset;
+ u32 len;
+};
+
+struct nic_mpu_lt_opera {
+ struct hinic3_mgmt_msg_head msg_head;
+ struct mpu_lt_info net_lt_cmd;
+ u8 data[100];
+};
+
+struct hinic3_force_pkt_drop {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port;
+ u8 rsvd1[3];
+};
+
+struct hinic3_rx_mode_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u32 rx_mode;
+};
+
+/* rss */
+struct hinic3_rss_context_table {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u32 context;
+};
+
+struct hinic3_cmd_rss_engine_type {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 hash_engine;
+ u8 rsvd1[4];
+};
+
+struct hinic3_cmd_rss_hash_key {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u8 key[NIC_RSS_KEY_SIZE];
+};
+
+struct hinic3_rss_indir_table {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 indir[NIC_RSS_INDIR_SIZE];
+};
+
+#define NIC_RSS_CMD_TEMP_ALLOC 0x01
+#define NIC_RSS_CMD_TEMP_FREE 0x02
+
+struct hinic3_rss_template_mgmt {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 cmd;
+ u8 template_id;
+ u8 rsvd1[4];
+};
+
+struct hinic3_cmd_rss_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 rss_en;
+ u8 rq_priority_number;
+ u8 prio_tc[NIC_DCB_COS_MAX];
+ u16 num_qps;
+ u16 rsvd1;
+};
+
+struct hinic3_dcb_state {
+ u8 dcb_on;
+ u8 default_cos;
+ u8 trust;
+ u8 rsvd1;
+ u8 pcp2cos[NIC_DCB_UP_MAX];
+ u8 dscp2cos[64];
+ u32 rsvd2[7];
+};
+
+struct hinic3_cmd_vf_dcb_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ struct hinic3_dcb_state state;
+};
+
+struct hinic3_up_ets_cfg { /* delet */
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+
+ u8 cos_tc[NIC_DCB_COS_MAX];
+ u8 tc_bw[NIC_DCB_TC_MAX];
+ u8 cos_prio[NIC_DCB_COS_MAX];
+ u8 cos_bw[NIC_DCB_COS_MAX];
+ u8 tc_prio[NIC_DCB_TC_MAX];
+};
+
+#define CMD_QOS_ETS_COS_TC BIT(0)
+#define CMD_QOS_ETS_TC_BW BIT(1)
+#define CMD_QOS_ETS_COS_PRIO BIT(2)
+#define CMD_QOS_ETS_COS_BW BIT(3)
+#define CMD_QOS_ETS_TC_PRIO BIT(4)
+#define CMD_QOS_ETS_TC_RATELIMIT BIT(5)
+struct hinic3_cmd_ets_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 1 - set, 0 - get */
+ /* bit0 - cos_tc, bit1 - tc_bw, bit2 - cos_prio, bit3 - cos_bw, bit4 - tc_prio */
+ u8 cfg_bitmap;
+ u8 rsvd;
+
+ u8 cos_tc[NIC_DCB_COS_MAX];
+ u8 tc_bw[NIC_DCB_TC_MAX];
+ u8 cos_prio[NIC_DCB_COS_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 cos_bw[NIC_DCB_COS_MAX];
+ u8 tc_prio[NIC_DCB_TC_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 rate_limit[NIC_DCB_TC_MAX];
+};
+
+struct hinic3_cmd_set_dcb_state {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 op_code; /* 0 - get dcb state, 1 - set dcb state */
+ u8 state; /* 0 - disable, 1 - enable dcb */
+ u8 port_state; /* 0 - disable, 1 - enable dcb */
+ u8 rsvd[7];
+};
+
+#define PFC_BIT_MAP_NUM 8
+struct hinic3_cmd_set_pfc {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 0:get 1: set pfc_en 2: set pfc_bitmap 3: set all */
+ u8 pfc_en; /* pfc_en 和 pfc_bitmap 必须同时设置 */
+ u8 pfc_bitmap;
+ u8 rsvd[4];
+};
+
+#define CMD_QOS_PORT_TRUST BIT(0)
+#define CMD_QOS_PORT_DFT_COS BIT(1)
+struct hinic3_cmd_qos_port_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 0 - get, 1 - set */
+ u8 cfg_bitmap; /* bit0 - trust, bit1 - dft_cos */
+ u8 rsvd0;
+
+ u8 trust;
+ u8 dft_cos;
+ u8 rsvd1[18];
+};
+
+#define MAP_COS_MAX_NUM 8
+#define CMD_QOS_MAP_PCP2COS BIT(0)
+#define CMD_QOS_MAP_DSCP2COS BIT(1)
+struct hinic3_cmd_qos_map_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 op_code;
+ u8 cfg_bitmap; /* bit0 - pcp2cos, bit1 - dscp2cos */
+ u16 rsvd0;
+
+ u8 pcp2cos[8]; /* 8 must be configured together */
+ /* If the dscp2cos parameter is set to 0xFF, the MPU ignores the DSCP priority,
+ * Multiple mappings between DSCP values and CoS values can be configured at a time.
+ */
+ u8 dscp2cos[64];
+ u32 rsvd1[4];
+};
+
+struct hinic3_cos_up_map {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 cos_valid_mask; /* every bit indicate index of map is valid 1 or not 0 */
+ u16 rsvd1;
+
+ /* user priority in cos(index:cos, value: up pri) */
+ u8 map[NIC_DCB_UP_MAX];
+};
+
+struct hinic3_cmd_pause_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode;
+ u16 rsvd1;
+ u8 auto_neg;
+ u8 rx_pause;
+ u8 tx_pause;
+ u8 rsvd2[5];
+};
+
+struct nic_cmd_pause_inquiry_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 valid;
+
+ u32 type; /* 1: set, 2: get */
+
+ u32 cos_id;
+
+ u32 rx_inquiry_pause_drop_pkts_en;
+ u32 rx_inquiry_pause_period_ms;
+ u32 rx_inquiry_pause_times;
+ /* rx pause Detection Threshold, Default PAUSE_FRAME_THD_10G/25G/40G/100 */
+ u32 rx_inquiry_pause_frame_thd;
+ u32 rx_inquiry_tx_total_pkts;
+
+ u32 tx_inquiry_pause_en; /* tx pause detect enable */
+ u32 tx_inquiry_pause_period_ms; /* tx pause Default Detection Period 200ms */
+ u32 tx_inquiry_pause_times; /* tx pause Default Times Period 5 */
+ u32 tx_inquiry_pause_frame_thd; /* tx pause Detection Threshold */
+ u32 tx_inquiry_rx_total_pkts;
+ u32 rsvd[3];
+};
+
+/* pfc/pause Storm TX exception reporting */
+struct nic_cmd_tx_pause_notice {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 tx_pause_except; /* 1: abnormality,0: normal */
+ u32 except_level;
+ u32 rsvd;
+};
+
+#define HINIC3_CMD_OP_FREE 0
+#define HINIC3_CMD_OP_ALLOC 1
+
+struct hinic3_cmd_cfg_qps {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 1: alloc qp, 0: free qp */
+ u8 rsvd1;
+ u16 num_qps;
+ u16 rsvd2;
+};
+
+struct hinic3_cmd_led_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port;
+ u8 type;
+ u8 mode;
+ u8 rsvd1;
+};
+
+struct hinic3_cmd_port_loopback {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode;
+ u8 mode;
+ u8 en;
+ u32 rsvd1[2];
+};
+
+struct hinic3_cmd_get_light_module_abs {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 abs_status; /* 0:present, 1:absent */
+ u8 rsv[2];
+};
+
+#define STD_SFP_INFO_MAX_SIZE 640
+struct hinic3_cmd_get_std_sfp_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 wire_type;
+ u16 eeprom_len;
+ u32 rsvd;
+ u8 sfp_info[STD_SFP_INFO_MAX_SIZE];
+};
+
+struct hinic3_cable_plug_event {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 plugged; /* 0: unplugged, 1: plugged */
+ u8 port_id;
+};
+
+struct nic_cmd_mac_info {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 valid_bitmap;
+ u16 rsvd;
+
+ u8 host_id[32];
+ u8 port_id[32];
+ u8 mac_addr[192];
+};
+
+struct nic_cmd_set_tcam_enable {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 tcam_enable;
+ u8 rsvd1;
+ u32 rsvd2;
+};
+
+struct nic_cmd_set_fdir_status {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 pkt_type_en;
+ u8 pkt_type;
+ u8 qid;
+ u8 rsvd2;
+};
+
+#define HINIC3_TCAM_BLOCK_ENABLE 1
+#define HINIC3_TCAM_BLOCK_DISABLE 0
+#define HINIC3_MAX_TCAM_RULES_NUM 4096
+
+/* tcam block type, according to tcam block size */
+enum {
+ NIC_TCAM_BLOCK_TYPE_LARGE = 0, /* block_size: 16 */
+ NIC_TCAM_BLOCK_TYPE_SMALL, /* block_size: 0 */
+ NIC_TCAM_BLOCK_TYPE_MAX
+};
+
+/* alloc tcam block input struct */
+struct nic_cmd_ctrl_tcam_block_in {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
+ /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
+ u8 tcam_type;
+ u16 tcam_block_index;
+ /* Size of the block that the driver wants to allocate
+ * Interface returned by the UP to the driver,
+ * indicating the size of the allocated TCAM block supported by the UP
+ */
+ u16 alloc_block_num;
+};
+
+/* alloc tcam block output struct */
+struct nic_cmd_ctrl_tcam_block_out {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
+ /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
+ u8 tcam_type;
+ u16 tcam_block_index;
+ /* Size of the block that the driver wants to allocate
+ * Interface returned by the UP to the driver,
+ * indicating the size of the allocated TCAM block supported by the UP
+ */
+ u16 mpu_alloc_block_size;
+};
+
+struct nic_cmd_flush_tcam_rules {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u16 rsvd;
+};
+
+struct nic_cmd_dfx_fdir_tcam_block_table {
+ struct hinic3_mgmt_msg_head head;
+ u8 tcam_type;
+ u8 valid;
+ u16 tcam_block_index;
+ u16 use_function_id;
+ u16 rsvd;
+};
+
+struct tcam_result {
+ u32 qid;
+ u32 rsvd;
+};
+
+#define TCAM_FLOW_KEY_SIZE (44)
+
+struct tcam_key_x_y {
+ u8 x[TCAM_FLOW_KEY_SIZE];
+ u8 y[TCAM_FLOW_KEY_SIZE];
+};
+
+struct nic_tcam_cfg_rule {
+ u32 index;
+ struct tcam_result data;
+ struct tcam_key_x_y key;
+};
+
+#define TCAM_RULE_FDIR_TYPE 0
+#define TCAM_RULE_PPA_TYPE 1
+
+struct nic_cmd_fdir_add_rule {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 type;
+ u8 fdir_ext; /* 0x1: flow bifur en bit */
+ struct nic_tcam_cfg_rule rule;
+};
+
+struct nic_cmd_fdir_del_rules {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 type;
+ u8 rsvd;
+ u32 index_start;
+ u32 index_num;
+};
+
+struct nic_cmd_fdir_get_rule {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 index;
+ u8 valid;
+ u8 type;
+ u16 rsvd;
+ struct tcam_key_x_y key;
+ struct tcam_result data;
+ u64 packet_count;
+ u64 byte_count;
+};
+
+struct nic_cmd_fdir_get_block_rules {
+ struct hinic3_mgmt_msg_head head;
+ u8 tcam_block_type; // only NIC_TCAM_BLOCK_TYPE_LARGE
+ u8 tcam_table_type; // TCAM_RULE_PPA_TYPE or TCAM_RULE_FDIR_TYPE
+ u16 tcam_block_index;
+ u8 valid[NIC_TCAM_BLOCK_LARGE_SIZE];
+ struct tcam_key_x_y key[NIC_TCAM_BLOCK_LARGE_SIZE];
+ struct tcam_result data[NIC_TCAM_BLOCK_LARGE_SIZE];
+};
+
+struct hinic3_tcam_key_ipv4_mem {
+ u32 rsvd1 : 1;
+ u32 bifur_flag : 2;
+ u32 model : 1;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+ u32 sipv4_h : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+ u32 dipv4_h : 16;
+ u32 sipv4_l : 16;
+ u32 vlan_id : 15;
+ u32 vlan_flag : 1;
+ u32 dipv4_l : 16;
+ u32 rsvd3;
+ u32 dport : 16;
+ u32 rsvd4 : 16;
+ u32 rsvd5 : 16;
+ u32 sport : 16;
+ u32 outer_sipv4_h : 16;
+ u32 rsvd6 : 16;
+ u32 outer_dipv4_h : 16;
+ u32 outer_sipv4_l : 16;
+ u32 vni_h : 16;
+ u32 outer_dipv4_l : 16;
+ u32 rsvd7 : 16;
+ u32 vni_l : 16;
+};
+
+union hinic3_tag_tcam_ext_info {
+ struct {
+ u32 id : 16; /* id */
+ u32 type : 4; /* type: 0-func, 1-vmdq, 2-port, 3-rsvd, 4-trunk, 5-dp, 6-mc */
+ u32 host_id : 3;
+ u32 rss_q_num : 8; /* rss queue num */
+ u32 ext : 1;
+ } bs;
+ u32 value;
+};
+
+struct hinic3_tcam_key_ipv6_mem {
+ u32 bifur_flag : 2;
+ u32 vlan_flag : 1;
+ u32 outer_ip_type : 1;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+ u32 sipv6_key0 : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+ u32 sipv6_key2 : 16;
+ u32 sipv6_key1 : 16;
+ u32 sipv6_key4 : 16;
+ u32 sipv6_key3 : 16;
+ u32 sipv6_key6 : 16;
+ u32 sipv6_key5 : 16;
+ u32 dport : 16;
+ u32 sipv6_key7 : 16;
+ u32 dipv6_key0 : 16;
+ u32 sport : 16;
+ u32 dipv6_key2 : 16;
+ u32 dipv6_key1 : 16;
+ u32 dipv6_key4 : 16;
+ u32 dipv6_key3 : 16;
+ u32 dipv6_key6 : 16;
+ u32 dipv6_key5 : 16;
+ u32 rsvd2 : 16;
+ u32 dipv6_key7 : 16;
+};
+
+struct hinic3_tcam_key_vxlan_ipv6_mem {
+ u32 rsvd1 : 4;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+
+ u32 dipv6_key0 : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+
+ u32 dipv6_key2 : 16;
+ u32 dipv6_key1 : 16;
+
+ u32 dipv6_key4 : 16;
+ u32 dipv6_key3 : 16;
+
+ u32 dipv6_key6 : 16;
+ u32 dipv6_key5 : 16;
+
+ u32 dport : 16;
+ u32 dipv6_key7 : 16;
+
+ u32 rsvd2 : 16;
+ u32 sport : 16;
+
+ u32 outer_sipv4_h : 16;
+ u32 rsvd3 : 16;
+
+ u32 outer_dipv4_h : 16;
+ u32 outer_sipv4_l : 16;
+
+ u32 vni_h : 16;
+ u32 outer_dipv4_l : 16;
+
+ u32 rsvd4 : 16;
+ u32 vni_l : 16;
+};
+
+struct tag_tcam_key {
+ union {
+ struct hinic3_tcam_key_ipv4_mem key_info;
+ struct hinic3_tcam_key_ipv6_mem key_info_ipv6;
+ struct hinic3_tcam_key_vxlan_ipv6_mem key_info_vxlan_ipv6;
+ };
+
+ union {
+ struct hinic3_tcam_key_ipv4_mem key_mask;
+ struct hinic3_tcam_key_ipv6_mem key_mask_ipv6;
+ struct hinic3_tcam_key_vxlan_ipv6_mem key_mask_vxlan_ipv6;
+ };
+};
+
+enum {
+ PPA_TABLE_ID_CLEAN_CMD = 0,
+ PPA_TABLE_ID_ADD_CMD,
+ PPA_TABLE_ID_DEL_CMD,
+ FDIR_TABLE_ID_ADD_CMD,
+ FDIR_TABLE_ID_DEL_CMD,
+ PPA_TABEL_ID_MAX
+};
+
+struct hinic3_ppa_cfg_table_id_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u16 cmd;
+ u16 table_id;
+ u16 rsvd1;
+};
+
+struct hinic3_ppa_cfg_ppa_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 ppa_en;
+ u8 ppa_miss_drop_en;
+};
+
+struct hinic3_func_flow_bifur_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 func_id;
+ u8 flow_bifur_en;
+ u8 rsvd[5];
+};
+
+struct hinic3_port_flow_bifur_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 port_id;
+ u8 flow_bifur_en;
+ u8 flow_bifur_type; /* 0->vf bifur, 2->traffic bifur */
+ u8 rsvd[4];
+};
+
+struct hinic3_bond_mask_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 func_id;
+ u8 bond_mask;
+ u8 bond_en;
+ u8 func_valid;
+ u8 rsvd[3];
+};
+
+struct hinic3_func_er_value_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 vf_id;
+ u16 er_fwd_id;
+};
+
+#define HINIC3_TX_SET_PROMISC_SKIP 0
+#define HINIC3_TX_GET_PROMISC_SKIP 1
+
+#define HINIC3_GET_TRAFFIC_BIFUR_STATE 0
+#define HINIC3_SET_TRAFFIC_BIFUR_STATE 1
+
+struct hinic3_tx_promisc_cfg {
+ struct hinic3_mgmt_msg_head msg_head;
+ u8 port_id;
+ u8 promisc_skip_en; /* 0: disable tx promisc replication, 1: enable */
+ u8 opcode; /* 0: set, 1: get */
+ u8 rsvd1;
+};
+
+struct hinic3_ppa_cfg_mode_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u8 ppa_mode;
+ u8 qpc_func_nums;
+ u16 base_qpc_func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_ppa_flush_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u8 flush_en; /* 0 flush done, 1 in flush operation */
+ u8 rsvd1;
+};
+
+struct hinic3_ppa_fdir_query_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u32 index;
+ u32 rsvd;
+ u64 pkt_nums;
+ u64 pkt_bytes;
+};
+
+/* BIOS CONF */
+enum {
+ NIC_NVM_DATA_SET = BIT(0), /* 1-save, 0-read */
+ NIC_NVM_DATA_PXE = BIT(1),
+ NIC_NVM_DATA_VLAN = BIT(2),
+ NIC_NVM_DATA_VLAN_PRI = BIT(3),
+ NIC_NVM_DATA_VLAN_ID = BIT(4),
+ NIC_NVM_DATA_WORK_MODE = BIT(5),
+ NIC_NVM_DATA_PF_TX_SPEED_LIMIT = BIT(6),
+ NIC_NVM_DATA_GE_MODE = BIT(7),
+ NIC_NVM_DATA_AUTO_NEG = BIT(8),
+ NIC_NVM_DATA_LINK_FEC = BIT(9),
+ NIC_NVM_DATA_PF_ADAPTIVE_LINK = BIT(10),
+ NIC_NVM_DATA_SRIOV_CONTROL = BIT(11),
+ NIC_NVM_DATA_EXTEND_MODE = BIT(12),
+ NIC_NVM_DATA_LEGACY_VLAN = BIT(13),
+ NIC_NVM_DATA_LEGACY_VLAN_PRI = BIT(14),
+ NIC_NVM_DATA_LEGACY_VLAN_ID = BIT(15),
+ NIC_NVM_DATA_RESET = BIT(31),
+};
+
+#define BIOS_CFG_SIGNATURE 0x1923E518
+#define BIOS_OP_CFG_ALL(op_code_val) \
+ ((((op_code_val) >> 1) & (0xFFFFFFFF)) != 0)
+#define BIOS_OP_CFG_WRITE(op_code_val) \
+ ((((op_code_val) & NIC_NVM_DATA_SET)) != 0)
+#define BIOS_OP_CFG_PXE_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PXE) != 0)
+#define BIOS_OP_CFG_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN) != 0)
+#define BIOS_OP_CFG_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_ID) != 0)
+#define BIOS_OP_CFG_WORK_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_WORK_MODE) != 0)
+#define BIOS_OP_CFG_PF_BW(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_TX_SPEED_LIMIT) != 0)
+#define BIOS_OP_CFG_GE_SPEED(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_GE_MODE) != 0)
+#define BIOS_OP_CFG_AUTO_NEG(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_AUTO_NEG) != 0)
+#define BIOS_OP_CFG_LINK_FEC(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LINK_FEC) != 0)
+#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_ADAPTIVE_LINK) != 0)
+#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_SRIOV_CONTROL) != 0)
+#define BIOS_OP_CFG_EXTEND_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_EXTEND_MODE) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_ID) != 0)
+#define BIOS_OP_CFG_RST_DEF_SET(op_code_val) \
+ (((op_code_val) & (u32)NIC_NVM_DATA_RESET) != 0)
+
+
+#define NIC_BIOS_CFG_MAX_PF_BW 100
+
+struct nic_legacy_vlan_cfg {
+ /* Legacy mode PXE VLAN enable: 0 - disable 1 - enable */
+ u8 pxe_vlan_en : 1;
+ /* Legacy mode PXE VLAN priority: 0-7 */
+ u8 pxe_vlan_pri : 3;
+ /* Legacy mode PXE VLAN ID 1-4094 */
+ u16 pxe_vlan_id : 12;
+};
+
+/* Note: This structure must be 4-byte aligned. */
+struct nic_bios_cfg {
+ u32 signature;
+ u8 pxe_en;
+ u8 extend_mode;
+ struct nic_legacy_vlan_cfg nlvc;
+ u8 pxe_vlan_en;
+ u8 pxe_vlan_pri;
+ u16 pxe_vlan_id;
+ u32 service_mode;
+ u32 pf_tx_bw;
+ u8 speed;
+ u8 auto_neg;
+ u8 lanes;
+ u8 fec;
+ u8 auto_adapt;
+ u8 func_valid;
+ u8 func_id;
+ u8 sriov_en;
+};
+
+struct nic_cmd_bios_cfg {
+ struct hinic3_mgmt_msg_head head;
+ u32 op_code; /* Operation Code: Bit0[0: read 1:write, BIT1-6: cfg_mask */
+ struct nic_bios_cfg bios_cfg;
+};
+
+struct nic_rx_rate_bios_cfg {
+ struct mgmt_msg_head msg_head;
+
+ u32 op_code; /* Operation Code:[0:read 1:write] */
+ u8 rx_rate_limit;
+ u8 func_id;
+};
+
+struct nic_cmd_vhd_config {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 vhd_type;
+ u8 virtio_small_enable; /* 0: mergeable mode, 1: small mode */
+};
+
+/* BOND */
+struct hinic3_create_bond_info {
+ u32 bond_id;
+ u32 master_slave_port_id;
+ u32 slave_bitmap; /* bond port id bitmap */
+ u32 poll_timeout; /* Bond device link check time */
+ u32 up_delay; /* Temporarily reserved */
+ u32 down_delay; /* Temporarily reserved */
+ u32 bond_mode; /* Temporarily reserved */
+ u32 active_pf; /* bond use active pf id */
+ u32 active_port_max_num; /* Maximum number of active bond member interfaces */
+ u32 active_port_min_num; /* Minimum number of active bond member interfaces */
+ u32 xmit_hash_policy;
+ u32 default_param_flag;
+ u32 rsvd;
+};
+
+struct hinic3_cmd_create_bond {
+ struct hinic3_mgmt_msg_head head;
+ struct hinic3_create_bond_info create_bond_info;
+};
+
+struct hinic3_cmd_delete_bond {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 rsvd[2];
+};
+
+struct hinic3_open_close_bond_info {
+ u32 bond_id;
+ u32 open_close_flag; /* Bond flag. 1: open; 0: close. */
+ u32 rsvd[2];
+};
+
+struct hinic3_cmd_open_close_bond {
+ struct hinic3_mgmt_msg_head head;
+ struct hinic3_open_close_bond_info open_close_bond_info;
+};
+
+struct lacp_port_params {
+ u16 port_number;
+ u16 port_priority;
+ u16 key;
+ u16 system_priority;
+ u8 system[ETH_ALEN];
+ u8 port_state;
+ u8 rsvd;
+};
+
+struct lacp_port_info {
+ u32 selected;
+ u32 aggregator_port_id;
+
+ struct lacp_port_params actor;
+ struct lacp_port_params partner;
+
+ u64 tx_lacp_pkts;
+ u64 rx_lacp_pkts;
+ u64 rx_8023ad_drop;
+ u64 tx_8023ad_drop;
+ u64 unknown_pkt_drop;
+ u64 rx_marker_pkts;
+ u64 tx_marker_pkts;
+};
+
+struct hinic3_bond_status_info {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 bon_mmi_status;
+ u32 active_bitmap;
+ u32 port_count;
+
+ struct lacp_port_info port_info[4];
+
+ u64 success_report_cnt[4];
+ u64 fail_report_cnt[4];
+
+ u64 poll_timeout;
+ u64 fast_periodic_timeout;
+ u64 slow_periodic_timeout;
+ u64 short_timeout;
+ u64 long_timeout;
+ u64 aggregate_wait_timeout;
+ u64 tx_period_timeout;
+ u64 rx_marker_timer;
+};
+
+struct hinic3_bond_active_report_info {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 bon_mmi_status;
+ u32 active_bitmap;
+
+ u8 rsvd[16];
+};
+
+/* IP checksum error packets, enable rss quadruple hash. */
+struct hinic3_ipcs_err_rss_enable_operation_s {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 en_tag;
+ u8 type; /* 1: set 0: get */
+ u8 rsvd[2];
+};
+
+struct hinic3_smac_check_state {
+ struct hinic3_mgmt_msg_head head;
+ u8 smac_check_en; /* 1: enable 0: disable */
+ u8 op_code; /* 1: set 0: get */
+ u8 flash_en; /* 1: enable 0: disable */
+ u8 rsvd;
+};
+
+struct hinic3_clear_log_state {
+ struct hinic3_mgmt_msg_head head;
+ u32 type;
+};
+
+struct hinic3_outband_cfg_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 outband_default_vid;
+ u16 func_id;
+};
+
+struct hinic3_wr_ordering {
+ struct hinic3_mgmt_msg_head head;
+ u8 op_code; /* 1: set 0: get */
+ u8 wr_pkt_so_ro;
+ u8 rd_pkt_so_ro;
+ u8 rsvd;
+};
+
+struct hinic3_function_active_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_rq_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rq_depth;
+ u16 rq_num;
+ u16 pf_num;
+ u16 port_num;
+};
+
+#endif /* HINIC_MGMT_INTERFACE_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
new file mode 100644
index 0000000..3e625fc
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
+ * File Name : nic_npu_cmd.h
+ * Version : Initial Draft
+ * Created : 2019/4/25
+ * Last Modified :
+ * Description : NIC Commands between Driver and NPU
+ * Function List :
+ */
+
+#ifndef NIC_NPU_CMD_H
+#define NIC_NPU_CMD_H
+
+/* NIC CMDQ MODE */
+enum hinic3_ucode_cmd {
+ HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
+ HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
+ HINIC3_UCODE_CMD_ARM_SQ, /**< Unused */
+ HINIC3_UCODE_CMD_ARM_RQ, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_IQ_ENABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
+ HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
+ HINIC3_UCODE_CMD_PPA_HASH_TABLE,
+ HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_UCODE_MIG_CFG_Q_CTX = 14,
+ HINIC3_UCODE_MIG_CHK_SQ_STOP,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ HINIC3_UCODE_MIG_CFG_BAT_INFO,
+};
+
+#endif /* NIC_NPU_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
index 78a8d7f..00f4a24 100644
--- a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
+++ b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
@@ -4,7 +4,9 @@
#ifndef OSSL_KNL_LINUX_H_
#define OSSL_KNL_LINUX_H_
+#include <net/checksum.h>
#include <net/ipv6.h>
+#include <net/devlink.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/device.h>
@@ -18,6 +20,12 @@
#include <linux/list.h>
#include <linux/bitmap.h>
#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/filter.h>
+#include <linux/aer.h>
+#include <linux/socket.h>
#ifndef NETIF_F_SCTP_CSUM
#define NETIF_F_SCTP_CSUM 0
@@ -173,12 +181,10 @@ static inline void *_hinic3_dma_zalloc_coherent(struct device *dev,
}
#endif
-#ifndef DT_KNL_EMU
struct timeval {
__kernel_old_time_t tv_sec; /* seconds */
__kernel_suseconds_t tv_usec; /* microseconds */
};
-#endif
#ifndef do_gettimeofday
#define do_gettimeofday(time) _kc_do_gettimeofday(time)
@@ -196,6 +202,10 @@ static inline void _kc_do_gettimeofday(struct timeval *tv)
#define ETH_GET_HEADLEN_NEED_DEV
#define HAVE_GENL_OPS_FIELD_VALIDATE
+#ifndef FIELD_SIZEOF
+#define FIELD_SIZEOF(t, f) (sizeof(((t *)0)->f))
+#endif
+
#define HAVE_DEVLINK_FLASH_UPDATE_PARAMS
#ifndef rtc_time_to_tm
@@ -253,12 +263,12 @@ static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size,
size, vaddr, dma_handle);
}
-#define HAVE_DEVLINK_FW_FILE_NAME_MEMBER
-
#define HAVE_ENCAPSULATION_TSO
#define HAVE_ENCAPSULATION_CSUM
+#define HAVE_UDP_TUNNEL_NIC_INFO
+
#ifndef eth_zero_addr
static inline void hinic3_eth_zero_addr(u8 *addr)
{
@@ -333,4 +343,15 @@ u64 ossl_get_real_time(void);
#define tasklet_state(tasklet) ((tasklet)->state)
+dma_addr_t pci_map_single(struct pci_dev *pdev,
+ void *ptr, size_t size, int direction);
+int pci_dma_mapping_error(struct pci_dev *pdev,
+ dma_addr_t dma_addr);
+void pci_unmap_single(struct pci_dev *pdev,
+ dma_addr_t dma_addr, size_t size, int direction);
+void *pci_alloc_consistent(struct pci_dev *pdev,
+ size_t size, dma_addr_t *dma_handle);
+void pci_free_consistent(struct pci_dev *pdev,
+ size_t size, void *vaddr, dma_addr_t dma_handle);
+
#endif
--
2.45.1.windows.1
2
1
Changes since v2:
- Add CONFIG_FUSE_PASSTHROUGH=y to openeuler_defconfig for x86_64
Changes since v1:
- Add CONFIG_FUSE_PASSTHROUGH=y to openeuler_defconfig for arm64
Amir Goldstein (57):
fs: rename __mnt_{want,drop}_write*() helpers
fs: export mnt_{get,put}_write_access() to modules
fuse: factor out helper fuse_truncate_update_attr()
fuse: allocate ff->release_args only if release is needed
fuse: break up fuse_open_common()
fuse: prepare for failing open response
fuse: introduce inode io modes
fuse: allow parallel dio writes with FUSE_DIRECT_IO_ALLOW_MMAP
ovl: use simpler function to convert iocb to rw flags
ovl: propagate IOCB_APPEND flag on writes to realfile
ovl: punt write aio completion to workqueue
ovl: protect copying of realinode attributes to ovl inode
fs: get mnt_writers count for an open backing file's real path
fs: create helper file_user_path() for user displayed mapped file path
fs: store real path instead of fake path in backing file f_path
ovl: add helper ovl_file_modified()
ovl: split ovl_want_write() into two helpers
ovl: reorder ovl_want_write() after ovl_inode_lock()
ovl: do not open/llseek lower file with upper sb_writers held
ovl: do not encode lower fh with upper sb_writers held
ovl: add permission hooks outside of do_splice_direct()
splice: remove permission hook from do_splice_direct()
splice: move permission hook out of splice_direct_to_actor()
splice: move permission hook out of splice_file_to_pipe()
splice: remove permission hook from iter_file_splice_write()
remap_range: move permission hooks out of do_clone_file_range()
remap_range: move file_start_write() to after permission hook
btrfs: move file_start_write() to after permission hook
coda: change locking order in coda_file_write_iter()
fs: move file_start_write() into vfs_iter_write()
fs: move permission hook out of do_iter_write()
fs: move permission hook out of do_iter_read()
fs: move kiocb_start_write() into vfs_iocb_iter_write()
fs: create __sb_write_started() helper
fs: create file_write_started() helper
fs: create {sb,file}_write_not_started() helpers
fs: prepare for stackable filesystems backing file helpers
fs: factor out backing_file_{read,write}_iter() helpers
fs: factor out backing_file_splice_{read,write}() helpers
fs: factor out backing_file_mmap() helper
fuse: factor out helper for FUSE_DEV_IOC_CLONE
fuse: introduce FUSE_PASSTHROUGH capability
fuse: implement ioctls to manage backing files
fuse: prepare for opening file in passthrough mode
fuse: implement open in passthrough mode
fuse: implement read/write passthrough
fuse: implement splice read/write passthrough
fuse: implement passthrough for mmap
fuse: fix wrong ff->iomode state changes from parallel dio write
fuse: fix parallel dio write on file open in passthrough mode
fuse: verify zero padding in fuse_backing_map
fuse: respect FOPEN_KEEP_CACHE on opendir
ovl: fix dentry reference leak after changes to underlying layers
ovl: relax WARN_ON in ovl_verify_area()
remap_range: merge do_clone_file_range() into vfs_clone_file_range()
fs: pass offset and result to backing_file end_write() callback
fuse: update inode size after extending passthrough write
Bernd Schubert (3):
fuse: create helper function if DIO write needs exclusive lock
fuse: add fuse_dio_lock/unlock helper functions
fuse: disable the combination of passthrough and writeback cache
Ed Tsai (1):
backing-file: convert to using fops->splice_write
Vegard Nossum (1):
fs: fix __sb_write_started() kerneldoc formatting
yangyun (1):
fuse: use exclusive lock when FUSE_I_CACHE_IO_MODE is set
fs/fuse/fuse_i.h | 151 +++++++++--
fs/internal.h | 21 +-
fs/overlayfs/overlayfs.h | 38 ++-
include/linux/backing-file.h | 42 +++
include/linux/fs.h | 89 ++++--
include/linux/fsnotify.h | 3 +-
include/linux/mount.h | 4 +-
include/uapi/linux/fuse.h | 23 +-
arch/arc/kernel/troubleshoot.c | 6 +-
drivers/block/loop.c | 2 -
drivers/target/target_core_file.c | 10 +-
fs/backing-file.c | 339 +++++++++++++++++++++++
fs/btrfs/ioctl.c | 12 +-
fs/cachefiles/io.c | 5 +-
fs/coda/file.c | 2 -
fs/file_table.c | 12 +-
fs/fuse/dev.c | 98 +++++--
fs/fuse/dir.c | 49 +++-
fs/fuse/file.c | 362 +++++++++++++++++--------
fs/fuse/inode.c | 37 +++
fs/fuse/iomode.c | 276 +++++++++++++++++++
fs/fuse/passthrough.c | 355 ++++++++++++++++++++++++
fs/inode.c | 8 +-
fs/namespace.c | 36 +--
fs/nfsd/vfs.c | 7 +-
fs/open.c | 70 ++---
fs/overlayfs/copy_up.c | 168 ++++++++----
fs/overlayfs/dir.c | 60 ++--
fs/overlayfs/export.c | 7 +-
fs/overlayfs/file.c | 230 ++++------------
fs/overlayfs/inode.c | 57 ++--
fs/overlayfs/namei.c | 37 ++-
fs/overlayfs/super.c | 47 ++--
fs/overlayfs/util.c | 75 ++++-
fs/proc/base.c | 2 +-
fs/proc/nommu.c | 2 +-
fs/proc/task_mmu.c | 4 +-
fs/proc/task_nommu.c | 2 +-
fs/read_write.c | 156 +++++++----
fs/remap_range.c | 44 ++-
fs/splice.c | 82 +++---
fs/super.c | 1 +
kernel/acct.c | 4 +-
kernel/trace/trace_output.c | 2 +-
MAINTAINERS | 9 +
arch/arm64/configs/openeuler_defconfig | 1 +
arch/x86/configs/openeuler_defconfig | 1 +
fs/Kconfig | 4 +
fs/Makefile | 1 +
fs/fuse/Kconfig | 11 +
fs/fuse/Makefile | 2 +
fs/overlayfs/Kconfig | 1 +
52 files changed, 2292 insertions(+), 775 deletions(-)
create mode 100644 include/linux/backing-file.h
create mode 100644 fs/backing-file.c
create mode 100644 fs/fuse/iomode.c
create mode 100644 fs/fuse/passthrough.c
--
2.39.2
3
65

08 May '25
From: zhuyikai <zhuyikai1(a)h-partners.com>
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IC5K44?from=project-issue
CVE: NA
--------------------------------
Add optical module type adaptation.
Add ethtool fec function.
Add NIC XDP PASS function.
Add QoS persistence.
Add NIC out-of-band VLAN configuration function.
Fix NIC bifur bugs.
Fix performance test bugs.
Fix NIC RX bugs.
Fix NIC VF bugs.
Fix the bug of exiting when probing NIC.
Fix bond bugs.
Fix the bug of reading NIC status incorrectly.
Fix and add some statistics.
Signed-off-by: zhuyikai <zhuyikai1(a)h-partners.com>
---
drivers/net/ethernet/huawei/hinic3/Makefile | 1 +
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c | 136 +-
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h | 1 +
drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h | 212 ---
drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h | 239 ---
drivers/net/ethernet/huawei/hinic3/comm_defs.h | 105 --
drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h | 103 --
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c | 51 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h | 2 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c | 86 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c | 1 -
drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c | 28 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c | 27 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c | 35 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c | 9 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c | 12 +-
drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h | 185 ---
drivers/net/ethernet/huawei/hinic3/hinic3_common.h | 118 --
drivers/net/ethernet/huawei/hinic3/hinic3_crm.h | 30 +-
drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c | 305 ++--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c | 267 ++--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h | 7 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c | 227 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c | 387 +++--
drivers/net/ethernet/huawei/hinic3/hinic3_filter.c | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_hw.h | 18 +
drivers/net/ethernet/huawei/hinic3/hinic3_irq.c | 11 +-
drivers/net/ethernet/huawei/hinic3/hinic3_lld.h | 205 ---
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c | 836 +++++++++-
drivers/net/ethernet/huawei/hinic3/hinic3_main.c | 476 +++++-
drivers/net/ethernet/huawei/hinic3/hinic3_mt.h | 225 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c | 372 +++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic.h | 61 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c | 450 +++++-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h | 55 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c | 167 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c | 13 +
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h | 221 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c | 119 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c | 18 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c | 18 +-
drivers/net/ethernet/huawei/hinic3/hinic3_profile.h | 146 --
drivers/net/ethernet/huawei/hinic3/hinic3_rss.c | 140 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c | 41 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rx.c | 357 +++--
drivers/net/ethernet/huawei/hinic3/hinic3_rx.h | 39 +-
drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h | 6 +-
drivers/net/ethernet/huawei/hinic3/hinic3_tx.c | 141 +-
drivers/net/ethernet/huawei/hinic3/hinic3_wq.h | 4 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c | 15 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c | 13 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h | 5 -
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c | 206 ++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h | 13 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c | 5 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c | 14 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c | 42 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c | 91 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h | 13 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c | 163 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c | 116 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c | 87 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h | 34 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c | 40 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c | 1221 +++++++++++++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c | 3 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c | 6 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c | 44 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c | 182 ++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h | 4 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h | 31 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c | 52 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c | 2 +-
drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h | 4 +
.../include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h | 13 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h | 42 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h | 2 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h | 130 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h | 109 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h | 5 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h | 30 +-
.../include/mpu/mpu_outband_ncsi_cmd_defs.h | 8 +
drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h | 16 +-
drivers/net/ethernet/huawei/hinic3/include/vram_common.h | 11 +-
drivers/net/ethernet/huawei/hinic3/{mag_cmd.h => mag_mpu_cmd_defs.h} | 237 ++-
drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h | 27 -
drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h | 63 -
drivers/net/ethernet/huawei/hinic3/{hinic3_nic_cmd.h => nic_mpu_cmd.h} | 59 +-
drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h | 1420 +++++++++++++++++
drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h | 36 +
drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h | 94 +-
96 files changed, 8394 insertions(+), 3041 deletions(-)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_defs.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_common.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
rename drivers/net/ethernet/huawei/hinic3/{mag_cmd.h => mag_mpu_cmd_defs.h} (79%)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
rename drivers/net/ethernet/huawei/hinic3/{hinic3_nic_cmd.h => nic_mpu_cmd.h} (77%)
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
diff --git a/drivers/net/ethernet/huawei/hinic3/Makefile b/drivers/net/ethernet/huawei/hinic3/Makefile
index 11fe010..21d8093 100644
--- a/drivers/net/ethernet/huawei/hinic3/Makefile
+++ b/drivers/net/ethernet/huawei/hinic3/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/hw/
+ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/bond/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/cqm/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/cqm/
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
index ba3076c..a252e09 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
@@ -9,14 +9,18 @@
#include <linux/net.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
+#include <linux/version.h>
+#include "ossl_knl.h"
#include "hinic3_lld.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic_dev.h"
#include "hinic3_hw.h"
-#include "mpu_inband_cmd.h"
-#include "hinic3_hwdev.h"
#include "hinic3_bond.h"
+#include "hinic3_hwdev.h"
+
+#include "bond_common_defs.h"
+#include "vram_common.h"
#define PORT_INVALID_ID 0xFF
@@ -214,10 +218,10 @@ static void bond_dev_untrack_port(struct hinic3_bond_dev *bdev, u8 idx)
spin_lock(&bdev->lock);
if (bdev->tracker.ndev[idx]) {
- pr_info("hinic3_bond: untrack port:%u ndev:%s cnt:%d\n", idx,
- bdev->tracker.ndev[idx]->name, bdev->tracker.cnt);
bdev->tracker.ndev[idx] = NULL;
bdev->tracker.cnt--;
+ pr_info("hinic3_bond: untrack port:%u ndev:%s cnt:%d\n", idx,
+ bdev->tracker.ndev[idx]->name, bdev->tracker.cnt);
}
spin_unlock(&bdev->lock);
@@ -268,11 +272,16 @@ static void bond_master_event(struct hinic3_bond_dev *bdev,
queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
}
-static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
+static struct hinic3_bond_dev *bond_get_bdev(struct bonding *bond)
{
struct hinic3_bond_dev *bdev = NULL;
int bid;
+ if (bond == NULL) {
+ pr_err("hinic3_bond: bond is NULL\n");
+ return NULL;
+ }
+
mutex_lock(&g_bond_mutex);
for (bid = BOND_FIRST_ID; bid <= BOND_MAX_ID; bid++) {
bdev = bond_mngr.bond_dev[bid];
@@ -283,38 +292,72 @@ static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
mutex_unlock(&g_bond_mutex);
return bdev;
}
+
+ if (strncmp(bond->dev->name, bdev->name, BOND_NAME_MAX_LEN) == 0) {
+ bdev->bond = bond;
+ return bdev;
+ }
}
mutex_unlock(&g_bond_mutex);
return NULL;
}
-static void bond_handle_rtnl_event(struct net_device *ndev)
+static struct bonding *get_bonding_by_netdev(struct net_device *ndev)
{
- struct hinic3_bond_dev *bdev = NULL;
struct bonding *bond = NULL;
struct slave *slave = NULL;
if (netif_is_bond_master(ndev)) {
bond = netdev_priv(ndev);
- bdev = bond_get_bdev(bond);
} else if (netif_is_bond_slave(ndev)) {
- /*lint -e(160) */
slave = bond_slave_get_rtnl(ndev);
if (slave) {
bond = bond_get_bond_by_slave(slave);
- bdev = bond_get_bdev(bond);
}
}
- if (!bond || !bdev)
+ return bond;
+}
+/*lint -e580 -e546*/
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+
+ if (!ndev) {
+ pr_err("hinic3_bond: netdev is NULL\n");
+ return false;
+ }
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
+ return false;
+
+ return bdev->status == BOND_DEV_STATUS_ACTIVATED;
+}
+EXPORT_SYMBOL(hinic3_is_bond_dev_status_actived);
+/*lint +e580 +e546*/
+
+static void bond_handle_rtnl_event(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+ struct slave *slave = NULL;
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
return;
bond_update_attr(bdev, bond);
- if (slave)
+ if (netif_is_bond_slave(ndev)) {
+ slave = bond_slave_get_rtnl(ndev);
bond_slave_event(bdev, slave);
- else
+ } else {
bond_master_event(bdev, bond);
+ }
}
static void bond_rtnl_data_ready(struct sock *sk)
@@ -478,7 +521,11 @@ static void bond_update_slave_info(struct hinic3_bond_dev *bdev,
continue;
}
+ if (!bdev->tracker.ndev[i])
+ continue;
+
bond_pf_bitmap_set(bdev, i);
+
if (!bdev->tracker.netdev_state[i].tx_enabled)
continue;
@@ -516,6 +563,7 @@ static int bond_upcmd_config(struct hinic3_bond_dev *bdev,
attr->active_slaves,
attr->lacp_collect_slaves);
pr_info("bond_pf_bitmap: 0x%x\n", attr->bond_pf_bitmap);
+ pr_info("bond user_bitmap 0x%x\n", attr->user_bitmap);
err = bond_send_upcmd(bdev, attr, MPU_CMD_BOND_SET_ATTR);
if (!err)
@@ -560,17 +608,36 @@ static void bond_call_service_func(struct hinic3_bond_dev *bdev, struct bond_att
mutex_unlock(&g_bond_service_func_mutex);
}
+static u32 bond_get_user_bitmap(struct hinic3_bond_dev *bdev)
+{
+ u32 user_bitmap = 0;
+ u8 user;
+
+ for (user = HINIC3_BOND_USER_OVS; user < HINIC3_BOND_USER_NUM; user++) {
+ if (bdev->slot_used[user] == 1)
+ BITMAP_SET(user_bitmap, user);
+ }
+ return user_bitmap;
+}
+
static void bond_do_work(struct hinic3_bond_dev *bdev)
{
bool is_bonded = 0;
struct bond_attr attr;
+ int is_in_kexec;
int err = 0;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ pr_info("Skip changing bond status during os replace\n");
+ return;
+ }
+
spin_lock(&bdev->lock);
is_bonded = bdev->tracker.is_bonded;
attr = bdev->new_attr;
spin_unlock(&bdev->lock);
- attr.user_bitmap = 0;
+ attr.user_bitmap = bond_get_user_bitmap(bdev);
/* is_bonded indicates whether bond should be activated. */
if (is_bonded && !bond_dev_is_activated(bdev)) {
@@ -591,17 +658,21 @@ static void bond_do_work(struct hinic3_bond_dev *bdev)
pr_err("hinic3_bond: Do bond failed\n");
}
-#define MIN_BOND_SLAVE_CNT 2
static void bond_try_do_work(struct work_struct *work)
{
struct delayed_work *delayed_work = to_delayed_work(work);
struct hinic3_bond_dev *bdev =
container_of(delayed_work, struct hinic3_bond_dev, bond_work);
+ int status;
- if (g_bond_service_func[HINIC3_BOND_USER_ROCE] && bdev->tracker.cnt < MIN_BOND_SLAVE_CNT)
+ status = mutex_trylock(&g_bond_mutex);
+ if (status == 0) {
+ /* Delay 1 sec and retry */
queue_delayed_work(bdev->wq, &bdev->bond_work, HZ);
- else
+ } else {
bond_do_work(bdev);
+ mutex_unlock(&g_bond_mutex);
+ }
}
static int bond_dev_init(struct hinic3_bond_dev *bdev, const char *name)
@@ -630,6 +701,7 @@ static int bond_dev_release(struct hinic3_bond_dev *bdev)
err = bond_upcmd_deactivate(bdev);
if (err) {
pr_err("hinic3_bond: Failed to deactivate dev\n");
+ mutex_unlock(&g_bond_mutex);
return err;
}
@@ -764,20 +836,28 @@ static struct hinic3_bond_dev *bond_dev_by_name(const char *name)
static void bond_dev_user_attach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user)
{
+ u32 user_bitmap;
+
+ if (user < 0 || user >= HINIC3_BOND_USER_NUM)
+ return;
+
if (bdev->slot_used[user])
return;
bdev->slot_used[user] = 1;
if (!kref_get_unless_zero(&bdev->ref))
kref_init(&bdev->ref);
+ else {
+ user_bitmap = bond_get_user_bitmap(bdev);
+ pr_info("hinic3_bond: user %u attach bond %s, user_bitmap %#x\n",
+ user, bdev->name, user_bitmap);
+ queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
+ }
}
static void bond_dev_user_detach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user, bool *freed)
{
- if (user < 0 || user >= HINIC3_BOND_USER_NUM)
- return;
-
if (bdev->slot_used[user]) {
bdev->slot_used[user] = 0;
if (kref_read(&bdev->ref) == 1)
@@ -790,12 +870,15 @@ static struct bonding *bond_get_knl_bonding(const char *name)
{
struct net_device *ndev_tmp = NULL;
+ rcu_read_lock();
for_each_netdev(&init_net, ndev_tmp) {
if (netif_is_bond_master(ndev_tmp) &&
- !strcmp(ndev_tmp->name, name))
+ !strcmp(ndev_tmp->name, name)) {
+ rcu_read_unlock();
return netdev_priv(ndev_tmp);
+ }
}
-
+ rcu_read_unlock();
return NULL;
}
@@ -852,8 +935,9 @@ int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user)
int err = 0;
bool lock_freed = false;
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
- pr_warn("hinic3_bond: Invalid bond id:%u to delete\n", bond_id);
+ if (!BOND_ID_IS_VALID(bond_id) || user >= HINIC3_BOND_USER_NUM) {
+ pr_warn("hinic3_bond: Invalid bond id or user, bond_id: %u, user: %d\n",
+ bond_id, user);
return -EINVAL;
}
@@ -891,7 +975,7 @@ EXPORT_SYMBOL(hinic3_bond_clean_user);
int hinic3_bond_get_uplink_id(u16 bond_id, u32 *uplink_id)
{
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID || !uplink_id) {
+ if (!BOND_ID_IS_VALID(bond_id) || !uplink_id) {
pr_warn("hinic3_bond: Invalid args, id: %u, uplink: %d\n",
bond_id, !!uplink_id);
return -EINVAL;
@@ -941,7 +1025,7 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
int i;
int len;
- if (!info || bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
+ if (!info || !BOND_ID_IS_VALID(bond_id)) {
pr_warn("hinic3_bond: Invalid args, info: %d,id: %u\n",
!!info, bond_id);
return -EINVAL;
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
index 024de95..5ab36f7 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
@@ -82,6 +82,7 @@ struct hinic3_bond_cmd {
char bond_name[16];
};
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev);
void hinic3_bond_set_user_bitmap(struct bond_attr *attr, enum hinic3_bond_user user);
int hinic3_bond_attach(const char *name, enum hinic3_bond_user user, u16 *bond_id);
int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user);
diff --git a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h b/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
deleted file mode 100644
index 557f326..0000000
--- a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2016-2022. All rights reserved.
- * File name: Cfg_mgt_comm_pub.h
- * Version No.: Draft
- * Generation date: 2016 year 05 month 07 day
- * Latest modification:
- * Function description: Header file for communication between the: Host and FW
- * Function list:
- * Modification history:
- * 1. Date: 2016 May 07
- * Modify content: Create a file.
- */
-#ifndef CFG_MGT_COMM_PUB_H
-#define CFG_MGT_COMM_PUB_H
-
-#include "mgmt_msg_base.h"
-
-enum servic_bit_define {
- SERVICE_BIT_NIC = 0,
- SERVICE_BIT_ROCE = 1,
- SERVICE_BIT_VBS = 2,
- SERVICE_BIT_TOE = 3,
- SERVICE_BIT_IPSEC = 4,
- SERVICE_BIT_FC = 5,
- SERVICE_BIT_VIRTIO = 6,
- SERVICE_BIT_OVS = 7,
- SERVICE_BIT_NVME = 8,
- SERVICE_BIT_ROCEAA = 9,
- SERVICE_BIT_CURRENET = 10,
- SERVICE_BIT_PPA = 11,
- SERVICE_BIT_MIGRATE = 12,
- SERVICE_BIT_MAX
-};
-
-#define CFG_SERVICE_MASK_NIC (0x1 << SERVICE_BIT_NIC)
-#define CFG_SERVICE_MASK_ROCE (0x1 << SERVICE_BIT_ROCE)
-#define CFG_SERVICE_MASK_VBS (0x1 << SERVICE_BIT_VBS)
-#define CFG_SERVICE_MASK_TOE (0x1 << SERVICE_BIT_TOE)
-#define CFG_SERVICE_MASK_IPSEC (0x1 << SERVICE_BIT_IPSEC)
-#define CFG_SERVICE_MASK_FC (0x1 << SERVICE_BIT_FC)
-#define CFG_SERVICE_MASK_VIRTIO (0x1 << SERVICE_BIT_VIRTIO)
-#define CFG_SERVICE_MASK_OVS (0x1 << SERVICE_BIT_OVS)
-#define CFG_SERVICE_MASK_NVME (0x1 << SERVICE_BIT_NVME)
-#define CFG_SERVICE_MASK_ROCEAA (0x1 << SERVICE_BIT_ROCEAA)
-#define CFG_SERVICE_MASK_CURRENET (0x1 << SERVICE_BIT_CURRENET)
-#define CFG_SERVICE_MASK_PPA (0x1 << SERVICE_BIT_PPA)
-#define CFG_SERVICE_MASK_MIGRATE (0x1 << SERVICE_BIT_MIGRATE)
-
-/* Definition of the scenario ID in the cfg_data, which is used for SML memory allocation. */
-enum scenes_id_define {
- SCENES_ID_FPGA_ETH = 0,
- SCENES_ID_FPGA_TIOE = 1, /* Discarded */
- SCENES_ID_STORAGE_ROCEAA_2x100 = 2,
- SCENES_ID_STORAGE_ROCEAA_4x25 = 3,
- SCENES_ID_CLOUD = 4,
- SCENES_ID_FC = 5,
- SCENES_ID_STORAGE_ROCE = 6,
- SCENES_ID_COMPUTE_ROCE = 7,
- SCENES_ID_STORAGE_TOE = 8,
- SCENES_ID_MAX
-};
-
-/* struct cfg_cmd_dev_cap.sf_svc_attr */
-enum {
- SF_SVC_FT_BIT = (1 << 0),
- SF_SVC_RDMA_BIT = (1 << 1),
-};
-
-enum cfg_cmd {
- CFG_CMD_GET_DEV_CAP = 0,
- CFG_CMD_GET_HOST_TIMER = 1,
-};
-
-struct cfg_cmd_host_timer {
- struct mgmt_msg_head head;
-
- u8 host_id;
- u8 rsvd1;
-
- u8 timer_pf_num;
- u8 timer_pf_id_start;
- u16 timer_vf_num;
- u16 timer_vf_id_start;
- u32 rsvd2[8];
-};
-
-struct cfg_cmd_dev_cap {
- struct mgmt_msg_head head;
-
- u16 func_id;
- u16 rsvd1;
-
- /* Public resources */
- u8 host_id;
- u8 ep_id;
- u8 er_id;
- u8 port_id;
-
- u16 host_total_func;
- u8 host_pf_num;
- u8 pf_id_start;
- u16 host_vf_num;
- u16 vf_id_start;
- u8 host_oq_id_mask_val;
- u8 timer_en;
- u8 host_valid_bitmap;
- u8 rsvd_host;
-
- u16 svc_cap_en;
- u16 max_vf;
- u8 flexq_en;
- u8 valid_cos_bitmap;
- /* Reserved for func_valid_cos_bitmap */
- u8 port_cos_valid_bitmap;
- u8 rsvd_func1;
- u32 rsvd_func2;
-
- u8 sf_svc_attr;
- u8 func_sf_en;
- u8 lb_mode;
- u8 smf_pg;
-
- u32 max_conn_num;
- u16 max_stick2cache_num;
- u16 max_bfilter_start_addr;
- u16 bfilter_len;
- u16 hash_bucket_num;
-
- /* shared resource */
- u8 host_sf_en;
- u8 master_host_id;
- u8 srv_multi_host_mode;
- u8 virtio_vq_size;
-
- u32 rsvd_func3[5];
-
- /* l2nic */
- u16 nic_max_sq_id;
- u16 nic_max_rq_id;
- u16 nic_default_num_queues;
- u16 rsvd1_nic;
- u32 rsvd2_nic[2];
-
- /* RoCE */
- u32 roce_max_qp;
- u32 roce_max_cq;
- u32 roce_max_srq;
- u32 roce_max_mpt;
- u32 roce_max_drc_qp;
-
- u32 roce_cmtt_cl_start;
- u32 roce_cmtt_cl_end;
- u32 roce_cmtt_cl_size;
-
- u32 roce_dmtt_cl_start;
- u32 roce_dmtt_cl_end;
- u32 roce_dmtt_cl_size;
-
- u32 roce_wqe_cl_start;
- u32 roce_wqe_cl_end;
- u32 roce_wqe_cl_size;
- u8 roce_srq_container_mode;
- u8 rsvd_roce1[3];
- u32 rsvd_roce2[5];
-
- /* IPsec */
- u32 ipsec_max_sactx;
- u16 ipsec_max_cq;
- u16 rsvd_ipsec1;
- u32 rsvd_ipsec[2];
-
- /* OVS */
- u32 ovs_max_qpc;
- u32 rsvd_ovs1[3];
-
- /* ToE */
- u32 toe_max_pctx;
- u32 toe_max_cq;
- u16 toe_max_srq;
- u16 toe_srq_id_start;
- u16 toe_max_mpt;
- u16 toe_max_cctxt;
- u32 rsvd_toe[2];
-
- /* FC */
- u32 fc_max_pctx;
- u32 fc_max_scq;
- u32 fc_max_srq;
-
- u32 fc_max_cctx;
- u32 fc_cctx_id_start;
-
- u8 fc_vp_id_start;
- u8 fc_vp_id_end;
- u8 rsvd_fc1[2];
- u32 rsvd_fc2[5];
-
- /* VBS */
- u16 vbs_max_volq;
- u16 rsvd0_vbs;
- u32 rsvd1_vbs[3];
-
- u16 fake_vf_start_id;
- u16 fake_vf_num;
- u32 fake_vf_max_pctx;
- u16 fake_vf_bfilter_start_addr;
- u16 fake_vf_bfilter_len;
- u32 rsvd_glb[8];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
deleted file mode 100644
index 6f5f87b..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/******************************************************************************
- * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
- ******************************************************************************
- File Name : comm_cmdq_intf.h
- Version : Initial Draft
- Description : common command queue interface
- Function List :
- History :
- Modification: Created file
-
-******************************************************************************/
-
-#ifndef COMM_CMDQ_INTF_H
-#define COMM_CMDQ_INTF_H
-
-/* Cmdq ack type */
-enum hinic3_ack_type {
- HINIC3_ACK_TYPE_CMDQ,
- HINIC3_ACK_TYPE_SHARE_CQN,
- HINIC3_ACK_TYPE_APP_CQN,
-
- HINIC3_MOD_ACK_MAX = 15,
-};
-
-/* Defines the queue type of the set arm bit. */
-enum {
- SET_ARM_BIT_FOR_CMDQ = 0,
- SET_ARM_BIT_FOR_L2NIC_SQ,
- SET_ARM_BIT_FOR_L2NIC_RQ,
- SET_ARM_BIT_TYPE_NUM
-};
-
-/* Defines the type. Each function supports a maximum of eight CMDQ types. */
-enum {
- CMDQ_0 = 0,
- CMDQ_1 = 1, /* dedicated and non-blocking queues */
- CMDQ_NUM
-};
-
-/* *******************cmd common command data structure ************************ */
-// Func->ucode, which is used to set arm bit data,
-// The microcode needs to perform big-endian conversion.
-struct comm_info_ucode_set_arm_bit {
- u32 q_type;
- u32 q_id;
-};
-
-/* *******************WQE data structure ************************ */
-union cmdq_wqe_cs_dw0 {
- struct {
- u32 err_status : 29;
- u32 error_code : 2;
- u32 rsvd : 1;
- } bs;
- u32 val;
-};
-
-union cmdq_wqe_cs_dw1 {
- // This structure is used when the driver writes the wqe.
- struct {
- u32 token : 16; // [15:0]
- u32 cmd : 8; // [23:16]
- u32 mod : 5; // [28:24]
- u32 ack_type : 2; // [30:29]
- u32 obit : 1; // [31]
- } drv_wr;
-
- /* The uCode writes back the structure of the CS_DW1.
- * The driver reads and uses the structure. */
- struct {
- u32 mod : 5; // [4:0]
- u32 ack_type : 3; // [7:5]
- u32 cmd : 8; // [15:8]
- u32 arm : 1; // [16]
- u32 rsvd : 14; // [30:17]
- u32 obit : 1; // [31]
- } wb;
- u32 val;
-};
-
-/* CmdQ BD information or write back buffer information */
-struct cmdq_sge {
- u32 pa_h; // Upper 32 bits of the physical address
- u32 pa_l; // Upper 32 bits of the physical address
- u32 len; // Invalid bit[31].
- u32 resv;
-};
-
-/* Ctrls section definition of WQE */
-struct cmdq_wqe_ctrls {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
-};
-
-/* Complete section definition of WQE */
-struct cmdq_wqe_cs {
- union cmdq_wqe_cs_dw0 dw0;
- union cmdq_wqe_cs_dw1 dw1;
- union {
- struct cmdq_sge sge;
- u32 dw2_5[4];
- } ack;
-};
-
-/* Inline header in WQE inline, describing the length of inline data */
-union cmdq_wqe_inline_header {
- struct {
- u32 buf_len : 11; // [10:0] inline data len
- u32 rsv : 21; // [31:11]
- } bs;
- u32 val;
-};
-
-/* Definition of buffer descriptor section in WQE */
-union cmdq_wqe_bds {
- struct {
- struct cmdq_sge bds_sge;
- u32 rsvd[4]; /* Zwy is used to transfer the virtual address of the buffer. */
- } lcmd; /* Long command, non-inline, and SGE describe the buffer information. */
-};
-
-/* Definition of CMDQ WQE */
-/* (long cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(16B) |
- * | |
- * +----------------------------------------+
- * | driver section(16B) |
- * +----------------------------------------+
- *
- *
- * (middle cmd, 128B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(88B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- *
- *
- * (short cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(24B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- */
-struct cmdq_wqe {
- struct cmdq_wqe_ctrls ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds bds;
-};
-
-/* Definition of ctrls section in inline WQE */
-struct cmdq_wqe_ctrls_inline {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
- u64 db;
-};
-
-/* Buffer descriptor section definition of WQE */
-union cmdq_wqe_bds_inline {
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[80];
- } mcmd; /* Middle command, inline mode */
-
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[16];
- } scmd; /* Short command, inline mode */
-};
-
-struct cmdq_wqe_inline {
- struct cmdq_wqe_ctrls_inline ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds_inline bds;
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_defs.h b/drivers/net/ethernet/huawei/hinic3/comm_defs.h
deleted file mode 100644
index 91d298d..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_defs.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_defs.h
- * Version : Initial Draft
- * Description : common definitions
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef COMM_DEFS_H
-#define COMM_DEFS_H
-
-/* CMDQ MODULE_TYPE */
-enum hinic3_mod_type {
- HINIC3_MOD_COMM = 0, /* HW communication module */
- HINIC3_MOD_L2NIC = 1, /* L2NIC module */
- HINIC3_MOD_ROCE = 2,
- HINIC3_MOD_PLOG = 3,
- HINIC3_MOD_TOE = 4,
- HINIC3_MOD_FLR = 5,
- HINIC3_MOD_RSVD1 = 6,
- HINIC3_MOD_CFGM = 7, /* Configuration module */
- HINIC3_MOD_CQM = 8,
- HINIC3_MOD_RSVD2 = 9,
- COMM_MOD_FC = 10,
- HINIC3_MOD_OVS = 11,
- HINIC3_MOD_DSW = 12,
- HINIC3_MOD_MIGRATE = 13,
- HINIC3_MOD_HILINK = 14,
- HINIC3_MOD_CRYPT = 15, /* secure crypto module */
- HINIC3_MOD_VIO = 16,
- HINIC3_MOD_IMU = 17,
- HINIC3_MOD_DFT = 18, /* DFT */
- HINIC3_MOD_HW_MAX = 19, /* hardware max module id */
- /* Software module id, for PF/VF and multi-host */
- HINIC3_MOD_SW_FUNC = 20,
- HINIC3_MOD_MAX,
-};
-
-/* func reset的flag ,用于指示清理哪种资源 */
-enum func_reset_flag {
- RES_TYPE_FLUSH_BIT = 0,
- RES_TYPE_MQM,
- RES_TYPE_SMF,
- RES_TYPE_PF_BW_CFG,
-
- RES_TYPE_COMM = 10,
- RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_NIC,
- RES_TYPE_OVS,
- RES_TYPE_VBS,
- RES_TYPE_ROCE,
- RES_TYPE_FC,
- RES_TYPE_TOE,
- RES_TYPE_IPSEC,
- RES_TYPE_MAX,
-};
-
-#define HINIC3_COMM_RES \
- ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
- (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
- (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
-
-#define HINIC3_NIC_RES (1 << RES_TYPE_NIC)
-#define HINIC3_OVS_RES (1 << RES_TYPE_OVS)
-#define HINIC3_VBS_RES (1 << RES_TYPE_VBS)
-#define HINIC3_ROCE_RES (1 << RES_TYPE_ROCE)
-#define HINIC3_FC_RES (1 << RES_TYPE_FC)
-#define HINIC3_TOE_RES (1 << RES_TYPE_TOE)
-#define HINIC3_IPSEC_RES (1 << RES_TYPE_IPSEC)
-
-/* MODE OVS、NIC、UNKNOWN */
-#define HINIC3_WORK_MODE_OVS 0
-#define HINIC3_WORK_MODE_UNKNOWN 1
-#define HINIC3_WORK_MODE_NIC 2
-
-#define DEVICE_TYPE_L2NIC 0
-#define DEVICE_TYPE_NVME 1
-#define DEVICE_TYPE_VIRTIO_NET 2
-#define DEVICE_TYPE_VIRTIO_BLK 3
-#define DEVICE_TYPE_VIRTIO_VSOCK 4
-#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
-#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
-#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
-#define DEVICE_TYPE_VIRTIO_HPC 8
-
-#define IS_STORAGE_DEVICE_TYPE(dev_type) \
- ((dev_type) == DEVICE_TYPE_VIRTIO_BLK || \
- (dev_type) == DEVICE_TYPE_VIRTIO_BLK_TRANSITION || \
- (dev_type) == DEVICE_TYPE_VIRTIO_SCSI_TRANSITION)
-
-/* Common header control information of the COMM message
- * interaction command word between the driver and PF
- */
-struct comm_info_head {
- u8 status;
- u8 version;
- u8 rep_aeq_num;
- u8 rsvd[5];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
deleted file mode 100644
index ae998cf..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_msg_intf.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef COMM_MSG_INTF_H
-#define COMM_MSG_INTF_H
-
-#include "comm_defs.h"
-#include "mgmt_msg_base.h"
-#include "mpu_cmd_base_defs.h"
-#include "mpu_inband_cmd_defs.h"
-
-struct spu_cmd_freq_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: check */
- u8 rsvd[3];
- u32 freq;
-};
-
-struct spu_cmd_power_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: init */
- u8 slave_addr;
- u8 cmd_id;
- u8 size;
- u32 value;
-};
-
-struct spu_cmd_tsensor_operation {
- struct comm_info_head head;
-
- u8 op_code;
- u8 rsvd[3];
- s16 fabric_tsensor_temp_avg;
- s16 fabric_tsensor_temp;
- s16 sys_tsensor_temp_avg;
- s16 sys_tsensor_temp;
-};
-
-enum cfg_msix_operation {
- CFG_MSIX_OPERATION_FREE = 0,
- CFG_MSIX_OPERATION_ALLOC = 1,
-};
-
-struct comm_cmd_ffm_info {
- struct mgmt_msg_head head;
-
- u8 node_id;
- /* error level of the interrupt source */
- u8 err_level;
- /* Classification by interrupt source properties */
- u16 err_type;
- u32 err_csr_addr;
- u32 err_csr_value;
- u32 rsvd1;
-};
-
-struct hinic3_cmd_update_firmware {
- struct mgmt_msg_head msg_head;
-
- struct {
- u32 sl : 1;
- u32 sf : 1;
- u32 flag : 1;
- u32 bit_signed : 1;
- u32 reserved : 12;
- u32 fragment_len : 16;
- } ctl_info;
-
- struct {
- u32 section_crc;
- u32 section_type;
- } section_info;
-
- u32 total_len;
- u32 section_len;
- u32 section_version;
- u32 section_offset;
- u32 data[384];
-};
-
-struct hinic3_cmd_activate_firmware {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-struct hinic3_cmd_switch_config {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
index 76e128e..1562c59 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
@@ -28,6 +28,8 @@
#include "cqm_npu_cmd.h"
#include "cqm_npu_cmd_defs.h"
+#include "vram_common.h"
+
static void cqm_bat_fill_cla_common_gpa(struct tag_cqm_handle *cqm_handle,
struct tag_cqm_cla_table *cla_table,
struct tag_cqm_bat_entry_standerd *bat_entry_standerd)
@@ -367,6 +369,14 @@ static s32 cqm_bat_update_cmd(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
struct tag_cqm_cmdq_bat_update *bat_update_cmd = NULL;
s32 ret = CQM_FAIL;
+ int is_in_kexec;
+
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip updating the cqm_bat to chip during kexec!\n");
+ return CQM_SUCCESS;
+ }
+
bat_update_cmd = (struct tag_cqm_cmdq_bat_update *)(buf_in->buf);
bat_update_cmd->offset = 0;
@@ -644,6 +654,7 @@ void cqm_bat_uninit(struct tag_cqm_handle *cqm_handle)
static s32 cqm_cla_fill_buf(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *cla_base_buf,
struct tag_cqm_buf *cla_sub_buf, u8 gpa_check_enable)
{
+ struct hinic3_hwdev *handle = cqm_handle->ex_handle;
struct hinic3_func_attr *func_attr = NULL;
dma_addr_t *base = NULL;
u64 fake_en = 0;
@@ -655,13 +666,17 @@ static s32 cqm_cla_fill_buf(struct tag_cqm_handle *cqm_handle, struct tag_cqm_bu
/* Apply for space for base_buf */
if (!cla_base_buf->buf_list) {
- if (cqm_buf_alloc(cqm_handle, cla_base_buf, false) == CQM_FAIL)
+ if (cqm_buf_alloc(cqm_handle, cla_base_buf, false) ==
+ CQM_FAIL) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(cla_base_buf));
return CQM_FAIL;
+ }
}
/* Apply for space for sub_buf */
if (!cla_sub_buf->buf_list) {
if (cqm_buf_alloc(cqm_handle, cla_sub_buf, false) == CQM_FAIL) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(cla_sub_buf));
cqm_buf_free(cla_base_buf, cqm_handle);
return CQM_FAIL;
}
@@ -768,8 +783,10 @@ static s32 cqm_cla_xyz_lvl1(struct tag_cqm_handle *cqm_handle,
/* Applying for CLA_Z_BUF Space */
cla_z_buf = &cla_table->cla_z_buf;
cla_z_buf->buf_size = trunk_size;
- cla_z_buf->buf_number = (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
- cla_z_buf->page_number = cla_z_buf->buf_number << cla_table->trunk_order;
+ cla_z_buf->buf_number =
+ (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
+ cla_z_buf->page_number = cla_z_buf->buf_number <<
+ cla_table->trunk_order;
/* All buffer space must be statically allocated. */
if (cla_table->alloc_static) {
@@ -785,6 +802,7 @@ static s32 cqm_cla_xyz_lvl1(struct tag_cqm_handle *cqm_handle,
cla_z_buf->buf_list = vmalloc(cla_z_buf->buf_number *
sizeof(struct tag_cqm_buf_list));
if (!cla_z_buf->buf_list) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_1_z_buf));
cqm_buf_free(cla_y_buf, cqm_handle);
return CQM_FAIL;
}
@@ -840,6 +858,7 @@ static s32 cqm_cla_xyz_lvl2_xyz_apply(struct tag_cqm_handle *cqm_handle,
cla_x_buf->buf_size = trunk_size;
cla_x_buf->buf_number = 1;
cla_x_buf->page_number = cla_x_buf->buf_number << cla_table->trunk_order;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
ret = cqm_buf_alloc(cqm_handle, cla_x_buf, false);
if (ret != CQM_SUCCESS)
return CQM_FAIL;
@@ -869,14 +888,20 @@ static s32 cqm_cla_xyz_vram_name_init(struct tag_cqm_cla_table *cla_table,
cla_x_buf = &cla_table->cla_x_buf;
cla_z_buf = &cla_table->cla_z_buf;
cla_y_buf = &cla_table->cla_y_buf;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_x_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_X);
+ VRAM_NAME_APPLY_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_X);
+ cla_y_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_y_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Y);
+ VRAM_NAME_APPLY_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Y);
+ cla_z_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_z_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Z);
+ VRAM_NAME_APPLY_LEN, "%s%s",
+ cla_table->name, VRAM_CQM_CLA_COORD_Z);
return CQM_SUCCESS;
}
@@ -925,6 +950,7 @@ static s32 cqm_cla_xyz_lvl2(struct tag_cqm_handle *cqm_handle,
cla_z_buf->buf_list = vmalloc(cla_z_buf->buf_number *
sizeof(struct tag_cqm_buf_list));
if (!cla_z_buf->buf_list) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_2_z_buf));
cqm_buf_free(cla_x_buf, cqm_handle);
return CQM_FAIL;
}
@@ -934,6 +960,7 @@ static s32 cqm_cla_xyz_lvl2(struct tag_cqm_handle *cqm_handle,
cla_y_buf->buf_list = vmalloc(cla_y_buf->buf_number *
sizeof(struct tag_cqm_buf_list));
if (!cla_y_buf->buf_list) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_2_y_buf));
cqm_buf_free(cla_z_buf, cqm_handle);
cqm_buf_free(cla_x_buf, cqm_handle);
return CQM_FAIL;
@@ -1188,7 +1215,7 @@ static void cqm_cla_init_entry_extern(struct tag_cqm_handle *cqm_handle,
* exceed 128 x 4 KB. Otherwise, clearing the timer buffer of
* the function is complex.
*/
- cla_table->trunk_order = CQM_4K_PAGE_ORDER;
+ cla_table->trunk_order = CQM_8K_PAGE_ORDER;
cla_table->max_buffer_size = capability->timer_number *
capability->timer_basic_size;
cla_table->obj_size = capability->timer_basic_size;
@@ -1237,7 +1264,7 @@ static s32 cqm_cla_init_entry_condition(struct tag_cqm_handle *cqm_handle, u32 e
memcpy(cla_table_timer, cla_table, sizeof(struct tag_cqm_cla_table));
snprintf(cla_table_timer->name,
- VRAM_NAME_MAX_LEN - 1, "%s%s%01u", cla_table->name,
+ VRAM_NAME_APPLY_LEN, "%s%s%01u", cla_table->name,
VRAM_CQM_CLA_SMF_BASE, i);
if (cqm_cla_xyz(cqm_handle, cla_table_timer) ==
@@ -1268,7 +1295,7 @@ static s32 cqm_cla_init_entry(struct tag_cqm_handle *cqm_handle,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
cla_table->type = bat_table->bat_entry_type[i];
- snprintf(cla_table->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(cla_table->name, VRAM_NAME_APPLY_LEN,
"%s%s%s%02u", cqm_handle->name, VRAM_CQM_CLA_BASE,
VRAM_CQM_CLA_TYPE_BASE, cla_table->type);
@@ -1485,11 +1512,11 @@ static s32 cqm_cla_update(struct tag_cqm_handle *cqm_handle,
spu_en = 0;
pa = ((buf_node_parent->pa + (child_index * sizeof(dma_addr_t))) |
- (u32)spu_en);
+ spu_en);
cmd.gpa_h = CQM_ADDR_HI(pa);
cmd.gpa_l = CQM_ADDR_LW(pa);
- pa = (buf_node_child->pa | (u32)spu_en);
+ pa = (buf_node_child->pa | spu_en);
cmd.value_h = CQM_ADDR_HI(pa);
cmd.value_l = CQM_ADDR_LW(pa);
@@ -1980,7 +2007,7 @@ struct tag_cqm_cla_table *cqm_cla_table_get(struct tag_cqm_bat_table *bat_table,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
- if (cla_table && entry_type == cla_table->type)
+ if ((cla_table != NULL) && (entry_type == cla_table->type))
return cla_table;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
index dd0766e..a51c1dc 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
@@ -9,6 +9,7 @@
#include "cqm_bitmap_table.h"
#include "cqm_object.h"
+#include "vram_common.h"
/* When the connection check is enabled, the maximum number of connections
* supported by the chip is 1M - 63, which cannot reach 1M
@@ -19,6 +20,7 @@
#define CLA_TABLE_PAGE_ORDER 0
#define CQM_4K_PAGE_ORDER 0
#define CQM_4K_PAGE_SIZE 4096
+#define CQM_8K_PAGE_ORDER 1
#define CQM_BAT_ENTRY_MAX 16
#define CQM_BAT_ENTRY_SIZE 16
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
index f4844d5..86b268c 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
@@ -254,8 +254,10 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
}
pages = vmalloc(sizeof(struct page *) * buf->page_number);
- if (!pages)
+ if (!pages) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(pages));
return CQM_FAIL;
+ }
for (i = 0; i < buf->buf_number; i++) {
for (j = 0; j < ((u32)1 << order); j++)
@@ -273,6 +275,11 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
return CQM_SUCCESS;
}
+static bool check_use_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ return buf->buf_info.use_vram ? true : false;
+}
+
static bool check_use_non_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
{
return buf->buf_info.use_vram ? false : true;
@@ -294,11 +301,48 @@ static bool check_for_nouse_node_alloc(struct hinic3_hwdev *handle, struct tag_c
return false;
}
+static s32 cqm_buf_vram_kalloc(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ void *vaddr = NULL;
+ int i;
+
+ vaddr = hi_vram_kalloc(buf->buf_info.buf_vram_name, (u64)buf->buf_size * buf->buf_number);
+ if (!vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
+ return CQM_FAIL;
+ }
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = (void *)((char *)vaddr + i * (u64)buf->buf_size);
+
+ return CQM_SUCCESS;
+}
+
+static void cqm_buf_vram_free(struct tag_cqm_buf *buf)
+{
+ s32 i;
+
+ if (buf->buf_list == NULL) {
+ return;
+ }
+
+ if (buf->buf_list[0].va)
+ hi_vram_kfree(buf->buf_list[0].va, buf->buf_info.buf_vram_name,
+ (u64)buf->buf_size * buf->buf_number);
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = NULL;
+}
+
static void cqm_buf_free_page_common(struct tag_cqm_buf *buf)
{
u32 order;
s32 i;
+ if (buf->buf_list == NULL) {
+ return;
+ }
+
order = (u32)get_order(buf->buf_size);
for (i = 0; i < (s32)buf->buf_number; i++) {
@@ -320,8 +364,10 @@ static s32 cqm_buf_use_node_alloc_page(struct hinic3_hwdev *handle, struct tag_c
node = dev_to_node(handle->dev_hdl);
for (i = 0; i < (s32)buf->buf_number; i++) {
newpage = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, order);
- if (!newpage)
+ if (!newpage) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
va = (void *)page_address(newpage);
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
@@ -349,8 +395,10 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
for (i = 0; i < (s32)buf->buf_number; i++) {
va = (void *)ossl_get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
- if (!va)
+ if (!va) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
* value must be 0.
@@ -367,21 +415,21 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
return CQM_SUCCESS;
}
-#define MALLOC_FUNCS_COUNT 2
-#define FREE_FUNCS_COUNT 1
-static const struct malloc_memory g_malloc_funcs[MALLOC_FUNCS_COUNT] = {
+static const struct malloc_memory g_malloc_funcs[] = {
+ {check_use_vram, cqm_buf_vram_kalloc},
{check_for_use_node_alloc, cqm_buf_use_node_alloc_page},
{check_for_nouse_node_alloc, cqm_buf_unused_node_alloc_page}
};
-static const struct free_memory g_free_funcs[FREE_FUNCS_COUNT] = {
+static const struct free_memory g_free_funcs[] = {
+ {check_use_vram, cqm_buf_vram_free},
{check_use_non_vram, cqm_buf_free_page_common}
};
static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *buf)
{
struct hinic3_hwdev *handle = cqm_handle->ex_handle;
- u32 malloc_funcs_num = MALLOC_FUNCS_COUNT;
+ u32 malloc_funcs_num = ARRAY_SIZE(g_malloc_funcs);
u32 i;
for (i = 0; i < malloc_funcs_num; i++) {
@@ -398,7 +446,7 @@ static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
static void cqm_buf_free_page(struct tag_cqm_buf *buf)
{
- u32 free_funcs_num = FREE_FUNCS_COUNT;
+ u32 free_funcs_num = ARRAY_SIZE(g_free_funcs);
u32 i;
for (i = 0; i < free_funcs_num; i++) {
@@ -447,8 +495,11 @@ static s32 cqm_buf_get_secure_mem_pages(struct tag_cqm_handle *cqm_handle, struc
cqm_get_secure_mem_pages(handle,
(u32)get_order(buf->buf_size),
&buf->buf_list[i].pa);
- if (!buf->buf_list[i].va)
+ if (!buf->buf_list[i].va) {
+ cqm_err(handle->dev_hdl,
+ CQM_ALLOC_FAIL(cqm_get_secure_mem_pages));
break;
+ }
}
if (i != buf->buf_number) {
@@ -780,7 +831,10 @@ static s32 cqm_single_bitmap_init(struct tag_cqm_bitmap *bitmap)
*/
bit_number = (ALIGN(bitmap->max_num, CQM_NUM_BIT_BYTE) >>
CQM_BYTE_BIT_SHIFT);
- bitmap->table = vmalloc(bit_number);
+ if (bitmap->bitmap_info.use_vram != 0)
+ bitmap->table = hi_vram_kalloc(bitmap->bitmap_info.buf_vram_name, bit_number);
+ else
+ bitmap->table = vmalloc(bit_number);
if (!bitmap->table)
return CQM_FAIL;
memset(bitmap->table, 0, bit_number);
@@ -859,7 +913,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
}
bitmap = &cla_table->bitmap;
- snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_APPLY_LEN,
"%s%s%02d", cla_table->name,
VRAM_CQM_BITMAP_BASE, cla_table->type);
@@ -869,6 +923,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
bitmap->reserved_top = capability->qpc_reserved;
bitmap->reserved_back = capability->qpc_reserved_back;
bitmap->last = capability->qpc_reserved;
+ bitmap->bitmap_info.use_vram = get_use_vram_flag();
cqm_info(handle->dev_hdl,
"Bitmap init: cla_table_type=%u, max_num=0x%x\n",
cla_table->type, bitmap->max_num);
@@ -948,7 +1003,12 @@ void cqm_bitmap_uninit(struct tag_cqm_handle *cqm_handle)
if (cla_table->type != CQM_BAT_ENTRY_T_INVALID &&
bitmap->table) {
spin_lock_deinit(&bitmap->lock);
- vfree(bitmap->table);
+ if (bitmap->bitmap_info.use_vram != 0)
+ hi_vram_kfree(bitmap->table, bitmap->bitmap_info.buf_vram_name,
+ ALIGN(bitmap->max_num, CQM_NUM_BIT_BYTE) >>
+ CQM_BYTE_BIT_SHIFT);
+ else
+ vfree(bitmap->table);
bitmap->table = NULL;
}
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
index 7febf76..06b8661 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
@@ -9,6 +9,7 @@
#include <linux/spinlock.h>
#include "cqm_object.h"
+#include "vram_common.h"
struct tag_cqm_bitmap {
ulong *table;
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c
index cf7df37..3d38edc 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c
@@ -15,7 +15,6 @@
#include "cqm_bitmap_table.h"
#include "cqm_bat_cla.h"
#include "cqm_main.h"
-#include "cqm_cmd.h"
/**
* cqm_cmd_alloc - Apply for a cmd buffer. The buffer size is fixed to 2 KB,
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
index 9a13ae0..db65c8b 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
@@ -196,6 +196,12 @@ void *cqm_get_db_addr(void *ex_handle, u32 service_type)
pr_err("[CQM]%s: ex_handle is null\n", __func__);
return NULL;
}
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return NULL;
+ }
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -218,6 +224,17 @@ s32 cqm_ring_hardware_db(void *ex_handle, u32 service_type, u8 db_count, u64 db)
struct tag_cqm_service *service = NULL;
struct hinic3_hwdev *handle = NULL;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -278,6 +295,17 @@ s32 cqm_ring_direct_wqe_db(void *ex_handle, u32 service_type, u8 db_count,
u64 *tmp = (u64 *)direct_wqe;
int i;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
index 19a8b56..0e8a579 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
@@ -23,6 +23,8 @@
#include "cqm_memsec.h"
#include "cqm_main.h"
+#include "vram_common.h"
+
static unsigned char roce_qpc_rsv_mode = CQM_QPC_ROCE_NORMAL;
module_param(roce_qpc_rsv_mode, byte, 0644);
MODULE_PARM_DESC(roce_qpc_rsv_mode,
@@ -98,10 +100,17 @@ static s32 cqm_set_timer_enable(void *ex_handle)
{
struct hinic3_hwdev *handle = (struct hinic3_hwdev *)ex_handle;
struct tag_cqm_handle *cqm_handle = NULL;
+ int is_in_kexec;
if (!ex_handle)
return CQM_FAIL;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip starting cqm timer during kexec\n");
+ return CQM_SUCCESS;
+ }
+
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
if (cqm_handle->func_capability.fake_func_type == CQM_FAKE_FUNC_PARENT &&
cqm_set_fake_vf_timer(cqm_handle) != CQM_SUCCESS)
@@ -456,7 +465,7 @@ static void cqm_service_capability_init_roce(struct tag_cqm_handle *cqm_handle,
cqm_info(handle->dev_hdl, "Cap init: roce qpc 0x%x, scqc 0x%x, srqc 0x%x, drc_qp 0x%x\n",
roce_own_cap->max_qps, roce_own_cap->max_cqs,
roce_own_cap->max_srqs, roce_own_cap->max_drc_qps);
- cqm_info(handle->dev_hdl, "Cap init: type 0x%x, scenes:0x%x, qpc_rsv:0x%x, srv_bmp:0x%x\n",
+ cqm_info(handle->dev_hdl, "Cap init: board_type 0x%x, scenes_id:0x%x, qpc_rsv_mode:0x%x, srv_bmp:0x%x\n",
board_info->board_type, board_info->scenes_id,
roce_qpc_rsv_mode, board_info->service_en_bitmap);
@@ -610,7 +619,7 @@ static void cqm_service_capability_init_ipsec(struct tag_cqm_handle *cqm_handle,
func_cap->scqc_basic_size);
func_cap->scqc_alloc_static = true;
cqm_info(handle->dev_hdl, "Cap init: ipsec is valid\n");
- cqm_info(handle->dev_hdl, "Cap init: ipsec 0x%x, childc %d, scqc 0x%x, scqc_bsize %d\n",
+ cqm_info(handle->dev_hdl, "Cap init: ipsec childc_num 0x%x, childc_bsize %d, scqc_num 0x%x, scqc_bsize %d\n",
ipsec_srvcap->max_sactxs, func_cap->childc_basic_size,
ipsec_srvcap->max_cqs, func_cap->scqc_basic_size);
}
@@ -812,7 +821,7 @@ static int cqm_capability_init_bloomfilter(struct hinic3_hwdev *handle)
func_cap->bloomfilter_addr = service_capability->bfilter_start_addr;
if (func_cap->bloomfilter_length != 0 &&
!cqm_check_align(func_cap->bloomfilter_length)) {
- cqm_err(handle->dev_hdl, "Cap bloomfilter len %u is not the power of 2\n",
+ cqm_err(handle->dev_hdl, "Cap init: bloomfilter_length %u is not the power of 2\n",
func_cap->bloomfilter_length);
return CQM_FAIL;
@@ -883,7 +892,7 @@ static int cqm_capability_init_timer(struct hinic3_hwdev *handle)
func_cap->timer_vf_num = service_capability->timer_vf_num;
func_cap->timer_vf_id_start = service_capability->timer_vf_id_start;
cqm_info(handle->dev_hdl,
- "timer init: pf_num 0x%x, pf_start 0x%x, vf_num 0x%x, vf_start 0x%x\n",
+ "host timer init: timer_pf_num 0x%x, timer_pf_id_start 0x%x, timer_vf_num 0x%x, timer_vf_id_start 0x%x\n",
func_cap->timer_pf_num, func_cap->timer_pf_id_start,
func_cap->timer_vf_num, func_cap->timer_vf_id_start);
@@ -891,7 +900,7 @@ static int cqm_capability_init_timer(struct hinic3_hwdev *handle)
if (IS_SLAVE_HOST(handle)) {
total_timer_num *= CQM_TIMER_NUM_MULTI;
cqm_info(handle->dev_hdl,
- "timer init: need double tw resources, total_timer_num=0x%x\n",
+ "host timer init: need double tw resources, total_timer_num=0x%x\n",
total_timer_num);
}
}
@@ -1059,8 +1068,10 @@ static s32 cqm_fake_init(struct tag_cqm_handle *cqm_handle)
for (i = 0; i < (u32)child_func_number; i++) {
fake_cqm_handle = kmalloc(sizeof(*fake_cqm_handle), GFP_KERNEL | __GFP_ZERO);
- if (!fake_cqm_handle)
+ if (!fake_cqm_handle) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(fake_cqm_handle));
goto err;
+ }
/* Copy the attributes of the parent CQM handle to the child CQM
* handle and modify the values of function.
@@ -1129,7 +1140,7 @@ static s32 cqm_fake_mem_init(struct tag_cqm_handle *cqm_handle)
for (i = 0; i < (u32)child_func_number; i++) {
fake_cqm_handle = cqm_handle->fake_cqm_handle[i];
- snprintf(fake_cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(fake_cqm_handle->name, VRAM_NAME_APPLY_LEN,
"%s%s%02u", cqm_handle->name, VRAM_CQM_FAKE_MEM_BASE, i);
if (cqm_bat_init(fake_cqm_handle) != CQM_SUCCESS) {
@@ -1174,7 +1185,7 @@ s32 cqm_mem_init(void *ex_handle)
struct tag_cqm_handle *cqm_handle = NULL;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
- snprintf(cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(cqm_handle->name, VRAM_NAME_APPLY_LEN,
"%s%02u", VRAM_CQM_GLB_FUNC_BASE, hinic3_global_func_id(handle));
if (cqm_fake_init(cqm_handle) != CQM_SUCCESS) {
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
index 4f87bd1..8d1e481 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
@@ -362,6 +362,7 @@ s32 cqm_fake_vf_num_set(void *ex_handle, u16 fake_vf_num_cfg);
#define CQM_LOG_ID 0
#define CQM_PTR_NULL(x) "%s: " #x " is null\n", __func__
+#define CQM_ALLOC_FAIL(x) "%s: " #x " alloc fail\n", __func__
#define CQM_MAP_FAIL(x) "%s: " #x " map fail\n", __func__
#define CQM_FUNCTION_FAIL(x) "%s: " #x " return failure\n", __func__
#define CQM_WRONG_VALUE(x) "%s: " #x " %u is wrong\n", __func__, (u32)(x)
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
index 4888b0a..258c10a 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
@@ -21,6 +21,7 @@
#include "cqm_bloomfilter.h"
#include "cqm_db.h"
#include "cqm_main.h"
+#include "vram_common.h"
#include "vmsec_mpu_common.h"
#include "cqm_memsec.h"
@@ -34,6 +35,8 @@
#define STD_INPUT_ONE_PARA 1
#define STD_INPUT_TWO_PARA 2
#define MR_KEY_2_INDEX_SHIFT 8
+#define IS_ADDR_IN_MEMSEC(va, len, start, end) \
+ ((va) >= (start) && (va) + (len) < (end))
static int memsec_proc_show(struct seq_file *seq, void *offset);
static int memsec_proc_open(struct inode *inode, struct file *file);
@@ -49,12 +52,21 @@ static ssize_t memsec_proc_write(struct file *file, const char __user *data, siz
static struct proc_dir_entry *g_hinic3_memsec_proc_ent; /* proc dir */
static atomic_t g_memsec_proc_refcnt = ATOMIC_INIT(0);
+#if KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE
+static const struct file_operations memsec_proc_fops = {
+ .open = memsec_proc_open,
+ .read = seq_read,
+ .write = memsec_proc_write,
+ .release = memsec_proc_release,
+};
+#else
static const struct proc_ops memsec_proc_fops = {
.proc_open = memsec_proc_open,
.proc_read = seq_read,
.proc_write = memsec_proc_write,
.proc_release = memsec_proc_release,
};
+#endif
bool cqm_need_secure_mem(void *hwdev)
{
@@ -63,6 +75,9 @@ bool cqm_need_secure_mem(void *hwdev)
struct hinic3_hwdev *handle = (struct hinic3_hwdev *)hwdev;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (cqm_handle == NULL) {
+ return false;
+ }
info = &cqm_handle->secure_mem;
return ((info->need_secure_mem) && hinic3_is_guest_vmsec_enable(hwdev));
}
@@ -275,9 +290,10 @@ static int test_query_context(struct hinic3_hwdev *handle, char *data, size_t le
case CQM_OBJECT_SERVICE_CTX:
case CQM_OBJECT_MPT:
qpc_mpt = (struct tag_cqm_qpc_mpt *)cqm_obj;
- if (qpc_mpt->vaddr >= (u8 *)info->va_base &&
- (qpc_mpt->vaddr + cqm_obj->object_size) < (u8 *)info->va_end)
- in_secmem = true;
+ in_secmem = IS_ADDR_IN_MEMSEC(qpc_mpt->vaddr,
+ cqm_obj->object_size,
+ (u8 *)info->va_base,
+ (u8 *)info->va_end);
cqm_info(handle->dev_hdl,
"[memsec_dfx]Query %s:0x%x, va=%p %sin secure mem\n",
query_type == CQM_OBJECT_MPT ? "MPT, mpt_index" : "QPC, qpn",
@@ -286,9 +302,10 @@ static int test_query_context(struct hinic3_hwdev *handle, char *data, size_t le
case CQM_OBJECT_RDMA_SRQ:
case CQM_OBJECT_RDMA_SCQ:
cqm_queue = (struct tag_cqm_queue *)cqm_obj;
- if (cqm_queue->q_ctx_vaddr >= (u8 *)info->va_base &&
- (cqm_queue->q_ctx_vaddr + cqm_obj->object_size) < (u8 *)info->va_end)
- in_secmem = true;
+ in_secmem = IS_ADDR_IN_MEMSEC(cqm_queue->q_ctx_vaddr,
+ cqm_obj->object_size,
+ (u8 *)info->va_base,
+ (u8 *)info->va_end);
cqm_info(handle->dev_hdl,
"[memsec_dfx]Query %s:0x%x, va=%p %sin secure mem\n",
query_type == CQM_OBJECT_RDMA_SRQ ? "SRQC, srqn " : "SCQC, scqn",
@@ -378,7 +395,7 @@ static int hinic3_secure_mem_proc_node_remove(void *hwdev)
atomic_dec(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
@@ -401,7 +418,7 @@ static int hinic3_secure_mem_proc_node_add(void *hwdev)
atomic_inc(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
/* 0400 Read by owner */
@@ -653,7 +670,7 @@ void cqm_free_secure_mem_pages(struct hinic3_hwdev *handle, void *va, u32 order)
return;
}
- if (va < info->va_base || va > (info->va_end - PAGE_SIZE) ||
+ if (va < info->va_base || (va > (info->va_end - PAGE_SIZE)) ||
!PAGE_ALIGNED((va - info->va_base)))
cqm_err(handle->dev_hdl, "%s va wrong value\n", __func__);
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c
index 7d1bd35..86359c0 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c
@@ -180,8 +180,10 @@ struct tag_cqm_queue *cqm_object_recv_queue_create(void *ex_handle, u32 service_
rq_qinfo->common.q_header_vaddr =
cqm_kmalloc_align(sizeof(struct tag_cqm_queue_header),
GFP_KERNEL | __GFP_ZERO, CQM_QHEAD_ALIGN_ORDER);
- if (!rq_qinfo->common.q_header_vaddr)
+ if (!rq_qinfo->common.q_header_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_header_vaddr));
goto err1;
+ }
rq_qinfo->common.q_header_paddr =
pci_map_single(cqm_handle->dev, rq_qinfo->common.q_header_vaddr,
@@ -484,7 +486,8 @@ static bool cqm_object_nonrdma_queue_param_check(struct hinic3_hwdev *handle, u3
struct tag_cqm_handle *cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
/* exception of service registrion check */
- if (!cqm_handle->service[service_type].has_register) {
+ if (service_type >= CQM_SERVICE_T_MAX ||
+ !cqm_handle->service[service_type].has_register) {
cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(service_type));
return false;
}
@@ -1487,4 +1490,4 @@ void cqm_srq_used_rq_container_delete(struct tag_cqm_object *object, u8 *contain
}
kfree((void *)addr);
}
-EXPORT_SYMBOL(cqm_srq_used_rq_container_delete);
+EXPORT_SYMBOL(cqm_srq_used_rq_container_delete);
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c
index 92c19c4..1007b44 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c
@@ -127,8 +127,10 @@ s32 cqm_container_create(struct tag_cqm_object *object, u8 **container_addr, boo
* of the Container.
*/
new_container = kmalloc(qinfo->container_size, GFP_ATOMIC | __GFP_ZERO);
- if (!new_container)
+ if (!new_container) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(new_container));
return CQM_FAIL;
+ }
/* Container PCI mapping */
new_container_pa = pci_map_single(cqm_handle->dev, new_container,
@@ -299,8 +301,10 @@ s32 cqm_share_recv_queue_create(struct tag_cqm_object *object)
/* apply for buffer for SRQC */
common->q_ctx_vaddr = kmalloc(qinfo->q_ctx_size,
GFP_KERNEL | __GFP_ZERO);
- if (!common->q_ctx_vaddr)
+ if (!common->q_ctx_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_ctx_vaddr));
goto err2;
+ }
return CQM_SUCCESS;
err2:
@@ -808,8 +812,10 @@ static s32 cqm_nonrdma_queue_ctx_create(struct tag_cqm_object *object)
common->q_ctx_vaddr = cqm_kmalloc_align(qinfo->q_ctx_size,
GFP_KERNEL | __GFP_ZERO,
(u16)shift);
- if (!common->q_ctx_vaddr)
+ if (!common->q_ctx_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_ctx_vaddr));
return CQM_FAIL;
+ }
common->q_ctx_paddr = pci_map_single(cqm_handle->dev, common->q_ctx_vaddr,
qinfo->q_ctx_size, PCI_DMA_BIDIRECTIONAL);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h b/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
deleted file mode 100644
index ad732c3..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2019-2022. All rights reserved.
- * File Name : hinic3_comm_cmd.h
- * Version : Initial Draft
- * Created : 2019/4/25
- * Last Modified :
- * Description : COMM Commands between Driver and MPU
- * Function List :
- */
-
-#ifndef HINIC3_COMMON_CMD_H
-#define HINIC3_COMMON_CMD_H
-
-/* COMM Commands between Driver to MPU */
-enum hinic3_mgmt_cmd {
- /* flr及资源清理相关命令 */
- COMM_MGMT_CMD_FUNC_RESET = 0,
- COMM_MGMT_CMD_FEATURE_NEGO,
- COMM_MGMT_CMD_FLUSH_DOORBELL,
- COMM_MGMT_CMD_START_FLUSH,
- COMM_MGMT_CMD_SET_FUNC_FLR,
- COMM_MGMT_CMD_GET_GLOBAL_ATTR,
- COMM_MGMT_CMD_SET_PPF_FLR_TYPE,
- COMM_MGMT_CMD_SET_FUNC_SVC_USED_STATE,
-
- /* 分配msi-x中断资源 */
- COMM_MGMT_CMD_CFG_MSIX_NUM = 10,
-
- /* 驱动相关配置命令 */
- COMM_MGMT_CMD_SET_CMDQ_CTXT = 20,
- COMM_MGMT_CMD_SET_VAT,
- COMM_MGMT_CMD_CFG_PAGESIZE,
- COMM_MGMT_CMD_CFG_MSIX_CTRL_REG,
- COMM_MGMT_CMD_SET_CEQ_CTRL_REG,
- COMM_MGMT_CMD_SET_DMA_ATTR,
-
- /* INFRA配置相关命令字 */
- COMM_MGMT_CMD_GET_MQM_FIX_INFO = 40,
- COMM_MGMT_CMD_SET_MQM_CFG_INFO,
- COMM_MGMT_CMD_SET_MQM_SRCH_GPA,
- COMM_MGMT_CMD_SET_PPF_TMR,
- COMM_MGMT_CMD_SET_PPF_HT_GPA,
- COMM_MGMT_CMD_SET_FUNC_TMR_BITMAT,
- COMM_MGMT_CMD_SET_MBX_CRDT,
- COMM_MGMT_CMD_CFG_TEMPLATE,
- COMM_MGMT_CMD_SET_MQM_LIMIT,
-
- /* 信息获取相关命令字 */
- COMM_MGMT_CMD_GET_FW_VERSION = 60,
- COMM_MGMT_CMD_GET_BOARD_INFO,
- COMM_MGMT_CMD_SYNC_TIME,
- COMM_MGMT_CMD_GET_HW_PF_INFOS,
- COMM_MGMT_CMD_SEND_BDF_INFO,
- COMM_MGMT_CMD_GET_VIRTIO_BDF_INFO,
- COMM_MGMT_CMD_GET_SML_TABLE_INFO,
- COMM_MGMT_CMD_GET_SDI_INFO,
-
- /* 升级相关命令字 */
- COMM_MGMT_CMD_UPDATE_FW = 80,
- COMM_MGMT_CMD_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_DONE_NOTICE,
- COMM_MGMT_CMD_SWITCH_CFG,
- COMM_MGMT_CMD_CHECK_FLASH,
- COMM_MGMT_CMD_CHECK_FLASH_RW,
- COMM_MGMT_CMD_RESOURCE_CFG,
- COMM_MGMT_CMD_UPDATE_BIOS, /* TODO: merge to COMM_MGMT_CMD_UPDATE_FW */
- COMM_MGMT_CMD_MPU_GIT_CODE,
-
- /* chip reset相关 */
- COMM_MGMT_CMD_FAULT_REPORT = 100,
- COMM_MGMT_CMD_WATCHDOG_INFO,
- COMM_MGMT_CMD_MGMT_RESET,
- COMM_MGMT_CMD_FFM_SET, /* TODO: check if needed */
-
- /* chip info/log 相关 */
- COMM_MGMT_CMD_GET_LOG = 120,
- COMM_MGMT_CMD_TEMP_OP,
- COMM_MGMT_CMD_EN_AUTO_RST_CHIP,
- COMM_MGMT_CMD_CFG_REG,
- COMM_MGMT_CMD_GET_CHIP_ID,
- COMM_MGMT_CMD_SYSINFO_DFX,
- COMM_MGMT_CMD_PCIE_DFX_NTC,
- COMM_MGMT_CMD_DICT_LOG_STATUS, /* LOG STATUS 127 */
- COMM_MGMT_CMD_MSIX_INFO,
- COMM_MGMT_CMD_CHANNEL_DETECT,
- COMM_MGMT_CMD_DICT_COUNTER_STATUS,
-
- /* switch workmode 相关 */
- COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140,
- COMM_MGMT_CMD_SWITCH_WORKMODE,
-
- /* mpu 相关 */
- COMM_MGMT_CMD_MIGRATE_DFX_HPA = 150,
- COMM_MGMT_CMD_BDF_INFO,
- COMM_MGMT_CMD_NCSI_CFG_INFO_GET_PROC,
-
- /* rsvd0 section */
- COMM_MGMT_CMD_SECTION_RSVD_0 = 160,
-
- /* rsvd1 section */
- COMM_MGMT_CMD_SECTION_RSVD_1 = 170,
-
- /* rsvd2 section */
- COMM_MGMT_CMD_SECTION_RSVD_2 = 180,
-
- /* rsvd3 section */
- COMM_MGMT_CMD_SECTION_RSVD_3 = 190,
-
- /* TODO: move to DFT mode */
- COMM_MGMT_CMD_GET_DIE_ID = 200,
- COMM_MGMT_CMD_GET_EFUSE_TEST,
- COMM_MGMT_CMD_EFUSE_INFO_CFG,
- COMM_MGMT_CMD_GPIO_CTL,
- COMM_MGMT_CMD_HI30_SERLOOP_START, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_SERLOOP_STOP, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_SET_FLAG, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_GET_RESULT, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_ECC_TEST,
- COMM_MGMT_CMD_FUNC_BIST_TEST, /* 209 */
-
- COMM_MGMT_CMD_VPD_SET = 210,
- COMM_MGMT_CMD_VPD_GET,
-
- COMM_MGMT_CMD_ERASE_FLASH,
- COMM_MGMT_CMD_QUERY_FW_INFO,
- COMM_MGMT_CMD_GET_CFG_INFO,
- COMM_MGMT_CMD_GET_UART_LOG,
- COMM_MGMT_CMD_SET_UART_CMD,
- COMM_MGMT_CMD_SPI_TEST,
-
- /* TODO: ALL reg read/write merge to COMM_MGMT_CMD_CFG_REG */
- COMM_MGMT_CMD_UP_REG_GET,
- COMM_MGMT_CMD_UP_REG_SET, /* 219 */
-
- COMM_MGMT_CMD_REG_READ = 220,
- COMM_MGMT_CMD_REG_WRITE,
- COMM_MGMT_CMD_MAG_REG_WRITE,
- COMM_MGMT_CMD_ANLT_REG_WRITE,
-
- COMM_MGMT_CMD_HEART_EVENT, /* TODO: delete */
- COMM_MGMT_CMD_NCSI_OEM_GET_DRV_INFO, /* TODO: delete */
- COMM_MGMT_CMD_LASTWORD_GET,
- COMM_MGMT_CMD_READ_BIN_DATA, /* TODO: delete */
- /* COMM_MGMT_CMD_WWPN_GET, TODO: move to FC? */
- /* COMM_MGMT_CMD_WWPN_SET, TODO: move to FC? */ /* 229 */
-
- /* TODO: check if needed */
- COMM_MGMT_CMD_SET_VIRTIO_DEV = 230,
- COMM_MGMT_CMD_SET_MAC,
- /* MPU patch cmd */
- COMM_MGMT_CMD_LOAD_PATCH,
- COMM_MGMT_CMD_REMOVE_PATCH,
- COMM_MGMT_CMD_PATCH_ACTIVE,
- COMM_MGMT_CMD_PATCH_DEACTIVE,
- COMM_MGMT_CMD_PATCH_SRAM_OPTIMIZE,
- /* container host process */
- COMM_MGMT_CMD_CONTAINER_HOST_PROC,
- /* nsci counter */
- COMM_MGMT_CMD_NCSI_COUNTER_PROC,
- COMM_MGMT_CMD_CHANNEL_STATUS_CHECK, /* 239 */
-
- /* hot patch rsvd cmd */
- COMM_MGMT_CMD_RSVD_0 = 240,
- COMM_MGMT_CMD_RSVD_1,
- COMM_MGMT_CMD_RSVD_2,
- COMM_MGMT_CMD_RSVD_3,
- COMM_MGMT_CMD_RSVD_4,
- /* 无效字段,版本收编删除,编译使用 */
- COMM_MGMT_CMD_SEND_API_ACK_BY_UP,
-
- /* 注:添加cmd,不能修改已有命令字的值,请在前方rsvd
- * section中添加;原则上所有分支cmd表完全一致
- */
- COMM_MGMT_CMD_MAX = 255,
-};
-
-/* CmdQ Common subtype */
-enum comm_cmdq_cmd {
- COMM_CMD_UCODE_ARM_BIT_SET = 2,
- COMM_CMD_SEND_NPU_DFT_CMD,
-};
-
-#endif /* HINIC3_COMMON_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
deleted file mode 100644
index 9ce908e..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_COMMON_H
-#define HINIC3_COMMON_H
-
-#include <linux/types.h>
-
-struct hinic3_dma_addr_align {
- u32 real_size;
-
- void *ori_vaddr;
- dma_addr_t ori_paddr;
-
- void *align_vaddr;
- dma_addr_t align_paddr;
-};
-
-enum hinic3_wait_return {
- WAIT_PROCESS_CPL = 0,
- WAIT_PROCESS_WAITING = 1,
- WAIT_PROCESS_ERR = 2,
-};
-
-struct hinic3_sge {
- u32 hi_addr;
- u32 lo_addr;
- u32 len;
-};
-
-#ifdef static
-#undef static
-#define LLT_STATIC_DEF_SAVED
-#endif
-
-/* *
- * hinic_cpu_to_be32 - convert data to big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert, must be Multiple of 4B
- */
-static inline void hinic3_cpu_to_be32(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = cpu_to_be32(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_cpu_to_be32 - convert data from big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert
- */
-static inline void hinic3_be32_to_cpu(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = be32_to_cpu(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_set_sge - set dma area in scatter gather entry
- * @sge: scatter gather entry
- * @addr: dma address
- * @len: length of relevant data in the dma address
- */
-static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
- int len)
-{
- sge->hi_addr = upper_32_bits(addr);
- sge->lo_addr = lower_32_bits(addr);
- sge->len = len;
-}
-
-#define hinic3_hw_be32(val) (val)
-#define hinic3_hw_cpu32(val) (val)
-#define hinic3_hw_cpu16(val) (val)
-
-static inline void hinic3_hw_be32_len(void *data, int len)
-{
-}
-
-static inline void hinic3_hw_cpu32_len(void *data, int len)
-{
-}
-
-int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
- unsigned int flag,
- struct hinic3_dma_addr_align *mem_align);
-
-void hinic3_dma_free_coherent_align(void *dev_hdl,
- struct hinic3_dma_addr_align *mem_align);
-
-typedef enum hinic3_wait_return (*wait_cpl_handler)(void *priv_data);
-
-int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
- u32 wait_total_ms, u32 wait_once_us);
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
index f269691..7979244 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
@@ -8,7 +8,7 @@
#include "mpu_cmd_base_defs.h"
-#define HINIC3_DRV_VERSION "15.17.1.1"
+#define HINIC3_DRV_VERSION "17.7.8.1"
#define HINIC3_DRV_DESC "Intelligent Network Interface Card Driver"
#define HIUDK_DRV_DESC "Intelligent Network Unified Driver"
@@ -45,6 +45,8 @@ enum hinic3_service_type {
SERVICE_T_CUSTOM,
SERVICE_T_VROCE,
SERVICE_T_CRYPT,
+ SERVICE_T_VSOCK,
+ SERVICE_T_BIFUR,
SERVICE_T_MAX,
/* Only used for interruption resource management,
@@ -63,6 +65,9 @@ struct nic_service_cap {
u16 max_sqs;
u16 max_rqs;
u16 default_num_queues;
+ u16 outband_vlan_cfg_en;
+ u8 lro_enable;
+ u8 rsvd1[3];
};
struct ppa_service_cap {
@@ -76,6 +81,10 @@ struct ppa_service_cap {
u16 rsvd1;
};
+struct bifur_service_cap {
+ u8 rsvd;
+};
+
struct vbs_service_cap {
u16 vbs_max_volq;
u8 vbs_main_pf_enable;
@@ -785,6 +794,15 @@ bool hinic3_support_toe(void *hwdev, struct toe_service_cap *cap);
*/
bool hinic3_support_ppa(void *hwdev, struct ppa_service_cap *cap);
+/* *
+ * @brief hinic3_support_bifur - function support bifur
+ * @param hwdev: device pointer to hwdev
+ * @param cap: bifur service capbility
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+bool hinic3_support_bifur(void *hwdev, struct bifur_service_cap *cap);
+
/* *
* @brief hinic3_support_migr - function support migrate
* @param hwdev: device pointer to hwdev
@@ -895,6 +913,13 @@ int hinic3_get_mgmt_version(void *hwdev, u8 *mgmt_ver, u8 version_size,
int hinic3_get_fw_version(void *hwdev, struct hinic3_fw_version *fw_ver,
u16 channel);
+/* *
+ * @brief hinic3_get_bond_create_mode - get bond create mode
+ * @param hwdev: device pointer to hwdev
+ * @retval global function id
+ */
+u8 hinic3_get_bond_create_mode(void *udkdev);
+
/* *
* @brief hinic3_global_func_id - get global function id
* @param hwdev: device pointer to hwdev
@@ -1249,4 +1274,7 @@ int hinic3_mbox_to_host_sync(void *hwdev, enum hinic3_mod_type mod,
int hinic3_get_func_vroce_enable(void *hwdev, u16 glb_func_idx, u8 *en);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type);
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
index 5863bee..9b5f017 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
@@ -18,9 +18,8 @@
#include "hinic3_tx.h"
#include "hinic3_dcb.h"
#include "hinic3_nic.h"
-#include "hinic3_mgmt_interface.h"
-#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "hinic3_bond.h"
+#include "nic_mpu_cmd_defs.h"
typedef int (*nic_driv_module)(struct hinic3_nic_dev *nic_dev,
const void *buf_in, u32 in_size,
@@ -48,7 +47,7 @@ static int get_nic_drv_version(void *buf_out, const u32 *out_size)
}
err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
- HINIC3_NIC_DRV_VERSION, "2024-07-03_09:33:00");
+ HINIC3_NIC_DRV_VERSION, "2025-05-01_00:00:03");
if (err < 0)
return -EINVAL;
@@ -94,13 +93,13 @@ static int get_q_num(struct hinic3_nic_dev *nic_dev,
return -EFAULT;
}
- if (!buf_out) {
+ if (!buf_out || !out_size) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Get queue number para buf_out is NULL.\n");
return -EINVAL;
}
- if (!out_size || *out_size != sizeof(u16)) {
+ if (*out_size != sizeof(u16)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user: %u, expect: %lu\n",
*out_size, sizeof(u16));
@@ -126,7 +125,8 @@ static int get_tx_wqe_info(struct hinic3_nic_dev *nic_dev,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -178,7 +178,8 @@ static int get_rx_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
rq_info->delta = (u16)nic_dev->rxqs[q_id].delta;
- rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx & nic_dev->rxqs[q_id].q_mask);
+ rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx &
+ nic_dev->rxqs[q_id].q_mask);
rq_info->sw_pi = nic_dev->rxqs[q_id].next_to_update;
rq_info->msix_vector = nic_dev->rxqs[q_id].irq_id;
@@ -201,7 +202,8 @@ static int get_rx_wqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -230,7 +232,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EFAULT;
}
- if (!buf_in || !buf_out) {
+ if (!buf_in || !buf_out || !out_size) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Buf_in or buf_out is NULL.\n");
return -EINVAL;
@@ -243,7 +245,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EINVAL;
}
- if (!out_size || *out_size != sizeof(struct hinic3_rq_cqe)) {
+ if (*out_size != sizeof(struct hinic3_rq_cqe)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(struct hinic3_rq_cqe));
@@ -252,10 +254,16 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
q_id = (u16)info->q_id;
idx = (u16)info->wqe_id;
- if (q_id >= nic_dev->q_params.num_qps || idx >= nic_dev->rxqs[q_id].q_depth) {
+ if (q_id >= nic_dev->q_params.num_qps) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid q_id[%u] >= %u.\n", q_id,
+ nic_dev->q_params.num_qps);
+ return -EFAULT;
+ }
+ if (idx >= nic_dev->rxqs[q_id].q_depth) {
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Invalid q_id[%u] >= %u, or wqe idx[%u] >= %u.\n",
- q_id, nic_dev->q_params.num_qps, idx, nic_dev->rxqs[q_id].q_depth);
+ "Invalid wqe idx[%u] >= %u.\n", idx,
+ nic_dev->rxqs[q_id].q_depth);
return -EFAULT;
}
@@ -338,7 +346,8 @@ static int set_loopback_mode(struct hinic3_nic_dev *nic_dev, const void *buf_in,
err = hinic3_set_loopback_mode(nic_dev->hwdev, (u8)mode->loop_mode,
(u8)mode->loop_ctrl);
if (err == 0)
- nicif_info(nic_dev, drv, nic_dev->netdev, "Set loopback mode %u en %u succeed\n",
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Set loopback mode %u en %u succeed\n",
mode->loop_mode, mode->loop_ctrl);
return err;
@@ -417,6 +426,59 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
{
u32 pf_bw_limit;
int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
+
+ if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To set VF bandwidth rate, please use ip link cmd\n");
+ return -EINVAL;
+ }
+
+ if (!buf_in || !buf_out || in_size != sizeof(u32) ||
+ !out_size || *out_size != sizeof(u8))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_TX;
+ pf_bw_limit = *((u32 *)buf_in);
+
+ err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
+ if (err) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %u%%\n",
+ pf_bw_limit);
+ if (err < 0)
+ return err;
+ }
+
+ *((u8 *)buf_out) = (u8)err;
+
+ return 0;
+}
+
+static int set_rx_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ u32 pf_bw_limit;
+ int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
nicif_err(nic_dev, drv, nic_dev->netdev, "To set VF bandwidth rate, please use ip link cmd\n");
@@ -426,11 +488,16 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || !buf_out || in_size != sizeof(u32) || !out_size || *out_size != sizeof(u8))
return -EINVAL;
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_RX;
pf_bw_limit = *((u32 *)buf_in);
err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %d%%\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to set pf bandwidth limit to %d%%\n",
pf_bw_limit);
if (err < 0)
return err;
@@ -445,19 +512,21 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
struct hinic3_nic_io *nic_io = NULL;
+ u32 *rate_limit = (u32 *)buf_out;
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "To get VF bandwidth rate, please use ip link cmd\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To get VF bandwidth rate, please use ip link cmd\n");
return -EINVAL;
}
if (!buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(u32)) {
+ if (*out_size != sizeof(u32) * 2) { // 2:Stored in an array, TX and RX, both length are u32
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user: %d, expect: %lu\n",
- *out_size, sizeof(u32));
+ *out_size, sizeof(u32) * 2);
return -EFAULT;
}
@@ -465,8 +534,12 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!nic_io)
return -EINVAL;
- *((u32 *)buf_out) = nic_io->nic_cfg.pf_bw_limit;
+ rate_limit[HINIC3_NIC_RX] = nic_io->nic_cfg.pf_bw_rx_limit;
+ rate_limit[HINIC3_NIC_TX] = nic_io->nic_cfg.pf_bw_tx_limit;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "read rate cfg success rx rate is: %u, tx rate is : %u\n",
+ rate_limit[HINIC3_NIC_RX], rate_limit[HINIC3_NIC_TX]);
return 0;
}
@@ -477,8 +550,8 @@ static int get_sset_count(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || in_size != sizeof(u32) || !out_size ||
*out_size != sizeof(u32) || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
@@ -504,16 +577,16 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
int err;
if (!buf_in || in_size != sizeof(u32) || !out_size || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
size = sizeof(u32);
err = get_sset_count(nic_dev, buf_in, in_size, &count, &size);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Get sset count failed, ret=%d\n",
- err);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Get sset count failed, ret=%d\n", err);
return -EINVAL;
}
if (count * sizeof(*items) != *out_size) {
@@ -527,12 +600,14 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
switch (sset) {
case HINIC3_SHOW_SSET_IO_STATS:
- hinic3_get_io_stats(nic_dev, items);
+ err = hinic3_get_io_stats(nic_dev, items);
+ if (err < 0)
+ return -EINVAL;
break;
default:
- nicif_err(nic_dev, drv, nic_dev->netdev, "Unknown %u to get stats\n",
- sset);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unknown %u to get stats\n", sset);
err = -EINVAL;
break;
}
@@ -544,15 +619,18 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int i;
u8 cos_num = 0, valid_cos_bitmap = 0;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_PCP2COS) {
for (i = 0; i < NIC_DCB_UP_MAX; i++) {
- if (!(nic_dev->func_dft_cos_bitmap & BIT(qos_in->pcp2cos[i]))) {
+ if (!(dcb->func_dft_cos_bitmap &
+ BIT(qos_in->pcp2cos[i]))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- qos_in->pcp2cos[i], nic_dev->func_dft_cos_bitmap);
+ qos_in->pcp2cos[i],
+ dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -562,7 +640,8 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
}
- memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos, sizeof(qos_in->pcp2cos));
+ memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos,
+ sizeof(qos_in->pcp2cos));
wanted_dcb_cfg->pcp_user_cos_num = cos_num;
wanted_dcb_cfg->pcp_valid_cos_map = valid_cos_bitmap;
}
@@ -572,12 +651,14 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = 0;
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++) {
u8 cos = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->wanted_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ dcb->wanted_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
- if (cos >= NIC_DCB_UP_MAX || !(nic_dev->func_dft_cos_bitmap & BIT(cos))) {
+ if (cos >= NIC_DCB_UP_MAX ||
+ !(dcb->func_dft_cos_bitmap & BIT(cos))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- cos, nic_dev->func_dft_cos_bitmap);
+ cos, dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -588,8 +669,10 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- wanted_dcb_cfg->dscp2cos[i] = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->hw_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ wanted_dcb_cfg->dscp2cos[i] =
+ qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
+ dcb->hw_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
wanted_dcb_cfg->dscp_user_cos_num = cos_num;
wanted_dcb_cfg->dscp_valid_cos_map = valid_cos_bitmap;
}
@@ -601,11 +684,12 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int ret;
u8 cos_num, valid_cos_bitmap;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_TRUST) {
- if (qos_in->trust > DCB_DSCP) {
+ if (qos_in->trust > HINIC3_DCB_DSCP) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid trust=%u\n", qos_in->trust);
return -EINVAL;
@@ -615,7 +699,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
}
if (qos_in->cfg_bitmap & CMD_QOS_DEV_DFT_COS) {
- if (!(BIT(qos_in->dft_cos) & nic_dev->func_dft_cos_bitmap)) {
+ if (!(BIT(qos_in->dft_cos) & dcb->func_dft_cos_bitmap)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid dft_cos=%u\n", qos_in->dft_cos);
return -EINVAL;
@@ -628,7 +712,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
if (ret)
return ret;
- if (wanted_dcb_cfg->trust == DCB_PCP) {
+ if (wanted_dcb_cfg->trust == HINIC3_DCB_PCP) {
cos_num = wanted_dcb_cfg->pcp_user_cos_num;
valid_cos_bitmap = wanted_dcb_cfg->pcp_valid_cos_map;
} else {
@@ -636,18 +720,11 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = wanted_dcb_cfg->dscp_valid_cos_map;
}
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "DCB is on, cos num should not more than channel num:%u\n",
- nic_dev->q_params.num_qps);
- return -EOPNOTSUPP;
- }
- }
-
if (!(BIT(wanted_dcb_cfg->default_cos) & valid_cos_bitmap)) {
- nicif_info(nic_dev, drv, nic_dev->netdev, "Current default_cos=%u, change to %u\n",
- wanted_dcb_cfg->default_cos, (u8)fls(valid_cos_bitmap) - 1);
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Current default_cos=%u, change to %u\n",
+ wanted_dcb_cfg->default_cos,
+ (u8)fls(valid_cos_bitmap) - 1);
wanted_dcb_cfg->default_cos = (u8)fls(valid_cos_bitmap) - 1;
}
@@ -657,6 +734,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_dev_cfg *qos_in = buf_in;
struct hinic3_mt_qos_dev_cfg *qos_out = buf_out;
u8 i;
@@ -675,9 +753,10 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(qos_out, qos_in, sizeof(*qos_in));
qos_out->head.status = 0;
if (qos_in->op_code & MT_DCB_OPCODE_WR) {
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg,
+ memcpy(&dcb->wanted_dcb_cfg, &dcb->hw_dcb_cfg,
sizeof(struct hinic3_dcb_config));
- err = update_wanted_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg, qos_in);
+ err = update_wanted_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg,
+ qos_in);
if (err) {
qos_out->head.status = MT_EINVAL;
return 0;
@@ -687,12 +766,12 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
qos_out->head.status = MT_EIO;
} else {
- qos_out->dft_cos = nic_dev->hw_dcb_cfg.default_cos;
- qos_out->trust = nic_dev->hw_dcb_cfg.trust;
+ qos_out->dft_cos = dcb->hw_dcb_cfg.default_cos;
+ qos_out->trust = dcb->hw_dcb_cfg.trust;
for (i = 0; i < NIC_DCB_UP_MAX; i++)
- qos_out->pcp2cos[i] = nic_dev->hw_dcb_cfg.pcp2cos[i];
+ qos_out->pcp2cos[i] = dcb->hw_dcb_cfg.pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- qos_out->dscp2cos[i] = nic_dev->hw_dcb_cfg.dscp2cos[i];
+ qos_out->dscp2cos[i] = dcb->hw_dcb_cfg.dscp2cos[i];
}
return 0;
@@ -721,27 +800,17 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(dcb_out, dcb_in, sizeof(*dcb_in));
dcb_out->head.status = 0;
if (dcb_in->op_code & MT_DCB_OPCODE_WR) {
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) == dcb_in->state)
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ==
+ dcb_in->state)
return 0;
- if (dcb_in->state) {
- if (user_cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "cos num %u should not more than channel num %u\n",
- user_cos_num,
- nic_dev->q_params.num_qps);
-
- return -EOPNOTSUPP;
- }
- }
-
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? user_cos_num : 0,
+ err = hinic3_setup_cos(nic_dev->netdev,
+ dcb_in->state ? user_cos_num : 0,
netif_run);
if (err)
goto setup_cos_fail;
@@ -751,7 +820,6 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
goto vport_up_fail;
}
- rtnl_unlock();
} else {
dcb_out->state = !!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
}
@@ -759,12 +827,12 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
vport_up_fail:
- hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num,
+ netif_run);
setup_cos_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
return err;
}
@@ -772,13 +840,15 @@ setup_cos_fail:
static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_cos_cfg *cos_cfg_in = buf_in;
struct hinic3_mt_qos_cos_cfg *cos_cfg_out = buf_out;
if (!buf_in || !buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(*cos_cfg_out) || in_size != sizeof(*cos_cfg_in)) {
+ if (*out_size != sizeof(*cos_cfg_out) ||
+ in_size != sizeof(*cos_cfg_in)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
in_size, *out_size, sizeof(*cos_cfg_in));
@@ -789,9 +859,9 @@ static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
cos_cfg_out->head.status = 0;
cos_cfg_out->port_id = hinic3_physical_port_id(nic_dev->hwdev);
- cos_cfg_out->func_cos_bitmap = (u8)nic_dev->func_dft_cos_bitmap;
- cos_cfg_out->port_cos_bitmap = (u8)nic_dev->port_dft_cos_bitmap;
- cos_cfg_out->func_max_cos_num = nic_dev->cos_config_num_max;
+ cos_cfg_out->func_cos_bitmap = (u8)dcb->func_dft_cos_bitmap;
+ cos_cfg_out->port_cos_bitmap = (u8)dcb->port_dft_cos_bitmap;
+ cos_cfg_out->func_max_cos_num = dcb->cos_config_num_max;
return 0;
}
@@ -803,7 +873,13 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
intr_num = hinic3_intr_num(nic_dev->hwdev);
- if (!buf_out || !out_size || *out_size != sizeof(u16)) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != sizeof(u16)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(u16));
@@ -817,20 +893,27 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
static int get_netdev_name(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- if (!buf_out || !out_size || *out_size != IFNAMSIZ) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != IFNAMSIZ) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %u\n",
*out_size, IFNAMSIZ);
return -EFAULT;
}
- strlcpy(buf_out, nic_dev->netdev->name, IFNAMSIZ);
+ strscpy(buf_out, nic_dev->netdev->name, IFNAMSIZ);
return 0;
}
-static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
int *tx_timeout = buf_out;
@@ -839,7 +922,8 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (*out_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, out_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, out_size: %u, expect: %lu\n",
*out_size, sizeof(int));
return -EINVAL;
}
@@ -849,8 +933,9 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return 0;
}
-static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
const int *tx_timeout = buf_in;
@@ -859,13 +944,15 @@ static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (in_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, in_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, in_size: %u, expect: %lu\n",
in_size, sizeof(int));
return -EINVAL;
}
net_dev->watchdog_timeo = *tx_timeout * HZ;
- nicif_info(nic_dev, drv, net_dev, "Set tx timeout check period to %ds\n", *tx_timeout);
+ nicif_info(nic_dev, drv, net_dev,
+ "Set tx timeout check period to %ds\n", *tx_timeout);
return 0;
}
@@ -891,6 +978,34 @@ static int get_xsfp_present(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
}
+static int get_xsfp_tlv_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct drv_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info = buf_out;
+ const struct mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req = buf_in;
+ int err;
+
+ if ((buf_in == NULL) || (buf_out == NULL) || (out_size == NULL))
+ return -EINVAL;
+
+ if (*out_size != sizeof(*sfp_tlv_info) ||
+ in_size != sizeof(*sfp_tlv_info_req)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
+ in_size, *out_size, sizeof(*sfp_tlv_info));
+ return -EINVAL;
+ }
+
+ err = hinic3_get_sfp_tlv_info(nic_dev->hwdev,
+ sfp_tlv_info, sfp_tlv_info_req);
+ if (err != 0) {
+ sfp_tlv_info->head.status = MT_EIO;
+ return 0;
+ }
+
+ return 0;
+}
+
static int get_xsfp_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
@@ -928,7 +1043,7 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{GET_LOOPBACK_MODE, get_loopback_mode},
{SET_LOOPBACK_MODE, set_loopback_mode},
{SET_LINK_MODE, set_link_mode},
- {SET_PF_BW_LIMIT, set_pf_bw_limit},
+ {SET_TX_PF_BW_LIMIT, set_pf_bw_limit},
{GET_PF_BW_LIMIT, get_pf_bw_limit},
{GET_SSET_COUNT, get_sset_count},
{GET_SSET_ITEMS, get_sset_stats},
@@ -940,17 +1055,22 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{SET_TX_TIMEOUT, set_netdev_tx_timeout},
{GET_XSFP_PRESENT, get_xsfp_present},
{GET_XSFP_INFO, get_xsfp_info},
+ {GET_XSFP_INFO_COMP_CMIS, get_xsfp_tlv_info},
+ {SET_RX_PF_BW_LIMIT, set_rx_pf_bw_limit}
};
static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
u32 cmd, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(nic_driv_module_cmd_handle) /
- sizeof(nic_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(nic_driv_module_cmd_handle) /
+ sizeof(nic_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type = (enum driver_cmd_type)cmd;
int err = 0;
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_lock();
+
mutex_lock(&nic_dev->nic_mutex);
for (index = 0; index < num_cmds; index++) {
if (cmd_type ==
@@ -963,6 +1083,9 @@ static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
}
mutex_unlock(&nic_dev->nic_mutex);
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_unlock();
+
if (index == num_cmds) {
pr_err("Can't find callback for %d\n", cmd_type);
return -EINVAL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
index a1fb4af..aa53c19 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
@@ -24,82 +24,80 @@
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_user_cos_num;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_user_cos_num;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_user_cos_num;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_user_cos_num;
return 0;
}
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_valid_cos_map;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_valid_cos_map;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_valid_cos_map;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_valid_cos_map;
return 0;
}
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
- u8 i, remainder, num_sq_per_cos, cur_cos_num = 0;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ struct hinic3_dcb_config *wanted_dcb_cfg =
+ &nic_dev->dcb->wanted_dcb_cfg;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
+ u8 cos_qp_num, cos_qp_offset = 0;
+ u8 i, remainder, num_qp_per_cos;
- if (num_cos == 0)
- return;
-
- num_sq_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
- if (num_sq_per_cos == 0)
+ if (num_cos == 0 || nic_dev->q_params.num_qps == 0)
return;
- remainder = nic_dev->q_params.num_qps % num_sq_per_cos;
+ num_qp_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
+ remainder = nic_dev->q_params.num_qps % num_cos;
- memset(dcb_cfg->cos_qp_offset, 0, sizeof(dcb_cfg->cos_qp_offset));
- memset(dcb_cfg->cos_qp_num, 0, sizeof(dcb_cfg->cos_qp_num));
+ memset(hw_dcb_cfg->cos_qp_offset, 0, sizeof(hw_dcb_cfg->cos_qp_offset));
+ memset(hw_dcb_cfg->cos_qp_num, 0, sizeof(hw_dcb_cfg->cos_qp_num));
for (i = 0; i < PCP_MAX_UP; i++) {
if (BIT(i) & valid_cos_map) {
- u8 cos_qp_num = num_sq_per_cos;
- u8 cos_qp_offset = (u8)(cur_cos_num * num_sq_per_cos);
-
- if (cur_cos_num < remainder) {
- cos_qp_num++;
- cos_qp_offset += cur_cos_num;
- } else {
- cos_qp_offset += remainder;
- }
-
- cur_cos_num++;
- valid_cos_map -= (u8)BIT(i);
+ cos_qp_num = num_qp_per_cos + ((remainder > 0) ?
+ (remainder--, 1) : 0);
- dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
- dcb_cfg->cos_qp_num[i] = cos_qp_num;
+ hw_dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
+ hw_dcb_cfg->cos_qp_num[i] = cos_qp_num;
hinic3_info(nic_dev, drv, "cos %u, cos_qp_offset=%u cos_qp_num=%u\n",
i, cos_qp_offset, cos_qp_num);
+
+ cos_qp_offset += cos_qp_num;
+ valid_cos_map -= (int)BIT(i);
}
}
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_offset, dcb_cfg->cos_qp_offset,
- sizeof(dcb_cfg->cos_qp_offset));
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_num, dcb_cfg->cos_qp_num,
- sizeof(dcb_cfg->cos_qp_num));
+ memcpy(wanted_dcb_cfg->cos_qp_offset, hw_dcb_cfg->cos_qp_offset,
+ sizeof(hw_dcb_cfg->cos_qp_offset));
+ memcpy(wanted_dcb_cfg->cos_qp_num, hw_dcb_cfg->cos_qp_num,
+ sizeof(hw_dcb_cfg->cos_qp_num));
}
void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
u8 i;
u16 start_qid, q_num;
hinic3_set_txq_cos(nic_dev, 0, nic_dev->q_params.num_qps,
- nic_dev->hw_dcb_cfg.default_cos);
+ hw_dcb_cfg->default_cos);
if (!dcb_en)
return;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- q_num = (u16)nic_dev->hw_dcb_cfg.cos_qp_num[i];
+ q_num = (u16)hw_dcb_cfg->cos_qp_num[i];
if (q_num) {
- start_qid = (u16)nic_dev->hw_dcb_cfg.cos_qp_offset[i];
+ start_qid = (u16)hw_dcb_cfg->cos_qp_offset[i];
hinic3_set_txq_cos(nic_dev, start_qid, q_num, i);
hinic3_info(nic_dev, drv, "update tx db cos, start_qid %u, q_num=%u cos=%u\n",
@@ -110,30 +108,29 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ struct hinic3_dcb_config *hw_dcb_cfg = &dcb->hw_dcb_cfg;
struct hinic3_dcb_state dcb_state = {0};
u8 i;
int err;
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- /* VF does not support DCB, use the default cos */
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
-
- return 0;
- }
+ u32 pcp2cos_size = sizeof(dcb_state.pcp2cos);
+ u32 dscp2cos_size = sizeof(dcb_state.dscp2cos);
dcb_state.dcb_on = dcb_en;
- dcb_state.default_cos = dcb_cfg->default_cos;
- dcb_state.trust = dcb_cfg->trust;
+ dcb_state.default_cos = hw_dcb_cfg->default_cos;
+ dcb_state.trust = hw_dcb_cfg->trust;
if (dcb_en) {
for (i = 0; i < NIC_DCB_COS_MAX; i++)
- dcb_state.pcp2cos[i] = dcb_cfg->pcp2cos[i];
+ dcb_state.pcp2cos[i] = hw_dcb_cfg->pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- dcb_state.dscp2cos[i] = dcb_cfg->dscp2cos[i];
+ dcb_state.dscp2cos[i] = hw_dcb_cfg->dscp2cos[i];
} else {
- memset(dcb_state.pcp2cos, dcb_cfg->default_cos, sizeof(dcb_state.pcp2cos));
- memset(dcb_state.dscp2cos, dcb_cfg->default_cos, sizeof(dcb_state.dscp2cos));
+ memset(dcb_state.pcp2cos, hw_dcb_cfg->default_cos,
+ pcp2cos_size);
+ memset(dcb_state.dscp2cos, hw_dcb_cfg->default_cos,
+ dscp2cos_size);
}
err = hinic3_set_dcb_state(nic_dev->hwdev, &dcb_state);
@@ -143,7 +140,7 @@ static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
return err;
}
-static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
int err;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
@@ -169,11 +166,13 @@ static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
goto rx_configure_fail;
}
- if (dcb_en)
+ if (dcb_en) {
set_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
- else
+ set_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ } else {
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
-
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ }
return 0;
rx_configure_fail:
hinic3_set_tx_cos_state(nic_dev, dcb_en ? 0 : 1);
@@ -188,6 +187,7 @@ set_tx_cos_fail:
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err;
if (cos && test_bit(HINIC3_SAME_RXTX, &nic_dev->flags)) {
@@ -195,9 +195,10 @@ int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
return -EOPNOTSUPP;
}
- if (cos > nic_dev->cos_config_num_max) {
- nicif_err(nic_dev, drv, netdev, "Invalid num_tc: %u, max cos: %u\n",
- cos, nic_dev->cos_config_num_max);
+ if (cos > dcb->cos_config_num_max) {
+ nicif_err(nic_dev, drv, netdev,
+ "Invalid num_tc: %u, max cos: %u\n",
+ cos, dcb->cos_config_num_max);
return -EINVAL;
}
@@ -223,36 +224,48 @@ static u8 get_cos_num(u8 hw_valid_cos_bitmap)
static void hinic3_sync_dcb_cfg(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dcb_config *dcb_cfg)
{
- struct hinic3_dcb_config *hw_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
- memcpy(hw_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(hw_dcb_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
}
static int init_default_dcb_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *dcb_cfg)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 i, hw_dft_cos_map, port_cos_bitmap, dscp_ind;
int err;
+ int is_in_kexec;
- err = hinic3_cos_valid_bitmap(nic_dev->hwdev, &hw_dft_cos_map, &port_cos_bitmap);
+ err = hinic3_cos_valid_bitmap(nic_dev->hwdev,
+ &hw_dft_cos_map, &port_cos_bitmap);
if (err) {
hinic3_err(nic_dev, drv, "None cos supported\n");
return -EFAULT;
}
- nic_dev->func_dft_cos_bitmap = hw_dft_cos_map;
- nic_dev->port_dft_cos_bitmap = port_cos_bitmap;
- nic_dev->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+ is_in_kexec = vram_get_kexec_flag();
- dcb_cfg->trust = DCB_PCP;
- dcb_cfg->pcp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->dscp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
+ dcb->func_dft_cos_bitmap = hw_dft_cos_map;
+ dcb->port_dft_cos_bitmap = port_cos_bitmap;
+
+ dcb->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+
+ if (is_in_kexec == 0) {
+ dcb_cfg->trust = HINIC3_DCB_PCP;
+ dcb_cfg->default_cos = (u8)fls(dcb->func_dft_cos_bitmap) - 1;
+ } else {
+ dcb_cfg->trust = nic_dev->dcb->hw_dcb_cfg.trust;
+ dcb_cfg->default_cos = nic_dev->dcb->hw_dcb_cfg.default_cos;
+ }
+ dcb_cfg->pcp_user_cos_num = dcb->cos_config_num_max;
+ dcb_cfg->dscp_user_cos_num = dcb->cos_config_num_max;
dcb_cfg->pcp_valid_cos_map = hw_dft_cos_map;
dcb_cfg->dscp_valid_cos_map = hw_dft_cos_map;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i) ? i : dcb_cfg->default_cos;
+ dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i)
+ ? i : (u8)fls(dcb->func_dft_cos_bitmap) - 1;
for (dscp_ind = 0; dscp_ind < NIC_DCB_COS_MAX; dscp_ind++)
dcb_cfg->dscp2cos[i * NIC_DCB_DSCP_NUM + dscp_ind] = dcb_cfg->pcp2cos[i];
}
@@ -276,58 +289,121 @@ int hinic3_configure_dcb(struct net_device *netdev)
int err;
err = hinic3_sync_dcb_state(nic_dev->hwdev, 1,
- test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)
+ ? 1 : 0);
if (err) {
hinic3_err(nic_dev, drv, "Set dcb state failed\n");
return err;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ hinic3_sync_dcb_cfg(nic_dev, &nic_dev->dcb->wanted_dcb_cfg);
else
hinic3_dcb_reset_hw_config(nic_dev);
return 0;
}
+static int hinic3_dcb_alloc(struct hinic3_nic_dev *nic_dev)
+{
+ u16 func_id;
+ int is_use_vram;
+ int ret;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ ret = snprintf(nic_dev->dcb_name, VRAM_NAME_MAX_LEN,
+ "%s%u%s", VRAM_CQM_GLB_FUNC_BASE, func_id,
+ VRAM_NIC_DCB);
+ if (ret < 0) {
+ hinic3_err(nic_dev, drv, "Nic dcb snprintf failed, ret:%d.\n", ret);
+ return ret;
+ }
+
+ nic_dev->dcb = (struct hinic3_dcb *)hi_vram_kalloc(nic_dev->dcb_name,
+ sizeof(*nic_dev->dcb));
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to vram alloc dcb.\n");
+ return -EFAULT;
+ }
+ } else {
+ nic_dev->dcb = kzalloc(sizeof(*nic_dev->dcb), GFP_KERNEL);
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to create dcb.\n");
+ return -EFAULT;
+ }
+ }
+
+ return 0;
+}
+
+static void hinic3_dcb_free(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram)
+ hi_vram_kfree((void *)nic_dev->dcb, nic_dev->dcb_name, sizeof(*nic_dev->dcb));
+ else
+ kfree(nic_dev->dcb);
+ nic_dev->dcb = NULL;
+}
+
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
+ hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+
+ hinic3_dcb_free(nic_dev);
+}
+
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = NULL;
int err;
u8 dcb_en = test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0;
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- return hinic3_set_tx_cos_state(nic_dev, dcb_en);
+ err = hinic3_dcb_alloc(nic_dev);
+ if (err != 0) {
+ hinic3_err(nic_dev, drv, "Dcb alloc failed.\n");
+ return err;
+ }
- err = init_default_dcb_cfg(nic_dev, dcb_cfg);
+ hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ err = init_default_dcb_cfg(nic_dev, hw_dcb_cfg);
if (err) {
- hinic3_err(nic_dev, drv, "Initialize dcb configuration failed\n");
+ hinic3_err(nic_dev, drv,
+ "Initialize dcb configuration failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&nic_dev->dcb->wanted_dcb_cfg, hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
hinic3_info(nic_dev, drv, "Support num cos %u, default cos %u\n",
- nic_dev->cos_config_num_max, dcb_cfg->default_cos);
+ nic_dev->dcb->cos_config_num_max, hw_dcb_cfg->default_cos);
err = hinic3_set_tx_cos_state(nic_dev, dcb_en);
if (err) {
hinic3_err(nic_dev, drv, "Set tx cos state failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- sema_init(&nic_dev->dcb_sem, 1);
-
return 0;
}
-static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dcb_config *dcb_cfg)
+static int change_qos_cfg(struct hinic3_nic_dev *nic_dev,
+ const struct hinic3_dcb_config *dcb_cfg)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err = 0;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags)) {
+ if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags)) {
nicif_warn(nic_dev, drv, netdev,
"Cos_up map setting in inprocess, please try again later\n");
return -EFAULT;
@@ -337,40 +413,44 @@ static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dc
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
- clear_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags);
+ clear_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags);
return err;
}
int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err, rollback_err;
u8 netif_run = 0;
struct hinic3_dcb_config old_dcb_cfg;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- memcpy(&old_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&old_dcb_cfg, &dcb->hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
- if (!memcmp(&nic_dev->wanted_dcb_cfg, &old_dcb_cfg, sizeof(struct hinic3_dcb_config))) {
+ if (!memcmp(&dcb->wanted_dcb_cfg, &old_dcb_cfg,
+ sizeof(struct hinic3_dcb_config))) {
nicif_info(nic_dev, drv, nic_dev->netdev,
"Same valid up bitmap, don't need to change anything\n");
return 0;
}
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = change_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ err = change_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Set cos_up map to hw failed\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Set cos_up map to hw failed\n");
goto change_qos_cfg_fail;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- err = hinic3_setup_cos(nic_dev->netdev, user_cos_num, netif_run);
+ err = hinic3_setup_cos(nic_dev->netdev,
+ user_cos_num, netif_run);
if (err)
goto set_err;
}
@@ -381,13 +461,12 @@ int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
goto vport_up_fail;
}
- rtnl_unlock();
-
return 0;
vport_up_fail:
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_setup_cos(nic_dev->netdev, user_cos_num ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, user_cos_num
+ ? 0 : user_cos_num, netif_run);
set_err:
rollback_err = change_qos_cfg(nic_dev, &old_dcb_cfg);
@@ -399,7 +478,5 @@ change_qos_cfg_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
-
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
index 7987f56..e0b35cb 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
@@ -24,11 +24,6 @@ struct hinic3_tc_cfg {
u16 rsvd;
};
-enum HINIC3_DCB_TRUST {
- DCB_PCP,
- DCB_DSCP,
-};
-
#define PCP_MAX_UP 8
#define DSCP_MAC_UP 64
#define DBG_DFLT_DSCP_VAL 0xFF
@@ -50,6 +45,7 @@ struct hinic3_dcb_config {
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev);
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev);
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev);
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev);
void hinic3_dcb_reset_hw_config(struct hinic3_nic_dev *nic_dev);
int hinic3_configure_dcb(struct net_device *netdev);
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run);
@@ -75,4 +71,5 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos);
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev);
int hinic3_vport_up(struct hinic3_nic_dev *nic_dev);
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
index 2b3561e..548d67d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
@@ -44,9 +44,9 @@ static void hinic3_get_drvinfo(struct net_device *netdev,
u8 mgmt_ver[HINIC3_MGMT_VERSION_MAX_LEN] = {0};
int err;
- strlcpy(info->driver, HINIC3_NIC_DRV_NAME, sizeof(info->driver));
- strlcpy(info->version, HINIC3_NIC_DRV_VERSION, sizeof(info->version));
- strlcpy(info->bus_info, pci_name(pdev), sizeof(info->bus_info));
+ strscpy(info->driver, HINIC3_NIC_DRV_NAME, sizeof(info->driver));
+ strscpy(info->version, HINIC3_NIC_DRV_VERSION, sizeof(info->version));
+ strscpy(info->bus_info, pci_name(pdev), sizeof(info->bus_info));
err = hinic3_get_mgmt_version(nic_dev->hwdev, mgmt_ver,
HINIC3_MGMT_VERSION_MAX_LEN,
@@ -123,10 +123,15 @@ reset_err:
return err;
}
+#ifdef HAVE_ETHTOOL_RINGPARAM_EXTACK
static void hinic3_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring,
struct kernel_ethtool_ringparam *kernel_ring,
struct netlink_ext_ack *extack)
+#else
+static void hinic3_get_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+#endif
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
@@ -176,10 +181,15 @@ static int check_ringparam_valid(struct net_device *netdev,
return 0;
}
+#ifdef HAVE_ETHTOOL_RINGPARAM_EXTACK
static int hinic3_set_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring,
struct kernel_ethtool_ringparam *kernel_ring,
struct netlink_ext_ack *extack)
+#else
+static int hinic3_set_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+#endif
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic3_dyna_txrxq_params q_params = {0};
@@ -273,7 +283,7 @@ static int get_coalesce(struct net_device *netdev,
static int set_queue_coalesce(struct hinic3_nic_dev *nic_dev, u16 q_id,
struct hinic3_intr_coal_info *coal)
{
- struct hinic3_intr_coal_info *intr_coal;
+ struct hinic3_intr_coal_info *intr_coal = NULL;
struct interrupt_info info = {0};
struct net_device *netdev = nic_dev->netdev;
int err;
@@ -367,24 +377,11 @@ static int is_coalesce_exceed_limit(struct net_device *netdev,
return 0;
}
-static int is_coalesce_legal(struct net_device *netdev,
- const struct ethtool_coalesce *coal)
+static int is_coalesce_allowed_change(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct ethtool_coalesce tmp_coal = {0};
- int err;
-
- if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
- nicif_err(nic_dev, drv, netdev,
- "tx-usecs must be equal to rx-usecs\n");
- return -EINVAL;
- }
-
- if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
- nicif_err(nic_dev, drv, netdev,
- "tx-frames must be equal to rx-frames\n");
- return -EINVAL;
- }
tmp_coal.cmd = coal->cmd;
tmp_coal.rx_coalesce_usecs = coal->rx_coalesce_usecs;
@@ -409,6 +406,31 @@ static int is_coalesce_legal(struct net_device *netdev,
return -EOPNOTSUPP;
}
+ return 0;
+}
+
+static int is_coalesce_legal(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-usecs must be equal to rx-usecs\n");
+ return -EINVAL;
+ }
+
+ if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-frames must be equal to rx-frames\n");
+ return -EINVAL;
+ }
+
+ err = is_coalesce_allowed_change(netdev, coal);
+ if (err)
+ return err;
+
err = is_coalesce_exceed_limit(netdev, coal);
if (err)
return err;
@@ -491,19 +513,10 @@ static int set_hw_coal_param(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static int set_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *coal, u16 queue)
+static void check_coalesce_align(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
- struct hinic3_intr_coal_info intr_coal = {0};
- struct hinic3_intr_coal_info *ori_intr_coal = NULL;
- u32 last_adaptive_rx;
- char obj_str[32] = {0};
- int err = 0;
-
- err = is_coalesce_legal(netdev, coal);
- if (err)
- return err;
CHECK_COALESCE_ALIGN(coal, rx_coalesce_usecs, COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal, rx_max_coalesced_frames,
@@ -516,6 +529,14 @@ static int set_coalesce(struct net_device *netdev,
COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal, rx_max_coalesced_frames_low,
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int check_coalesce_change(struct net_device *netdev,
+ u16 queue, struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info *ori_intr_coal = NULL;
+ char obj_str[32] = {0};
if (queue == COALESCE_ALL_QUEUE) {
ori_intr_coal = &nic_dev->intr_coalesce[0];
@@ -524,6 +545,7 @@ static int set_coalesce(struct net_device *netdev,
ori_intr_coal = &nic_dev->intr_coalesce[queue];
snprintf(obj_str, sizeof(obj_str), "for queue %u", queue);
}
+
CHECK_COALESCE_CHANGED(coal, rx_coalesce_usecs, COALESCE_TIMER_CFG_UNIT,
ori_intr_coal->coalesce_timer_cfg, obj_str);
CHECK_COALESCE_CHANGED(coal, rx_max_coalesced_frames,
@@ -545,28 +567,52 @@ static int set_coalesce(struct net_device *netdev,
CHECK_COALESCE_CHANGED(coal, rx_max_coalesced_frames_low,
COALESCE_PENDING_LIMIT_UNIT,
ori_intr_coal->rx_pending_limt_low, obj_str);
+ return 0;
+}
- intr_coal.coalesce_timer_cfg =
+static void init_intr_coal_params(struct hinic3_intr_coal_info *intr_coal,
+ struct ethtool_coalesce *coal)
+{
+ intr_coal->coalesce_timer_cfg =
(u8)(coal->rx_coalesce_usecs / COALESCE_TIMER_CFG_UNIT);
- intr_coal.pending_limt = (u8)(coal->rx_max_coalesced_frames /
- COALESCE_PENDING_LIMIT_UNIT);
+ intr_coal->pending_limt = (u8)(coal->rx_max_coalesced_frames /
+ COALESCE_PENDING_LIMIT_UNIT);
- last_adaptive_rx = nic_dev->adaptive_rx_coal;
- nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
-
- intr_coal.pkt_rate_high = coal->pkt_rate_high;
- intr_coal.rx_usecs_high =
+ intr_coal->pkt_rate_high = coal->pkt_rate_high;
+ intr_coal->rx_usecs_high =
(u8)(coal->rx_coalesce_usecs_high / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_high =
+ intr_coal->rx_pending_limt_high =
(u8)(coal->rx_max_coalesced_frames_high /
COALESCE_PENDING_LIMIT_UNIT);
- intr_coal.pkt_rate_low = coal->pkt_rate_low;
- intr_coal.rx_usecs_low =
+ intr_coal->pkt_rate_low = coal->pkt_rate_low;
+ intr_coal->rx_usecs_low =
(u8)(coal->rx_coalesce_usecs_low / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_low =
+ intr_coal->rx_pending_limt_low =
(u8)(coal->rx_max_coalesced_frames_low /
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal, u16 queue)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info intr_coal = {0};
+ u32 last_adaptive_rx;
+ int err = 0;
+
+ err = is_coalesce_legal(netdev, coal);
+ if (err)
+ return err;
+
+ check_coalesce_align(netdev, coal);
+
+ check_coalesce_change(netdev, queue, coal);
+
+ init_intr_coal_params(&intr_coal, coal);
+
+ last_adaptive_rx = nic_dev->adaptive_rx_coal;
+ nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
/* coalesce timer or pending set to zero will disable coalesce */
if (!nic_dev->adaptive_rx_coal &&
@@ -588,18 +634,28 @@ static int set_coalesce(struct net_device *netdev,
return set_hw_coal_param(nic_dev, &intr_coal, queue);
}
+#ifdef HAVE_ETHTOOL_COALESCE_EXTACK
static int hinic3_get_coalesce(struct net_device *netdev,
struct ethtool_coalesce *coal,
struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack)
+#else
+static int hinic3_get_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
+#endif
{
return get_coalesce(netdev, coal, COALESCE_ALL_QUEUE);
}
+#ifdef HAVE_ETHTOOL_COALESCE_EXTACK
static int hinic3_set_coalesce(struct net_device *netdev,
struct ethtool_coalesce *coal,
struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack)
+#else
+static int hinic3_set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
+#endif
{
return set_coalesce(netdev, coal, COALESCE_ALL_QUEUE);
}
@@ -762,6 +818,14 @@ static int hinic3_get_module_info(struct net_device *netdev,
modinfo->type = ETH_MODULE_SFF_8636;
modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
break;
+ case MODULE_TYPE_DSFP:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
+ case MODULE_TYPE_QSFP_CMIS:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
default:
nicif_warn(nic_dev, drv, netdev,
"Optical module unknown: 0x%x\n", sfp_type);
@@ -784,6 +848,9 @@ static int hinic3_get_module_eeprom(struct net_device *netdev,
memset(data, 0, ee->len);
err = hinic3_get_sfp_eeprom(nic_dev->hwdev, (u8 *)sfp_data, ee->len);
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(nic_dev->hwdev, (u8 *)sfp_data, sizeof(sfp_data));
+
if (err)
return err;
@@ -814,7 +881,7 @@ static u32 hinic3_get_priv_flags(struct net_device *netdev)
return priv_flags;
}
-int hinic3_set_rxq_recovery_flag(struct net_device *netdev, u32 priv_flags)
+static int hinic3_set_rxq_recovery_flag(struct net_device *netdev, u32 priv_flags)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
@@ -844,12 +911,14 @@ static int hinic3_set_symm_rss_flag(struct net_device *netdev, u32 priv_flags)
if (priv_flags & HINIC3_PRIV_FLAGS_SYMM_RSS) {
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, netdev, "Failed to open Symmetric RSS while DCB is enabled\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to open Symmetric RSS while DCB is enabled\n");
return -EOPNOTSUPP;
}
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, netdev, "Failed to open Symmetric RSS while RSS is disabled\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to open Symmetric RSS while RSS is disabled\n");
return -EOPNOTSUPP;
}
@@ -1129,10 +1198,61 @@ static void hinic3_diag_test(struct net_device *netdev,
hinic3_lp_test(netdev, eth_test, data, 0);
}
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+static int hinic3_get_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u8 advertised_fec = 0;
+ u8 supported_fec = 0;
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_GFECPARAM) {
+ nicif_err(nic_dev, drv, netdev,
+ "get fecparam cmd err.exp:0x%x,real:0x%x\n",
+ ETHTOOL_GFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = get_fecparam(nic_dev->hwdev, &advertised_fec, &supported_fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Get fec param failed\n");
+ return err;
+ }
+ fecparam->active_fec = (u32)advertised_fec;
+ fecparam->fec = (u32)supported_fec;
+
+ nicif_info(nic_dev, drv, netdev, "Get fec param success\n");
+ return 0;
+}
+
+static int hinic3_set_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_SFECPARAM) {
+ nicif_err(nic_dev, drv, netdev, "Set fecparam cmd err.exp:0x%x,real:0x%x\n", ETHTOOL_SFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = set_fecparam(nic_dev->hwdev, (u8)fecparam->fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Set fec param failed\n");
+ return err;
+ }
+
+ nicif_info(nic_dev, drv, netdev, "Set fec param success\n");
+ return 0;
+}
+#endif
+
static const struct ethtool_ops hinic3_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1179,6 +1299,11 @@ static const struct ethtool_ops hinic3_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
+
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
@@ -1239,7 +1364,10 @@ static const struct ethtool_ops_ext hinic3_ethtool_ops_ext = {
static const struct ethtool_ops hinic3vf_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1266,6 +1394,11 @@ static const struct ethtool_ops hinic3vf_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
+
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
index de59b76..ec89f62 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
@@ -24,11 +24,24 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
-#define FPGA_PORT_COUNTER 0
-#define EVB_PORT_COUNTER 1
-u16 mag_support_mode = EVB_PORT_COUNTER;
-module_param(mag_support_mode, ushort, 0444);
-MODULE_PARM_DESC(mag_support_mode, "Set mag port counter support mode, 0:FPGA 1:EVB, default is 1");
+#define HINIC_SET_LINK_STR_LEN 128
+#define HINIC_ETHTOOL_FEC_INFO_LEN 6
+#define HINIC_SUPPORTED_FEC_CMD 0
+#define HINIC_ADVERTISED_FEC_CMD 1
+
+struct hinic3_ethtool_fec {
+ u8 hinic_fec_offset;
+ u8 ethtool_bit_offset;
+};
+
+static struct hinic3_ethtool_fec hinic3_ethtool_fec_info[HINIC_ETHTOOL_FEC_INFO_LEN] = {
+ {PORT_FEC_NOT_SET, 0xFF}, /* The ethtool does not have the corresponding enumeration variable */
+ {PORT_FEC_RSFEC, 0x32}, /* ETHTOOL_LINK_MODE_FEC_RS_BIT */
+ {PORT_FEC_BASEFEC, 0x33}, /* ETHTOOL_LINK_MODE_FEC_BASER_BIT */
+ {PORT_FEC_NOFEC, 0x31}, /* ETHTOOL_LINK_MODE_FEC_NONE_BIT */
+ {PORT_FEC_LLRSFEC, 0x4A}, /* ETHTOOL_LINK_MODE_FEC_LLRS_BIT: Available only in later versions */
+ {PORT_FEC_AUTO, 0XFF} /* The ethtool does not have the corresponding enumeration variable */
+};
struct hinic3_stats {
char name[ETH_GSTRING_LEN];
@@ -36,6 +49,20 @@ struct hinic3_stats {
int offset;
};
+struct hinic3_netdev_link_count_str {
+ u64 link_down_events_phy;
+};
+
+#define HINIC3_NETDEV_LINK_COUNT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic3_netdev_link_count_str, _stat_item), \
+ .offset = offsetof(struct hinic3_netdev_link_count_str, _stat_item) \
+}
+
+static struct hinic3_stats hinic3_netdev_link_count[] = {
+ HINIC3_NETDEV_LINK_COUNT(link_down_events_phy),
+};
+
#define HINIC3_NETDEV_STAT(_stat_item) { \
.name = #_stat_item, \
.size = FIELD_SIZEOF(struct rtnl_link_stats64, _stat_item), \
@@ -94,7 +121,6 @@ static struct hinic3_stats hinic3_nic_dev_stats_extern[] = {
.offset = offsetof(struct hinic3_txq_stats, _stat_item) \
}
-/*lint -save -e786*/
static struct hinic3_stats hinic3_rx_queue_stats[] = {
HINIC3_RXQ_STAT(packets),
HINIC3_RXQ_STAT(bytes),
@@ -135,8 +161,6 @@ static struct hinic3_stats hinic3_tx_queue_stats_extern[] = {
HINIC3_TXQ_STAT(rsvd2),
};
-/*lint -restore*/
-
#define HINIC3_FUNC_STAT(_stat_item) { \
.name = #_stat_item, \
.size = FIELD_SIZEOF(struct hinic3_vport_stats, _stat_item), \
@@ -260,49 +284,22 @@ static struct hinic3_stats hinic3_port_stats[] = {
HINIC3_PORT_STAT(mac_rx_unfilter_pkt_num),
};
+#define HINIC3_RSFEC_STAT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct mag_cmd_rsfec_stats, _stat_item), \
+ .offset = offsetof(struct mag_cmd_rsfec_stats, _stat_item) \
+}
+
+static struct hinic3_stats g_hinic3_rsfec_stats[] = {
+ HINIC3_RSFEC_STAT(rx_err_lane_phy),
+};
+
#define HINIC3_FGPA_PORT_STAT(_stat_item) { \
.name = #_stat_item, \
.size = FIELD_SIZEOF(struct hinic3_phy_fpga_port_stats, _stat_item), \
.offset = offsetof(struct hinic3_phy_fpga_port_stats, _stat_item) \
}
-static struct hinic3_stats g_hinic3_fpga_port_stats[] = {
- HINIC3_FGPA_PORT_STAT(mac_rx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_under_frame_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_frag_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_crc_error_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_length_err_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_pause_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_unknown_mac_frame_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_underrun_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_pause_pkts_port),
-};
-
static char g_hinic_priv_flags_strings[][ETH_GSTRING_LEN] = {
"Symmetric-RSS",
"Force-Link-up",
@@ -313,12 +310,12 @@ u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev)
{
u32 count;
- count = ARRAY_LEN(hinic3_nic_dev_stats) +
+ count = (u32)(ARRAY_LEN(hinic3_nic_dev_stats) +
ARRAY_LEN(hinic3_nic_dev_stats_extern) +
(ARRAY_LEN(hinic3_tx_queue_stats) +
ARRAY_LEN(hinic3_tx_queue_stats_extern) +
ARRAY_LEN(hinic3_rx_queue_stats) +
- ARRAY_LEN(hinic3_rx_queue_stats_extern)) * nic_dev->max_qps;
+ ARRAY_LEN(hinic3_rx_queue_stats_extern)) * nic_dev->max_qps);
return count;
}
@@ -342,46 +339,81 @@ u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev)
} \
} while (0)
-#define QUEUE_STATS_PACK(items, item_idx, array, stats_ptr, qid) do { \
- int j; \
- for (j = 0; j < ARRAY_LEN(array); j++) { \
- memcpy((items)[item_idx].name, (array)[j].name, \
- HINIC3_SHOW_ITEM_LEN); \
- snprintf((items)[item_idx].name, HINIC3_SHOW_ITEM_LEN, \
- (array)[j].name, (qid)); \
- (items)[item_idx].hexadecimal = 0; \
- (items)[item_idx].value = \
- GET_VALUE_OF_PTR((array)[j].size, \
- (char *)(stats_ptr) + (array)[j].offset); \
- (item_idx)++; \
- } \
-} while (0)
+int hinic3_rx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat, struct hinic3_rxq_stats *rxq_stats, u16 qid)
+{
+ int ret;
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
+ ret = snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
+ if (ret < 0)
+ return -EINVAL;
+
+ item->hexadecimal = 0;
+ item->value = GET_VALUE_OF_PTR(stat->size, (char *)(rxq_stats) + stat->offset);
+
+ return 0;
+}
+
+int hinic3_tx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat, struct hinic3_txq_stats *txq_stats, u16 qid)
+{
+ int ret;
+
+ ret = snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
+ if (ret < 0)
+ return -EINVAL;
+
+ item->hexadecimal = 0;
+ item->value = GET_VALUE_OF_PTR(stat->size, (char *)(txq_stats) + stat->offset);
+
+ return 0;
+}
+
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
{
struct hinic3_show_item *items = stats;
int item_idx = 0;
u16 qid;
+ int idx;
+ int ret;
DEV_STATS_PACK(items, item_idx, hinic3_nic_dev_stats, &nic_dev->stats);
- DEV_STATS_PACK(items, item_idx, hinic3_nic_dev_stats_extern,
- &nic_dev->stats);
+ DEV_STATS_PACK(items, item_idx, hinic3_nic_dev_stats_extern, &nic_dev->stats);
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- QUEUE_STATS_PACK(items, item_idx, hinic3_tx_queue_stats,
- &nic_dev->txqs[qid].txq_stats, qid);
- QUEUE_STATS_PACK(items, item_idx, hinic3_tx_queue_stats_extern,
- &nic_dev->txqs[qid].txq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++], &hinic3_tx_queue_stats[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats_extern); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++], &hinic3_tx_queue_stats_extern[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
}
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- QUEUE_STATS_PACK(items, item_idx, hinic3_rx_queue_stats,
- &nic_dev->rxqs[qid].rxq_stats, qid);
- QUEUE_STATS_PACK(items, item_idx, hinic3_rx_queue_stats_extern,
- &nic_dev->rxqs[qid].rxq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++], &hinic3_rx_queue_stats[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats_extern); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++], &hinic3_rx_queue_stats_extern[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
}
-}
+ return 0;
+}
static char g_hinic3_test_strings[][ETH_GSTRING_LEN] = {
"Internal lb test (on/offline)",
"External lb test (external_lb)",
@@ -398,16 +430,15 @@ int hinic3_get_sset_count(struct net_device *netdev, int sset)
case ETH_SS_STATS:
q_num = nic_dev->q_params.num_qps;
count = ARRAY_LEN(hinic3_netdev_stats) +
- ARRAY_LEN(hinic3_nic_dev_stats) +
+ ARRAY_LEN(hinic3_nic_dev_stats) +
+ ARRAY_LEN(hinic3_netdev_link_count) +
ARRAY_LEN(hinic3_function_stats) +
(ARRAY_LEN(hinic3_tx_queue_stats) +
ARRAY_LEN(hinic3_rx_queue_stats)) * q_num;
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER)
- count += ARRAY_LEN(g_hinic3_fpga_port_stats);
- else
- count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(g_hinic3_rsfec_stats);
}
return count;
@@ -452,9 +483,9 @@ static void get_drv_queue_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
}
}
-static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct hinic3_phy_fpga_port_stats *port_stats = NULL;
+ struct mag_cmd_port_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
@@ -464,19 +495,19 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to malloc port stats\n");
memset(&data[i], 0,
- ARRAY_LEN(g_hinic3_fpga_port_stats) * sizeof(*data));
- i += ARRAY_LEN(g_hinic3_fpga_port_stats);
+ ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
+ i += ARRAY_LEN(hinic3_port_stats);
return i;
}
- err = hinic3_get_fpga_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to get port stats from fw\n");
- for (j = 0; j < ARRAY_LEN(g_hinic3_fpga_port_stats); j++, i++) {
- p = (char *)(port_stats) + g_hinic3_fpga_port_stats[j].offset;
- data[i] = (g_hinic3_fpga_port_stats[j].size ==
+ for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
+ p = (char *)(port_stats) + hinic3_port_stats[j].offset;
+ data[i] = (hinic3_port_stats[j].size ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
@@ -485,35 +516,32 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
return i;
}
-static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_rsfec_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct mag_cmd_port_stats *port_stats = NULL;
+ struct mag_cmd_rsfec_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
- if (mag_support_mode == FPGA_PORT_COUNTER)
- return get_fpga_port_stats(nic_dev, data);
-
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
if (!port_stats) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to malloc port stats\n");
memset(&data[i], 0,
- ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
- i += ARRAY_LEN(hinic3_port_stats);
+ ARRAY_LEN(g_hinic3_rsfec_stats) * sizeof(*data));
+ i += ARRAY_LEN(g_hinic3_rsfec_stats);
return i;
- }
+ }
- err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_rsfec_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to get port stats from fw\n");
+ "Failed to get rsfec stats from fw\n");
- for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
- p = (char *)(port_stats) + hinic3_port_stats[j].offset;
- data[i] = (hinic3_port_stats[j].size ==
- sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+ for (j = 0; j < ARRAY_LEN(g_hinic3_rsfec_stats); j++, i++) {
+ p = (char *)(port_stats) + g_hinic3_rsfec_stats[j].offset;
+ data[i] = (g_hinic3_rsfec_stats[j].size ==
+ sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
kfree(port_stats);
@@ -537,6 +565,8 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
u16 i = 0, j = 0;
char *p = NULL;
int err;
+ int link_down_events_phy_tmp = 0;
+ struct hinic3_netdev_link_count_str link_count = {0};
#ifdef HAVE_NDO_GET_STATS64
net_stats = dev_get_stats(netdev, &temp);
@@ -554,6 +584,14 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = GET_VALUE_OF_PTR(hinic3_nic_dev_stats[j].size, p);
}
+ err = hinic3_get_link_event_stats(nic_dev->hwdev, &link_down_events_phy_tmp);
+
+ link_count.link_down_events_phy = (u64)link_down_events_phy_tmp;
+ for (j = 0; j < ARRAY_LEN(hinic3_netdev_link_count); j++, i++) {
+ p = (char *)(&link_count) + hinic3_netdev_link_count[j].offset;
+ data[i] = GET_VALUE_OF_PTR(hinic3_netdev_link_count[j].size, p);
+ }
+
err = hinic3_get_vport_stats(nic_dev->hwdev, hinic3_global_func_id(nic_dev->hwdev),
&vport_stats);
if (err)
@@ -565,8 +603,10 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = GET_VALUE_OF_PTR(hinic3_function_stats[j].size, p);
}
- if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
i += get_ethtool_port_stats(nic_dev, data + i);
+ i += get_ethtool_rsfec_stats(nic_dev, data + i);
+ }
get_drv_queue_stats(nic_dev, data + i);
}
@@ -588,6 +628,12 @@ static u16 get_drv_dev_strings(struct hinic3_nic_dev *nic_dev, char *p)
cnt++;
}
+ for (i = 0; i < ARRAY_LEN(hinic3_netdev_link_count); i++) {
+ memcpy(p, hinic3_netdev_link_count[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+
return cnt;
}
@@ -603,18 +649,16 @@ static u16 get_hw_stats_strings(struct hinic3_nic_dev *nic_dev, char *p)
}
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER) {
- for (i = 0; i < ARRAY_LEN(g_hinic3_fpga_port_stats); i++) {
- memcpy(p, g_hinic3_fpga_port_stats[i].name, ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
- } else {
- for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
- memcpy(p, hinic3_port_stats[i].name, ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
+ for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
+ memcpy(p, hinic3_port_stats[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+ for (i = 0; i < ARRAY_LEN(g_hinic3_rsfec_stats); i++) {
+ memcpy(p, g_hinic3_rsfec_stats[i].name,
+ ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
}
}
@@ -758,7 +802,6 @@ struct hw2ethtool_link_mode {
u32 speed;
};
-/*lint -save -e26 */
static const struct hw2ethtool_link_mode
hw2ethtool_link_mode_table[LINK_MODE_MAX_NUMBERS] = {
[LINK_MODE_GE] = {
@@ -818,8 +861,6 @@ static const struct hw2ethtool_link_mode
},
};
-/*lint -restore */
-
#define GET_SUPPORTED_MODE 0
#define GET_ADVERTISED_MODE 1
@@ -838,29 +879,33 @@ struct cmd_link_settings {
#define ETHTOOL_ADD_ADVERTISED_LINK_MODE(ecmd, mode) \
set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->advertising)
-#define ETHTOOL_ADD_SUPPORTED_SPEED_LINK_MODE(ecmd, mode) \
-do { \
- u32 i; \
- for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) { \
- if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >= \
- __ETHTOOL_LINK_MODE_MASK_NBITS) \
- continue; \
- set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i], \
- (ecmd)->supported); \
- } \
-} while (0)
+static void ethtool_add_supported_speed_link_mode(struct cmd_link_settings *link_settings,
+ u32 mode)
+{
+ u32 i;
-#define ETHTOOL_ADD_ADVERTISED_SPEED_LINK_MODE(ecmd, mode) \
-do { \
- u32 i; \
- for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) { \
- if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >= \
- __ETHTOOL_LINK_MODE_MASK_NBITS) \
- continue; \
- set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i], \
- (ecmd)->advertising); \
- } \
-} while (0)
+ for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
+ if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
+ continue;
+ set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
+ link_settings->supported);
+ }
+}
+
+static void ethtool_add_advertised_speed_link_mode(struct cmd_link_settings *link_settings,
+ u32 mode)
+{
+ u32 i;
+
+ for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
+ if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
+ continue;
+ set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
+ link_settings->advertising);
+ }
+}
/* Related to enum mag_cmd_port_speed */
static u32 hw_to_ethtool_speed[] = {
@@ -888,11 +933,11 @@ static void hinic3_add_ethtool_link_mode(struct cmd_link_settings *link_settings
for (link_mode = 0; link_mode < LINK_MODE_MAX_NUMBERS; link_mode++) {
if (hw_link_mode & BIT(link_mode)) {
if (name == GET_SUPPORTED_MODE)
- ETHTOOL_ADD_SUPPORTED_SPEED_LINK_MODE
- (link_settings, link_mode);
+ ethtool_add_supported_speed_link_mode(
+ link_settings, link_mode);
else
- ETHTOOL_ADD_ADVERTISED_SPEED_LINK_MODE
- (link_settings, link_mode);
+ ethtool_add_advertised_speed_link_mode(
+ link_settings, link_mode);
}
}
}
@@ -915,10 +960,15 @@ static int hinic3_link_speed_set(struct hinic3_nic_dev *nic_dev,
err = hinic3_get_link_state(nic_dev->hwdev, &link_state);
if (!err && link_state) {
- link_settings->speed =
- port_info->speed < ARRAY_LEN(hw_to_ethtool_speed) ?
- hw_to_ethtool_speed[port_info->speed] :
- (u32)SPEED_UNKNOWN;
+ if (hinic3_get_bond_create_mode(nic_dev->hwdev)) {
+ link_settings->speed = port_info->bond_speed;
+ } else {
+ link_settings->speed =
+ port_info->speed <
+ ARRAY_LEN(hw_to_ethtool_speed) ?
+ hw_to_ethtool_speed[port_info->speed] :
+ (u32)SPEED_UNKNOWN;
+ }
link_settings->duplex = port_info->duplex;
} else {
@@ -993,6 +1043,39 @@ static int get_link_pause_settings(struct hinic3_nic_dev *nic_dev,
return 0;
}
+static bool is_bit_offset_defined(u8 bit_offset)
+{
+ if (bit_offset < __ETHTOOL_LINK_MODE_MASK_NBITS)
+ return true;
+ return false;
+}
+
+static void
+ethtool_add_supported_advertised_fec(struct cmd_link_settings *link_settings,
+ u32 fec, u8 cmd)
+{
+ u8 i;
+ for (i = 0; i < HINIC_ETHTOOL_FEC_INFO_LEN; i++) {
+ if ((fec & BIT(hinic3_ethtool_fec_info[i].hinic_fec_offset)) == 0)
+ continue;
+ if ((is_bit_offset_defined(hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true) &&
+ (cmd == HINIC_ADVERTISED_FEC_CMD)) {
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset, link_settings->advertising);
+ return; /* There can be only one advertised fec mode. */
+ }
+ if ((is_bit_offset_defined(hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true) &&
+ (cmd == HINIC_SUPPORTED_FEC_CMD))
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset, link_settings->supported);
+ }
+}
+
+static void hinic3_link_fec_type(struct cmd_link_settings *link_settings,
+ u32 fec, u32 supported_fec)
+{
+ ethtool_add_supported_advertised_fec(link_settings, supported_fec, HINIC_SUPPORTED_FEC_CMD);
+ ethtool_add_supported_advertised_fec(link_settings, fec, HINIC_ADVERTISED_FEC_CMD);
+}
+
static int get_link_settings(struct net_device *netdev,
struct cmd_link_settings *link_settings)
{
@@ -1013,6 +1096,9 @@ static int get_link_settings(struct net_device *netdev,
hinic3_link_port_type(link_settings, port_info.port_type);
+ hinic3_link_fec_type(link_settings, BIT(port_info.fec),
+ port_info.supported_fec_mode);
+
link_settings->autoneg = port_info.autoneg_state == PORT_CFG_AN_ON ?
AUTONEG_ENABLE : AUTONEG_DISABLE;
if (port_info.autoneg_cap)
@@ -1138,10 +1224,11 @@ static int hinic3_set_settings_to_hw(struct hinic3_nic_dev *nic_dev,
struct net_device *netdev = nic_dev->netdev;
struct hinic3_link_ksettings settings = {0};
int speed_level = 0;
- char set_link_str[128] = {0};
+ char set_link_str[HINIC_SET_LINK_STR_LEN] = {0};
+ char link_info[HINIC_SET_LINK_STR_LEN] = {0};
int err = 0;
- err = snprintf(set_link_str, sizeof(set_link_str) - 1, "%s",
+ err = snprintf(link_info, sizeof(link_info), "%s",
(bool)(set_settings & HILINK_LINK_SET_AUTONEG) ?
((bool)autoneg ? "autong enable " : "autong disable ") : "");
if (err < 0)
@@ -1149,8 +1236,8 @@ static int hinic3_set_settings_to_hw(struct hinic3_nic_dev *nic_dev,
if (set_settings & HILINK_LINK_SET_SPEED) {
speed_level = hinic3_ethtool_to_hw_speed_level(speed);
- err = snprintf(set_link_str, sizeof(set_link_str) - 1,
- "%sspeed %u ", set_link_str, speed);
+ err = snprintf(set_link_str, sizeof(set_link_str),
+ "%sspeed %u ", link_info, speed);
if (err < 0)
return -EINVAL;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
index 70346d6..2daa7f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
@@ -82,7 +82,7 @@ static struct hinic3_mac_filter *hinic3_add_filter(struct hinic3_nic_dev *nic_de
struct list_head *mac_filter_list,
u8 *addr)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
@@ -117,7 +117,7 @@ static void hinic3_del_filter(struct hinic3_nic_dev *nic_dev,
static struct hinic3_mac_filter *hinic3_mac_filter_entry_clone(const struct hinic3_mac_filter *src)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
index ef8c62b..7fed1c1 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
@@ -40,6 +40,7 @@ enum hinic3_channel_id {
HINIC3_CHANNEL_DSW,
HINIC3_CHANNEL_MIG,
HINIC3_CHANNEL_CRYPT,
+ HINIC3_CHANNEL_VROCE,
HINIC3_CHANNEL_MAX = 32,
};
@@ -397,6 +398,16 @@ void hinic3_free_cmd_buf(void *hwdev, struct hinic3_cmd_buf *cmd_buf);
**/
int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read clear
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+
/**
* @brief hinic3_sm_ctr_rd32 - small single 32 counter read
* @param hwdev: device pointer to hwdev
@@ -810,6 +821,13 @@ int hinic3_dbg_lt_wr_16byte_mask(void *hwdev, u8 dest, u8 instance,
*/
void hinic3_link_event_stats(void *dev, u8 link);
+/**
+ * @brief hinic3_get_link_event_stats - link event stats
+ * @param hwdev: device pointer to hwdev
+ * @param link: link status
+ */
+int hinic3_get_link_event_stats(void *dev, int *link_state);
+
/**
* @brief hinic3_get_hw_pf_infos - get pf infos
* @param hwdev: device pointer to hwdev
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
index 3c835ff..7a2644c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
@@ -12,6 +12,7 @@
#include <linux/netdevice.h>
#include <linux/debugfs.h>
+#include "ossl_knl.h"
#include "hinic3_hw.h"
#include "hinic3_crm.h"
#include "hinic3_nic_io.h"
@@ -47,12 +48,16 @@ static void qp_add_napi(struct hinic3_irq *irq_cfg)
netif_napi_add(nic_dev->netdev, &irq_cfg->napi,
hinic3_poll, nic_dev->poll_weight);
napi_enable(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_IS_REGIN;
}
-static void qp_del_napi(struct hinic3_irq *irq_cfg)
+void qp_del_napi(struct hinic3_irq *irq_cfg)
{
- napi_disable(&irq_cfg->napi);
- netif_napi_del(&irq_cfg->napi);
+ if (irq_cfg->napi_reign == NAPI_IS_REGIN) {
+ napi_disable(&irq_cfg->napi);
+ netif_napi_del(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_NOT_REGIN;
+ }
}
static irqreturn_t qp_irq(int irq, void *data)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
deleted file mode 100644
index 2482c5f..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_LLD_H
-#define HINIC3_LLD_H
-
-#include "hinic3_crm.h"
-
-struct hinic3_lld_dev {
- struct pci_dev *pdev;
- void *hwdev;
-};
-
-struct hinic3_uld_info {
- /* When the function does not need to initialize the corresponding uld,
- * @probe needs to return 0 and uld_dev is set to NULL;
- * if uld_dev is NULL, @remove will not be called when uninstalling
- */
- int (*probe)(struct hinic3_lld_dev *lld_dev, void **uld_dev, char *uld_dev_name);
- void (*remove)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- int (*suspend)(struct hinic3_lld_dev *lld_dev, void *uld_dev, pm_message_t state);
- int (*resume)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- void (*event)(struct hinic3_lld_dev *lld_dev, void *uld_dev,
- struct hinic3_event_info *event);
- int (*ioctl)(void *uld_dev, u32 cmd, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size);
-};
-
-/* hinic3_register_uld - register an upper-layer driver
- * @type: uld service type
- * @uld_info: uld callback
- *
- * Registers an upper-layer driver.
- * Traverse existing devices and call @probe to initialize the uld device.
- */
-int hinic3_register_uld(enum hinic3_service_type type, struct hinic3_uld_info *uld_info);
-
-/**
- * hinic3_unregister_uld - unregister an upper-layer driver
- * @type: uld service type
- *
- * Traverse existing devices and call @remove to uninstall the uld device.
- * Unregisters an existing upper-layer driver.
- */
-void hinic3_unregister_uld(enum hinic3_service_type type);
-
-void lld_hold(void);
-void lld_put(void);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_name - get lld device by chip name
- * @param chip_name: chip name
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_name(const char *chip_name);
-
-/**
- * @brief lld_dev_hold - get reference to lld_dev
- * @param dev: lld device
- *
- * Hold reference to device to keep it from being freed
- **/
-void lld_dev_hold(struct hinic3_lld_dev *dev);
-
-/**
- * @brief lld_dev_put - release reference to lld_dev
- * @param dev: lld device
- *
- * Release reference to device to allow it to be freed
- **/
-void lld_dev_put(struct hinic3_lld_dev *dev);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name_unsafe - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * hinic3_get_lld_dev_by_dev_name_unsafe() is completely analogous to
- * hinic3_get_lld_dev_by_dev_name(), The only difference is that the reference
- * of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that lld_dev will not be freed during the remove process
- * when using lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name_unsafe(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_and_port - get lld device by chip name and port id
- * @param chip_name: chip name
- * @param port_id: port id
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name, u8 port_id);
-
-/**
- * @brief hinic3_get_ppf_lld_dev - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief hinic3_get_ppf_lld_dev_unsafe - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * hinic3_get_ppf_lld_dev_unsafe() is completely analogous to hinic3_get_ppf_lld_dev(),
- * The only difference is that the reference of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that ppf's lld_dev will not be freed during the remove process
- * when using ppf lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev_unsafe(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief uld_dev_hold - get reference to uld_dev
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * Hold reference to uld device to keep it from being freed
- **/
-void uld_dev_hold(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief uld_dev_put - release reference to lld_dev
- * @param dev: lld device
- * @param type: uld service type
- *
- * Release reference to uld device to allow it to be freed
- **/
-void uld_dev_put(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * The value of uld_dev reference increases when uld_dev is obtained. The caller needs
- * to release the reference by calling uld_dev_put.
- **/
-void *hinic3_get_uld_dev(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev_unsafe - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * hinic3_get_uld_dev_unsafe() is completely analogous to hinic3_get_uld_dev(),
- * The only difference is that the reference of uld_dev is not increased when uld_dev is obtained.
- *
- * The caller must ensure that uld_dev will not be freed during the remove process
- * when using uld_dev.
- **/
-void *hinic3_get_uld_dev_unsafe(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_chip_name - get chip name by lld device
- * @param lld_dev: lld device
- * @param chip_name: String for storing the chip name
- * @param max_len: Maximum number of characters to be copied for chip_name
- **/
-int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len);
-
-struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev);
-
-struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev);
-
-bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service);
-
-int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
- bool vf_srv_load);
-
-int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id,
- u16 service, bool en);
-
-bool hinic3_get_vf_load_state(struct pci_dev *pdev);
-
-int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state);
-
-int hinic3_attach_nic(struct hinic3_lld_dev *lld_dev);
-
-void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
-
-int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-const char **hinic3_get_uld_names(void);
-int hinic3_lld_init(void);
-void hinic3_lld_exit(void);
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
index 2fe808b..8cd891e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
@@ -17,12 +17,22 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_hw.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_common.h"
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
+#define CAP_INFO_MAX_LEN 512
+#define DEVICE_VENDOR_MAX_LEN 17
+#define READ_RSFEC_REGISTER_DELAY_TIME_MS 500
+
+struct parse_tlv_info g_page_info = {0};
+struct drv_mag_cmd_get_xsfp_tlv_rsp g_xsfp_tlv_info = {0};
+
static int mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
static int mag_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in,
@@ -78,8 +88,10 @@ int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats)
return -ENOMEM;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
memset(&stats_info, 0, sizeof(stats_info));
stats_info.port_id = hinic3_physical_port_id(hwdev);
@@ -104,6 +116,64 @@ out:
}
EXPORT_SYMBOL(hinic3_get_phy_port_stats);
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats)
+{
+ struct mag_cmd_get_mag_cnt *port_stats = NULL;
+ struct mag_cmd_get_mag_cnt stats_info;
+ u16 out_size = sizeof(*port_stats);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !stats)
+ return -EINVAL;
+
+ port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
+ if (!port_stats)
+ return -ENOMEM;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ memset(&stats_info, 0, sizeof(stats_info));
+ stats_info.port_id = hinic3_physical_port_id(hwdev);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT,
+ &stats_info, sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+ /* 读2遍, 清除误码残留 */
+ msleep(READ_RSFEC_REGISTER_DELAY_TIME_MS);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT, &stats_info,
+ sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+
+ memcpy(stats, &port_stats->mag_csr[MAG_RX_RSFEC_ERR_CW_CNT],
+ sizeof(u32));
+
+out:
+ kfree(port_stats);
+
+ return err;
+}
+EXPORT_SYMBOL(hinic3_get_phy_rsfec_stats);
+
int hinic3_set_port_funcs_state(void *hwdev, bool enable)
{
return 0;
@@ -180,6 +250,8 @@ int hinic3_get_loopback_mode(void *hwdev, u8 *mode, u8 *enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_cfg_loopback_mode(nic_io, MGMT_MSG_CMD_OP_GET, mode,
enable);
@@ -195,6 +267,8 @@ int hinic3_set_loopback_mode(void *hwdev, u8 mode, u8 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) {
nic_err(nic_io->dev_hdl, "Invalid loopback mode %u to set\n",
@@ -218,6 +292,9 @@ int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&led_info, 0, sizeof(led_info));
led_info.function_id = hinic3_global_func_id(hwdev);
@@ -249,6 +326,8 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
memset(&port_msg, 0, sizeof(port_msg));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
port_msg.port_id = hinic3_physical_port_id(hwdev);
@@ -268,9 +347,12 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
port_info->port_type = port_msg.wire_type;
port_info->speed = port_msg.speed;
port_info->fec = port_msg.fec;
+ port_info->lanes = port_msg.lanes;
port_info->supported_mode = port_msg.supported_mode;
port_info->advertised_mode = port_msg.advertised_mode;
-
+ port_info->supported_fec_mode = port_msg.supported_fec_mode;
+ /* switch Gbps to Mbps */
+ port_info->bond_speed = (u32)port_msg.bond_speed * RATE_MBPS_TO_GBPS;
return 0;
}
@@ -306,6 +388,8 @@ int hinic3_set_link_settings(void *hwdev,
memset(&info, 0, sizeof(info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
info.port_id = hinic3_physical_port_id(hwdev);
info.config_bitmap = settings->valid_bitmap;
@@ -335,6 +419,8 @@ int hinic3_get_link_state(void *hwdev, u8 *link_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&get_link, 0, sizeof(get_link));
get_link.port_id = hinic3_physical_port_id(hwdev);
@@ -364,9 +450,10 @@ void hinic3_notify_vf_link_status(struct hinic3_nic_io *nic_io,
if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
link.status = link_status;
link.port_id = hinic3_physical_port_id(nic_io->hwdev);
- err = hinic3_mbox_to_vf(nic_io->hwdev, vf_id, HINIC3_MOD_HILINK,
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
MAG_CMD_GET_LINK_STATUS, &link,
- sizeof(link), &link, &out_size, 0,
+ sizeof(link), &link, &out_size,
HINIC3_CHANNEL_NIC);
if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
@@ -387,6 +474,9 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
u16 i;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
+
nic_io->link_status = link_status;
for (i = 1; i <= nic_io->max_vfs; i++) {
if (!nic_io->vf_infos[HW_VF_ID_TO_OS(i)].link_forced)
@@ -394,6 +484,167 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
}
}
+static char *g_hw_to_char_fec[HILINK_FEC_MAX_TYPE] = {
+ "not set", "rsfec", "basefec",
+ "nofec", "llrsfec"};
+static char *g_hw_to_speed_info[PORT_SPEED_UNKNOWN] = {
+ "not set", "10MB", "100MB", "1GB", "10GB",
+ "25GB", "40GB", "50GB", "100GB", "200GB"};
+static char *g_hw_to_an_state_info[PORT_CFG_AN_OFF + 1] = {
+ "not set", "on", "off"};
+
+struct port_type_table {
+ u32 port_type;
+ char *port_type_name;
+};
+
+static const struct port_type_table port_optical_type_table_s[] = {
+ {LINK_PORT_UNKNOWN, "UNKNOWN"},
+ {LINK_PORT_OPTICAL_MM, "optical_sr"},
+ {LINK_PORT_OPTICAL_SM, "optical_lr"},
+ {LINK_PORT_PAS_COPPER, "copper"},
+ {LINK_PORT_ACC, "ACC"},
+ {LINK_PORT_BASET, "baset"},
+ {LINK_PORT_AOC, "AOC"},
+ {LINK_PORT_ELECTRIC, "electric"},
+ {LINK_PORT_BACKBOARD_INTERFACE, "interface"},
+};
+
+static char *get_port_type_name(u32 type)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(port_optical_type_table_s); i++) {
+ if (type == port_optical_type_table_s[i].port_type)
+ return port_optical_type_table_s[i].port_type_name;
+ }
+ return "UNKNOWN TYPE";
+}
+
+static void get_port_type(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ char **port_type)
+{
+ if (info->port_type <= LINK_PORT_BACKBOARD_INTERFACE)
+ *port_type = get_port_type_name(info->port_type);
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown port type: %u\n",
+ info->port_type);
+}
+
+static int get_port_temperature_power(struct mag_cmd_event_port_info *info,
+ char *str)
+{
+ char cap_info[CAP_INFO_MAX_LEN];
+
+ memset(cap_info, 0, sizeof(cap_info));
+ snprintf(cap_info, CAP_INFO_MAX_LEN, "%s, %s, Temperature: %u", str,
+ info->sfp_type ? "QSFP" : "SFP", info->cable_temp);
+
+ if (info->sfp_type)
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuw %uuW %uuW %uuW",
+ cap_info, info->power[0x0], info->power[0x1],
+ info->power[0x2], info->power[0x3]);
+ else
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuW, tx power: %uuW",
+ cap_info, info->power[0x0], info->power[0x1]);
+
+ return 0;
+}
+
+static void print_cable_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info)
+{
+ char tmp_str[CAP_INFO_MAX_LEN] = {0};
+ char tmp_vendor[DEVICE_VENDOR_MAX_LEN] = {0};
+ char *port_type = "Unknown port type";
+ int i;
+ int err = 0;
+
+ if (info->gpio_insert) {
+ sdk_info(nic_io->dev_hdl, "Cable unpresent\n");
+ return;
+ }
+
+ get_port_type(nic_io, info, &port_type);
+
+ for (i = sizeof(info->vendor_name) - 1; i >= 0; i--) {
+ if (info->vendor_name[i] == ' ')
+ info->vendor_name[i] = '\0';
+ else
+ break;
+ }
+
+ memcpy(tmp_vendor, info->vendor_name, sizeof(info->vendor_name));
+ snprintf(tmp_str, CAP_INFO_MAX_LEN, "Vendor: %s, %s, length: %um, max_speed: %uGbps",
+ tmp_vendor, port_type, info->cable_length, info->max_speed);
+
+ if (info->port_type == LINK_PORT_OPTICAL_MM ||
+ info->port_type == LINK_PORT_AOC) {
+ err = get_port_temperature_power(info, tmp_str);
+ if (err)
+ return;
+ }
+
+ sdk_info(nic_io->dev_hdl, "Cable information: %s\n", tmp_str);
+}
+
+static void print_link_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ enum hinic3_nic_event_type type)
+{
+ char *fec = "None";
+ char *speed = "None";
+ char *an_state = "None";
+
+ if (info->fec < HILINK_FEC_MAX_TYPE)
+ fec = g_hw_to_char_fec[info->fec];
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown fec type: %u\n", info->fec);
+
+ if (info->an_state > PORT_CFG_AN_OFF) {
+ sdk_info(nic_io->dev_hdl, "an_state %u is invalid",
+ info->an_state);
+ return;
+ }
+
+ an_state = g_hw_to_an_state_info[info->an_state];
+
+ if (info->speed >= PORT_SPEED_UNKNOWN) {
+ sdk_info(nic_io->dev_hdl, "speed %u is invalid", info->speed);
+ return;
+ }
+
+ speed = g_hw_to_speed_info[info->speed];
+ sdk_info(nic_io->dev_hdl, "Link information: speed %s, %s, autoneg %s",
+ speed, fec, an_state);
+}
+
+void print_port_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *port_info,
+ enum hinic3_nic_event_type type)
+{
+ print_cable_info(nic_io, port_info);
+
+ print_link_info(nic_io, port_info, type);
+
+ if (type == EVENT_NIC_LINK_UP)
+ return;
+
+ sdk_info(nic_io->dev_hdl, "PMA ctrl: %s, tx %s, rx %s, PMA fifo reg: 0x%x, PMA signal ok reg: 0x%x, RF/LF status reg: 0x%x\n",
+ port_info->pma_ctrl == 1 ? "off" : "on",
+ port_info->tx_enable ? "enable" : "disable",
+ port_info->rx_enable ? "enable" : "disable", port_info->pma_fifo_reg,
+ port_info->pma_signal_ok_reg, port_info->rf_lf);
+ sdk_info(nic_io->dev_hdl, "alos: %u, rx_los: %u, PCS 64 66b reg: 0x%x, PCS link: 0x%x, MAC link: 0x%x PCS_err_cnt: 0x%x\n",
+ port_info->alos, port_info->rx_los, port_info->pcs_64_66b_reg,
+ port_info->pcs_link, port_info->pcs_mac_link,
+ port_info->pcs_err_cnt);
+ sdk_info(nic_io->dev_hdl, "his_link_machine_state = 0x%08x, cur_link_machine_state = 0x%08x\n",
+ port_info->his_link_machine_state,
+ port_info->cur_link_machine_state);
+}
+
static int hinic3_get_vf_link_status_msg_handler(struct hinic3_nic_io *nic_io,
u16 vf_id, void *buf_in,
u16 in_size, void *buf_out,
@@ -433,6 +684,10 @@ static void get_port_info(void *hwdev,
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (hinic3_func_type(hwdev) != TYPE_VF && link_status->status) {
err = hinic3_get_port_info(hwdev, &port_info, HINIC3_CHANNEL_NIC);
if (err) {
@@ -457,8 +712,17 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
struct hinic3_event_info event_info = {0};
struct hinic3_event_link_info *link_info = (void *)event_info.event_data;
struct hinic3_nic_io *nic_io = NULL;
+ struct pci_dev *pdev = NULL;
+
+ /* Ignore link change event */
+ if (hinic3_is_bm_slave_host(hwdev))
+ return;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
link_status = buf_in;
sdk_info(nic_io->dev_hdl, "Link status report received, func_id: %u, status: %u\n",
@@ -475,6 +739,13 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
hinic3_event_callback(hwdev, &event_info);
+ if (nic_io->pcidev_hdl != NULL) {
+ pdev = nic_io->pcidev_hdl;
+ if (pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID) {
+ return;
+ }
+ }
+
if (hinic3_func_type(hwdev) != TYPE_VF) {
hinic3_notify_all_vfs_link_changed(hwdev, link_status->status);
ret_link_status = buf_out;
@@ -483,20 +754,142 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
}
}
+static void port_info_event_printf(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_event_port_info *port_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info;
+ enum hinic3_nic_event_type type;
+
+ if (!hwdev) {
+ pr_err("hwdev is NULL\n");
+ return;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ if (in_size != sizeof(*port_info)) {
+ sdk_info(nic_io->dev_hdl, "Invalid port info message size %u, should be %lu\n",
+ in_size, sizeof(*port_info));
+ return;
+ }
+
+ ((struct mag_cmd_event_port_info *)buf_out)->head.status = 0;
+
+ type = port_info->event_type;
+ if (type < EVENT_NIC_LINK_DOWN || type > EVENT_NIC_LINK_UP) {
+ sdk_info(nic_io->dev_hdl, "Invalid hilink info report, type: %d\n",
+ type);
+ return;
+ }
+
+ print_port_info(nic_io, port_info, type);
+
+ memset(&event_info, 0, sizeof(event_info));
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = type;
+
+ *out_size = sizeof(*port_info);
+
+ hinic3_event_callback(hwdev, &event_info);
+}
+
+void hinic3_notify_vf_bond_status(struct hinic3_nic_io *nic_io,
+ u16 vf_id, u8 bond_status)
+{
+ struct mag_cmd_get_bond_status bond;
+ struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ u16 out_size = sizeof(bond);
+ int err;
+
+ memset(&bond, 0, sizeof(bond));
+ if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
+ bond.status = bond_status;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
+ MAG_CMD_GET_BOND_STATUS, &bond,
+ sizeof(bond), &bond, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF %hu not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return;
+ }
+ if (err || !out_size || bond.head.status)
+ nic_err(nic_io->dev_hdl,
+ "Send bond change event to VF %hu failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err, bond.head.status,
+ out_size);
+ }
+}
+
+void hinic3_notify_all_vfs_bond_changed(void *hwdev, u8 bond_status)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 i;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ nic_io->link_status = bond_status;
+ for (i = 1; i <= nic_io->max_vfs; i++)
+ hinic3_notify_vf_bond_status(nic_io, i, bond_status);
+}
+
+static void bond_status_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_get_bond_status *bond_status = NULL;
+ struct hinic3_event_info event_info = {};
+ struct hinic3_nic_io *nic_io = NULL;
+ struct mag_cmd_get_bond_status *ret_bond_status = NULL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+
+ bond_status = (struct mag_cmd_get_bond_status *)buf_in;
+ sdk_info(nic_io->dev_hdl, "bond status report received, func_id: %u, status: %u\n",
+ hinic3_global_func_id(hwdev), bond_status->status);
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = bond_status->status ?
+ EVENT_NIC_BOND_UP : EVENT_NIC_BOND_DOWN;
+
+ hinic3_event_callback(hwdev, &event_info);
+
+ if (hinic3_func_type(hwdev) != TYPE_VF) {
+ hinic3_notify_all_vfs_bond_changed(hwdev, bond_status->status);
+ ret_bond_status = buf_out;
+ ret_bond_status->head.status = 0;
+ *out_size = sizeof(*ret_bond_status);
+ }
+}
+
static void cable_plug_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct mag_cmd_wire_event *plug_event = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_event_info event_info;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
rt_cmd->mpu_send_sfp_abs = false;
rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
memset(&event_info, 0, sizeof(event_info));
@@ -518,20 +911,54 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
{
struct mag_cmd_get_xsfp_info *sfp_info = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_info)) {
- sdk_err(nic_io->dev_hdl, "Invalid sfp info cmd, length: %u, should be %ld\n",
+ sdk_err(nic_io->dev_hdl, "Invalid sfp info cmd, length: %u, should be %lu\n",
in_size, sizeof(*sfp_info));
return;
}
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
memcpy(&rt_cmd->std_sfp_info, sfp_info,
sizeof(struct mag_cmd_get_xsfp_info));
rt_cmd->mpu_send_sfp_info = true;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+}
+
+static void port_xsfp_tlv_info_event(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_get_xsfp_tlv_rsp *xsfp_tlv_info = buf_in;
+ struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
+ size_t cpy_len = in_size - sizeof(struct mgmt_msg_head) -
+ XSFP_TLV_PRE_INFO_LEN;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL)
+ return;
+
+ if (cpy_len > XSFP_CMIS_INFO_MAX_SIZE) {
+ sdk_err(nic_io->dev_hdl, "invalid cpy_len(%lu)\n", cpy_len);
+ return;
+ }
+ rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ rt_cmd_ext->std_xsfp_tlv_info.port_id = xsfp_tlv_info->port_id;
+ memcpy(&(rt_cmd_ext->std_xsfp_tlv_info.tlv_buf[0]),
+ &(xsfp_tlv_info->tlv_buf[0]), cpy_len);
+ rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = true;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
}
@@ -543,8 +970,10 @@ static void port_sfp_abs_event(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_abs)) {
- sdk_err(nic_io->dev_hdl, "Invalid sfp absent cmd, length: %u, should be %ld\n",
+ sdk_err(nic_io->dev_hdl, "Invalid sfp absent cmd, length: %u, should be %lu\n",
in_size, sizeof(*sfp_abs));
return;
}
@@ -564,9 +993,11 @@ bool hinic3_if_sfp_absent(void *hwdev)
u8 port_id = hinic3_physical_port_id(hwdev);
u16 out_size = sizeof(sfp_abs);
int err;
- bool sfp_abs_status;
+ bool sfp_abs_status = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return true;
memset(&sfp_abs, 0, sizeof(sfp_abs));
rt_cmd = &nic_io->nic_cfg.rt_cmd;
@@ -597,10 +1028,187 @@ bool hinic3_if_sfp_absent(void *hwdev)
return (sfp_abs.abs_status == 0 ? false : true);
}
+int hinic3_get_sfp_tlv_info(void *hwdev, struct drv_mag_cmd_get_xsfp_tlv_rsp
+ *sfp_tlv_info,
+ const struct mag_cmd_get_xsfp_tlv_req
+ *sfp_tlv_info_req)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ u16 out_size = sizeof(*sfp_tlv_info);
+ int err;
+
+ if ((hwdev == NULL) || (sfp_tlv_info == NULL))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL)
+ return -EINVAL;
+
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ if (rt_cmd_ext->mpu_send_xsfp_tlv_info == true) {
+ if (rt_cmd_ext->std_xsfp_tlv_info.head.status != 0) {
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return -EIO;
+ }
+
+ memcpy(sfp_tlv_info, &rt_cmd_ext->std_xsfp_tlv_info,
+ sizeof(*sfp_tlv_info));
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_TLV_INFO,
+ (void *)sfp_tlv_info_req,
+ sizeof(*sfp_tlv_info_req),
+ sfp_tlv_info, &out_size);
+ if ((sfp_tlv_info->head.status != 0) || (err != 0) || (out_size == 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get port%u tlv sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
+ hinic3_physical_port_id(hwdev), err,
+ sfp_tlv_info->head.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_get_page_pos(u32 page_id, u32 content_len, u32 *pos)
+{
+ if (page_id <= QSFP_CMIS_PAGE_03H) {
+ *pos = (page_id * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_11H) {
+ *pos = (QSFP_CMIS_PAGE_04H * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_12H) {
+ *pos = (QSFP_CMIS_PAGE_05H * content_len);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int hinic3_get_page_key_info(struct mgmt_tlv_info *tlv_info,
+ struct parse_tlv_info *page_info, u8 idx,
+ u32 *total_len)
+{
+ u8 *src_addr = NULL;
+ u8 *dst_addr = NULL;
+ u8 *tmp_addr = NULL;
+ u32 page_id = 0;
+ u32 content_len = 0;
+ u32 src_pos = 0;
+ int ret;
+
+ page_id = MGMT_TLV_GET_U32(tlv_info->value);
+ content_len = tlv_info->length - MGMT_TLV_U32_SIZE;
+ if (page_id == QSFP_CMIS_PAGE_00H) {
+ tmp_addr = (u8 *)(tlv_info + 1);
+ page_info->id = *(tmp_addr + MGMT_TLV_U32_SIZE);
+ }
+
+ ret = hinic3_trans_cmis_get_page_pos(page_id, content_len, &src_pos);
+ if (ret != 0)
+ return ret;
+
+ src_addr = page_info->tlv_page_info + src_pos;
+ tmp_addr = (u8 *)(tlv_info + 1);
+ dst_addr = tmp_addr + MGMT_TLV_U32_SIZE;
+ memcpy(src_addr, dst_addr, content_len);
+ if (ret != 0)
+ return ret;
+
+ if (idx < XSFP_CMIS_PARSE_PAGE_NUM)
+ page_info->tlv_page_num[idx] = page_id;
+
+ *total_len += content_len;
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_tlv_info_to_buf(u8 *sfp_tlv_info,
+ struct parse_tlv_info *page_info)
+{
+ struct mgmt_tlv_info *tlv_info = NULL;
+ u8 *tlv_buf = sfp_tlv_info;
+ u8 idx = 0;
+ u32 total_len = 0;
+ int ret = 0;
+ bool need_continue = true;
+
+ if ((sfp_tlv_info == NULL) || (page_info == NULL))
+ return -EIO;
+
+ while (need_continue) {
+ tlv_info = (struct mgmt_tlv_info *)tlv_buf;
+ switch (tlv_info->type) {
+ case MAG_XSFP_TYPE_PAGE:
+ ret = hinic3_get_page_key_info(
+ tlv_info, page_info, idx, &total_len);
+ if (ret != 0) {
+ pr_err("lib_get_page_key_info fail,ret:0x%x.\n",
+ ret);
+ break;
+ }
+ idx++;
+ break;
+
+ case MAG_XSFP_TYPE_WIRE_TYPE:
+ page_info->wire_type =
+ MGMT_TLV_GET_U32(&(tlv_info->value[0]));
+ break;
+
+ case MAG_XSFP_TYPE_END:
+ need_continue = false;
+ break;
+
+ default:
+ break;
+ }
+
+ tlv_buf += (sizeof(struct mgmt_tlv_info) + tlv_info->length);
+ }
+
+ page_info->tlv_page_info_len = total_len;
+
+ return 0;
+}
+
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len)
+{
+ int err = 0;
+ struct mag_cmd_get_xsfp_tlv_req xsfp_tlv_info_req = {0};
+
+ xsfp_tlv_info_req.rsp_buf_len = XSFP_CMIS_INFO_MAX_SIZE;
+ xsfp_tlv_info_req.port_id = hinic3_physical_port_id(hwdev);
+ err = hinic3_get_sfp_tlv_info(hwdev, &g_xsfp_tlv_info,
+ &xsfp_tlv_info_req);
+ if (err != 0)
+ return err;
+
+ err = hinic3_trans_cmis_tlv_info_to_buf(g_xsfp_tlv_info.tlv_buf,
+ &g_page_info);
+ if (err)
+ return -ENOMEM;
+
+ memcpy(data, g_page_info.tlv_page_info, len);
+
+ return (err == 0) ? 0 : -ENOMEM;
+}
+
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
{
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ u8 sfp_info_status = 0;
u16 out_size = sizeof(*sfp_info);
int err;
@@ -608,13 +1216,17 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ sfp_info_status = rt_cmd->std_sfp_info.head.status;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (sfp_info_status != 0) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return -EIO;
+ return (sfp_info_status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ ? HINIC3_MGMT_CMD_UNSUPPORTED : -EIO;
}
memcpy(sfp_info, &rt_cmd->std_sfp_info, sizeof(*sfp_info));
@@ -626,7 +1238,14 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
sfp_info->port_id = hinic3_physical_port_id(hwdev);
err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_INFO, sfp_info,
sizeof(*sfp_info), sfp_info, &out_size);
- if (sfp_info->head.status || err || !out_size) {
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED) {
+ return HINIC3_MGMT_CMD_UNSUPPORTED;
+ }
+
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED) {
+ return -EOPNOTSUPP;
+ }
+ if ((sfp_info->head.status != 0) || (err != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Failed to get port%u sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
hinic3_physical_port_id(hwdev), err,
@@ -642,7 +1261,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
struct mag_cmd_get_xsfp_info sfp_info;
int err;
- if (!hwdev || !data)
+ if (!hwdev || !data || len > PAGE_SIZE)
return -EINVAL;
if (hinic3_if_sfp_absent(hwdev))
@@ -654,7 +1273,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
if (err)
return err;
- memcpy(data, sfp_info.sfp_info, len);
+ memcpy(data, sfp_info.sfp_info, sizeof(sfp_info.sfp_info));
return 0;
}
@@ -664,7 +1283,7 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
- int err;
+ int err = 0;
if (!hwdev || !sfp_type || !sfp_type_ext)
return -EINVAL;
@@ -673,24 +1292,41 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
return -ENXIO;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (rt_cmd->std_sfp_info.head.status == 0) {
+ *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
+ *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ if (rt_cmd->std_sfp_info.head.status != HINIC3_MGMT_CMD_UNSUPPORTED) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
return -EIO;
}
- *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
- *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
- mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return 0;
+ err = HINIC3_MGMT_CMD_UNSUPPORTED; /* cmis */
}
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
- STD_SFP_INFO_MAX_SIZE);
+ if (err == 0) {
+ err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ } else {
+ /* mpu_send_sfp_info is false */
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ }
+
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+
if (err)
return err;
@@ -796,12 +1432,20 @@ int hinic3_set_pf_bw_limit(void *hwdev, u32 bw_limit)
return -EINVAL;
}
- old_bw_limit = nic_io->nic_cfg.pf_bw_limit;
- nic_io->nic_cfg.pf_bw_limit = bw_limit;
+ if (nic_io->direct == HINIC3_NIC_TX) {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_tx_limit;
+ nic_io->nic_cfg.pf_bw_tx_limit = bw_limit;
+ } else {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_rx_limit;
+ nic_io->nic_cfg.pf_bw_rx_limit = bw_limit;
+ }
err = hinic3_update_pf_bw(hwdev);
if (err) {
- nic_io->nic_cfg.pf_bw_limit = old_bw_limit;
+ if (nic_io->direct == HINIC3_NIC_TX)
+ nic_io->nic_cfg.pf_bw_tx_limit = old_bw_limit;
+ else
+ nic_io->nic_cfg.pf_bw_rx_limit = old_bw_limit;
return err;
}
@@ -828,6 +1472,8 @@ int hinic3_pf_mag_mbox_handler(void *hwdev, u16 vf_id,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (index = 0; index < cmd_size; index++) {
handler = &vf_mag_cmd_handler[index];
@@ -848,6 +1494,11 @@ static struct nic_event_handler mag_cmd_handler[] = {
.handler = link_status_event_handler,
},
+ {
+ .cmd = MAG_CMD_EVENT_PORT_INFO,
+ .handler = port_info_event_printf,
+ },
+
{
.cmd = MAG_CMD_WIRE_EVENT,
.handler = cable_plug_event,
@@ -862,6 +1513,16 @@ static struct nic_event_handler mag_cmd_handler[] = {
.cmd = MAG_CMD_GET_XSFP_PRESENT,
.handler = port_sfp_abs_event,
},
+
+ {
+ .cmd = MAG_CMD_GET_BOND_STATUS,
+ .handler = bond_status_event_handler,
+ },
+
+ {
+ .cmd = MAG_CMD_GET_XSFP_TLV_INFO,
+ .handler = port_xsfp_tlv_info_event,
+ },
};
static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
@@ -877,6 +1538,9 @@ static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
for (i = 0; i < size; i++) {
if (cmd == mag_cmd_handler[i].cmd) {
mag_cmd_handler[i].handler(hwdev, buf_in, in_size,
@@ -917,7 +1581,8 @@ static int _mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u32 i, cmd_cnt = ARRAY_LEN(vf_mag_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_mag_cmd_handler[i].cmd) {
cmd_to_pf = true;
@@ -949,3 +1614,124 @@ static int mag_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in,
return _mag_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out,
out_size, channel);
}
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+struct fecparam_value_map {
+ u8 hinic3_fec_offset;
+ u8 hinic3_fec_value;
+ u8 ethtool_fec_value;
+};
+
+static void fecparam_convert(u32 opcode, u8 in_fec_param, u8 *out_fec_param)
+{
+ u8 i;
+ u8 fec_value_table_lenth;
+ struct fecparam_value_map fec_value_table[] = {
+ {PORT_FEC_NOT_SET, BIT(PORT_FEC_NOT_SET), ETHTOOL_FEC_NONE},
+ {PORT_FEC_RSFEC, BIT(PORT_FEC_RSFEC), ETHTOOL_FEC_RS},
+ {PORT_FEC_BASEFEC, BIT(PORT_FEC_BASEFEC), ETHTOOL_FEC_BASER},
+ {PORT_FEC_NOFEC, BIT(PORT_FEC_NOFEC), ETHTOOL_FEC_OFF},
+#ifdef ETHTOOL_FEC_LLRS
+ {PORT_FEC_LLRSFEC, BIT(PORT_FEC_LLRSFEC), ETHTOOL_FEC_LLRS},
+#endif
+ {PORT_FEC_AUTO, BIT(PORT_FEC_AUTO), ETHTOOL_FEC_AUTO}
+ };
+
+ *out_fec_param = 0;
+ fec_value_table_lenth = (u8)(sizeof(fec_value_table) / sizeof(struct fecparam_value_map));
+
+ if (opcode == MAG_CMD_OPCODE_SET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].ethtool_fec_value) != 0)
+ /* The MPU uses the offset to determine the FEC mode. */
+ *out_fec_param =
+ fec_value_table[i].hinic3_fec_offset;
+ }
+ }
+
+ if (opcode == MAG_CMD_OPCODE_GET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].hinic3_fec_value) != 0)
+ *out_fec_param |=
+ fec_value_table[i].ethtool_fec_value;
+ }
+ }
+}
+
+/* When the ethtool is used to set the FEC mode */
+static bool check_fecparam_is_valid(u8 fec_param)
+{
+ if (
+#ifdef ETHTOOL_FEC_LLRS
+ (fec_param == ETHTOOL_FEC_LLRS) ||
+#endif
+ (fec_param == ETHTOOL_FEC_RS) ||
+ (fec_param == ETHTOOL_FEC_BASER) ||
+ (fec_param == ETHTOOL_FEC_OFF)) {
+ return true;
+ }
+ return false;
+}
+
+int set_fecparam(void *hwdev, u8 fecparam)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ u8 advertised_fec = 0;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (check_fecparam_is_valid(fecparam) == false) {
+ nic_err(nic_io->dev_hdl, "fec param is invalid, failed to set fec param\n");
+ return -EINVAL;
+ }
+ fecparam_convert(MAG_CMD_OPCODE_SET, fecparam, &advertised_fec);
+ fec_msg.opcode = MAG_CMD_OPCODE_SET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ fec_msg.advertised_fec = advertised_fec;
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0))
+ return -EINVAL;
+ return 0;
+}
+
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ fec_msg.opcode = MAG_CMD_OPCODE_GET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0))
+ return -EINVAL;
+
+ /* fec_msg.advertised_fec: bit offset,
+ *value is BIT(fec_msg.advertised_fec); fec_msg.supported_fec: value
+ */
+ fecparam_convert(MAG_CMD_OPCODE_GET, BIT(fec_msg.advertised_fec),
+ advertised_fec);
+ fecparam_convert(MAG_CMD_OPCODE_GET, fec_msg.supported_fec,
+ supported_fec);
+ return 0;
+}
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
index 307ad8d..7790ae2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
@@ -20,6 +20,9 @@
#include <linux/debugfs.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#include "hinic3_hw.h"
#include "hinic3_crm.h"
#include "hinic3_mt.h"
@@ -35,8 +38,8 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
#include "hinic3_profile.h"
+#include "hinic3_bond.h"
-/*lint -e806*/
#define DEFAULT_POLL_WEIGHT 64
static unsigned int poll_weight = DEFAULT_POLL_WEIGHT;
module_param(poll_weight, uint, 0444);
@@ -68,7 +71,9 @@ static unsigned char set_link_status_follow = HINIC3_LINK_FOLLOW_STATUS_MAX;
module_param(set_link_status_follow, byte, 0444);
MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=default,1=follow,2=separate,3=unset");
-/*lint +e806*/
+static bool page_pool_enabled = true;
+module_param(page_pool_enabled, bool, 0444);
+MODULE_PARM_DESC(page_pool_enabled, "enable/disable page_pool feature for rxq page management (default enable)");
#define HINIC3_NIC_DEV_WQ_NAME "hinic3_nic_dev_wq"
@@ -80,6 +85,8 @@ MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=
#define HINIC3_SQ_DEPTH 1024
#define HINIC3_RQ_DEPTH 1024
+#define LRO_ENABLE 1
+
enum hinic3_rx_buff_len {
RX_BUFF_VALID_2KB = 2,
RX_BUFF_VALID_4KB = 4,
@@ -88,6 +95,9 @@ enum hinic3_rx_buff_len {
};
#define CONVERT_UNIT 1024
+#define NIC_MAX_PF_NUM 32
+
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
static int hinic3_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr);
@@ -99,6 +109,17 @@ static struct notifier_block hinic3_netdev_notifier = {
.notifier_call = hinic3_netdev_event,
};
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+static const struct udp_tunnel_nic_info hinic3_udp_tunnels = {
+ .set_port = hinic3_udp_tunnel_set_port,
+ .unset_port = hinic3_udp_tunnel_unset_port,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static void hinic3_register_notifier(struct hinic3_nic_dev *nic_dev)
{
int err;
@@ -264,6 +285,11 @@ static void netdev_feature_init(struct net_device *netdev)
netdev->features |= dft_fts | cso_fts | tso_fts | vlan_fts;
netdev->vlan_features |= dft_fts | cso_fts | tso_fts;
+ if (nic_dev->nic_cap.lro_enable == LRO_ENABLE) {
+ netdev->features |= NETIF_F_LRO;
+ netdev->vlan_features |= NETIF_F_LRO;
+ }
+
#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT
hw_features |= get_netdev_hw_features(netdev);
#else
@@ -350,6 +376,7 @@ static int hinic3_init_intr_coalesce(struct hinic3_nic_dev *nic_dev)
static void hinic3_free_intr_coalesce(struct hinic3_nic_dev *nic_dev)
{
kfree(nic_dev->intr_coalesce);
+ nic_dev->intr_coalesce = NULL;
}
static int hinic3_alloc_txrxqs(struct hinic3_nic_dev *nic_dev)
@@ -404,8 +431,85 @@ static void hinic3_sw_deinit(struct hinic3_nic_dev *nic_dev)
HINIC3_CHANNEL_NIC);
hinic3_clear_rss_config(nic_dev);
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+ hinic3_dcb_deinit(nic_dev);
+}
+
+static void hinic3_netdev_mtu_init(struct net_device *netdev)
+{
+ /* MTU range: 384 - 9600 */
+#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
+ netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+
+#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
+ netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+}
+
+static int hinic3_set_default_mac(struct hinic3_nic_dev *nic_dev)
+{
+ struct net_device *netdev = nic_dev->netdev;
+ u8 mac_addr[ETH_ALEN];
+ int err = 0;
+
+ err = hinic3_get_default_mac(nic_dev->hwdev, mac_addr);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev, "Failed to get MAC address\n");
+ return err;
+ }
+
+ ether_addr_copy(netdev->dev_addr, mac_addr);
+
+ if (!is_valid_ether_addr(netdev->dev_addr)) {
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
+ nic_err(&nic_dev->pdev->dev,
+ "Invalid MAC address %pM\n",
+ netdev->dev_addr);
+ return -EIO;
+ }
+
+ nic_info(&nic_dev->pdev->dev,
+ "Invalid MAC address %pM, using random\n",
+ netdev->dev_addr);
+ eth_hw_addr_random(netdev);
+ }
+
+ err = hinic3_set_mac(nic_dev->hwdev, netdev->dev_addr, 0,
+ hinic3_global_func_id(nic_dev->hwdev),
+ HINIC3_CHANNEL_NIC);
+ /* When this is VF driver, we must consider that PF has already set VF
+ * MAC, and we can't consider this condition is error status during
+ * driver probe procedure.
+ */
+ if (err && err != HINIC3_PF_SET_VF_ALREADY) {
+ nic_err(&nic_dev->pdev->dev, "Failed to set default MAC\n");
+ }
+
+ if (err == HINIC3_PF_SET_VF_ALREADY)
+ return 0;
+
+ return err;
+}
+
+static void hinic3_outband_cfg_init(struct hinic3_nic_dev *nic_dev)
+{
+ u16 outband_default_vid = 0;
+ int err = 0;
+
+ if (!nic_dev->nic_cap.outband_vlan_cfg_en)
+ return;
+
+ err = hinic3_get_outband_vlan_cfg(nic_dev->hwdev, &outband_default_vid);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev, "Failed to get_outband_cfg, err: %d\n", err);
+ return;
+ }
+
+ nic_dev->outband_cfg.outband_default_vid = outband_default_vid;
+
+ return;
}
static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
@@ -421,8 +525,6 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
nic_features &= NIC_DRV_DEFAULT_FEATURE;
hinic3_update_nic_feature(nic_dev->hwdev, nic_features);
- sema_init(&nic_dev->port_state_sem, 1);
-
err = hinic3_dcb_init(nic_dev);
if (err) {
nic_err(&nic_dev->pdev->dev, "Failed to init dcb\n");
@@ -434,47 +536,12 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
hinic3_try_to_enable_rss(nic_dev);
- err = hinic3_get_default_mac(nic_dev->hwdev, netdev->dev_addr);
+ err = hinic3_set_default_mac(nic_dev);
if (err) {
- nic_err(&nic_dev->pdev->dev, "Failed to get MAC address\n");
- goto get_mac_err;
- }
-
- if (!is_valid_ether_addr(netdev->dev_addr)) {
- if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- nic_err(&nic_dev->pdev->dev, "Invalid MAC address %pM\n",
- netdev->dev_addr);
- err = -EIO;
- goto err_mac;
- }
-
- nic_info(&nic_dev->pdev->dev, "Invalid MAC address %pM, using random\n",
- netdev->dev_addr);
- eth_hw_addr_random(netdev);
- }
-
- err = hinic3_set_mac(nic_dev->hwdev, netdev->dev_addr, 0,
- hinic3_global_func_id(nic_dev->hwdev),
- HINIC3_CHANNEL_NIC);
- /* When this is VF driver, we must consider that PF has already set VF
- * MAC, and we can't consider this condition is error status during
- * driver probe procedure.
- */
- if (err && err != HINIC3_PF_SET_VF_ALREADY) {
- nic_err(&nic_dev->pdev->dev, "Failed to set default MAC\n");
goto set_mac_err;
}
- /* MTU range: 384 - 9600 */
-#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
- netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
-
-#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
- netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
+ hinic3_netdev_mtu_init(netdev);
err = hinic3_alloc_txrxqs(nic_dev);
if (err) {
@@ -482,6 +549,8 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
goto alloc_qps_err;
}
+ hinic3_outband_cfg_init(nic_dev);
+
return 0;
alloc_qps_err:
@@ -490,8 +559,6 @@ alloc_qps_err:
HINIC3_CHANNEL_NIC);
set_mac_err:
-err_mac:
-get_mac_err:
hinic3_clear_rss_config(nic_dev);
return err;
@@ -690,20 +757,51 @@ static void hinic3_periodic_work_handler(struct work_struct *work)
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
}
+static void hinic3_vport_stats_work_handler(struct work_struct *work)
+{
+ int err;
+ struct hinic3_vport_stats vport_stats = {0};
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_nic_dev *nic_dev = container_of(delay, struct hinic3_nic_dev, vport_stats_work);
+ err = hinic3_get_vport_stats(nic_dev->hwdev, hinic3_global_func_id(nic_dev->hwdev), &vport_stats);
+ if (err)
+ nic_err(&nic_dev->pdev->dev, "Failed to get dropped stats from fw\n");
+ else
+ nic_dev->vport_stats.rx_discard_vport = vport_stats.rx_discard_vport;
+ queue_delayed_work(nic_dev->workq, &nic_dev->vport_stats_work, HZ);
+}
+
+static void free_nic_dev_vram(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)nic_dev->nic_vram, nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ else
+ kfree(nic_dev->nic_vram);
+ nic_dev->nic_vram = NULL;
+}
+
static void free_nic_dev(struct hinic3_nic_dev *nic_dev)
{
hinic3_deinit_nic_prof_adapter(nic_dev);
destroy_workqueue(nic_dev->workq);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+ free_nic_dev_vram(nic_dev);
}
static int setup_nic_dev(struct net_device *netdev,
struct hinic3_lld_dev *lld_dev)
{
struct pci_dev *pdev = lld_dev->pdev;
- struct hinic3_nic_dev *nic_dev;
- char *netdev_name_fmt;
+ struct hinic3_nic_dev *nic_dev = NULL;
+ char *netdev_name_fmt = NULL;
u32 page_num;
+ u16 func_id;
+ int ret;
+ int is_in_kexec = vram_get_kexec_flag();
+ int is_use_vram = get_use_vram_flag();
nic_dev = (struct hinic3_nic_dev *)netdev_priv(netdev);
nic_dev->netdev = netdev;
@@ -718,24 +816,65 @@ static int setup_nic_dev(struct net_device *netdev,
nic_dev->dma_rx_buff_size = RX_BUFF_NUM_PER_PAGE * nic_dev->rx_buff_len;
page_num = nic_dev->dma_rx_buff_size / PAGE_SIZE;
nic_dev->page_order = page_num > 0 ? ilog2(page_num) : 0;
+ nic_dev->page_pool_enabled = page_pool_enabled;
+ nic_dev->outband_cfg.outband_default_vid = 0;
+
+ // value other than 0 indicates hot replace
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ ret = snprintf(nic_dev->nic_vram_name,
+ VRAM_NAME_MAX_LEN,
+ "%s%u", VRAM_NIC_VRAM, func_id);
+ if (ret < 0) {
+ nic_err(&pdev->dev, "NIC vram name snprintf failed, ret:%d.\n",
+ ret);
+ return -EINVAL;
+ }
+
+ nic_dev->nic_vram = (struct hinic3_vram *)hi_vram_kalloc(nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+
+ if (is_in_kexec == 0)
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ else
+ netdev->mtu = nic_dev->nic_vram->vram_mtu;
+ } else {
+ nic_dev->nic_vram = kzalloc(sizeof(struct hinic3_vram),
+ GFP_KERNEL);
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ }
mutex_init(&nic_dev->nic_mutex);
nic_dev->vlan_bitmap = kzalloc(VLAN_BITMAP_SIZE(nic_dev), GFP_KERNEL);
if (!nic_dev->vlan_bitmap) {
nic_err(&pdev->dev, "Failed to allocate vlan bitmap\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto vlan_bitmap_error;
}
nic_dev->workq = create_singlethread_workqueue(HINIC3_NIC_DEV_WQ_NAME);
if (!nic_dev->workq) {
nic_err(&pdev->dev, "Failed to initialize nic workqueue\n");
- kfree(nic_dev->vlan_bitmap);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto create_workq_error;
}
- INIT_DELAYED_WORK(&nic_dev->periodic_work, hinic3_periodic_work_handler);
- INIT_DELAYED_WORK(&nic_dev->rxq_check_work, hinic3_rxq_check_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->periodic_work,
+ hinic3_periodic_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->rxq_check_work,
+ hinic3_rxq_check_work_handler);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ INIT_DELAYED_WORK(&nic_dev->vport_stats_work,
+ hinic3_vport_stats_work_handler);
INIT_LIST_HEAD(&nic_dev->uc_filter_list);
INIT_LIST_HEAD(&nic_dev->mc_filter_list);
@@ -748,10 +887,23 @@ static int setup_nic_dev(struct net_device *netdev,
hinic3_init_nic_prof_adapter(nic_dev);
netdev_name_fmt = hinic3_get_dft_netdev_name_fmt(nic_dev);
- if (netdev_name_fmt)
- strncpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (netdev_name_fmt) {
+ ret = strscpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (ret < 0)
+ goto get_netdev_name_error;
+ }
return 0;
+
+get_netdev_name_error:
+ hinic3_deinit_nic_prof_adapter(nic_dev);
+ destroy_workqueue(nic_dev->workq);
+create_workq_error:
+ kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+vlan_bitmap_error:
+ free_nic_dev_vram(nic_dev);
+ return ret;
}
static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
@@ -790,6 +942,32 @@ static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
return 0;
}
+static void hinic3_bond_init(struct hinic3_nic_dev *nic_dev)
+{
+ u32 bond_id = HINIC3_INVALID_BOND_ID;
+ int err = hinic3_create_bond(nic_dev->hwdev, &bond_id);
+ if (err != 0) {
+ goto bond_init_failed;
+ }
+
+ /* bond id does not change, means this pf is not bond active pf, no log is generated */
+ if (bond_id == HINIC3_INVALID_BOND_ID) {
+ return;
+ }
+
+ err = hinic3_open_close_bond(nic_dev->hwdev, true);
+ if (err != 0) {
+ hinic3_delete_bond(nic_dev->hwdev);
+ goto bond_init_failed;
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Bond %d init success\n", bond_id);
+ return;
+
+bond_init_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond init failed\n");
+}
+
static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
char *uld_dev_name)
{
@@ -820,6 +998,12 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
goto err_out;
}
+ err = hinic3_get_dev_cap(lld_dev->hwdev);
+ if (err != 0) {
+ nic_err(&pdev->dev, "Failed to get dev cap\n");
+ goto err_out;
+ }
+
max_qps = hinic3_func_max_nic_qnum(lld_dev->hwdev);
netdev = alloc_etherdev_mq(sizeof(*nic_dev), max_qps);
if (!netdev) {
@@ -851,23 +1035,35 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
hinic3_assign_netdev_ops(nic_dev);
netdev_feature_init(netdev);
-
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+ netdev->udp_tunnel_nic_info = &hinic3_udp_tunnels;
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
err = hinic3_set_default_hw_feature(nic_dev);
if (err)
goto set_features_err;
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0) {
+ hinic3_bond_init(nic_dev);
+ }
+
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
hinic3_register_notifier(nic_dev);
#endif
- err = register_netdev(netdev);
- if (err) {
- nic_err(&pdev->dev, "Failed to register netdev\n");
- err = -ENOMEM;
- goto netdev_err;
+ if (pdev->subsystem_device != BIFUR_RESOURCE_PF_SSID) {
+ err = register_netdev(netdev);
+ if (err) {
+ nic_err(&pdev->dev, "Failed to register netdev\n");
+ err = -ENOMEM;
+ goto netdev_err;
+ }
}
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->vport_stats_work, HZ);
+
netif_carrier_off(netdev);
*uld_dev = nic_dev;
@@ -900,6 +1096,27 @@ err_out:
return err;
}
+static void hinic3_bond_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ int ret = 0;
+
+ ret = hinic3_open_close_bond(nic_dev->hwdev, false);
+ if (ret != 0) {
+ goto bond_deinit_failed;
+ }
+
+ ret = hinic3_delete_bond(nic_dev->hwdev);
+ if (ret != 0) {
+ goto bond_deinit_failed;
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Bond deinit success\n");
+ return;
+
+bond_deinit_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond deinit failed\n");
+}
+
static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
{
struct hinic3_nic_dev *nic_dev = adapter;
@@ -912,11 +1129,16 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
netdev = nic_dev->netdev;
- unregister_netdev(netdev);
+ if (lld_dev->pdev->subsystem_device != BIFUR_RESOURCE_PF_SSID) {
+ unregister_netdev(netdev);
+ }
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
hinic3_unregister_notifier(nic_dev);
#endif
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ cancel_delayed_work_sync(&nic_dev->vport_stats_work);
+
cancel_delayed_work_sync(&nic_dev->periodic_work);
cancel_delayed_work_sync(&nic_dev->rxq_check_work);
cancel_work_sync(&nic_dev->rx_mode_work);
@@ -924,6 +1146,10 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_flush_rx_flow_rule(nic_dev);
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0) {
+ hinic3_bond_deinit(nic_dev);
+ }
+
hinic3_update_nic_feature(nic_dev->hwdev, 0);
hinic3_set_nic_feature_to_hw(nic_dev->hwdev);
@@ -933,6 +1159,7 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_deinit_nic_prof_adapter(nic_dev);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
free_netdev(netdev);
@@ -981,6 +1208,120 @@ static void hinic3_port_module_event_handler(struct hinic3_nic_dev *nic_dev,
}
}
+bool hinic3_need_proc_link_event(struct hinic3_lld_dev *lld_dev)
+{
+ int ret = 0;
+ u16 func_id;
+ u8 roce_enable = false;
+ bool is_slave_func = false;
+ struct hinic3_hw_bond_infos hw_bond_infos = {0};
+
+ if (!lld_dev)
+ return false;
+
+ /* 非slave设备需要处理link down事件 */
+ ret = hinic3_is_slave_func(lld_dev->hwdev, &is_slave_func);
+ if (ret != 0) {
+ nic_err(&lld_dev->pdev->dev, "NIC get info, lld_dev is null\n");
+ return true;
+ }
+
+ if (!is_slave_func)
+ return true;
+
+ /* 未使能了vroce功能,需处理link down事件 */
+ func_id = hinic3_global_func_id(lld_dev->hwdev);
+ ret = hinic3_get_func_vroce_enable(lld_dev->hwdev, func_id,
+ &roce_enable);
+ if (ret != 0)
+ return true;
+
+ if (!roce_enable)
+ return true;
+
+ /* 未创建bond,需要处理link down事件 */
+ hw_bond_infos.bond_id = HINIC_OVS_BOND_DEFAULT_ID;
+
+ ret = hinic3_get_hw_bond_infos(lld_dev->hwdev, &hw_bond_infos,
+ HINIC3_CHANNEL_COMM);
+ if (ret != 0) {
+ pr_err("[ROCE, ERR] Get chipf bond info failed (%d)\n", ret);
+ return true;
+ }
+
+ if (!hw_bond_infos.valid)
+ return true;
+
+ return false;
+}
+
+bool hinic3_need_proc_bond_event(struct hinic3_lld_dev *lld_dev)
+{
+ return !hinic3_need_proc_link_event(lld_dev);
+}
+
+static void hinic_porc_bond_state_change(struct hinic3_lld_dev *lld_dev,
+ void *adapter,
+ struct hinic3_event_info *event)
+{
+ struct hinic3_nic_dev *nic_dev = adapter;
+
+ if (!nic_dev || !event || !hinic3_support_nic(lld_dev->hwdev, NULL))
+ return;
+
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond down\n");
+ hinic3_link_status_change(nic_dev, false);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond up\n");
+ hinic3_link_status_change(nic_dev, true);
+ break;
+ default:
+ break;
+ }
+}
+
+static void hinic3_outband_cfg_event_handler(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_outband_cfg_info *info)
+{
+ int err = 0;
+ if (!nic_dev || !info || !hinic3_support_nic(nic_dev->hwdev, NULL)) {
+ pr_err("Outband cfg event invalid param\n");
+ return;
+ }
+
+ if (hinic3_func_type(nic_dev->hwdev) != TYPE_VF &&
+ info->func_id >= NIC_MAX_PF_NUM) {
+ err = hinic3_notify_vf_outband_cfg(nic_dev->hwdev,
+ info->func_id,
+ info->outband_default_vid);
+ if (err)
+ nic_err(&nic_dev->pdev->dev, "Outband cfg event notify vf err: %d,"
+ "func_id: 0x%x, vid: 0x%x\n",
+ err, info->func_id, info->outband_default_vid);
+ return;
+ }
+
+ nic_info(&nic_dev->pdev->dev,
+ "Change outband default vid from %u to %u\n",
+ nic_dev->outband_cfg.outband_default_vid,
+ info->outband_default_vid);
+
+ nic_dev->outband_cfg.outband_default_vid = info->outband_default_vid;
+
+ return;
+}
+
static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
struct hinic3_event_info *event)
{
@@ -992,14 +1333,25 @@ static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_DOWN):
+ if (!hinic3_need_proc_link_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc link event\n");
+ return;
+ }
hinic3_link_status_change(nic_dev, false);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_UP):
hinic3_link_status_change(nic_dev, true);
break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ hinic_porc_bond_state_change(lld_dev, adapter, event);
+ break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_PORT_MODULE_EVENT):
hinic3_port_module_event_handler(nic_dev, event);
break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_OUTBAND_CFG):
+ hinic3_outband_cfg_event_handler(nic_dev, (void *)event->event_data);
+ break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_SRIOV_STATE_CHANGE):
sriov_state_change(nic_dev, (void *)event->event_data);
break;
@@ -1059,7 +1411,7 @@ struct hinic3_uld_info g_nic_uld_info = {
.resume = NULL,
.event = nic_event,
.ioctl = nic_ioctl,
-}; /*lint -e766*/
+};
struct hinic3_uld_info *get_nic_uld_info(void)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
index 774193a..7bc9376 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
@@ -4,11 +4,12 @@
#ifndef HINIC3_MT_H
#define HINIC3_MT_H
-#define HINIC3_DRV_NAME "hisdk3"
+#define HINIC3_DRV_NAME "hinic3"
#define HINIC3_CHIP_NAME "hinic"
/* Interrupt at most records, interrupt will be recorded in the FFM */
#define NICTOOL_CMD_TYPE (0x18)
+#define HINIC3_CARD_NAME_MAX_LEN (128)
struct api_cmd_rd {
u32 pf_id;
@@ -110,7 +111,8 @@ enum dbgtool_cmd {
DBGTOOL_CMD_NUM
};
-#define PF_MAX_SIZE (16)
+#define HINIC_PF_MAX_SIZE (16)
+#define HINIC_VF_MAX_SIZE (4096)
#define BUSINFO_LEN (32)
enum module_name {
@@ -132,7 +134,9 @@ enum module_name {
SEND_TO_MIGRATE_DRIVER,
SEND_TO_PPA_DRIVER,
SEND_TO_CUSTOM_DRIVER = SEND_TO_SRV_DRV_BASE + 11,
- SEND_TO_DRIVER_MAX = SEND_TO_SRV_DRV_BASE + 15, /* reserved */
+ SEND_TO_VSOCK_DRIVER = SEND_TO_SRV_DRV_BASE + 14,
+ SEND_TO_BIFUR_DRIVER,
+ SEND_TO_DRIVER_MAX = SEND_TO_SRV_DRV_BASE + 16, /* reserved */
};
enum driver_cmd_type {
@@ -159,7 +163,7 @@ enum driver_cmd_type {
GET_CHIP_FAULT_STATS,
NIC_RSVD1,
NIC_RSVD2,
- NIC_RSVD3,
+ GET_OS_HOT_REPLACE_INFO,
GET_CHIP_ID,
GET_SINGLE_CARD_INFO,
GET_FIRMWARE_ACTIVE_STATUS,
@@ -170,7 +174,7 @@ enum driver_cmd_type {
GET_LOOPBACK_MODE = 32,
SET_LOOPBACK_MODE,
SET_LINK_MODE,
- SET_PF_BW_LIMIT,
+ SET_TX_PF_BW_LIMIT,
GET_PF_BW_LIMIT,
ROCE_CMD,
GET_POLL_WEIGHT,
@@ -188,6 +192,7 @@ enum driver_cmd_type {
GET_NIC_STATS_STRING,
GET_NIC_STATS_INFO,
GET_PF_ID,
+ GET_MBOX_CNT,
NIC_RSVD4,
NIC_RSVD5,
DCB_QOS_INFO,
@@ -204,16 +209,54 @@ enum driver_cmd_type {
RSS_INDIR,
PORT_ID,
+ SET_RX_PF_BW_LIMIT = 0x43,
+
GET_FUNC_CAP = 0x50,
GET_XSFP_PRESENT = 0x51,
GET_XSFP_INFO = 0x52,
DEV_NAME_TEST = 0x53,
+ GET_XSFP_INFO_COMP_CMIS = 0x54,
GET_WIN_STAT = 0x60,
WIN_CSR_READ = 0x61,
WIN_CSR_WRITE = 0x62,
WIN_API_CMD_RD = 0x63,
+ GET_FUSION_Q = 0x64,
+ ROCE_CMD_SET_LDCP_PARAM = 0x70,
+
+ ROCE_CMD_GET_QPC_FROM_CACHE = 0x80,
+ ROCE_CMD_GET_QPC_FROM_HOST = 0x81,
+ ROCE_CMD_GET_CQC_FROM_CACHE = 0x82,
+ ROCE_CMD_GET_CQC_FROM_HOST = 0x83,
+ ROCE_CMD_GET_SRQC_FROM_CACHE = 0x84,
+ ROCE_CMD_GET_SRQC_FROM_HOST = 0x85,
+ ROCE_CMD_GET_MPT_FROM_CACHE = 0x86,
+ ROCE_CMD_GET_MPT_FROM_HOST = 0x87,
+ ROCE_CMD_GET_GID_FROM_CACHE = 0x88,
+ ROCE_CMD_GET_QPC_CQC_PI_CI = 0x89,
+ ROCE_CMD_GET_QP_COUNT = 0x8a,
+ ROCE_CMD_GET_DEV_ALGO = 0x8b,
+
+ ROCE_CMD_START_CAP_PACKET = 0x90,
+ ROCE_CMD_STOP_CAP_PACKET = 0x91,
+ ROCE_CMD_QUERY_CAP_INFO = 0x92,
+ ROCE_CMD_ENABLE_QP_CAP_PACKET = 0x93,
+ ROCE_CMD_DISABLE_QP_CAP_PACKET = 0x94,
+ ROCE_CMD_QUERY_QP_CAP_INFO = 0x95,
+
+ ROCE_CMD_ENABLE_BW_CTRL = 0xa0,
+ ROCE_CMD_DISABLE_BW_CTRL = 0xa1,
+ ROCE_CMD_CHANGE_BW_CTRL_PARAM = 0xa2,
+ ROCE_CMD_QUERY_BW_CTRL_PARAM = 0xa3,
+
+ ROCE_CMD_TIMEOUT_ALARM = 0xb0,
+ ROCE_CMD_PORT_TRAFFIC = 0Xb1,
+ ROCE_CMD_BOND_HASH_TYPE_SET = 0xb2,
+
+ BIFUR_SET_ENABLE = 0xc0,
+ BIFUR_GET_ENABLE = 0xc1,
+
VM_COMPAT_TEST = 0xFF
};
@@ -229,7 +272,8 @@ enum sm_cmd_type {
SM_CTR_RD64,
SM_CTR_RD32_CLEAR,
SM_CTR_RD64_PAIR_CLEAR,
- SM_CTR_RD64_CLEAR
+ SM_CTR_RD64_CLEAR,
+ SM_CTR_RD16_CLEAR,
};
struct cqm_stats {
@@ -317,10 +361,22 @@ struct pf_info {
};
struct card_info {
- struct pf_info pf[PF_MAX_SIZE];
+ struct pf_info pf[HINIC_PF_MAX_SIZE];
u32 pf_num;
};
+struct func_mbox_cnt_info {
+ char bus_info[BUSINFO_LEN];
+ u64 send_cnt;
+ u64 ack_cnt;
+};
+
+struct card_mbox_cnt_info {
+ struct func_mbox_cnt_info func_info[HINIC_PF_MAX_SIZE +
+ HINIC_VF_MAX_SIZE];
+ u32 func_num;
+};
+
struct hinic3_nic_loop_mode {
u32 loop_mode;
u32 loop_ctrl;
@@ -661,6 +717,161 @@ struct get_card_bond_msg_s {
struct bond_all_msg_s all_msg[MAX_BONDING_CNT_PER_CARD];
};
+#define MAX_FUSION_Q_STATS_STR_LEN 16
+#define MAX_FUSION_Q_NUM 256
+struct queue_status_s {
+ pid_t tgid;
+ char status[MAX_FUSION_Q_STATS_STR_LEN];
+};
+struct fusion_q_status_s {
+ u16 queue_num;
+ struct queue_status_s queue[MAX_FUSION_Q_NUM];
+};
+
+struct fusion_q_tx_hw_page {
+ u64 phy_addr;
+ u64 *map_addr;
+};
+
+struct fusion_sq_info {
+ u16 q_id;
+ u16 pi;
+ u16 ci; /* sw_ci */
+ u16 fi; /* hw_ci */
+ u32 q_depth;
+ u16 pi_reverse;
+ u16 wqebb_size;
+ u8 priority;
+ u16 *ci_addr;
+ u64 cla_addr;
+ void *slq_handle;
+ struct fusion_q_tx_hw_page direct_wqe;
+ struct fusion_q_tx_hw_page doorbell;
+ u32 page_idx;
+ u32 glb_sq_id;
+};
+
+struct fusion_q_tx_wqe {
+ u32 data[4];
+};
+
+struct fusion_rq_info {
+ u16 q_id;
+ u16 delta;
+ u16 hw_pi;
+ u16 ci; /* sw_ci */
+ u16 sw_pi;
+ u16 wqebb_size;
+ u16 q_depth;
+ u16 buf_len;
+
+ void *slq_handle;
+ u64 ci_wqe_page_addr;
+ u64 ci_cla_tbl_addr;
+
+ u8 coalesc_timer_cfg;
+ u8 pending_limt;
+ u16 msix_idx;
+ u32 msix_vector;
+};
+
+struct fusion_q_rx_wqe {
+ u32 data[8];
+};
+
+struct fusion_q_rx_cqe {
+ union {
+ struct {
+ unsigned int checksum_err : 16;
+ unsigned int lro_num : 8;
+ unsigned int rsvd1 : 7;
+ unsigned int rx_done : 1;
+ } bs;
+ unsigned int value;
+ } dw0;
+
+ union {
+ struct {
+ unsigned int vlan : 16;
+ unsigned int length : 16;
+ } bs;
+ unsigned int value;
+ } dw1;
+
+ union {
+ struct {
+ unsigned int pkt_types : 12;
+ unsigned int rsvd : 4;
+ unsigned int udp_0 : 1;
+ unsigned int ipv6_ex_add : 1;
+ unsigned int loopback : 1;
+ unsigned int umbcast : 2;
+ unsigned int vlan_offload_en : 1;
+ unsigned int tag_num : 2;
+ unsigned int rss_type : 8;
+ } bs;
+ unsigned int value;
+ } dw2;
+
+ union {
+ struct {
+ unsigned int rss_hash_value;
+ } bs;
+ unsigned int value;
+ } dw3;
+
+ union {
+ struct {
+ unsigned int tx_ts_seq : 16;
+ unsigned int message_1588_offset : 8;
+ unsigned int message_1588_type : 4;
+ unsigned int rsvd : 1;
+ unsigned int if_rx_ts : 1;
+ unsigned int if_tx_ts : 1;
+ unsigned int if_1588 : 1;
+ } bs;
+ unsigned int value;
+ } dw4;
+
+ union {
+ struct {
+ unsigned int ts;
+ } bs;
+ unsigned int value;
+ } dw5;
+
+ union {
+ struct {
+ unsigned int lro_ts;
+ } bs;
+ unsigned int value;
+ } dw6;
+
+ union {
+ struct {
+ unsigned int rsvd0;
+ } bs;
+ unsigned int value;
+ } dw7; /* 16Bytes Align */
+};
+
+struct os_hot_repalce_func_info {
+ char card_name[HINIC3_CARD_NAME_MAX_LEN];
+ int bus_num;
+ int valid;
+ int bdf;
+ int partition;
+ int backup_pf;
+ int pf_idx;
+ int port_id;
+};
+
+#define ALL_CARD_PF_NUM 2048 /* 64 card * 32 pf */
+struct os_hot_replace_info {
+ struct os_hot_repalce_func_info func_infos[ALL_CARD_PF_NUM];
+ u32 func_cnt;
+};
+
int alloc_buff_in(void *hwdev, struct msg_module *nt_msg, u32 in_size, void **buf_in);
int alloc_buff_out(void *hwdev, struct msg_module *nt_msg, u32 out_size, void **buf_out);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
index 81e4030..7cd9e4d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
@@ -15,6 +15,9 @@
#include <linux/ip.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#ifdef HAVE_XDP_SUPPORT
#include <linux/bpf.h>
#endif
@@ -28,6 +31,10 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
+#include "nic_npu_cmd.h"
+
+#include "vram_common.h"
+
#define HINIC3_DEFAULT_RX_CSUM_OFFLOAD 0xFFF
#define HINIC3_LRO_DEFAULT_COAL_PKT_SIZE 32
@@ -47,8 +54,64 @@ static void hinic3_nic_set_rx_mode(struct net_device *netdev)
queue_work(nic_dev->workq, &nic_dev->rx_mode_work);
}
+static void hinic3_free_irq_vram(struct hinic3_nic_dev *nic_dev, struct hinic3_dyna_txrxq_params *in_q_params)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ struct hinic3_dyna_txrxq_params q_params = nic_dev->q_params;
+
+ if (q_params.irq_cfg == NULL)
+ return;
+
+ size = sizeof(struct hinic3_irq) * (q_params.num_qps);
+
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)q_params.irq_cfg, q_params.irq_cfg_vram_name, size);
+ q_params.irq_cfg = NULL;
+ } else {
+ kfree(in_q_params->irq_cfg);
+ in_q_params->irq_cfg = NULL;
+ }
+}
+
+static int hinic3_alloc_irq_vram(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_dyna_txrxq_params *q_params, bool is_up_eth)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ u16 func_id;
+
+ size = sizeof(struct hinic3_irq) * q_params->num_qps;
+
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(q_params->irq_cfg_vram_name,
+ VRAM_NAME_MAX_LEN, "%s%u",
+ VRAM_NIC_IRQ_VRAM, func_id);
+ q_params->irq_cfg = (struct hinic3_irq *)hi_vram_kalloc(
+ q_params->irq_cfg_vram_name, size);
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq vram alloc failed.\n");
+ return -ENOMEM;
+ }
+ /* in order to clear napi stored in vram, irq need to init when eth up */
+ if (is_up_eth) {
+ memset(q_params->irq_cfg, 0, size);
+ }
+ } else {
+ q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq alloc failed.\n");
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_txrxq_params *q_params)
+ struct hinic3_dyna_txrxq_params *q_params,
+ bool is_up_eth)
{
u32 size;
int err;
@@ -70,12 +133,9 @@ static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
goto alloc_rxqs_res_arr_err;
}
- size = sizeof(*q_params->irq_cfg) * q_params->num_qps;
- q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
- if (!q_params->irq_cfg) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to alloc irq resource array\n");
- err = -ENOMEM;
+ err = hinic3_alloc_irq_vram(nic_dev, q_params, is_up_eth);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc irq resource array\n");
goto alloc_irq_cfg_err;
}
@@ -102,8 +162,7 @@ alloc_rxqs_res_err:
q_params->txqs_res);
alloc_txqs_res_err:
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ hinic3_free_irq_vram(nic_dev, q_params);
alloc_irq_cfg_err:
kfree(q_params->rxqs_res);
@@ -119,13 +178,14 @@ alloc_rxqs_res_arr_err:
static void hinic3_free_txrxq_resources(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_txrxq_params *q_params)
{
+ int is_in_kexec = vram_get_kexec_flag();
hinic3_free_rxqs_res(nic_dev, q_params->num_qps, q_params->rq_depth,
q_params->rxqs_res);
hinic3_free_txqs_res(nic_dev, q_params->num_qps, q_params->sq_depth,
q_params->txqs_res);
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ if (is_in_kexec == 0)
+ hinic3_free_irq_vram(nic_dev, q_params);
kfree(q_params->rxqs_res);
q_params->rxqs_res = NULL;
@@ -161,6 +221,7 @@ static int hinic3_configure_txrxqs(struct hinic3_nic_dev *nic_dev,
static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos;
if (!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
@@ -171,12 +232,13 @@ static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
num_cos = hinic3_get_dev_user_cos_num(nic_dev);
hinic3_update_qp_cos_cfg(nic_dev, num_cos);
/* For now, we don't support to change num_cos */
- if (num_cos > nic_dev->cos_config_num_max ||
+ if (num_cos > dcb->cos_config_num_max ||
nic_dev->q_params.num_qps < num_cos) {
nicif_err(nic_dev, drv, netdev, "Invalid num_cos: %u or num_qps: %u, disable DCB\n",
num_cos, nic_dev->q_params.num_qps);
nic_dev->q_params.num_cos = 0;
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
/* if we can't enable rss or get enough num_qps,
* need to sync default configure to hw
*/
@@ -190,11 +252,14 @@ static int hinic3_configure(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
- err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
- if (err) {
- nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
- return err;
+ if (is_in_kexec == 0) {
+ err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
+ return err;
+ }
}
config_dcb_qps_map(nic_dev);
@@ -256,10 +321,11 @@ static void config_dcb_num_qps(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dyna_txrxq_params *q_params,
u16 max_qps)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos = q_params->num_cos;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (!num_cos || num_cos > nic_dev->cos_config_num_max || num_cos > max_qps)
+ if (!num_cos || num_cos > dcb->cos_config_num_max || num_cos > max_qps)
return; /* will disable DCB in config_dcb_qps_map() */
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
@@ -334,57 +400,10 @@ static void hinic3_destroy_num_qps(struct hinic3_nic_dev *nic_dev)
kfree(nic_dev->qps_irq_info);
}
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev)
-{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- err = hinic3_set_port_enable(nic_dev->hwdev, false, HINIC3_CHANNEL_NIC);
- if (!err)
- nic_dev->force_port_disable = true;
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
-{
- int err = 0;
-
- down(&nic_dev->port_state_sem);
-
- nic_dev->force_port_disable = false;
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
- HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- /* Do nothing when force disable
- * Port will disable when call force port disable
- * and should not enable port when in force mode
- */
- if (nic_dev->force_port_disable) {
- up(&nic_dev->port_state_sem);
- return 0;
- }
-
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
+ return hinic3_set_port_enable(nic_dev->hwdev, enable,
HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
}
static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
@@ -401,7 +420,8 @@ static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+ struct hinic3_dyna_txrxq_params *trxq_params,
+ bool is_up_eth)
{
int err;
@@ -416,7 +436,7 @@ static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
return err;
}
- err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params);
+ err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params, is_up_eth);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc txrxq resources\n");
hinic3_free_qps(nic_dev->hwdev, qp_params);
@@ -544,9 +564,53 @@ vport_enable_err:
return err;
}
+static int hinic3_flush_rq_and_check(struct hinic3_nic_dev *nic_dev,
+ u16 glb_func_id)
+{
+ struct hinic3_flush_rq *rq_flush_msg = NULL;
+ struct hinic3_cmd_buf *cmd_buf = NULL;
+ int out_buf_len = sizeof(struct hinic3_flush_rq);
+ u16 rq_id;
+ u64 out_param = 0;
+ int ret;
+
+ cmd_buf = hinic3_alloc_cmd_buf(nic_dev->hwdev);
+ if (!cmd_buf) {
+ nic_err(&nic_dev->pdev->dev, "Failed to allocate cmd buf\n");
+ return -ENOMEM;
+ }
+
+ cmd_buf->size = sizeof(struct hinic3_flush_rq);
+ rq_flush_msg = (struct hinic3_flush_rq *)cmd_buf->buf;
+ rq_flush_msg->dw.bs.func_id = glb_func_id;
+ for (rq_id = 0; rq_id < nic_dev->q_params.num_qps; rq_id++) {
+ rq_flush_msg->dw.bs.rq_id = rq_id;
+ hinic3_cpu_to_be32(rq_flush_msg, out_buf_len);
+ ret = hinic3_cmdq_direct_resp(nic_dev->hwdev, HINIC3_MOD_L2NIC,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ cmd_buf, &out_param, 0,
+ HINIC3_CHANNEL_NIC);
+ if (ret != 0 || out_param != 0) {
+ nic_err(&nic_dev->pdev->dev, "Failed to flush rq, ret:%d, func:%u, rq:%u\n",
+ ret, glb_func_id, rq_id);
+ goto err;
+ }
+ hinic3_be32_to_cpu(rq_flush_msg, out_buf_len);
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Func:%u rq_num:%u flush rq success\n",
+ glb_func_id, nic_dev->q_params.num_qps);
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return 0;
+err:
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return -1;
+}
+
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
{
u16 glb_func_id;
+ int is_in_kexec = vram_get_kexec_flag();
netif_carrier_off(nic_dev->netdev);
netif_tx_disable(nic_dev->netdev);
@@ -559,18 +623,21 @@ void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, 0);
- hinic3_maybe_set_port_state(nic_dev, false);
+ if (is_in_kexec != 0)
+ nicif_info(nic_dev, drv, nic_dev->netdev, "Skip changing mag status!\n");
+ else
+ hinic3_maybe_set_port_state(nic_dev, false);
glb_func_id = hinic3_global_func_id(nic_dev->hwdev);
hinic3_set_vport_enable(nic_dev->hwdev, glb_func_id, false,
HINIC3_CHANNEL_NIC);
hinic3_flush_txqs(nic_dev->netdev);
- /* After set vport disable 100ms,
- * no packets will be send to host
- * FPGA set 2000ms
- */
- msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+ if (is_in_kexec == 0) {
+ msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+ } else {
+ (void)hinic3_flush_rq_and_check(nic_dev, glb_func_id);
+ }
hinic3_flush_qps_res(nic_dev->hwdev);
}
}
@@ -583,11 +650,12 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_qp_params new_qp_params = {0};
struct hinic3_dyna_qp_params cur_qp_params = {0};
int err;
+ bool is_free_resources = false;
hinic3_config_num_qps(nic_dev, trxq_params);
err = hinic3_alloc_channel_resources(nic_dev, &new_qp_params,
- trxq_params);
+ trxq_params, false);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc channel resources\n");
@@ -599,10 +667,19 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
hinic3_close_channel(nic_dev, &cur_qp_params);
hinic3_free_channel_resources(nic_dev, &cur_qp_params,
&nic_dev->q_params);
+ is_free_resources = true;
}
if (nic_dev->num_qp_irq > trxq_params->num_qps)
hinic3_qp_irq_change(nic_dev, trxq_params->num_qps);
+
+ if (is_free_resources) {
+ err = hinic3_alloc_irq_vram(nic_dev, trxq_params, false);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Change chl alloc irq failed\n");
+ goto alloc_irq_err;
+ }
+ }
nic_dev->q_params = *trxq_params;
if (reopen_handler)
@@ -623,7 +700,7 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
vport_up_err:
hinic3_close_channel(nic_dev, &new_qp_params);
-
+alloc_irq_err:
open_channel_err:
hinic3_free_channel_resources(nic_dev, &new_qp_params, trxq_params);
@@ -654,7 +731,7 @@ int hinic3_open(struct net_device *netdev)
}
err = hinic3_alloc_channel_resources(nic_dev, &qp_params,
- &nic_dev->q_params);
+ &nic_dev->q_params, true);
if (err)
goto alloc_channel_res_err;
@@ -693,12 +770,31 @@ setup_qps_err:
return err;
}
+static void hinic3_delete_napi(struct hinic3_nic_dev *nic_dev)
+{
+ u16 q_id;
+ int is_in_kexec = vram_get_kexec_flag();
+ struct hinic3_irq *irq_cfg = NULL;
+
+ if (is_in_kexec == 0 || nic_dev->q_params.irq_cfg == NULL)
+ return;
+
+ for (q_id = 0; q_id < nic_dev->q_params.num_qps; q_id++) {
+ irq_cfg = &(nic_dev->q_params.irq_cfg[q_id]);
+ qp_del_napi(irq_cfg);
+ }
+
+ hinic3_free_irq_vram(nic_dev, &nic_dev->q_params);
+}
+
int hinic3_close(struct net_device *netdev)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic3_dyna_qp_params qp_params = {0};
if (!test_and_clear_bit(HINIC3_INTF_UP, &nic_dev->flags)) {
+ /* delete napi in os hotreplace rollback */
+ hinic3_delete_napi(nic_dev);
nicif_info(nic_dev, drv, netdev, "Netdev already close, do nothing\n");
return 0;
}
@@ -835,6 +931,7 @@ static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb
#define GET_DSCP_PRI_OFFSET 2
static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev, struct sk_buff *skb)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int dscp_cp;
if (skb->protocol == htons(ETH_P_IP))
@@ -842,8 +939,8 @@ static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev, struct sk_buff *skb
else if (skb->protocol == htons(ETH_P_IPV6))
dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
else
- return nic_dev->hw_dcb_cfg.default_cos;
- return nic_dev->hw_dcb_cfg.dscp2cos[dscp_cp];
+ return dcb->hw_dcb_cfg.default_cos;
+ return dcb->hw_dcb_cfg.dscp2cos[dscp_cp];
}
#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY)
@@ -869,6 +966,7 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif /* end of HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK */
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u16 txq;
u8 cos, qp_num;
@@ -889,18 +987,19 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (nic_dev->hw_dcb_cfg.trust == DCB_PCP) {
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP) {
if (skb->vlan_tci)
- cos = nic_dev->hw_dcb_cfg.pcp2cos[skb->vlan_tci >> VLAN_PRIO_SHIFT];
+ cos = dcb->hw_dcb_cfg.pcp2cos[skb->vlan_tci >>
+ VLAN_PRIO_SHIFT];
else
- cos = nic_dev->hw_dcb_cfg.default_cos;
+ cos = dcb->hw_dcb_cfg.default_cos;
} else {
cos = hinic3_get_dscp_up(nic_dev, skb);
}
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cos] ?
- txq % nic_dev->hw_dcb_cfg.cos_qp_num[cos] : 0;
- txq = nic_dev->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
+ qp_num = dcb->hw_dcb_cfg.cos_qp_num[cos] ?
+ txq % dcb->hw_dcb_cfg.cos_qp_num[cos] : 0;
+ txq = dcb->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
}
return txq;
@@ -978,7 +1077,7 @@ static struct net_device_stats *hinic3_get_stats(struct net_device *netdev)
stats->rx_packets = packets;
stats->rx_bytes = bytes;
stats->rx_errors = errors;
- stats->rx_dropped = dropped;
+ stats->rx_dropped = dropped + nic_dev->vport_stats.rx_discard_vport;
#ifndef HAVE_VOID_NDO_GET_STATS64
return stats;
@@ -1025,10 +1124,17 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
u32 mtu = (u32)new_mtu;
int err = 0;
-
+ int is_in_kexec = vram_get_kexec_flag();
#ifdef HAVE_XDP_SUPPORT
u32 xdp_max_mtu;
+#endif
+ if (is_in_kexec != 0) {
+ nicif_info(nic_dev, drv, netdev, "Hotreplace skip change mtu\n");
+ return err;
+ }
+
+#ifdef HAVE_XDP_SUPPORT
if (hinic3_is_xdp_enable(nic_dev)) {
xdp_max_mtu = hinic3_xdp_max_mtu(nic_dev);
if (mtu > xdp_max_mtu) {
@@ -1047,6 +1153,7 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
nicif_info(nic_dev, drv, nic_dev->netdev, "Change mtu from %u to %d\n",
netdev->mtu, new_mtu);
netdev->mtu = mtu;
+ nic_dev->nic_vram->vram_mtu = mtu;
}
return err;
@@ -1080,6 +1187,71 @@ static int hinic3_set_mac_addr(struct net_device *netdev, void *addr)
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+static int hinic3_udp_tunnel_port_config(struct net_device *netdev,
+ struct udp_tunnel_info *ti,
+ u8 action)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u16 func_id = hinic3_global_func_id(nic_dev->hwdev);
+ u16 dst_port;
+ int ret = 0;
+
+ switch (ti->type) {
+ case UDP_TUNNEL_TYPE_VXLAN:
+ dst_port = ntohs(ti->port);
+ ret = hinic3_vlxan_port_config(nic_dev->hwdev, func_id,
+ dst_port, action);
+ if (ret != 0) {
+ nicif_warn(nic_dev, drv, netdev,
+ "Failed to set vxlan port %u to device(%d)\n",
+ dst_port, ret);
+ break;
+ }
+ nicif_info(nic_dev, link, netdev, "Vxlan dst port set to %u\n",
+ action == HINIC3_CMD_OP_ADD ?
+ dst_port : ntohs(VXLAN_OFFLOAD_PORT_LE));
+ break;
+ default:
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to add port, only vxlan dst port is supported\n");
+ ret = -EINVAL;
+ }
+ return ret;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+static void hinic3_udp_tunnel_add(struct net_device *netdev, struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+static void hinic3_udp_tunnel_del(struct net_device *netdev, struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD */
+
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev, __attribute__((unused)) unsigned int table,
+ __attribute__((unused))unsigned int entry, struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev, __attribute__((unused)) unsigned int table,
+ __attribute__((unused)) unsigned int entry, struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static int
hinic3_vlan_rx_add_vid(struct net_device *netdev,
__always_unused __be16 proto,
@@ -1126,7 +1298,7 @@ hinic3_vlan_rx_kill_vid(struct net_device *netdev,
int err = 0;
col = VID_COL(nic_dev, vid);
- line = VID_LINE(nic_dev, vid);
+ line = (int)VID_LINE(nic_dev, vid);
/* In the broadcast scenario, ucode finds the corresponding function
* based on VLAN 0 of vlan table. If we delete VLAN 0, the VLAN function
@@ -1165,14 +1337,12 @@ static int hinic3_vlan_restore(struct net_device *netdev)
return -EFAULT;
rcu_read_lock();
for (i = 0; i < VLAN_N_VID; i++) {
-/* lint -e778 */
#ifdef HAVE_VLAN_FIND_DEV_DEEP_RCU
vlandev =
__vlan_find_dev_deep_rcu(netdev, htons(ETH_P_8021Q), i);
#else
vlandev = __vlan_find_dev_deep(netdev, htons(ETH_P_8021Q), i);
#endif
-/* lint +e778 */
col = VID_COL(nic_dev, i);
line = VID_LINE(nic_dev, i);
if (!vlandev && (vlan_bitmap[line] & (1UL << col)) != 0) {
@@ -1330,12 +1500,17 @@ static int set_feature_vlan_filter(struct hinic3_nic_dev *nic_dev,
return 0;
#ifdef NEED_VLAN_RESTORE
- if (en)
+ if (en) {
err = hinic3_vlan_restore(nic_dev->netdev);
+ if (err) {
+ hinic3_err(nic_dev, drv, "vlan restore failed\n");
+ *failed_features |= vlan_filter_feature;
+ return err;
+ }
+ }
#endif
- if (err == 0)
- err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
+ err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
if (err) {
hinic3_err(nic_dev, drv, "%s rx vlan filter failed\n",
SET_FEATURES_OP_STR(en));
@@ -1429,8 +1604,8 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
struct hinic3_nic_dev *adapter = netdev_priv(netdev);
int err;
- if (is_multicast_ether_addr(mac) || /*lint !e574*/
- vf >= pci_num_vf(adapter->pdev)) /*lint !e574*/
+ if (is_multicast_ether_addr(mac) ||
+ vf >= pci_num_vf(adapter->pdev))
return -EINVAL;
err = hinic3_set_vf_mac(adapter->hwdev, OS_VF_ID_TO_HW(vf), mac);
@@ -1448,7 +1623,6 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
return 0;
}
-/*lint -save -e574 -e734*/
#ifdef IFLA_VF_MAX
static int set_hw_vf_vlan(void *hwdev, u16 cur_vlanprio, int vf,
u16 vlan, u8 qos)
@@ -1670,7 +1844,7 @@ static int hinic3_ndo_set_vf_bw(struct net_device *netdev, int vf,
return -EIO;
/* rate limit cannot be less than 0 and greater than link speed */
- if (max_tx_rate < 0 || max_tx_rate > speeds[port_info.speed]) {
+ if (max_tx_rate < 0 || max_tx_rate > (int)(speeds[port_info.speed])) {
nicif_err(adapter, drv, netdev, "Set vf max tx rate must be in [0 - %u]\n",
speeds[port_info.speed]);
return -EINVAL;
@@ -1719,7 +1893,7 @@ static int hinic3_xdp_setup(struct hinic3_nic_dev *nic_dev,
int max_mtu = hinic3_xdp_max_mtu(nic_dev);
int q_id;
- if (nic_dev->netdev->mtu > max_mtu) {
+ if (nic_dev->netdev->mtu > (u32)max_mtu) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to setup xdp program, the current MTU %d is larger than max allowed MTU %d\n",
nic_dev->netdev->mtu, max_mtu);
@@ -1844,6 +2018,10 @@ static const struct net_device_ops hinic3_netdev_ops = {
.ndo_xdp = hinic3_xdp,
#endif
#endif
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+ .ndo_udp_tunnel_add = hinic3_udp_tunnel_add,
+ .ndo_udp_tunnel_del = hinic3_udp_tunnel_del,
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD */
#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT
};
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
index cc00bdc..1bc6a14 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
@@ -10,6 +10,8 @@
#include "hinic3_common.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
/* ************************ array index define ********************* */
#define ARRAY_INDEX_0 0
@@ -21,6 +23,35 @@
#define ARRAY_INDEX_6 6
#define ARRAY_INDEX_7 7
+#define XSFP_TLV_PRE_INFO_LEN 4
+
+enum hinic3_link_port_type {
+ LINK_PORT_UNKNOWN,
+ LINK_PORT_OPTICAL_MM,
+ LINK_PORT_OPTICAL_SM,
+ LINK_PORT_PAS_COPPER,
+ LINK_PORT_ACC,
+ LINK_PORT_BASET,
+ LINK_PORT_AOC = 0x40,
+ LINK_PORT_ELECTRIC,
+ LINK_PORT_BACKBOARD_INTERFACE,
+};
+
+enum hilink_fibre_subtype {
+ FIBRE_SUBTYPE_SR = 1,
+ FIBRE_SUBTYPE_LR,
+ FIBRE_SUBTYPE_MAX,
+};
+
+enum hilink_fec_type {
+ HILINK_FEC_NOT_SET,
+ HILINK_FEC_RSFEC,
+ HILINK_FEC_BASEFEC,
+ HILINK_FEC_NOFEC,
+ HILINK_FEC_LLRSFE,
+ HILINK_FEC_MAX_TYPE,
+};
+
struct hinic3_sq_attr {
u8 dma_attr_off;
u8 pending_limit;
@@ -58,24 +89,32 @@ struct hinic3_port_routine_cmd {
struct mag_cmd_get_xsfp_present abs;
};
+struct hinic3_port_routine_cmd_extern {
+ bool mpu_send_xsfp_tlv_info;
+
+ struct drv_mag_cmd_get_xsfp_tlv_rsp std_xsfp_tlv_info;
+};
+
struct hinic3_nic_cfg {
- struct semaphore cfg_lock;
+ struct semaphore cfg_lock;
/* Valid when pfc is disable */
- bool pause_set;
- struct nic_pause_config nic_pause;
+ bool pause_set;
+ struct nic_pause_config nic_pause;
- u8 pfc_en;
- u8 pfc_bitmap;
+ u8 pfc_en;
+ u8 pfc_bitmap;
- struct nic_port_info port_info;
+ struct nic_port_info port_info;
/* percentage of pf link bandwidth */
- u32 pf_bw_limit;
- u32 rsvd2;
+ u32 pf_bw_tx_limit;
+ u32 pf_bw_rx_limit;
- struct hinic3_port_routine_cmd rt_cmd;
- struct mutex sfp_mutex; /* mutex used for copy sfp info */
+ struct hinic3_port_routine_cmd rt_cmd;
+ struct hinic3_port_routine_cmd_extern rt_cmd_ext;
+ /* mutex used for copy sfp info */
+ struct mutex sfp_mutex;
};
struct hinic3_nic_io {
@@ -84,7 +123,7 @@ struct hinic3_nic_io {
void *dev_hdl;
u8 link_status;
- u8 rsvd1;
+ u8 direct;
u32 rsvd2;
struct hinic3_io_queue *sq;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
index 2c1b565..525a353 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
@@ -20,10 +20,126 @@
#include "hinic3_nic_io.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_common.h"
#include "hinic3_nic_cfg.h"
+#include "vram_common.h"
+
+int hinic3_delete_bond(void *hwdev)
+{
+ struct hinic3_cmd_delete_bond cmd_delete_bond;
+ u16 out_size = sizeof(cmd_delete_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_delete_bond, 0, sizeof(cmd_delete_bond));
+ cmd_delete_bond.bond_id = HINIC3_INVALID_BOND_ID;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_DELETE,
+ &cmd_delete_bond, sizeof(cmd_delete_bond),
+ &cmd_delete_bond, &out_size);
+ if (err || !out_size || cmd_delete_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to delete bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_delete_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_delete_bond.bond_id != HINIC3_INVALID_BOND_ID) {
+ nic_info(nic_io->dev_hdl, "Delete bond success\n");
+ }
+
+ return 0;
+}
+
+int hinic3_open_close_bond(void *hwdev, u32 bond_en)
+{
+ struct hinic3_cmd_open_close_bond cmd_open_close_bond;
+ u16 out_size = sizeof(cmd_open_close_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_open_close_bond, 0, sizeof(cmd_open_close_bond));
+ cmd_open_close_bond.open_close_bond_info.bond_id = HINIC3_INVALID_BOND_ID;
+ cmd_open_close_bond.open_close_bond_info.open_close_flag = bond_en;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_OPEN_CLOSE,
+ &cmd_open_close_bond, sizeof(cmd_open_close_bond),
+ &cmd_open_close_bond, &out_size);
+ if (err || !out_size || cmd_open_close_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to %s bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ bond_en == true ? "open" : "close", err, cmd_open_close_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_open_close_bond.open_close_bond_info.bond_id != HINIC3_INVALID_BOND_ID) {
+ nic_info(nic_io->dev_hdl, "%s bond success\n", bond_en == true ? "Open" : "Close");
+ }
+
+ return 0;
+}
+
+int hinic3_create_bond(void *hwdev, u32 *bond_id)
+{
+ struct hinic3_cmd_create_bond cmd_create_bond;
+ u16 out_size = sizeof(cmd_create_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_create_bond, 0, sizeof(cmd_create_bond));
+ cmd_create_bond.create_bond_info.default_param_flag = true;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_CREATE,
+ &cmd_create_bond, sizeof(cmd_create_bond),
+ &cmd_create_bond, &out_size);
+ if (err || !out_size || cmd_create_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to create default bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_create_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_create_bond.create_bond_info.bond_id != HINIC3_INVALID_BOND_ID) {
+ *bond_id = cmd_create_bond.create_bond_info.bond_id;
+ nic_info(nic_io->dev_hdl, "Create bond success\n");
+ }
+
+ return 0;
+}
+
int hinic3_set_ci_table(void *hwdev, struct hinic3_sq_attr *attr)
{
struct hinic3_cmd_cons_idx_attr cons_idx_attr;
@@ -37,6 +153,8 @@ int hinic3_set_ci_table(void *hwdev, struct hinic3_sq_attr *attr)
memset(&cons_idx_attr, 0, sizeof(cons_idx_attr));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cons_idx_attr.func_idx = hinic3_global_func_id(hwdev);
@@ -152,6 +270,8 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -183,7 +303,7 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
}
EXPORT_SYMBOL(hinic3_del_mac);
-int hinic3_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
+int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
u16 func_id)
{
struct hinic3_port_mac_update mac_info;
@@ -197,6 +317,8 @@ int hinic3_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -247,6 +369,8 @@ int hinic3_get_default_mac(void *hwdev, u8 *mac_addr)
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
mac_info.func_id = hinic3_global_func_id(hwdev);
@@ -292,6 +416,45 @@ static int hinic3_config_vlan(struct hinic3_nic_io *nic_io, u8 opcode,
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action)
+{
+ struct hinic3_cmd_vxlan_port_info vxlan_port_info;
+ u16 out_size = sizeof(vxlan_port_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ memset(&vxlan_port_info, 0, sizeof(vxlan_port_info));
+ vxlan_port_info.opcode = action;
+ vxlan_port_info.cfg_mode = 0; // other ethtool set
+ vxlan_port_info.func_id = func_id;
+ vxlan_port_info.vxlan_port = port;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+ &vxlan_port_info, sizeof(vxlan_port_info),
+ &vxlan_port_info, &out_size);
+ if (err || !out_size || vxlan_port_info.msg_head.status) {
+ if (vxlan_port_info.msg_head.status == 0x2) {
+ nic_warn(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port because it has already been set by hinicadm\n",
+ action == HINIC3_CMD_OP_ADD ? "add" : "delete");
+ } else {
+ nic_err(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port, err: %d, status: 0x%x, out size: 0x%x\n",
+ action == HINIC3_CMD_OP_ADD ? "add" : "delete",
+ err, vxlan_port_info.msg_head.status, out_size);
+ }
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
{
struct hinic3_nic_io *nic_io = NULL;
@@ -300,6 +463,9 @@ int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan_id, func_id);
}
@@ -311,6 +477,9 @@ int hinic3_del_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_DEL, vlan_id, func_id);
}
@@ -354,6 +523,9 @@ int hinic3_set_dcb_state(void *hwdev, struct hinic3_dcb_state *dcb_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (!memcmp(&nic_io->dcb_state, dcb_state, sizeof(nic_io->dcb_state)))
return 0;
@@ -515,6 +687,8 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_cfg = &nic_io->nic_cfg;
@@ -540,7 +714,6 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
{
- struct hinic3_nic_cfg *nic_cfg = NULL;
struct hinic3_nic_io *nic_io = NULL;
int err = 0;
@@ -548,17 +721,13 @@ int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- nic_cfg = &nic_io->nic_cfg;
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_hw_pause(nic_io, HINIC3_CMD_OP_GET, nic_pause);
if (err)
return err;
- if (nic_cfg->pause_set || !nic_pause->auto_neg) {
- nic_pause->rx_pause = nic_cfg->nic_pause.rx_pause;
- nic_pause->tx_pause = nic_cfg->nic_pause.tx_pause;
- }
-
return 0;
}
@@ -573,6 +742,8 @@ int hinic3_sync_dcb_state(void *hwdev, u8 op_code, u8 state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&dcb_state, 0, sizeof(dcb_state));
@@ -659,44 +830,6 @@ int hinic3_cache_out_qps_res(void *hwdev)
return 0;
}
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats)
-{
- struct hinic3_port_stats *port_stats = NULL;
- struct hinic3_port_stats_info stats_info;
- u16 out_size = sizeof(*port_stats);
- struct hinic3_nic_io *nic_io = NULL;
- int err;
-
- port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
- if (!port_stats)
- return -ENOMEM;
-
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
-
- memset(&stats_info, 0, sizeof(stats_info));
-
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_PORT_STAT,
- &stats_info, sizeof(stats_info),
- port_stats, &out_size);
- if (err || !out_size || port_stats->msg_head.status) {
- nic_err(nic_io->dev_hdl,
- "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
- err, port_stats->msg_head.status, out_size);
- err = -EIO;
- goto out;
- }
-
- memcpy(stats, &port_stats->stats, sizeof(*stats));
-
-out:
- kfree(port_stats);
-
- return err;
-}
-EXPORT_SYMBOL(hinic3_get_fpga_phy_port_stats);
-
int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *stats)
{
struct hinic3_port_stats_info stats_info;
@@ -712,6 +845,8 @@ int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *
memset(&vport_stats, 0, sizeof(vport_stats));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
stats_info.func_id = func_id;
@@ -778,6 +913,8 @@ int hinic3_set_port_mtu(void *hwdev, u16 new_mtu)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (new_mtu < HINIC3_MIN_MTU_SIZE) {
nic_err(nic_io->dev_hdl,
@@ -808,6 +945,9 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&feature_nego, 0, sizeof(feature_nego));
feature_nego.func_id = hinic3_global_func_id(hwdev);
feature_nego.opcode = opcode;
@@ -829,29 +969,21 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return 0;
}
-static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
+static int hinic3_get_bios_pf_bw_tx_limit(void *hwdev, struct hinic3_nic_io *nic_io, u16 func_id, u32 *pf_rate)
{
- struct hinic3_nic_io *nic_io = NULL;
+ int err = 0; // default success
struct nic_cmd_bios_cfg cfg = {{0}};
u16 out_size = sizeof(cfg);
- int err;
- if (!hwdev || !pf_bw_limit)
- return -EINVAL;
-
- if (hinic3_func_type(hwdev) == TYPE_VF || !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
- return 0;
-
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- cfg.bios_cfg.func_id = (u8)hinic3_global_func_id(hwdev);
+ cfg.bios_cfg.func_id = (u8)func_id;
cfg.bios_cfg.func_valid = 1;
- cfg.op_code = 0 | NIC_NVM_DATA_PF_SPEED_LIMIT;
+ cfg.op_code = 0 | NIC_NVM_DATA_PF_TX_SPEED_LIMIT;
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BIOS_CFG, &cfg, sizeof(cfg),
&cfg, &out_size);
if (err || !out_size || cfg.head.status) {
nic_err(nic_io->dev_hdl,
- "Failed to get bios pf bandwidth limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ "Failed to get bios pf bandwidth tx limit, err: %d, status: 0x%x, out size: 0x%x\n",
err, cfg.head.status, out_size);
return -EIO;
}
@@ -861,13 +993,77 @@ static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
nic_warn(nic_io->dev_hdl, "Invalid bios configuration data, signature: 0x%x\n",
cfg.bios_cfg.signature);
- if (cfg.bios_cfg.pf_bw > MAX_LIMIT_BW) {
+ if (cfg.bios_cfg.pf_tx_bw > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
+ cfg.bios_cfg.pf_tx_bw);
+ return -EINVAL;
+ }
+
+ (*pf_rate) = cfg.bios_cfg.pf_tx_bw;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_rx_limit(void *hwdev, struct hinic3_nic_io *nic_io, u16 func_id, u32 *pf_rate)
+{
+ int err = 0; // default success
+ struct nic_rx_rate_bios_cfg rx_bios_conf = {{0}};
+ u16 out_size = sizeof(rx_bios_conf);
+
+ rx_bios_conf.func_id = (u8)func_id;
+ rx_bios_conf.op_code = 0; /* 1-save, 0-read */
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_RX_RATE_CFG, &rx_bios_conf, sizeof(rx_bios_conf),
+ &rx_bios_conf, &out_size);
+ if (rx_bios_conf.msg_head.status == HINIC3_MGMT_CMD_UNSUPPORTED && err == 0) { // Compatible older firmware
+ nic_warn(nic_io->dev_hdl, "Not support get bios pf bandwidth rx limit\n");
+ return 0;
+ } else if (err || !out_size || rx_bios_conf.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get bios pf bandwidth rx limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, rx_bios_conf.msg_head.status, out_size);
+ return -EIO;
+ }
+ if (rx_bios_conf.rx_rate_limit > MAX_LIMIT_BW) {
nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
- cfg.bios_cfg.pf_bw);
+ rx_bios_conf.rx_rate_limit);
return -EINVAL;
}
- *pf_bw_limit = cfg.bios_cfg.pf_bw;
+ (*pf_rate) = rx_bios_conf.rx_rate_limit;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit, u8 direct)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u32 pf_rate = 0;
+ int err = 0;
+ u16 func_id;
+ func_id = hinic3_global_func_id(hwdev);
+
+ if (!hwdev || !pf_bw_limit)
+ return -EINVAL;
+
+ if (hinic3_func_type(hwdev) == TYPE_VF || !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
+ return 0;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (direct == HINIC3_NIC_TX) {
+ err = hinic3_get_bios_pf_bw_tx_limit(hwdev, nic_io, func_id, &pf_rate);
+ } else if (direct == HINIC3_NIC_RX) {
+ err = hinic3_get_bios_pf_bw_rx_limit(hwdev, nic_io, func_id, &pf_rate);
+ }
+
+ if (err != 0)
+ return err;
+
+ if (pf_rate > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n", pf_rate);
+ return -EINVAL;
+ }
+ *pf_bw_limit = pf_rate;
return 0;
}
@@ -876,8 +1072,9 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
{
struct hinic3_cmd_tx_rate_cfg rate_cfg = {{0}};
struct hinic3_nic_io *nic_io = NULL;
+ u32 rate_limit;
u16 out_size = sizeof(rate_cfg);
- u32 pf_rate;
+ u32 pf_rate = 0;
int err;
u32 speed_convert[PORT_SPEED_UNKNOWN] = {
0, 10, 100, 1000, 10000, 25000, 40000, 50000, 100000, 200000
@@ -892,19 +1089,21 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
return -EINVAL;
}
- if (nic_io->nic_cfg.pf_bw_limit == MAX_LIMIT_BW) {
- pf_rate = 0;
- } else {
+ rate_limit = (nic_io->direct == HINIC3_NIC_TX) ?
+ nic_io->nic_cfg.pf_bw_tx_limit : nic_io->nic_cfg.pf_bw_rx_limit;
+
+ if (rate_limit != MAX_LIMIT_BW) {
/* divided by 100 to convert to percentage */
- pf_rate = (speed_convert[speed_level] / 100) * nic_io->nic_cfg.pf_bw_limit;
+ pf_rate = (speed_convert[speed_level] / 100) * rate_limit;
/* bandwidth limit is very small but not unlimit in this case */
- if (pf_rate == 0 && speed_level != PORT_SPEED_NOT_SET)
+ if ((pf_rate == 0) && (speed_level != PORT_SPEED_NOT_SET))
pf_rate = 1;
}
rate_cfg.func_id = hinic3_global_func_id(hwdev);
rate_cfg.min_rate = 0;
rate_cfg.max_rate = pf_rate;
+ rate_cfg.direct = nic_io->direct;
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_MAX_MIN_RATE, &rate_cfg,
sizeof(rate_cfg), &rate_cfg, &out_size);
@@ -927,6 +1126,8 @@ int hinic3_set_nic_feature_to_hw(void *hwdev)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return nic_feature_nego(hwdev, HINIC3_CMD_OP_SET, &nic_io->feature_cap, 1);
}
@@ -936,6 +1137,8 @@ u64 hinic3_get_feature_cap(void *hwdev)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
return nic_io->feature_cap;
}
@@ -945,6 +1148,9 @@ void hinic3_update_nic_feature(void *hwdev, u64 s_feature)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
+
nic_io->feature_cap = s_feature;
nic_info(nic_io->dev_hdl, "Update nic feature to 0x%llx\n", nic_io->feature_cap);
@@ -978,6 +1184,7 @@ static int hinic3_init_nic_io(void *hwdev, void *pcidev_hdl, void *dev_hdl,
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_abs = false;
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_info = false;
+ (*nic_io)->nic_cfg.rt_cmd_ext.mpu_send_xsfp_tlv_info = false;
return 0;
}
@@ -994,11 +1201,14 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
{
struct hinic3_nic_io *nic_io = NULL;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
err = hinic3_init_nic_io(hwdev, pcidev_hdl, dev_hdl, &nic_io);
if (err)
return err;
+ nic_io->rx_buff_len = rx_buff_len;
+
err = hinic3_register_service_adapter(hwdev, nic_io, SERVICE_T_NIC);
if (err) {
nic_err(nic_io->dev_hdl, "Failed to register service adapter\n");
@@ -1011,10 +1221,12 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
goto set_used_state_err;
}
- err = hinic3_init_function_table(nic_io);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to init function table\n");
- goto err_out;
+ if (is_in_kexec == 0) {
+ err = hinic3_init_function_table(nic_io);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to init function table\n");
+ goto err_out;
+ }
}
err = hinic3_get_nic_feature_from_hw(hwdev, &nic_io->feature_cap, 1);
@@ -1025,9 +1237,19 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
sdk_info(dev_hdl, "nic features: 0x%llx\n", nic_io->feature_cap);
- err = hinic3_get_bios_pf_bw_limit(hwdev, &nic_io->nic_cfg.pf_bw_limit);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to get pf bandwidth limit\n");
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_tx_limit,
+ HINIC3_NIC_TX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf tx bandwidth limit\n");
+ goto err_out;
+ }
+
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_rx_limit,
+ HINIC3_NIC_RX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf rx bandwidth limit\n");
goto err_out;
}
@@ -1037,12 +1259,13 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
goto err_out;
}
- nic_io->rx_buff_len = rx_buff_len;
-
return 0;
err_out:
- hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 0, HINIC3_CHANNEL_NIC);
+ if (hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 0,
+ HINIC3_CHANNEL_NIC) != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to set function svc used state\n");
+ }
set_used_state_err:
hinic3_unregister_service_adapter(hwdev, SERVICE_T_NIC);
@@ -1092,6 +1315,8 @@ int hinic3_force_drop_tx_pkt(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&pkt_drop, 0, sizeof(pkt_drop));
pkt_drop.port = hinic3_physical_port_id(hwdev);
@@ -1120,6 +1345,8 @@ int hinic3_set_rx_mode(void *hwdev, u32 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&rx_mode_cfg, 0, sizeof(rx_mode_cfg));
rx_mode_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1148,6 +1375,8 @@ int hinic3_set_rx_vlan_offload(void *hwdev, u8 en)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_cfg, 0, sizeof(vlan_cfg));
vlan_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1176,6 +1405,9 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
if (!nic_io->vf_infos || is_zero_ether_addr(vf_info->drv_mac_addr))
return 0;
@@ -1215,6 +1447,8 @@ static int hinic3_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en,
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_cfg, 0, sizeof(lro_cfg));
lro_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1246,6 +1480,8 @@ static int hinic3_set_rx_lro_timer(void *hwdev, u32 timer_value)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_timer, 0, sizeof(lro_timer));
lro_timer.opcode = HINIC3_CMD_OP_SET;
@@ -1278,6 +1514,8 @@ int hinic3_set_rx_lro_state(void *hwdev, u8 lro_en, u32 lro_timer,
ipv6_en = lro_en ? 1 : 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_info(nic_io->dev_hdl, "Set LRO max coalesce packet size to %uK\n",
lro_max_pkt_len);
@@ -1306,6 +1544,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_filter, 0, sizeof(vlan_filter));
vlan_filter.func_id = hinic3_global_func_id(hwdev);
@@ -1325,7 +1565,6 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
{
- // struct hinic_hwdev *dev = hwdev;
struct nic_cmd_capture_info cap_info = {{0}};
u16 out_size = sizeof(cap_info);
int err;
@@ -1334,7 +1573,6 @@ int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
return -EINVAL;
/* 2 function capture types */
- // cap_info.op_type = UP_UCAPTURE_OP_TYPE_FUNC;
cap_info.is_en_trx = cap_en;
cap_info.func_port = func_id;
@@ -1359,6 +1597,8 @@ int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (tcam_rule->index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to add is invalid\n");
return -EINVAL;
@@ -1394,6 +1634,8 @@ int hinic3_del_tcam_rule(void *hwdev, u32 index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to del is invalid\n");
return -EINVAL;
@@ -1443,6 +1685,8 @@ static int hinic3_mgmt_tcam_block(void *hwdev, u8 alloc_en, u16 *index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&tcam_block_info, 0,
sizeof(struct nic_cmd_ctrl_tcam_block_out));
@@ -1488,6 +1732,8 @@ int hinic3_set_fdir_tcam_rule_filter(void *hwdev, bool enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
port_tcam_cmd.func_id = hinic3_global_func_id(hwdev);
port_tcam_cmd.tcam_enable = (u8)enable;
@@ -1516,6 +1762,9 @@ int hinic3_flush_tcam_rule(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&tcam_flush, 0, sizeof(struct nic_cmd_flush_tcam_rules));
tcam_flush.func_id = hinic3_global_func_id(hwdev);
@@ -1546,6 +1795,9 @@ int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -1588,8 +1840,10 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return -EINVAL;
}
- if (hinic3_func_type(hwdev) == TYPE_VF)
+ if (hinic3_func_type(hwdev) == TYPE_VF) {
+ pr_err("VF are not supported to set link state.\n");
return -EINVAL;
+ }
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
if (!nic_io) {
@@ -1606,3 +1860,35 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return 0;
}
EXPORT_SYMBOL(hinic3_pf_set_vf_link_state);
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid)
+{
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ u16 out_size = sizeof(outband_cfg_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !outband_default_vid)
+ return -EINVAL;
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_OUTBAND_CFG,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size);
+ if (err || !out_size || outband_cfg_info.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get outband cfg, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, outband_cfg_info.msg_head.status, out_size);
+ return -EINVAL;
+ }
+
+ *outband_default_vid = outband_cfg_info.outband_default_vid;
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
index ee0587c..0fe7b9f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
@@ -7,9 +7,9 @@
#include <linux/types.h>
#include <linux/netdevice.h>
-#include "hinic3_mgmt_interface.h"
+#include "nic_mpu_cmd_defs.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#define OS_VF_ID_TO_HW(os_vf_id) ((os_vf_id) + 1)
#define HW_VF_ID_TO_OS(hw_vf_id) ((hw_vf_id) - 1)
@@ -54,6 +54,8 @@
#define MAX_LIMIT_BW 100
+#define HINIC3_INVALID_BOND_ID 0xffffffff
+
enum hinic3_valid_link_settings {
HILINK_LINK_SET_SPEED = 0x1,
HILINK_LINK_SET_AUTONEG = 0x2,
@@ -67,6 +69,11 @@ enum hinic3_link_follow_status {
HINIC3_LINK_FOLLOW_STATUS_MAX,
};
+enum hinic3_nic_pf_direct {
+ HINIC3_NIC_RX = 0,
+ HINIC3_NIC_TX,
+};
+
struct hinic3_link_ksettings {
u32 valid_bitmap;
u8 speed; /* enum nic_speed_level */
@@ -150,8 +157,12 @@ struct nic_port_info {
u8 duplex;
u8 speed;
u8 fec;
+ u8 lanes;
+ u8 rsvd;
u32 supported_mode;
u32 advertised_mode;
+ u32 supported_fec_mode;
+ u32 bond_speed;
};
struct nic_pause_config {
@@ -176,11 +187,17 @@ struct hinic3_rxq_hw {
#define MODULE_TYPE_QSFP28 0x11
#define MODULE_TYPE_QSFP 0x0C
#define MODULE_TYPE_QSFP_PLUS 0x0D
+#define MODULE_TYPE_DSFP 0x1B
+#define MODULE_TYPE_QSFP_CMIS 0x1E
#define TCAM_IP_TYPE_MASK 0x1
#define TCAM_TUNNEL_TYPE_MASK 0xF
#define TCAM_FUNC_ID_MASK 0x7FFF
+int hinic3_delete_bond(void *hwdev);
+int hinic3_open_close_bond(void *hwdev, u32 bond_en);
+int hinic3_create_bond(void *hwdev, u32 *bond_id);
+
int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule);
int hinic3_del_tcam_rule(void *hwdev, u32 index);
@@ -201,7 +218,7 @@ int hinic3_flush_tcam_rule(void *hwdev);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic3_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
+int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
u16 func_id);
/* *
@@ -333,7 +350,7 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr);
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr);
/* *
* @brief hinic3_vf_info_vlanprio - get vf vlan priority
@@ -508,7 +525,14 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table);
*/
int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats);
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats);
+/* *
+ * @brief hinic3_get_phy_rsfec_stats - get rsfec stats
+ * @param hwdev: device pointer to hwdev
+ * @param stats: rsfec(Reed-Solomon Forward Error Correction) stats
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats);
int hinic3_set_port_funcs_state(void *hwdev, bool enable);
@@ -544,6 +568,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl);
void hinic3_clear_vfs_info(void *hwdev);
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id);
+
int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id);
int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
@@ -563,10 +589,13 @@ int hinic3_set_autoneg(void *hwdev, bool enable);
int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext);
int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len);
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len);
bool hinic3_if_sfp_absent(void *hwdev);
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info);
-
+int hinic3_get_sfp_tlv_info(void *hwdev,
+ struct drv_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info,
+ const struct mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req);
/* *
* @brief hinic3_set_nic_feature_to_hw - sync nic feature to hardware
* @param hwdev: device pointer to hwdev
@@ -618,4 +647,18 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level);
int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type);
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+/* *
+ * @brief hinic3_vlxan_port_config - add/del vxlan dst port
+ * @param hwdev: device pointer to hwdev
+ * @param func_id: function id
+ * @param port: vxlan dst port
+ * @param action: add or del, del will set to default value (0x12B5)
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action);
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
index b46cf78..654673f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
@@ -21,7 +21,8 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
/*lint -e806*/
static unsigned char set_vf_link_state;
@@ -116,7 +117,7 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
err = hinic3_set_vlan_ctx(nic_io, glb_func_id, vlan_tag,
NIC_CONFIG_ALL_QUEUE_VLAN_CTX,
opcode == HINIC3_CMD_OP_ADD);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d vlan ctx, err: %d\n",
HW_VF_ID_TO_OS(vf_id), err);
@@ -137,22 +138,21 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
/* this function just be called by hinic3_ndo_set_vf_mac,
* others are not permitted.
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr)
{
- struct vf_data_storage *vf_info;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_info = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
-#ifndef __VMWARE__
+
/* duplicate request, so just return success */
if (ether_addr_equal(vf_info->user_mac_addr, mac_addr))
return 0;
-#else
- if (ether_addr_equal(vf_info->user_mac_addr, mac_addr))
- return 0;
-#endif
ether_addr_copy(vf_info->user_mac_addr, mac_addr);
return 0;
@@ -160,13 +160,15 @@ int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan, qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan = vlan;
@@ -180,17 +182,20 @@ int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_infos = nic_io->vf_infos;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_DEL,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_info(nic_io->dev_hdl, "Remove VLAN %u on VF %d\n",
@@ -205,11 +210,13 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
u16 hinic3_vf_info_vlanprio(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
u16 pf_vlan, vlanprio;
u8 pf_qos;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
pf_vlan = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan;
pf_qos = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos;
@@ -222,9 +229,14 @@ int hinic3_set_vf_link_state(void *hwdev, u16 vf_id, int link)
{
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ struct vf_data_storage *vf_infos = NULL;
u8 link_status = 0;
+ if (!nic_io)
+ return -EINVAL;
+
+ vf_infos = nic_io->vf_infos;
+
switch (link) {
case HINIC3_IFLA_VF_LINK_STATE_AUTO:
vf_infos[HW_VF_ID_TO_OS(vf_id)].link_forced = false;
@@ -264,6 +276,9 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_infos = nic_io->vf_infos;
memset(&spoofchk_cfg, 0, sizeof(spoofchk_cfg));
@@ -288,9 +303,11 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
bool hinic3_vf_info_spoofchk(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].spoofchk;
}
@@ -304,7 +321,7 @@ int hinic3_set_vf_trust(void *hwdev, u16 vf_id, bool trust)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
+ if (!nic_io || vf_id > nic_io->max_vfs)
return -EINVAL;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust = trust;
@@ -317,11 +334,11 @@ bool hinic3_get_vf_trust(void *hwdev, int vf_id)
struct hinic3_nic_io *nic_io = NULL;
if (!hwdev)
- return -EINVAL;
+ return false;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
- return -EINVAL;
+ if (!nic_io || vf_id > nic_io->max_vfs)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust;
}
@@ -339,6 +356,7 @@ static int hinic3_set_vf_tx_rate_max_min(struct hinic3_nic_io *nic_io,
rate_cfg.func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf_id;
rate_cfg.max_rate = max_rate;
rate_cfg.min_rate = min_rate;
+ rate_cfg.direct = HINIC3_NIC_TX;
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
&rate_cfg, sizeof(rate_cfg), &rate_cfg,
@@ -359,13 +377,16 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (!HINIC3_SUPPORT_RATE_LIMIT(hwdev)) {
nic_err(nic_io->dev_hdl, "Current function doesn't support to set vf rate limit\n");
return -EOPNOTSUPP;
}
err = hinic3_set_vf_tx_rate_max_min(nic_io, vf_id, max_rate, min_rate);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].max_rate = max_rate;
@@ -376,12 +397,16 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
void hinic3_get_vf_config(void *hwdev, u16 vf_id, struct ifla_vf_info *ivi)
{
- struct vf_data_storage *vfinfo;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vfinfo = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
vfinfo = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vfinfo)
+ return;
ivi->vf = HW_VF_ID_TO_OS(vf_id);
ether_addr_copy(ivi->mac, vfinfo->user_mac_addr);
@@ -455,12 +480,12 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
nic_io->hwdev, hinic3_vf_event_handler);
- if (err)
+ if (err != 0)
return err;
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
nic_io->hwdev, hinic3_vf_mag_event_handler);
- if (err)
+ if (err != 0)
goto reg_hilink_err;
memset(®ister_info, 0, sizeof(register_info));
@@ -472,6 +497,12 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
®ister_info, &out_size, 0,
HINIC3_CHANNEL_NIC);
if (err || !out_size || register_info.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev)) {
+ nic_warn(nic_io->dev_hdl,
+ "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, register_info.msg_head.status, out_size);
+ return 0;
+ }
nic_err(nic_io->dev_hdl, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
err, register_info.msg_head.status, out_size);
err = -EIO;
@@ -506,18 +537,18 @@ static int pf_init_vf_infos(struct hinic3_nic_io *nic_io)
for (i = 0; i < nic_io->max_vfs; i++) {
err = hinic3_init_vf_infos(nic_io, i);
- if (err)
+ if (err != 0)
goto init_vf_infos_err;
}
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
nic_io->hwdev, hinic3_pf_mbox_handler);
- if (err)
+ if (err != 0)
goto register_pf_mbox_cb_err;
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
nic_io->hwdev, hinic3_pf_mag_mbox_handler);
- if (err)
+ if (err != 0)
goto register_pf_mag_mbox_cb_err;
return 0;
@@ -540,16 +571,16 @@ int hinic3_vf_func_init(struct hinic3_nic_io *nic_io)
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
nic_io->hwdev, hinic3_pf_event_handler);
- if (err)
+ if (err != 0)
return err;
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
nic_io->hwdev, hinic3_pf_mag_event_handler);
- if (err)
+ if (err != 0)
goto register_mgmt_msg_cb_err;
err = pf_init_vf_infos(nic_io);
- if (err)
+ if (err != 0)
goto pf_init_vf_infos_err;
return 0;
@@ -576,9 +607,15 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
&unregister, sizeof(unregister),
&unregister, &out_size, 0,
HINIC3_CHANNEL_NIC);
- if (err || !out_size || unregister.msg_head.status)
- nic_err(nic_io->dev_hdl, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
- err, unregister.msg_head.status, out_size);
+ if (err || !out_size || unregister.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev))
+ nic_info(nic_io->dev_hdl,
+ "vRoCE VF notify PF unsuccessful is allowed");
+ else
+ nic_err(nic_io->dev_hdl,
+ "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, unregister.msg_head.status, out_size);
+ }
hinic3_unregister_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
} else {
@@ -587,6 +624,7 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
hinic3_unregister_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
hinic3_clear_vfs_info(nic_io->hwdev);
kfree(nic_io->vf_infos);
+ nic_io->vf_infos = NULL;
}
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
@@ -595,11 +633,15 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
static void clear_vf_infos(void *hwdev, u16 vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
u16 func_id;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
func_id = hinic3_glb_pf_vf_offset(hwdev) + vf_id;
vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
@@ -628,10 +670,57 @@ static void clear_vf_infos(void *hwdev, u16 vf_id)
void hinic3_clear_vfs_info(void *hwdev)
{
+ u16 i;
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- u16 i;
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
for (i = 0; i < nic_io->max_vfs; i++)
clear_vf_infos(hwdev, OS_VF_ID_TO_HW(i));
}
+
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id)
+{
+ int err = 0;
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ struct vf_data_storage *vf_infos = NULL;
+ u16 out_size = sizeof(outband_cfg_info);
+ u16 vf_id;
+ struct hinic3_nic_io *nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return 0;
+ }
+
+ vf_id = func_id - hinic3_glb_pf_vf_offset(nic_io->hwdev);
+ vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+ if (vf_infos->registered) {
+ outband_cfg_info.func_id = func_id;
+ outband_cfg_info.outband_default_vid = vlan_id;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_L2NIC,
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return 0;
+ }
+ if (err || !out_size || outband_cfg_info.msg_head.status)
+ nic_err(nic_io->dev_hdl,
+ "outband cfg event to VF %d failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err,
+ outband_cfg_info.msg_head.status, out_size);
+ }
+
+ return err;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
index 17d48c4..2878f66 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
@@ -30,6 +30,9 @@ int hinic3_dbg_get_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (q_id >= nic_io->num_qps) {
pr_err("q_id[%u] > num_qps_cfg[%u].\n", q_id, nic_io->num_qps);
return -EINVAL;
@@ -69,6 +72,9 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -82,6 +88,8 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
sq = &nic_io->sq[q_id];
+ if (!sq)
+ return -EINVAL;
sq_info->q_id = q_id;
sq_info->pi = hinic3_get_sq_local_pi(sq);
@@ -112,6 +120,9 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -125,6 +136,8 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
rq = &nic_io->rq[q_id];
+ if (!rq)
+ return -EINVAL;
rq_info->q_id = q_id;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
index 800fa73..137098b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
@@ -15,9 +15,10 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
#include "hinic3_dcb.h"
+#include "vram_common.h"
#define HINIC3_NIC_DRV_NAME "hinic3"
-#define HINIC3_NIC_DRV_VERSION "15.17.1.1"
+#define HINIC3_NIC_DRV_VERSION "17.7.8.1"
#define HINIC3_FUNC_IS_VF(hwdev) (hinic3_func_type(hwdev) == TYPE_VF)
@@ -25,6 +26,10 @@
#define HINIC3_MODERATONE_DELAY HZ
#define LP_PKT_CNT 64
+#define LP_PKT_LEN 60
+
+#define NAPI_IS_REGIN 1
+#define NAPI_NOT_REGIN 0
enum hinic3_flags {
HINIC3_INTF_UP,
@@ -91,6 +96,8 @@ struct hinic3_irq {
u16 rsvd1;
u32 irq_id; /* The IRQ number from OS */
+ u32 napi_reign;
+
char irq_name[IFNAMSIZ + 16];
struct napi_struct napi;
cpumask_t affinity_mask;
@@ -123,6 +130,41 @@ struct hinic3_dyna_txrxq_params {
struct hinic3_dyna_txq_res *txqs_res;
struct hinic3_dyna_rxq_res *rxqs_res;
struct hinic3_irq *irq_cfg;
+ char irq_cfg_vram_name[VRAM_NAME_MAX_LEN];
+};
+
+struct hinic3_flush_rq {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 lb_proc : 1;
+ u32 rsvd : 10;
+ u32 rq_id : 8;
+ u32 func_id : 13;
+#else
+ u32 func_id : 13;
+ u32 rq_id : 8;
+ u32 rsvd : 10;
+ u32 lb_proc : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd2 : 2;
+ u32 src_chnl : 12;
+ u32 pkt_len : 18;
+#else
+ u32 pkt_len : 18;
+ u32 src_chnl : 12;
+ u32 rsvd2 : 2;
+#endif
+ } bs;
+ u32 value;
+ } lb_info0; /* loop back information, used by uCode */
};
#define HINIC3_NIC_STATS_INC(nic_dev, field) \
@@ -147,6 +189,10 @@ struct hinic3_nic_stats {
#endif
};
+struct hinic3_nic_vport_stats {
+ u64 rx_discard_vport;
+};
+
#define HINIC3_TCAM_DYNAMIC_BLOCK_SIZE 16
#define HINIC3_MAX_TCAM_FILTERS 512
@@ -185,104 +231,123 @@ struct hinic3_tcam_info {
struct hinic3_tcam_dynamic_block_info tcam_dynamic_info;
};
+struct hinic3_dcb {
+ u8 cos_config_num_max;
+ u8 func_dft_cos_bitmap;
+ /* used to tool validity check */
+ u16 port_dft_cos_bitmap;
+
+ struct hinic3_dcb_config hw_dcb_cfg;
+ struct hinic3_dcb_config wanted_dcb_cfg;
+ unsigned long dcb_flags;
+};
+
+struct hinic3_vram {
+ u32 vram_mtu;
+ u16 vram_num_qps;
+ unsigned long flags;
+};
+
+struct hinic3_outband_cfg {
+ u16 outband_default_vid;
+ u16 rsvd;
+};
+
struct hinic3_nic_dev {
- struct pci_dev *pdev;
- struct net_device *netdev;
- struct hinic3_lld_dev *lld_dev;
- void *hwdev;
+ struct pci_dev *pdev;
+ struct net_device *netdev;
+ struct hinic3_lld_dev *lld_dev;
+ void *hwdev;
- int poll_weight;
- u32 rsvd1;
- unsigned long *vlan_bitmap;
+ int poll_weight;
+ u32 rsvd1;
+ unsigned long *vlan_bitmap;
- u16 max_qps;
+ u16 max_qps;
- u32 msg_enable;
- unsigned long flags;
+ u32 msg_enable;
+ unsigned long flags;
- u32 lro_replenish_thld;
- u32 dma_rx_buff_size;
- u16 rx_buff_len;
- u32 page_order;
+ u32 lro_replenish_thld;
+ u32 dma_rx_buff_size;
+ u16 rx_buff_len;
+ u32 page_order;
+ bool page_pool_enabled;
/* Rss related varibles */
- u8 rss_hash_engine;
- struct nic_rss_type rss_type;
- u8 *rss_hkey;
+ u8 rss_hash_engine;
+ struct nic_rss_type rss_type;
+ u8 *rss_hkey;
/* hkey in big endian */
- u32 *rss_hkey_be;
- u32 *rss_indir;
+ u32 *rss_hkey_be;
+ u32 *rss_indir;
- u8 cos_config_num_max;
- u8 func_dft_cos_bitmap;
- u16 port_dft_cos_bitmap; /* used to tool validity check */
+ struct hinic3_dcb *dcb;
+ char dcb_name[VRAM_NAME_MAX_LEN];
- struct hinic3_dcb_config hw_dcb_cfg;
- struct hinic3_dcb_config wanted_dcb_cfg;
- struct hinic3_dcb_config dcb_cfg;
- unsigned long dcb_flags;
- int disable_port_cnt;
- /* lock for disable or enable traffic flow */
- struct semaphore dcb_sem;
+ struct hinic3_vram *nic_vram;
+ char nic_vram_name[VRAM_NAME_MAX_LEN];
- struct hinic3_intr_coal_info *intr_coalesce;
- unsigned long last_moder_jiffies;
- u32 adaptive_rx_coal;
- u8 intr_coal_set_flag;
+ int disable_port_cnt;
+
+ struct hinic3_intr_coal_info *intr_coalesce;
+ unsigned long last_moder_jiffies;
+ u32 adaptive_rx_coal;
+ u8 intr_coal_set_flag;
#ifndef HAVE_NETDEV_STATS_IN_NETDEV
- struct net_device_stats net_stats;
+ struct net_device_stats net_stats;
#endif
- struct hinic3_nic_stats stats;
+ struct hinic3_nic_stats stats;
+ struct hinic3_nic_vport_stats vport_stats;
/* lock for nic resource */
- struct mutex nic_mutex;
- bool force_port_disable;
- struct semaphore port_state_sem;
- u8 link_status;
+ struct mutex nic_mutex;
+ u8 link_status;
- struct nic_service_cap nic_cap;
+ struct nic_service_cap nic_cap;
- struct hinic3_txq *txqs;
- struct hinic3_rxq *rxqs;
+ struct hinic3_txq *txqs;
+ struct hinic3_rxq *rxqs;
struct hinic3_dyna_txrxq_params q_params;
- u16 num_qp_irq;
- struct irq_info *qps_irq_info;
+ u16 num_qp_irq;
+ struct irq_info *qps_irq_info;
- struct workqueue_struct *workq;
+ struct workqueue_struct *workq;
- struct work_struct rx_mode_work;
- struct delayed_work moderation_task;
+ struct work_struct rx_mode_work;
+ struct delayed_work moderation_task;
- struct list_head uc_filter_list;
- struct list_head mc_filter_list;
- unsigned long rx_mod_state;
- int netdev_uc_cnt;
- int netdev_mc_cnt;
+ struct list_head uc_filter_list;
+ struct list_head mc_filter_list;
+ unsigned long rx_mod_state;
+ int netdev_uc_cnt;
+ int netdev_mc_cnt;
- int lb_test_rx_idx;
- int lb_pkt_len;
- u8 *lb_test_rx_buf;
+ int lb_test_rx_idx;
+ int lb_pkt_len;
+ u8 *lb_test_rx_buf;
- struct hinic3_tcam_info tcam;
- struct hinic3_rx_flow_rule rx_flow_rule;
+ struct hinic3_tcam_info tcam;
+ struct hinic3_rx_flow_rule rx_flow_rule;
#ifdef HAVE_XDP_SUPPORT
- struct bpf_prog *xdp_prog;
+ struct bpf_prog *xdp_prog;
#endif
- struct delayed_work periodic_work;
+ struct delayed_work periodic_work;
/* reference to enum hinic3_event_work_flags */
- unsigned long event_flag;
-
- struct hinic3_nic_prof_attr *prof_attr;
- struct hinic3_prof_adapter *prof_adap;
- u64 rsvd8[7];
- u32 rsvd9;
- u32 rxq_get_err_times;
- struct delayed_work rxq_check_work;
+ unsigned long event_flag;
+
+ struct hinic3_nic_prof_attr *prof_attr;
+ struct hinic3_prof_adapter *prof_adap;
+ u64 rsvd8[7];
+ struct hinic3_outband_cfg outband_cfg;
+ u32 rxq_get_err_times;
+ struct delayed_work rxq_check_work;
+ struct delayed_work vport_stats_work;
};
#define hinic_msg(level, nic_dev, msglvl, format, arg...) \
@@ -309,7 +374,7 @@ struct hinic3_uld_info *get_nic_uld_info(void);
u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev);
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
int hinic3_open(struct net_device *netdev);
@@ -328,6 +393,8 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev);
void hinic3_qps_irq_deinit(struct hinic3_nic_dev *nic_dev);
+void qp_del_napi(struct hinic3_irq *irq_cfg);
+
void hinic3_set_netdev_ops(struct hinic3_nic_dev *nic_dev);
bool hinic3_is_netdev_ops_match(const struct net_device *netdev);
@@ -345,10 +412,6 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
int hinic3_get_sset_count(struct net_device *netdev, int sset);
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev);
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
#ifdef ETHTOOL_GLINKSETTINGS
@@ -383,5 +446,17 @@ bool hinic3_is_xdp_enable(struct hinic3_nic_dev *nic_dev);
int hinic3_xdp_max_mtu(struct hinic3_nic_dev *nic_dev);
#endif
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+int set_fecparam(void *hwdev, u8 fecparam);
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec);
+#endif
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
index 57cf07c..6cc294e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
@@ -21,11 +21,12 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
{
- struct vf_data_storage *vf_info;
+ struct vf_data_storage *vf_info = NULL;
u16 func_id;
int err = 0;
@@ -38,7 +39,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
vf_info->pf_vlan, func_id,
HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d MAC\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -51,7 +52,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD,
vf_info->pf_vlan, vf_info->pf_qos,
vf_id);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to add VF %d VLAN_QOS\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -62,7 +63,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_vf_tx_rate(nic_io->hwdev, vf_id,
vf_info->max_rate,
vf_info->min_rate);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d max rate %u, min rate %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->max_rate,
vf_info->min_rate);
@@ -84,7 +85,7 @@ static int register_vf_msg_handler(struct hinic3_nic_io *nic_io, u16 vf_id)
}
err = hinic3_init_vf_config(nic_io, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].registered = true;
@@ -137,6 +138,9 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
int err;
+ if (!vf_info)
+ return -EINVAL;
+
if (register_vf->op_register) {
vf_info->support_extra_feature = register_vf->support_extra_feature;
err = register_vf_msg_handler(nic_io, vf_id);
@@ -145,7 +149,7 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
vf_info->support_extra_feature = 0;
}
- if (err)
+ if (err != 0)
register_info->msg_head.status = EFAULT;
*out_size = sizeof(*register_info);
@@ -157,6 +161,9 @@ void hinic3_unregister_vf(struct hinic3_nic_io *nic_io, u16 vf_id)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vf_info)
+ return;
+
unregister_vf_msg_handler(nic_io, vf_id);
vf_info->support_extra_feature = 0;
}
@@ -181,14 +188,21 @@ static int hinic3_get_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
void *buf_out, u16 *out_size)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf);
+ struct hinic3_port_mac_set *mac_in =
+ (struct hinic3_port_mac_set *)buf_in;
struct hinic3_port_mac_set *mac_info = buf_out;
int err;
- if (HINIC3_SUPPORT_VF_MAC(nic_io->hwdev)) {
+ if (!mac_info || !vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
+ if (HINIC3_SUPPORT_VF_MAC(nic_io->hwdev) != 0) {
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_GET_MAC, buf_in,
in_size, buf_out, out_size);
- if (!err) {
+ if (err == 0) {
if (is_zero_ether_addr(mac_info->mac))
ether_addr_copy(mac_info->mac, vf_info->drv_mac_addr);
}
@@ -211,6 +225,11 @@ static int hinic3_set_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -247,6 +266,11 @@ static int hinic3_del_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -283,12 +307,15 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
struct hinic3_port_mac_update *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
if (!is_valid_ether_addr(mac_in->new_mac)) {
nic_err(nic_io->dev_hdl, "Update VF MAC is invalid.\n");
return -EINVAL;
}
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
-#ifndef __VMWARE__
if (vf_info->use_specified_mac && !vf_info->trust) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
HW_VF_ID_TO_OS(vf));
@@ -296,17 +323,7 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
*out_size = sizeof(*mac_out);
return 0;
}
-#else
- err = hinic_config_vf_request(nic_io->hwdev->pcidev_hdl,
- HW_VF_ID_TO_OS(vf),
- HINIC_CFG_VF_MAC_CHANGED,
- (void *)mac_in->new_mac);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to config VF %d MAC request, err: %d\n",
- HW_VF_ID_TO_OS(vf), err);
- return err;
- }
-#endif
+
mac_in->vlan_id = vf_info->pf_vlan;
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_UPDATE_MAC,
buf_in, in_size, buf_out, out_size);
@@ -362,7 +379,8 @@ static int _l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u32 i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_cmd_handler[i].cmd)
cmd_to_pf = true;
@@ -404,6 +422,8 @@ int hinic3_pf_mbox_handler(void *hwdev,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (index = 0; index < cmd_size; index++) {
if (cmd == vf_cmd_handler[index].cmd)
@@ -460,10 +480,14 @@ void hinic3_notify_dcb_state_event(struct hinic3_nic_io *nic_io,
static void dcb_state_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- struct hinic3_cmd_vf_dcb_state *vf_dcb;
- struct hinic3_nic_io *nic_io;
+ struct hinic3_cmd_vf_dcb_state *vf_dcb = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
vf_dcb = buf_in;
if (!vf_dcb)
@@ -479,9 +503,13 @@ static void tx_pause_excp_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*excp_info)) {
- nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
+ nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %lu\n",
in_size, sizeof(*excp_info));
return;
}
@@ -501,6 +529,10 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_event_info event_info = {0};
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*active_info)) {
nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
@@ -515,6 +547,36 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
hinic3_event_callback(nic_io->hwdev, &event_info);
}
+static void outband_vlan_cfg_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out,
+ u16 *out_size)
+{
+ struct hinic3_outband_cfg_info *outband_cfg_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info = {0};
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ nic_info(nic_io->dev_hdl, "outband vlan cfg event received\n");
+
+ if (in_size != sizeof(*outband_cfg_info)) {
+ nic_err(nic_io->dev_hdl, "outband cfg info invalid in_size: %u, should be %lu\n",
+ in_size, sizeof(*outband_cfg_info));
+ return;
+ }
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = EVENT_NIC_OUTBAND_CFG;
+ memcpy((void *)event_info.event_data,
+ outband_cfg_info, sizeof(*outband_cfg_info));
+
+ hinic3_event_callback(nic_io->hwdev, &event_info);
+}
+
static const struct nic_event_handler nic_cmd_handler[] = {
{
.cmd = HINIC3_NIC_CMD_VF_COS,
@@ -529,6 +591,11 @@ static const struct nic_event_handler nic_cmd_handler[] = {
.cmd = HINIC3_NIC_CMD_BOND_ACTIVE_NOTICE,
.handler = bond_active_event_handler,
},
+
+ {
+ .cmd = HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ .handler = outband_vlan_cfg_event_handler,
+ },
};
static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
@@ -543,6 +610,8 @@ static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (i = 0; i < size; i++) {
if (cmd == nic_cmd_handler[i].cmd) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
index 22670ff..a9768b7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
@@ -16,7 +16,8 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_nic_io.h"
#define HINIC3_DEAULT_TX_CI_PENDING_LIMIT 1
@@ -34,7 +35,7 @@ MODULE_PARM_DESC(tx_coalescing_time, "TX CI coalescing parameter coalescing_time
static unsigned char rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
module_param(rq_wqe_type, byte, 0444);
-MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 0-8Bytes, 1-16Bytes, 2-32Bytes (default=2)");
+MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 1-16Bytes, 2-32Bytes (default=2)");
/*lint +e806*/
static u32 tx_drop_thd_on = HINIC3_DEAULT_DROP_THD_ON;
@@ -45,7 +46,7 @@ static u32 tx_drop_thd_off = HINIC3_DEAULT_DROP_THD_OFF;
module_param(tx_drop_thd_off, uint, 0644);
MODULE_PARM_DESC(tx_drop_thd_off, "TX parameter drop_thd_off (default=0)");
/* performance: ci addr RTE_CACHE_SIZE(64B) alignment */
-#define HINIC3_CI_Q_ADDR_SIZE (64)
+#define HINIC3_CI_Q_ADDR_SIZE (64U)
#define CI_TABLE_SIZE(num_qps, pg_sz) \
(ALIGN((num_qps) * HINIC3_CI_Q_ADDR_SIZE, pg_sz))
@@ -350,6 +351,13 @@ static int hinic3_create_rq(struct hinic3_nic_io *nic_io, struct hinic3_io_queue
{
int err;
+ /* rq_wqe_type Only support type 1-16Bytes, 2-32Bytes */
+ if (rq_wqe_type != HINIC3_NORMAL_RQ_WQE && rq_wqe_type != HINIC3_EXTEND_RQ_WQE) {
+ sdk_warn(nic_io->dev_hdl, "Module Parameter rq_wqe_type value %d is out of range: [%d, %d].",
+ rq_wqe_type, HINIC3_NORMAL_RQ_WQE, HINIC3_EXTEND_RQ_WQE);
+ rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
+ }
+
rq->wqe_type = rq_wqe_type;
rq->q_id = q_id;
rq->msix_entry_idx = rq_msix_idx;
@@ -1044,8 +1052,8 @@ static int clean_queue_offload_ctxt(struct hinic3_nic_io *nic_io,
static int clean_qp_offload_ctxt(struct hinic3_nic_io *nic_io)
{
/* clean LRO/TSO context space */
- return (clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_SQ) ||
- clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_RQ));
+ return ((clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_SQ) != 0) ||
+ (clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_RQ) != 0));
}
/* init qps ctxt and set sq ci attr and arm all sq */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
index 5c5585a..943a736 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
@@ -303,7 +303,7 @@ static inline void hinic3_write_db(struct hinic3_io_queue *queue, int cos,
wmb(); /* Write all before the doorbell */
- writeq(*((u64 *)&db), DB_ADDR(queue, pi));
+ writeq(*((u64 *)(u8 *)&db), DB_ADDR(queue, pi));
}
struct hinic3_dyna_qp_params {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
index 78d943d..9ea93a0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
@@ -32,7 +32,7 @@ struct hinic3_prof_adapter nic_prof_adap_objs[] = {
void hinic3_init_nic_prof_adapter(struct hinic3_nic_dev *nic_dev)
{
- u16 num_adap = ARRAY_SIZE(nic_prof_adap_objs);
+ int num_adap = ARRAY_LEN(nic_prof_adap_objs);
nic_dev->prof_adap = hinic3_prof_init(nic_dev, nic_prof_adap_objs, num_adap,
(void *)&nic_dev->prof_attr);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
index 283c544..6d9b0c1 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
@@ -394,7 +394,8 @@ hinic3_alloc_dynamic_block_resource(struct hinic3_nic_dev *nic_dev,
dynamic_block_ptr = kzalloc(sizeof(*dynamic_block_ptr), GFP_KERNEL);
if (!dynamic_block_ptr) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "fdir filter dynamic alloc block index %d memory failed\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "fdir filter dynamic alloc block index %u memory failed\n",
dynamic_block_id);
return NULL;
}
@@ -433,7 +434,8 @@ hinic3_dynamic_lookup_tcam_filter(struct hinic3_nic_dev *nic_dev,
list_for_each_entry(tmp,
&tcam_info->tcam_dynamic_info.tcam_dynamic_list,
block_list)
- if (tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)
+ if (!tmp ||
+ tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)
break;
if (!tmp || tmp->dynamic_index_cnt >= HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) {
@@ -515,7 +517,7 @@ static int hinic3_add_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, queue: %d, tcam_rule_nums: %d succeed\n",
+ "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, queue: %u, tcam_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev),
tcam_filter->dynamic_block_id, index, fdir_tcam_rule->index,
fdir_tcam_rule->data.qid, tcam_info->tcam_rule_nums + 1);
@@ -582,7 +584,7 @@ static int hinic3_del_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, local_rules_nums: %d, global_rule_nums: %d succeed\n",
+ "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, local_rules_nums: %u, global_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev), dynamic_block_id,
tcam_filter->index, index, tmp->dynamic_index_cnt - 1,
tcam_info->tcam_rule_nums - 1);
@@ -608,7 +610,7 @@ static inline struct hinic3_tcam_filter *
hinic3_tcam_filter_lookup(const struct list_head *filter_list,
struct tag_tcam_key *key)
{
- struct hinic3_tcam_filter *iter;
+ struct hinic3_tcam_filter *iter = NULL;
list_for_each_entry(iter, filter_list, tcam_filter_list) {
if (memcmp(key, &iter->tcam_key,
@@ -633,7 +635,7 @@ static int hinic3_remove_one_rule(struct hinic3_nic_dev *nic_dev,
struct hinic3_ethtool_rx_flow_rule *eth_rule)
{
struct hinic3_tcam_info *tcam_info = &nic_dev->tcam;
- struct hinic3_tcam_filter *tcam_filter;
+ struct hinic3_tcam_filter *tcam_filter = NULL;
struct nic_tcam_cfg_rule fdir_tcam_rule;
struct tag_tcam_key tcam_key;
int err;
@@ -754,7 +756,7 @@ static int validate_flow(struct hinic3_nic_dev *nic_dev,
{
if (fs->location >= MAX_NUM_OF_ETHTOOL_NTUPLE_RULES) {
nicif_err(nic_dev, drv, nic_dev->netdev, "loc exceed limit[0,%lu]\n",
- MAX_NUM_OF_ETHTOOL_NTUPLE_RULES);
+ MAX_NUM_OF_ETHTOOL_NTUPLE_RULES - 1);
return -EINVAL;
}
@@ -875,7 +877,7 @@ int hinic3_ethtool_get_flow(const struct hinic3_nic_dev *nic_dev,
int hinic3_ethtool_get_all_flows(const struct hinic3_nic_dev *nic_dev,
struct ethtool_rxnfc *info, u32 *rule_locs)
{
- int idx = 0;
+ u32 idx = 0;
struct hinic3_ethtool_rx_flow_rule *eth_rule = NULL;
if (!HINIC3_SUPPORT_FDIR(nic_dev->hwdev)) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h b/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
deleted file mode 100644
index a93f3b6..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_PROFILE_H
-#define HINIC3_PROFILE_H
-
-typedef bool (*hinic3_is_match_prof)(void *device);
-typedef void *(*hinic3_init_prof_attr)(void *device);
-typedef void (*hinic3_deinit_prof_attr)(void *porf_attr);
-
-enum prof_adapter_type {
- PROF_ADAP_TYPE_INVALID,
- PROF_ADAP_TYPE_PANGEA = 1,
-
- /* Add prof adapter type before default */
- PROF_ADAP_TYPE_DEFAULT,
-};
-
-/**
- * struct hinic3_prof_adapter - custom scene's profile adapter
- * @type: adapter type
- * @match: Check whether the current function is used in the custom scene.
- * Implemented in the current source file
- * @init: When @match return true, the initialization function called in probe.
- * Implemented in the source file of the custom scene
- * @deinit: When @match return true, the deinitialization function called when
- * remove. Implemented in the source file of the custom scene
- */
-struct hinic3_prof_adapter {
- enum prof_adapter_type type;
- hinic3_is_match_prof match;
- hinic3_init_prof_attr init;
- hinic3_deinit_prof_attr deinit;
-};
-
-#ifdef static
-#undef static
-#define LLT_STATIC_DEF_SAVED
-#endif
-
-/*lint -save -e661 */
-static inline struct hinic3_prof_adapter *
-hinic3_prof_init(void *device, struct hinic3_prof_adapter *adap_objs, int num_adap,
- void **prof_attr)
-{
- struct hinic3_prof_adapter *prof_obj = NULL;
- u16 i;
-
- for (i = 0; i < num_adap; i++) {
- prof_obj = &adap_objs[i];
- if (!(prof_obj->match && prof_obj->match(device)))
- continue;
-
- *prof_attr = prof_obj->init ? prof_obj->init(device) : NULL;
-
- return prof_obj;
- }
-
- return NULL;
-}
-
-static inline void hinic3_prof_deinit(struct hinic3_prof_adapter *prof_obj, void *prof_attr)
-{
- if (!prof_obj)
- return;
-
- if (prof_obj->deinit)
- prof_obj->deinit(prof_attr);
-}
-
-/*lint -restore*/
-
-/* module-level interface */
-#ifdef CONFIG_MODULE_PROF
-struct hinic3_module_ops {
- int (*module_prof_init)(void);
- void (*module_prof_exit)(void);
- void (*probe_fault_process)(void *pdev, u16 level);
- int (*probe_pre_process)(void *pdev);
- void (*probe_pre_unprocess)(void *pdev);
-};
-
-struct hinic3_module_ops *hinic3_get_module_prof_ops(void);
-
-static inline void hinic3_probe_fault_process(void *pdev, u16 level)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (ops && ops->probe_fault_process)
- ops->probe_fault_process(pdev, level);
-}
-
-static inline int hinic3_module_pre_init(void)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (!ops || !ops->module_prof_init)
- return -EINVAL;
-
- return ops->module_prof_init();
-}
-
-static inline void hinic3_module_post_exit(void)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (ops && ops->module_prof_exit)
- ops->module_prof_exit();
-}
-
-static inline int hinic3_probe_pre_process(void *pdev)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (!ops || !ops->probe_pre_process)
- return -EINVAL;
-
- return ops->probe_pre_process(pdev);
-}
-
-static inline void hinic3_probe_pre_unprocess(void *pdev)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (ops && ops->probe_pre_unprocess)
- ops->probe_pre_unprocess(pdev);
-}
-#else
-static inline void hinic3_probe_fault_process(void *pdev, u16 level) { };
-
-static inline int hinic3_module_pre_init(void)
-{
- return 0;
-}
-
-static inline void hinic3_module_post_exit(void) { };
-
-static inline int hinic3_probe_pre_process(void *pdev)
-{
- return 0;
-}
-
-static inline void hinic3_probe_pre_unprocess(void *pdev) { };
-#endif
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
index 6bf3b11..94acf61 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/dcbnl.h>
+#include <linux/init.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -23,7 +24,8 @@
#include "hinic3_hw.h"
#include "hinic3_rss.h"
-/*lint -e806*/
+#include "vram_common.h"
+
static u16 num_qps;
module_param(num_qps, ushort, 0444);
MODULE_PARM_DESC(num_qps, "Number of Queue Pairs (default=0)");
@@ -104,88 +106,84 @@ static int hinic3_get_rq2iq_map(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev, u8 num_cos, u32 *indir)
+static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev,
+ u8 group_num, u32 *indir)
{
- u16 k, group_size, start_qid = 0, qp_num = 0;
- int i = 0;
- u8 j, cur_cos = 0, default_cos;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ u16 k, group_size, start_qid = 0, cur_cos_qnum = 0;
+ u32 i = 0;
+ u8 j, cur_cos = 0, group = 0;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
- if (num_cos == 0) {
+ if (group_num == 0) {
for (i = 0; i < NIC_RSS_INDIR_SIZE; i++)
indir[i] = i % nic_dev->q_params.num_qps;
} else {
- group_size = NIC_RSS_INDIR_SIZE / num_cos;
-
- for (j = 0; j < num_cos; j++) {
- while (cur_cos < NIC_DCB_COS_MAX &&
- nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos] == 0)
- cur_cos++;
-
- if (cur_cos >= NIC_DCB_COS_MAX) {
- if (BIT(nic_dev->hw_dcb_cfg.default_cos) & valid_cos_map)
- default_cos = nic_dev->hw_dcb_cfg.default_cos;
- else
- default_cos = (u8)fls(valid_cos_map) - 1;
+ group_size = NIC_RSS_INDIR_SIZE / group_num;
+
+ for (group = 0; group < group_num; group++) {
+ cur_cos = dcb->hw_dcb_cfg.default_cos;
+ for (j = 0; j < NIC_DCB_COS_MAX; j++) {
+ if ((BIT(j) & valid_cos_map) != 0) {
+ cur_cos = j;
+ valid_cos_map -= (u8)BIT(j);
+ break;
+ }
+ }
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[default_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[default_cos];
+ cur_cos_qnum = dcb->hw_dcb_cfg.cos_qp_num[cur_cos];
+ if (cur_cos_qnum > 0) {
+ start_qid =
+ dcb->hw_dcb_cfg.cos_qp_offset[cur_cos];
} else {
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[cur_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos];
+ start_qid = cur_cos % nic_dev->q_params.num_qps;
+ /* Ensure that the offset of start_id is 0. */
+ cur_cos_qnum = 1;
}
for (k = 0; k < group_size; k++)
- indir[i++] = start_qid + k % qp_num;
-
- cur_cos++;
+ indir[i++] = start_qid + k % cur_cos_qnum;
}
}
}
-/*lint -e528*/
int hinic3_rss_init(struct hinic3_nic_dev *nic_dev, u8 *rq2iq_map, u32 map_size, u8 dcb_en)
{
struct net_device *netdev = nic_dev->netdev;
- u8 i, cos_num;
- u8 cos_map[NIC_DCB_UP_MAX] = {0};
- u8 cfg_map[NIC_DCB_UP_MAX] = {0};
+ u8 i, group_num, cos_bitmap, group = 0;
+ u8 cos_group[NIC_DCB_UP_MAX] = {0};
int err;
- if (dcb_en) {
- cos_num = hinic3_get_dev_user_cos_num(nic_dev);
-
- if (nic_dev->hw_dcb_cfg.trust == 0) {
- memcpy(cfg_map, nic_dev->hw_dcb_cfg.pcp2cos, sizeof(cfg_map));
- } else if (nic_dev->hw_dcb_cfg.trust == 1) {
- for (i = 0; i < NIC_DCB_UP_MAX; i++)
- cfg_map[i] = nic_dev->hw_dcb_cfg.dscp2cos[i * NIC_DCB_DSCP_NUM];
- }
-#define COS_CHANGE_OFFSET 4
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[COS_CHANGE_OFFSET + i] = cfg_map[i];
+ if (dcb_en != 0) {
+ group_num = (u8)roundup_pow_of_two(
+ hinic3_get_dev_user_cos_num(nic_dev));
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[i] = cfg_map[NIC_DCB_UP_MAX - (i + 1)];
+ cos_bitmap = hinic3_get_dev_valid_cos_map(nic_dev);
- while (cos_num & (cos_num - 1))
- cos_num++;
+ for (i = 0; i < NIC_DCB_UP_MAX; i++) {
+ if ((BIT(i) & cos_bitmap) != 0)
+ cos_group[NIC_DCB_UP_MAX - i - 1] = group++;
+ else
+ cos_group[NIC_DCB_UP_MAX - i - 1] =
+ group_num - 1;
+ }
} else {
- cos_num = 0;
+ group_num = 0;
}
- err = hinic3_set_hw_rss_parameters(netdev, 1, cos_num, cos_map, dcb_en);
+ err = hinic3_set_hw_rss_parameters(netdev, 1, group_num,
+ cos_group, dcb_en);
if (err)
return err;
- err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps, cos_num, cos_map,
- NIC_DCB_UP_MAX, nic_dev->rss_indir, rq2iq_map, map_size);
+ err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps,
+ group_num, cos_group, NIC_DCB_UP_MAX,
+ nic_dev->rss_indir, rq2iq_map, map_size);
if (err)
nicif_err(nic_dev, drv, netdev, "Failed to get rq map\n");
return err;
}
-/*lint -e528*/
void hinic3_rss_deinit(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -246,28 +244,59 @@ discard_user_rss_indir:
hinic3_set_default_rss_indir(netdev);
}
+#ifdef HAVE_HOT_REPLACE_FUNC
+bool partition_slave_doing_hotupgrade(void)
+{
+ return get_partition_role() && partition_doing_hotupgrade();
+}
+#endif
+
static void decide_num_qps(struct hinic3_nic_dev *nic_dev)
{
u16 tmp_num_qps = nic_dev->max_qps;
u16 num_cpus = 0;
+ u16 max_num_cpus;
int i, node;
+ int is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ nic_dev->q_params.num_qps = nic_dev->nic_vram->vram_num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Os hotreplace use vram to init num qps 1:%hu 2:%hu\n",
+ nic_dev->q_params.num_qps,
+ nic_dev->nic_vram->vram_num_qps);
+ return;
+ }
+
if (nic_dev->nic_cap.default_num_queues != 0 &&
nic_dev->nic_cap.default_num_queues < nic_dev->max_qps)
tmp_num_qps = nic_dev->nic_cap.default_num_queues;
MOD_PARA_VALIDATE_NUM_QPS(nic_dev, num_qps, tmp_num_qps);
- for (i = 0; i < (int)num_online_cpus(); i++) {
+#ifdef HAVE_HOT_REPLACE_FUNC
+ if (partition_slave_doing_hotupgrade())
+ max_num_cpus = (u16)num_present_cpus();
+ else
+ max_num_cpus = (u16)num_online_cpus();
+#else
+ max_num_cpus = (u16)num_online_cpus();
+#endif
+
+ for (i = 0; i < max_num_cpus; i++) {
node = (int)cpu_to_node(i);
if (node == dev_to_node(&nic_dev->pdev->dev))
num_cpus++;
}
if (!num_cpus)
- num_cpus = (u16)num_online_cpus();
+ num_cpus = max_num_cpus;
nic_dev->q_params.num_qps = (u16)min_t(u16, tmp_num_qps, num_cpus);
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "init num qps 1:%u 2:%u\n",
+ nic_dev->q_params.num_qps, nic_dev->nic_vram->vram_num_qps);
}
static void copy_value_to_rss_hkey(struct hinic3_nic_dev *nic_dev,
@@ -324,7 +353,6 @@ static int alloc_rss_resource(struct hinic3_nic_dev *nic_dev)
return 0;
}
-/*lint -e528*/
void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -363,6 +391,7 @@ void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
set_q_params:
clear_bit(HINIC3_RSS_ENABLE, &nic_dev->flags);
nic_dev->q_params.num_qps = nic_dev->max_qps;
+ nic_dev->nic_vram->vram_num_qps = nic_dev->max_qps;
}
static int hinic3_config_rss_hw_resource(struct hinic3_nic_dev *nic_dev,
@@ -756,6 +785,7 @@ int hinic3_set_channels(struct net_device *netdev,
nic_dev->q_params.num_qps = (u16)count;
}
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
return 0;
}
@@ -816,7 +846,7 @@ int hinic3_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
int err = 0;
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
@@ -923,7 +953,7 @@ int hinic3_get_rxfh_indir(struct net_device *netdev, u32 *indir)
indir = indir1->ring_index;
#endif
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
index 175c4d6..902d7e2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
@@ -15,13 +15,14 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_nic_cfg.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_hw.h"
#include "hinic3_nic.h"
#include "hinic3_common.h"
static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
- u8 *key)
+ u8 *key, u16 key_size)
{
struct hinic3_cmd_rss_hash_key hash_key;
u16 out_size = sizeof(hash_key);
@@ -32,7 +33,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
hash_key.opcode = opcode;
if (opcode == HINIC3_CMD_OP_SET)
- memcpy(hash_key.key, key, NIC_RSS_KEY_SIZE);
+ memcpy(hash_key.key, key, key_size);
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_CFG_RSS_HASH_KEY,
@@ -46,7 +47,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
}
if (opcode == HINIC3_CMD_OP_GET)
- memcpy(key, hash_key.key, NIC_RSS_KEY_SIZE);
+ memcpy(key, hash_key.key, key_size);
return 0;
}
@@ -60,8 +61,11 @@ int hinic3_rss_set_hash_key(void *hwdev, const u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memcpy(hash_key, key, NIC_RSS_KEY_SIZE);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET, hash_key);
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET,
+ hash_key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
@@ -72,7 +76,10 @@ int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET, key);
+ if (!nic_io)
+ return -EINVAL;
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET,
+ key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
@@ -86,6 +93,9 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -126,6 +136,8 @@ int hinic3_rss_set_indir_tbl(void *hwdev, const u32 *indir_table)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd buf\n");
@@ -170,6 +182,8 @@ static int hinic3_cmdq_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
@@ -221,6 +235,8 @@ static int hinic3_mgmt_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&ctx_tbl, 0, sizeof(ctx_tbl));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
ctx |= HINIC3_RSS_TYPE_SET(1, VALID) |
@@ -270,6 +286,8 @@ int hinic3_get_rss_type(void *hwdev, struct nic_rss_type *rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&ctx_tbl, 0, sizeof(struct hinic3_rss_context_table));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
@@ -303,6 +321,9 @@ static int hinic3_rss_cfg_hash_engine(struct hinic3_nic_io *nic_io, u8 opcode,
u16 out_size = sizeof(hash_type);
int err;
+ if (!nic_io)
+ return -EINVAL;
+
memset(&hash_type, 0, sizeof(struct hinic3_cmd_rss_engine_type));
hash_type.func_id = hinic3_global_func_id(nic_io->hwdev);
@@ -336,6 +357,9 @@ int hinic3_rss_set_hash_engine(void *hwdev, u8 type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_SET, &type);
}
@@ -347,6 +371,9 @@ int hinic3_rss_get_hash_engine(void *hwdev, u8 *type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_GET, type);
}
@@ -362,6 +389,8 @@ int hinic3_rss_cfg(void *hwdev, u8 rss_en, u8 cos_num, u8 *prio_tc, u16 num_qps)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&rss_cfg, 0, sizeof(struct hinic3_cmd_rss_config));
rss_cfg.func_id = hinic3_global_func_id(hwdev);
rss_cfg.rss_en = rss_en;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
index 5c60d01..4dbd6dd 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
@@ -10,6 +10,7 @@
#include <linux/interrupt.h>
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
+#include <net/xdp.h>
#include <linux/device.h>
#include <linux/pci.h>
#include <linux/u64_stats_sync.h>
@@ -20,6 +21,7 @@
#include <linux/ipv6.h>
#include <linux/module.h>
#include <linux/compiler.h>
+#include <linux/filter.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -31,10 +33,6 @@
#include "hinic3_rss.h"
#include "hinic3_rx.h"
-static u32 rq_pi_rd_en;
-module_param(rq_pi_rd_en, uint, 0644);
-MODULE_PARM_DESC(rq_pi_rd_en, "Enable rq read pi from host, defaut update pi by doorbell (default=0)");
-
/* performance: ci addr RTE_CACHE_SIZE(64B) alignment */
#define HINIC3_RX_HDR_SIZE 256
#define HINIC3_RX_BUFFER_WRITE 16
@@ -63,19 +61,34 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
struct pci_dev *pdev = nic_dev->pdev;
struct page *page = rx_info->page;
dma_addr_t dma = rx_info->buf_dma_addr;
+ u32 page_offset = 0;
if (likely(dma))
return true;
/* alloc new page for storage */
- page = alloc_pages_node(NUMA_NO_NODE, GFP_ATOMIC | __GFP_COLD |
- __GFP_COMP, nic_dev->page_order);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page = page_pool_alloc_frag(rx_info->page_pool, &page_offset,
+ nic_dev->rx_buff_len,
+ GFP_ATOMIC | __GFP_COLD |
+ __GFP_COMP);
+ if (unlikely(!page))
+ return false;
+ dma = page_pool_get_dma_addr(page);
+ goto set_rx_info;
+ }
+#endif
+ page = alloc_pages_node(NUMA_NO_NODE,
+ GFP_ATOMIC | __GFP_COLD | __GFP_COMP,
+ nic_dev->page_order);
+
if (unlikely(!page))
return false;
/* map page for use */
- dma = dma_map_page(&pdev->dev, page, 0, nic_dev->dma_rx_buff_size,
- DMA_FROM_DEVICE);
+ dma = dma_map_page(&pdev->dev, page, page_offset,
+ nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
/* if mapping failed free memory back to system since
* there isn't much point in holding memory we can't use
*/
@@ -83,10 +96,12 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
__free_pages(page, nic_dev->page_order);
return false;
}
+ goto set_rx_info;
+set_rx_info:
rx_info->page = page;
rx_info->buf_dma_addr = dma;
- rx_info->page_offset = 0;
+ rx_info->page_offset = page_offset;
return true;
}
@@ -108,8 +123,8 @@ static u32 hinic3_rx_fill_wqe(struct hinic3_rxq *rxq)
/* unit of cqe length is 16B */
hinic3_set_sge(&rq_wqe->extend_wqe.cqe_sect.sge,
rx_info->cqe_dma,
- (sizeof(struct hinic3_rq_cqe) >>
- HINIC3_CQE_SIZE_SHIFT));
+ (HINIC3_CQE_LEN >>
+ HINIC3_CQE_SIZE_SHIFT));
/* use fixed len */
rq_wqe->extend_wqe.buf_desc.sge.len =
nic_dev->rx_buff_len;
@@ -163,18 +178,11 @@ static u32 hinic3_rx_fill_buffers(struct hinic3_rxq *rxq)
}
if (likely(i)) {
- if (!rq_pi_rd_en) {
- hinic3_write_db(rxq->rq,
- rxq->q_id & (NIC_DCB_COS_MAX - 1),
- RQ_CFLAG_DP,
- (u16)((u32)rxq->next_to_update <<
- rxq->rq->wqe_type));
- } else {
- /* Write all the wqes before pi update */
- wmb();
-
- hinic3_update_rq_hw_pi(rxq->rq, rxq->next_to_update);
- }
+ hinic3_write_db(rxq->rq,
+ rxq->q_id & (NIC_RX_DB_COS_MAX - 1),
+ RQ_CFLAG_DP,
+ (u16)((u32)rxq->next_to_update <<
+ rxq->rq->wqe_type));
rxq->delta -= i;
rxq->next_to_alloc = rxq->next_to_update;
} else if (free_wqebbs == rxq->q_depth - 1) {
@@ -208,6 +216,18 @@ static void hinic3_rx_free_buffers(struct hinic3_nic_dev *nic_dev, u32 q_depth,
for (i = 0; i < q_depth; i++) {
rx_info = &rx_info_arr[i];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ if (rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool,
+ rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ }
+ continue;
+ }
+#endif
+
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev,
rx_info->buf_dma_addr,
@@ -226,7 +246,7 @@ static void hinic3_rx_free_buffers(struct hinic3_nic_dev *nic_dev, u32 q_depth,
static void hinic3_reuse_rx_page(struct hinic3_rxq *rxq,
struct hinic3_rx_info *old_rx_info)
{
- struct hinic3_rx_info *new_rx_info;
+ struct hinic3_rx_info *new_rx_info = NULL;
u16 nta = rxq->next_to_alloc;
new_rx_info = &rxq->rx_info[nta];
@@ -250,8 +270,8 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
struct hinic3_rx_info *rx_info,
struct sk_buff *skb, u32 size)
{
- struct page *page;
- u8 *va;
+ struct page *page = NULL;
+ u8 *va = NULL;
page = rx_info->page;
va = (u8 *)page_address(page) + rx_info->page_offset;
@@ -267,8 +287,15 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
DMA_FROM_DEVICE);
if (size <= HINIC3_RX_HDR_SIZE && !skb_is_nonlinear(skb)) {
- memcpy(__skb_put(skb, size), va,
- ALIGN(size, sizeof(long))); /*lint !e666*/
+ __skb_put_data(skb, va, size);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool,
+ page, false);
+ return false;
+ }
+#endif
/* page is not reserved, we can reuse buffer as-is */
if (likely(page_to_nid(page) == numa_node_id()))
@@ -276,25 +303,37 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
/* this page cannot be reused so discard it */
put_page(page);
- return false;
+ goto discard_page;
}
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
(int)rx_info->page_offset, (int)size, rxq->buf_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
+
/* avoid re-using remote pages */
if (unlikely(page_to_nid(page) != numa_node_id()))
- return false;
+ goto discard_page;
/* if we are only owner of page we can reuse it */
if (unlikely(page_count(page) != 1))
- return false;
+ goto discard_page;
/* flip page offset to other buffer */
rx_info->page_offset ^= rxq->buf_len;
get_page(page);
return true;
+
+discard_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
}
static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
@@ -334,13 +373,9 @@ static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
head_skb->truesize += rxq->buf_len;
}
- if (likely(hinic3_add_rx_frag(rxq, rx_info, skb, size))) {
+ if (likely(hinic3_add_rx_frag(rxq, rx_info, skb, size)))
hinic3_reuse_rx_page(rxq, rx_info);
- } else {
- /* we are not reusing the buffer so unmap it */
- dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
- rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
- }
+
/* clear contents of buffer_info */
rx_info->buf_dma_addr = 0;
rx_info->page = NULL;
@@ -481,9 +516,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
protocol = hdr.eth->h_proto;
/* L2 header */
- /*lint -save -e778*/
if (protocol == htons(ETH_P_8021_AD) ||
- protocol == htons(ETH_P_8021_Q)) { /*lint -restore*/
+ protocol == htons(ETH_P_8021_Q)) {
if (unlikely(max_len < ETH_HLEN + VLAN_HLEN))
return max_len;
@@ -495,9 +529,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
}
/* L3 header */
- /*lint -save -e778*/
switch (protocol) {
- case htons(ETH_P_IP): /*lint -restore*/
+ case htons(ETH_P_IP):
if ((int)(hdr.data - data) >
(int)(max_len - sizeof(struct iphdr)))
return max_len;
@@ -680,7 +713,7 @@ static void hinic3_copy_lp_data(struct hinic3_nic_dev *nic_dev,
nicif_warn(nic_dev, rx_err, netdev, "Loopback test warning, receive too many test pkts\n");
}
- if (skb->len != nic_dev->lb_pkt_len) {
+ if (skb->len != (u32)(nic_dev->lb_pkt_len)) {
nicif_warn(nic_dev, rx_err, netdev, "Wrong packet length\n");
nic_dev->lb_test_rx_idx++;
return;
@@ -714,7 +747,10 @@ static inline void hinic3_lro_set_gso_params(struct sk_buff *skb, u16 num_lro)
}
#ifdef HAVE_XDP_SUPPORT
-enum hinic3_xdp_pkt {
+enum hinic3_xdp_status {
+ // bpf_prog status
+ HINIC3_XDP_PROG_EMPTY,
+ // pkt action
HINIC3_XDP_PKT_PASS,
HINIC3_XDP_PKT_DROP,
};
@@ -725,9 +761,15 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
while (weqbb_num) {
rx_info = &rxq->rx_info[rxq->cons_idx & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool)
+ goto discard_direct;
+#endif
if (likely(page_to_nid(rx_info->page) == numa_node_id()))
hinic3_reuse_rx_page(rxq, rx_info);
+ goto discard_direct;
+discard_direct:
rx_info->buf_dma_addr = 0;
rx_info->page = NULL;
rxq->cons_idx++;
@@ -737,11 +779,10 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
}
}
-int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
+int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len, struct xdp_buff *xdp)
{
struct bpf_prog *xdp_prog = NULL;
struct hinic3_rx_info *rx_info = NULL;
- struct xdp_buff xdp;
int result = HINIC3_XDP_PKT_PASS;
u16 weqbb_num = 1; /* xdp can only use one rx_buff */
u8 *va = NULL;
@@ -749,13 +790,14 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
rcu_read_lock();
xdp_prog = READ_ONCE(rxq->xdp_prog);
- if (!xdp_prog)
+ if (!xdp_prog) {
+ result = HINIC3_XDP_PROG_EMPTY;
goto unlock_rcu;
+ }
if (unlikely(pkt_len > rxq->buf_len)) {
RXQ_STATS_INC(rxq, xdp_large_pkt);
- weqbb_num = (u16)(pkt_len >> rxq->rx_buff_shift) +
- ((pkt_len & (rxq->buf_len - 1)) ? 1 : 0);
+ weqbb_num = HINIC3_GET_SGE_NUM(pkt_len, rxq);
result = HINIC3_XDP_PKT_DROP;
goto xdp_out;
}
@@ -766,19 +808,20 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
dma_sync_single_range_for_cpu(rxq->dev, rx_info->buf_dma_addr,
rx_info->page_offset,
rxq->buf_len, DMA_FROM_DEVICE);
- xdp.data = va;
- xdp.data_hard_start = xdp.data;
- xdp.data_end = xdp.data + pkt_len;
+ xdp->data = va;
+ xdp->data_hard_start = xdp->data;
+ xdp->data_end = xdp->data + pkt_len;
#ifdef HAVE_XDP_FRAME_SZ
- xdp.frame_sz = rxq->buf_len;
+ xdp->frame_sz = rxq->buf_len;
#endif
#ifdef HAVE_XDP_DATA_META
- xdp_set_data_meta_invalid(&xdp);
+ xdp_set_data_meta_invalid(xdp);
#endif
- prefetchw(xdp.data_hard_start);
- act = bpf_prog_run_xdp(xdp_prog, &xdp);
+ prefetchw(xdp->data_hard_start);
+ act = bpf_prog_run_xdp(xdp_prog, xdp);
switch (act) {
case XDP_PASS:
+ result = HINIC3_XDP_PKT_PASS;
break;
case XDP_DROP:
result = HINIC3_XDP_PKT_DROP;
@@ -799,12 +842,94 @@ unlock_rcu:
return result;
}
+
+static bool hinic3_add_rx_frag_with_xdp(struct hinic3_rxq *rxq, u32 pkt_len,
+ struct hinic3_rx_info *rx_info,
+ struct sk_buff *skb,
+ struct xdp_buff *xdp)
+{
+ struct page *page = rx_info->page;
+
+ if (pkt_len <= HINIC3_RX_HDR_SIZE) {
+ __skb_put_data(skb, xdp->data, pkt_len);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool,
+ page, false);
+ return false;
+ }
+#endif
+
+ if (likely(page_to_nid(page) == numa_node_id()))
+ return true;
+
+ put_page(page);
+ goto umap_page;
+ }
+
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
+ (int)(rx_info->page_offset +
+ (xdp->data - xdp->data_hard_start)),
+ (int)pkt_len, rxq->buf_len);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
+ if (unlikely(page_to_nid(page) != numa_node_id()))
+ goto umap_page;
+ if (unlikely(page_count(page) != 1))
+ goto umap_page;
+
+ rx_info->page_offset ^= rxq->buf_len;
+ get_page(page);
+
+ return true;
+
+umap_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
+}
+
+static struct sk_buff *hinic3_fetch_rx_buffer_xdp(struct hinic3_rxq *rxq,
+ u32 pkt_len,
+ struct xdp_buff *xdp)
+{
+ struct sk_buff *skb;
+ struct hinic3_rx_info *rx_info;
+ u32 sw_ci;
+ bool reuse;
+
+ sw_ci = rxq->cons_idx & rxq->q_mask;
+ rx_info = &rxq->rx_info[sw_ci];
+
+ skb = netdev_alloc_skb_ip_align(rxq->netdev, HINIC3_RX_HDR_SIZE);
+ if (unlikely(!skb))
+ return NULL;
+
+ reuse = hinic3_add_rx_frag_with_xdp(rxq, pkt_len, rx_info, skb, xdp);
+ if (likely(reuse))
+ hinic3_reuse_rx_page(rxq, rx_info);
+
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+
+ rxq->cons_idx += 1;
+ rxq->delta += 1;
+
+ return skb;
+}
+
#endif
static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_rq_cqe *rx_cqe,
u32 pkt_len, u32 vlan_len, u32 status)
{
- struct sk_buff *skb;
+ struct sk_buff *skb = NULL;
struct net_device *netdev = rxq->netdev;
u32 offload_type;
u16 num_lro;
@@ -812,13 +937,25 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_rq_cqe *rx_cqe,
#ifdef HAVE_XDP_SUPPORT
u32 xdp_status;
+ struct xdp_buff xdp = { 0 };
- xdp_status = hinic3_run_xdp(rxq, pkt_len);
+ xdp_status = (u32)(hinic3_run_xdp(rxq, pkt_len, &xdp));
if (xdp_status == HINIC3_XDP_PKT_DROP)
return 0;
-#endif
+ // build skb
+ if (xdp_status != HINIC3_XDP_PROG_EMPTY) {
+ // xdp_prog configured, build skb with xdp
+ skb = hinic3_fetch_rx_buffer_xdp(rxq, pkt_len, &xdp);
+ } else {
+ // xdp_prog not configured, build skb
+ skb = hinic3_fetch_rx_buffer(rxq, pkt_len);
+ }
+#else
+
+ // xdp is not supported
skb = hinic3_fetch_rx_buffer(rxq, pkt_len);
+#endif
if (unlikely(!skb)) {
RXQ_STATS_INC(rxq, alloc_skb_err);
return -ENOMEM;
@@ -852,7 +989,7 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_rq_cqe *rx_cqe,
hinic3_copy_lp_data(nic_dev, skb);
num_lro = HINIC3_GET_RX_NUM_LRO(status);
- if (num_lro)
+ if (num_lro > 1)
hinic3_lro_set_gso_params(skb, num_lro);
skb_record_rx_queue(skb, rxq->q_id);
@@ -931,12 +1068,40 @@ int hinic3_rx_poll(struct hinic3_rxq *rxq, int budget)
return pkts;
}
+#ifdef HAVE_PAGE_POOL_SUPPORT
+static struct page_pool *hinic3_create_page_pool(struct hinic3_nic_dev *nic_dev,
+ u32 rq_depth,
+ struct hinic3_rx_info *rx_info_arr)
+{
+ struct page_pool_params pp_params = {
+ .flags = PP_FLAG_DMA_MAP | PP_FLAG_PAGE_FRAG |
+ PP_FLAG_DMA_SYNC_DEV,
+ .order = nic_dev->page_order,
+ .pool_size = rq_depth * nic_dev->rx_buff_len /
+ (PAGE_SIZE << nic_dev->page_order),
+ .nid = dev_to_node(&(nic_dev->pdev->dev)),
+ .dev = &(nic_dev->pdev->dev),
+ .dma_dir = DMA_FROM_DEVICE,
+ .offset = 0,
+ .max_len = PAGE_SIZE << nic_dev->page_order,
+ };
+ struct page_pool *page_pool;
+ int i;
+
+ page_pool = nic_dev->page_pool_enabled ?
+ page_pool_create(&pp_params) : NULL;
+ for (i = 0; i < rq_depth; i++)
+ rx_info_arr[i].page_pool = page_pool;
+ return page_pool;
+}
+#endif
+
int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
u32 rq_depth, struct hinic3_dyna_rxq_res *rxqs_res)
{
struct hinic3_dyna_rxq_res *rqres = NULL;
u64 cqe_mem_size = sizeof(struct hinic3_rq_cqe) * rq_depth;
- int idx, i;
+ int idx;
u32 pkts;
u64 size;
@@ -947,46 +1112,49 @@ int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
if (!rqres->rx_info) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx info\n", idx);
- goto err_out;
+ goto err_alloc_rx_info;
}
-
rqres->cqe_start_vaddr =
dma_zalloc_coherent(&nic_dev->pdev->dev, cqe_mem_size,
&rqres->cqe_start_paddr,
GFP_KERNEL);
if (!rqres->cqe_start_vaddr) {
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d cqe\n", idx);
- goto err_out;
+ goto err_alloc_cqe;
}
-
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ rqres->page_pool = hinic3_create_page_pool(nic_dev, rq_depth,
+ rqres->rx_info);
+ if (nic_dev->page_pool_enabled && !rqres->page_pool) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to create rxq%d page pool\n", idx);
+ goto err_create_page_pool;
+ }
+#endif
pkts = hinic3_rx_alloc_buffers(nic_dev, rq_depth,
rqres->rx_info);
if (!pkts) {
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx buffers\n", idx);
- goto err_out;
+ goto err_alloc_buffers;
}
rqres->next_to_alloc = (u16)pkts;
}
return 0;
-err_out:
- for (i = 0; i < idx; i++) {
- rqres = &rxqs_res[i];
-
- hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- kfree(rqres->rx_info);
- }
-
+err_alloc_buffers:
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ page_pool_destroy(rqres->page_pool);
+err_create_page_pool:
+#endif
+ dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
+ rqres->cqe_start_vaddr,
+ rqres->cqe_start_paddr);
+err_alloc_cqe:
+ kfree(rqres->rx_info);
+err_alloc_rx_info:
+ hinic3_free_rxqs_res(nic_dev, idx, rq_depth, rxqs_res);
return -ENOMEM;
}
@@ -1001,6 +1169,10 @@ void hinic3_free_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
rqres = &rxqs_res[idx];
hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rqres->page_pool)
+ page_pool_destroy(rqres->page_pool);
+#endif
dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
rqres->cqe_start_vaddr,
rqres->cqe_start_paddr);
@@ -1084,6 +1256,7 @@ void hinic3_free_rxqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->rxqs);
+ nic_dev->rxqs = NULL;
}
int hinic3_alloc_rxqs(struct net_device *netdev)
@@ -1207,6 +1380,15 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
nic_info(&nic_dev->pdev->dev, "rxq %u restore_buf_num:%u\n", q_id, rxq->restore_buf_num);
rx_info = &rxq->rx_info[(hw_ci + rxq->q_depth - 1) & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool && rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool,
+ rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ goto reset_rxq;
+ }
+#endif
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev, rx_info->buf_dma_addr,
nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
@@ -1217,7 +1399,9 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
__free_pages(rx_info->page, nic_dev->page_order);
rx_info->page = NULL;
}
+ goto reset_rxq;
+reset_rxq:
rxq->delta = 1;
rxq->next_to_update = (u16)((hw_ci + rxq->q_depth - 1) & rxq->q_mask);
rxq->cons_idx = (u16)((rxq->next_to_update + 1) & rxq->q_mask);
@@ -1238,15 +1422,10 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
return err;
}
- if (!rq_pi_rd_en) {
- hinic3_write_db(rxq->rq, rxq->q_id & (NIC_DCB_COS_MAX - 1),
- RQ_CFLAG_DP, (u16)((u32)rxq->next_to_update << rxq->rq->wqe_type));
- } else {
- /* Write all the wqes before pi update */
- wmb();
+ hinic3_write_db(rxq->rq, rxq->q_id & (NIC_DCB_COS_MAX - 1),
+ RQ_CFLAG_DP,
+ (u16)((u32)rxq->next_to_update << rxq->rq->wqe_type));
- hinic3_update_rq_hw_pi(rxq->rq, rxq->next_to_update);
- }
return 0;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
index f4d6f4f..7dd4618 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
@@ -4,6 +4,9 @@
#ifndef HINIC3_RX_H
#define HINIC3_RX_H
+#ifdef HAVE_PAGE_POOL_SUPPORT
+#include <net/page_pool.h>
+#endif
#include <linux/types.h>
#include <linux/device.h>
#include <linux/mm_types.h>
@@ -27,22 +30,22 @@
#define HINIC3_RX_CSUM_IPSU_OTHER_ERR BIT(8)
#define HINIC3_HEADER_DATA_UNIT 2
+#define HINIC3_CQE_LEN 32
struct hinic3_rxq_stats {
- u64 packets;
- u64 bytes;
- u64 errors;
- u64 csum_errors;
- u64 other_errors;
- u64 dropped;
- u64 xdp_dropped;
- u64 rx_buf_empty;
-
- u64 alloc_skb_err;
- u64 alloc_rx_buf_err;
- u64 xdp_large_pkt;
- u64 restore_drop_sge;
- u64 rsvd2;
+ u64 packets;
+ u64 bytes;
+ u64 errors;
+ u64 csum_errors;
+ u64 other_errors;
+ u64 dropped;
+ u64 xdp_dropped;
+ u64 rx_buf_empty;
+ u64 alloc_skb_err;
+ u64 alloc_rx_buf_err;
+ u64 xdp_large_pkt;
+ u64 restore_drop_sge;
+ u64 rsvd2;
#ifdef HAVE_NDO_GET_STATS64
struct u64_stats_sync syncp;
#else
@@ -56,6 +59,9 @@ struct hinic3_rx_info {
struct hinic3_rq_cqe *cqe;
dma_addr_t cqe_dma;
struct page *page;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
u32 page_offset;
u32 rsvd1;
struct hinic3_rq_wqe *rq_wqe;
@@ -96,7 +102,7 @@ struct hinic3_rxq {
u16 next_to_update;
struct device *dev; /* device for DMA mapping */
- unsigned long status;
+ u64 status;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
@@ -124,6 +130,9 @@ struct hinic3_dyna_rxq_res {
struct hinic3_rx_info *rx_info;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
};
int hinic3_alloc_rxqs(struct net_device *netdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
index bdd5a8e..051f05d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
@@ -11,9 +11,10 @@
#ifndef HINIC3_SRV_NIC_H
#define HINIC3_SRV_NIC_H
-#include "hinic3_mgmt_interface.h"
+#include <linux/netdevice.h>
+#include "nic_mpu_cmd_defs.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_lld.h"
enum hinic3_queue_type {
@@ -64,6 +65,7 @@ enum hinic3_nic_event_type {
EVENT_NIC_DCB_STATE_CHANGE,
EVENT_NIC_BOND_DOWN,
EVENT_NIC_BOND_UP,
+ EVENT_NIC_OUTBAND_CFG,
};
/* *
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
index e958782..d3f8696 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
@@ -218,6 +218,77 @@ static void get_inner_l4_info(struct sk_buff *skb, union hinic3_l4 *l4,
}
}
+static void get_inner_l3_l4_type(struct sk_buff *skb, union hinic3_ip *ip,
+ union hinic3_l4 *l4,
+ enum sq_l3_type *l3_type, u8 *l4_proto)
+{
+ unsigned char *exthdr = NULL;
+
+ if (ip->v4->version == IP4_VERSION) {
+ *l3_type = IPV4_PKT_WITH_CHKSUM_OFFLOAD;
+ *l4_proto = ip->v4->protocol;
+
+#ifdef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
+ /* inner_transport_header is wrong in centos7.0 and suse12.1 */
+ l4->hdr = ip->hdr + ((u8)ip->v4->ihl << IP_HDR_IHL_UNIT_SHIFT);
+#endif
+ } else if (ip->v4->version == IP6_VERSION) {
+ *l3_type = IPV6_PKT;
+ exthdr = ip->hdr + sizeof(*ip->v6);
+ *l4_proto = ip->v6->nexthdr;
+ if (exthdr != l4->hdr) {
+ __be16 frag_off = 0;
+#ifndef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
+ ipv6_skip_exthdr(skb, (int)(exthdr - skb->data),
+ l4_proto, &frag_off);
+#else
+ int pld_off = 0;
+
+ pld_off = ipv6_skip_exthdr(skb,
+ (int)(exthdr - skb->data),
+ l4_proto, &frag_off);
+ l4->hdr = skb->data + pld_off;
+#endif
+ }
+ } else {
+ *l3_type = UNKNOWN_L3TYPE;
+ *l4_proto = 0;
+ }
+}
+
+static u8 hinic3_get_inner_l4_type(struct sk_buff *skb)
+{
+ enum sq_l3_type l3_type;
+ u8 l4_proto;
+ union hinic3_ip ip;
+ union hinic3_l4 l4;
+
+ ip.hdr = skb_inner_network_header(skb);
+ l4.hdr = skb_inner_transport_header(skb);
+
+ get_inner_l3_l4_type(skb, &ip, &l4, &l3_type, &l4_proto);
+ return l4_proto;
+}
+
+static void hinic3_set_unknown_tunnel_csum(struct sk_buff *skb)
+{
+ int csum_offset;
+ __sum16 skb_csum;
+ u8 l4_proto;
+
+ l4_proto = hinic3_get_inner_l4_type(skb);
+ /* Unsupport tunnel packet, disable csum offload */
+ skb_checksum_help(skb);
+ /* The value of csum is changed from 0xffff to 0 according to RFC1624 */
+ if (skb->ip_summed == CHECKSUM_NONE && l4_proto != IPPROTO_UDP) {
+ csum_offset = skb_checksum_start_offset(skb) + skb->csum_offset;
+ skb_csum = *(__sum16 *)(skb->data + csum_offset);
+ if (skb_csum == 0xffff) {
+ *(__sum16 *)(skb->data + csum_offset) = 0;
+ }
+ }
+}
+
static int hinic3_tx_csum(struct hinic3_txq *txq, struct hinic3_sq_task *task,
struct sk_buff *skb)
{
@@ -251,11 +322,9 @@ static int hinic3_tx_csum(struct hinic3_txq *txq, struct hinic3_sq_task *task,
l4_proto = IPPROTO_RAW;
}
- if (l4_proto != IPPROTO_UDP ||
- ((struct udphdr *)skb_transport_header(skb))->dest != VXLAN_OFFLOAD_PORT_LE) {
+ if (l4_proto != IPPROTO_UDP) {
TXQ_STATS_INC(txq, unknown_tunnel_pkt);
- /* Unsupport tunnel packet, disable csum offload */
- skb_checksum_help(skb);
+ hinic3_set_unknown_tunnel_csum(skb);
return 0;
}
}
@@ -265,44 +334,6 @@ static int hinic3_tx_csum(struct hinic3_txq *txq, struct hinic3_sq_task *task,
return 1;
}
-static void get_inner_l3_l4_type(struct sk_buff *skb, union hinic3_ip *ip,
- union hinic3_l4 *l4,
- enum sq_l3_type *l3_type, u8 *l4_proto)
-{
- unsigned char *exthdr = NULL;
-
- if (ip->v4->version == IP4_VERSION) {
- *l3_type = IPV4_PKT_WITH_CHKSUM_OFFLOAD;
- *l4_proto = ip->v4->protocol;
-
-#ifdef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
- /* inner_transport_header is wrong in centos7.0 and suse12.1 */
- l4->hdr = ip->hdr + ((u8)ip->v4->ihl << IP_HDR_IHL_UNIT_SHIFT);
-#endif
- } else if (ip->v4->version == IP6_VERSION) {
- *l3_type = IPV6_PKT;
- exthdr = ip->hdr + sizeof(*ip->v6);
- *l4_proto = ip->v6->nexthdr;
- if (exthdr != l4->hdr) {
- __be16 frag_off = 0;
-#ifndef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
- ipv6_skip_exthdr(skb, (int)(exthdr - skb->data),
- l4_proto, &frag_off);
-#else
- int pld_off = 0;
-
- pld_off = ipv6_skip_exthdr(skb,
- (int)(exthdr - skb->data),
- l4_proto, &frag_off);
- l4->hdr = skb->data + pld_off;
-#endif
- }
- } else {
- *l3_type = UNKNOWN_L3TYPE;
- *l4_proto = 0;
- }
-}
-
static void hinic3_set_tso_info(struct hinic3_sq_task *task, u32 *queue_info,
enum sq_l4offload_type l4_offload,
u32 offset, u32 mss)
@@ -463,7 +494,8 @@ static void get_pkt_stats(struct hinic3_tx_info *tx_info, struct sk_buff *skb)
#endif
} else {
#endif
- ihs = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ ihs = (u32)(skb_transport_offset(skb)) +
+ tcp_hdrlen(skb);
#if (defined(HAVE_SKB_INNER_TRANSPORT_HEADER) && \
defined(HAVE_SK_BUFF_ENCAPSULATION))
}
@@ -471,7 +503,8 @@ static void get_pkt_stats(struct hinic3_tx_info *tx_info, struct sk_buff *skb)
hdr_len = (skb_shinfo(skb)->gso_segs - 1) * ihs;
tx_info->num_bytes = skb->len + (u64)hdr_len;
} else {
- tx_info->num_bytes = skb->len > ETH_ZLEN ? skb->len : ETH_ZLEN;
+ tx_info->num_bytes = (skb->len > ETH_ZLEN) ?
+ skb->len : ETH_ZLEN;
}
tx_info->num_pkts = 1;
@@ -626,6 +659,14 @@ static netdev_tx_t hinic3_send_one_skb(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
+ /* l2nic outband vlan cfg enable */
+ if ((!skb_vlan_tag_present(skb)) &&
+ (nic_dev->nic_cap.outband_vlan_cfg_en == 1) &&
+ nic_dev->outband_cfg.outband_default_vid != 0) {
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+ (u16)nic_dev->outband_cfg.outband_default_vid);
+ }
+
offload = hinic3_tx_offload(skb, &task, &queue_info, txq);
if (unlikely(offload == TX_OFFLOAD_INVALID)) {
TXQ_STATS_INC(txq, offload_cow_skb_err);
@@ -834,6 +875,7 @@ int hinic3_alloc_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
tqres->bds = kzalloc(size, GFP_KERNEL);
if (!tqres->bds) {
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc txq%d bds info\n", idx);
goto err_out;
@@ -847,7 +889,9 @@ err_out:
tqres = &txqs_res[i];
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
return -ENOMEM;
@@ -864,7 +908,9 @@ void hinic3_free_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
free_all_tx_skbs(nic_dev, sq_depth, tqres->tx_info);
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
}
@@ -938,6 +984,7 @@ void hinic3_free_txqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->txqs);
+ nic_dev->txqs = NULL;
}
static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
@@ -954,7 +1001,7 @@ static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
static int hinic3_stop_sq(struct hinic3_txq *txq)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(txq->netdev);
- unsigned long timeout;
+ u64 timeout;
int err;
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -963,7 +1010,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
return 0;
usleep_range(900, 1000); /* sleep 900 us ~ 1000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* force hardware to drop packets */
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -976,7 +1023,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
break;
usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* Avoid msleep takes too long and get a fake result */
if (is_hw_complete_sq_process(txq->sq))
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
index 1b9e509..7ae029b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
@@ -29,7 +29,7 @@ struct hinic3_wq {
#define WQ_MASK_IDX(wq, idx) ((idx) & (wq)->idx_mask)
#define WQ_MASK_PAGE(wq, pg_idx) \
- ((pg_idx) < (wq)->num_wq_pages ? (pg_idx) : 0)
+ (((pg_idx) < ((wq)->num_wq_pages)) ? (pg_idx) : 0)
#define WQ_PAGE_IDX(wq, idx) ((idx) >> (wq)->wqebbs_per_page_shift)
#define WQ_OFFSET_IN_PAGE(wq, idx) ((idx) & (wq)->wqebbs_per_page_mask)
#define WQ_GET_WQEBB_ADDR(wq, pg_idx, idx_in_pg) \
@@ -75,7 +75,7 @@ static inline void *hinic3_wq_get_multi_wqebbs(struct hinic3_wq *wq,
pg_idx = WQ_PAGE_IDX(wq, *prod_idx);
off_in_page = WQ_OFFSET_IN_PAGE(wq, *prod_idx);
- if (off_in_page + num_wqebbs > wq->wqebbs_per_page) {
+ if ((off_in_page + num_wqebbs) > wq->wqebbs_per_page) {
/* wqe across wq page boundary */
*second_part_wqebbs_addr =
WQ_GET_WQEBB_ADDR(wq, WQ_MASK_PAGE(wq, pg_idx + 1), 0);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
index b742f8a..0419fc2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
@@ -400,12 +400,16 @@ static int wait_for_status_poll(struct hinic3_api_cmd_chain *chain)
API_CMD_STATUS_TIMEOUT, 100); /* wait 100 us once */
}
-static void copy_resp_data(struct hinic3_api_cmd_cell_ctxt *ctxt, void *ack,
- u16 ack_size)
+static void copy_resp_data(struct hinic3_api_cmd_chain *chain,
+ struct hinic3_api_cmd_cell_ctxt *ctxt,
+ void *ack, u16 ack_size)
{
struct hinic3_api_cmd_resp_fmt *resp = ctxt->resp;
+ int rsp_size_align = chain->rsp_size_align - 0x8;
+ int rsp_size = (ack_size > rsp_size_align) ? rsp_size_align : ack_size;
+
+ memcpy(ack, &resp->resp_data, rsp_size);
- memcpy(ack, &resp->resp_data, ack_size);
ctxt->status = 0;
}
@@ -464,7 +468,7 @@ static int wait_for_api_cmd_completion(struct hinic3_api_cmd_chain *chain,
case HINIC3_API_CMD_POLL_READ:
err = wait_for_resp_polling(ctxt);
if (err == 0)
- copy_resp_data(ctxt, ack, ack_size);
+ copy_resp_data(chain, ctxt, ack, ack_size);
else
sdk_err(dev, "API CMD poll response timeout\n");
break;
@@ -1055,13 +1059,11 @@ alloc_cells_buf_err:
alloc_wb_status_err:
kfree(chain->cell_ctxt);
-/*lint -save -e548*/
alloc_cell_ctxt_err:
if (chain->chain_type == HINIC3_API_CMD_WRITE_ASYNC_TO_MGMT_CPU)
spin_lock_deinit(&chain->async_lock);
else
sema_deinit(&chain->sem);
-/*lint -restore*/
return err;
}
@@ -1078,6 +1080,7 @@ static void api_chain_free(struct hinic3_api_cmd_chain *chain)
dma_free_coherent(dev, sizeof(*chain->wb_status),
chain->wb_status, chain->wb_status_paddr);
kfree(chain->cell_ctxt);
+ chain->cell_ctxt = NULL;
if (chain->chain_type == HINIC3_API_CMD_WRITE_ASYNC_TO_MGMT_CPU)
spin_lock_deinit(&chain->async_lock);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
index 0878186..ceb7636 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
@@ -657,7 +657,7 @@ static int cmdq_sync_cmd_direct_resp(struct hinic3_cmdq *cmdq, u8 mod,
cmd_info->channel = channel;
cmdq_set_cmd_buf(cmd_info, cmdq->hwdev, buf_in, NULL);
- memcpy(&saved_cmd_info, cmd_info, sizeof(*cmd_info));
+ memcpy(&saved_cmd_info, cmd_info, sizeof(struct hinic3_cmdq_cmd_info));
cmdq_set_lcmd_wqe(&wqe, SYNC_CMD_DIRECT_RESP, buf_in, NULL,
wrapped, mod, cmd, curr_prod_idx);
@@ -745,7 +745,7 @@ static int cmdq_sync_cmd_detail_resp(struct hinic3_cmdq *cmdq, u8 mod, u8 cmd,
cmd_info->channel = channel;
cmdq_set_cmd_buf(cmd_info, cmdq->hwdev, buf_in, buf_out);
- memcpy(&saved_cmd_info, cmd_info, sizeof(*cmd_info));
+ memcpy(&saved_cmd_info, cmd_info, sizeof(struct hinic3_cmdq_cmd_info));
cmdq_set_lcmd_wqe(&wqe, SYNC_CMD_SGE_RESP, buf_in, buf_out,
wrapped, mod, cmd, curr_prod_idx);
@@ -994,9 +994,11 @@ int hinic3_cmdq_async(void *hwdev, u8 mod, u8 cmd, struct hinic3_cmd_buf *buf_in
return cmdq_async_cmd(&cmdqs->cmdq[HINIC3_CMDQ_SYNC], mod,
cmd, buf_in, channel);
}
+EXPORT_SYMBOL(hinic3_cmdq_async);
int hinic3_cmdq_async_cos(void *hwdev, u8 mod, u8 cmd,
- u8 cos_id, struct hinic3_cmd_buf *buf_in, u16 channel)
+ u8 cos_id, struct hinic3_cmd_buf *buf_in,
+ u16 channel)
{
struct hinic3_cmdqs *cmdqs = NULL;
int err;
@@ -1136,7 +1138,7 @@ void hinic3_cmdq_ceq_handler(void *handle, u32 ceqe_data)
break;
case HINIC3_CMD_TYPE_SET_ARM:
/* arm_bit was set until here */
- if (cmdq_arm_ceq_handler(cmdq, wqe, ci))
+ if (cmdq_arm_ceq_handler(cmdq, wqe, ci) != 0)
return;
break;
default:
@@ -1221,6 +1223,7 @@ cmd_infos_err:
static void free_cmdq(struct hinic3_cmdq *cmdq)
{
kfree(cmdq->cmd_infos);
+ cmdq->cmd_infos = NULL;
spin_lock_deinit(&cmdq->cmdq_lock);
}
@@ -1425,7 +1428,7 @@ static int create_cmdq_wq(struct hinic3_cmdqs *cmdqs)
type = HINIC3_CMDQ_SYNC;
for (; type < cmdqs->cmdq_num; type++)
memcpy((u8 *)cmdqs->wq_block_vaddr +
- CMDQ_WQ_CLA_SIZE * type,
+ ((u64)type * CMDQ_WQ_CLA_SIZE),
cmdqs->cmdq[type].wq.wq_block_vaddr,
cmdqs->cmdq[type].wq.num_wq_pages * sizeof(u64));
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
index b0344ea..b174ad2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
@@ -14,11 +14,6 @@
#include "hinic3_common.h"
#include "hinic3_hwdev.h"
-struct dma_pool {
- unsigned int size;
- void *dev_hdl;
-};
-
#define HINIC3_SCMD_DATA_LEN 16
#define HINIC3_CMDQ_DEPTH 4096
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
index 4c13a2e..af336f2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
@@ -22,11 +22,15 @@
#include "hinic3_sriov.h"
#include "hinic3_nictool.h"
#include "hinic3_pci_id_tbl.h"
+#include "hinic3_hwdev.h"
+#include "cfg_mgmt_mpu_cmd_defs.h"
+#include "mpu_cmd_base_defs.h"
#include "hinic3_dev_mgmt.h"
#define HINIC3_WAIT_TOOL_CNT_TIMEOUT 10000
#define HINIC3_WAIT_TOOL_MIN_USLEEP_TIME 9900
#define HINIC3_WAIT_TOOL_MAX_USLEEP_TIME 10000
+#define HIGHT_BDF 8
static unsigned long card_bit_map;
@@ -60,15 +64,23 @@ void lld_dev_cnt_init(struct hinic3_pcidev *pci_adapter)
void lld_dev_hold(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_inc(&pci_adapter->ref_cnt);
}
void lld_dev_put(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_dec(&pci_adapter->ref_cnt);
}
@@ -236,6 +248,40 @@ void hinic3_get_all_chip_id(void *id_info)
card_id->num = (u32)i;
}
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+ u64 bar1_phy_addr = 0;
+ u64 bar3_phy_addr = 0;
+ u64 bar1_size = 0;
+ u64 bar3_size = 0;
+
+ lld_hold();
+
+ /* get PF bar1 or bar3 physical address to verify */
+ list_for_each_entry(chip_node, &g_hinic3_chip_list, node) {
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (hinic3_func_type(dev->hwdev) == TYPE_VF)
+ continue;
+
+ bar1_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+ bar1_size = pci_resource_len(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+
+ bar3_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ bar3_size = pci_resource_len(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ if ((phy_addr == bar1_phy_addr && vmsize <= bar1_size) ||
+ (phy_addr == bar3_phy_addr && vmsize <= bar3_size)) {
+ lld_put();
+ return 0;
+ }
+ }
+ }
+
+ lld_put();
+ return -EINVAL;
+}
+
void hinic3_get_card_func_info_by_card_name(const char *chip_name,
struct hinic3_card_func_info *card_func)
{
@@ -328,7 +374,6 @@ out:
if (dev)
lld_dev_hold(dev);
lld_put();
-
return dev;
}
@@ -422,6 +467,28 @@ struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name
return NULL;
}
+void *hinic3_get_ppf_dev(void)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct list_head *chip_list = NULL;
+
+ lld_hold();
+ chip_list = get_hinic3_chip_list();
+
+ list_for_each_entry(chip_node, chip_list, node)
+ list_for_each_entry(pci_adapter, &chip_node->func_list, node)
+ if (hinic3_func_type(pci_adapter->hwdev) == TYPE_PPF) {
+ pr_info("Get ppf_func_id:%u", hinic3_global_func_id(pci_adapter->hwdev));
+ lld_put();
+ return pci_adapter->lld_dev.hwdev;
+ }
+
+ lld_put();
+ return NULL;
+}
+EXPORT_SYMBOL(hinic3_get_ppf_dev);
+
struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
enum hinic3_service_type type)
{
@@ -518,6 +585,7 @@ EXPORT_SYMBOL(hinic3_get_ppf_lld_dev_unsafe);
int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len)
{
struct hinic3_pcidev *pci_adapter = NULL;
+ int ret = 0;
if (!lld_dev || !chip_name || !max_len)
return -EINVAL;
@@ -527,12 +595,18 @@ int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 ma
return -EFAULT;
lld_hold();
- strncpy(chip_name, pci_adapter->chip_node->chip_name, max_len);
+ if (strscpy(chip_name, pci_adapter->chip_node->chip_name, max_len) < 0)
+ goto RELEASE;
chip_name[max_len - 1] = '\0';
lld_put();
return 0;
+
+RELEASE:
+ lld_put();
+
+ return ret;
}
EXPORT_SYMBOL(hinic3_get_chip_name);
@@ -541,6 +615,81 @@ struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev)
return lld_dev->hwdev;
}
+void hinic3_write_oshr_info(struct os_hot_replace_info *out_oshr_info,
+ struct hw_pf_info *info,
+ struct hinic3_board_info *board_info,
+ struct card_node *chip_node, u32 serivce_enable,
+ u32 func_info_idx)
+{
+ out_oshr_info->func_infos[func_info_idx].pf_idx = info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].backup_pf =
+ (((info->glb_func_idx) / (board_info->port_num)) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ ((info->glb_func_idx) + (board_info->port_num)) :
+ ((info->glb_func_idx) - (board_info->port_num));
+ out_oshr_info->func_infos[func_info_idx].partition =
+ ((info->glb_func_idx) / (board_info->port_num)) % HOT_REPLACE_PARTITION_NUM;
+ out_oshr_info->func_infos[func_info_idx].port_id = info->port_id;
+ out_oshr_info->func_infos[func_info_idx].bdf = (info->bus_num << HIGHT_BDF) + info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].bus_num = chip_node->bus_num;
+ out_oshr_info->func_infos[func_info_idx].valid = serivce_enable;
+ memcpy(out_oshr_info->func_infos[func_info_idx].card_name,
+ chip_node->chip_name, IFNAMSIZ);
+}
+
+void hinic3_get_os_hot_replace_info(void *oshr_info)
+{
+ struct os_hot_replace_info *out_oshr_info = (struct os_hot_replace_info *)oshr_info;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dst_dev = NULL;
+ struct hinic3_board_info *board_info = NULL;
+ struct hw_pf_info *infos = NULL;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ u32 func_info_idx = 0, func_id = 0, func_num, serivce_enable = 0;
+ struct list_head *hinic3_chip_list = get_hinic3_chip_list();
+ int err;
+
+ lld_hold();
+ pf_infos = kzalloc(sizeof(struct hinic3_hw_pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ pr_err("kzalloc pf_infos fail\n");
+ lld_put();
+ return;
+ }
+ list_for_each_entry(chip_node, hinic3_chip_list, node) {
+ list_for_each_entry(dst_dev, &chip_node->func_list, node) { // get all pf infos in one time by one pf_id
+ err = hinic3_get_hw_pf_infos(dst_dev->hwdev, pf_infos, HINIC3_CHANNEL_COMM);
+ if (err != 0) {
+ pr_err("get pf info failed\n");
+ break;
+ }
+
+ serivce_enable = 0;
+ infos = pf_infos->infos;
+ board_info = &((struct hinic3_hwdev *)(dst_dev->hwdev))->board_info;
+ if (((struct hinic3_hwdev *)(dst_dev->hwdev))->hot_replace_mode == HOT_REPLACE_ENABLE) {
+ serivce_enable = 1;
+ }
+ break;
+ }
+
+ func_num = pf_infos->num_pfs;
+ if (func_num <= 0) {
+ pr_err("get pf num failed\n");
+ break;
+ }
+
+ for (func_id = 0; func_id < func_num; func_id++) {
+ hinic3_write_oshr_info(out_oshr_info, &infos[func_id],
+ board_info, chip_node,
+ serivce_enable, func_info_idx);
+ func_info_idx++;
+ }
+ }
+ out_oshr_info->func_cnt = func_info_idx;
+ kfree(pf_infos);
+ lld_put();
+}
+
struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(lld_dev->pdev);
@@ -620,9 +769,13 @@ void hinic3_get_card_info(const void *hwdev, void *bufin)
}
if (hinic3_func_for_mgmt(fun_hwdev))
- strlcpy(info->pf[i].name, "FOR_MGMT", IFNAMSIZ);
+ strscpy(info->pf[i].name, "FOR_MGMT", IFNAMSIZ);
+
+ if (dev->lld_dev.pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID) {
+ strscpy(info->pf[i].name, "bifur", IFNAMSIZ);
+ }
- strlcpy(info->pf[i].bus_info, pci_name(dev->pcidev),
+ strscpy(info->pf[i].bus_info, pci_name(dev->pcidev),
sizeof(info->pf[i].bus_info));
info->pf_num++;
i = info->pf_num;
@@ -719,6 +872,7 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
struct card_node *chip_node = NULL;
unsigned char i;
unsigned char bus_number = 0;
+ int err;
if (chip_node_is_exist(pci_adapter, &bus_number))
return 0;
@@ -750,6 +904,13 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
return -EINVAL;
}
+ err = sscanf(chip_node->chip_name, HINIC3_CHIP_NAME "%d", &(chip_node->chip_id));
+ if (err <= 0) {
+ clear_bit(i, &card_bit_map);
+ kfree(chip_node);
+ return -EINVAL;
+ }
+
sdk_info(&pci_adapter->pcidev->dev,
"Add new chip %s to global list succeed\n",
chip_node->chip_name);
@@ -801,3 +962,36 @@ int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *
return 0;
}
+
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin)
+{
+ struct card_node *chip_node = NULL;
+ struct card_mbox_cnt_info *info = (struct card_mbox_cnt_info *)bufin;
+ struct hinic3_pcidev *dev = NULL;
+ struct hinic3_hwdev *func_hwdev = NULL;
+ u32 i = 0;
+
+ info->func_num = 0;
+ chip_node = hinic3_get_chip_node_by_hwdev(hwdev);
+ if (chip_node == NULL)
+ return;
+
+ lld_hold();
+
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ func_hwdev = (struct hinic3_hwdev *)dev->hwdev;
+ strscpy(info->func_info[i].bus_info, pci_name(dev->pcidev),
+ sizeof(info->func_info[i].bus_info));
+
+ info->func_info[i].send_cnt = func_hwdev->mbox_send_cnt;
+ info->func_info[i].ack_cnt = func_hwdev->mbox_ack_cnt;
+ info->func_num++;
+ i = info->func_num;
+ if (i >= ARRAY_SIZE(info->func_info)) {
+ sdk_err(&dev->pcidev->dev, "chip_node->func_list bigger than pf_max + vf_max\n");
+ break;
+ }
+ }
+
+ lld_put();
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
index a327c4a..bfa8f3e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
@@ -19,8 +19,10 @@
#define PRINT_ULD_DETACH_TIMEOUT_INTERVAL 1000 /* 1 second */
#define ULD_LOCK_MIN_USLEEP_TIME 900
#define ULD_LOCK_MAX_USLEEP_TIME 1000
+#define BIFUR_RESOURCE_PF_SSID 0x05a1
-#define HINIC3_IS_VF_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_VF)
+#define HINIC3_IS_VF_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_VF || \
+ (pdev)->device == HINIC3_DEV_SDI_5_1_ID_VF)
#define HINIC3_IS_SPU_DEV(pdev) \
(((pdev)->device == HINIC3_DEV_ID_SPU) || ((pdev)->device == HINIC3_DEV_ID_SDI_5_0_PF) || \
(((pdev)->device == HINIC3_DEV_ID_DPU_PF)))
@@ -79,6 +81,13 @@ struct hinic3_pcidev {
u16 probe_fault_level;
u16 rsvd2;
u64 rsvd4;
+
+ struct workqueue_struct *multi_host_mgmt_workq;
+ struct work_struct slave_nic_work;
+ struct work_struct slave_vroce_work;
+
+ struct workqueue_struct *migration_probe_workq;
+ struct delayed_work migration_probe_dwork;
};
struct hinic_chip_info {
@@ -104,4 +113,6 @@ void wait_lld_dev_unused(struct hinic3_pcidev *pci_adapter);
void *hinic3_get_hwdev_by_pcidev(struct pci_dev *pdev);
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
index 1949ab8..8f9d00a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
@@ -101,7 +101,8 @@ static bool check_image_device_type(struct hinic3_hwdev *hwdev, u32 device_type)
static void encapsulate_update_cmd(struct hinic3_cmd_update_firmware *msg,
struct firmware_section *section_info,
- int *remain_len, u32 *send_len, u32 *send_pos)
+ const int *remain_len, u32 *send_len,
+ u32 *send_pos)
{
memset(msg->data, 0, sizeof(msg->data));
msg->ctl_info.sf = (*remain_len == section_info->section_len) ? true : false;
@@ -380,6 +381,7 @@ int hinic3_init_devlink(struct hinic3_hwdev *hwdev)
struct pci_dev *pdev = NULL;
int err;
+ pdev = hwdev->hwif->pdev;
devlink = devlink_alloc(&hinic3_devlink_ops, sizeof(struct hinic3_devlink));
if (!devlink) {
sdk_err(hwdev->dev_hdl, "Failed to alloc devlink\n");
@@ -391,7 +393,6 @@ int hinic3_init_devlink(struct hinic3_hwdev *hwdev)
hwdev->devlink_dev->activate_fw = FW_CFG_DEFAULT_INDEX;
hwdev->devlink_dev->switch_cfg = FW_CFG_DEFAULT_INDEX;
- pdev = hwdev->hwif->pdev;
err = devlink_register(devlink, &pdev->dev);
if (err) {
sdk_err(hwdev->dev_hdl, "Failed to register devlink\n");
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
index 4b08aa0..caa99e3 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
@@ -26,6 +26,8 @@
#include "hinic3_prof_adap.h"
#include "hinic3_eqs.h"
+#include "vram_common.h"
+
#define HINIC3_EQS_WQ_NAME "hinic3_eqs"
#define AEQ_CTRL_0_INTR_IDX_SHIFT 0
@@ -66,7 +68,6 @@
#define HINIC3_TASK_PROCESS_EQE_LIMIT 1024
#define HINIC3_EQ_UPDATE_CI_STEP 64
-/*lint -e806*/
static uint g_aeq_len = HINIC3_DEFAULT_AEQ_LEN;
module_param(g_aeq_len, uint, 0444);
MODULE_PARM_DESC(g_aeq_len,
@@ -83,7 +84,6 @@ static uint g_num_ceqe_in_tasklet = HINIC3_TASK_PROCESS_EQE_LIMIT;
module_param(g_num_ceqe_in_tasklet, uint, 0444);
MODULE_PARM_DESC(g_num_ceqe_in_tasklet,
"The max number of ceqe can be processed in tasklet, default = 1024");
-/*lint +e806*/
#define CEQ_CTRL_0_INTR_IDX_SHIFT 0
#define CEQ_CTRL_0_DMA_ATTR_SHIFT 12
@@ -801,6 +801,7 @@ static int alloc_eq_pages(struct hinic3_eq *eq)
u32 reg, init_val;
u16 pg_idx, i;
int err;
+ gfp_t gfp_vram;
eq->eq_pages = kcalloc(eq->num_pages, sizeof(*eq->eq_pages),
GFP_KERNEL);
@@ -809,12 +810,15 @@ static int alloc_eq_pages(struct hinic3_eq *eq)
return -ENOMEM;
}
+ gfp_vram = hi_vram_get_gfp_vram();
+
for (pg_idx = 0; pg_idx < eq->num_pages; pg_idx++) {
eq_page = &eq->eq_pages[pg_idx];
err = hinic3_dma_zalloc_coherent_align(eq->hwdev->dev_hdl,
eq->page_size,
HINIC3_MIN_EQ_PAGE_SIZE,
- GFP_KERNEL, eq_page);
+ GFP_KERNEL | gfp_vram,
+ eq_page);
if (err) {
sdk_err(eq->hwdev->dev_hdl, "Failed to alloc eq page, page index: %hu\n",
pg_idx);
@@ -865,6 +869,7 @@ static void free_eq_pages(struct hinic3_eq *eq)
&eq->eq_pages[pg_idx]);
kfree(eq->eq_pages);
+ eq->eq_pages = NULL;
}
static inline u32 get_page_size(const struct hinic3_eq *eq)
@@ -1104,7 +1109,8 @@ int hinic3_aeqs_init(struct hinic3_hwdev *hwdev, u16 num_aeqs,
hwdev->aeqs = aeqs;
aeqs->hwdev = hwdev;
aeqs->num_aeqs = num_aeqs;
- aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME, WQ_MEM_RECLAIM,
+ aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME,
+ WQ_MEM_RECLAIM | WQ_HIGHPRI,
HINIC3_MAX_AEQS);
if (!aeqs->workq) {
sdk_err(hwdev->dev_hdl, "Failed to initialize aeq workqueue\n");
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
index a4cbac8..6b96b87 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
@@ -82,6 +82,48 @@ int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id,
return 0;
}
+/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read and clear to zero
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
+ u16 *value)
+{
+ struct chipif_sml_ctr_rd_req req;
+ union ctr_rd_rsp rsp;
+ int ret;
+
+ if (!hwdev || !value)
+ return -EFAULT;
+
+ if (!COMM_SUPPORT_API_CHAIN((struct hinic3_hwdev *)hwdev))
+ return -EPERM;
+
+ memset(&req, 0, sizeof(req));
+
+ hinic3_sml_ctr_read_build_req(&req, instance,
+ CHIPIF_SM_CTR_OP_READ_CLEAR,
+ CHIPIF_ACK, ctr_id, 0);
+
+ ret = hinic3_api_cmd_read_ack(hwdev, node, (u8 *)&req,
+ (unsigned short)sizeof(req),
+ (void *)&rsp,
+ (unsigned short)sizeof(rsp));
+ if (ret) {
+ sdk_err(((struct hinic3_hwdev *)hwdev)->dev_hdl,
+ "Sm 16bit counter clear fail, err(%d)\n", ret);
+ return ret;
+ }
+ sml_ctr_htonl_n((u32 *)&rsp, sizeof(rsp) / sizeof(u32));
+ *value = rsp.bs_ss16_rsp.value1;
+
+ return 0;
+}
+
/**
* hinic3_sm_ctr_rd32 - small single 32 counter read
* @hwdev: the hardware device
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
index cea7581..2d4a9f6 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
@@ -34,13 +34,16 @@ static void parse_pub_res_cap_dfx(struct hinic3_hwdev *hwdev,
cap->max_vf);
sdk_info(hwdev->dev_hdl, "Host_pf_num: 0x%x, pf_id_start: 0x%x, host_vf_num: 0x%x, vf_id_start: 0x%x\n",
cap->pf_num, cap->pf_id_start, cap->vf_num, cap->vf_id_start);
- sdk_info(hwdev->dev_hdl, "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x\n",
- cap->host_valid_bitmap, cap->master_host_id, cap->srv_multi_host_mode);
sdk_info(hwdev->dev_hdl,
- "fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
- cap->fake_vf_start_id, cap->fake_vf_num, cap->fake_vf_max_pctx);
- sdk_info(hwdev->dev_hdl, "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x\n",
- cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len);
+ "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x, hot_plug_disable: 0x%x\n",
+ cap->host_valid_bitmap, cap->master_host_id, cap->srv_multi_host_mode,
+ cap->hot_plug_disable);
+ sdk_info(hwdev->dev_hdl,
+ "os_hot_replace: 0x%x, fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
+ cap->os_hot_replace, cap->fake_vf_start_id, cap->fake_vf_num, cap->fake_vf_max_pctx);
+ sdk_info(hwdev->dev_hdl,
+ "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x, bond_create_mode: 0x%x\n",
+ cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len, cap->bond_create_mode);
}
static void parse_cqm_res_cap(struct hinic3_hwdev *hwdev, struct service_cap *cap,
@@ -109,6 +112,9 @@ static void parse_pub_res_cap(struct hinic3_hwdev *hwdev,
cap->host_valid_bitmap = dev_cap->host_valid_bitmap;
cap->master_host_id = dev_cap->master_host_id;
cap->srv_multi_host_mode = dev_cap->srv_multi_host_mode;
+ cap->hot_plug_disable = dev_cap->hot_plug_disable;
+ cap->bond_create_mode = dev_cap->bond_create_mode;
+ cap->os_hot_replace = dev_cap->os_hot_replace;
cap->fake_vf_en = dev_cap->fake_vf_en;
cap->fake_vf_start_bit = dev_cap->fake_vf_start_bit;
cap->fake_vf_end_bit = dev_cap->fake_vf_end_bit;
@@ -148,18 +154,27 @@ static void parse_l2nic_res_cap(struct hinic3_hwdev *hwdev,
nic_cap->max_sqs = dev_cap->nic_max_sq_id + 1;
nic_cap->max_rqs = dev_cap->nic_max_rq_id + 1;
nic_cap->default_num_queues = dev_cap->nic_default_num_queues;
+ nic_cap->outband_vlan_cfg_en = dev_cap->outband_vlan_cfg_en;
+ nic_cap->lro_enable = dev_cap->lro_enable;
sdk_info(hwdev->dev_hdl, "L2nic resource capbility, max_sqs: 0x%x, max_rqs: 0x%x\n",
nic_cap->max_sqs, nic_cap->max_rqs);
/* Check parameters from firmware */
- if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP ||
- nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
- sdk_info(hwdev->dev_hdl, "Number of qp exceed limit[1-%d]: sq: %u, rq: %u\n",
- HINIC3_CFG_MAX_QP, nic_cap->max_sqs, nic_cap->max_rqs);
+ if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of sq exceed limit[1-%d]: sq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_sqs);
nic_cap->max_sqs = HINIC3_CFG_MAX_QP;
+ }
+
+ if (nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of rq exceed limit[1-%d]: rq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_rqs);
nic_cap->max_rqs = HINIC3_CFG_MAX_QP;
}
+
+ if (nic_cap->outband_vlan_cfg_en)
+ sdk_info(hwdev->dev_hdl, "L2nic outband vlan cfg enabled\n");
}
static void parse_fc_res_cap(struct hinic3_hwdev *hwdev,
@@ -333,6 +348,28 @@ static void parse_ipsec_res_cap(struct hinic3_hwdev *hwdev,
dev_cap->ipsec_max_sactx, dev_cap->ipsec_max_cq);
}
+static void parse_vbs_res_cap(struct hinic3_hwdev *hwdev,
+ struct service_cap *cap,
+ struct cfg_cmd_dev_cap *dev_cap,
+ enum func_type type)
+{
+ struct vbs_service_cap *vbs_cap = &cap->vbs_cap;
+
+ vbs_cap->vbs_max_volq = dev_cap->vbs_max_volq;
+ vbs_cap->vbs_main_pf_enable = dev_cap->vbs_main_pf_enable;
+ vbs_cap->vbs_vsock_pf_enable = dev_cap->vbs_vsock_pf_enable;
+ vbs_cap->vbs_fushion_queue_pf_enable = dev_cap->vbs_fushion_queue_pf_enable;
+
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS resource capbility, vbs_max_volq: 0x%x\n",
+ dev_cap->vbs_max_volq);
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS pf info, vbs_main_pf_enable: 0x%x, vbs_vsock_pf_enable: 0x%x, vbs_fushion_queue_pf_enable: 0x%x\n",
+ dev_cap->vbs_main_pf_enable,
+ dev_cap->vbs_vsock_pf_enable,
+ dev_cap->vbs_fushion_queue_pf_enable);
+}
+
static void parse_dev_cap(struct hinic3_hwdev *dev,
struct cfg_cmd_dev_cap *dev_cap, enum func_type type)
{
@@ -375,6 +412,9 @@ static void parse_dev_cap(struct hinic3_hwdev *dev,
if (IS_PPA_TYPE(dev))
parse_ppa_res_cap(dev, cap, dev_cap, type);
+
+ if (IS_VBS_TYPE(dev))
+ parse_vbs_res_cap(dev, cap, dev_cap, type);
}
static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
@@ -404,6 +444,23 @@ static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
return 0;
}
+u8 hinic3_get_bond_create_mode(void *dev)
+{
+ struct hinic3_hwdev *hwdev = NULL;
+ struct service_cap *cap = NULL;
+
+ if (!dev) {
+ pr_err("pointer dev is NULL\n");
+ return -EINVAL;
+ }
+
+ hwdev = (struct hinic3_hwdev *)dev;
+ cap = &hwdev->cfg_mgmt->svc_cap;
+
+ return cap->bond_create_mode;
+}
+EXPORT_SYMBOL(hinic3_get_bond_create_mode);
+
int hinic3_get_dev_cap(void *dev)
{
enum func_type type;
@@ -1173,6 +1230,20 @@ bool hinic3_support_ppa(void *hwdev, struct ppa_service_cap *cap)
}
EXPORT_SYMBOL(hinic3_support_ppa);
+bool hinic3_support_bifur(void *hwdev, struct bifur_service_cap *cap)
+{
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)hwdev;
+
+ if (!hwdev)
+ return false;
+
+ if (!IS_BIFUR_TYPE(dev))
+ return false;
+
+ return true;
+}
+EXPORT_SYMBOL(hinic3_support_bifur);
+
bool hinic3_support_migr(void *hwdev, struct migr_service_cap *cap)
{
struct hinic3_hwdev *dev = hwdev;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
index db6e3ca..7157e97 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
@@ -166,6 +166,11 @@ struct service_cap {
u8 srv_multi_host_mode;
u16 virtio_vq_size;
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 os_hot_replace;
+ u8 rsvd1;
+
u8 timer_pf_num;
u8 timer_pf_id_start;
u16 timer_vf_num;
@@ -319,9 +324,11 @@ struct cfg_mgmt_info {
#define IS_RDMA_ENABLE(dev) \
((dev)->cfg_mgmt->svc_cap.sf_svc_attr.rdma_en)
#define IS_PPA_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_PPA)
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_PPA)
#define IS_MIGR_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_MIGRATE)
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_MIGRATE)
+#define IS_BIFUR_TYPE(dev) \
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_BIFUR)
int init_cfg_mgmt(struct hinic3_hwdev *dev);
@@ -333,5 +340,7 @@ void free_capability(struct hinic3_hwdev *dev);
int hinic3_init_vf_dev_cap(void *hwdev);
+u8 hinic3_get_bond_create_mode(void *dev);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
index d8a1a28..47264f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
@@ -21,7 +21,9 @@
#include "hinic3_hw_cfg.h"
#include "hinic3_cmdq.h"
#include "mpu_inband_cmd_defs.h"
+#include "mpu_board_defs.h"
#include "hinic3_hw_comm.h"
+#include "vram_common.h"
#define HINIC3_MSIX_CNT_LLI_TIMER_SHIFT 0
#define HINIC3_MSIX_CNT_LLI_CREDIT_SHIFT 8
@@ -242,12 +244,19 @@ int hinic3_func_reset(void *dev, u16 func_id, u64 reset_flag, u16 channel)
struct hinic3_hwdev *hwdev = dev;
u16 out_size = sizeof(func_reset);
int err = 0;
+ int is_in_kexec;
if (!dev) {
pr_err("Invalid para: dev is null.\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ sdk_info(hwdev->dev_hdl, "Skip function reset!\n");
+ return 0;
+ }
+
sdk_info(hwdev->dev_hdl, "Function is reset, flag: 0x%llx, channel:0x%x\n",
reset_flag, channel);
@@ -523,7 +532,7 @@ EXPORT_SYMBOL(hinic3_set_ppf_flr_type);
int hinic3_set_ppf_tbl_hotreplace_flag(void *hwdev, u8 flag)
{
- struct comm_cmd_ppf_tbl_htrp_config htr_info = {0};
+ struct comm_cmd_ppf_tbl_htrp_config htr_info = {};
u16 out_size = sizeof(struct comm_cmd_ppf_tbl_htrp_config);
struct hinic3_hwdev *dev = hwdev;
int ret;
@@ -868,11 +877,19 @@ static int set_ppf_tmr_status(struct hinic3_hwdev *hwdev,
int hinic3_ppf_tmr_start(void *hwdev)
{
+ int is_in_kexec;
+
if (!hwdev) {
pr_err("Hwdev pointer is NULL for starting ppf timer\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ pr_info("Skip starting ppt timer during kexec");
+ return 0;
+ }
+
return set_ppf_tmr_status(hwdev, HINIC_PPF_TMR_FLAG_START);
}
EXPORT_SYMBOL(hinic3_ppf_tmr_start);
@@ -888,18 +905,110 @@ int hinic3_ppf_tmr_stop(void *hwdev)
}
EXPORT_SYMBOL(hinic3_ppf_tmr_stop);
+static int hi_vram_kalloc_align(struct hinic3_hwdev *hwdev, char *name,
+ u32 page_size, u32 page_num,
+ struct hinic3_dma_addr_align *mem_align)
+{
+ void *vaddr = NULL, *align_vaddr = NULL;
+ dma_addr_t paddr, align_paddr;
+ u64 real_size = page_size;
+ u64 align = page_size;
+
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ /* align */
+ if (align_paddr == paddr) {
+ align_vaddr = vaddr;
+ goto out;
+ }
+
+ hi_vram_kfree((void *)vaddr, name, real_size);
+
+ /* realloc memory for align */
+ real_size = page_size + align;
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc align failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ align_vaddr = (void *)((u64)vaddr + (align_paddr - paddr));
+
+out:
+ mem_align->real_size = (u32)real_size;
+ mem_align->ori_vaddr = vaddr;
+ mem_align->ori_paddr = paddr;
+ mem_align->align_vaddr = align_vaddr;
+ mem_align->align_paddr = align_paddr;
+
+ return 0;
+}
+
+static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
+{
+ u32 i;
+ struct hinic3_dma_addr_align *page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = hwdev->mqm_eqm_vram_name;
+
+ page_addr = hwdev->mqm_att.brm_srch_page_addr;
+
+ for (i = 0; i < hwdev->mqm_att.page_num; i++) {
+ if (is_use_vram != 0) {
+ hi_vram_kfree(page_addr->ori_vaddr, mqm_eqm_vram_name[i].vram_name,
+ page_addr->real_size);
+ } else {
+ hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
+ }
+ page_addr->ori_vaddr = NULL;
+ page_addr++;
+ }
+
+ kfree(mqm_eqm_vram_name);
+ hwdev->mqm_eqm_vram_name = NULL;
+}
+
static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
u32 page_num)
{
struct hinic3_dma_addr_align *page_addr = hwdev->mqm_att.brm_srch_page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = NULL;
u32 valid_num = 0;
u32 flag = 1;
u32 i = 0;
int err;
+ u16 func_id;
+
+ mqm_eqm_vram_name = kzalloc(sizeof(struct mqm_eqm_vram_name_s) * page_num, GFP_KERNEL);
+ if (mqm_eqm_vram_name == NULL) {
+ sdk_err(hwdev->dev_hdl, "mqm eqm alloc vram name failed.\n");
+ return -ENOMEM;
+ }
+
+ hwdev->mqm_eqm_vram_name = mqm_eqm_vram_name;
+ func_id = hinic3_global_func_id(hwdev);
for (i = 0; i < page_num; i++) {
- err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl, page_size,
- page_size, GFP_KERNEL, page_addr);
+ if (is_use_vram != 0) {
+ snprintf(mqm_eqm_vram_name[i].vram_name,
+ VRAM_NAME_MAX_LEN, "%s%u%s%u",
+ VRAM_CQM_GLB_FUNC_BASE, func_id, VRAM_NIC_MQM, i);
+ err = hi_vram_kalloc_align(
+ hwdev, mqm_eqm_vram_name[i].vram_name,
+ page_size, page_num, page_addr);
+ } else {
+ err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl, page_size,
+ page_size, GFP_KERNEL, page_addr);
+ }
if (err) {
flag = 0;
break;
@@ -908,15 +1017,12 @@ static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
page_addr++;
}
+ hwdev->mqm_att.page_num = valid_num;
+
if (flag == 1) {
hwdev->mqm_att.page_size = page_size;
- hwdev->mqm_att.page_num = page_num;
} else {
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
- for (i = 0; i < valid_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
+ mqm_eqm_free_page_mem(hwdev);
return -EFAULT;
}
@@ -955,19 +1061,6 @@ static int mqm_eqm_alloc_page_mem(struct hinic3_hwdev *hwdev)
return ret;
}
-static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
-{
- u32 i;
- struct hinic3_dma_addr_align *page_addr;
-
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
-
- for (i = 0; i < hwdev->mqm_att.page_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
-}
-
static int mqm_eqm_set_cfg_2_hw(struct hinic3_hwdev *hwdev, u8 valid)
{
struct comm_cmd_eqm_cfg info_eqm_cfg;
@@ -1098,6 +1191,7 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
{
struct comm_cmd_get_eqm_num info_eqm_fix;
int ret;
+ int is_in_kexec;
if (hwdev->hwif->attr.func_type != TYPE_PPF)
return 0;
@@ -1127,10 +1221,15 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
goto err_page;
}
- ret = mqm_eqm_set_page_2_hw(hwdev);
- if (ret) {
- sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
- goto err_ecmd;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ ret = mqm_eqm_set_page_2_hw(hwdev);
+ if (ret) {
+ sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
+ goto err_ecmd;
+ }
+ } else {
+ sdk_info(hwdev->dev_hdl, "Mqm db don't set to chip when os hot replace.\r\n");
}
ret = mqm_eqm_set_cfg_2_hw(hwdev, 1);
@@ -1568,3 +1667,15 @@ int hinic3_switch_config(void *hwdev, u8 cfg_index)
return 0;
}
+
+bool hinic3_is_optical_module_mode(void *hwdev)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (dev->board_info.board_type == BOARD_TYPE_STRG_4X25G_COMSTORAGE ||
+ dev->board_info.board_type == BOARD_TYPE_CAL_4X25G_COMSTORAGE ||
+ dev->board_info.board_type == BOARD_TYPE_CAL_2X100G_TCE_BACKPLANE)
+ return false;
+
+ return true;
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
index baa1ce0..722fecd 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
@@ -252,98 +252,6 @@ static u32 get_up_timeout_val(enum hinic3_mod_type mod, u16 cmd)
return 0; /* use default mbox/apichain timeout time */
}
-static int api_csr_read(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
-{
- struct up_log_msg_st *up_log_msg = (struct up_log_msg_st *)buf_in;
- u8 *buf_out_tmp = (u8 *)buf_out;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
-
- if (!buf_in || !buf_out || in_size != sizeof(*up_log_msg) ||
- *out_size != up_log_msg->rd_len || up_log_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = up_log_msg->rd_len;
- rd_addr = up_log_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_rd32(hwdev, node_id,
- rd_addr + offset,
- (u32 *)(buf_out_tmp + offset));
- if (ret) {
- pr_err("Csr rd fail, err: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, node_id, rd_addr + offset);
- return ret;
- }
- offset += DW_WIDTH;
- }
- *out_size = rd_len;
-
- return ret;
-}
-
-static int api_csr_write(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out,
- u32 *out_size)
-{
- struct csr_write_st *csr_write_msg = (struct csr_write_st *)buf_in;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
- u8 *data = NULL;
-
- if (!buf_in || in_size != sizeof(*csr_write_msg) || csr_write_msg->rd_len == 0 ||
- csr_write_msg->rd_len > API_CSR_MAX_RD_LEN || csr_write_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = csr_write_msg->rd_len;
- rd_addr = csr_write_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- data = kzalloc(rd_len, GFP_KERNEL);
- if (!data) {
- pr_err("No more memory\n");
- return -EFAULT;
- }
- if (copy_from_user(data, (void *)csr_write_msg->data, rd_len)) {
- pr_err("Copy information from user failed\n");
- kfree(data);
- return -EFAULT;
- }
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_wr32(hwdev, node_id,
- rd_addr + offset,
- *((u32 *)(data + offset)));
- if (ret) {
- pr_err("Csr wr fail, ret: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, rd_addr + offset, node_id);
- kfree(data);
- return ret;
- }
- offset += DW_WIDTH;
- }
-
- *out_size = 0;
- kfree(data);
- return ret;
-}
-
int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
@@ -370,10 +278,8 @@ int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
return ret;
}
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_BYPASS) {
- if (nt_msg->mpu_cmd.cmd == API_CSR_WRITE)
- return api_csr_write(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
-
- ret = api_csr_read(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
+ pr_err("Unsupported api_type %u\n", nt_msg->mpu_cmd.api_type);
+ return -EINVAL;
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_TO_MPU) {
timeout = get_up_timeout_val(mod, cmd);
if (hinic3_pcie_itf_id(hwdev) != SPU_HOST_ID)
@@ -440,6 +346,23 @@ static int sm_rd16(void *hwdev, u32 id, u8 instance,
return ret;
}
+static int sm_rd16_clear(void *hwdev, u32 id, u8 instance,
+ u8 node, struct sm_out_st *buf_out)
+{
+ u16 val1;
+ int ret;
+
+ ret = hinic3_sm_ctr_rd16_clear(hwdev, node, instance, id, &val1);
+ if (ret != 0) {
+ pr_err("Get sm ctr clear information (16 bits)failed!\n");
+ val1 = 0xffff;
+ }
+
+ buf_out->val1 = val1;
+
+ return ret;
+}
+
static int sm_rd32(void *hwdev, u32 id, u8 instance,
u8 node, struct sm_out_st *buf_out)
{
@@ -559,6 +482,7 @@ const struct sm_module_handle sm_module_cmd_handle[] = {
{SM_CTR_RD32, sm_rd32},
{SM_CTR_RD64_PAIR, sm_rd64_pair},
{SM_CTR_RD64, sm_rd64},
+ {SM_CTR_RD16_CLEAR, sm_rd16_clear},
{SM_CTR_RD32_CLEAR, sm_rd32_clear},
{SM_CTR_RD64_PAIR_CLEAR, sm_rd64_pair_clear},
{SM_CTR_RD64_CLEAR, sm_rd64_clear}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
index 620136a..ac80b63 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
@@ -101,6 +101,12 @@ enum hinic3_pcie_tph {
#define SLAVE_HOST_STATUS_SET(host_id, enable) (((u8)(enable) & 1U) << (host_id))
#define SLAVE_HOST_STATUS_GET(host_id, val) (!!((val) & (1U << (host_id))))
+#ifdef HAVE_HOT_REPLACE_FUNC
+ extern int get_partition_id(void);
+#else
+ static int get_partition_id(void) { return 0; }
+#endif
+
void set_slave_host_enable(void *hwdev, u8 host_id, bool enable)
{
u32 reg_val;
@@ -207,6 +213,28 @@ static void hinic3_init_host_mode_pre(struct hinic3_hwdev *hwdev)
}
}
+static void hinic3_init_hot_plug_status(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->hot_plug_disable) {
+ hwdev->hot_plug_mode = HOT_PLUG_DISABLE;
+ } else {
+ hwdev->hot_plug_mode = HOT_PLUG_ENABLE;
+ }
+}
+
+static void hinic3_init_os_hot_replace(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->os_hot_replace) {
+ hwdev->hot_replace_mode = HOT_REPLACE_ENABLE;
+ } else {
+ hwdev->hot_replace_mode = HOT_REPLACE_DISABLE;
+ }
+}
+
static u8 hinic3_nic_sw_aeqe_handler(void *hwdev, u8 event, u8 *data)
{
struct hinic3_hwdev *dev = hwdev;
@@ -270,14 +298,20 @@ static void chip_fault_show(struct hinic3_hwdev *hwdev,
"fatal", "reset", "host", "flr", "general", "suggestion"};
char level_str[FAULT_SHOW_STR_LEN + 1];
u8 level;
+ int ret;
memset(level_str, 0, FAULT_SHOW_STR_LEN + 1);
level = event->event.chip.err_level;
- if (level < FAULT_LEVEL_MAX)
- strncpy(level_str, fault_level[level],
- FAULT_SHOW_STR_LEN);
- else
- strncpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (level < FAULT_LEVEL_MAX) {
+ ret = strscpy(level_str, fault_level[level],
+ FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ } else {
+ ret = strscpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ }
if (level == FAULT_LEVEL_SERIOUS_FLR)
dev_err(hwdev->dev_hdl, "err_level: %u [%s], flr func_id: %u\n",
@@ -299,6 +333,7 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
"reg rd timeout", "reg wr timeout", "phy fault", "tsensor fault"};
char type_str[FAULT_SHOW_STR_LEN + 1] = {0};
struct fault_event_stats *fault = NULL;
+ int ret;
sdk_err(hwdev->dev_hdl, "Fault event report received, func_id: %u\n",
hinic3_global_func_id(hwdev));
@@ -306,10 +341,14 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
fault = &hwdev->hw_stats.fault_event_stats;
if (event->type < FAULT_TYPE_MAX) {
- strncpy(type_str, fault_type[event->type], sizeof(type_str));
+ ret = strscpy(type_str, fault_type[event->type], sizeof(type_str));
+ if (ret < 0)
+ return;
atomic_inc(&fault->fault_type_stat[event->type]);
} else {
- strncpy(type_str, "Unknown", sizeof(type_str));
+ ret = strscpy(type_str, "Unknown", sizeof(type_str));
+ if (ret < 0)
+ return;
}
sdk_err(hwdev->dev_hdl, "Fault type: %u [%s]\n", event->type, type_str);
@@ -1536,15 +1575,30 @@ int hinic3_init_hwdev(struct hinic3_init_para *para)
hinic3_init_host_mode_pre(hwdev);
+ hinic3_init_hot_plug_status(hwdev);
+
+ hinic3_init_os_hot_replace(hwdev);
+
err = hinic3_multi_host_mgmt_init(hwdev);
if (err != 0) {
sdk_err(hwdev->dev_hdl, "Failed to init function mode\n");
goto init_multi_host_fail;
}
- err = hinic3_init_ppf_work(hwdev);
- if (err != 0)
- goto init_ppf_work_fail;
+ // hot_replace_mode is enable, run ppf function only when partition_id is 0
+ // or run ppf function directly
+ if (hwdev->hot_replace_mode == HOT_REPLACE_ENABLE) {
+ if (get_partition_id() == 0) {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0) {
+ goto init_ppf_work_fail;
+ }
+ }
+ } else {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0)
+ goto init_ppf_work_fail;
+ }
err = hinic3_set_comm_features(hwdev, hwdev->features, COMM_MAX_FEATURE_QWORD);
if (err != 0) {
@@ -1948,6 +2002,19 @@ void hinic3_link_event_stats(void *dev, u8 link)
}
EXPORT_SYMBOL(hinic3_link_event_stats);
+int hinic3_get_link_event_stats(void *dev, int *link_state)
+{
+ struct hinic3_hwdev *hwdev = dev;
+
+ if (!hwdev || !link_state)
+ return -EINVAL;
+
+ *link_state = hwdev->hw_stats.link_event_stats.link_down_stats.counter;
+
+ return 0;
+}
+EXPORT_SYMBOL(hinic3_get_link_event_stats);
+
u8 hinic3_max_pf_num(void *hwdev)
{
if (!hwdev)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
index e739767..7c2cfc2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
@@ -10,6 +10,7 @@
#include "hinic3_hw.h"
#include "mpu_inband_cmd_defs.h"
#include "hinic3_profile.h"
+#include "vram_common.h"
struct cfg_mgmt_info;
@@ -82,6 +83,22 @@ enum hinic3_host_mode_e {
HINIC3_SDI_MODE_MAX,
};
+enum hinic3_hot_plug_mode {
+ HOT_PLUG_ENABLE,
+ HOT_PLUG_DISABLE,
+};
+
+enum hinic3_os_hot_replace_mode {
+ HOT_REPLACE_DISABLE,
+ HOT_REPLACE_ENABLE,
+};
+
+#define UNSUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_DISABLE)
+
+#define SUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_ENABLE)
+
#define MULTI_HOST_CHIP_MODE_SHIFT 0
#define MULTI_HOST_MASTER_MBX_STS_SHIFT 17
#define MULTI_HOST_PRIV_DATA_SHIFT 0x8
@@ -100,6 +117,10 @@ enum hinic3_host_mode_e {
((val) & (~(MULTI_HOST_##member##_MASK \
<< MULTI_HOST_##member##_SHIFT)))
+struct mqm_eqm_vram_name_s {
+ char vram_name[VRAM_NAME_MAX_LEN];
+};
+
struct hinic3_hwdev {
void *adapter_hdl; /* pointer to hinic3_pcidev or NDIS_Adapter */
void *pcidev_hdl; /* pointer to pcidev or Handler */
@@ -138,6 +159,9 @@ struct hinic3_hwdev {
u32 rsvd2;
struct hinic3_multi_host_mgmt *mhost_mgmt;
+ char mhost_mgmt_name[VRAM_NAME_MAX_LEN];
+
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name;
struct mutex stateful_mutex; /* protect cqm init and deinit */
@@ -170,7 +194,10 @@ struct hinic3_hwdev {
struct hinic3_devlink *devlink_dev;
enum hinic3_func_mode func_mode;
- u32 rsvd3;
+ enum hinic3_hot_plug_mode hot_plug_mode;
+
+ enum hinic3_os_hot_replace_mode hot_replace_mode;
+ u32 rsvd5;
DECLARE_BITMAP(func_probe_in_host, MAX_FUNCTION_NUM);
DECLARE_BITMAP(netdev_setup_state, MAX_FUNCTION_NUM);
@@ -179,7 +206,10 @@ struct hinic3_hwdev {
u64 last_recv_aeq_cnt;
u16 aeq_busy_cnt;
- u64 rsvd4[8];
+ u64 mbox_send_cnt;
+ u64 mbox_ack_cnt;
+
+ u64 rsvd4[5];
};
#define HINIC3_DRV_FEATURE_QW0 \
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
index 33f1210..8590f70 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
@@ -544,6 +544,7 @@ static void free_db_area(struct hinic3_free_db_area *free_db_area)
{
spin_lock_deinit(&free_db_area->idx_lock);
kfree(free_db_area->db_bitmap_array);
+ free_db_area->db_bitmap_array = NULL;
}
static int get_db_idx(struct hinic3_hwif *hwif, u32 *idx)
@@ -841,6 +842,7 @@ void hinic3_free_hwif(struct hinic3_hwdev *hwdev)
free_db_area(&hwdev->hwif->free_db_area);
enable_all_msix(hwdev);
kfree(hwdev->hwif);
+ hwdev->hwif = NULL;
}
u16 hinic3_global_func_id(void *hwdev)
@@ -856,6 +858,44 @@ u16 hinic3_global_func_id(void *hwdev)
}
EXPORT_SYMBOL(hinic3_global_func_id);
+/**
+ * get function id from register,used by sriov hot migration process
+ * @hwdev: the pointer to hw device
+ */
+u16 hinic3_global_func_id_hw(void *hwdev)
+{
+ u32 addr, attr0;
+ struct hinic3_hwdev *dev;
+
+ dev = (struct hinic3_hwdev *)hwdev;
+ addr = HINIC3_CSR_FUNC_ATTR0_ADDR;
+ attr0 = hinic3_hwif_read_reg(dev->hwif, addr);
+
+ return HINIC3_AF0_GET(attr0, FUNC_GLOBAL_IDX);
+}
+
+/**
+ * get function id, used by sriov hot migratition process.
+ * @hwdev: the pointer to hw device
+ * @func_id: function id
+ */
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id)
+{
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)hwdev;
+
+ if (!hwdev || !func_id)
+ return -EINVAL;
+
+ /* only vf get func_id from chip reg for sriov migrate */
+ if (!HINIC3_IS_VF(dev)) {
+ *func_id = hinic3_global_func_id(hwdev);
+ return 0;
+ }
+
+ *func_id = hinic3_global_func_id_hw(dev);
+ return 0;
+}
+
u16 hinic3_intr_num(void *hwdev)
{
struct hinic3_hwif *hwif = NULL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
index 321a3b7..82a26ae 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
@@ -16,6 +16,7 @@
#include <linux/rtc.h>
#include <linux/aer.h>
#include <linux/debugfs.h>
+#include <linux/notifier.h>
#include "ossl_knl.h"
#include "hinic3_mt.h"
@@ -29,26 +30,41 @@
#include "hinic3_lld.h"
#include "hinic3_profile.h"
+#include "hinic3_hw_cfg.h"
+#include "hinic3_multi_host_mgmt.h"
#include "hinic3_hwdev.h"
#include "hinic3_prof_adap.h"
-#include "comm_msg_intf.h"
+#include "hinic3_devlink.h"
+
+#include "vram_common.h"
+
+enum partition_dev_type {
+ PARTITION_DEV_NONE = 0,
+ PARTITION_DEV_SHARED,
+ PARTITION_DEV_EXCLUSIVE,
+ PARTITION_DEV_BACKUP,
+};
+
+#ifdef HAVE_HOT_REPLACE_FUNC
+extern int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type, unsigned int partition_id);
+extern int get_partition_id(void);
+#else
+static int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type, unsigned int partition_id) { return 0; }
+static int get_partition_id(void) { return 0; }
+#endif
static bool disable_vf_load;
module_param(disable_vf_load, bool, 0444);
MODULE_PARM_DESC(disable_vf_load,
"Disable virtual functions probe or not - default is false");
+static bool g_is_pf_migrated;
static bool disable_attach;
module_param(disable_attach, bool, 0444);
MODULE_PARM_DESC(disable_attach, "disable_attach or not - default is false");
#define HINIC3_WAIT_SRIOV_CFG_TIMEOUT 15000
-MODULE_AUTHOR("Huawei Technologies CO., Ltd");
-MODULE_DESCRIPTION(HINIC3_DRV_DESC);
-MODULE_VERSION(HINIC3_DRV_VERSION);
-MODULE_LICENSE("GPL");
-
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
static DEVICE_ATTR(sriov_numvfs, 0664,
hinic3_sriov_numvfs_show, hinic3_sriov_numvfs_store);
@@ -71,7 +87,18 @@ static const struct attribute_group hinic3_attr_group = {
struct hinic3_uld_info g_uld_info[SERVICE_T_MAX] = { {0} };
#define HINIC3_EVENT_PROCESS_TIMEOUT 10000
+#define HINIC3_WAIT_EVENT_PROCESS_TIMEOUT 100
struct mutex g_uld_mutex;
+#define BUS_MAX_DEV_NUM 256
+#define HINIC3_SLAVE_WORK_MAX_NUM 20
+
+typedef struct vf_offset_info {
+ u8 valid;
+ u16 vf_offset_from_pf[CMD_MAX_MAX_PF_NUM];
+} VF_OFFSET_INFO_S;
+
+static VF_OFFSET_INFO_S g_vf_offset;
+DEFINE_MUTEX(g_vf_offset_lock);
void hinic3_uld_lock_init(void)
{
@@ -80,13 +107,23 @@ void hinic3_uld_lock_init(void)
static const char *s_uld_name[SERVICE_T_MAX] = {
"nic", "ovs", "roce", "toe", "ioe",
- "fc", "vbs", "ipsec", "virtio", "migrate", "ppa", "custom"};
+ "fc", "vbs", "ipsec", "virtio", "migrate",
+ "ppa", "custom", "vroce", "crypt", "vsock", "bifur"};
const char **hinic3_get_uld_names(void)
{
return s_uld_name;
}
+#ifdef CONFIG_PCI_IOV
+static int hinic3_get_pf_device_id(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_dev = pci_physfn(pdev);
+
+ return pf_dev->device;
+}
+#endif
+
static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
const struct hinic3_uld_info *uld_info)
{
@@ -105,6 +142,10 @@ static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
atomic_set(&dev->uld_ref_cnt[type], 0);
+ if (!uld_info->probe) {
+ err = 0;
+ goto out_unlock;
+ }
err = uld_info->probe(&dev->lld_dev, &uld_dev, dev->uld_dev_name[type]);
if (err) {
sdk_err(&dev->pcidev->dev,
@@ -173,6 +214,10 @@ static void detach_uld(struct hinic3_pcidev *dev,
wait_uld_unused(dev, type);
+ if (!uld_info->remove) {
+ mutex_unlock(&dev->pdev_mutex);
+ return;
+ }
uld_info->remove(&dev->lld_dev, dev->uld_dev[type]);
dev->uld_dev[type] = NULL;
@@ -190,10 +235,15 @@ static void attach_ulds(struct hinic3_pcidev *dev)
enum hinic3_service_type type;
struct pci_dev *pdev = dev->pcidev;
- lld_hold();
+ int is_in_kexec = vram_get_kexec_flag();
+ /* don't need hold when driver parallel load during spu hot replace */
+ if (is_in_kexec == 0) {
+ lld_hold();
+ }
+
mutex_lock(&g_uld_mutex);
- for (type = SERVICE_T_NIC; type < SERVICE_T_MAX; type++) {
+ for (type = SERVICE_T_OVS; type < SERVICE_T_MAX; type++) {
if (g_uld_info[type].probe) {
if (pdev->is_virtfn &&
(!hinic3_get_vf_service_load(pdev, (u16)type))) {
@@ -205,7 +255,10 @@ static void attach_ulds(struct hinic3_pcidev *dev)
}
}
mutex_unlock(&g_uld_mutex);
- lld_put();
+
+ if (is_in_kexec == 0) {
+ lld_put();
+ }
}
static void detach_ulds(struct hinic3_pcidev *dev)
@@ -255,10 +308,10 @@ int hinic3_register_uld(enum hinic3_service_type type,
}
chip_list = get_hinic3_chip_list();
- memcpy(&g_uld_info[type], uld_info, sizeof(*uld_info));
+ memcpy(&g_uld_info[type], uld_info, sizeof(struct hinic3_uld_info));
list_for_each_entry(chip_node, chip_list, node) {
list_for_each_entry(dev, &chip_node->func_list, node) {
- if (attach_uld(dev, type, uld_info)) {
+ if (attach_uld(dev, type, uld_info) != 0) {
sdk_err(&dev->pcidev->dev,
"Attach %s driver to pcie device failed\n",
s_uld_name[type]);
@@ -312,7 +365,7 @@ void hinic3_unregister_uld(enum hinic3_service_type type)
}
uld_info = &g_uld_info[type];
- memset(uld_info, 0, sizeof(*uld_info));
+ memset(uld_info, 0, sizeof(struct hinic3_uld_info));
mutex_unlock(&g_uld_mutex);
lld_put();
}
@@ -366,6 +419,26 @@ void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_ser
}
EXPORT_SYMBOL(hinic3_detach_service);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ __module_get(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_get);
+
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ module_put(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_put);
+
static void hinic3_sync_time_to_fmw(struct hinic3_pcidev *pdev_pri)
{
struct timeval tv = {0};
@@ -382,7 +455,8 @@ static void hinic3_sync_time_to_fmw(struct hinic3_pcidev *pdev_pri)
err);
} else {
rtc_time_to_tm((unsigned long)(tv.tv_sec), &rt_time);
- sdk_info(&pdev_pri->pcidev->dev, "Synchronize UTC time to firmware succeed. UTC time %d-%02d-%02d %02d:%02d:%02d.\n",
+ sdk_info(&pdev_pri->pcidev->dev,
+ "Synchronize UTC time to firmware succeed. UTC time %d-%02d-%02d %02d:%02d:%02d.\n",
rt_time.tm_year + HINIC3_SYNC_YEAR_OFFSET,
rt_time.tm_mon + HINIC3_SYNC_MONTH_OFFSET,
rt_time.tm_mday, rt_time.tm_hour,
@@ -448,23 +522,434 @@ static void send_event_to_all_pf(struct hinic3_pcidev *dev,
lld_put();
}
+u32 hinic3_pdev_is_virtfn(struct pci_dev *pdev)
+{
+#ifdef CONFIG_PCI_IOV
+ return pdev->is_virtfn;
+#else
+ return 0;
+#endif
+}
+
+static int hinic3_get_function_enable(struct pci_dev *pdev, bool *en)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+ int err;
+
+ /* PF in host os or function in guest os, probe sdk in default */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev) {
+ *en = true;
+ return 0;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev) {
+ /* vf in host and pf sdk not probed */
+ return -EFAULT;
+ }
+ pf_hwdev = pci_adapter->hwdev;
+
+ err = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (err) {
+ sdk_err(&pci_adapter->pcidev->dev, "Func hinic3_get_vfid_by_vfpci fail %d \n", err);
+ return err;
+ }
+
+ err = hinic3_get_func_nic_enable(pf_hwdev, global_func_id, en);
+ if (!!err) {
+ sdk_info(&pdev->dev, "Failed to get function nic status, err %d.\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+int hinic3_set_func_probe_in_host(void *hwdev, u16 func_id, bool probe)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (hinic3_func_type(hwdev) != TYPE_PPF)
+ return -EINVAL;
+
+ if (probe)
+ set_bit(func_id, dev->func_probe_in_host);
+ else
+ clear_bit(func_id, dev->func_probe_in_host);
+
+ return 0;
+}
+
+bool hinic3_get_func_probe_in_host(void *hwdev, u16 func_id)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+ bool probed = false;
+
+ if (!hwdev)
+ return false;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return false;
+ }
+
+ probed = !!test_bit(func_id, ppf_dev->func_probe_in_host);
+ up(&dev->ppf_sem);
+
+ return probed;
+}
+
+void *hinic3_get_ppf_hwdev_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ chip_node = pci_adapter->chip_node;
+ lld_dev_hold(&pci_adapter->lld_dev);
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (dev->lld_state == HINIC3_IN_REMOVE)
+ continue;
+
+ if (dev->hwdev && hinic3_func_type(dev->hwdev) == TYPE_PPF) {
+ lld_dev_put(&pci_adapter->lld_dev);
+ return dev->hwdev;
+ }
+ }
+ lld_dev_put(&pci_adapter->lld_dev);
+
+ return NULL;
+}
+
+static int hinic3_set_vf_nic_used_state(void *hwdev, u16 func_id, bool opened)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+
+ if (!dev || func_id >= MAX_FUNCTION_NUM)
+ return -EINVAL;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return -EINVAL;
+ }
+
+ if (opened)
+ set_bit(func_id, ppf_dev->netdev_setup_state);
+ else
+ clear_bit(func_id, ppf_dev->netdev_setup_state);
+
+ up(&dev->ppf_sem);
+
+ return 0;
+}
+
+static void set_vf_func_in_use(struct pci_dev *pdev, bool in_use)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+
+ /* only need to be set when VF is on the host */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev)
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev)
+ return;
+
+ pf_hwdev = pci_adapter->hwdev;
+
+ global_func_id = (u16)pdev->devfn + hinic3_glb_pf_vf_offset(pf_hwdev);
+ (void)hinic3_set_vf_nic_used_state(pf_hwdev, global_func_id, in_use);
+}
+
+static int hinic3_pf_get_vf_offset_info(struct hinic3_pcidev *des_dev, u16 *vf_offset)
+{
+ int err, i;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ u16 pf_func_id;
+ struct hinic3_pcidev *pf_pci_adapter = NULL;
+
+ pf_pci_adapter = (hinic3_pdev_is_virtfn(des_dev->pcidev)) ? pci_get_drvdata(des_dev->pcidev->physfn) : des_dev;
+ pf_func_id = hinic3_global_func_id(pf_pci_adapter->hwdev);
+ if (pf_func_id >= CMD_MAX_MAX_PF_NUM || !vf_offset)
+ return -EINVAL;
+
+ mutex_lock(&g_vf_offset_lock);
+ if (g_vf_offset.valid == 0) {
+ pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ sdk_err(&pf_pci_adapter->pcidev->dev, "Malloc pf_infos fail\n");
+ err = -ENOMEM;
+ goto err_malloc;
+ }
+
+ err = hinic3_get_hw_pf_infos(pf_pci_adapter->hwdev, pf_infos, HINIC3_CHANNEL_COMM);
+ if (err) {
+ sdk_warn(&pf_pci_adapter->pcidev->dev, "Hinic3_get_hw_pf_infos fail err %d\n", err);
+ err = -EFAULT;
+ goto err_out;
+ }
+
+ g_vf_offset.valid = 1;
+ for (i = 0; i < CMD_MAX_MAX_PF_NUM; i++) {
+ g_vf_offset.vf_offset_from_pf[i] = pf_infos->infos[i].vf_offset;
+ }
+
+ kfree(pf_infos);
+ }
+
+ *vf_offset = g_vf_offset.vf_offset_from_pf[pf_func_id];
+
+ mutex_unlock(&g_vf_offset_lock);
+
+ return 0;
+
+err_out:
+ kfree(pf_infos);
+err_malloc:
+ mutex_unlock(&g_vf_offset_lock);
+ return err;
+}
+
+static struct pci_dev *get_vf_pdev_by_pf(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ int err;
+ u16 bus_num;
+ u16 vf_start, vf_end;
+ u16 des_fn, pf_func_id, vf_offset;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ pf_func_id = hinic3_global_func_id(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end || pf_func_id >= CMD_MAX_MAX_PF_NUM)
+ return NULL;
+
+ err = hinic3_pf_get_vf_offset_info(des_dev, &vf_offset);
+ if (err) {
+ sdk_warn(&des_dev->pcidev->dev, "Hinic3_pf_get_vf_offset_info fail\n");
+ return NULL;
+ }
+
+ des_fn = ((func_id - vf_start) - 1) + pf_func_id + vf_offset;
+ bus_num = des_dev->pcidev->bus->number + des_fn / BUS_MAX_DEV_NUM;
+
+ return pci_get_domain_bus_and_slot(0, bus_num, (des_fn % BUS_MAX_DEV_NUM));
+}
+
+static struct hinic3_pcidev *get_des_pci_adapter(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ struct pci_dev *des_pdev = NULL;
+ u16 vf_start, vf_end;
+ bool probe_in_host = false;
+
+ if (hinic3_global_func_id(des_dev->hwdev) == func_id)
+ return des_dev;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end)
+ return NULL;
+
+ des_pdev = get_vf_pdev_by_pf(des_dev, func_id);
+ if (!des_pdev)
+ return NULL;
+
+ pci_dev_put(des_pdev);
+
+ probe_in_host = hinic3_get_func_probe_in_host(des_dev->hwdev, func_id);
+ if (!probe_in_host)
+ return NULL;
+
+ return pci_get_drvdata(des_pdev);
+}
+
+int __set_vroce_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ u8 enable_vroce = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_vroce_enable(pci_adapter->hwdev, func_id, &enable_vroce);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Failed to get vroce state.\n");
+ return err;
+ }
+
+ mutex_lock(&g_uld_mutex);
+
+ if (!!enable_vroce) {
+ if (!g_uld_info[SERVICE_T_ROCE].probe) {
+ sdk_info(&pdev->dev, "Uld(roce_info) has not been registered!\n");
+ mutex_unlock(&g_uld_mutex);
+ return 0;
+ }
+
+ err = attach_uld(pci_adapter, SERVICE_T_ROCE, &g_uld_info[SERVICE_T_ROCE]);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Failed to initialize VROCE.\n");
+ mutex_unlock(&g_uld_mutex);
+ return err;
+ }
+ } else {
+ sdk_info(&pdev->dev, "Func %hu vroce state: disable.\n", func_id);
+ if (g_uld_info[SERVICE_T_ROCE].remove)
+ detach_uld(pci_adapter, SERVICE_T_ROCE);
+ }
+
+ mutex_unlock(&g_uld_mutex);
+
+ return 0;
+}
+
+void slave_host_mgmt_vroce_work(struct work_struct *work)
+{
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_vroce_work);
+
+ __set_vroce_func_state(pci_adapter);
+}
+
+void *hinic3_get_roce_uld_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ return pci_adapter->uld_dev[SERVICE_T_ROCE];
+}
+
+static int __func_service_state_process(struct hinic3_pcidev *event_dev,
+ struct hinic3_pcidev *des_dev,
+ struct hinic3_mhost_nic_func_state *state, u16 cmd)
+{
+ int err = 0;
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)event_dev->hwdev;
+
+ switch (cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ state->enable = hinic3_get_roce_uld_by_pdev(des_dev->pcidev) ? 1 : 0;
+ break;
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive nic[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ if (event_dev->multi_host_mgmt_workq) {
+ queue_work(event_dev->multi_host_mgmt_workq, &des_dev->slave_nic_work);
+ } else {
+ sdk_err(&des_dev->pcidev->dev, "Can not schedule slave nic work\n");
+ err = -EFAULT;
+ }
+ break;
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive vroce[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ queue_work_on(hisdk3_get_work_cpu_affinity(dev, WORK_TYPE_MBOX),
+ event_dev->multi_host_mgmt_workq,
+ &des_dev->slave_vroce_work);
+ break;
+ default:
+ sdk_warn(&des_dev->pcidev->dev, "Service state process with unknown cmd: %u\n", cmd);
+ err = -EFAULT;
+ break;
+ }
+
+ return err;
+}
+
+static void __multi_host_mgmt(struct hinic3_pcidev *dev,
+ struct hinic3_multi_host_mgmt_event *mhost_mgmt)
+{
+ struct hinic3_pcidev *cur_dev = NULL;
+ struct hinic3_pcidev *des_dev = NULL;
+ struct hinic3_mhost_nic_func_state *nic_state = NULL;
+ u16 sub_cmd = mhost_mgmt->sub_cmd;
+
+ switch (sub_cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ nic_state = mhost_mgmt->data;
+ nic_state->status = 0;
+ if (!dev->hwdev)
+ return;
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)dev->hwdev))
+ return;
+
+ /* find func_idx pci_adapter and disable or enable nic */
+ lld_dev_hold(&dev->lld_dev);
+ list_for_each_entry(cur_dev, &dev->chip_node->func_list, node) {
+ if (cur_dev->lld_state == HINIC3_IN_REMOVE || hinic3_pdev_is_virtfn(cur_dev->pcidev))
+ continue;
+
+ des_dev = get_des_pci_adapter(cur_dev, nic_state->func_idx);
+ if (!des_dev)
+ continue;
+
+ if (__func_service_state_process(dev, des_dev, nic_state, sub_cmd))
+ nic_state->status = 1;
+ break;
+ }
+ lld_dev_put(&dev->lld_dev);
+ break;
+ default:
+ sdk_warn(&dev->pcidev->dev, "Received unknown multi-host mgmt event: %u\n",
+ mhost_mgmt->sub_cmd);
+ break;
+ }
+}
+
static void hinic3_event_process(void *adapter, struct hinic3_event_info *event)
{
struct hinic3_pcidev *dev = adapter;
struct hinic3_fault_event *fault = (void *)event->event_data;
+ struct hinic3_multi_host_mgmt_event *mhost_event = (void *)event->event_data;
u16 func_id;
- if ((event->service == EVENT_SRV_COMM && event->type == EVENT_COMM_FAULT) &&
- fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
- fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
- func_id = fault->event.chip.func_id;
- return send_event_to_dst_pf(adapter, func_id, event);
- }
-
- if (event->type == EVENT_COMM_MGMT_WATCHDOG)
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MULTI_HOST_MGMT):
+ __multi_host_mgmt(dev, mhost_event);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_FAULT):
+ if (fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
+ fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
+ func_id = fault->event.chip.func_id;
+ return send_event_to_dst_pf(adapter, func_id, event);
+ }
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MGMT_WATCHDOG):
send_event_to_all_pf(adapter, event);
- else
+ break;
+ default:
send_uld_dev_event(adapter, event);
+ break;
+ }
}
static void uld_def_init(struct hinic3_pcidev *pci_adapter)
@@ -631,36 +1116,75 @@ static void hinic3_pci_deinit(struct pci_dev *pdev)
kfree(pci_adapter);
}
-#ifdef CONFIG_X86
-/**
- * cfg_order_reg - when cpu model is haswell or broadwell, should configure dma
- * order register to zero
- * @pci_adapter: pci_adapter
- **/
-/*lint -save -e40 */
-static void cfg_order_reg(struct hinic3_pcidev *pci_adapter)
+static void set_vf_load_state(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
{
- u8 cpu_model[] = {0x3c, 0x3f, 0x45, 0x46, 0x3d, 0x47, 0x4f, 0x56};
- struct cpuinfo_x86 *cpuinfo = NULL;
- u32 i;
-
- if (hinic3_func_type(pci_adapter->hwdev) == TYPE_VF)
- return;
+ /* In bm mode, slave host will load vfs in default */
+ if (IS_BMGW_SLAVE_HOST(((struct hinic3_hwdev *)pci_adapter->hwdev)) &&
+ hinic3_func_type(pci_adapter->hwdev) != TYPE_VF)
+ hinic3_set_vf_load_state(pdev, false);
- cpuinfo = &cpu_data(0);
- for (i = 0; i < sizeof(cpu_model); i++) {
- if (cpu_model[i] == cpuinfo->x86_model)
- hinic3_set_pcie_order_cfg(pci_adapter->hwdev);
+ if (!disable_attach) {
+ if ((hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) &&
+ hinic3_is_bm_slave_host(pci_adapter->hwdev)) {
+ if (hinic3_func_max_vf(pci_adapter->hwdev) == 0) {
+ sdk_warn(&pdev->dev, "The sriov enabling process is skipped, vfs_num: 0.\n");
+ return;
+ }
+ hinic3_pci_sriov_enable(pdev, hinic3_func_max_vf(pci_adapter->hwdev));
+ }
}
}
-/*lint -restore*/
-#endif
-
-static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+static void hinic3_init_ppf_hwdev(struct hinic3_hwdev *hwdev)
{
- struct hinic3_init_para init_para = {0};
- bool cqm_init_en = false;
+ if (!hwdev) {
+ pr_err("[%s:%d] null hwdev pointer\n", __FILE__, __LINE__);
+ return;
+ }
+
+ hwdev->ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(hwdev->pcidev_hdl);
+ return;
+}
+
+static int set_nic_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ bool enable_nic = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_nic_enable(pci_adapter->hwdev, func_id, &enable_nic);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Failed to get nic state.\n");
+ return err;
+ }
+
+ if (!enable_nic) {
+ sdk_info(&pdev->dev, "Func %hu nic state: disable.\n", func_id);
+ detach_uld(pci_adapter, SERVICE_T_NIC);
+ return 0;
+ }
+
+ if (IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ (void)hinic3_init_vf_dev_cap(pci_adapter->hwdev);
+
+ if (g_uld_info[SERVICE_T_NIC].probe) {
+ err = attach_uld(pci_adapter, SERVICE_T_NIC, &g_uld_info[SERVICE_T_NIC]);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Initialize NIC failed\n");
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_init_para init_para = {0};
+ bool cqm_init_en = false;
int err;
init_para.adapter_hdl = pci_adapter;
@@ -715,7 +1239,16 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
list_add_tail(&pci_adapter->node, &pci_adapter->chip_node->func_list);
lld_unlock_chip_node();
+ hinic3_init_ppf_hwdev((struct hinic3_hwdev *)pci_adapter->hwdev);
+
+ set_vf_load_state(pdev, pci_adapter);
+
if (!disable_attach) {
+ /* NIC is base driver, probe firstly */
+ err = set_nic_func_state(pci_adapter);
+ if (err)
+ goto set_nic_func_state_err;
+
attach_ulds(pci_adapter);
if (hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) {
@@ -726,10 +1259,6 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
goto create_sysfs_err;
}
}
-
-#ifdef CONFIG_X86
- cfg_order_reg(pci_adapter);
-#endif
}
return 0;
@@ -737,6 +1266,7 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
create_sysfs_err:
detach_ulds(pci_adapter);
+set_nic_func_state_err:
lld_lock_chip_node();
list_del(&pci_adapter->node);
lld_unlock_chip_node();
@@ -785,6 +1315,7 @@ static void hinic3_func_deinit(struct pci_dev *pdev)
hinic3_free_stateful(pci_adapter->hwdev);
hinic3_free_hwdev(pci_adapter->hwdev);
+ pci_adapter->hwdev = NULL;
}
static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
@@ -806,6 +1337,49 @@ static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
} while (time_before(jiffies, end));
}
+static bool hinic3_get_vf_nic_en_status(struct pci_dev *pdev)
+{
+ bool nic_en = false;
+ u16 global_func_id;
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev) {
+ pr_err("pdev is null.\n");
+ return false;
+ }
+
+ if (pdev->is_virtfn)
+ pf_pdev = pdev->physfn;
+ else
+ return false;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return false;
+ }
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ return false;
+
+ if (hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id)) {
+ sdk_err(&pdev->dev, "Get vf id by vfpci failed\n");
+ return false;
+ }
+
+ if (hinic3_get_mhost_func_nic_enable(pci_adapter->hwdev,
+ global_func_id, &nic_en)) {
+ sdk_err(&pdev->dev, "Get function nic status failed\n");
+ return false;
+ }
+
+ sdk_info(&pdev->dev, "Func %hu %s default probe in host\n",
+ global_func_id, (nic_en) ? "enable" : "disable");
+
+ return nic_en;
+}
+
bool hinic3_get_vf_load_state(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = NULL;
@@ -860,6 +1434,8 @@ int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state)
}
EXPORT_SYMBOL(hinic3_set_vf_load_state);
+
+
bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service)
{
struct hinic3_pcidev *pci_adapter = NULL;
@@ -923,6 +1499,33 @@ int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
}
EXPORT_SYMBOL(hinic3_set_vf_service_load);
+static bool hinic3_is_host_vmsec_enable(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct pci_dev *pf_pdev = NULL;
+
+ if (pdev->is_virtfn) {
+ pf_pdev = pdev->physfn;
+ } else {
+ pf_pdev = pdev;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ pr_err("Pci_adapter is null.\n");
+ return false;
+ }
+
+ /* pf/vf used in host */
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ (hinic3_func_type(pci_adapter->hwdev) == TYPE_PF) &&
+ IS_RDMA_TYPE((struct hinic3_hwdev *)pci_adapter->hwdev)) {
+ return true;
+ }
+
+ return false;
+}
+
static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
@@ -936,6 +1539,13 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
pci_adapter->lld_state = HINIC3_IN_REMOVE;
mutex_unlock(&pci_adapter->pdev_mutex);
+ if (!(pdev->is_virtfn) && (hinic3_is_host_vmsec_enable(pdev) == true) &&
+ (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF)) {
+ cancel_delayed_work_sync(&pci_adapter->migration_probe_dwork);
+ flush_workqueue(pci_adapter->migration_probe_workq);
+ destroy_workqueue(pci_adapter->migration_probe_workq);
+ }
+
hinic3_detect_hw_present(pci_adapter->hwdev);
hisdk3_remove_pre_process(pci_adapter->hwdev);
@@ -960,23 +1570,129 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
sdk_info(&pdev->dev, "Pcie device removed function\n");
+ set_vf_func_in_use(pdev, false);
+
+ return 0;
+}
+
+int hinic3_get_vfid_by_vfpci(void *hwdev, struct pci_dev *pdev, u16 *global_func_id)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ u16 pf_bus, vf_bus, vf_offset;
+ int err;
+
+ if (!pdev || !global_func_id || !hinic3_pdev_is_virtfn(pdev))
+ return -EINVAL;
+ (void)hwdev;
+ pf_pdev = pdev->physfn;
+
+ vf_bus = pdev->bus->number;
+ pf_bus = pf_pdev->bus->number;
+
+ if (pdev->vendor == HINIC3_VIRTIO_VNEDER_ID) {
+ return -EPERM;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return -EINVAL;
+ }
+
+ err = hinic3_pf_get_vf_offset_info(pci_adapter, &vf_offset);
+ if (err) {
+ sdk_err(&pdev->dev, "Func hinic3_pf_get_vf_offset_info fail\n");
+ return -EFAULT;
+ }
+
+ *global_func_id = (u16)((vf_bus - pf_bus) * BUS_MAX_DEV_NUM) + (u16)pdev->devfn +
+ (u16)(CMD_MAX_MAX_PF_NUM - g_vf_offset.vf_offset_from_pf[0]);
+
return 0;
}
+EXPORT_SYMBOL(hinic3_get_vfid_by_vfpci);
+
+static void hinic3_set_vf_status_in_host(struct pci_dev *pdev, bool status)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ void *ppf_hwdev = NULL;
+ u16 global_func_id;
+ int ret;
+
+ if (!pf_pdev)
+ return;
+
+ if (!hinic3_pdev_is_virtfn(pdev))
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ pf_hwdev = pci_adapter->hwdev;
+ ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(pf_pdev);
+ if (!pf_hwdev || !ppf_hwdev)
+ return;
+
+ ret = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (ret) {
+ sdk_err(&pci_adapter->pcidev->dev, "Func hinic3_get_vfid_by_vfpci fail %d \n", ret);
+ return;
+ }
+
+ ret = hinic3_set_func_probe_in_host(ppf_hwdev, global_func_id, status);
+ if (ret)
+ sdk_err(&pci_adapter->pcidev->dev, "Set the function probe status in host failed\n");
+}
+#ifdef CONFIG_PCI_IOV
+static bool check_pdev_type_and_state(struct pci_dev *pdev)
+{
+ if (!(pdev->is_virtfn)) {
+ return false;
+ }
+
+ if ((hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_1_PF) &&
+ (hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_0_PF)) {
+ return false;
+ }
+
+ if (!hinic3_get_vf_load_state(pdev)) {
+ return false;
+ }
+
+ return true;
+}
+#endif
static void hinic3_remove(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
+ sdk_info(&pdev->dev, "Pcie device remove begin\n");
+
if (!pci_adapter)
- return;
+ goto out;
+#ifdef CONFIG_PCI_IOV
+ if (check_pdev_type_and_state(pdev)) {
+ goto out;
+ }
+#endif
- sdk_info(&pdev->dev, "Pcie device remove begin\n");
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
hinic3_remove_func(pci_adapter);
+ if (!pci_adapter->pcidev->is_virtfn &&
+ pci_adapter->multi_host_mgmt_workq)
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
+
hinic3_pci_deinit(pdev);
hinic3_probe_pre_unprocess(pdev);
+out:
+ hinic3_set_vf_status_in_host(pdev, false);
+
sdk_info(&pdev->dev, "Pcie device removed\n");
}
@@ -995,7 +1711,7 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
if (pci_adapter->lld_state >= HINIC3_PROBE_START) {
sdk_warn(&pdev->dev, "Don not probe repeat\n");
mutex_unlock(&pci_adapter->pdev_mutex);
- return 0;
+ return -EEXIST;
}
pci_adapter->lld_state = HINIC3_PROBE_START;
mutex_unlock(&pci_adapter->pdev_mutex);
@@ -1003,15 +1719,28 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
return 0;
}
+static void hinic3_probe_success_process(struct hinic3_pcidev *pci_adapter)
+{
+ hinic3_probe_success(pci_adapter->hwdev);
+
+ mutex_lock(&pci_adapter->pdev_mutex);
+ pci_adapter->lld_state = HINIC3_PROBE_OK;
+ mutex_unlock(&pci_adapter->pdev_mutex);
+}
+
static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
int err;
err = probe_func_param_init(pci_adapter);
- if (err)
+ if (err == -EEXIST)
+ return 0;
+ else if (err)
return err;
+ set_vf_func_in_use(pdev, true);
+
err = mapping_bar(pdev, pci_adapter);
if (err) {
sdk_err(&pdev->dev, "Failed to map bar\n");
@@ -1043,11 +1772,7 @@ static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
}
}
- hinic3_probe_success(pci_adapter->hwdev);
-
- mutex_lock(&pci_adapter->pdev_mutex);
- pci_adapter->lld_state = HINIC3_PROBE_OK;
- mutex_unlock(&pci_adapter->pdev_mutex);
+ hinic3_probe_success_process(pci_adapter);
return 0;
@@ -1063,18 +1788,299 @@ alloc_chip_node_fail:
unmapping_bar(pci_adapter);
map_bar_failed:
+ set_vf_func_in_use(pdev, false);
sdk_err(&pdev->dev, "Pcie device probe function failed\n");
return err;
}
+void hinic3_set_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int err;
+ bool enable_func = false;
+
+ err = hinic3_get_function_enable(pdev, &enable_func);
+ if (err) {
+ sdk_info(&pdev->dev, "Get function enable failed\n");
+ return;
+ }
+
+ sdk_info(&pdev->dev, "%s function resource start\n",
+ enable_func ? "Initialize" : "Free");
+ if (enable_func) {
+ err = hinic3_probe_func(pci_adapter);
+ if (err)
+ sdk_info(&pdev->dev, "Function probe failed\n");
+ } else {
+ hinic3_remove_func(pci_adapter);
+ }
+ if (err == 0)
+ sdk_info(&pdev->dev, "%s function resource end\n",
+ enable_func ? "Initialize" : "Free");
+}
+
+void slave_host_mgmt_work(struct work_struct *work)
+{
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_nic_work);
+
+ if (hinic3_pdev_is_virtfn(pci_adapter->pcidev))
+ hinic3_set_func_state(pci_adapter);
+ else
+ set_nic_func_state(pci_adapter);
+}
+
+static int pci_adapter_assign_val(struct hinic3_pcidev **ppci_adapter,
+ struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ *ppci_adapter = pci_get_drvdata(pdev);
+ (*ppci_adapter)->disable_vf_load = disable_vf_load;
+ (*ppci_adapter)->id = *id;
+ (*ppci_adapter)->lld_state = HINIC3_NOT_PROBE;
+ (*ppci_adapter)->probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ lld_dev_cnt_init(*ppci_adapter);
+
+ (*ppci_adapter)->multi_host_mgmt_workq =
+ alloc_workqueue("hinic_mhost_mgmt", WQ_UNBOUND,
+ HINIC3_SLAVE_WORK_MAX_NUM);
+ if (!(*ppci_adapter)->multi_host_mgmt_workq) {
+ hinic3_pci_deinit(pdev);
+ sdk_err(&pdev->dev, "Alloc multi host mgmt workqueue failed\n");
+ return -ENOMEM;
+ }
+
+ INIT_WORK(&(*ppci_adapter)->slave_nic_work, slave_host_mgmt_work);
+ INIT_WORK(&(*ppci_adapter)->slave_vroce_work,
+ slave_host_mgmt_vroce_work);
+
+ return 0;
+}
+
+static void slave_host_vfio_probe_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_pcidev *pci_adapter = container_of(delay, struct hinic3_pcidev, migration_probe_dwork);
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int (*dev_migration_probe)(struct pci_dev *);
+ int rc;
+
+ if (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) != TYPE_PF) {
+ return;
+ }
+
+ dev_migration_probe = __symbol_get("migration_dev_migration_probe");
+ if (!(dev_migration_probe)) {
+ sdk_err(&pdev->dev,
+ "Failed to find: migration_dev_migration_probe");
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork, WAIT_TIME * HZ);
+ } else {
+ rc = dev_migration_probe(pdev);
+ __symbol_put("migration_dev_migration_probe");
+ if (rc) {
+ sdk_err(&pdev->dev,
+ "Failed to __dev_migration_probe, rc:0x%x, pf migrated(%d).\n",
+ rc, g_is_pf_migrated);
+ } else {
+ g_is_pf_migrated = true;
+ sdk_info(&pdev->dev,
+ "Successed in __dev_migration_probe, pf migrated(%d).\n",
+ g_is_pf_migrated);
+ }
+ }
+
+ return;
+}
+
+struct vf_add_delaywork {
+ struct pci_dev *vf_pdev;
+ struct delayed_work migration_vf_add_dwork;
+};
+
+static void slave_host_migration_vf_add_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct vf_add_delaywork *vf_add = container_of(delay, struct vf_add_delaywork, migration_vf_add_dwork);
+ struct pci_dev *vf_pdev = vf_add->vf_pdev;
+ struct pci_dev *pf_pdev = NULL;
+ int (*migration_dev_add_vf)(struct pci_dev *);
+ int ret;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!vf_pdev) {
+ pr_err("vf pdev is null.\n");
+ goto err1;
+ }
+ if (!vf_pdev->is_virtfn) {
+ sdk_err(&vf_pdev->dev, "Pdev is not virtfn.\n");
+ goto err1;
+ }
+
+ pf_pdev = vf_pdev->physfn;
+ if (!pf_pdev) {
+ sdk_err(&vf_pdev->dev, "pf_pdev is null.\n");
+ goto err1;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&vf_pdev->dev, "Pci_adapter is null.\n");
+ goto err1;
+ }
+
+ if (!g_is_pf_migrated) {
+ sdk_info(&vf_pdev->dev, "pf is not migrated yet, so vf continues to try again.\n");
+ goto delay_work;
+ }
+
+ migration_dev_add_vf = __symbol_get("migration_dev_add_vf");
+ if (migration_dev_add_vf) {
+ ret = migration_dev_add_vf(vf_pdev);
+ __symbol_put("migration_dev_add_vf");
+ if (ret) {
+ sdk_err(&vf_pdev->dev,
+ "vf get migration symbol successed, but dev add vf failed, ret:%d.\n",
+ ret);
+ } else {
+ sdk_info(&vf_pdev->dev,
+ "vf get migration symbol successed, and dev add vf success.\n");
+ }
+ goto err1;
+ }
+ sdk_info(&vf_pdev->dev, "pf is migrated, but vf get migration symbol failed.\n");
+
+delay_work:
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork, WAIT_TIME * HZ);
+ return;
+
+err1:
+ kfree(vf_add);
+ return;
+}
+
+static void hinic3_probe_vf_add_dwork(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!hinic3_is_host_vmsec_enable(pdev)) {
+ return;
+ }
+
+#if defined(CONFIG_SP_VID_DID)
+ if ((pdev->vendor == PCI_VENDOR_ID_SPNIC) && (pdev->device == HINIC3_DEV_SDI_5_1_ID_VF)) {
+#elif defined(CONFIG_NF_VID_DID)
+ if ((pdev->vendor == PCI_VENDOR_ID_NF) && (pdev->device == NFNIC_DEV_ID_VF)) {
+#else
+ if ((pdev->vendor == PCI_VENDOR_ID_HUAWEI) && (pdev->device == HINIC3_DEV_SDI_5_0_ID_VF)) {
+#endif
+ struct vf_add_delaywork *vf_add = kmalloc(sizeof(struct vf_add_delaywork), GFP_ATOMIC);
+ if (!vf_add) {
+ sdk_info(&pdev->dev, "vf_add is null.\n");
+ return;
+ }
+ vf_add->vf_pdev = pdev;
+
+ pf_pdev = pdev->physfn;
+
+ if (!pf_pdev) {
+ sdk_info(&pdev->dev, "Vf-pf_pdev is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_info(&pdev->dev, "Pci_adapter is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ INIT_DELAYED_WORK(&vf_add->migration_vf_add_dwork,
+ slave_host_migration_vf_add_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork,
+ WAIT_TIME * HZ);
+ }
+
+ return;
+}
+
+static int hinic3_probe_migration_dwork(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+{
+ if (!hinic3_is_host_vmsec_enable(pdev)) {
+ sdk_info(&pdev->dev, "Probe_migration : hinic3_is_host_vmsec_enable is (0).\n");
+ return 0;
+ }
+
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF) {
+ pci_adapter->migration_probe_workq =
+ create_singlethread_workqueue("hinic3_migration_probe_delay");
+ if (!pci_adapter->migration_probe_workq) {
+ sdk_err(&pdev->dev, "Failed to create work queue:%s\n",
+ "hinic3_migration_probe_delay");
+ return -EINVAL;
+ }
+
+ INIT_DELAYED_WORK(&pci_adapter->migration_probe_dwork,
+ slave_host_vfio_probe_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork, WAIT_TIME * HZ);
+ }
+
+ return 0;
+}
+
+static bool hinic3_os_hot_replace_allow(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_hwdev *hwdev = (struct hinic3_hwdev *)pci_adapter->hwdev;
+ // check service enable and dev is not VF
+ if (hinic3_func_type(hwdev) == TYPE_VF || hwdev->hot_replace_mode == HOT_REPLACE_DISABLE)
+ return false;
+
+ return true;
+}
+
+static bool hinic3_os_hot_replace_process(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_board_info *board_info;
+ u16 cur_pf_id = hinic3_global_func_id(pci_adapter->hwdev);
+ u8 cur_partion_id;
+ board_info = &((struct hinic3_hwdev *)(pci_adapter->hwdev))->board_info;
+ // probe to os
+ vpci_set_partition_attrs(pci_adapter->pcidev, PARTITION_DEV_EXCLUSIVE,
+ get_function_partition(cur_pf_id, board_info->port_num));
+
+ // check pf_id is in the right partition_id
+ cur_partion_id = get_partition_id();
+ if (get_function_partition(cur_pf_id, board_info->port_num) == cur_partion_id) {
+ return true;
+ }
+
+ pci_adapter->probe_fault_level = FAULT_LEVEL_SUGGESTION;
+ return false;
+}
+
static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct hinic3_pcidev *pci_adapter = NULL;
u16 probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ u32 device_id, function_id;
int err;
sdk_info(&pdev->dev, "Pcie device probe begin\n");
-
+#ifdef CONFIG_PCI_IOV
+ hinic3_set_vf_status_in_host(pdev, true);
+ if (check_pdev_type_and_state(pdev)) {
+ sdk_info(&pdev->dev, "VFs are not binded to hinic\n");
+ hinic3_probe_vf_add_dwork(pdev);
+ return -EINVAL;
+ }
+#endif
err = hinic3_probe_pre_process(pdev);
if (err != 0 && err != HINIC3_NOT_PROBE)
goto out;
@@ -1082,33 +2088,53 @@ static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (err == HINIC3_NOT_PROBE)
return 0;
- err = hinic3_pci_init(pdev);
- if (err)
+ if (hinic3_pci_init(pdev))
goto pci_init_err;
- pci_adapter = pci_get_drvdata(pdev);
- pci_adapter->disable_vf_load = disable_vf_load;
- pci_adapter->id = *id;
- pci_adapter->lld_state = HINIC3_NOT_PROBE;
- pci_adapter->probe_fault_level = probe_fault_level;
- lld_dev_cnt_init(pci_adapter);
+ if (pci_adapter_assign_val(&pci_adapter, pdev, id))
+ goto allco_queue_err;
- if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev))) {
+ if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev)) &&
+ (!hinic3_get_vf_nic_en_status(pdev))) {
sdk_info(&pdev->dev, "VF device disable load in host\n");
return 0;
}
- err = hinic3_probe_func(pci_adapter);
- if (err)
+ if (hinic3_probe_func(pci_adapter))
+ goto hinic3_probe_func_fail;
+
+ if (hinic3_os_hot_replace_allow(pci_adapter)) {
+ if (!hinic3_os_hot_replace_process(pci_adapter)) {
+ device_id = PCI_SLOT(pdev->devfn);
+ function_id = PCI_FUNC(pdev->devfn);
+ sdk_info(&pdev->dev,
+ "os hot replace: skip function %d:%d for partition %d",
+ device_id, function_id, get_partition_id());
+ goto os_hot_repalce_not_allow;
+ }
+ }
+
+ if (hinic3_probe_migration_dwork(pdev, pci_adapter))
goto hinic3_probe_func_fail;
sdk_info(&pdev->dev, "Pcie device probed\n");
return 0;
+os_hot_repalce_not_allow:
+ hinic3_func_deinit(pdev);
+ lld_lock_chip_node();
+ free_chip_node(pci_adapter);
+ lld_unlock_chip_node();
+ unmapping_bar(pci_adapter);
+ set_vf_func_in_use(pdev, false);
+
hinic3_probe_func_fail:
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
+allco_queue_err:
probe_fault_level = pci_adapter->probe_fault_level;
hinic3_pci_deinit(pdev);
-
pci_init_err:
hinic3_probe_pre_unprocess(pdev);
@@ -1131,6 +2157,10 @@ static int hinic3_get_pf_info(struct pci_dev *pdev, u16 service,
}
*pf_infos = kzalloc(sizeof(struct hinic3_hw_pf_infos), GFP_KERNEL);
+ if (*pf_infos == NULL) {
+ sdk_err(&pdev->dev, "pf_infos kzalloc failed\n");
+ return -EFAULT;
+ }
err = hinic3_get_hw_pf_infos(dev->hwdev, *pf_infos, HINIC3_CHANNEL_COMM);
if (err) {
kfree(*pf_infos);
@@ -1146,6 +2176,7 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
{
int err;
+ mutex_lock(&dst_dev->pdev_mutex);
/* unload invalid vf func id */
if (!en && vf_func_id != hinic3_global_func_id(dst_dev->hwdev) &&
!strcmp(des_pdev->driver->name, HINIC3_DRV_NAME)) {
@@ -1163,6 +2194,8 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
err = hinic3_probe_func(dst_dev);
if (err)
return -EFAULT;
+ } else {
+ mutex_unlock(&dst_dev->pdev_mutex);
}
return 0;
@@ -1187,7 +2220,6 @@ static int get_vf_service_state_param(struct pci_dev *pdev, struct hinic3_pcidev
return 0;
}
-#define BUS_MAX_DEV_NUM 256
static int hinic3_dst_pdev_valid(struct hinic3_pcidev *dst_dev, struct pci_dev **des_pdev_ptr,
u16 vf_devfn, bool en)
{
@@ -1245,7 +2277,7 @@ int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id, u16 servic
lld_hold();
list_for_each_entry(dst_dev, &dev->chip_node->func_list, node) {
- if (paramerter_is_unexpected(dst_dev, &func_id, &vf_start, &vf_end, vf_func_id))
+ if (paramerter_is_unexpected(dst_dev, &func_id, &vf_start, &vf_end, vf_func_id) != 0)
continue;
vf_devfn = pf_infos->infos[func_id].vf_offset + (vf_func_id - vf_start) +
@@ -1269,7 +2301,6 @@ int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id, u16 servic
if (en)
pci_dev_put(des_pdev);
- mutex_lock(&dst_dev->pdev_mutex);
find_dst_dev = true;
break;
}
@@ -1289,19 +2320,18 @@ free_pf_info:
}
EXPORT_SYMBOL(hinic3_set_vf_service_state);
-/*lint -save -e133 -e10*/
static const struct pci_device_id hinic3_pci_table[] = {
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SPU), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_STANDARD), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_1_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_SDI_5_1_ID_VF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_VF), 0},
{0, 0}
};
-/*lint -restore*/
-
MODULE_DEVICE_TABLE(pci, hinic3_pci_table);
/**
@@ -1333,14 +2363,27 @@ static pci_ers_result_t hinic3_io_error_detected(struct pci_dev *pdev,
return PCI_ERS_RESULT_CAN_RECOVER;
}
+static void hinic3_timer_disable(void *hwdev)
+{
+ if (!hwdev)
+ return;
+
+ if (hinic3_get_stateful_enable(hwdev) && hinic3_get_timer_enable(hwdev))
+ (void)hinic3_func_tmr_bitmap_set(hwdev, hinic3_global_func_id(hwdev), false);
+
+ return;
+}
+
static void hinic3_shutdown(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
sdk_info(&pdev->dev, "Shutdown device\n");
- if (pci_adapter)
+ if (pci_adapter) {
+ hinic3_timer_disable(pci_adapter->hwdev);
hinic3_shutdown_hwdev(pci_adapter->hwdev);
+ }
pci_disable_device(pdev);
@@ -1367,6 +2410,9 @@ static struct pci_driver hinic3_driver = {
.probe = hinic3_probe,
.remove = hinic3_remove,
.shutdown = hinic3_shutdown,
+#ifdef CONFIG_PARTITION_DEVICE
+ .driver.probe_concurrency = true,
+#endif
#if defined(HAVE_SRIOV_CONFIGURE)
.sriov_configure = hinic3_pci_sriov_configure,
#elif defined(HAVE_RHEL6_SRIOV_CONFIGURE)
@@ -1388,16 +2434,21 @@ int hinic3_lld_init(void)
err = hinic3_module_pre_init();
if (err) {
pr_err("Init custom failed\n");
- return err;
+ goto module_pre_init_err;
}
err = pci_register_driver(&hinic3_driver);
if (err) {
- hinic3_module_post_exit();
- return err;
+ pr_err("sdk3 pci register driver failed\n");
+ goto register_pci_driver_err;
}
return 0;
+
+register_pci_driver_err:
+ hinic3_module_post_exit();
+module_pre_init_err:
+ return err;
}
void hinic3_lld_exit(void)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
index d2a7dd7..5398a34 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
@@ -584,6 +584,7 @@ static void free_recv_mbox(struct hinic3_recv_mbox *recv_msg)
kfree(recv_msg->resp_buff);
kfree(recv_msg->msg);
kfree(recv_msg);
+ recv_msg = NULL;
}
static void recv_func_mbox_work_handler(struct work_struct *work)
@@ -1233,6 +1234,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
set_mbox_to_func_event(func_to_func, EVENT_FAIL);
goto send_err;
}
+ func_to_func->hwdev->mbox_send_cnt++;
if (wait_mbox_msg_completion(func_to_func, timeout) != 0) {
sdk_err(func_to_func->hwdev->dev_hdl,
@@ -1241,6 +1243,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
err = -ETIMEDOUT;
goto send_err;
}
+ func_to_func->hwdev->mbox_ack_cnt++;
if (mod != msg_desc->mod || cmd != msg_desc->cmd) {
sdk_err(func_to_func->hwdev->dev_hdl,
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
index 3ad9a77..0d75177 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
@@ -348,7 +348,7 @@ int hinic3_pf_to_mgmt_sync(void *hwdev, u8 mod, u16 cmd, void *buf_in,
if (!COMM_SUPPORT_API_CHAIN((struct hinic3_hwdev *)hwdev))
return -EPERM;
- if (!buf_in || in_size == 0)
+ if ((buf_in == NULL) || (in_size == 0))
return -EINVAL;
ret = msg_to_mgmt_pre(mod, buf_in, in_size);
@@ -864,6 +864,7 @@ static int alloc_recv_msg(struct hinic3_recv_msg *recv_msg)
static void free_recv_msg(struct hinic3_recv_msg *recv_msg)
{
kfree(recv_msg->msg);
+ recv_msg->msg = NULL;
}
/**
@@ -935,6 +936,9 @@ static void free_msg_buf(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt)
free_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
+ pf_to_mgmt->mgmt_ack_buf = NULL;
+ pf_to_mgmt->sync_msg_buf = NULL;
+ pf_to_mgmt->async_msg_buf = NULL;
}
/**
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
index 3548410..b619800 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
@@ -676,6 +676,11 @@ static int hinic3_register_slave_ppf(struct hinic3_hwdev *hwdev, bool registered
if (!IS_SLAVE_HOST(hwdev))
return -EINVAL;
+ /* if unsupport hot plug, return true. */
+ if (UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev)) {
+ return 0;
+ }
+
host_info = kcalloc(1, sizeof(struct register_slave_host), GFP_KERNEL);
if (!host_info)
return -ENOMEM;
@@ -1074,8 +1079,9 @@ int hinic3_get_func_nic_enable(void *hwdev, u16 glb_func_idx, bool *en)
if (!hwdev || !en)
return -EINVAL;
- /* if single host, return true. */
- if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev)) {
+ /* if single host or unsupport hot plug, return true. */
+ if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev) ||
+ UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev)) {
*en = true;
return 0;
}
@@ -1145,11 +1151,18 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
{
int err;
struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+ int is_use_vram, is_in_kexec;
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
- hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0) {
+ snprintf(hwdev->mhost_mgmt_name, VRAM_NAME_MAX_LEN, "%s", VRAM_NIC_MHOST_MGMT);
+ hwdev->mhost_mgmt = hi_vram_kalloc(hwdev->mhost_mgmt_name, sizeof(*hwdev->mhost_mgmt));
+ } else {
+ hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ }
if (!hwdev->mhost_mgmt)
return -ENOMEM;
@@ -1165,8 +1178,11 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK, hwdev, hilink_ppf_mbox_handler);
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC, hwdev, sw_func_ppf_mbox_handler);
- bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
- bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ }
/* Slave host:
* register slave host ppf functions
@@ -1179,7 +1195,13 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
return 0;
out_free_mhost_mgmt:
- kfree(hwdev->mhost_mgmt);
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)hwdev->mhost_mgmt,
+ hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ } else {
+ kfree(hwdev->mhost_mgmt);
+ }
hwdev->mhost_mgmt = NULL;
return err;
@@ -1187,6 +1209,7 @@ out_free_mhost_mgmt:
int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
{
+ int is_use_vram;
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
@@ -1203,7 +1226,14 @@ int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC);
- kfree(hwdev->mhost_mgmt);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)hwdev->mhost_mgmt,
+ hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ } else {
+ kfree(hwdev->mhost_mgmt);
+ }
hwdev->mhost_mgmt = NULL;
return 0;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
index f7d350c..ee7afef 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
@@ -14,6 +14,7 @@
#include "hinic3_crm.h"
#include "hinic3_hw.h"
#include "hinic3_hw_cfg.h"
+#include "hinic3_dev_mgmt.h"
#include "hinic3_hwdev.h"
#include "hinic3_lld.h"
#include "hinic3_hw_mt.h"
@@ -22,9 +23,7 @@
static int g_nictool_ref_cnt;
static dev_t g_dev_id = {0};
-/*lint -save -e104 -e808*/
static struct class *g_nictool_class;
-/*lint -restore*/
static struct cdev g_nictool_cdev;
#define HINIC3_MAX_BUF_SIZE (2048 * 1024)
@@ -92,6 +91,21 @@ static int get_all_chip_id_cmd(struct hinic3_lld_dev *lld_dev, const void *buf_i
return 0;
}
+static int get_os_hot_replace_info(struct hinic3_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ if (*out_size != sizeof(struct os_hot_replace_info) || !buf_out) {
+ pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
+ *out_size, sizeof(struct os_hot_replace_info));
+ return -EFAULT;
+ }
+
+ hinic3_get_os_hot_replace_info(buf_out);
+
+ return 0;
+}
+
static int get_card_usr_api_chain_mem(int card_idx)
{
unsigned char *tmp = NULL;
@@ -100,8 +114,8 @@ static int get_card_usr_api_chain_mem(int card_idx)
card_id = card_idx;
if (!g_card_vir_addr[card_idx]) {
g_card_vir_addr[card_idx] =
- (void *)__get_free_pages(GFP_KERNEL,
- DBGTOOL_PAGE_ORDER);
+ (void *)ossl_get_free_pages(GFP_KERNEL,
+ DBGTOOL_PAGE_ORDER);
if (!g_card_vir_addr[card_idx]) {
pr_err("Alloc api chain memory fail for card %d!\n", card_idx);
return -EFAULT;
@@ -166,7 +180,7 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
if (!buf_out || *out_size != sizeof(struct pf_dev_info) * PF_DEV_INFO_NUM) {
pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
- *out_size, sizeof(dev_info) * PF_DEV_INFO_NUM);
+ *out_size, sizeof(*dev_info) * PF_DEV_INFO_NUM);
return -EFAULT;
}
@@ -193,13 +207,18 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
return 0;
}
-static long dbgtool_knl_free_mem(int id)
+static void dbgtool_knl_free_mem(int id)
{
unsigned char *tmp = NULL;
int i;
+ if (id < 0 || id >= MAX_CARD_NUM) {
+ pr_err("Invalid card id\n");
+ return;
+ }
+
if (!g_card_vir_addr[id])
- return 0;
+ return;
tmp = g_card_vir_addr[id];
for (i = 0; i < (1 << DBGTOOL_PAGE_ORDER); i++) {
@@ -210,8 +229,6 @@ static long dbgtool_knl_free_mem(int id)
free_pages((unsigned long)g_card_vir_addr[id], DBGTOOL_PAGE_ORDER);
g_card_vir_addr[id] = NULL;
g_card_phy_addr[id] = 0;
-
- return 0;
}
static int free_knl_mem(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_size,
@@ -236,7 +253,8 @@ static int free_knl_mem(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32
return 0;
}
-static int card_info_param_valid(char *dev_name, const void *buf_out, u32 buf_out_size, int *id)
+static int card_info_param_valid(const char *dev_name, const void *buf_out,
+ u32 buf_out_size, int *id)
{
int err;
@@ -351,7 +369,7 @@ static int get_hw_drv_version(struct hinic3_lld_dev *lld_dev, const void *buf_in
}
err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s", HINIC3_DRV_VERSION,
- "2023-05-17_19:56:38");
+ "2025-05-01_00:00:03");
if (err < 0)
return -EINVAL;
@@ -386,22 +404,38 @@ static int get_pf_id(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_
return 0;
}
+static int get_mbox_cnt(struct hinic3_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ if (buf_out == NULL || *out_size != sizeof(struct card_mbox_cnt_info)) {
+ pr_err("buf_out is NULL, or out_size != %lu\n",
+ sizeof(struct card_info));
+ return -EINVAL;
+ }
+
+ hinic3_get_mbox_cnt(hinic3_get_sdk_hwdev_by_lld(lld_dev), buf_out);
+
+ return 0;
+}
+
struct hw_drv_module_handle hw_driv_module_cmd_handle[] = {
- {FUNC_TYPE, get_func_type},
- {GET_FUNC_IDX, get_func_id},
- {GET_HW_STATS, (hw_driv_module)get_hw_driver_stats},
- {CLEAR_HW_STATS, clear_hw_driver_stats},
- {GET_SELF_TEST_RES, get_self_test_result},
- {GET_CHIP_FAULT_STATS, (hw_driv_module)get_chip_faults_stats},
- {GET_SINGLE_CARD_INFO, (hw_driv_module)get_single_card_info},
- {IS_DRV_IN_VM, is_driver_in_vm},
- {GET_CHIP_ID, get_all_chip_id_cmd},
- {GET_PF_DEV_INFO, get_pf_dev_info},
- {CMD_FREE_MEM, free_knl_mem},
- {GET_CHIP_INFO, get_card_func_info},
- {GET_FUNC_CAP, get_pf_cap_info},
- {GET_DRV_VERSION, get_hw_drv_version},
- {GET_PF_ID, get_pf_id},
+ {FUNC_TYPE, get_func_type},
+ {GET_FUNC_IDX, get_func_id},
+ {GET_HW_STATS, (hw_driv_module)get_hw_driver_stats},
+ {CLEAR_HW_STATS, clear_hw_driver_stats},
+ {GET_SELF_TEST_RES, get_self_test_result},
+ {GET_CHIP_FAULT_STATS, (hw_driv_module)get_chip_faults_stats},
+ {GET_SINGLE_CARD_INFO, (hw_driv_module)get_single_card_info},
+ {IS_DRV_IN_VM, is_driver_in_vm},
+ {GET_CHIP_ID, get_all_chip_id_cmd},
+ {GET_PF_DEV_INFO, get_pf_dev_info},
+ {CMD_FREE_MEM, free_knl_mem},
+ {GET_CHIP_INFO, get_card_func_info},
+ {GET_FUNC_CAP, get_pf_cap_info},
+ {GET_DRV_VERSION, get_hw_drv_version},
+ {GET_PF_ID, get_pf_id},
+ {GET_OS_HOT_REPLACE_INFO, get_os_hot_replace_info},
+ {GET_MBOX_CNT, (hw_driv_module)get_mbox_cnt},
};
static int alloc_tmp_buf(void *hwdev, struct msg_module *nt_msg, u32 in_size,
@@ -439,8 +473,8 @@ static void free_tmp_buf(void *hwdev, struct msg_module *nt_msg,
static int send_to_hw_driver(struct hinic3_lld_dev *lld_dev, struct msg_module *nt_msg,
const void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(hw_driv_module_cmd_handle) /
- sizeof(hw_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(hw_driv_module_cmd_handle) /
+ sizeof(hw_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type =
(enum driver_cmd_type)(nt_msg->msg_formate);
int err = 0;
@@ -482,8 +516,8 @@ static int send_to_service_driver(struct hinic3_lld_dev *lld_dev, struct msg_mod
if (nt_msg->msg_formate == GET_DRV_VERSION)
return 0;
- pr_err("Can not get the uld dev correctly: %s, %s driver may be not register\n",
- nt_msg->device_name, service_name[type]);
+ pr_err("Can not get the uld dev correctly: %s driver may be not register\n",
+ service_name[type]);
return -EINVAL;
}
@@ -550,26 +584,29 @@ static struct hinic3_lld_dev *get_lld_dev_by_nt_msg(struct msg_module *nt_msg)
{
struct hinic3_lld_dev *lld_dev = NULL;
- if (nt_msg->module >= SEND_TO_SRV_DRV_BASE && nt_msg->module < SEND_TO_DRIVER_MAX &&
- nt_msg->module != SEND_TO_HW_DRIVER && nt_msg->msg_formate != GET_DRV_VERSION) {
+ if (nt_msg->module == SEND_TO_NIC_DRIVER &&
+ (nt_msg->msg_formate == GET_XSFP_INFO ||
+ nt_msg->msg_formate == GET_XSFP_PRESENT ||
+ nt_msg->msg_formate == GET_XSFP_INFO_COMP_CMIS)) {
+ lld_dev = hinic3_get_lld_dev_by_chip_and_port(nt_msg->device_name, nt_msg->port_id);
+ } else if (nt_msg->module == SEND_TO_CUSTOM_DRIVER &&
+ nt_msg->msg_formate == CMD_CUSTOM_BOND_GET_CHIP_NAME) {
+ lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
+ SERVICE_T_MAX);
+ } else if (nt_msg->module == SEND_TO_VBS_DRIVER ||
+ nt_msg->module == SEND_TO_BIFUR_DRIVER) {
+ lld_dev = hinic3_get_lld_dev_by_chip_name(nt_msg->device_name);
+ } else if (nt_msg->module >= SEND_TO_SRV_DRV_BASE &&
+ nt_msg->module < SEND_TO_DRIVER_MAX &&
+ nt_msg->msg_formate != GET_DRV_VERSION) {
lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
nt_msg->module - SEND_TO_SRV_DRV_BASE);
} else {
lld_dev = hinic3_get_lld_dev_by_chip_name(nt_msg->device_name);
if (!lld_dev)
- lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
- SERVICE_T_MAX);
+ lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name, SERVICE_T_MAX);
}
- if (nt_msg->module == SEND_TO_NIC_DRIVER && (nt_msg->msg_formate == GET_XSFP_INFO ||
- nt_msg->msg_formate == GET_XSFP_PRESENT))
- lld_dev = hinic3_get_lld_dev_by_chip_and_port(nt_msg->device_name,
- nt_msg->port_id);
-
- if (nt_msg->module == SEND_TO_CUSTOM_DRIVER &&
- nt_msg->msg_formate == CMD_CUSTOM_BOND_GET_CHIP_NAME)
- lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name, SERVICE_T_MAX);
-
return lld_dev;
}
@@ -591,14 +628,16 @@ static long hinicadm_k_unlocked_ioctl(struct file *pfile, unsigned long arg)
lld_dev = get_lld_dev_by_nt_msg(&nt_msg);
if (!lld_dev) {
if (nt_msg.msg_formate != DEV_NAME_TEST)
- pr_err("Can not find device %s for module %d\n",
+ pr_err("Can not find device %s for module %u\n",
nt_msg.device_name, nt_msg.module);
return -ENODEV;
}
- if (nt_msg.msg_formate == DEV_NAME_TEST)
+ if (nt_msg.msg_formate == DEV_NAME_TEST) {
+ lld_dev_put(lld_dev);
return 0;
+ }
ret = alloc_tmp_buf(hinic3_get_sdk_hwdev_by_lld(lld_dev), &nt_msg,
in_size, &buf_in, out_size_expect, &buf_out);
@@ -642,6 +681,9 @@ out_free_lock:
static long dbgtool_knl_ffm_info_rd(struct dbgtool_param *para,
struct dbgtool_k_glb_info *dbgtool_info)
{
+ if (!para->param.ffm_rd || !dbgtool_info->ffm)
+ return -EINVAL;
+
/* Copy the ffm_info to user mode */
if (copy_to_user(para->param.ffm_rd, dbgtool_info->ffm,
(unsigned int)sizeof(struct ffm_record_info))) {
@@ -674,13 +716,14 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
card_info = (struct card_node *)g_card_node_array[i];
if (!card_info)
continue;
- if (!strncmp(param.chip_name, card_info->chip_name, IFNAMSIZ))
+ if (memcmp(param.chip_name, card_info->chip_name,
+ strlen(card_info->chip_name) + 1) == 0)
break;
}
if (i == MAX_CARD_NUM || !card_info) {
lld_put();
- pr_err("Can't find this card %s\n", param.chip_name);
+ pr_err("Can't find this card.\n");
return -EFAULT;
}
@@ -701,6 +744,7 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
default:
pr_err("Dbgtool cmd(0x%x) not support now\n", real_cmd);
ret = -EFAULT;
+ break;
}
up(&dbgtool_info->dbgtool_sem);
@@ -746,9 +790,11 @@ static long nictool_k_unlocked_ioctl(struct file *pfile,
static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
{
+ pgprot_t vm_page_prot;
unsigned long vmsize = vma->vm_end - vma->vm_start;
phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
phys_addr_t phy_addr;
+ int err = 0;
if (vmsize > (PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER))) {
pr_err("Map size = %lu is bigger than alloc\n", vmsize);
@@ -757,14 +803,18 @@ static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
/* old version of tool set vma->vm_pgoff to 0 */
phy_addr = offset ? offset : g_card_phy_addr[card_id];
-
- if (!phy_addr) {
- pr_err("Card_id = %d physical address is 0\n", card_id);
- return -EAGAIN;
+ /* check phy_addr valid */
+ if (phy_addr != g_card_phy_addr[card_id]) {
+ err = hinic3_bar_mmap_param_valid(phy_addr, vmsize);
+ if (err != 0) {
+ pr_err("mmap param invalid, err: %d\n", err);
+ return err;
+ }
}
/* Disable cache and write buffer in the mapping area */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_page_prot = vm_page_prot;
if (remap_pfn_range(vma, vma->vm_start, (phy_addr >> PAGE_SHIFT),
vmsize, vma->vm_page_prot)) {
pr_err("Remap pfn range failed.\n");
@@ -787,7 +837,6 @@ static const struct file_operations fifo_operations = {
static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
{
struct dbgtool_k_glb_info *dbgtool_info = NULL;
- int err, id;
if (hinic3_func_type(hwdev) != TYPE_VF)
chip_info->func_handle_array[hinic3_global_func_id(hwdev)] = NULL;
@@ -795,23 +844,23 @@ static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
if (--chip_info->func_num)
return;
- err = sscanf(chip_info->chip_name, HINIC3_CHIP_NAME "%d", &id);
- if (err < 0)
- pr_err("Failed to get card id\n");
-
- if (id < MAX_CARD_NUM)
- g_card_node_array[id] = NULL;
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ g_card_node_array[chip_info->chip_id] = NULL;
dbgtool_info = chip_info->dbgtool_info;
/* FFM deinit */
- kfree(dbgtool_info->ffm);
- dbgtool_info->ffm = NULL;
+ if (dbgtool_info && dbgtool_info->ffm) {
+ kfree(dbgtool_info->ffm);
+ dbgtool_info->ffm = NULL;
+ }
+
+ if (dbgtool_info)
+ kfree(dbgtool_info);
- kfree(dbgtool_info);
chip_info->dbgtool_info = NULL;
- if (id < MAX_CARD_NUM)
- (void)dbgtool_knl_free_mem(id);
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ dbgtool_knl_free_mem(chip_info->chip_id);
}
static int alloc_dbgtool_info(void *hwdev, struct card_node *chip_info)
@@ -872,7 +921,6 @@ dbgtool_info_fail:
* nictool_k_init - initialize the hw interface
**/
/* temp for dbgtool_info */
-/*lint -e438*/
int nictool_k_init(void *hwdev, void *chip_node)
{
struct card_node *chip_info = (struct card_node *)chip_node;
@@ -895,9 +943,7 @@ int nictool_k_init(void *hwdev, void *chip_node)
}
/* Create equipment */
- /*lint -save -e160*/
g_nictool_class = class_create(THIS_MODULE, HIADM3_DEV_CLASS);
- /*lint -restore*/
if (IS_ERR(g_nictool_class)) {
pr_err("Create nictool_class fail\n");
err = -EFAULT;
@@ -944,7 +990,7 @@ alloc_chdev_fail:
free_dbgtool_info(hwdev, chip_info);
return err;
-} /*lint +e438*/
+}
void nictool_k_uninit(void *hwdev, void *chip_node)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
index f368133..c943dfc 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
@@ -18,6 +18,8 @@
int nictool_k_init(void *hwdev, void *chip_node);
void nictool_k_uninit(void *hwdev, void *chip_node);
+void hinic3_get_os_hot_replace_info(void *oshr_info);
+
void hinic3_get_all_chip_id(void *id_info);
void hinic3_get_card_func_info_by_card_name
@@ -29,6 +31,8 @@ bool hinic3_is_in_host(void);
int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *isvalid);
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin);
+
extern struct hinic3_uld_info g_uld_info[SERVICE_T_MAX];
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
index 2d5423e..6f145a0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
@@ -19,6 +19,20 @@
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
+#elif defined(CONFIG_NF_VID_DID)
+#define PCI_VENDOR_ID_NF 0x2036
+#define NFNIC_DEV_ID_STANDARD 0x1618
+#define NFNIC_DEV_ID_SDI_5_1_PF 0x0226
+#define NFNIC_DEV_ID_SDI_5_0_PF 0x0225
+#define NFNIC_DEV_ID_DPU_PF 0x0224
+#define NFNIC_DEV_ID_VF 0x1619
+#define NFNIC_DEV_ID_VF_HV 0x379F
+#define NFNIC_DEV_SDI_5_1_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_0_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_1_ID_VF_HV 0x379F
+#define NFNIC_DEV_ID_SPU 0xAC00
+#define NFNIC_DEV_SDI_5_1_SSDID_VF 0x1000
+#define NFNIC_DEV_SDI_V100_SSDID_MASK (3 << 12)
#else
#define PCI_VENDOR_ID_HUAWEI 0x19e5
#define HINIC3_DEV_ID_STANDARD 0x0222
@@ -28,16 +42,33 @@
#define HINIC3_DEV_ID_VF 0x375F
#define HINIC3_DEV_ID_VF_HV 0x379F
#define HINIC3_DEV_SDI_5_1_ID_VF 0x375F
+#define HINIC3_DEV_SDI_5_0_ID_VF 0x375F
#define HINIC3_DEV_SDI_5_1_ID_VF_HV 0x379F
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
#endif
+#define NFNIC_DEV_SSID_2X25G_NF 0x0860
+#define NFNIC_DEV_SSID_4X25G_NF 0x0861
+#define NFNIC_DEV_SSID_2x100G_NF 0x0862
+#define NFNIC_DEV_SSID_2x200G_NF 0x0863
+
+#define HINIC3_DEV_SSID_2X10G 0x0035
#define HINIC3_DEV_SSID_2X25G 0x0051
#define HINIC3_DEV_SSID_4X25G 0x0052
+#define HINIC3_DEV_SSID_4X25G_BD 0x0252
+#define HINIC3_DEV_SSID_4X25G_SMARTNIC 0x0152
+#define HINIC3_DEV_SSID_6X25G_VL 0x0356
#define HINIC3_DEV_SSID_2X100G 0x00A1
+#define HINIC3_DEV_SSID_2X100G_SMARTNIC 0x01A1
+#define HINIC3_DEV_SSID_2X200G 0x04B1
#define HINIC3_DEV_SSID_2X100G_VF 0x1000
+#define HINIC3_DEV_SSID_HPC_4_HOST_NIC 0x005A
+#define HINIC3_DEV_SSID_2X200G_VL 0x00B1
+#define HINIC3_DEV_SSID_1X100G 0x02A4
+
+#define BIFUR_RESOURCE_PF_SSID 0x05a1
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
index b23b69f..c8258ff 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
@@ -68,7 +68,6 @@ ssize_t hinic3_sriov_numvfs_show(struct device *dev,
return sprintf(buf, "%d\n", pci_num_vf(pdev));
}
-/*lint -save -e713*/
ssize_t hinic3_sriov_numvfs_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -116,7 +115,6 @@ ssize_t hinic3_sriov_numvfs_store(struct device *dev,
return count;
}
-/*lint -restore*/
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
int hinic3_pci_sriov_disable(struct pci_dev *dev)
@@ -174,24 +172,15 @@ int hinic3_pci_sriov_disable(struct pci_dev *dev)
return 0;
}
-int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
-{
#ifdef CONFIG_PCI_IOV
- struct hinic3_sriov_info *sriov_info = NULL;
- struct hinic3_event_info event = {0};
- void *hwdev = NULL;
- int pre_existing_vfs = 0;
- int err = 0;
-
- sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
- hwdev = hinic3_get_hwdev_by_pcidev(dev);
- if (!hwdev) {
- sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
- return -EPERM;
- }
+int hinic3_pci_sriov_check(struct hinic3_sriov_info *sriov_info, struct pci_dev *dev, int num_vfs)
+{
+ int pre_existing_vfs;
+ int err;
if (test_and_set_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state)) {
- sdk_err(&dev->dev, "SR-IOV enable in process, please wait, num_vfs %d\n",
+ sdk_err(&dev->dev,
+ "SR-IOV enable in process, please wait, num_vfs %d\n",
num_vfs);
return -EPERM;
}
@@ -202,6 +191,7 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
clear_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state);
return -ERANGE;
}
+
if (pre_existing_vfs && pre_existing_vfs != num_vfs) {
err = hinic3_pci_sriov_disable(dev);
if (err) {
@@ -213,6 +203,31 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
return num_vfs;
}
+ return 0;
+}
+#endif
+
+
+int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
+{
+#ifdef CONFIG_PCI_IOV
+ struct hinic3_sriov_info *sriov_info = NULL;
+ struct hinic3_event_info event = {0};
+ void *hwdev = NULL;
+ int err = 0;
+
+ sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
+ hwdev = hinic3_get_hwdev_by_pcidev(dev);
+ if (!hwdev) {
+ sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
+ return -EPERM;
+ }
+
+ err = hinic3_pci_sriov_check(sriov_info, dev, num_vfs);
+ if (err != 0) {
+ return err;
+ }
+
err = hinic3_init_vf_hw(hwdev, 1, (u16)num_vfs);
if (err) {
sdk_err(&dev->dev, "Failed to init vf in hardware before enable sriov, error %d\n",
@@ -262,6 +277,3 @@ int hinic3_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
else
return hinic3_pci_sriov_enable(dev, num_vfs);
}
-
-/*lint -restore*/
-
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c
index 2f5e098..4f8acd6 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c
@@ -128,7 +128,7 @@ int hinic3_wq_create(void *hwdev, struct hinic3_wq *wq, u32 q_depth,
wq_page_size = ALIGN(dev->wq_page_size, PAGE_SIZE);
- memset(wq, 0, sizeof(*wq));
+ memset(wq, 0, sizeof(struct hinic3_wq));
wq->dev_hdl = dev->dev_hdl;
wq->q_depth = q_depth;
wq->idx_mask = (u16)(q_depth - 1);
diff --git a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
index 9e8fc75..bfb4499 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
@@ -10,6 +10,10 @@
#define OVS_PORT_NUM_MAX BOND_PORT_MAX_NUM
#define DEFAULT_ROCE_BOND_FUNC 0xFFFFFFFF
+#define BOND_ID_IS_VALID(_id) \
+ (((_id) >= BOND_FIRST_ID) && ((_id) <= BOND_MAX_ID))
+#define BOND_ID_IS_INVALID(_id) (!(BOND_ID_IS_VALID(_id)))
+
enum bond_group_id {
BOND_FIRST_ID = 1,
BOND_MAX_ID = 4,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
index f56df08..f9737ea 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
@@ -21,6 +21,7 @@ enum servic_bit_define {
SERVICE_BIT_PPA = 11,
SERVICE_BIT_MIGRATE = 12,
SERVICE_BIT_VROCE = 13,
+ SERVICE_BIT_BIFUR = 14,
SERVICE_BIT_MAX
};
@@ -38,6 +39,7 @@ enum servic_bit_define {
#define CFG_SERVICE_MASK_PPA (0x1 << SERVICE_BIT_PPA)
#define CFG_SERVICE_MASK_MIGRATE (0x1 << SERVICE_BIT_MIGRATE)
#define CFG_SERVICE_MASK_VROCE (0x1 << SERVICE_BIT_VROCE)
+#define CFG_SERVICE_MASK_BIFUR (0x1 << SERVICE_BIT_BIFUR)
/* Definition of the scenario ID in the cfg_data, which is used for SML memory allocation. */
enum scenes_id_define {
@@ -50,6 +52,8 @@ enum scenes_id_define {
SCENES_ID_STORAGE_ROCE = 6,
SCENES_ID_COMPUTE_ROCE = 7,
SCENES_ID_STORAGE_TOE = 8,
+ SCENES_ID_COMPUTE_DPU = 100,
+ SCENES_ID_COMPUTE_SMART_NIC = 101,
SCENES_ID_MAX
};
@@ -120,13 +124,18 @@ struct cfg_cmd_dev_cap {
u8 srv_multi_host_mode;
u8 virtio_vq_size;
- u32 rsvd_func3[5];
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 lro_enable;
+ u8 os_hot_replace;
+
+ u32 rsvd_func3[4];
/* l2nic */
u16 nic_max_sq_id;
u16 nic_max_rq_id;
u16 nic_default_num_queues;
- u16 rsvd1_nic;
+ u16 outband_vlan_cfg_en;
u32 rsvd2_nic[2];
/* RoCE */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
index d9f67e2..6c5b995 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
@@ -37,7 +37,7 @@ static inline void hinic3_cpu_to_be32(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -59,7 +59,7 @@ static inline void hinic3_be32_to_cpu(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -86,52 +86,16 @@ static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
sge->len = (u32)len;
}
-#ifdef HW_CONVERT_ENDIAN
#define hinic3_hw_be32(val) (val)
#define hinic3_hw_cpu32(val) (val)
#define hinic3_hw_cpu16(val) (val)
-#else
-#define hinic3_hw_be32(val) cpu_to_be32(val)
-#define hinic3_hw_cpu32(val) be32_to_cpu(val)
-#define hinic3_hw_cpu16(val) be16_to_cpu(val)
-#endif
static inline void hinic3_hw_be32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_be32(*mem);
- mem++;
- }
-#endif
}
static inline void hinic3_hw_cpu32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_cpu32(*mem);
- mem++;
- }
-#endif
}
int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
@@ -149,6 +113,8 @@ int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
/* func_attr.glb_func_idx, global function index */
u16 hinic3_global_func_id(void *hwdev);
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id);
+
/* func_attr.p2p_idx, belongs to which pf */
u8 hinic3_pf_id_of_vf(void *hwdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
index 9a9bfe2..e36ba1d 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
@@ -219,5 +219,7 @@ void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
const char **hinic3_get_uld_names(void);
+int hinic3_lld_init(void);
+void hinic3_lld_exit(void);
#endif
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
index 97d34f0..199f17a 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
@@ -43,6 +43,10 @@ enum mag_cmd {
MAG_CMD_GET_XSFP_PRESENT = 62, /* get xsfp present status @see mag_cmd_get_xsfp_present */
MAG_CMD_SET_XSFP_RW = 63, /* sfp/qsfp single byte read/write, @see mag_cmd_set_xsfp_rw */
MAG_CMD_CFG_XSFP_TEMPERATURE = 64, /* get xsfp temp @see mag_cmd_sfp_temp_out_info */
+ /**< set xsfp tlv info @see struct mag_cmd_set_xsfp_tlv_req */
+ MAG_CMD_SET_XSFP_TLV_INFO = 65,
+ /**< get xsfp tlv info @see struct drv_mag_cmd_get_xsfp_tlv_rsp */
+ MAG_CMD_GET_XSFP_TLV_INFO = 66,
/* Event reported 100-149 */
MAG_CMD_WIRE_EVENT = 100,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
index caaba5d..88a9c0d 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
@@ -16,32 +16,43 @@
#define BOARD_TYPE_RSVD_RANGE_END 255
enum board_type_define_e {
- BOARD_TYPE_MPU_DEFAULT = 0, /* Default config */
- BOARD_TYPE_TEST_EVB_4X25G = 1, /* EVB Board */
- BOARD_TYPE_TEST_CEM_2X100G = 2, /* 2X100G CEM Card */
- BOARD_TYPE_STRG_SMARTIO_4X32G_FC = 30, /* 4X32G SmartIO FC Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_TIOE = 31, /* 4X25GE SmartIO TIOE Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE = 32, /* 4X25GE SmartIO ROCE Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE_AA = 33, /* 4X25GE SmartIO ROCE_AA Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV = 34, /* 4X25GE SmartIO container Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV_SW = 35, /* 4X25GE SmartIO container switch Card */
- BOARD_TYPE_STRG_4X25G_COMSTORAGE = 36, /* 4X25GE compute storage Onboard Card */
- BOARD_TYPE_STRG_2X100G_TIOE = 40, /* 2X100G SmartIO TIOE Card */
- BOARD_TYPE_STRG_2X100G_ROCE = 41, /* 2X100G SmartIO ROCE Card */
- BOARD_TYPE_STRG_2X100G_ROCE_AA = 42, /* 2X100G SmartIO ROCE_AA Card */
- BOARD_TYPE_CAL_2X25G_NIC_75MPPS = 100, /* 2X25G ETH Standard card 75MPPS */
- BOARD_TYPE_CAL_2X25G_NIC_40MPPS = 101, /* 2X25G ETH Standard card 40MPPS */
- BOARD_TYPE_CAL_2X100G_DPU = 102, /* 2x100G DPU Card */
- BOARD_TYPE_CAL_4X25G_NIC_120MPPS = 105, /* 4X25G ETH Standard card 120MPPS */
- BOARD_TYPE_CAL_4X25G_COMSTORAGE = 106, /* 4X25GE compute storage Onboard Card */
- BOARD_TYPE_CAL_2X32G_FC_HBA = 110, /* 2X32G FC HBA card */
- BOARD_TYPE_CAL_2X16G_FC_HBA = 111, /* 2X16G FC HBA card */
- BOARD_TYPE_CAL_2X100G_NIC_120MPPS = 115, /* 2X100G ETH Standard card 120MPPS */
- BOARD_TYPE_CAL_2X25G_DPU = 116, /* 2x25G DPU Card */
- BOARD_TYPE_CAL_4X25G_DPU = 118, /* 4x25G DPU Card */
- BOARD_TYPE_CLD_2X100G_SDI5_1 = 170, /* 2X100G SDI 5.1 Card */
- BOARD_TYPE_CLD_2X25G_SDI5_0_LITE = 171, /* 2x25G SDI5.0 Lite Card */
- BOARD_TYPE_CLD_2X100G_SDI5_0 = 172, /* 2x100G SDI5.0 Card */
+ BOARD_TYPE_MPU_DEFAULT = 0,
+ BOARD_TYPE_TEST_EVB_4X25G = 1,
+ BOARD_TYPE_TEST_CEM_2X100G = 2,
+ BOARD_TYPE_STRG_SMARTIO_4X32G_FC = 30,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_TIOE = 31,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE = 32,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE_AA = 33,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV = 34,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV_SW = 35,
+ BOARD_TYPE_STRG_4X25G_COMSTORAGE = 36,
+ BOARD_TYPE_STRG_2X100G_TIOE = 40,
+ BOARD_TYPE_STRG_2X100G_ROCE = 41,
+ BOARD_TYPE_STRG_2X100G_ROCE_AA = 42,
+ BOARD_TYPE_CAL_2X25G_NIC_75MPPS = 100,
+ BOARD_TYPE_CAL_2X25G_NIC_40MPPS = 101,
+ BOARD_TYPE_CAL_2X100G_DPU_VL = 102,
+ BOARD_TYPE_CAL_4X25G_NIC_120MPPS = 105,
+ BOARD_TYPE_CAL_4X25G_COMSTORAGE = 106,
+ BOARD_TYPE_CAL_2X32G_FC_HBA = 110,
+ BOARD_TYPE_CAL_2X16G_FC_HBA = 111,
+ BOARD_TYPE_CAL_2X100G_NIC_120MPPS = 115,
+ BOARD_TYPE_CAL_2X25G_DPU_BD = 116,
+ BOARD_TYPE_CAL_2X100G_TCE_BACKPLANE = 117,
+ BOARD_TYPE_CAL_4X25G_DPU_VL = 118,
+ BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS = 119,
+ BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS = 120,
+ BOARD_TYPE_CAL_6X25G_DPU_VL = 121,
+ BOARD_TYPE_CAL_4X25G_DPU_BD = 122,
+ BOARD_TYPE_CAL_2X25G_NIC_4HOST = 123,
+ BOARD_TYPE_CAL_2X10G_LOW_POWER = 125,
+ BOARD_TYPE_CAL_2X200G_NIC_INTERNET = 127,
+ BOARD_TYPE_CAL_1X100GR2_OCP = 129,
+ BOARD_TYPE_CAL_2X200G_DPU_VL = 130,
+ BOARD_TYPE_CLD_2X100G_SDI5_1 = 170,
+ BOARD_TYPE_CLD_2X25G_SDI5_0_LITE = 171,
+ BOARD_TYPE_CLD_2X100G_SDI5_0 = 172,
+ BOARD_TYPE_CLD_4X25G_SDI5_0_C = 175,
BOARD_TYPE_MAX_INDEX = 0xFF
};
@@ -49,23 +60,76 @@ static inline u32 spu_board_type_valid(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
- ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
+}
+
+static inline int board_type_is_sdi_50(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
+ ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C);
}
static inline int board_type_is_sdi(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_1) ||
((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
- ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0);
+ ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C);
+}
+
+static inline int board_type_is_dpu_spu(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
}
static inline int board_type_is_dpu(u32 board_type)
{
- return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_6X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
+}
+
+static inline int board_type_is_smartnic(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS);
+}
+
+/* 此接口判断是否是分布式存储的标卡以及计算的标卡(含ROCE特性),
+ * 仅用于LLDP TX功能冲突命令字处理的判断
+ */
+static inline int board_type_is_compute(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_75MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_40MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_NIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_COMSTORAGE) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_NIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X10G_LOW_POWER) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_NIC_INTERNET) ||
+ ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_4HOST) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS);
+}
+
+/* 此接口判断服务器输入reboot网卡是否需要复位 */
+static inline int board_type_is_multi_socket(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP);
}
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
index 89d5cc4..e65c206 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
@@ -1,11 +1,11 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ * Description : common definitions
+ */
#ifndef COMM_DEFS_H
#define COMM_DEFS_H
-#include "mgmt_msg_base.h"
-
/** MPU CMD MODULE TYPE */
enum hinic3_mod_type {
HINIC3_MOD_COMM = 0, /* HW communication module */
@@ -33,16 +33,16 @@ enum hinic3_mod_type {
HINIC3_MOD_MAX,
};
-/* Func reset flag, Specifies the resource to be cleaned.*/
-enum func_reset_flag_e {
+/* func reset的flag ,用于指示清理哪种资源 */
+enum func_reset_flag_e{
RES_TYPE_FLUSH_BIT = 0,
RES_TYPE_MQM,
RES_TYPE_SMF,
RES_TYPE_PF_BW_CFG,
RES_TYPE_COMM = 10,
- RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
RES_TYPE_NIC,
RES_TYPE_OVS,
RES_TYPE_VBS,
@@ -53,33 +53,48 @@ enum func_reset_flag_e {
RES_TYPE_MAX,
};
-#define HINIC3_COMM_RES \
- ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
- (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
- (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
+#define HINIC3_COMM_RES \
+ ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
+ (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
+ (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
-#define HINIC3_NIC_RES BIT(RES_TYPE_NIC)
-#define HINIC3_OVS_RES BIT(RES_TYPE_OVS)
-#define HINIC3_VBS_RES BIT(RES_TYPE_VBS)
-#define HINIC3_ROCE_RES BIT(RES_TYPE_ROCE)
-#define HINIC3_FC_RES BIT(RES_TYPE_FC)
-#define HINIC3_TOE_RES BIT(RES_TYPE_TOE)
-#define HINIC3_IPSEC_RES BIT(RES_TYPE_IPSEC)
+#define HINIC3_NIC_RES (1 << RES_TYPE_NIC)
+#define HINIC3_OVS_RES (1 << RES_TYPE_OVS)
+#define HINIC3_VBS_RES (1 << RES_TYPE_VBS)
+#define HINIC3_ROCE_RES (1 << RES_TYPE_ROCE)
+#define HINIC3_FC_RES (1 << RES_TYPE_FC)
+#define HINIC3_TOE_RES (1 << RES_TYPE_TOE)
+#define HINIC3_IPSEC_RES (1 << RES_TYPE_IPSEC)
/* MODE OVS、NIC、UNKNOWN */
#define HINIC3_WORK_MODE_OVS 0
#define HINIC3_WORK_MODE_UNKNOWN 1
#define HINIC3_WORK_MODE_NIC 2
-#define DEVICE_TYPE_L2NIC 0
-#define DEVICE_TYPE_NVME 1
-#define DEVICE_TYPE_VIRTIO_NET 2
-#define DEVICE_TYPE_VIRTIO_BLK 3
-#define DEVICE_TYPE_VIRTIO_VSOCK 4
-#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
-#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
-#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
-#define DEVICE_TYPE_VIRTIO_HPC 8
+#define DEVICE_TYPE_L2NIC 0
+#define DEVICE_TYPE_NVME 1
+#define DEVICE_TYPE_VIRTIO_NET 2
+#define DEVICE_TYPE_VIRTIO_BLK 3
+#define DEVICE_TYPE_VIRTIO_VSOCK 4
+#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
+#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
+#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
+#define DEVICE_TYPE_VIRTIO_HPC 8
+#define DEVICE_TYPE_VIRTIO_FS 9
+
+#define IS_STORAGE_DEVICE_TYPE(dev_type) \
+ ((dev_type) == DEVICE_TYPE_VIRTIO_BLK || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_BLK_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_SCSI_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_FS)
+
+#define MGMT_MSG_CMD_OP_SET 1
+#define MGMT_MSG_CMD_OP_GET 0
+
+#define MGMT_MSG_CMD_OP_START 1
+#define MGMT_MSG_CMD_OP_STOP 0
+
+#define HOT_REPLACE_PARTITION_NUM 2
enum hinic3_svc_type {
SVC_T_COMM = 0,
@@ -98,8 +113,17 @@ enum hinic3_svc_type {
};
/**
- * Common header control information of the COMM message interaction command word
- * between the driver and PF.
+ * Common header control information of the COMM message interaction command word between the driver and PF
+ * stuct mgmt_msg_head and struct comm_info_head are the same stucture
+ */
+struct mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+/**
+ * Common header control information of the COMM message interaction command word between the driver and PF
*/
struct comm_info_head {
/** response status code, 0: success, others: error code */
@@ -113,4 +137,29 @@ struct comm_info_head {
u8 rsvd[5];
};
+
+static inline u32 get_function_partition(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM;
+}
+
+static inline u32 is_primary_function(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0;
+}
+
+static inline u32 mpu_nic_get_primary_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ function_id : (function_id - port_num);
+}
+
+// when func_id is in partition 0/1, it will get its another func_id in partition 1/0
+static inline u32 mpu_nic_get_backup_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ (function_id + port_num) : (function_id - port_num);
+}
+
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
index b24e729..fd0401f 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
@@ -89,6 +89,10 @@ enum hinic3_mgmt_cmd {
* @see comm_read_ucode_sm_resp
*/
COMM_MGMT_CMD_CLEAR_LOG, /**< clear log @see comm_cmd_clear_log_s */
+ COMM_MGMT_CMD_UCODE_SM_COUNTER_PER,
+ /**< get ucode sm counter @see struct comm_read_ucode_sm_per_req
+ * @see struct comm_read_ucode_sm_per_resp
+ */
COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140, /* check if switch workmode reserved
* @see comm_cmd_check_if_switch_workmode
@@ -101,6 +105,7 @@ enum hinic3_mgmt_cmd {
COMM_MGMT_CMD_CPI_TCAM_DBG, /* enable or disable the scheduled cpi tcam task,
* set task interval time @see comm_cmd_cpi_tcam_dbg_s
*/
+ COMM_MGMT_CMD_LLDP_TX_FUNC_SET,
COMM_MGMT_CMD_SECTION_RSVD_0 = 160, /**< rsvd0 section */
COMM_MGMT_CMD_SECTION_RSVD_1 = 170, /**< rsvd1 section */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
index f535777..fd3a7dd 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
@@ -313,7 +313,8 @@ struct comm_cmd_get_fw_version {
struct mgmt_msg_head head;
u16 fw_type; /**< firmware type @see enum hinic3_fw_ver_type */
- u16 rsvd1;
+ u16 fw_dfx_vld : 1; /**< 0: release, 1: debug */
+ u16 rsvd1 : 15;
u8 ver[HINIC3_FW_VERSION_LEN]; /**< firmware version */
u8 time[HINIC3_FW_COMPILE_TIME_LEN]; /**< firmware compile time */
};
@@ -558,6 +559,7 @@ struct nic_log_info_request {
#define MPU_TEMP_OP_GET 0
#define MPU_TEMP_THRESHOLD_OP_CFG 1
+#define MPU_TEMP_MCTP_DFX_INFO_GET 2
struct comm_temp_in_info {
struct comm_info_head head;
u8 opt_type; /**< operation type 0:read operation 1:cfg operation */
@@ -660,6 +662,28 @@ struct comm_read_ucode_sm_resp {
u64 val2;
};
+#define PER_REQ_MAX_DATA_LEN 0x600
+
+struct comm_read_ucode_sm_per_req {
+ struct mgmt_msg_head msg_head;
+
+ u32 tbl_type;
+ u32 count_id;
+};
+
+struct comm_read_ucode_sm_per_resp {
+ struct mgmt_msg_head msg_head;
+
+ u8 data[PER_REQ_MAX_DATA_LEN];
+};
+
+struct ucode_sm_counter_get_info {
+ u32 width_type;
+ u32 tbl_type;
+ unsigned int base_count;
+ unsigned int count_num;
+};
+
enum log_type {
MPU_LOG_CLEAR = 0,
SMU_LOG_CLEAR = 1,
@@ -1057,7 +1081,9 @@ struct comm_cmd_ncsi_settings {
u8 lldp_over_ncsi_enable;
u8 lldp_over_mctp_enable;
u32 magicwd;
- u8 rsvd[8];
+ u8 lldp_tx_enable;
+ u8 rsvd[3];
+ u32 crc;
struct tag_ncsi_chan_info ncsi_chan_info;
};
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
index fde8617..767f886 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
@@ -114,6 +114,14 @@ struct tag_ncsi_client_info {
#define AEN_CTRL_CONFIG_REQ_SHIFT 1
#define AEN_CTRL_DRV_CHANGE_SHIFT 2
+/* AEN Type */
+enum aen_type_e{
+ AEN_LINK_STATUS_CHANGE_TYPE = 0x0,
+ AEN_CONFIG_REQUIRED_TYPE = 0x1,
+ OEM_AEN_CONFIG_REQUEST_TYPE = 0x80,
+ AEN_TYPE_MAX = 0x100
+} ;
+
/* get link status 0x0A */
#define GET_LINK_STATUS_REQ_LEN 0
#define GET_LINK_STATUS_RSP_LEN 16
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
index fe663e1..83b75f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
@@ -1,5 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+/*
+ * Copyright (C), 2001-2021, Huawei Tech. Co., Ltd.
+ * File Name : nic_cfg_comm.h
+ * Version : Initial Draft
+ * Description : nic config common header file
+ * Function List :
+ * History :
+ * Modification: Created file
+ */
#ifndef NIC_CFG_COMM_H
#define NIC_CFG_COMM_H
@@ -26,7 +34,7 @@ enum nic_rss_hash_type {
};
#define NIC_RSS_INDIR_SIZE 256
-#define NIC_RSS_KEY_SIZE 40
+#define NIC_RSS_KEY_SIZE 40
/* *
* Definition of the NIC receiving mode
@@ -36,6 +44,7 @@ enum nic_rss_hash_type {
#define NIC_RX_MODE_BC 0x04
#define NIC_RX_MODE_MC_ALL 0x08
#define NIC_RX_MODE_PROMISC 0x10
+#define NIC_RX_DB_COS_MAX 0x4
/* IEEE 802.1Qaz std */
#define NIC_DCB_COS_MAX 0x8
@@ -52,4 +61,7 @@ enum nic_rss_hash_type {
#define NIC_DCB_PRIO_STRICT 0x1
#define NIC_DCB_MAX_PFC_NUM 0x4
+
+#define NIC_ETS_PERCENT_WEIGHT 100
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
index 801aeed..9f93f7e 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
@@ -23,7 +23,11 @@
#define VRAM_CQM_BITMAP_BASE "B"
#define VRAM_NIC_DCB "DCB"
+#define VRAM_NIC_MHOST_MGMT "MHOST_MGMT"
#define VRAM_NIC_VRAM "NIC_VRAM"
+#define VRAM_NIC_IRQ_VRAM "NIC_IRQ"
+
+#define VRAM_NIC_MQM "NM"
#define VRAM_VBS_BASE_IOCB "BASE_IOCB"
#define VRAM_VBS_EX_IOCB "EX_IOCB"
@@ -55,11 +59,16 @@ enum KUP_HOOK_POINT {
PRE_FREEZE,
FREEZE_TO_KILL,
PRE_UPDATE_KERNEL,
- FLUSH_DURING_KUP,
POST_UPDATE_KERNEL,
UNFREEZE_TO_RUN,
POST_RUN,
KUP_HOOK_MAX,
};
+#define hi_vram_kalloc(name, size) 0
+#define hi_vram_kfree(vaddr, name, size)
+#define get_use_vram_flag(void) 0
+#define vram_get_kexec_flag(void) 0
+#define hi_vram_get_gfp_vram(void) 0
+
#endif /* VRAM_COMMON_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
similarity index 79%
rename from drivers/net/ethernet/huawei/hinic3/mag_cmd.h
rename to drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
index 9649503..e77d7d5 100644
--- a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
@@ -9,6 +9,7 @@
/* serdes cmd struct define */
#define CMD_ARRAY_BUF_SIZE 64
#define SERDES_CMD_DATA_BUF_SIZE 512
+#define RATE_MBPS_TO_GBPS 1000
struct serdes_in_info {
u32 chip_id : 16;
u32 macro_id : 16;
@@ -127,6 +128,7 @@ enum mag_cmd_cnt_type {
MAG_RX_PCS_E_BLK_CNT = 5,
MAG_RX_PCS_DEC_ERR_BLK_CNT = 6,
MAG_RX_PCS_LANE_BIP_ERR_CNT = 7,
+ MAG_RX_RSFEC_ERR_CW_CNT = 8,
MAG_CNT_NUM
};
@@ -208,7 +210,9 @@ struct mag_cmd_get_port_info {
u32 supported_mode;
u32 advertised_mode;
- u8 rsvd2[8];
+ u32 supported_fec_mode;
+ u16 bond_speed;
+ u8 rsvd2[2];
};
#define MAG_CMD_OPCODE_GET 0
@@ -330,8 +334,8 @@ struct mag_cmd_cfg_fec_mode {
u8 port_id;
u8 opcode; /* 0:get fec mode 1:set fec mode */
- u8 fec;
- u8 rsvd0;
+ u8 advertised_fec;
+ u8 supported_fec;
};
/* speed */
@@ -641,7 +645,7 @@ struct mag_cmd_event_port_info {
u32 cable_length; /* 1/3/5m */
u8 cable_temp; /* temp */
u8 max_speed; /* Maximum rate of an optical module */
- u8 sfp_type; /* sfp/qsfp */
+ u8 sfp_type; /* sfp/qsfp/dsfp */
u8 rsvd1;
u32 power[4]; /* Optical Power */
@@ -678,6 +682,10 @@ struct mag_cmd_event_port_info {
u8 rsvd3[360];
};
+struct mag_cmd_rsfec_stats {
+ u32 rx_err_lane_phy;
+};
+
struct mag_cmd_port_stats {
u64 mac_tx_fragment_pkt_num;
u64 mac_tx_undersize_pkt_num;
@@ -913,10 +921,223 @@ struct mag_cmd_sfp_temp_in_info {
};
struct mag_cmd_sfp_temp_out_info {
- struct mgmt_msg_head head; /* 8B */
- s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
- s32 max_temp; /* Chip optical module threshold */
- s32 min_temp; /* Chip optical module threshold */
+ struct mgmt_msg_head head; /* 8B */
+ s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
+ s32 max_temp; /* Chip optical module threshold */
+ s32 min_temp; /* Chip optical module threshold */
+};
+
+#define XSFP_CMIS_PARSE_PAGE_NUM 6
+#define XSFP_CMIS_INFO_MAX_SIZE 1536
+#define QSFP_CMIS_PAGE_SIZE 128
+#define QSFP_CMIS_MAX_CHANNEL_NUM 0x8
+
+/* Lower: Control and Essentials, Upper: Administrative Information */
+#define QSFP_CMIS_PAGE_00H 0x00
+/* Advertising */
+#define QSFP_CMIS_PAGE_01H 0x01
+/* Module and lane Thresholds */
+#define QSFP_CMIS_PAGE_02H 0x02
+/* User EEPROM */
+#define QSFP_CMIS_PAGE_03H 0x03
+/* Laser Capabilities Advertising (Page 04h, Optional) */
+#define QSFP_CMIS_PAGE_04H 0x04
+#define QSFP_CMIS_PAGE_05H 0x05
+/* Lane and Data Path Control */
+#define QSFP_CMIS_PAGE_10H 0x10
+/* Lane Status */
+#define QSFP_CMIS_PAGE_11H 0x11
+#define QSFP_CMIS_PAGE_12H 0x12
+
+#define MGMT_TLV_U8_SIZE 1
+#define MGMT_TLV_U16_SIZE 2
+#define MGMT_TLV_U32_SIZE 4
+
+#define MGMT_TLV_GET_U8(addr) (*((u8 *)(void *)(addr)))
+#define MGMT_TLV_SET_U8(addr, value) \
+ ((*((u8 *)(void *)(addr))) = ((u8)(value)))
+
+#define MGMT_TLV_GET_U16(addr) (*((u16 *)(void *)(addr)))
+#define MGMT_TLV_SET_U16(addr, value) \
+ ((*((u16 *)(void *)(addr))) = ((u16)(value)))
+
+#define MGMT_TLV_GET_U32(addr) (*((u32 *)(void *)(addr)))
+#define MGMT_TLV_SET_U32(addr, value) \
+ ((*((u32 *)(void *)(addr))) = ((u32)(value)))
+
+#define MGMT_TLV_TYPE_END 0xFFFF
+
+enum mag_xsfp_type {
+ MAG_XSFP_TYPE_PAGE = 0x01,
+ MAG_XSFP_TYPE_WIRE_TYPE = 0x02,
+ MAG_XSFP_TYPE_END = MGMT_TLV_TYPE_END
+};
+
+struct qsfp_cmis_lower_page_00_s {
+ u8 resv0[14];
+ u8 temperature_msb;
+ u8 temperature_lsb;
+ u8 volt_supply[2];
+ u8 resv1[67];
+ u8 media_type;
+ u8 electrical_interface_id;
+ u8 media_interface_id;
+ u8 lane_count;
+ u8 resv2[39];
+};
+
+struct qsfp_cmis_upper_page_00_s {
+ u8 identifier;
+ u8 vendor_name[16];
+ u8 vendor_oui[3];
+ u8 vendor_pn[16];
+ u8 vendor_rev[2];
+ u8 vendor_sn[16];
+ u8 date_code[8];
+ u8 clei_code[10];
+ u8 power_character[2];
+ u8 cable_len;
+ u8 connector;
+ u8 copper_cable_attenuation[6];
+ u8 near_end_implementation;
+ u8 far_end_config;
+ u8 media_technology;
+ u8 resv0[43];
+};
+
+struct qsfp_cmis_upper_page_01_s {
+ u8 firmware_rev[2];
+ u8 hardware_rev[2];
+ u8 smf_len_km;
+ u8 om5_len;
+ u8 om4_len;
+ u8 om3_len;
+ u8 om2_len;
+ u8 resv0;
+ u8 wavelength[2];
+ u8 wavelength_tolerance[2];
+ u8 pages_implement;
+ u8 resv1[16];
+ u8 monitor_implement[2];
+ u8 resv2[95];
+};
+
+struct qsfp_cmis_upper_page_02_s {
+ u8 temperature_high_alarm[2];
+ u8 temperature_low_alarm[2];
+ u8 temperature_high_warn[2];
+ u8 temperature_low_warn[2];
+ u8 volt_high_alarm[2];
+ u8 volt_low_alarm[2];
+ u8 volt_high_warn[2];
+ u8 volt_low_warn[2];
+ u8 resv0[32];
+ u8 tx_power_high_alarm[2];
+ u8 tx_power_low_alarm[2];
+ u8 tx_power_high_warn[2];
+ u8 tx_power_low_warn[2];
+ u8 tx_bias_high_alarm[2];
+ u8 tx_bias_low_alarm[2];
+ u8 tx_bias_high_warn[2];
+ u8 tx_bias_low_warn[2];
+ u8 rx_power_high_alarm[2];
+ u8 rx_power_low_alarm[2];
+ u8 rx_power_high_warn[2];
+ u8 rx_power_low_warn[2];
+ u8 resv1[56];
+};
+
+struct qsfp_cmis_upper_page_03_s {
+ u8 resv0[QSFP_CMIS_PAGE_SIZE]; /* Reg 128-255: Upper Memory: Page 03H */
+};
+
+struct qsfp_cmis_upper_page_10_s {
+ u8 resv0[2]; /* Reg 128-129: Upper Memory: Page 10H */
+ u8 tx_disable; /* Reg 130: Tx disable, 0b=enabled, 1b=disabled */
+ u8 resv1[125]; /* Reg 131-255 */
+};
+
+struct qsfp_cmis_upper_page_11_s {
+ u8 resv0[7];
+ u8 tx_fault;
+ u8 tx_los;
+ u8 resv1[10];
+ u8 rx_los;
+ u8 resv2[6];
+ u8 tx_power[16];
+ u8 tx_bias[16];
+ u8 rx_power[16];
+ u8 resv3[54];
+};
+
+struct qsfp_cmis_info_s {
+ struct qsfp_cmis_lower_page_00_s lower_page_00;
+ struct qsfp_cmis_upper_page_00_s upper_page_00;
+ struct qsfp_cmis_upper_page_01_s upper_page_01;
+ struct qsfp_cmis_upper_page_02_s upper_page_02;
+ struct qsfp_cmis_upper_page_10_s upper_page_10;
+ struct qsfp_cmis_upper_page_11_s upper_page_11;
+};
+
+struct qsfp_cmis_comm_power_s {
+ u32 chl_power[QSFP_CMIS_MAX_CHANNEL_NUM];
+};
+
+struct qsfp_cmis_wire_info_s {
+ struct qsfp_cmis_comm_power_s rx_power;
+ u8 rx_los;
+ u8 resv0[3];
+};
+
+struct mgmt_tlv_info {
+ u16 type;
+ u16 length;
+ u8 value[];
+};
+
+struct mag_cmd_set_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 tlv_buf[];
+};
+
+struct mag_cmd_set_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+};
+
+struct mag_cmd_get_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd;
+ u16 rsp_buf_len;
+};
+
+struct mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[];
+};
+
+
+struct parse_tlv_info {
+ u8 tlv_page_info[XSFP_CMIS_INFO_MAX_SIZE + 1];
+ u32 tlv_page_info_len;
+ u32 tlv_page_num[XSFP_CMIS_PARSE_PAGE_NUM];
+ u32 wire_type;
+ u8 id;
+};
+
+struct drv_mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[XSFP_CMIS_INFO_MAX_SIZE];
};
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h b/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
deleted file mode 100644
index 257bf67..0000000
--- a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : mgmt_msg_base.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef MGMT_MSG_BASE_H
-#define MGMT_MSG_BASE_H
-
-#define MGMT_MSG_CMD_OP_SET 1
-#define MGMT_MSG_CMD_OP_GET 0
-
-#define MGMT_MSG_CMD_OP_START 1
-#define MGMT_MSG_CMD_OP_STOP 0
-
-struct mgmt_msg_head {
- u8 status;
- u8 version;
- u8 rsvd0[6];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
deleted file mode 100644
index 9fb4232..0000000
--- a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2001-2021, Huawei Tech. Co., Ltd.
- * File Name : nic_cfg_comm.h
- * Version : Initial Draft
- * Description : nic config common header file
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef NIC_CFG_COMM_H
-#define NIC_CFG_COMM_H
-
-/* rss */
-#define HINIC3_RSS_TYPE_VALID_SHIFT 23
-#define HINIC3_RSS_TYPE_TCP_IPV6_EXT_SHIFT 24
-#define HINIC3_RSS_TYPE_IPV6_EXT_SHIFT 25
-#define HINIC3_RSS_TYPE_TCP_IPV6_SHIFT 26
-#define HINIC3_RSS_TYPE_IPV6_SHIFT 27
-#define HINIC3_RSS_TYPE_TCP_IPV4_SHIFT 28
-#define HINIC3_RSS_TYPE_IPV4_SHIFT 29
-#define HINIC3_RSS_TYPE_UDP_IPV6_SHIFT 30
-#define HINIC3_RSS_TYPE_UDP_IPV4_SHIFT 31
-
-#define HINIC3_RSS_TYPE_SET(val, member) (((u32)(val) & 0x1) << HINIC3_RSS_TYPE_##member##_SHIFT)
-#define HINIC3_RSS_TYPE_GET(val, member) (((u32)(val) >> HINIC3_RSS_TYPE_##member##_SHIFT) & 0x1)
-
-enum nic_rss_hash_type {
- NIC_RSS_HASH_TYPE_XOR = 0,
- NIC_RSS_HASH_TYPE_TOEP,
-
- NIC_RSS_HASH_TYPE_MAX /* MUST BE THE LAST ONE */
-};
-
-#define NIC_RSS_INDIR_SIZE 256
-#define NIC_RSS_KEY_SIZE 40
-
-/* *
- * Definition of the NIC receiving mode
- */
-#define NIC_RX_MODE_UC 0x01
-#define NIC_RX_MODE_MC 0x02
-#define NIC_RX_MODE_BC 0x04
-#define NIC_RX_MODE_MC_ALL 0x08
-#define NIC_RX_MODE_PROMISC 0x10
-
-/* IEEE 802.1Qaz std */
-#define NIC_DCB_COS_MAX 0x8
-#define NIC_DCB_UP_MAX 0x8
-#define NIC_DCB_TC_MAX 0x8
-#define NIC_DCB_PG_MAX 0x8
-#define NIC_DCB_TSA_SP 0x0
-#define NIC_DCB_TSA_CBS 0x1 /* hi1822 do NOT support */
-#define NIC_DCB_TSA_ETS 0x2
-#define NIC_DCB_DSCP_NUM 0x8
-#define NIC_DCB_IP_PRI_MAX 0x40
-
-#define NIC_DCB_PRIO_DWRR 0x0
-#define NIC_DCB_PRIO_STRICT 0x1
-
-#define NIC_DCB_MAX_PFC_NUM 0x4
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
similarity index 77%
rename from drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
rename to drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
index 31e224a..8e0fa89 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
- * File Name : hinic3_comm_cmd.h
+ * File Name : nic_mpu_cmd.h
* Version : Initial Draft
* Created : 2019/4/25
* Last Modified :
@@ -9,8 +9,8 @@
* Function List :
*/
-#ifndef HINIC3_NIC_CMD_H
-#define HINIC3_NIC_CMD_H
+#ifndef NIC_MPU_CMD_H
+#define NIC_MPU_CMD_H
/* Commands between NIC to MPU
*/
@@ -33,8 +33,9 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_CFG_LOCAL_LRO_STATE,
HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
+ HINIC3_NIC_CMD_SET_FUNC_ER_FWD_ID,
- /* MAC & VLAN CFG */
+ /** MAC & VLAN CFG & VXLAN CFG */
HINIC3_NIC_CMD_GET_MAC = 20,
HINIC3_NIC_CMD_SET_MAC,
HINIC3_NIC_CMD_DEL_MAC,
@@ -45,6 +46,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_VLAN_FILTER_EN,
HINIC3_NIC_CMD_SET_RX_VLAN_OFFLOAD,
HINIC3_NIC_CMD_SMAC_CHECK_STATE,
+ HINIC3_NIC_CMD_OUTBAND_SET_FUNC_VLAN,
+
+ HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+ HINIC3_NIC_CMD_RX_RATE_CFG,
+ HINIC3_NIC_CMD_WR_ORDERING_CFG,
/* SR-IOV */
HINIC3_NIC_CMD_CFG_VF_VLAN = 40,
@@ -61,6 +67,7 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC,
/* IP checksum error packets, enable rss quadruple hash */
HINIC3_NIC_CMD_IPCS_ERR_RSS_ENABLE_OP = 66,
+ HINIC3_NIC_CMD_GTP_INNER_PARSE_STATUS,
/* PPA/FDIR */
HINIC3_NIC_CMD_ADD_TC_FLOW = 80,
@@ -76,6 +83,10 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_CFG_PPA_FLUSH,
HINIC3_NIC_CMD_SET_FDIR_STATUS,
HINIC3_NIC_CMD_GET_PPA_COUNTER,
+ HINIC3_NIC_CMD_SET_FUNC_FLOW_BIFUR_ENABLE,
+ HINIC3_NIC_CMD_SET_BOND_MASK,
+ HINIC3_NIC_CMD_GET_BLOCK_TC_FLOWS,
+ HINIC3_NIC_CMD_GET_BOND_MASK,
/* PORT CFG */
HINIC3_NIC_CMD_SET_PORT_ENABLE = 100,
@@ -94,6 +105,8 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_QOS_PORT_CFG,
HINIC3_NIC_CMD_QOS_MAP_CFG,
HINIC3_NIC_CMD_FORCE_PKT_DROP,
+ HINIC3_NIC_CMD_CFG_TX_PROMISC_SKIP = 114,
+ HINIC3_NIC_CMD_SET_PORT_FLOW_BIFUR_ENABLE = 117,
HINIC3_NIC_CMD_TX_PAUSE_EXCP_NOTICE = 118,
HINIC3_NIC_CMD_INQUIRT_PAUSE_CFG = 119,
@@ -116,6 +129,10 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_UCAPTURE_OPT = 160, /* TODO: move to roce */
HINIC3_NIC_CMD_SET_VHD_CFG,
+ /* OUT OF BAND */
+ HINIC3_NIC_CMD_GET_OUTBAND_CFG = 170,
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+
/* TODO: move to HILINK */
HINIC3_NIC_CMD_GET_PORT_STAT = 200,
HINIC3_NIC_CMD_CLEAN_PORT_STAT,
@@ -136,24 +153,22 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_LINK_ERR_EVENT,
HINIC3_NIC_CMD_SET_LED_STATUS,
- HINIC3_NIC_CMD_MAX = 256,
-};
+ /* mig */
+ HINIC3_NIC_CMD_MIG_SET_CEQ_CTRL = 230,
+ HINIC3_NIC_CMD_MIG_CFG_MSIX_INFO,
+ HINIC3_NIC_CMD_MIG_CFG_FUNC_VAT_TBL,
+ HINIC3_NIC_CMD_MIG_GET_VF_INFO,
+ HINIC3_NIC_CMD_MIG_CHK_MBX_EMPTY,
+ HINIC3_NIC_CMD_MIG_SET_VPORT_ENABLE,
+ HINIC3_NIC_CMD_MIG_CFG_SQ_CI,
+ HINIC3_NIC_CMD_MIG_CFG_RSS_TBL,
+ HINIC3_NIC_CMD_MIG_CFG_MAC_TBL,
+ HINIC3_NIC_CMD_MIG_TMP_SET_CMDQ_CTX,
+
+ HINIC3_OSHR_CMD_ACTIVE_FUNCTION = 240,
+ HINIC3_NIC_CMD_GET_RQ_INFO = 241,
-/* NIC CMDQ MODE */
-enum hinic3_ucode_cmd {
- HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
- HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
- HINIC3_UCODE_CMD_ARM_SQ,
- HINIC3_UCODE_CMD_ARM_RQ,
- HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_SET_IQ_ENABLE,
- HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
- HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
- HINIC3_UCODE_CMD_PPA_HASH_TABLE,
- HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_NIC_CMD_MAX = 256,
};
-#endif /* HINIC3_NIC_CMD_H */
+#endif /* NIC_MPU_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
new file mode 100644
index 0000000..ee6bf20
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
@@ -0,0 +1,1420 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+
+#ifndef NIC_MPU_CMD_DEFS_H
+#define NIC_MPU_CMD_DEFS_H
+
+#include "nic_cfg_comm.h"
+#include "mpu_cmd_base_defs.h"
+
+#ifndef ETH_ALEN
+#define ETH_ALEN 6
+#endif
+
+#define HINIC3_CMD_OP_SET 1
+#define HINIC3_CMD_OP_GET 0
+
+#define HINIC3_CMD_OP_ADD 1
+#define HINIC3_CMD_OP_DEL 0
+
+#define NIC_TCAM_BLOCK_LARGE_NUM 256
+#define NIC_TCAM_BLOCK_LARGE_SIZE 16
+
+#define TRAFFIC_BIFUR_MODEL_TYPE 2
+
+#define NIC_TCAM_FLOW_BIFUR_FLAG (1 << 0)
+
+#ifndef BIT
+#define BIT(n) (1UL << (n))
+#endif
+
+enum nic_feature_cap {
+ NIC_F_CSUM = BIT(0),
+ NIC_F_SCTP_CRC = BIT(1),
+ NIC_F_TSO = BIT(2),
+ NIC_F_LRO = BIT(3),
+ NIC_F_UFO = BIT(4),
+ NIC_F_RSS = BIT(5),
+ NIC_F_RX_VLAN_FILTER = BIT(6),
+ NIC_F_RX_VLAN_STRIP = BIT(7),
+ NIC_F_TX_VLAN_INSERT = BIT(8),
+ NIC_F_VXLAN_OFFLOAD = BIT(9),
+ NIC_F_IPSEC_OFFLOAD = BIT(10),
+ NIC_F_FDIR = BIT(11),
+ NIC_F_PROMISC = BIT(12),
+ NIC_F_ALLMULTI = BIT(13),
+ NIC_F_XSFP_REPORT = BIT(14),
+ NIC_F_VF_MAC = BIT(15),
+ NIC_F_RATE_LIMIT = BIT(16),
+ NIC_F_RXQ_RECOVERY = BIT(17),
+};
+
+#define NIC_F_ALL_MASK 0x3FFFF /* 使能所有属性 */
+
+struct hinic3_mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+#define NIC_MAX_FEATURE_QWORD 4
+struct hinic3_cmd_feature_nego {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 1: set, 0: get */
+ u8 rsvd;
+ u64 s_feature[NIC_MAX_FEATURE_QWORD];
+};
+
+struct hinic3_port_mac_set {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 rsvd1;
+ u8 mac[ETH_ALEN];
+};
+
+struct hinic3_port_mac_update {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 rsvd1;
+ u8 old_mac[ETH_ALEN];
+ u16 rsvd2;
+ u8 new_mac[ETH_ALEN];
+};
+
+struct hinic3_vport_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 state; /* 0--disable, 1--enable */
+ u8 rsvd2[3];
+};
+
+struct hinic3_port_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 state; /* 0--disable, 1--enable */
+ u8 rsvd2[3];
+};
+
+#define HINIC3_SET_PORT_CAR_PROFILE 0
+#define HINIC3_SET_PORT_CAR_STATE 1
+#define HINIC3_GET_PORT_CAR_LIMIT_SPEED 2
+
+struct hinic3_port_car_info {
+ u32 cir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
+ u32 xir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
+ u32 cbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
+ u32 xbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
+};
+
+struct hinic3_cmd_set_port_car {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode; /* 0--set car profile, 1--set car state */
+ u8 state; /* 0--disable, 1--enable */
+ u8 level;
+
+ struct hinic3_port_car_info car;
+};
+
+struct hinic3_cmd_clear_qp_resource {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_cmd_cache_out_qp_resource {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_port_stats_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_vport_stats {
+ u64 tx_unicast_pkts_vport;
+ u64 tx_unicast_bytes_vport;
+ u64 tx_multicast_pkts_vport;
+ u64 tx_multicast_bytes_vport;
+ u64 tx_broadcast_pkts_vport;
+ u64 tx_broadcast_bytes_vport;
+
+ u64 rx_unicast_pkts_vport;
+ u64 rx_unicast_bytes_vport;
+ u64 rx_multicast_pkts_vport;
+ u64 rx_multicast_bytes_vport;
+ u64 rx_broadcast_pkts_vport;
+ u64 rx_broadcast_bytes_vport;
+
+ u64 tx_discard_vport;
+ u64 rx_discard_vport;
+ u64 tx_err_vport;
+ u64 rx_err_vport;
+};
+
+struct hinic3_phy_fpga_port_stats {
+ u64 mac_rx_total_octs_port;
+ u64 mac_tx_total_octs_port;
+ u64 mac_rx_under_frame_pkts_port;
+ u64 mac_rx_frag_pkts_port;
+ u64 mac_rx_64_oct_pkts_port;
+ u64 mac_rx_127_oct_pkts_port;
+ u64 mac_rx_255_oct_pkts_port;
+ u64 mac_rx_511_oct_pkts_port;
+ u64 mac_rx_1023_oct_pkts_port;
+ u64 mac_rx_max_oct_pkts_port;
+ u64 mac_rx_over_oct_pkts_port;
+ u64 mac_tx_64_oct_pkts_port;
+ u64 mac_tx_127_oct_pkts_port;
+ u64 mac_tx_255_oct_pkts_port;
+ u64 mac_tx_511_oct_pkts_port;
+ u64 mac_tx_1023_oct_pkts_port;
+ u64 mac_tx_max_oct_pkts_port;
+ u64 mac_tx_over_oct_pkts_port;
+ u64 mac_rx_good_pkts_port;
+ u64 mac_rx_crc_error_pkts_port;
+ u64 mac_rx_broadcast_ok_port;
+ u64 mac_rx_multicast_ok_port;
+ u64 mac_rx_mac_frame_ok_port;
+ u64 mac_rx_length_err_pkts_port;
+ u64 mac_rx_vlan_pkts_port;
+ u64 mac_rx_pause_pkts_port;
+ u64 mac_rx_unknown_mac_frame_port;
+ u64 mac_tx_good_pkts_port;
+ u64 mac_tx_broadcast_ok_port;
+ u64 mac_tx_multicast_ok_port;
+ u64 mac_tx_underrun_pkts_port;
+ u64 mac_tx_mac_frame_ok_port;
+ u64 mac_tx_vlan_pkts_port;
+ u64 mac_tx_pause_pkts_port;
+};
+
+struct hinic3_port_stats {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ struct hinic3_phy_fpga_port_stats stats;
+};
+
+struct hinic3_cmd_vport_stats {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u32 stats_size;
+ u32 rsvd1;
+ struct hinic3_vport_stats stats;
+ u64 rsvd2[6];
+};
+
+struct hinic3_cmd_qpn {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 base_qpn;
+};
+
+enum hinic3_func_tbl_cfg_bitmap {
+ FUNC_CFG_INIT,
+ FUNC_CFG_RX_BUF_SIZE,
+ FUNC_CFG_MTU,
+};
+
+struct hinic3_func_tbl_cfg {
+ u16 rx_wqe_buf_size;
+ u16 mtu;
+ u32 rsvd[9];
+};
+
+struct hinic3_cmd_set_func_tbl {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd;
+
+ u32 cfg_bitmap;
+ struct hinic3_func_tbl_cfg tbl_cfg;
+};
+
+struct hinic3_cmd_cons_idx_attr {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_idx;
+ u8 dma_attr_off;
+ u8 pending_limit;
+ u8 coalescing_time;
+ u8 intr_en;
+ u16 intr_idx;
+ u32 l2nic_sqn;
+ u32 rsvd;
+ u64 ci_addr;
+};
+
+union sm_tbl_args {
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } mac_table_arg;
+ struct {
+ u32 er_id;
+ u32 vlan_id;
+ } vlan_elb_table_arg;
+ struct {
+ u32 func_id;
+ } vlan_filter_arg;
+ struct {
+ u32 mc_id;
+ } mc_elb_arg;
+ struct {
+ u32 func_id;
+ } func_tbl_arg;
+ struct {
+ u32 port_id;
+ } port_tbl_arg;
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } fdir_io_table_arg;
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } flexq_table_arg;
+ u32 args[4];
+};
+
+#define DFX_SM_TBL_BUF_MAX (768)
+
+struct nic_cmd_dfx_sm_table {
+ struct hinic3_mgmt_msg_head msg_head;
+ u32 tbl_type;
+ union sm_tbl_args args;
+ u8 tbl_buf[DFX_SM_TBL_BUF_MAX];
+};
+
+struct hinic3_cmd_vlan_offload {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 vlan_offload;
+ u8 rsvd1[5];
+};
+
+/* ucode capture cfg info */
+struct nic_cmd_capture_info {
+ struct hinic3_mgmt_msg_head msg_head;
+ u32 op_type;
+ u32 func_port;
+ u32 is_en_trx;
+ u32 offset_cos;
+ u32 data_vlan;
+};
+
+struct hinic3_cmd_lro_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u8 lro_ipv4_en;
+ u8 lro_ipv6_en;
+ u8 lro_max_pkt_len; /* unit is 1K */
+ u8 resv2[13];
+};
+
+struct hinic3_cmd_lro_timer {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 opcode; /* 1: set timer value, 0: get timer value */
+ u8 rsvd1;
+ u16 rsvd2;
+ u32 timer;
+};
+
+struct hinic3_cmd_local_lro_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 state; /* 0: disable, 1: enable */
+};
+
+struct hinic3_cmd_gtp_inner_parse_status {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 status; /* 0: disable, 1: enable */
+};
+
+struct hinic3_cmd_vf_vlan_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u16 vlan_id;
+ u8 qos;
+ u8 rsvd2[5];
+};
+
+struct hinic3_cmd_spoofchk_set {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 state;
+ u8 rsvd1;
+};
+
+struct hinic3_cmd_tx_rate_cfg {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 rsvd1;
+ u8 direct;
+ u32 min_rate;
+ u32 max_rate;
+ u8 rsvd2[8];
+};
+
+struct hinic3_cmd_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+ u8 port_type;
+ u8 autoneg_cap;
+ u8 autoneg_state;
+ u8 duplex;
+ u8 speed;
+ u8 fec;
+ u16 rsvd2;
+ u32 rsvd3[4];
+};
+
+struct hinic3_cmd_register_vf {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 op_register; /* 0 - unregister, 1 - register */
+ u8 rsvd1[3];
+ u32 support_extra_feature;
+ u8 rsvd2[32];
+};
+
+struct hinic3_cmd_link_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 state;
+ u16 rsvd1;
+};
+
+struct hinic3_cmd_vlan_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 outband_defvid_flag;
+ u16 vlan_id;
+ u8 blacklist_flag;
+ u8 rsvd2;
+};
+
+#define VLAN_BLACKLIST_ENABLE 1
+#define VLAN_BLACKLIST_DISABLE 0
+
+struct hinic3_cmd_vxlan_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 cfg_mode;
+ u16 vxlan_port;
+ u16 rsvd2;
+};
+
+/* set vlan filter */
+struct hinic3_cmd_set_vlan_filter {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 resvd[2];
+ u32 vlan_filter_ctrl; /* bit0:vlan filter en; bit1:broadcast_filter_en */
+};
+
+struct hinic3_cmd_link_ksettings_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+
+ u32 valid_bitmap;
+ u8 speed; /* enum nic_speed_level */
+ u8 autoneg; /* 0 - off, 1 - on */
+ u8 fec; /* 0 - RSFEC, 1 - BASEFEC, 2 - NOFEC */
+ u8 rsvd2[21]; /* reserved for duplex, port, etc. */
+};
+
+struct mpu_lt_info {
+ u8 node;
+ u8 inst;
+ u8 entry_size;
+ u8 rsvd;
+ u32 lt_index;
+ u32 offset;
+ u32 len;
+};
+
+struct nic_mpu_lt_opera {
+ struct hinic3_mgmt_msg_head msg_head;
+ struct mpu_lt_info net_lt_cmd;
+ u8 data[100];
+};
+
+struct hinic3_force_pkt_drop {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port;
+ u8 rsvd1[3];
+};
+
+struct hinic3_rx_mode_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u32 rx_mode;
+};
+
+/* rss */
+struct hinic3_rss_context_table {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u32 context;
+};
+
+struct hinic3_cmd_rss_engine_type {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 hash_engine;
+ u8 rsvd1[4];
+};
+
+struct hinic3_cmd_rss_hash_key {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u8 key[NIC_RSS_KEY_SIZE];
+};
+
+struct hinic3_rss_indir_table {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 indir[NIC_RSS_INDIR_SIZE];
+};
+
+#define NIC_RSS_CMD_TEMP_ALLOC 0x01
+#define NIC_RSS_CMD_TEMP_FREE 0x02
+
+struct hinic3_rss_template_mgmt {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 cmd;
+ u8 template_id;
+ u8 rsvd1[4];
+};
+
+struct hinic3_cmd_rss_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 rss_en;
+ u8 rq_priority_number;
+ u8 prio_tc[NIC_DCB_COS_MAX];
+ u16 num_qps;
+ u16 rsvd1;
+};
+
+struct hinic3_dcb_state {
+ u8 dcb_on;
+ u8 default_cos;
+ u8 trust;
+ u8 rsvd1;
+ u8 pcp2cos[NIC_DCB_UP_MAX];
+ u8 dscp2cos[64];
+ u32 rsvd2[7];
+};
+
+struct hinic3_cmd_vf_dcb_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ struct hinic3_dcb_state state;
+};
+
+struct hinic3_up_ets_cfg { /* delet */
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+
+ u8 cos_tc[NIC_DCB_COS_MAX];
+ u8 tc_bw[NIC_DCB_TC_MAX];
+ u8 cos_prio[NIC_DCB_COS_MAX];
+ u8 cos_bw[NIC_DCB_COS_MAX];
+ u8 tc_prio[NIC_DCB_TC_MAX];
+};
+
+#define CMD_QOS_ETS_COS_TC BIT(0)
+#define CMD_QOS_ETS_TC_BW BIT(1)
+#define CMD_QOS_ETS_COS_PRIO BIT(2)
+#define CMD_QOS_ETS_COS_BW BIT(3)
+#define CMD_QOS_ETS_TC_PRIO BIT(4)
+#define CMD_QOS_ETS_TC_RATELIMIT BIT(5)
+
+struct hinic3_cmd_ets_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 1 - set, 0 - get */
+ /* bit0 - cos_tc, bit1 - tc_bw, bit2 - cos_prio, bit3 - cos_bw, bit4 - tc_prio */
+ u8 cfg_bitmap;
+ u8 rsvd;
+
+ u8 cos_tc[NIC_DCB_COS_MAX];
+ u8 tc_bw[NIC_DCB_TC_MAX];
+ u8 cos_prio[NIC_DCB_COS_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 cos_bw[NIC_DCB_COS_MAX];
+ u8 tc_prio[NIC_DCB_TC_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 rate_limit[NIC_DCB_TC_MAX];
+};
+
+struct hinic3_cmd_set_dcb_state {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 op_code; /* 0 - get dcb state, 1 - set dcb state */
+ u8 state; /* 0 - disable, 1 - enable dcb */
+ u8 port_state; /* 0 - disable, 1 - enable dcb */
+ u8 rsvd[7];
+};
+
+#define PFC_BIT_MAP_NUM 8
+struct hinic3_cmd_set_pfc {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 0:get 1: set pfc_en 2: set pfc_bitmap 3: set all */
+ u8 pfc_en; /* pfc_en 和 pfc_bitmap 必须同时设置 */
+ u8 pfc_bitmap;
+ u8 rsvd[4];
+};
+
+#define CMD_QOS_PORT_TRUST BIT(0)
+#define CMD_QOS_PORT_DFT_COS BIT(1)
+struct hinic3_cmd_qos_port_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 0 - get, 1 - set */
+ u8 cfg_bitmap; /* bit0 - trust, bit1 - dft_cos */
+ u8 rsvd0;
+
+ u8 trust;
+ u8 dft_cos;
+ u8 rsvd1[18];
+};
+
+#define MAP_COS_MAX_NUM 8
+#define CMD_QOS_MAP_PCP2COS BIT(0)
+#define CMD_QOS_MAP_DSCP2COS BIT(1)
+struct hinic3_cmd_qos_map_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 op_code;
+ u8 cfg_bitmap; /* bit0 - pcp2cos, bit1 - dscp2cos */
+ u16 rsvd0;
+
+ u8 pcp2cos[8]; /* 8 must be configured together */
+ /* If the dscp2cos parameter is set to 0xFF, the MPU ignores the DSCP priority,
+ * Multiple mappings between DSCP values and CoS values can be configured at a time.
+ */
+ u8 dscp2cos[64];
+ u32 rsvd1[4];
+};
+
+struct hinic3_cos_up_map {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 cos_valid_mask; /* every bit indicate index of map is valid 1 or not 0 */
+ u16 rsvd1;
+
+ /* user priority in cos(index:cos, value: up pri) */
+ u8 map[NIC_DCB_UP_MAX];
+};
+
+struct hinic3_cmd_pause_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode;
+ u16 rsvd1;
+ u8 auto_neg;
+ u8 rx_pause;
+ u8 tx_pause;
+ u8 rsvd2[5];
+};
+
+struct nic_cmd_pause_inquiry_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 valid;
+
+ u32 type; /* 1: set, 2: get */
+
+ u32 cos_id;
+
+ u32 rx_inquiry_pause_drop_pkts_en;
+ u32 rx_inquiry_pause_period_ms;
+ u32 rx_inquiry_pause_times;
+ /* rx pause Detection Threshold, Default PAUSE_FRAME_THD_10G/25G/40G/100 */
+ u32 rx_inquiry_pause_frame_thd;
+ u32 rx_inquiry_tx_total_pkts;
+
+ u32 tx_inquiry_pause_en; /* tx pause detect enable */
+ u32 tx_inquiry_pause_period_ms; /* tx pause Default Detection Period 200ms */
+ u32 tx_inquiry_pause_times; /* tx pause Default Times Period 5 */
+ u32 tx_inquiry_pause_frame_thd; /* tx pause Detection Threshold */
+ u32 tx_inquiry_rx_total_pkts;
+ u32 rsvd[3];
+};
+
+/* pfc/pause Storm TX exception reporting */
+struct nic_cmd_tx_pause_notice {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 tx_pause_except; /* 1: abnormality,0: normal */
+ u32 except_level;
+ u32 rsvd;
+};
+
+#define HINIC3_CMD_OP_FREE 0
+#define HINIC3_CMD_OP_ALLOC 1
+
+struct hinic3_cmd_cfg_qps {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 1: alloc qp, 0: free qp */
+ u8 rsvd1;
+ u16 num_qps;
+ u16 rsvd2;
+};
+
+struct hinic3_cmd_led_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port;
+ u8 type;
+ u8 mode;
+ u8 rsvd1;
+};
+
+struct hinic3_cmd_port_loopback {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode;
+ u8 mode;
+ u8 en;
+ u32 rsvd1[2];
+};
+
+struct hinic3_cmd_get_light_module_abs {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 abs_status; /* 0:present, 1:absent */
+ u8 rsv[2];
+};
+
+#define STD_SFP_INFO_MAX_SIZE 640
+struct hinic3_cmd_get_std_sfp_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 wire_type;
+ u16 eeprom_len;
+ u32 rsvd;
+ u8 sfp_info[STD_SFP_INFO_MAX_SIZE];
+};
+
+struct hinic3_cable_plug_event {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 plugged; /* 0: unplugged, 1: plugged */
+ u8 port_id;
+};
+
+struct nic_cmd_mac_info {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 valid_bitmap;
+ u16 rsvd;
+
+ u8 host_id[32];
+ u8 port_id[32];
+ u8 mac_addr[192];
+};
+
+struct nic_cmd_set_tcam_enable {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 tcam_enable;
+ u8 rsvd1;
+ u32 rsvd2;
+};
+
+struct nic_cmd_set_fdir_status {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 pkt_type_en;
+ u8 pkt_type;
+ u8 qid;
+ u8 rsvd2;
+};
+
+#define HINIC3_TCAM_BLOCK_ENABLE 1
+#define HINIC3_TCAM_BLOCK_DISABLE 0
+#define HINIC3_MAX_TCAM_RULES_NUM 4096
+
+/* tcam block type, according to tcam block size */
+enum {
+ NIC_TCAM_BLOCK_TYPE_LARGE = 0, /* block_size: 16 */
+ NIC_TCAM_BLOCK_TYPE_SMALL, /* block_size: 0 */
+ NIC_TCAM_BLOCK_TYPE_MAX
+};
+
+/* alloc tcam block input struct */
+struct nic_cmd_ctrl_tcam_block_in {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
+ /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
+ u8 tcam_type;
+ u16 tcam_block_index;
+ /* Size of the block that the driver wants to allocate
+ * Interface returned by the UP to the driver,
+ * indicating the size of the allocated TCAM block supported by the UP
+ */
+ u16 alloc_block_num;
+};
+
+/* alloc tcam block output struct */
+struct nic_cmd_ctrl_tcam_block_out {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
+ /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
+ u8 tcam_type;
+ u16 tcam_block_index;
+ /* Size of the block that the driver wants to allocate
+ * Interface returned by the UP to the driver,
+ * indicating the size of the allocated TCAM block supported by the UP
+ */
+ u16 mpu_alloc_block_size;
+};
+
+struct nic_cmd_flush_tcam_rules {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u16 rsvd;
+};
+
+struct nic_cmd_dfx_fdir_tcam_block_table {
+ struct hinic3_mgmt_msg_head head;
+ u8 tcam_type;
+ u8 valid;
+ u16 tcam_block_index;
+ u16 use_function_id;
+ u16 rsvd;
+};
+
+struct tcam_result {
+ u32 qid;
+ u32 rsvd;
+};
+
+#define TCAM_FLOW_KEY_SIZE (44)
+
+struct tcam_key_x_y {
+ u8 x[TCAM_FLOW_KEY_SIZE];
+ u8 y[TCAM_FLOW_KEY_SIZE];
+};
+
+struct nic_tcam_cfg_rule {
+ u32 index;
+ struct tcam_result data;
+ struct tcam_key_x_y key;
+};
+
+#define TCAM_RULE_FDIR_TYPE 0
+#define TCAM_RULE_PPA_TYPE 1
+
+struct nic_cmd_fdir_add_rule {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 type;
+ u8 fdir_ext; /* 0x1: flow bifur en bit */
+ struct nic_tcam_cfg_rule rule;
+};
+
+struct nic_cmd_fdir_del_rules {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 type;
+ u8 rsvd;
+ u32 index_start;
+ u32 index_num;
+};
+
+struct nic_cmd_fdir_get_rule {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 index;
+ u8 valid;
+ u8 type;
+ u16 rsvd;
+ struct tcam_key_x_y key;
+ struct tcam_result data;
+ u64 packet_count;
+ u64 byte_count;
+};
+
+struct nic_cmd_fdir_get_block_rules {
+ struct hinic3_mgmt_msg_head head;
+ u8 tcam_block_type; // only NIC_TCAM_BLOCK_TYPE_LARGE
+ u8 tcam_table_type; // TCAM_RULE_PPA_TYPE or TCAM_RULE_FDIR_TYPE
+ u16 tcam_block_index;
+ u8 valid[NIC_TCAM_BLOCK_LARGE_SIZE];
+ struct tcam_key_x_y key[NIC_TCAM_BLOCK_LARGE_SIZE];
+ struct tcam_result data[NIC_TCAM_BLOCK_LARGE_SIZE];
+};
+
+struct hinic3_tcam_key_ipv4_mem {
+ u32 rsvd1 : 1;
+ u32 bifur_flag : 2;
+ u32 model : 1;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+ u32 sipv4_h : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+ u32 dipv4_h : 16;
+ u32 sipv4_l : 16;
+ u32 vlan_id : 15;
+ u32 vlan_flag : 1;
+ u32 dipv4_l : 16;
+ u32 rsvd3;
+ u32 dport : 16;
+ u32 rsvd4 : 16;
+ u32 rsvd5 : 16;
+ u32 sport : 16;
+ u32 outer_sipv4_h : 16;
+ u32 rsvd6 : 16;
+ u32 outer_dipv4_h : 16;
+ u32 outer_sipv4_l : 16;
+ u32 vni_h : 16;
+ u32 outer_dipv4_l : 16;
+ u32 rsvd7 : 16;
+ u32 vni_l : 16;
+};
+
+union hinic3_tag_tcam_ext_info {
+ struct {
+ u32 id : 16; /* id */
+ u32 type : 4; /* type: 0-func, 1-vmdq, 2-port, 3-rsvd, 4-trunk, 5-dp, 6-mc */
+ u32 host_id : 3;
+ u32 rss_q_num : 8; /* rss queue num */
+ u32 ext : 1;
+ } bs;
+ u32 value;
+};
+
+struct hinic3_tcam_key_ipv6_mem {
+ u32 bifur_flag : 2;
+ u32 vlan_flag : 1;
+ u32 outer_ip_type : 1;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+ u32 sipv6_key0 : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+ u32 sipv6_key2 : 16;
+ u32 sipv6_key1 : 16;
+ u32 sipv6_key4 : 16;
+ u32 sipv6_key3 : 16;
+ u32 sipv6_key6 : 16;
+ u32 sipv6_key5 : 16;
+ u32 dport : 16;
+ u32 sipv6_key7 : 16;
+ u32 dipv6_key0 : 16;
+ u32 sport : 16;
+ u32 dipv6_key2 : 16;
+ u32 dipv6_key1 : 16;
+ u32 dipv6_key4 : 16;
+ u32 dipv6_key3 : 16;
+ u32 dipv6_key6 : 16;
+ u32 dipv6_key5 : 16;
+ u32 rsvd2 : 16;
+ u32 dipv6_key7 : 16;
+};
+
+struct hinic3_tcam_key_vxlan_ipv6_mem {
+ u32 rsvd1 : 4;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+
+ u32 dipv6_key0 : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+
+ u32 dipv6_key2 : 16;
+ u32 dipv6_key1 : 16;
+
+ u32 dipv6_key4 : 16;
+ u32 dipv6_key3 : 16;
+
+ u32 dipv6_key6 : 16;
+ u32 dipv6_key5 : 16;
+
+ u32 dport : 16;
+ u32 dipv6_key7 : 16;
+
+ u32 rsvd2 : 16;
+ u32 sport : 16;
+
+ u32 outer_sipv4_h : 16;
+ u32 rsvd3 : 16;
+
+ u32 outer_dipv4_h : 16;
+ u32 outer_sipv4_l : 16;
+
+ u32 vni_h : 16;
+ u32 outer_dipv4_l : 16;
+
+ u32 rsvd4 : 16;
+ u32 vni_l : 16;
+};
+
+struct tag_tcam_key {
+ union {
+ struct hinic3_tcam_key_ipv4_mem key_info;
+ struct hinic3_tcam_key_ipv6_mem key_info_ipv6;
+ struct hinic3_tcam_key_vxlan_ipv6_mem key_info_vxlan_ipv6;
+ };
+
+ union {
+ struct hinic3_tcam_key_ipv4_mem key_mask;
+ struct hinic3_tcam_key_ipv6_mem key_mask_ipv6;
+ struct hinic3_tcam_key_vxlan_ipv6_mem key_mask_vxlan_ipv6;
+ };
+};
+
+enum {
+ PPA_TABLE_ID_CLEAN_CMD = 0,
+ PPA_TABLE_ID_ADD_CMD,
+ PPA_TABLE_ID_DEL_CMD,
+ FDIR_TABLE_ID_ADD_CMD,
+ FDIR_TABLE_ID_DEL_CMD,
+ PPA_TABEL_ID_MAX
+};
+
+struct hinic3_ppa_cfg_table_id_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u16 cmd;
+ u16 table_id;
+ u16 rsvd1;
+};
+
+struct hinic3_ppa_cfg_ppa_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 ppa_en;
+ u8 ppa_miss_drop_en;
+};
+
+struct hinic3_func_flow_bifur_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 func_id;
+ u8 flow_bifur_en;
+ u8 rsvd[5];
+};
+
+struct hinic3_port_flow_bifur_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 port_id;
+ u8 flow_bifur_en;
+ u8 flow_bifur_type; /* 0->vf bifur, 2->traffic bifur */
+ u8 rsvd[4];
+};
+
+struct hinic3_bond_mask_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 func_id;
+ u8 bond_mask;
+ u8 bond_en;
+ u8 func_valid;
+ u8 rsvd[3];
+};
+
+struct hinic3_func_er_value_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 vf_id;
+ u16 er_fwd_id;
+};
+
+#define HINIC3_TX_SET_PROMISC_SKIP 0
+#define HINIC3_TX_GET_PROMISC_SKIP 1
+
+#define HINIC3_GET_TRAFFIC_BIFUR_STATE 0
+#define HINIC3_SET_TRAFFIC_BIFUR_STATE 1
+
+struct hinic3_tx_promisc_cfg {
+ struct hinic3_mgmt_msg_head msg_head;
+ u8 port_id;
+ u8 promisc_skip_en; /* 0: disable tx promisc replication, 1: enable */
+ u8 opcode; /* 0: set, 1: get */
+ u8 rsvd1;
+};
+
+struct hinic3_ppa_cfg_mode_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u8 ppa_mode;
+ u8 qpc_func_nums;
+ u16 base_qpc_func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_ppa_flush_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u8 flush_en; /* 0 flush done, 1 in flush operation */
+ u8 rsvd1;
+};
+
+struct hinic3_ppa_fdir_query_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u32 index;
+ u32 rsvd;
+ u64 pkt_nums;
+ u64 pkt_bytes;
+};
+
+/* BIOS CONF */
+enum {
+ NIC_NVM_DATA_SET = BIT(0), /* 1-save, 0-read */
+ NIC_NVM_DATA_PXE = BIT(1),
+ NIC_NVM_DATA_VLAN = BIT(2),
+ NIC_NVM_DATA_VLAN_PRI = BIT(3),
+ NIC_NVM_DATA_VLAN_ID = BIT(4),
+ NIC_NVM_DATA_WORK_MODE = BIT(5),
+ NIC_NVM_DATA_PF_TX_SPEED_LIMIT = BIT(6),
+ NIC_NVM_DATA_GE_MODE = BIT(7),
+ NIC_NVM_DATA_AUTO_NEG = BIT(8),
+ NIC_NVM_DATA_LINK_FEC = BIT(9),
+ NIC_NVM_DATA_PF_ADAPTIVE_LINK = BIT(10),
+ NIC_NVM_DATA_SRIOV_CONTROL = BIT(11),
+ NIC_NVM_DATA_EXTEND_MODE = BIT(12),
+ NIC_NVM_DATA_LEGACY_VLAN = BIT(13),
+ NIC_NVM_DATA_LEGACY_VLAN_PRI = BIT(14),
+ NIC_NVM_DATA_LEGACY_VLAN_ID = BIT(15),
+ NIC_NVM_DATA_RESET = BIT(31),
+};
+
+#define BIOS_CFG_SIGNATURE 0x1923E518
+#define BIOS_OP_CFG_ALL(op_code_val) \
+ ((((op_code_val) >> 1) & (0xFFFFFFFF)) != 0)
+#define BIOS_OP_CFG_WRITE(op_code_val) \
+ ((((op_code_val) & NIC_NVM_DATA_SET)) != 0)
+#define BIOS_OP_CFG_PXE_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PXE) != 0)
+#define BIOS_OP_CFG_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN) != 0)
+#define BIOS_OP_CFG_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_ID) != 0)
+#define BIOS_OP_CFG_WORK_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_WORK_MODE) != 0)
+#define BIOS_OP_CFG_PF_BW(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_TX_SPEED_LIMIT) != 0)
+#define BIOS_OP_CFG_GE_SPEED(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_GE_MODE) != 0)
+#define BIOS_OP_CFG_AUTO_NEG(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_AUTO_NEG) != 0)
+#define BIOS_OP_CFG_LINK_FEC(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LINK_FEC) != 0)
+#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_ADAPTIVE_LINK) != 0)
+#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_SRIOV_CONTROL) != 0)
+#define BIOS_OP_CFG_EXTEND_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_EXTEND_MODE) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_ID) != 0)
+#define BIOS_OP_CFG_RST_DEF_SET(op_code_val) \
+ (((op_code_val) & (u32)NIC_NVM_DATA_RESET) != 0)
+
+
+#define NIC_BIOS_CFG_MAX_PF_BW 100
+
+struct nic_legacy_vlan_cfg {
+ /* Legacy mode PXE VLAN enable: 0 - disable 1 - enable */
+ u8 pxe_vlan_en : 1;
+ /* Legacy mode PXE VLAN priority: 0-7 */
+ u8 pxe_vlan_pri : 3;
+ /* Legacy mode PXE VLAN ID 1-4094 */
+ u16 pxe_vlan_id : 12;
+};
+
+/* Note: This structure must be 4-byte aligned. */
+struct nic_bios_cfg {
+ u32 signature;
+ u8 pxe_en;
+ u8 extend_mode;
+ struct nic_legacy_vlan_cfg nlvc;
+ u8 pxe_vlan_en;
+ u8 pxe_vlan_pri;
+ u16 pxe_vlan_id;
+ u32 service_mode;
+ u32 pf_tx_bw;
+ u8 speed;
+ u8 auto_neg;
+ u8 lanes;
+ u8 fec;
+ u8 auto_adapt;
+ u8 func_valid;
+ u8 func_id;
+ u8 sriov_en;
+};
+
+struct nic_cmd_bios_cfg {
+ struct hinic3_mgmt_msg_head head;
+ u32 op_code; /* Operation Code: Bit0[0: read 1:write, BIT1-6: cfg_mask */
+ struct nic_bios_cfg bios_cfg;
+};
+
+struct nic_rx_rate_bios_cfg {
+ struct mgmt_msg_head msg_head;
+
+ u32 op_code; /* Operation Code:[0:read 1:write] */
+ u8 rx_rate_limit;
+ u8 func_id;
+};
+
+struct nic_cmd_vhd_config {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 vhd_type;
+ u8 virtio_small_enable; /* 0: mergeable mode, 1: small mode */
+};
+
+/* BOND */
+struct hinic3_create_bond_info {
+ u32 bond_id;
+ u32 master_slave_port_id;
+ u32 slave_bitmap; /* bond port id bitmap */
+ u32 poll_timeout; /* Bond device link check time */
+ u32 up_delay; /* Temporarily reserved */
+ u32 down_delay; /* Temporarily reserved */
+ u32 bond_mode; /* Temporarily reserved */
+ u32 active_pf; /* bond use active pf id */
+ u32 active_port_max_num; /* Maximum number of active bond member interfaces */
+ u32 active_port_min_num; /* Minimum number of active bond member interfaces */
+ u32 xmit_hash_policy;
+ u32 default_param_flag;
+ u32 rsvd;
+};
+
+struct hinic3_cmd_create_bond {
+ struct hinic3_mgmt_msg_head head;
+ struct hinic3_create_bond_info create_bond_info;
+};
+
+struct hinic3_cmd_delete_bond {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 rsvd[2];
+};
+
+struct hinic3_open_close_bond_info {
+ u32 bond_id;
+ u32 open_close_flag; /* Bond flag. 1: open; 0: close. */
+ u32 rsvd[2];
+};
+
+struct hinic3_cmd_open_close_bond {
+ struct hinic3_mgmt_msg_head head;
+ struct hinic3_open_close_bond_info open_close_bond_info;
+};
+
+struct lacp_port_params {
+ u16 port_number;
+ u16 port_priority;
+ u16 key;
+ u16 system_priority;
+ u8 system[ETH_ALEN];
+ u8 port_state;
+ u8 rsvd;
+};
+
+struct lacp_port_info {
+ u32 selected;
+ u32 aggregator_port_id;
+
+ struct lacp_port_params actor;
+ struct lacp_port_params partner;
+
+ u64 tx_lacp_pkts;
+ u64 rx_lacp_pkts;
+ u64 rx_8023ad_drop;
+ u64 tx_8023ad_drop;
+ u64 unknown_pkt_drop;
+ u64 rx_marker_pkts;
+ u64 tx_marker_pkts;
+};
+
+struct hinic3_bond_status_info {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 bon_mmi_status;
+ u32 active_bitmap;
+ u32 port_count;
+
+ struct lacp_port_info port_info[4];
+
+ u64 success_report_cnt[4];
+ u64 fail_report_cnt[4];
+
+ u64 poll_timeout;
+ u64 fast_periodic_timeout;
+ u64 slow_periodic_timeout;
+ u64 short_timeout;
+ u64 long_timeout;
+ u64 aggregate_wait_timeout;
+ u64 tx_period_timeout;
+ u64 rx_marker_timer;
+};
+
+struct hinic3_bond_active_report_info {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 bon_mmi_status;
+ u32 active_bitmap;
+
+ u8 rsvd[16];
+};
+
+/* IP checksum error packets, enable rss quadruple hash. */
+struct hinic3_ipcs_err_rss_enable_operation_s {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 en_tag;
+ u8 type; /* 1: set 0: get */
+ u8 rsvd[2];
+};
+
+struct hinic3_smac_check_state {
+ struct hinic3_mgmt_msg_head head;
+ u8 smac_check_en; /* 1: enable 0: disable */
+ u8 op_code; /* 1: set 0: get */
+ u8 flash_en; /* 1: enable 0: disable */
+ u8 rsvd;
+};
+
+struct hinic3_clear_log_state {
+ struct hinic3_mgmt_msg_head head;
+ u32 type;
+};
+
+struct hinic3_outband_cfg_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 outband_default_vid;
+ u16 func_id;
+};
+
+struct hinic3_wr_ordering {
+ struct hinic3_mgmt_msg_head head;
+ u8 op_code; /* 1: set 0: get */
+ u8 wr_pkt_so_ro;
+ u8 rd_pkt_so_ro;
+ u8 rsvd;
+};
+
+struct hinic3_function_active_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_rq_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rq_depth;
+ u16 rq_num;
+ u16 pf_num;
+ u16 port_num;
+};
+
+#endif /* HINIC_MGMT_INTERFACE_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
new file mode 100644
index 0000000..97eda43
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
+ * File Name : nic_npu_cmd.h
+ * Version : Initial Draft
+ * Created : 2019/4/25
+ * Last Modified :
+ * Description : NIC Commands between Driver and NPU
+ * Function List :
+ */
+
+#ifndef NIC_NPU_CMD_H
+#define NIC_NPU_CMD_H
+
+/* NIC CMDQ MODE */
+enum hinic3_ucode_cmd {
+ HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
+ HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
+ HINIC3_UCODE_CMD_ARM_SQ, /**< Unused */
+ HINIC3_UCODE_CMD_ARM_RQ, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_IQ_ENABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
+ HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
+ HINIC3_UCODE_CMD_PPA_HASH_TABLE,
+ HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_UCODE_MIG_CFG_Q_CTX = 14,
+ HINIC3_UCODE_MIG_CHK_SQ_STOP,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ HINIC3_UCODE_MIG_CFG_BAT_INFO,
+};
+
+#endif /* NIC_NPU_CMD_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
index ee005a8..5f0f790 100644
--- a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
+++ b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
@@ -4,8 +4,8 @@
#ifndef OSSL_KNL_LINUX_H_
#define OSSL_KNL_LINUX_H_
-#include <net/checksum.h>
#include <net/ipv6.h>
+#include <net/devlink.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/device.h>
@@ -19,6 +19,12 @@
#include <linux/list.h>
#include <linux/bitmap.h>
#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/filter.h>
+#include <linux/aer.h>
+#include <linux/socket.h>
#ifndef NETIF_F_SCTP_CSUM
#define NETIF_F_SCTP_CSUM 0
@@ -37,6 +43,17 @@
#define ossl_get_free_pages __get_free_pages
+#ifndef ETHTOOL_LINK_MODE_100000baseKR_Full_BIT
+#define ETHTOOL_LINK_MODE_100000baseKR_Full_BIT 75
+#define ETHTOOL_LINK_MODE_100000baseCR_Full_BIT 78
+#define ETHTOOL_LINK_MODE_100000baseSR_Full_BIT 76
+#endif
+#ifndef ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT
+#define ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT 80
+#define ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT 81
+#define ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT 84
+#endif
+
#ifndef high_16_bits
#define low_16_bits(x) ((x) & 0xFFFF)
#define high_16_bits(x) (((x) & 0xFFFF0000) >> 16)
@@ -54,13 +71,11 @@
#endif
#define HAVE_INET6_IFADDR_LIST
-
#define HAVE_NDO_GET_STATS64
#ifndef HAVE_MQPRIO
#define HAVE_MQPRIO
#endif
-
#ifndef HAVE_SETUP_TC
#define HAVE_SETUP_TC
#endif
@@ -68,25 +83,20 @@
#ifndef HAVE_NDO_SET_FEATURES
#define HAVE_NDO_SET_FEATURES
#endif
-
#define HAVE_IRQ_AFFINITY_NOTIFY
-
#define HAVE_ETHTOOL_SET_PHYS_ID
-
#define HAVE_NETDEV_WANTED_FEAUTES
#ifndef HAVE_PCI_DEV_FLAGS_ASSIGNED
#define HAVE_PCI_DEV_FLAGS_ASSIGNED
#define HAVE_VF_SPOOFCHK_CONFIGURE
#endif
-
#ifndef HAVE_SKB_L4_RXHASH
#define HAVE_SKB_L4_RXHASH
#endif
#define HAVE_ETHTOOL_GRXFHINDIR_SIZE
#define HAVE_INT_NDO_VLAN_RX_ADD_VID
-
#ifdef ETHTOOL_SRXNTUPLE
#undef ETHTOOL_SRXNTUPLE
#endif
@@ -95,9 +105,9 @@
#define _kc_kunmap_atomic(addr) kunmap_atomic(addr)
#include <linux/of_net.h>
-
#define HAVE_FDB_OPS
#define HAVE_ETHTOOL_GET_TS_INFO
+
#define HAVE_NAPI_GRO_FLUSH_OLD
#ifndef HAVE_SRIOV_CONFIGURE
@@ -107,6 +117,7 @@
#define HAVE_ENCAP_TSO_OFFLOAD
#define HAVE_SKB_INNER_NETWORK_HEADER
+
#define HAVE_NDO_SET_VF_LINK_STATE
#define HAVE_SKB_INNER_PROTOCOL
#define HAVE_MPLS_FEATURES
@@ -115,12 +126,12 @@
#define HAVE_NETIF_SET_XPS_QUEUE_CONST_MASK
#define HAVE_VXLAN_CHECKS
-#define HAVE_NDO_SELECT_QUEUE_ACCEL
#define HAVE_NET_GET_RANDOM_ONCE
#define HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS
#define HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK
+
#define HAVE_NDO_SET_VF_MIN_MAX_TX_RATE
#define HAVE_VLAN_FIND_DEV_DEEP_RCU
@@ -128,8 +139,8 @@
#define HAVE_MULTI_VLAN_OFFLOAD_EN
#define HAVE_ETH_GET_HEADLEN_FUNC
-#define HAVE_RXFH_HASHFUNC
+#define HAVE_RXFH_HASHFUNC
#define HAVE_NDO_SET_VF_TRUST
#include <net/devlink.h>
@@ -138,6 +149,7 @@
#define HAVE_NETDEVICE_MIN_MAX_MTU
+
#define HAVE_VOID_NDO_GET_STATS64
#define HAVE_VM_OPS_FAULT_NO_VMA
@@ -146,9 +158,13 @@
#define HAVE_PCI_ERROR_HANDLER_RESET_PREPARE
#define HAVE_PTP_CLOCK_DO_AUX_WORK
+
#define HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV
#define HAVE_XDP_SUPPORT
+#if (KERNEL_VERSION(5, 9, 0) > LINUX_VERSION_CODE)
+#define HAVE_XDP_QUERY_PROG
+#endif
#define HAVE_NDO_BPF_NETDEV_BPF
#define HAVE_TIMER_SETUP
@@ -158,6 +174,7 @@
#define HAVE_NDO_SELECT_QUEUE_SB_DEV
+
#define dev_open(x) dev_open(x, NULL)
#define HAVE_NEW_ETHTOOL_LINK_SETTINGS_ONLY
@@ -180,12 +197,14 @@ static inline void *_hinic3_dma_zalloc_coherent(struct device *dev,
}
#endif
+#if (KERNEL_VERSION(5, 6, 0) <= LINUX_VERSION_CODE)
#ifndef DT_KNL_EMU
struct timeval {
__kernel_old_time_t tv_sec; /* seconds */
__kernel_suseconds_t tv_usec; /* microseconds */
};
#endif
+#endif
#ifndef do_gettimeofday
#define do_gettimeofday(time) _kc_do_gettimeofday(time)
@@ -199,6 +218,8 @@ static inline void _kc_do_gettimeofday(struct timeval *tv)
}
#endif
+
+
#define HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY
#define ETH_GET_HEADLEN_NEED_DEV
#define HAVE_GENL_OPS_FIELD_VALIDATE
@@ -207,32 +228,75 @@ static inline void _kc_do_gettimeofday(struct timeval *tv)
#define FIELD_SIZEOF(t, f) (sizeof(((t *)0)->f))
#endif
+/*****************************************************************************/
+#if (KERNEL_VERSION(5, 5, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.5.0 */
#define HAVE_DEVLINK_FLASH_UPDATE_PARAMS
+#endif /* 5.5.0 */
+/*****************************************************************************/
+#if (KERNEL_VERSION(5, 6, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.6.0 */
#ifndef rtc_time_to_tm
#define rtc_time_to_tm rtc_time64_to_tm
#endif
#define HAVE_NDO_TX_TIMEOUT_TXQ
#define HAVE_PROC_OPS
+#endif /* 5.6.0 */
+/*****************************************************************************/
+#if (KERNEL_VERSION(5, 7, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.7.0 */
#define SUPPORTED_COALESCE_PARAMS
#ifndef pci_cleanup_aer_uncorrect_error_status
#define pci_cleanup_aer_uncorrect_error_status pci_aer_clear_nonfatal_status
#endif
+#endif /* 5.7.0 */
+
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 9, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.9.0 */
#define HAVE_XDP_FRAME_SZ
+#endif /* 5.9.0 */
+
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE)
+#define HAVE_DEVLINK_FW_FILE_NAME_PARAM
+#else /* >= 5.10.0 */
+#endif /* 5.10.0 */
#define HAVE_DEVLINK_FW_FILE_NAME_MEMBER
-#define HAVE_ENCAPSULATION_TSO
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.10.0 */
+#if !defined(HAVE_ETHTOOL_COALESCE_EXTACK) && \
+ !defined(NO_ETHTOOL_COALESCE_EXTACK)
+#define HAVE_ETHTOOL_COALESCE_EXTACK
+#endif
+#endif /* 5.10.0 */
+
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE)
+
+#else /* >= 5.10.0 */
+#if !defined(HAVE_ETHTOOL_RINGPARAM_EXTACK) && \
+ !defined(NO_ETHTOOL_RINGPARAM_EXTACK)
+#define HAVE_ETHTOOL_RINGPARAM_EXTACK
+#endif
+#endif /* 5.10.0 */
+/* ************************************************************************ */
+#define HAVE_NDO_UDP_TUNNEL_ADD
+#define HAVE_ENCAPSULATION_TSO
#define HAVE_ENCAPSULATION_CSUM
#ifndef eth_zero_addr
static inline void hinic3_eth_zero_addr(u8 *addr)
{
- memset(addr, 0x00, ETH_ALEN);
+ (void)memset(addr, 0x00, ETH_ALEN);
}
#define eth_zero_addr(_addr) hinic3_eth_zero_addr(_addr)
@@ -273,13 +337,10 @@ int creat_thread(struct sdk_thread_info *thread_info);
void stop_thread(struct sdk_thread_info *thread_info);
#define destroy_work(work)
-
void utctime_to_localtime(u64 utctime, u64 *localtime);
-
#ifndef HAVE_TIMER_SETUP
void initialize_timer(const void *adapter_hdl, struct timer_list *timer);
#endif
-
void add_to_timer(struct timer_list *timer, u64 period);
void stop_timer(struct timer_list *timer);
void delete_timer(struct timer_list *timer);
@@ -304,3 +365,4 @@ u64 ossl_get_real_time(void);
#define tasklet_state(tasklet) ((tasklet)->state)
#endif
+/* ************************************************************************ */
--
2.45.1.windows.1
2
1
Fix CVE-2022-49850.
Ryusuke Konishi (1):
nilfs2: fix deadlock in nilfs_count_free_blocks()
fs/nilfs2/the_nilfs.c | 2 --
1 file changed, 2 deletions(-)
--
2.34.1
2
2
Fix CVE-2022-49842.
Chen Zhongjin (2):
ASoC: core: Fix use-after-free in snd_soc_exit()
ASoC: soc-utils: Remove __exit for snd_soc_util_exit()
sound/soc/soc-core.c | 17 +++++++++++++++--
sound/soc/soc-utils.c | 2 +-
2 files changed, 16 insertions(+), 3 deletions(-)
--
2.34.1
2
3
各位Maintainer好,loongarch kvm PR review申请
https://gitee.com/openeuler/kernel/pulls/14328
需要review一下关于drivers/iommu和drivers/pci相关的修改
1
0
*** BLURB HERE ***
Wang ShaoBo (1):
mISDN: fix misuse of put_device() in mISDN_register_device()
Yang Yingliang (1):
mISDN: fix possible memory leak in mISDN_register_device()
drivers/isdn/mISDN/core.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
--
2.34.1
2
3

08 May '25
From: f30059697 <fuguiming(a)huawei.com>
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IC5K0L?from=project-issue
CVE: NA
--------------------------------
Add optical module type adaptation.
Add ethtool fec function.
Add NIC XDP PASS function.
Add QoS persistence.
Add NIC out-of-band VLAN configuration function.
Fix NIC bifur bugs.
Fix performance test bugs.
Fix NIC RX bugs.
Fix NIC VF bugs.
Fix the bug of exiting when probing NIC.
Fix bond bugs.
Fix the bug of MAC address configuration failure in OS 6.6.
Fix the bug of reading NIC status incorrectly.
Fix and add some statistics.
Signed-off-by: f30059697 <fuguiming(a)huawei.com>
---
drivers/net/ethernet/huawei/hinic3/Makefile | 1 +
drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c | 3 +-
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c | 181 ++-
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h | 1 +
drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h | 212 ---
drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h | 239 ----
drivers/net/ethernet/huawei/hinic3/comm_defs.h | 100 --
drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h | 103 --
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c | 40 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h | 2 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c | 88 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c | 29 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c | 22 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h | 185 ---
drivers/net/ethernet/huawei/hinic3/hinic3_common.h | 118 --
drivers/net/ethernet/huawei/hinic3/hinic3_crm.h | 16 +-
drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c | 298 ++--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c | 264 ++--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h | 7 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c | 252 +++-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c | 456 +++---
drivers/net/ethernet/huawei/hinic3/hinic3_filter.c | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_hw.h | 19 +
drivers/net/ethernet/huawei/hinic3/hinic3_irq.c | 39 +-
drivers/net/ethernet/huawei/hinic3/hinic3_lld.h | 205 ---
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c | 831 ++++++++++-
drivers/net/ethernet/huawei/hinic3/hinic3_main.c | 492 ++++++-
drivers/net/ethernet/huawei/hinic3/hinic3_mt.h | 218 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c | 402 ++++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic.h | 50 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c | 557 ++++++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h | 54 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c | 186 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c | 10 +
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h | 114 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c | 105 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c | 50 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c | 15 +-
drivers/net/ethernet/huawei/hinic3/hinic3_profile.h | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rss.c | 141 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c | 41 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rx.c | 311 +++-
drivers/net/ethernet/huawei/hinic3/hinic3_rx.h | 41 +-
drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h | 7 +-
drivers/net/ethernet/huawei/hinic3/hinic3_tx.c | 79 +-
drivers/net/ethernet/huawei/hinic3/hinic3_wq.h | 4 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c | 11 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c | 6 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h | 5 -
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c | 1 -
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c | 213 ++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h | 18 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c | 3 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c | 14 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c | 42 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c | 79 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h | 7 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c | 155 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c | 115 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c | 85 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h | 31 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c | 40 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c | 1247 +++++++++++++++--
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c | 3 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c | 4 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c | 41 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c | 126 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h | 4 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h | 31 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c | 56 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h | 6 +-
drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c | 1 +
drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h | 4 +
.../include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h | 11 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h | 42 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h | 2 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h | 70 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h | 141 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h | 5 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h | 88 +-
.../include/mpu/mpu_outband_ncsi_cmd_defs.h | 8 +
drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/vram_common.h | 25 +-
drivers/net/ethernet/huawei/hinic3/{mag_cmd.h => mag_mpu_cmd_defs.h} | 237 +++-
drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h | 27 -
drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h | 65 -
drivers/net/ethernet/huawei/hinic3/{hinic3_nic_cmd.h => nic_mpu_cmd.h} | 55 +-
...c3_mgmt_interface.h => nic_mpu_cmd_defs.h} | 198 ++-
drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h | 36 +
drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h | 29 +-
96 files changed, 7173 insertions(+), 2828 deletions(-)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_defs.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_common.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
rename drivers/net/ethernet/huawei/hinic3/{mag_cmd.h => mag_mpu_cmd_defs.h} (79%)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
rename drivers/net/ethernet/huawei/hinic3/{hinic3_nic_cmd.h => nic_mpu_cmd.h} (77%)
rename drivers/net/ethernet/huawei/hinic3/{hinic3_mgmt_interface.h => nic_mpu_cmd_defs.h} (86%)
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
diff --git a/drivers/net/ethernet/huawei/hinic3/Makefile b/drivers/net/ethernet/huawei/hinic3/Makefile
index 6f9ed3f..457c920 100644
--- a/drivers/net/ethernet/huawei/hinic3/Makefile
+++ b/drivers/net/ethernet/huawei/hinic3/Makefile
@@ -11,6 +11,7 @@ ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/mpu/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/bond/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/vmsec/
+ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/bond/
obj-$(CONFIG_HINIC3) += hinic3.o
hinic3-objs := hw/hinic3_hwdev.o \
diff --git a/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c b/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c
index cc2e4b3..440fea6 100644
--- a/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_nic_cmdq.h"
#include "sw_cmdq_ops.h"
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
index e8c703b..cd6ea8e 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
@@ -9,6 +9,7 @@
#include <linux/net.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
+#include <linux/version.h>
#include "hinic3_lld.h"
#include "hinic3_srv_nic.h"
@@ -81,7 +82,7 @@ static u32 bond_gen_uplink_id(struct hinic3_bond_dev *bdev)
spin_lock(&bdev->lock);
for (i = 0; i < BOND_PORT_MAX_NUM; i++) {
if (BITMAP_JUDGE(bdev->bond_attr.slaves, i)) {
- if (!bdev->tracker.ndev[i])
+ if (bdev->tracker.ndev[i] == NULL)
continue;
nic_dev = netdev_priv(bdev->tracker.ndev[i]);
pdev = nic_dev->pdev;
@@ -109,7 +110,8 @@ static struct hinic3_nic_dev *get_nic_dev_safe(struct net_device *ndev)
return netdev_priv(ndev);
}
-static u8 bond_get_slaves_bitmap(struct hinic3_bond_dev *bdev, struct bonding *bond)
+static u8 bond_get_slaves_bitmap(struct hinic3_bond_dev *bdev,
+ struct bonding *bond)
{
struct slave *slave = NULL;
struct list_head *iter = NULL;
@@ -203,7 +205,8 @@ static u8 bond_dev_track_port(struct hinic3_bond_dev *bdev,
bdev->tracker.netdev_state[port_id].tx_enabled = 0;
if (!bdev->ppf_hwdev)
bdev->ppf_hwdev = ppf_hwdev;
- pr_info("TRACK cnt: %d, slave_name(%s)\n", bdev->tracker.cnt, ndev->name);
+ pr_info("TRACK cnt: %d, slave_name(%s)\n",
+ bdev->tracker.cnt, ndev->name);
spin_unlock(&bdev->lock);
return port_id;
@@ -268,11 +271,16 @@ static void bond_master_event(struct hinic3_bond_dev *bdev,
queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
}
-static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
+static struct hinic3_bond_dev *bond_get_bdev(struct bonding *bond)
{
struct hinic3_bond_dev *bdev = NULL;
int bid;
+ if (bond == NULL) {
+ pr_err("hinic3_bond: bond is NULL\n");
+ return NULL;
+ }
+
mutex_lock(&g_bond_mutex);
for (bid = BOND_FIRST_ID; bid <= BOND_MAX_ID; bid++) {
bdev = bond_mngr.bond_dev[bid];
@@ -283,38 +291,73 @@ static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
mutex_unlock(&g_bond_mutex);
return bdev;
}
+
+ if (strncmp(bond->dev->name,
+ bdev->name, BOND_NAME_MAX_LEN) == 0) {
+ bdev->bond = bond;
+ return bdev;
+ }
}
mutex_unlock(&g_bond_mutex);
return NULL;
}
-static void bond_handle_rtnl_event(struct net_device *ndev)
+static struct bonding *get_bonding_by_netdev(struct net_device *ndev)
{
- struct hinic3_bond_dev *bdev = NULL;
struct bonding *bond = NULL;
struct slave *slave = NULL;
if (netif_is_bond_master(ndev)) {
bond = netdev_priv(ndev);
- bdev = bond_get_bdev(bond);
} else if (netif_is_bond_slave(ndev)) {
- /*lint -e(160) */
slave = bond_slave_get_rtnl(ndev);
if (slave) {
bond = bond_get_bond_by_slave(slave);
- bdev = bond_get_bdev(bond);
}
}
- if (!bond || !bdev)
+ return bond;
+}
+/*lint -e580 -e546*/
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+
+ if (!ndev) {
+ pr_err("hinic3_bond: netdev is NULL\n");
+ return false;
+ }
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
+ return false;
+
+ return bdev->status == BOND_DEV_STATUS_ACTIVATED;
+}
+EXPORT_SYMBOL(hinic3_is_bond_dev_status_actived);
+/*lint +e580 +e546*/
+
+static void bond_handle_rtnl_event(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+ struct slave *slave = NULL;
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
return;
bond_update_attr(bdev, bond);
- if (slave)
+ if (netif_is_bond_slave(ndev)) {
+ slave = bond_slave_get_rtnl(ndev);
bond_slave_event(bdev, slave);
- else
+ } else {
bond_master_event(bdev, bond);
+ }
}
static void bond_rtnl_data_ready(struct sock *sk)
@@ -368,7 +411,8 @@ static int bond_enable_netdev_event(void)
(*rtnl_sock)->sk->sk_data_ready = bond_rtnl_data_ready;
(*rtnl_sock)->sk->sk_allocation = GFP_KERNEL;
- err = kernel_bind(*rtnl_sock, (struct sockaddr *)(u8 *)&addr, sizeof(addr));
+ err = kernel_bind(*rtnl_sock, (struct sockaddr *)(u8 *)&addr,
+ sizeof(addr));
if (err) {
pr_err("hinic3_bond: Couldn't bind rtnl socket.\n");
sock_release(*rtnl_sock);
@@ -387,7 +431,7 @@ static void bond_disable_netdev_event(void)
static int bond_send_upcmd(struct hinic3_bond_dev *bdev, struct bond_attr *attr,
u8 cmd_type)
{
- int err, len;
+ int err, ret, len;
struct hinic3_bond_cmd cmd = {0};
u16 out_size = sizeof(cmd);
@@ -403,7 +447,9 @@ static int bond_send_upcmd(struct hinic3_bond_dev *bdev, struct bond_attr *attr,
len = sizeof(cmd.bond_name);
if (cmd_type == MPU_CMD_BOND_CREATE) {
- strscpy(cmd.bond_name, bdev->name, len);
+ ret = strscpy(cmd.bond_name, bdev->name, len);
+ if (ret < 0)
+ pr_err("strscpy bond name failed\n");
cmd.bond_name[sizeof(cmd.bond_name) - 1] = '\0';
}
@@ -478,7 +524,11 @@ static void bond_update_slave_info(struct hinic3_bond_dev *bdev,
continue;
}
+ if (!bdev->tracker.ndev[i])
+ continue;
+
bond_pf_bitmap_set(bdev, i);
+
if (!bdev->tracker.netdev_state[i].tx_enabled)
continue;
@@ -516,6 +566,7 @@ static int bond_upcmd_config(struct hinic3_bond_dev *bdev,
attr->active_slaves,
attr->lacp_collect_slaves);
pr_info("bond_pf_bitmap: 0x%x\n", attr->bond_pf_bitmap);
+ pr_info("bond user_bitmap 0x%x\n", attr->user_bitmap);
err = bond_send_upcmd(bdev, attr, MPU_CMD_BOND_SET_ATTR);
if (!err)
@@ -544,8 +595,10 @@ static int bond_upcmd_activate(struct hinic3_bond_dev *bdev,
return err;
}
-static void bond_call_service_func(struct hinic3_bond_dev *bdev, struct bond_attr *attr,
- enum bond_service_proc_pos pos, int bond_status)
+static void bond_call_service_func(struct hinic3_bond_dev *bdev,
+ struct bond_attr *attr,
+ enum bond_service_proc_pos pos,
+ int bond_status)
{
int i;
@@ -560,6 +613,18 @@ static void bond_call_service_func(struct hinic3_bond_dev *bdev, struct bond_att
mutex_unlock(&g_bond_service_func_mutex);
}
+static u32 bond_get_user_bitmap(struct hinic3_bond_dev *bdev)
+{
+ u32 user_bitmap = 0;
+ u8 user;
+
+ for (user = HINIC3_BOND_USER_OVS; user < HINIC3_BOND_USER_NUM; user++) {
+ if (bdev->slot_used[user] == 1)
+ BITMAP_SET(user_bitmap, user);
+ }
+ return user_bitmap;
+}
+
static void bond_do_work(struct hinic3_bond_dev *bdev)
{
bool is_bonded = 0;
@@ -570,7 +635,7 @@ static void bond_do_work(struct hinic3_bond_dev *bdev)
is_bonded = bdev->tracker.is_bonded;
attr = bdev->new_attr;
spin_unlock(&bdev->lock);
- attr.user_bitmap = 0;
+ attr.user_bitmap = bond_get_user_bitmap(bdev);
/* is_bonded indicates whether bond should be activated. */
if (is_bonded && !bond_dev_is_activated(bdev)) {
@@ -597,15 +662,22 @@ static void bond_try_do_work(struct work_struct *work)
struct delayed_work *delayed_work = to_delayed_work(work);
struct hinic3_bond_dev *bdev =
container_of(delayed_work, struct hinic3_bond_dev, bond_work);
+ int status;
- if (g_bond_service_func[HINIC3_BOND_USER_ROCE] && bdev->tracker.cnt < MIN_BOND_SLAVE_CNT)
+ status = mutex_trylock(&g_bond_mutex);
+ if (status == 0) {
+ /* Delay 1 sec and retry */
queue_delayed_work(bdev->wq, &bdev->bond_work, HZ);
- else
+ } else {
bond_do_work(bdev);
+ mutex_unlock(&g_bond_mutex);
+ }
}
static int bond_dev_init(struct hinic3_bond_dev *bdev, const char *name)
{
+ int err = 0;
+
bdev->wq = create_singlethread_workqueue("hinic3_bond_wq");
if (!bdev->wq) {
pr_err("hinic3_bond: Failed to create workqueue\n");
@@ -614,7 +686,13 @@ static int bond_dev_init(struct hinic3_bond_dev *bdev, const char *name)
INIT_DELAYED_WORK(&bdev->bond_work, bond_try_do_work);
bdev->status = BOND_DEV_STATUS_IDLE;
- strscpy(bdev->name, name, sizeof(bdev->name));
+ err = strscpy(bdev->name, name, strlen(name));
+ if (err < 0) {
+ pr_err("hinic3_bond: Failed to init bond dev\n");
+ cancel_delayed_work_sync(&bdev->bond_work);
+ destroy_workqueue(bdev->wq);
+ return err;
+ }
spin_lock_init(&bdev->lock);
@@ -630,6 +708,7 @@ static int bond_dev_release(struct hinic3_bond_dev *bdev)
err = bond_upcmd_deactivate(bdev);
if (err) {
pr_err("hinic3_bond: Failed to deactivate dev\n");
+ mutex_unlock(&g_bond_mutex);
return err;
}
@@ -637,7 +716,8 @@ static int bond_dev_release(struct hinic3_bond_dev *bdev)
if (bond_mngr.bond_dev[i] == bdev) {
bond_mngr.bond_dev[i] = NULL;
bond_mngr.cnt--;
- pr_info("hinic3_bond: Free bond, id: %u mngr_cnt:%u\n", i, bond_mngr.cnt);
+ pr_info("hinic3_bond: Free bond, id: %u mngr_cnt:%u\n",
+ i, bond_mngr.cnt);
break;
}
}
@@ -694,7 +774,8 @@ static struct hinic3_bond_dev *bond_dev_alloc(const char *name)
bdev->bond_attr.bond_id = i;
bond_mngr.bond_dev[i] = bdev;
bond_mngr.cnt++;
- pr_info("hinic3_bond: Create bond dev, id:%u cnt:%u\n", i, bond_mngr.cnt);
+ pr_info("hinic3_bond: Create bond dev, id:%u cnt:%u\n",
+ i, bond_mngr.cnt);
break;
}
}
@@ -764,20 +845,28 @@ static struct hinic3_bond_dev *bond_dev_by_name(const char *name)
static void bond_dev_user_attach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user)
{
+ u32 user_bitmap;
+
+ if (user < 0 || user >= HINIC3_BOND_USER_NUM)
+ return;
+
if (bdev->slot_used[user])
return;
bdev->slot_used[user] = 1;
if (!kref_get_unless_zero(&bdev->ref))
kref_init(&bdev->ref);
+ else {
+ user_bitmap = bond_get_user_bitmap(bdev);
+ pr_info("hinic3_bond: user %u attach bond %s, user_bitmap %#x\n",
+ user, bdev->name, user_bitmap);
+ queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
+ }
}
static void bond_dev_user_detach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user, bool *freed)
{
- if (user < 0 || user >= HINIC3_BOND_USER_NUM)
- return;
-
if (bdev->slot_used[user]) {
bdev->slot_used[user] = 0;
if (kref_read(&bdev->ref) == 1)
@@ -790,16 +879,20 @@ static struct bonding *bond_get_knl_bonding(const char *name)
{
struct net_device *ndev_tmp = NULL;
+ rcu_read_lock();
for_each_netdev(&init_net, ndev_tmp) {
if (netif_is_bond_master(ndev_tmp) &&
- !strcmp(ndev_tmp->name, name))
+ !strcmp(ndev_tmp->name, name)) {
+ rcu_read_unlock();
return netdev_priv(ndev_tmp);
+ }
}
-
+ rcu_read_unlock();
return NULL;
}
-void hinic3_bond_set_user_bitmap(struct bond_attr *attr, enum hinic3_bond_user user)
+void hinic3_bond_set_user_bitmap(struct bond_attr *attr,
+ enum hinic3_bond_user user)
{
if (!BITMAP_JUDGE(attr->user_bitmap, user))
BITMAP_SET(attr->user_bitmap, user);
@@ -852,8 +945,9 @@ int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user)
int err = 0;
bool lock_freed = false;
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
- pr_warn("hinic3_bond: Invalid bond id:%u to delete\n", bond_id);
+ if (!BOND_ID_IS_VALID(bond_id) || user >= HINIC3_BOND_USER_NUM) {
+ pr_warn("hinic3_bond: Invalid bond id or user, bond_id: %u, user: %d\n",
+ bond_id, user);
return -EINVAL;
}
@@ -861,7 +955,8 @@ int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user)
if (!bond_mngr.bond_dev[bond_id])
err = -ENODEV;
else
- bond_dev_user_detach(bond_mngr.bond_dev[bond_id], user, &lock_freed);
+ bond_dev_user_detach(bond_mngr.bond_dev[bond_id],
+ user, &lock_freed);
if (!lock_freed)
mutex_unlock(&g_bond_mutex);
@@ -877,7 +972,8 @@ void hinic3_bond_clean_user(enum hinic3_bond_user user)
mutex_lock(&g_bond_mutex);
for (i = BOND_FIRST_ID; i <= BOND_MAX_ID; i++) {
if (bond_mngr.bond_dev[i]) {
- bond_dev_user_detach(bond_mngr.bond_dev[i], user, &lock_freed);
+ bond_dev_user_detach(bond_mngr.bond_dev[i],
+ user, &lock_freed);
if (lock_freed) {
mutex_lock(&g_bond_mutex);
lock_freed = false;
@@ -891,7 +987,7 @@ EXPORT_SYMBOL(hinic3_bond_clean_user);
int hinic3_bond_get_uplink_id(u16 bond_id, u32 *uplink_id)
{
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID || !uplink_id) {
+ if (!BOND_ID_IS_VALID(bond_id) || !uplink_id) {
pr_warn("hinic3_bond: Invalid args, id: %u, uplink: %d\n",
bond_id, !!uplink_id);
return -EINVAL;
@@ -941,7 +1037,7 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
int i;
int len;
- if (!info || bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
+ if (!info || !BOND_ID_IS_VALID(bond_id)) {
pr_warn("hinic3_bond: Invalid args, info: %d,id: %u\n",
!!info, bond_id);
return -EINVAL;
@@ -962,7 +1058,8 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
for (i = 0; i < BOND_PORT_MAX_NUM; i++) {
if (BITMAP_JUDGE(info->slaves, i) && tracker->ndev[i]) {
len = sizeof(info->slaves_name[0]);
- strscpy(info->slaves_name[info->cnt], tracker->ndev[i]->name, len);
+ strscpy(info->slaves_name[info->cnt],
+ tracker->ndev[i]->name, len);
info->cnt++;
}
}
@@ -972,7 +1069,8 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
}
EXPORT_SYMBOL(hinic3_bond_get_slaves);
-struct net_device *hinic3_bond_get_netdev_by_portid(const char *bond_name, u8 port_id)
+struct net_device *hinic3_bond_get_netdev_by_portid(const char *bond_name,
+ u8 port_id)
{
struct hinic3_bond_dev *bdev = NULL;
@@ -989,7 +1087,8 @@ struct net_device *hinic3_bond_get_netdev_by_portid(const char *bond_name, u8 po
}
EXPORT_SYMBOL(hinic3_bond_get_netdev_by_portid);
-int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos, u16 channel)
+int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos,
+ u16 channel)
{
struct comm_cmd_hw_bond_infos bond_infos;
u16 out_size = sizeof(bond_infos);
@@ -1002,7 +1101,8 @@ int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos, u1
bond_infos.infos.bond_id = infos->bond_id;
- err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_COMM, COMM_MGMT_CMD_GET_HW_BOND,
+ err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_COMM,
+ COMM_MGMT_CMD_GET_HW_BOND,
&bond_infos, sizeof(bond_infos),
&bond_infos, &out_size, 0, channel);
if (bond_infos.head.status || err || !out_size) {
@@ -1018,7 +1118,8 @@ int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos, u1
}
EXPORT_SYMBOL(hinic3_get_hw_bond_infos);
-int hinic3_get_bond_tracker_by_name(const char *name, struct bond_tracker *tracker)
+int hinic3_get_bond_tracker_by_name(const char *name,
+ struct bond_tracker *tracker)
{
struct hinic3_bond_dev *bdev = NULL;
int i;
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
index 024de95..5ab36f7 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
@@ -82,6 +82,7 @@ struct hinic3_bond_cmd {
char bond_name[16];
};
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev);
void hinic3_bond_set_user_bitmap(struct bond_attr *attr, enum hinic3_bond_user user);
int hinic3_bond_attach(const char *name, enum hinic3_bond_user user, u16 *bond_id);
int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user);
diff --git a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h b/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
deleted file mode 100644
index 557f326..0000000
--- a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2016-2022. All rights reserved.
- * File name: Cfg_mgt_comm_pub.h
- * Version No.: Draft
- * Generation date: 2016 year 05 month 07 day
- * Latest modification:
- * Function description: Header file for communication between the: Host and FW
- * Function list:
- * Modification history:
- * 1. Date: 2016 May 07
- * Modify content: Create a file.
- */
-#ifndef CFG_MGT_COMM_PUB_H
-#define CFG_MGT_COMM_PUB_H
-
-#include "mgmt_msg_base.h"
-
-enum servic_bit_define {
- SERVICE_BIT_NIC = 0,
- SERVICE_BIT_ROCE = 1,
- SERVICE_BIT_VBS = 2,
- SERVICE_BIT_TOE = 3,
- SERVICE_BIT_IPSEC = 4,
- SERVICE_BIT_FC = 5,
- SERVICE_BIT_VIRTIO = 6,
- SERVICE_BIT_OVS = 7,
- SERVICE_BIT_NVME = 8,
- SERVICE_BIT_ROCEAA = 9,
- SERVICE_BIT_CURRENET = 10,
- SERVICE_BIT_PPA = 11,
- SERVICE_BIT_MIGRATE = 12,
- SERVICE_BIT_MAX
-};
-
-#define CFG_SERVICE_MASK_NIC (0x1 << SERVICE_BIT_NIC)
-#define CFG_SERVICE_MASK_ROCE (0x1 << SERVICE_BIT_ROCE)
-#define CFG_SERVICE_MASK_VBS (0x1 << SERVICE_BIT_VBS)
-#define CFG_SERVICE_MASK_TOE (0x1 << SERVICE_BIT_TOE)
-#define CFG_SERVICE_MASK_IPSEC (0x1 << SERVICE_BIT_IPSEC)
-#define CFG_SERVICE_MASK_FC (0x1 << SERVICE_BIT_FC)
-#define CFG_SERVICE_MASK_VIRTIO (0x1 << SERVICE_BIT_VIRTIO)
-#define CFG_SERVICE_MASK_OVS (0x1 << SERVICE_BIT_OVS)
-#define CFG_SERVICE_MASK_NVME (0x1 << SERVICE_BIT_NVME)
-#define CFG_SERVICE_MASK_ROCEAA (0x1 << SERVICE_BIT_ROCEAA)
-#define CFG_SERVICE_MASK_CURRENET (0x1 << SERVICE_BIT_CURRENET)
-#define CFG_SERVICE_MASK_PPA (0x1 << SERVICE_BIT_PPA)
-#define CFG_SERVICE_MASK_MIGRATE (0x1 << SERVICE_BIT_MIGRATE)
-
-/* Definition of the scenario ID in the cfg_data, which is used for SML memory allocation. */
-enum scenes_id_define {
- SCENES_ID_FPGA_ETH = 0,
- SCENES_ID_FPGA_TIOE = 1, /* Discarded */
- SCENES_ID_STORAGE_ROCEAA_2x100 = 2,
- SCENES_ID_STORAGE_ROCEAA_4x25 = 3,
- SCENES_ID_CLOUD = 4,
- SCENES_ID_FC = 5,
- SCENES_ID_STORAGE_ROCE = 6,
- SCENES_ID_COMPUTE_ROCE = 7,
- SCENES_ID_STORAGE_TOE = 8,
- SCENES_ID_MAX
-};
-
-/* struct cfg_cmd_dev_cap.sf_svc_attr */
-enum {
- SF_SVC_FT_BIT = (1 << 0),
- SF_SVC_RDMA_BIT = (1 << 1),
-};
-
-enum cfg_cmd {
- CFG_CMD_GET_DEV_CAP = 0,
- CFG_CMD_GET_HOST_TIMER = 1,
-};
-
-struct cfg_cmd_host_timer {
- struct mgmt_msg_head head;
-
- u8 host_id;
- u8 rsvd1;
-
- u8 timer_pf_num;
- u8 timer_pf_id_start;
- u16 timer_vf_num;
- u16 timer_vf_id_start;
- u32 rsvd2[8];
-};
-
-struct cfg_cmd_dev_cap {
- struct mgmt_msg_head head;
-
- u16 func_id;
- u16 rsvd1;
-
- /* Public resources */
- u8 host_id;
- u8 ep_id;
- u8 er_id;
- u8 port_id;
-
- u16 host_total_func;
- u8 host_pf_num;
- u8 pf_id_start;
- u16 host_vf_num;
- u16 vf_id_start;
- u8 host_oq_id_mask_val;
- u8 timer_en;
- u8 host_valid_bitmap;
- u8 rsvd_host;
-
- u16 svc_cap_en;
- u16 max_vf;
- u8 flexq_en;
- u8 valid_cos_bitmap;
- /* Reserved for func_valid_cos_bitmap */
- u8 port_cos_valid_bitmap;
- u8 rsvd_func1;
- u32 rsvd_func2;
-
- u8 sf_svc_attr;
- u8 func_sf_en;
- u8 lb_mode;
- u8 smf_pg;
-
- u32 max_conn_num;
- u16 max_stick2cache_num;
- u16 max_bfilter_start_addr;
- u16 bfilter_len;
- u16 hash_bucket_num;
-
- /* shared resource */
- u8 host_sf_en;
- u8 master_host_id;
- u8 srv_multi_host_mode;
- u8 virtio_vq_size;
-
- u32 rsvd_func3[5];
-
- /* l2nic */
- u16 nic_max_sq_id;
- u16 nic_max_rq_id;
- u16 nic_default_num_queues;
- u16 rsvd1_nic;
- u32 rsvd2_nic[2];
-
- /* RoCE */
- u32 roce_max_qp;
- u32 roce_max_cq;
- u32 roce_max_srq;
- u32 roce_max_mpt;
- u32 roce_max_drc_qp;
-
- u32 roce_cmtt_cl_start;
- u32 roce_cmtt_cl_end;
- u32 roce_cmtt_cl_size;
-
- u32 roce_dmtt_cl_start;
- u32 roce_dmtt_cl_end;
- u32 roce_dmtt_cl_size;
-
- u32 roce_wqe_cl_start;
- u32 roce_wqe_cl_end;
- u32 roce_wqe_cl_size;
- u8 roce_srq_container_mode;
- u8 rsvd_roce1[3];
- u32 rsvd_roce2[5];
-
- /* IPsec */
- u32 ipsec_max_sactx;
- u16 ipsec_max_cq;
- u16 rsvd_ipsec1;
- u32 rsvd_ipsec[2];
-
- /* OVS */
- u32 ovs_max_qpc;
- u32 rsvd_ovs1[3];
-
- /* ToE */
- u32 toe_max_pctx;
- u32 toe_max_cq;
- u16 toe_max_srq;
- u16 toe_srq_id_start;
- u16 toe_max_mpt;
- u16 toe_max_cctxt;
- u32 rsvd_toe[2];
-
- /* FC */
- u32 fc_max_pctx;
- u32 fc_max_scq;
- u32 fc_max_srq;
-
- u32 fc_max_cctx;
- u32 fc_cctx_id_start;
-
- u8 fc_vp_id_start;
- u8 fc_vp_id_end;
- u8 rsvd_fc1[2];
- u32 rsvd_fc2[5];
-
- /* VBS */
- u16 vbs_max_volq;
- u16 rsvd0_vbs;
- u32 rsvd1_vbs[3];
-
- u16 fake_vf_start_id;
- u16 fake_vf_num;
- u32 fake_vf_max_pctx;
- u16 fake_vf_bfilter_start_addr;
- u16 fake_vf_bfilter_len;
- u32 rsvd_glb[8];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
deleted file mode 100644
index 59e20a1..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/******************************************************************************
- * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
- ******************************************************************************
- File Name : comm_cmdq_intf.h
- Version : Initial Draft
- Description : common command queue interface
- Function List :
- History :
- Modification: Created file
-
-******************************************************************************/
-
-#ifndef COMM_CMDQ_INTF_H
-#define COMM_CMDQ_INTF_H
-
-/* Cmdq ack type */
-enum hinic3_ack_type {
- HINIC3_ACK_TYPE_CMDQ,
- HINIC3_ACK_TYPE_SHARE_CQN,
- HINIC3_ACK_TYPE_APP_CQN,
-
- HINIC3_MOD_ACK_MAX = 15,
-};
-
-/* Defines the queue type of the set arm bit. */
-enum {
- SET_ARM_BIT_FOR_CMDQ = 0,
- SET_ARM_BIT_FOR_L2NIC_SQ,
- SET_ARM_BIT_FOR_L2NIC_RQ,
- SET_ARM_BIT_TYPE_NUM
-};
-
-/* Defines the type. Each function supports a maximum of eight CMDQ types. */
-enum {
- CMDQ_0 = 0,
- CMDQ_1 = 1, /* dedicated and non-blocking queues */
- CMDQ_NUM
-};
-
-/* *******************cmd common command data structure ************************ */
-// Func->ucode, which is used to set arm bit data,
-// The microcode needs to perform big-endian conversion.
-struct comm_info_ucode_set_arm_bit {
- u32 q_type;
- u32 q_id;
-};
-
-/* *******************WQE data structure ************************ */
-union cmdq_wqe_cs_dw0 {
- struct {
- u32 err_status : 29;
- u32 error_code : 2;
- u32 rsvd : 1;
- } bs;
- u32 val;
-};
-
-union cmdq_wqe_cs_dw1 {
- // This structure is used when the driver writes the wqe.
- struct {
- u32 token : 16; // [15:0]
- u32 cmd : 8; // [23:16]
- u32 mod : 5; // [28:24]
- u32 ack_type : 2; // [30:29]
- u32 obit : 1; // [31]
- } drv_wr;
-
- /* The uCode writes back the structure of the CS_DW1. */
- /* The driver reads and uses the structure. */
- struct {
- u32 mod : 5; // [4:0]
- u32 ack_type : 3; // [7:5]
- u32 cmd : 8; // [15:8]
- u32 arm : 1; // [16]
- u32 rsvd : 14; // [30:17]
- u32 obit : 1; // [31]
- } wb;
- u32 val;
-};
-
-/* CmdQ BD information or write back buffer information */
-struct cmdq_sge {
- u32 pa_h; // Upper 32 bits of the physical address
- u32 pa_l; // Upper 32 bits of the physical address
- u32 len; // Invalid bit[31].
- u32 resv;
-};
-
-/* Ctrls section definition of WQE */
-struct cmdq_wqe_ctrls {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
-};
-
-/* Complete section definition of WQE */
-struct cmdq_wqe_cs {
- union cmdq_wqe_cs_dw0 dw0;
- union cmdq_wqe_cs_dw1 dw1;
- union {
- struct cmdq_sge sge;
- u32 dw2_5[4];
- } ack;
-};
-
-/* Inline header in WQE inline, describing the length of inline data */
-union cmdq_wqe_inline_header {
- struct {
- u32 buf_len : 11; // [10:0] inline data len
- u32 rsv : 21; // [31:11]
- } bs;
- u32 val;
-};
-
-/* Definition of buffer descriptor section in WQE */
-union cmdq_wqe_bds {
- struct {
- struct cmdq_sge bds_sge;
- u32 rsvd[4]; /* Zwy is used to transfer the virtual address of the buffer. */
- } lcmd; /* Long command, non-inline, and SGE describe the buffer information. */
-};
-
-/* Definition of CMDQ WQE */
-/* (long cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(16B) |
- * | |
- * +----------------------------------------+
- * | driver section(16B) |
- * +----------------------------------------+
- *
- *
- * (middle cmd, 128B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(88B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- *
- *
- * (short cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(24B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- */
-struct cmdq_wqe {
- struct cmdq_wqe_ctrls ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds bds;
-};
-
-/* Definition of ctrls section in inline WQE */
-struct cmdq_wqe_ctrls_inline {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
- u64 db;
-};
-
-/* Buffer descriptor section definition of WQE */
-union cmdq_wqe_bds_inline {
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[80];
- } mcmd; /* Middle command, inline mode */
-
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[16];
- } scmd; /* Short command, inline mode */
-};
-
-struct cmdq_wqe_inline {
- struct cmdq_wqe_ctrls_inline ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds_inline bds;
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_defs.h b/drivers/net/ethernet/huawei/hinic3/comm_defs.h
deleted file mode 100644
index c5b1913..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_defs.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_defs.h
- * Version : Initial Draft
- * Description : common definitions
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef COMM_DEFS_H
-#define COMM_DEFS_H
-
-/* CMDQ MODULE_TYPE */
-enum hinic3_mod_type {
- HINIC3_MOD_COMM = 0, /* HW communication module */
- HINIC3_MOD_L2NIC = 1, /* L2NIC module */
- HINIC3_MOD_ROCE = 2,
- HINIC3_MOD_PLOG = 3,
- HINIC3_MOD_TOE = 4,
- HINIC3_MOD_FLR = 5,
- HINIC3_MOD_RSVD1 = 6,
- HINIC3_MOD_CFGM = 7, /* Configuration module */
- HINIC3_MOD_CQM = 8,
- HINIC3_MOD_VMSEC = 9,
- COMM_MOD_FC = 10,
- HINIC3_MOD_OVS = 11,
- HINIC3_MOD_DSW = 12,
- HINIC3_MOD_MIGRATE = 13,
- HINIC3_MOD_HILINK = 14,
- HINIC3_MOD_CRYPT = 15, /* secure crypto module */
- HINIC3_MOD_VIO = 16,
- HINIC3_MOD_IMU = 17,
- HINIC3_MOD_DFT = 18, /* DFT */
- HINIC3_MOD_HW_MAX = 19, /* hardware max module id */
- /* Software module id, for PF/VF and multi-host */
- HINIC3_MOD_SW_FUNC = 20,
- HINIC3_MOD_MAX,
-};
-
-/* func reset的flag ,用于指示清理哪种资源 */
-enum func_reset_flag {
- RES_TYPE_FLUSH_BIT = 0,
- RES_TYPE_MQM,
- RES_TYPE_SMF,
- RES_TYPE_PF_BW_CFG,
-
- RES_TYPE_COMM = 10,
- RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_NIC,
- RES_TYPE_OVS,
- RES_TYPE_VBS,
- RES_TYPE_ROCE,
- RES_TYPE_FC,
- RES_TYPE_TOE,
- RES_TYPE_IPSEC,
- RES_TYPE_MAX,
-};
-
-#define HINIC3_COMM_RES \
- ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
- (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
- (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
-
-#define HINIC3_NIC_RES BIT(RES_TYPE_NIC)
-#define HINIC3_OVS_RES BIT(RES_TYPE_OVS)
-#define HINIC3_VBS_RES BIT(RES_TYPE_VBS)
-#define HINIC3_ROCE_RES BIT(RES_TYPE_ROCE)
-#define HINIC3_FC_RES BIT(RES_TYPE_FC)
-#define HINIC3_TOE_RES BIT(RES_TYPE_TOE)
-#define HINIC3_IPSEC_RES BIT(RES_TYPE_IPSEC)
-
-/* MODE OVS、NIC、UNKNOWN */
-#define HINIC3_WORK_MODE_OVS 0
-#define HINIC3_WORK_MODE_UNKNOWN 1
-#define HINIC3_WORK_MODE_NIC 2
-
-#define DEVICE_TYPE_L2NIC 0
-#define DEVICE_TYPE_NVME 1
-#define DEVICE_TYPE_VIRTIO_NET 2
-#define DEVICE_TYPE_VIRTIO_BLK 3
-#define DEVICE_TYPE_VIRTIO_VSOCK 4
-#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
-#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
-#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
-#define DEVICE_TYPE_VIRTIO_HPC 8
-
-/* Common header control information of the COMM message
- * interaction command word between the driver and PF
- */
-struct comm_info_head {
- u8 status;
- u8 version;
- u8 rep_aeq_num;
- u8 rsvd[5];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
deleted file mode 100644
index ae998cf..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_msg_intf.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef COMM_MSG_INTF_H
-#define COMM_MSG_INTF_H
-
-#include "comm_defs.h"
-#include "mgmt_msg_base.h"
-#include "mpu_cmd_base_defs.h"
-#include "mpu_inband_cmd_defs.h"
-
-struct spu_cmd_freq_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: check */
- u8 rsvd[3];
- u32 freq;
-};
-
-struct spu_cmd_power_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: init */
- u8 slave_addr;
- u8 cmd_id;
- u8 size;
- u32 value;
-};
-
-struct spu_cmd_tsensor_operation {
- struct comm_info_head head;
-
- u8 op_code;
- u8 rsvd[3];
- s16 fabric_tsensor_temp_avg;
- s16 fabric_tsensor_temp;
- s16 sys_tsensor_temp_avg;
- s16 sys_tsensor_temp;
-};
-
-enum cfg_msix_operation {
- CFG_MSIX_OPERATION_FREE = 0,
- CFG_MSIX_OPERATION_ALLOC = 1,
-};
-
-struct comm_cmd_ffm_info {
- struct mgmt_msg_head head;
-
- u8 node_id;
- /* error level of the interrupt source */
- u8 err_level;
- /* Classification by interrupt source properties */
- u16 err_type;
- u32 err_csr_addr;
- u32 err_csr_value;
- u32 rsvd1;
-};
-
-struct hinic3_cmd_update_firmware {
- struct mgmt_msg_head msg_head;
-
- struct {
- u32 sl : 1;
- u32 sf : 1;
- u32 flag : 1;
- u32 bit_signed : 1;
- u32 reserved : 12;
- u32 fragment_len : 16;
- } ctl_info;
-
- struct {
- u32 section_crc;
- u32 section_type;
- } section_info;
-
- u32 total_len;
- u32 section_len;
- u32 section_version;
- u32 section_offset;
- u32 data[384];
-};
-
-struct hinic3_cmd_activate_firmware {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-struct hinic3_cmd_switch_config {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
index 8c95032..8c9f849 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
@@ -28,6 +28,8 @@
#include "cqm_npu_cmd.h"
#include "cqm_npu_cmd_defs.h"
+#include "vram_common.h"
+
static void cqm_bat_fill_cla_common_gpa(struct tag_cqm_handle *cqm_handle,
struct tag_cqm_cla_table *cla_table,
struct tag_cqm_bat_entry_standerd *bat_entry_standerd)
@@ -366,6 +368,13 @@ static s32 cqm_bat_update_cmd(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
struct hinic3_hwdev *handle = cqm_handle->ex_handle;
struct tag_cqm_cmdq_bat_update *bat_update_cmd = NULL;
s32 ret = CQM_FAIL;
+ int is_in_kexec;
+
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip updating the cqm_bat to chip during kexec!\n");
+ return CQM_SUCCESS;
+ }
bat_update_cmd = (struct tag_cqm_cmdq_bat_update *)(buf_in->buf);
bat_update_cmd->offset = 0;
@@ -768,8 +777,10 @@ static s32 cqm_cla_xyz_lvl1(struct tag_cqm_handle *cqm_handle,
/* Applying for CLA_Z_BUF Space */
cla_z_buf = &cla_table->cla_z_buf;
cla_z_buf->buf_size = trunk_size;
- cla_z_buf->buf_number = (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
- cla_z_buf->page_number = cla_z_buf->buf_number << cla_table->trunk_order;
+ cla_z_buf->buf_number =
+ (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
+ cla_z_buf->page_number = cla_z_buf->buf_number <<
+ cla_table->trunk_order;
/* All buffer space must be statically allocated. */
if (cla_table->alloc_static) {
@@ -840,6 +851,7 @@ static s32 cqm_cla_xyz_lvl2_xyz_apply(struct tag_cqm_handle *cqm_handle,
cla_x_buf->buf_size = trunk_size;
cla_x_buf->buf_number = 1;
cla_x_buf->page_number = cla_x_buf->buf_number << cla_table->trunk_order;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
ret = cqm_buf_alloc(cqm_handle, cla_x_buf, false);
if (ret != CQM_SUCCESS)
return CQM_FAIL;
@@ -869,14 +881,20 @@ static s32 cqm_cla_xyz_vram_name_init(struct tag_cqm_cla_table *cla_table,
cla_x_buf = &cla_table->cla_x_buf;
cla_z_buf = &cla_table->cla_z_buf;
cla_y_buf = &cla_table->cla_y_buf;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_x_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_X);
+ VRAM_NAME_MAX_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_X);
+ cla_y_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_y_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Y);
+ VRAM_NAME_MAX_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Y);
+ cla_z_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_z_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Z);
+ VRAM_NAME_MAX_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Z);
return CQM_SUCCESS;
}
@@ -1188,7 +1206,7 @@ static void cqm_cla_init_entry_extern(struct tag_cqm_handle *cqm_handle,
* exceed 128 x 4 KB. Otherwise, clearing the timer buffer of
* the function is complex.
*/
- cla_table->trunk_order = CQM_4K_PAGE_ORDER;
+ cla_table->trunk_order = CQM_8K_PAGE_ORDER;
cla_table->max_buffer_size = capability->timer_number *
capability->timer_basic_size;
cla_table->obj_size = capability->timer_basic_size;
@@ -1237,7 +1255,7 @@ static s32 cqm_cla_init_entry_condition(struct tag_cqm_handle *cqm_handle, u32 e
memcpy(cla_table_timer, cla_table, sizeof(struct tag_cqm_cla_table));
snprintf(cla_table_timer->name,
- VRAM_NAME_MAX_LEN - 1, "%s%s%01u", cla_table->name,
+ VRAM_NAME_MAX_LEN, "%s%s%01u", cla_table->name,
VRAM_CQM_CLA_SMF_BASE, i);
if (cqm_cla_xyz(cqm_handle, cla_table_timer) ==
@@ -1268,7 +1286,7 @@ static s32 cqm_cla_init_entry(struct tag_cqm_handle *cqm_handle,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
cla_table->type = bat_table->bat_entry_type[i];
- snprintf(cla_table->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(cla_table->name, VRAM_NAME_MAX_LEN,
"%s%s%s%02u", cqm_handle->name, VRAM_CQM_CLA_BASE,
VRAM_CQM_CLA_TYPE_BASE, cla_table->type);
@@ -1485,11 +1503,11 @@ static s32 cqm_cla_update(struct tag_cqm_handle *cqm_handle,
spu_en = 0;
pa = ((buf_node_parent->pa + (child_index * sizeof(dma_addr_t))) |
- (u32)spu_en);
+ spu_en);
cmd.gpa_h = CQM_ADDR_HI(pa);
cmd.gpa_l = CQM_ADDR_LW(pa);
- pa = (buf_node_child->pa | (u32)spu_en);
+ pa = (buf_node_child->pa | spu_en);
cmd.value_h = CQM_ADDR_HI(pa);
cmd.value_l = CQM_ADDR_LW(pa);
@@ -1979,7 +1997,7 @@ struct tag_cqm_cla_table *cqm_cla_table_get(struct tag_cqm_bat_table *bat_table,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
- if (cla_table && entry_type == cla_table->type)
+ if ((cla_table != NULL) && (entry_type == cla_table->type))
return cla_table;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
index dd0766e..a51c1dc 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
@@ -9,6 +9,7 @@
#include "cqm_bitmap_table.h"
#include "cqm_object.h"
+#include "vram_common.h"
/* When the connection check is enabled, the maximum number of connections
* supported by the chip is 1M - 63, which cannot reach 1M
@@ -19,6 +20,7 @@
#define CLA_TABLE_PAGE_ORDER 0
#define CQM_4K_PAGE_ORDER 0
#define CQM_4K_PAGE_SIZE 4096
+#define CQM_8K_PAGE_ORDER 1
#define CQM_BAT_ENTRY_MAX 16
#define CQM_BAT_ENTRY_SIZE 16
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
index d5fac94..5f095c8 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
@@ -254,8 +254,10 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
}
pages = vmalloc(sizeof(struct page *) * buf->page_number);
- if (!pages)
+ if (!pages) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(pages));
return CQM_FAIL;
+ }
for (i = 0; i < buf->buf_number; i++) {
for (j = 0; j < ((u32)1 << order); j++)
@@ -273,6 +275,11 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
return CQM_SUCCESS;
}
+static bool check_use_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ return buf->buf_info.use_vram ? true : false;
+}
+
static bool check_use_non_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
{
return buf->buf_info.use_vram ? false : true;
@@ -294,11 +301,46 @@ static bool check_for_nouse_node_alloc(struct hinic3_hwdev *handle, struct tag_c
return false;
}
+static s32 cqm_buf_vram_kalloc(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ void *vaddr = NULL;
+ int i;
+
+ vaddr = hi_vram_kalloc(buf->buf_info.buf_vram_name, (u64)buf->buf_size * buf->buf_number);
+ if (!vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
+ return CQM_FAIL;
+ }
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = (void *)((char *)vaddr + i * (u64)buf->buf_size);
+
+ return CQM_SUCCESS;
+}
+
+static void cqm_buf_vram_free(struct tag_cqm_buf *buf)
+{
+ s32 i;
+
+ if (buf->buf_list == NULL)
+ return;
+
+ if (buf->buf_list[0].va)
+ hi_vram_kfree(buf->buf_list[0].va, buf->buf_info.buf_vram_name,
+ (u64)buf->buf_size * buf->buf_number);
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = NULL;
+}
+
static void cqm_buf_free_page_common(struct tag_cqm_buf *buf)
{
u32 order;
s32 i;
+ if (buf->buf_list == NULL)
+ return;
+
order = (u32)get_order(buf->buf_size);
for (i = 0; i < (s32)buf->buf_number; i++) {
@@ -320,8 +362,10 @@ static s32 cqm_buf_use_node_alloc_page(struct hinic3_hwdev *handle, struct tag_c
node = dev_to_node(handle->dev_hdl);
for (i = 0; i < (s32)buf->buf_number; i++) {
newpage = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, order);
- if (!newpage)
+ if (!newpage) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
va = (void *)page_address(newpage);
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
@@ -349,8 +393,10 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
for (i = 0; i < (s32)buf->buf_number; i++) {
va = (void *)ossl_get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
- if (!va)
+ if (!va) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
* value must be 0.
@@ -367,21 +413,21 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
return CQM_SUCCESS;
}
-#define MALLOC_FUNCS_COUNT 2
-#define FREE_FUNCS_COUNT 1
-static const struct malloc_memory g_malloc_funcs[MALLOC_FUNCS_COUNT] = {
+static const struct malloc_memory g_malloc_funcs[] = {
+ {check_use_vram, cqm_buf_vram_kalloc},
{check_for_use_node_alloc, cqm_buf_use_node_alloc_page},
{check_for_nouse_node_alloc, cqm_buf_unused_node_alloc_page}
};
-static const struct free_memory g_free_funcs[FREE_FUNCS_COUNT] = {
+static const struct free_memory g_free_funcs[] = {
+ {check_use_vram, cqm_buf_vram_free},
{check_use_non_vram, cqm_buf_free_page_common}
};
static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *buf)
{
struct hinic3_hwdev *handle = cqm_handle->ex_handle;
- u32 malloc_funcs_num = MALLOC_FUNCS_COUNT;
+ u32 malloc_funcs_num = ARRAY_SIZE(g_malloc_funcs);
u32 i;
for (i = 0; i < malloc_funcs_num; i++) {
@@ -398,7 +444,7 @@ static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
static void cqm_buf_free_page(struct tag_cqm_buf *buf)
{
- u32 free_funcs_num = FREE_FUNCS_COUNT;
+ u32 free_funcs_num = ARRAY_SIZE(g_free_funcs);
u32 i;
for (i = 0; i < free_funcs_num; i++) {
@@ -447,8 +493,11 @@ static s32 cqm_buf_get_secure_mem_pages(struct tag_cqm_handle *cqm_handle, struc
cqm_get_secure_mem_pages(handle,
(u32)get_order(buf->buf_size),
&buf->buf_list[i].pa);
- if (!buf->buf_list[i].va)
+ if (!buf->buf_list[i].va) {
+ cqm_err(handle->dev_hdl,
+ CQM_ALLOC_FAIL(cqm_get_secure_mem_pages));
break;
+ }
}
if (i != buf->buf_number) {
@@ -777,7 +826,12 @@ static s32 cqm_single_bitmap_init(struct tag_cqm_bitmap *bitmap)
*/
bit_number = (ALIGN(bitmap->max_num, CQM_NUM_BIT_BYTE) >>
CQM_BYTE_BIT_SHIFT);
- bitmap->table = vmalloc(bit_number);
+ if (bitmap->bitmap_info.use_vram != 0)
+ bitmap->table = hi_vram_kalloc(
+ bitmap->bitmap_info.buf_vram_name,
+ bit_number);
+ else
+ bitmap->table = vmalloc(bit_number);
if (!bitmap->table)
return CQM_FAIL;
memset(bitmap->table, 0, bit_number);
@@ -856,7 +910,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
}
bitmap = &cla_table->bitmap;
- snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_MAX_LEN,
"%s%s%02d", cla_table->name,
VRAM_CQM_BITMAP_BASE, cla_table->type);
@@ -866,6 +920,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
bitmap->reserved_top = capability->qpc_reserved;
bitmap->reserved_back = capability->qpc_reserved_back;
bitmap->last = capability->qpc_reserved;
+ bitmap->bitmap_info.use_vram = get_use_vram_flag();
cqm_info(handle->dev_hdl,
"Bitmap init: cla_table_type=%u, max_num=0x%x\n",
cla_table->type, bitmap->max_num);
@@ -945,7 +1000,14 @@ void cqm_bitmap_uninit(struct tag_cqm_handle *cqm_handle)
if (cla_table->type != CQM_BAT_ENTRY_T_INVALID &&
bitmap->table) {
spin_lock_deinit(&bitmap->lock);
- vfree(bitmap->table);
+ if (bitmap->bitmap_info.use_vram != 0)
+ hi_vram_kfree(bitmap->table,
+ bitmap->bitmap_info.buf_vram_name,
+ ALIGN(bitmap->max_num,
+ CQM_NUM_BIT_BYTE) >>
+ CQM_BYTE_BIT_SHIFT);
+ else
+ vfree(bitmap->table);
bitmap->table = NULL;
}
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
index 7febf76..06b8661 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
@@ -9,6 +9,7 @@
#include <linux/spinlock.h>
#include "cqm_object.h"
+#include "vram_common.h"
struct tag_cqm_bitmap {
ulong *table;
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
index 9a13ae0..2a24e4a 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
@@ -196,6 +196,13 @@ void *cqm_get_db_addr(void *ex_handle, u32 service_type)
pr_err("[CQM]%s: ex_handle is null\n", __func__);
return NULL;
}
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return NULL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -218,6 +225,17 @@ s32 cqm_ring_hardware_db(void *ex_handle, u32 service_type, u8 db_count, u64 db)
struct tag_cqm_service *service = NULL;
struct hinic3_hwdev *handle = NULL;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -278,6 +296,17 @@ s32 cqm_ring_direct_wqe_db(void *ex_handle, u32 service_type, u8 db_count,
u64 *tmp = (u64 *)direct_wqe;
int i;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
index 19a8b56..1f1235c 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
@@ -23,6 +23,8 @@
#include "cqm_memsec.h"
#include "cqm_main.h"
+#include "vram_common.h"
+
static unsigned char roce_qpc_rsv_mode = CQM_QPC_ROCE_NORMAL;
module_param(roce_qpc_rsv_mode, byte, 0644);
MODULE_PARM_DESC(roce_qpc_rsv_mode,
@@ -98,10 +100,17 @@ static s32 cqm_set_timer_enable(void *ex_handle)
{
struct hinic3_hwdev *handle = (struct hinic3_hwdev *)ex_handle;
struct tag_cqm_handle *cqm_handle = NULL;
+ int is_in_kexec;
if (!ex_handle)
return CQM_FAIL;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip starting cqm timer during kexec\n");
+ return CQM_SUCCESS;
+ }
+
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
if (cqm_handle->func_capability.fake_func_type == CQM_FAKE_FUNC_PARENT &&
cqm_set_fake_vf_timer(cqm_handle) != CQM_SUCCESS)
@@ -473,7 +482,8 @@ static void cqm_service_capability_init_roce(struct tag_cqm_handle *cqm_handle,
func_cap->qpc_number += roce_own_cap->max_qps;
func_cap->qpc_basic_size = GET_MAX(roce_own_cap->qpc_entry_sz,
func_cap->qpc_basic_size);
- if (cqm_handle->func_attribute.func_type == CQM_PF && (IS_MASTER_HOST(handle))) {
+ if (cqm_handle->func_attribute.func_type == CQM_PF &&
+ (IS_MASTER_HOST(handle))) {
func_cap->hash_number = roce_own_cap->max_qps;
func_cap->hash_basic_size = CQM_HASH_BUCKET_SIZE_64;
}
@@ -1129,8 +1139,9 @@ static s32 cqm_fake_mem_init(struct tag_cqm_handle *cqm_handle)
for (i = 0; i < (u32)child_func_number; i++) {
fake_cqm_handle = cqm_handle->fake_cqm_handle[i];
- snprintf(fake_cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
- "%s%s%02u", cqm_handle->name, VRAM_CQM_FAKE_MEM_BASE, i);
+ snprintf(fake_cqm_handle->name, VRAM_NAME_MAX_LEN,
+ "%s%s%02u", cqm_handle->name,
+ VRAM_CQM_FAKE_MEM_BASE, i);
if (cqm_bat_init(fake_cqm_handle) != CQM_SUCCESS) {
cqm_err(handle->dev_hdl,
@@ -1174,8 +1185,9 @@ s32 cqm_mem_init(void *ex_handle)
struct tag_cqm_handle *cqm_handle = NULL;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
- snprintf(cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
- "%s%02u", VRAM_CQM_GLB_FUNC_BASE, hinic3_global_func_id(handle));
+ snprintf(cqm_handle->name, VRAM_NAME_MAX_LEN,
+ "%s%02u", VRAM_CQM_GLB_FUNC_BASE,
+ hinic3_global_func_id(handle));
if (cqm_fake_init(cqm_handle) != CQM_SUCCESS) {
cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_fake_init));
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
index 4f87bd1..8d1e481 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
@@ -362,6 +362,7 @@ s32 cqm_fake_vf_num_set(void *ex_handle, u16 fake_vf_num_cfg);
#define CQM_LOG_ID 0
#define CQM_PTR_NULL(x) "%s: " #x " is null\n", __func__
+#define CQM_ALLOC_FAIL(x) "%s: " #x " alloc fail\n", __func__
#define CQM_MAP_FAIL(x) "%s: " #x " map fail\n", __func__
#define CQM_FUNCTION_FAIL(x) "%s: " #x " return failure\n", __func__
#define CQM_WRONG_VALUE(x) "%s: " #x " %u is wrong\n", __func__, (u32)(x)
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
index 213803f..f5fce8f 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
@@ -378,7 +378,7 @@ static int hinic3_secure_mem_proc_node_remove(void *hwdev)
atomic_dec(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
@@ -401,7 +401,7 @@ static int hinic3_secure_mem_proc_node_add(void *hwdev)
atomic_inc(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
/* 0400 Read by owner */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h b/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
deleted file mode 100644
index ad732c3..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2019-2022. All rights reserved.
- * File Name : hinic3_comm_cmd.h
- * Version : Initial Draft
- * Created : 2019/4/25
- * Last Modified :
- * Description : COMM Commands between Driver and MPU
- * Function List :
- */
-
-#ifndef HINIC3_COMMON_CMD_H
-#define HINIC3_COMMON_CMD_H
-
-/* COMM Commands between Driver to MPU */
-enum hinic3_mgmt_cmd {
- /* flr及资源清理相关命令 */
- COMM_MGMT_CMD_FUNC_RESET = 0,
- COMM_MGMT_CMD_FEATURE_NEGO,
- COMM_MGMT_CMD_FLUSH_DOORBELL,
- COMM_MGMT_CMD_START_FLUSH,
- COMM_MGMT_CMD_SET_FUNC_FLR,
- COMM_MGMT_CMD_GET_GLOBAL_ATTR,
- COMM_MGMT_CMD_SET_PPF_FLR_TYPE,
- COMM_MGMT_CMD_SET_FUNC_SVC_USED_STATE,
-
- /* 分配msi-x中断资源 */
- COMM_MGMT_CMD_CFG_MSIX_NUM = 10,
-
- /* 驱动相关配置命令 */
- COMM_MGMT_CMD_SET_CMDQ_CTXT = 20,
- COMM_MGMT_CMD_SET_VAT,
- COMM_MGMT_CMD_CFG_PAGESIZE,
- COMM_MGMT_CMD_CFG_MSIX_CTRL_REG,
- COMM_MGMT_CMD_SET_CEQ_CTRL_REG,
- COMM_MGMT_CMD_SET_DMA_ATTR,
-
- /* INFRA配置相关命令字 */
- COMM_MGMT_CMD_GET_MQM_FIX_INFO = 40,
- COMM_MGMT_CMD_SET_MQM_CFG_INFO,
- COMM_MGMT_CMD_SET_MQM_SRCH_GPA,
- COMM_MGMT_CMD_SET_PPF_TMR,
- COMM_MGMT_CMD_SET_PPF_HT_GPA,
- COMM_MGMT_CMD_SET_FUNC_TMR_BITMAT,
- COMM_MGMT_CMD_SET_MBX_CRDT,
- COMM_MGMT_CMD_CFG_TEMPLATE,
- COMM_MGMT_CMD_SET_MQM_LIMIT,
-
- /* 信息获取相关命令字 */
- COMM_MGMT_CMD_GET_FW_VERSION = 60,
- COMM_MGMT_CMD_GET_BOARD_INFO,
- COMM_MGMT_CMD_SYNC_TIME,
- COMM_MGMT_CMD_GET_HW_PF_INFOS,
- COMM_MGMT_CMD_SEND_BDF_INFO,
- COMM_MGMT_CMD_GET_VIRTIO_BDF_INFO,
- COMM_MGMT_CMD_GET_SML_TABLE_INFO,
- COMM_MGMT_CMD_GET_SDI_INFO,
-
- /* 升级相关命令字 */
- COMM_MGMT_CMD_UPDATE_FW = 80,
- COMM_MGMT_CMD_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_DONE_NOTICE,
- COMM_MGMT_CMD_SWITCH_CFG,
- COMM_MGMT_CMD_CHECK_FLASH,
- COMM_MGMT_CMD_CHECK_FLASH_RW,
- COMM_MGMT_CMD_RESOURCE_CFG,
- COMM_MGMT_CMD_UPDATE_BIOS, /* TODO: merge to COMM_MGMT_CMD_UPDATE_FW */
- COMM_MGMT_CMD_MPU_GIT_CODE,
-
- /* chip reset相关 */
- COMM_MGMT_CMD_FAULT_REPORT = 100,
- COMM_MGMT_CMD_WATCHDOG_INFO,
- COMM_MGMT_CMD_MGMT_RESET,
- COMM_MGMT_CMD_FFM_SET, /* TODO: check if needed */
-
- /* chip info/log 相关 */
- COMM_MGMT_CMD_GET_LOG = 120,
- COMM_MGMT_CMD_TEMP_OP,
- COMM_MGMT_CMD_EN_AUTO_RST_CHIP,
- COMM_MGMT_CMD_CFG_REG,
- COMM_MGMT_CMD_GET_CHIP_ID,
- COMM_MGMT_CMD_SYSINFO_DFX,
- COMM_MGMT_CMD_PCIE_DFX_NTC,
- COMM_MGMT_CMD_DICT_LOG_STATUS, /* LOG STATUS 127 */
- COMM_MGMT_CMD_MSIX_INFO,
- COMM_MGMT_CMD_CHANNEL_DETECT,
- COMM_MGMT_CMD_DICT_COUNTER_STATUS,
-
- /* switch workmode 相关 */
- COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140,
- COMM_MGMT_CMD_SWITCH_WORKMODE,
-
- /* mpu 相关 */
- COMM_MGMT_CMD_MIGRATE_DFX_HPA = 150,
- COMM_MGMT_CMD_BDF_INFO,
- COMM_MGMT_CMD_NCSI_CFG_INFO_GET_PROC,
-
- /* rsvd0 section */
- COMM_MGMT_CMD_SECTION_RSVD_0 = 160,
-
- /* rsvd1 section */
- COMM_MGMT_CMD_SECTION_RSVD_1 = 170,
-
- /* rsvd2 section */
- COMM_MGMT_CMD_SECTION_RSVD_2 = 180,
-
- /* rsvd3 section */
- COMM_MGMT_CMD_SECTION_RSVD_3 = 190,
-
- /* TODO: move to DFT mode */
- COMM_MGMT_CMD_GET_DIE_ID = 200,
- COMM_MGMT_CMD_GET_EFUSE_TEST,
- COMM_MGMT_CMD_EFUSE_INFO_CFG,
- COMM_MGMT_CMD_GPIO_CTL,
- COMM_MGMT_CMD_HI30_SERLOOP_START, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_SERLOOP_STOP, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_SET_FLAG, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_GET_RESULT, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_ECC_TEST,
- COMM_MGMT_CMD_FUNC_BIST_TEST, /* 209 */
-
- COMM_MGMT_CMD_VPD_SET = 210,
- COMM_MGMT_CMD_VPD_GET,
-
- COMM_MGMT_CMD_ERASE_FLASH,
- COMM_MGMT_CMD_QUERY_FW_INFO,
- COMM_MGMT_CMD_GET_CFG_INFO,
- COMM_MGMT_CMD_GET_UART_LOG,
- COMM_MGMT_CMD_SET_UART_CMD,
- COMM_MGMT_CMD_SPI_TEST,
-
- /* TODO: ALL reg read/write merge to COMM_MGMT_CMD_CFG_REG */
- COMM_MGMT_CMD_UP_REG_GET,
- COMM_MGMT_CMD_UP_REG_SET, /* 219 */
-
- COMM_MGMT_CMD_REG_READ = 220,
- COMM_MGMT_CMD_REG_WRITE,
- COMM_MGMT_CMD_MAG_REG_WRITE,
- COMM_MGMT_CMD_ANLT_REG_WRITE,
-
- COMM_MGMT_CMD_HEART_EVENT, /* TODO: delete */
- COMM_MGMT_CMD_NCSI_OEM_GET_DRV_INFO, /* TODO: delete */
- COMM_MGMT_CMD_LASTWORD_GET,
- COMM_MGMT_CMD_READ_BIN_DATA, /* TODO: delete */
- /* COMM_MGMT_CMD_WWPN_GET, TODO: move to FC? */
- /* COMM_MGMT_CMD_WWPN_SET, TODO: move to FC? */ /* 229 */
-
- /* TODO: check if needed */
- COMM_MGMT_CMD_SET_VIRTIO_DEV = 230,
- COMM_MGMT_CMD_SET_MAC,
- /* MPU patch cmd */
- COMM_MGMT_CMD_LOAD_PATCH,
- COMM_MGMT_CMD_REMOVE_PATCH,
- COMM_MGMT_CMD_PATCH_ACTIVE,
- COMM_MGMT_CMD_PATCH_DEACTIVE,
- COMM_MGMT_CMD_PATCH_SRAM_OPTIMIZE,
- /* container host process */
- COMM_MGMT_CMD_CONTAINER_HOST_PROC,
- /* nsci counter */
- COMM_MGMT_CMD_NCSI_COUNTER_PROC,
- COMM_MGMT_CMD_CHANNEL_STATUS_CHECK, /* 239 */
-
- /* hot patch rsvd cmd */
- COMM_MGMT_CMD_RSVD_0 = 240,
- COMM_MGMT_CMD_RSVD_1,
- COMM_MGMT_CMD_RSVD_2,
- COMM_MGMT_CMD_RSVD_3,
- COMM_MGMT_CMD_RSVD_4,
- /* 无效字段,版本收编删除,编译使用 */
- COMM_MGMT_CMD_SEND_API_ACK_BY_UP,
-
- /* 注:添加cmd,不能修改已有命令字的值,请在前方rsvd
- * section中添加;原则上所有分支cmd表完全一致
- */
- COMM_MGMT_CMD_MAX = 255,
-};
-
-/* CmdQ Common subtype */
-enum comm_cmdq_cmd {
- COMM_CMD_UCODE_ARM_BIT_SET = 2,
- COMM_CMD_SEND_NPU_DFT_CMD,
-};
-
-#endif /* HINIC3_COMMON_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
deleted file mode 100644
index 9ce908e..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_COMMON_H
-#define HINIC3_COMMON_H
-
-#include <linux/types.h>
-
-struct hinic3_dma_addr_align {
- u32 real_size;
-
- void *ori_vaddr;
- dma_addr_t ori_paddr;
-
- void *align_vaddr;
- dma_addr_t align_paddr;
-};
-
-enum hinic3_wait_return {
- WAIT_PROCESS_CPL = 0,
- WAIT_PROCESS_WAITING = 1,
- WAIT_PROCESS_ERR = 2,
-};
-
-struct hinic3_sge {
- u32 hi_addr;
- u32 lo_addr;
- u32 len;
-};
-
-#ifdef static
-#undef static
-#define LLT_STATIC_DEF_SAVED
-#endif
-
-/* *
- * hinic_cpu_to_be32 - convert data to big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert, must be Multiple of 4B
- */
-static inline void hinic3_cpu_to_be32(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = cpu_to_be32(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_cpu_to_be32 - convert data from big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert
- */
-static inline void hinic3_be32_to_cpu(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = be32_to_cpu(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_set_sge - set dma area in scatter gather entry
- * @sge: scatter gather entry
- * @addr: dma address
- * @len: length of relevant data in the dma address
- */
-static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
- int len)
-{
- sge->hi_addr = upper_32_bits(addr);
- sge->lo_addr = lower_32_bits(addr);
- sge->len = len;
-}
-
-#define hinic3_hw_be32(val) (val)
-#define hinic3_hw_cpu32(val) (val)
-#define hinic3_hw_cpu16(val) (val)
-
-static inline void hinic3_hw_be32_len(void *data, int len)
-{
-}
-
-static inline void hinic3_hw_cpu32_len(void *data, int len)
-{
-}
-
-int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
- unsigned int flag,
- struct hinic3_dma_addr_align *mem_align);
-
-void hinic3_dma_free_coherent_align(void *dev_hdl,
- struct hinic3_dma_addr_align *mem_align);
-
-typedef enum hinic3_wait_return (*wait_cpl_handler)(void *priv_data);
-
-int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
- u32 wait_total_ms, u32 wait_once_us);
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
index 64139c4..4f5792f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
@@ -8,7 +8,7 @@
#include "mpu_cmd_base_defs.h"
-#define HINIC3_DRV_VERSION "15.17.1.2"
+#define HINIC3_DRV_VERSION "17.7.8.1"
#define HINIC3_DRV_DESC "Intelligent Network Interface Card Driver"
#define HIUDK_DRV_DESC "Intelligent Network Unified Driver"
@@ -45,6 +45,7 @@ enum hinic3_service_type {
SERVICE_T_CUSTOM,
SERVICE_T_VROCE,
SERVICE_T_CRYPT,
+ SERVICE_T_VSOCK,
SERVICE_T_BIFUR,
SERVICE_T_MAX,
@@ -64,6 +65,9 @@ struct nic_service_cap {
u16 max_sqs;
u16 max_rqs;
u16 default_num_queues;
+ u16 outband_vlan_cfg_en;
+ u8 lro_enable;
+ u8 rsvd1[3];
};
struct ppa_service_cap {
@@ -909,6 +913,13 @@ int hinic3_get_mgmt_version(void *hwdev, u8 *mgmt_ver, u8 version_size,
int hinic3_get_fw_version(void *hwdev, struct hinic3_fw_version *fw_ver,
u16 channel);
+/* *
+ * @brief hinic3_get_bond_create_mode - get bond create mode
+ * @param hwdev: device pointer to hwdev
+ * @retval global function id
+ */
+u8 hinic3_get_bond_create_mode(void *udkdev);
+
/* *
* @brief hinic3_global_func_id - get global function id
* @param hwdev: device pointer to hwdev
@@ -1263,4 +1274,7 @@ int hinic3_mbox_to_host_sync(void *hwdev, enum hinic3_mod_type mod,
int hinic3_get_func_vroce_enable(void *hwdev, u16 glb_func_idx, u8 *en);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type);
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
index 40ff473..8f5bb32 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
@@ -18,9 +18,10 @@
#include "hinic3_tx.h"
#include "hinic3_dcb.h"
#include "hinic3_nic.h"
-#include "hinic3_mgmt_interface.h"
+#include "hinic3_bond.h"
+#include "nic_mpu_cmd_defs.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
typedef int (*nic_driv_module)(struct hinic3_nic_dev *nic_dev,
const void *buf_in, u32 in_size,
@@ -34,7 +35,6 @@ struct nic_drv_module_handle {
static int get_nic_drv_version(void *buf_out, const u32 *out_size)
{
struct drv_version_info *ver_info = buf_out;
- int err;
if (!buf_out) {
pr_err("Buf_out is NULL.\n");
@@ -47,10 +47,8 @@ static int get_nic_drv_version(void *buf_out, const u32 *out_size)
return -EINVAL;
}
- err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
- HINIC3_NIC_DRV_VERSION, "2023-05-17_19:56:38");
- if (err < 0)
- return -EINVAL;
+ snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
+ HINIC3_NIC_DRV_VERSION, "2025-05-08_00:00:08");
return 0;
}
@@ -126,7 +124,8 @@ static int get_tx_wqe_info(struct hinic3_nic_dev *nic_dev,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -178,7 +177,8 @@ static int get_rx_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
rq_info->delta = (u16)nic_dev->rxqs[q_id].delta;
- rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx & nic_dev->rxqs[q_id].q_mask);
+ rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx &
+ nic_dev->rxqs[q_id].q_mask);
rq_info->sw_pi = nic_dev->rxqs[q_id].next_to_update;
rq_info->msix_vector = nic_dev->rxqs[q_id].irq_id;
@@ -201,7 +201,8 @@ static int get_rx_wqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -230,7 +231,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EFAULT;
}
- if (!buf_in || !buf_out) {
+ if (!buf_in || !buf_out || !out_size) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Buf_in or buf_out is NULL.\n");
return -EINVAL;
@@ -243,7 +244,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EINVAL;
}
- if (!out_size || *out_size != sizeof(struct hinic3_rq_cqe)) {
+ if (*out_size != sizeof(struct hinic3_rq_cqe)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(struct hinic3_rq_cqe));
@@ -252,10 +253,12 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
q_id = (u16)info->q_id;
idx = (u16)info->wqe_id;
- if (q_id >= nic_dev->q_params.num_qps || idx >= nic_dev->rxqs[q_id].q_depth) {
+ if (q_id >= nic_dev->q_params.num_qps ||
+ idx >= nic_dev->rxqs[q_id].q_depth) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid q_id[%u] >= %u, or wqe idx[%u] >= %u.\n",
- q_id, nic_dev->q_params.num_qps, idx, nic_dev->rxqs[q_id].q_depth);
+ q_id, nic_dev->q_params.num_qps, idx,
+ nic_dev->rxqs[q_id].q_depth);
return -EFAULT;
}
@@ -338,7 +341,8 @@ static int set_loopback_mode(struct hinic3_nic_dev *nic_dev, const void *buf_in,
err = hinic3_set_loopback_mode(nic_dev->hwdev, (u8)mode->loop_mode,
(u8)mode->loop_ctrl);
if (err == 0)
- nicif_info(nic_dev, drv, nic_dev->netdev, "Set loopback mode %u en %u succeed\n",
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Set loopback mode %u en %u succeed\n",
mode->loop_mode, mode->loop_ctrl);
return err;
@@ -417,6 +421,59 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
{
u32 pf_bw_limit;
int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
+
+ if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To set VF bandwidth rate, please use ip link cmd\n");
+ return -EINVAL;
+ }
+
+ if (!buf_in || !buf_out || in_size != sizeof(u32) ||
+ !out_size || *out_size != sizeof(u8))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_TX;
+ pf_bw_limit = *((u32 *)buf_in);
+
+ err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
+ if (err) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %u%%\n",
+ pf_bw_limit);
+ if (err < 0)
+ return err;
+ }
+
+ *((u8 *)buf_out) = (u8)err;
+
+ return 0;
+}
+
+static int set_rx_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ u32 pf_bw_limit;
+ int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
nicif_err(nic_dev, drv, nic_dev->netdev, "To set VF bandwidth rate, please use ip link cmd\n");
@@ -426,11 +483,16 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || !buf_out || in_size != sizeof(u32) || !out_size || *out_size != sizeof(u8))
return -EINVAL;
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_RX;
pf_bw_limit = *((u32 *)buf_in);
err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %d%%\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to set pf bandwidth limit to %d%%\n",
pf_bw_limit);
if (err < 0)
return err;
@@ -445,19 +507,21 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
struct hinic3_nic_io *nic_io = NULL;
+ u32 *rate_limit = (u32 *)buf_out;
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "To get VF bandwidth rate, please use ip link cmd\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To get VF bandwidth rate, please use ip link cmd\n");
return -EINVAL;
}
if (!buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(u32)) {
+ if (*out_size != sizeof(u32) * 2) { // 2:Stored in an array, TX and RX, both length are u32
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user: %d, expect: %lu\n",
- *out_size, sizeof(u32));
+ *out_size, sizeof(u32) * 2);
return -EFAULT;
}
@@ -465,8 +529,12 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!nic_io)
return -EINVAL;
- *((u32 *)buf_out) = nic_io->nic_cfg.pf_bw_limit;
+ rate_limit[HINIC3_NIC_RX] = nic_io->nic_cfg.pf_bw_rx_limit;
+ rate_limit[HINIC3_NIC_TX] = nic_io->nic_cfg.pf_bw_tx_limit;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "read rate cfg success rx rate is: %u, tx rate is : %u\n",
+ rate_limit[HINIC3_NIC_RX], rate_limit[HINIC3_NIC_TX]);
return 0;
}
@@ -477,8 +545,8 @@ static int get_sset_count(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || in_size != sizeof(u32) || !out_size ||
*out_size != sizeof(u32) || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
@@ -504,16 +572,16 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
int err;
if (!buf_in || in_size != sizeof(u32) || !out_size || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
size = sizeof(u32);
err = get_sset_count(nic_dev, buf_in, in_size, &count, &size);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Get sset count failed, ret=%d\n",
- err);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Get sset count failed, ret=%d\n", err);
return -EINVAL;
}
if (count * sizeof(*items) != *out_size) {
@@ -527,12 +595,14 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
switch (sset) {
case HINIC3_SHOW_SSET_IO_STATS:
- hinic3_get_io_stats(nic_dev, items);
+ err = hinic3_get_io_stats(nic_dev, items);
+ if (err < 0)
+ return -EINVAL;
break;
default:
- nicif_err(nic_dev, drv, nic_dev->netdev, "Unknown %u to get stats\n",
- sset);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unknown %u to get stats\n", sset);
err = -EINVAL;
break;
}
@@ -544,15 +614,18 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int i;
u8 cos_num = 0, valid_cos_bitmap = 0;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_PCP2COS) {
for (i = 0; i < NIC_DCB_UP_MAX; i++) {
- if (!(nic_dev->func_dft_cos_bitmap & BIT(qos_in->pcp2cos[i]))) {
+ if (!(dcb->func_dft_cos_bitmap &
+ BIT(qos_in->pcp2cos[i]))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- qos_in->pcp2cos[i], nic_dev->func_dft_cos_bitmap);
+ qos_in->pcp2cos[i],
+ dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -562,7 +635,8 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
}
- memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos, sizeof(qos_in->pcp2cos));
+ memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos,
+ sizeof(qos_in->pcp2cos));
wanted_dcb_cfg->pcp_user_cos_num = cos_num;
wanted_dcb_cfg->pcp_valid_cos_map = valid_cos_bitmap;
}
@@ -572,12 +646,14 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = 0;
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++) {
u8 cos = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->wanted_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ dcb->wanted_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
- if (cos >= NIC_DCB_UP_MAX || !(nic_dev->func_dft_cos_bitmap & BIT(cos))) {
+ if (cos >= NIC_DCB_UP_MAX ||
+ !(dcb->func_dft_cos_bitmap & BIT(cos))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- cos, nic_dev->func_dft_cos_bitmap);
+ cos, dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -588,8 +664,10 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- wanted_dcb_cfg->dscp2cos[i] = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->hw_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ wanted_dcb_cfg->dscp2cos[i] =
+ qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
+ dcb->hw_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
wanted_dcb_cfg->dscp_user_cos_num = cos_num;
wanted_dcb_cfg->dscp_valid_cos_map = valid_cos_bitmap;
}
@@ -601,11 +679,12 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int ret;
u8 cos_num, valid_cos_bitmap;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_TRUST) {
- if (qos_in->trust > DCB_DSCP) {
+ if (qos_in->trust > HINIC3_DCB_DSCP) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid trust=%u\n", qos_in->trust);
return -EINVAL;
@@ -615,7 +694,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
}
if (qos_in->cfg_bitmap & CMD_QOS_DEV_DFT_COS) {
- if (!(BIT(qos_in->dft_cos) & nic_dev->func_dft_cos_bitmap)) {
+ if (!(BIT(qos_in->dft_cos) & dcb->func_dft_cos_bitmap)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid dft_cos=%u\n", qos_in->dft_cos);
return -EINVAL;
@@ -628,7 +707,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
if (ret)
return ret;
- if (wanted_dcb_cfg->trust == DCB_PCP) {
+ if (wanted_dcb_cfg->trust == HINIC3_DCB_PCP) {
cos_num = wanted_dcb_cfg->pcp_user_cos_num;
valid_cos_bitmap = wanted_dcb_cfg->pcp_valid_cos_map;
} else {
@@ -636,18 +715,11 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = wanted_dcb_cfg->dscp_valid_cos_map;
}
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "DCB is on, cos num should not more than channel num:%u\n",
- nic_dev->q_params.num_qps);
- return -EOPNOTSUPP;
- }
- }
-
if (!(BIT(wanted_dcb_cfg->default_cos) & valid_cos_bitmap)) {
- nicif_info(nic_dev, drv, nic_dev->netdev, "Current default_cos=%u, change to %u\n",
- wanted_dcb_cfg->default_cos, (u8)fls(valid_cos_bitmap) - 1);
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Current default_cos=%u, change to %u\n",
+ wanted_dcb_cfg->default_cos,
+ (u8)fls(valid_cos_bitmap) - 1);
wanted_dcb_cfg->default_cos = (u8)fls(valid_cos_bitmap) - 1;
}
@@ -657,6 +729,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_dev_cfg *qos_in = buf_in;
struct hinic3_mt_qos_dev_cfg *qos_out = buf_out;
u8 i;
@@ -675,9 +748,10 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(qos_out, qos_in, sizeof(*qos_in));
qos_out->head.status = 0;
if (qos_in->op_code & MT_DCB_OPCODE_WR) {
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg,
+ memcpy(&dcb->wanted_dcb_cfg, &dcb->hw_dcb_cfg,
sizeof(struct hinic3_dcb_config));
- err = update_wanted_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg, qos_in);
+ err = update_wanted_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg,
+ qos_in);
if (err) {
qos_out->head.status = MT_EINVAL;
return 0;
@@ -687,12 +761,12 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
qos_out->head.status = MT_EIO;
} else {
- qos_out->dft_cos = nic_dev->hw_dcb_cfg.default_cos;
- qos_out->trust = nic_dev->hw_dcb_cfg.trust;
+ qos_out->dft_cos = dcb->hw_dcb_cfg.default_cos;
+ qos_out->trust = dcb->hw_dcb_cfg.trust;
for (i = 0; i < NIC_DCB_UP_MAX; i++)
- qos_out->pcp2cos[i] = nic_dev->hw_dcb_cfg.pcp2cos[i];
+ qos_out->pcp2cos[i] = dcb->hw_dcb_cfg.pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- qos_out->dscp2cos[i] = nic_dev->hw_dcb_cfg.dscp2cos[i];
+ qos_out->dscp2cos[i] = dcb->hw_dcb_cfg.dscp2cos[i];
}
return 0;
@@ -721,27 +795,17 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(dcb_out, dcb_in, sizeof(*dcb_in));
dcb_out->head.status = 0;
if (dcb_in->op_code & MT_DCB_OPCODE_WR) {
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) == dcb_in->state)
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ==
+ dcb_in->state)
return 0;
- if (dcb_in->state) {
- if (user_cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "cos num %u should not more than channel num %u\n",
- user_cos_num,
- nic_dev->q_params.num_qps);
-
- return -EOPNOTSUPP;
- }
- }
-
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? user_cos_num : 0,
+ err = hinic3_setup_cos(nic_dev->netdev,
+ dcb_in->state ? user_cos_num : 0,
netif_run);
if (err)
goto setup_cos_fail;
@@ -751,7 +815,6 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
goto vport_up_fail;
}
- rtnl_unlock();
} else {
dcb_out->state = !!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
}
@@ -759,12 +822,12 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
vport_up_fail:
- hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num,
+ netif_run);
setup_cos_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
return err;
}
@@ -772,13 +835,15 @@ setup_cos_fail:
static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_cos_cfg *cos_cfg_in = buf_in;
struct hinic3_mt_qos_cos_cfg *cos_cfg_out = buf_out;
if (!buf_in || !buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(*cos_cfg_out) || in_size != sizeof(*cos_cfg_in)) {
+ if (*out_size != sizeof(*cos_cfg_out) ||
+ in_size != sizeof(*cos_cfg_in)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
in_size, *out_size, sizeof(*cos_cfg_in));
@@ -789,9 +854,9 @@ static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
cos_cfg_out->head.status = 0;
cos_cfg_out->port_id = hinic3_physical_port_id(nic_dev->hwdev);
- cos_cfg_out->func_cos_bitmap = (u8)nic_dev->func_dft_cos_bitmap;
- cos_cfg_out->port_cos_bitmap = (u8)nic_dev->port_dft_cos_bitmap;
- cos_cfg_out->func_max_cos_num = nic_dev->cos_config_num_max;
+ cos_cfg_out->func_cos_bitmap = (u8)dcb->func_dft_cos_bitmap;
+ cos_cfg_out->port_cos_bitmap = (u8)dcb->port_dft_cos_bitmap;
+ cos_cfg_out->func_max_cos_num = dcb->cos_config_num_max;
return 0;
}
@@ -803,7 +868,13 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
intr_num = hinic3_intr_num(nic_dev->hwdev);
- if (!buf_out || !out_size || *out_size != sizeof(u16)) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != sizeof(u16)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(u16));
@@ -817,7 +888,13 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
static int get_netdev_name(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- if (!buf_out || !out_size || *out_size != IFNAMSIZ) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != IFNAMSIZ) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %u\n",
*out_size, IFNAMSIZ);
@@ -829,8 +906,9 @@ static int get_netdev_name(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
}
-static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
int *tx_timeout = buf_out;
@@ -839,7 +917,8 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (*out_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, out_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, out_size: %u, expect: %lu\n",
*out_size, sizeof(int));
return -EINVAL;
}
@@ -849,8 +928,9 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return 0;
}
-static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
const int *tx_timeout = buf_in;
@@ -859,13 +939,15 @@ static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (in_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, in_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, in_size: %u, expect: %lu\n",
in_size, sizeof(int));
return -EINVAL;
}
net_dev->watchdog_timeo = *tx_timeout * HZ;
- nicif_info(nic_dev, drv, net_dev, "Set tx timeout check period to %ds\n", *tx_timeout);
+ nicif_info(nic_dev, drv, net_dev,
+ "Set tx timeout check period to %ds\n", *tx_timeout);
return 0;
}
@@ -891,6 +973,34 @@ static int get_xsfp_present(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
}
+static int get_xsfp_tlv_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info = buf_out;
+ const struct tag_mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req = buf_in;
+ int err;
+
+ if ((buf_in == NULL) || (buf_out == NULL) || (out_size == NULL))
+ return -EINVAL;
+
+ if (*out_size != sizeof(*sfp_tlv_info) ||
+ in_size != sizeof(*sfp_tlv_info_req)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
+ in_size, *out_size, sizeof(*sfp_tlv_info));
+ return -EINVAL;
+ }
+
+ err = hinic3_get_sfp_tlv_info(nic_dev->hwdev,
+ sfp_tlv_info, sfp_tlv_info_req);
+ if (err != 0) {
+ sfp_tlv_info->head.status = MT_EIO;
+ return 0;
+ }
+
+ return 0;
+}
+
static int get_xsfp_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
@@ -928,7 +1038,7 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{GET_LOOPBACK_MODE, get_loopback_mode},
{SET_LOOPBACK_MODE, set_loopback_mode},
{SET_LINK_MODE, set_link_mode},
- {SET_PF_BW_LIMIT, set_pf_bw_limit},
+ {SET_TX_PF_BW_LIMIT, set_pf_bw_limit},
{GET_PF_BW_LIMIT, get_pf_bw_limit},
{GET_SSET_COUNT, get_sset_count},
{GET_SSET_ITEMS, get_sset_stats},
@@ -940,17 +1050,22 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{SET_TX_TIMEOUT, set_netdev_tx_timeout},
{GET_XSFP_PRESENT, get_xsfp_present},
{GET_XSFP_INFO, get_xsfp_info},
+ {GET_XSFP_INFO_COMP_CMIS, get_xsfp_tlv_info},
+ {SET_RX_PF_BW_LIMIT, set_rx_pf_bw_limit}
};
static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
u32 cmd, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(nic_driv_module_cmd_handle) /
- sizeof(nic_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(nic_driv_module_cmd_handle) /
+ sizeof(nic_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type = (enum driver_cmd_type)cmd;
int err = 0;
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_lock();
+
mutex_lock(&nic_dev->nic_mutex);
for (index = 0; index < num_cmds; index++) {
if (cmd_type ==
@@ -963,6 +1078,9 @@ static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
}
mutex_unlock(&nic_dev->nic_mutex);
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_unlock();
+
if (index == num_cmds) {
pr_err("Can't find callback for %d\n", cmd_type);
return -EINVAL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
index a1fb4af..ba4ec4d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
@@ -24,82 +24,80 @@
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_user_cos_num;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_user_cos_num;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_user_cos_num;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_user_cos_num;
return 0;
}
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_valid_cos_map;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_valid_cos_map;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_valid_cos_map;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_valid_cos_map;
return 0;
}
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
- u8 i, remainder, num_sq_per_cos, cur_cos_num = 0;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ struct hinic3_dcb_config *wanted_dcb_cfg =
+ &nic_dev->dcb->wanted_dcb_cfg;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
+ u8 cos_qp_num, cos_qp_offset = 0;
+ u8 i, remainder, num_qp_per_cos;
- if (num_cos == 0)
- return;
-
- num_sq_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
- if (num_sq_per_cos == 0)
+ if (num_cos == 0 || nic_dev->q_params.num_qps == 0)
return;
- remainder = nic_dev->q_params.num_qps % num_sq_per_cos;
+ num_qp_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
+ remainder = nic_dev->q_params.num_qps % num_cos;
- memset(dcb_cfg->cos_qp_offset, 0, sizeof(dcb_cfg->cos_qp_offset));
- memset(dcb_cfg->cos_qp_num, 0, sizeof(dcb_cfg->cos_qp_num));
+ memset(hw_dcb_cfg->cos_qp_offset, 0, sizeof(hw_dcb_cfg->cos_qp_offset));
+ memset(hw_dcb_cfg->cos_qp_num, 0, sizeof(hw_dcb_cfg->cos_qp_num));
for (i = 0; i < PCP_MAX_UP; i++) {
if (BIT(i) & valid_cos_map) {
- u8 cos_qp_num = num_sq_per_cos;
- u8 cos_qp_offset = (u8)(cur_cos_num * num_sq_per_cos);
-
- if (cur_cos_num < remainder) {
- cos_qp_num++;
- cos_qp_offset += cur_cos_num;
- } else {
- cos_qp_offset += remainder;
- }
-
- cur_cos_num++;
- valid_cos_map -= (u8)BIT(i);
+ cos_qp_num = num_qp_per_cos + ((remainder > 0) ?
+ (remainder--, 1) : 0);
- dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
- dcb_cfg->cos_qp_num[i] = cos_qp_num;
+ hw_dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
+ hw_dcb_cfg->cos_qp_num[i] = cos_qp_num;
hinic3_info(nic_dev, drv, "cos %u, cos_qp_offset=%u cos_qp_num=%u\n",
i, cos_qp_offset, cos_qp_num);
+
+ cos_qp_offset += cos_qp_num;
+ valid_cos_map -= (u8)BIT(i);
}
}
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_offset, dcb_cfg->cos_qp_offset,
- sizeof(dcb_cfg->cos_qp_offset));
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_num, dcb_cfg->cos_qp_num,
- sizeof(dcb_cfg->cos_qp_num));
+ memcpy(wanted_dcb_cfg->cos_qp_offset, hw_dcb_cfg->cos_qp_offset,
+ sizeof(hw_dcb_cfg->cos_qp_offset));
+ memcpy(wanted_dcb_cfg->cos_qp_num, hw_dcb_cfg->cos_qp_num,
+ sizeof(hw_dcb_cfg->cos_qp_num));
}
void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
u8 i;
u16 start_qid, q_num;
hinic3_set_txq_cos(nic_dev, 0, nic_dev->q_params.num_qps,
- nic_dev->hw_dcb_cfg.default_cos);
+ hw_dcb_cfg->default_cos);
if (!dcb_en)
return;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- q_num = (u16)nic_dev->hw_dcb_cfg.cos_qp_num[i];
+ q_num = (u16)hw_dcb_cfg->cos_qp_num[i];
if (q_num) {
- start_qid = (u16)nic_dev->hw_dcb_cfg.cos_qp_offset[i];
+ start_qid = (u16)hw_dcb_cfg->cos_qp_offset[i];
hinic3_set_txq_cos(nic_dev, start_qid, q_num, i);
hinic3_info(nic_dev, drv, "update tx db cos, start_qid %u, q_num=%u cos=%u\n",
@@ -110,30 +108,28 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ struct hinic3_dcb_config *hw_dcb_cfg = &dcb->hw_dcb_cfg;
struct hinic3_dcb_state dcb_state = {0};
u8 i;
int err;
-
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- /* VF does not support DCB, use the default cos */
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
-
- return 0;
- }
+ u32 pcp2cos_size = sizeof(dcb_state.pcp2cos);
+ u32 dscp2cos_size = sizeof(dcb_state.dscp2cos);
dcb_state.dcb_on = dcb_en;
- dcb_state.default_cos = dcb_cfg->default_cos;
- dcb_state.trust = dcb_cfg->trust;
+ dcb_state.default_cos = hw_dcb_cfg->default_cos;
+ dcb_state.trust = hw_dcb_cfg->trust;
if (dcb_en) {
for (i = 0; i < NIC_DCB_COS_MAX; i++)
- dcb_state.pcp2cos[i] = dcb_cfg->pcp2cos[i];
+ dcb_state.pcp2cos[i] = hw_dcb_cfg->pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- dcb_state.dscp2cos[i] = dcb_cfg->dscp2cos[i];
+ dcb_state.dscp2cos[i] = hw_dcb_cfg->dscp2cos[i];
} else {
- memset(dcb_state.pcp2cos, dcb_cfg->default_cos, sizeof(dcb_state.pcp2cos));
- memset(dcb_state.dscp2cos, dcb_cfg->default_cos, sizeof(dcb_state.dscp2cos));
+ memset(dcb_state.pcp2cos, hw_dcb_cfg->default_cos,
+ pcp2cos_size);
+ memset(dcb_state.dscp2cos, hw_dcb_cfg->default_cos,
+ dscp2cos_size);
}
err = hinic3_set_dcb_state(nic_dev->hwdev, &dcb_state);
@@ -143,7 +139,7 @@ static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
return err;
}
-static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
int err;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
@@ -169,11 +165,13 @@ static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
goto rx_configure_fail;
}
- if (dcb_en)
+ if (dcb_en) {
set_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
- else
+ set_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ } else {
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
-
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ }
return 0;
rx_configure_fail:
hinic3_set_tx_cos_state(nic_dev, dcb_en ? 0 : 1);
@@ -188,6 +186,7 @@ set_tx_cos_fail:
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err;
if (cos && test_bit(HINIC3_SAME_RXTX, &nic_dev->flags)) {
@@ -195,9 +194,10 @@ int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
return -EOPNOTSUPP;
}
- if (cos > nic_dev->cos_config_num_max) {
- nicif_err(nic_dev, drv, netdev, "Invalid num_tc: %u, max cos: %u\n",
- cos, nic_dev->cos_config_num_max);
+ if (cos > dcb->cos_config_num_max) {
+ nicif_err(nic_dev, drv, netdev,
+ "Invalid num_tc: %u, max cos: %u\n",
+ cos, dcb->cos_config_num_max);
return -EINVAL;
}
@@ -223,36 +223,48 @@ static u8 get_cos_num(u8 hw_valid_cos_bitmap)
static void hinic3_sync_dcb_cfg(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dcb_config *dcb_cfg)
{
- struct hinic3_dcb_config *hw_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
- memcpy(hw_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(hw_dcb_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
}
static int init_default_dcb_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *dcb_cfg)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 i, hw_dft_cos_map, port_cos_bitmap, dscp_ind;
int err;
+ int is_in_kexec;
- err = hinic3_cos_valid_bitmap(nic_dev->hwdev, &hw_dft_cos_map, &port_cos_bitmap);
+ err = hinic3_cos_valid_bitmap(nic_dev->hwdev,
+ &hw_dft_cos_map, &port_cos_bitmap);
if (err) {
hinic3_err(nic_dev, drv, "None cos supported\n");
return -EFAULT;
}
- nic_dev->func_dft_cos_bitmap = hw_dft_cos_map;
- nic_dev->port_dft_cos_bitmap = port_cos_bitmap;
- nic_dev->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+ is_in_kexec = vram_get_kexec_flag();
- dcb_cfg->trust = DCB_PCP;
- dcb_cfg->pcp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->dscp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
+ dcb->func_dft_cos_bitmap = hw_dft_cos_map;
+ dcb->port_dft_cos_bitmap = port_cos_bitmap;
+
+ dcb->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+
+ if (is_in_kexec == 0) {
+ dcb_cfg->trust = HINIC3_DCB_PCP;
+ dcb_cfg->default_cos = (u8)fls(dcb->func_dft_cos_bitmap) - 1;
+ } else {
+ dcb_cfg->trust = nic_dev->dcb->hw_dcb_cfg.trust;
+ dcb_cfg->default_cos = nic_dev->dcb->hw_dcb_cfg.default_cos;
+ }
+ dcb_cfg->pcp_user_cos_num = dcb->cos_config_num_max;
+ dcb_cfg->dscp_user_cos_num = dcb->cos_config_num_max;
dcb_cfg->pcp_valid_cos_map = hw_dft_cos_map;
dcb_cfg->dscp_valid_cos_map = hw_dft_cos_map;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i) ? i : dcb_cfg->default_cos;
+ dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i) ?
+ i : (u8)fls(dcb->func_dft_cos_bitmap) - 1;
for (dscp_ind = 0; dscp_ind < NIC_DCB_COS_MAX; dscp_ind++)
dcb_cfg->dscp2cos[i * NIC_DCB_DSCP_NUM + dscp_ind] = dcb_cfg->pcp2cos[i];
}
@@ -276,58 +288,117 @@ int hinic3_configure_dcb(struct net_device *netdev)
int err;
err = hinic3_sync_dcb_state(nic_dev->hwdev, 1,
- test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)
+ ? 1 : 0);
if (err) {
hinic3_err(nic_dev, drv, "Set dcb state failed\n");
return err;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ hinic3_sync_dcb_cfg(nic_dev, &nic_dev->dcb->wanted_dcb_cfg);
else
hinic3_dcb_reset_hw_config(nic_dev);
return 0;
}
+static int hinic3_dcb_alloc(struct hinic3_nic_dev *nic_dev)
+{
+ u16 func_id;
+ int is_use_vram;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(nic_dev->dcb_name, VRAM_NAME_MAX_LEN,
+ "%s%hu%s", VRAM_CQM_GLB_FUNC_BASE, func_id,
+ VRAM_NIC_DCB);
+
+ nic_dev->dcb = (struct hinic3_dcb *)hi_vram_kalloc(nic_dev->dcb_name,
+ sizeof(*nic_dev->dcb));
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to vram alloc dcb.\n");
+ return -EFAULT;
+ }
+ } else {
+ nic_dev->dcb = kzalloc(sizeof(*nic_dev->dcb), GFP_KERNEL);
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to create dcb.\n");
+ return -EFAULT;
+ }
+ }
+
+ return 0;
+}
+
+static void hinic3_dcb_free(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram)
+ hi_vram_kfree((void *)nic_dev->dcb, nic_dev->dcb_name,
+ sizeof(*nic_dev->dcb));
+ else
+ kfree(nic_dev->dcb);
+ nic_dev->dcb = NULL;
+}
+
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
+ hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+
+ hinic3_dcb_free(nic_dev);
+}
+
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = NULL;
int err;
u8 dcb_en = test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0;
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- return hinic3_set_tx_cos_state(nic_dev, dcb_en);
+ err = hinic3_dcb_alloc(nic_dev);
+ if (err != 0) {
+ hinic3_err(nic_dev, drv, "Dcb alloc failed.\n");
+ return err;
+ }
- err = init_default_dcb_cfg(nic_dev, dcb_cfg);
+ hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ err = init_default_dcb_cfg(nic_dev, hw_dcb_cfg);
if (err) {
- hinic3_err(nic_dev, drv, "Initialize dcb configuration failed\n");
+ hinic3_err(nic_dev, drv,
+ "Initialize dcb configuration failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&nic_dev->dcb->wanted_dcb_cfg, hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
hinic3_info(nic_dev, drv, "Support num cos %u, default cos %u\n",
- nic_dev->cos_config_num_max, dcb_cfg->default_cos);
+ nic_dev->dcb->cos_config_num_max, hw_dcb_cfg->default_cos);
err = hinic3_set_tx_cos_state(nic_dev, dcb_en);
if (err) {
hinic3_err(nic_dev, drv, "Set tx cos state failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- sema_init(&nic_dev->dcb_sem, 1);
-
return 0;
}
-static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dcb_config *dcb_cfg)
+static int change_qos_cfg(struct hinic3_nic_dev *nic_dev,
+ const struct hinic3_dcb_config *dcb_cfg)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err = 0;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags)) {
+ if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags)) {
nicif_warn(nic_dev, drv, netdev,
"Cos_up map setting in inprocess, please try again later\n");
return -EFAULT;
@@ -337,40 +408,44 @@ static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dc
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
- clear_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags);
+ clear_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags);
return err;
}
int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err, rollback_err;
u8 netif_run = 0;
struct hinic3_dcb_config old_dcb_cfg;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- memcpy(&old_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&old_dcb_cfg, &dcb->hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
- if (!memcmp(&nic_dev->wanted_dcb_cfg, &old_dcb_cfg, sizeof(struct hinic3_dcb_config))) {
+ if (!memcmp(&dcb->wanted_dcb_cfg, &old_dcb_cfg,
+ sizeof(struct hinic3_dcb_config))) {
nicif_info(nic_dev, drv, nic_dev->netdev,
"Same valid up bitmap, don't need to change anything\n");
return 0;
}
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = change_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ err = change_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Set cos_up map to hw failed\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Set cos_up map to hw failed\n");
goto change_qos_cfg_fail;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- err = hinic3_setup_cos(nic_dev->netdev, user_cos_num, netif_run);
+ err = hinic3_setup_cos(nic_dev->netdev,
+ user_cos_num, netif_run);
if (err)
goto set_err;
}
@@ -381,13 +456,12 @@ int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
goto vport_up_fail;
}
- rtnl_unlock();
-
return 0;
vport_up_fail:
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_setup_cos(nic_dev->netdev, user_cos_num ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, user_cos_num
+ ? 0 : user_cos_num, netif_run);
set_err:
rollback_err = change_qos_cfg(nic_dev, &old_dcb_cfg);
@@ -399,7 +473,5 @@ change_qos_cfg_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
-
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
index 7987f56..e0b35cb 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
@@ -24,11 +24,6 @@ struct hinic3_tc_cfg {
u16 rsvd;
};
-enum HINIC3_DCB_TRUST {
- DCB_PCP,
- DCB_DSCP,
-};
-
#define PCP_MAX_UP 8
#define DSCP_MAC_UP 64
#define DBG_DFLT_DSCP_VAL 0xFF
@@ -50,6 +45,7 @@ struct hinic3_dcb_config {
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev);
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev);
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev);
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev);
void hinic3_dcb_reset_hw_config(struct hinic3_nic_dev *nic_dev);
int hinic3_configure_dcb(struct net_device *netdev);
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run);
@@ -75,4 +71,5 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos);
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev);
int hinic3_vport_up(struct hinic3_nic_dev *nic_dev);
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
index 5a19959..ae41819 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
@@ -56,9 +56,8 @@ static void hinic3_get_drvinfo(struct net_device *netdev,
return;
}
- err = snprintf(info->fw_version, sizeof(info->fw_version), "%s", mgmt_ver);
- if (err < 0)
- nicif_err(nic_dev, drv, netdev, "Failed to snprintf fw version\n");
+ snprintf(info->fw_version, sizeof(info->fw_version),
+ "%s", mgmt_ver);
}
static u32 hinic3_get_msglevel(struct net_device *netdev)
@@ -86,7 +85,8 @@ static int hinic3_nway_reset(struct net_device *netdev)
while (test_and_set_bit(HINIC3_AUTONEG_RESET, &nic_dev->flags))
msleep(100); /* sleep 100 ms, waiting for another autoneg restart progress done */
- err = hinic3_get_port_info(nic_dev->hwdev, &port_info, HINIC3_CHANNEL_NIC);
+ err = hinic3_get_port_info(nic_dev->hwdev, &port_info,
+ HINIC3_CHANNEL_NIC);
if (err) {
nicif_err(nic_dev, drv, netdev, "Get port info failed\n");
err = -EFAULT;
@@ -273,7 +273,7 @@ static int get_coalesce(struct net_device *netdev,
static int set_queue_coalesce(struct hinic3_nic_dev *nic_dev, u16 q_id,
struct hinic3_intr_coal_info *coal)
{
- struct hinic3_intr_coal_info *intr_coal;
+ struct hinic3_intr_coal_info *intr_coal = NULL;
struct interrupt_info info = {0};
struct net_device *netdev = nic_dev->netdev;
int err;
@@ -367,24 +367,11 @@ static int is_coalesce_exceed_limit(struct net_device *netdev,
return 0;
}
-static int is_coalesce_legal(struct net_device *netdev,
- const struct ethtool_coalesce *coal)
+static int is_coalesce_allowed_change(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct ethtool_coalesce tmp_coal = {0};
- int err;
-
- if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
- nicif_err(nic_dev, drv, netdev,
- "tx-usecs must be equal to rx-usecs\n");
- return -EINVAL;
- }
-
- if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
- nicif_err(nic_dev, drv, netdev,
- "tx-frames must be equal to rx-frames\n");
- return -EINVAL;
- }
tmp_coal.cmd = coal->cmd;
tmp_coal.rx_coalesce_usecs = coal->rx_coalesce_usecs;
@@ -409,6 +396,31 @@ static int is_coalesce_legal(struct net_device *netdev,
return -EOPNOTSUPP;
}
+ return 0;
+}
+
+static int is_coalesce_legal(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-usecs must be equal to rx-usecs\n");
+ return -EINVAL;
+ }
+
+ if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-frames must be equal to rx-frames\n");
+ return -EINVAL;
+ }
+
+ err = is_coalesce_allowed_change(netdev, coal);
+ if (err)
+ return err;
+
err = is_coalesce_exceed_limit(netdev, coal);
if (err)
return err;
@@ -444,7 +456,8 @@ static int is_coalesce_legal(struct net_device *netdev,
return 0;
}
-static inline void check_coalesce_align(struct hinic3_nic_dev *nic_dev, struct net_device *netdev,
+static inline void check_coalesce_aligned(struct hinic3_nic_dev *nic_dev,
+ struct net_device *netdev,
u32 item, u32 unit, char *str)
{
if (item % unit)
@@ -453,10 +466,12 @@ static inline void check_coalesce_align(struct hinic3_nic_dev *nic_dev, struct n
}
#define CHECK_COALESCE_ALIGN(member, unit) \
- check_coalesce_align(nic_dev, netdev, member, unit, #member)
+ check_coalesce_aligned(nic_dev, netdev, member, unit, #member)
-static inline void check_coalesce_changed(struct hinic3_nic_dev *nic_dev, struct net_device *netdev,
- u32 item, u32 unit, u32 ori_val, char *obj_str, char *str)
+static inline void check_coalesce_changed(struct hinic3_nic_dev *nic_dev,
+ struct net_device *netdev,
+ u32 item, u32 unit, u32 ori_val,
+ char *obj_str, char *str)
{
if ((item / unit) != ori_val)
nicif_info(nic_dev, drv, netdev, "Change %s from %d to %u %s\n",
@@ -466,8 +481,10 @@ static inline void check_coalesce_changed(struct hinic3_nic_dev *nic_dev, struct
#define CHECK_COALESCE_CHANGED(member, unit, ori_val, obj_str) \
check_coalesce_changed(nic_dev, netdev, member, unit, ori_val, obj_str, #member)
-static inline void check_pkt_rate_changed(struct hinic3_nic_dev *nic_dev, struct net_device *netdev,
- u32 item, u32 ori_val, char *obj_str, char *str)
+static inline void check_pkt_rate_changed(struct hinic3_nic_dev *nic_dev,
+ struct net_device *netdev,
+ u32 item, u32 ori_val, char *obj_str,
+ char *str)
{
if (item != ori_val)
nicif_info(nic_dev, drv, netdev, "Change %s from %d to %u %s\n",
@@ -497,19 +514,10 @@ static int set_hw_coal_param(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static int set_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *coal, u16 queue)
+static void check_coalesce_align(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
- struct hinic3_intr_coal_info intr_coal = {0};
- struct hinic3_intr_coal_info *ori_intr_coal = NULL;
- u32 last_adaptive_rx;
- char obj_str[32] = {0};
- int err = 0;
-
- err = is_coalesce_legal(netdev, coal);
- if (err)
- return err;
CHECK_COALESCE_ALIGN(coal->rx_coalesce_usecs, COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal->rx_max_coalesced_frames,
@@ -522,6 +530,14 @@ static int set_coalesce(struct net_device *netdev,
COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal->rx_max_coalesced_frames_low,
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int check_coalesce_change(struct net_device *netdev,
+ u16 queue, struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info *ori_intr_coal = NULL;
+ char obj_str[32] = {0};
if (queue == COALESCE_ALL_QUEUE) {
ori_intr_coal = &nic_dev->intr_coalesce[0];
@@ -552,27 +568,54 @@ static int set_coalesce(struct net_device *netdev,
COALESCE_PENDING_LIMIT_UNIT,
ori_intr_coal->rx_pending_limt_low, obj_str);
- intr_coal.coalesce_timer_cfg =
+ return 0;
+}
+
+static void init_intr_coal_params(struct hinic3_intr_coal_info *intr_coal,
+ struct ethtool_coalesce *coal)
+{
+ intr_coal->coalesce_timer_cfg =
(u8)(coal->rx_coalesce_usecs / COALESCE_TIMER_CFG_UNIT);
- intr_coal.pending_limt = (u8)(coal->rx_max_coalesced_frames /
+ intr_coal->pending_limt = (u8)(coal->rx_max_coalesced_frames /
COALESCE_PENDING_LIMIT_UNIT);
- last_adaptive_rx = nic_dev->adaptive_rx_coal;
- nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
-
- intr_coal.pkt_rate_high = coal->pkt_rate_high;
- intr_coal.rx_usecs_high =
+ intr_coal->pkt_rate_high = coal->pkt_rate_high;
+ intr_coal->rx_usecs_high =
(u8)(coal->rx_coalesce_usecs_high / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_high =
+ intr_coal->rx_pending_limt_high =
(u8)(coal->rx_max_coalesced_frames_high /
COALESCE_PENDING_LIMIT_UNIT);
- intr_coal.pkt_rate_low = coal->pkt_rate_low;
- intr_coal.rx_usecs_low =
+ intr_coal->pkt_rate_low = coal->pkt_rate_low;
+ intr_coal->rx_usecs_low =
(u8)(coal->rx_coalesce_usecs_low / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_low =
+ intr_coal->rx_pending_limt_low =
(u8)(coal->rx_max_coalesced_frames_low /
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal, u16 queue)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info intr_coal = {0};
+ u32 last_adaptive_rx;
+ int err = 0;
+
+ err = is_coalesce_legal(netdev, coal);
+ if (err)
+ return err;
+
+ check_coalesce_align(netdev, coal);
+
+ err = check_coalesce_change(netdev, queue, coal);
+ if (err)
+ return err;
+
+ init_intr_coal_params(&intr_coal, coal);
+
+ last_adaptive_rx = nic_dev->adaptive_rx_coal;
+ nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
/* coalesce timer or pending set to zero will disable coalesce */
if (!nic_dev->adaptive_rx_coal &&
@@ -709,14 +752,16 @@ static int hinic3_set_pauseparam(struct net_device *netdev,
return -EFAULT;
}
- auto_neg = port_info.autoneg_state == PORT_CFG_AN_ON ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+ auto_neg = port_info.autoneg_state == PORT_CFG_AN_ON ?
+ AUTONEG_ENABLE : AUTONEG_DISABLE;
if (pause->autoneg != auto_neg) {
nicif_err(nic_dev, drv, netdev,
"To change autoneg please use: ethtool -s <dev> autoneg <on|off>\n");
return -EOPNOTSUPP;
}
- nic_pause.auto_neg = pause->autoneg == AUTONEG_ENABLE ? PORT_CFG_AN_ON : PORT_CFG_AN_OFF;
+ nic_pause.auto_neg = pause->autoneg == AUTONEG_ENABLE ?
+ PORT_CFG_AN_ON : PORT_CFG_AN_OFF;
nic_pause.rx_pause = (u8)pause->rx_pause;
nic_pause.tx_pause = (u8)pause->tx_pause;
@@ -768,6 +813,14 @@ static int hinic3_get_module_info(struct net_device *netdev,
modinfo->type = ETH_MODULE_SFF_8636;
modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
break;
+ case MODULE_TYPE_DSFP:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
+ case MODULE_TYPE_QSFP_CMIS:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
default:
nicif_warn(nic_dev, drv, netdev,
"Optical module unknown: 0x%x\n", sfp_type);
@@ -790,6 +843,11 @@ static int hinic3_get_module_eeprom(struct net_device *netdev,
memset(data, 0, ee->len);
err = hinic3_get_sfp_eeprom(nic_dev->hwdev, (u8 *)sfp_data, ee->len);
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(nic_dev->hwdev,
+ (u8 *)sfp_data,
+ sizeof(sfp_data));
+
if (err)
return err;
@@ -832,7 +890,8 @@ int hinic3_set_rxq_recovery_flag(struct net_device *netdev, u32 priv_flags)
if (test_and_set_bit(HINIC3_RXQ_RECOVERY, &nic_dev->flags))
return 0;
- queue_delayed_work(nic_dev->workq, &nic_dev->rxq_check_work, HZ);
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->rxq_check_work, HZ);
nicif_info(nic_dev, drv, netdev, "open rxq recovery\n");
} else {
if (!test_and_clear_bit(HINIC3_RXQ_RECOVERY, &nic_dev->flags))
@@ -888,7 +947,8 @@ static int hinic3_set_force_link_flag(struct net_device *netdev, u32 priv_flags)
nicif_info(nic_dev, link, netdev, "Set link up\n");
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, nic_dev->link_status);
+ hinic3_notify_all_vfs_link_changed(
+ nic_dev->hwdev, nic_dev->link_status);
} else {
if (!test_and_clear_bit(HINIC3_FORCE_LINK_UP, &nic_dev->flags))
return 0;
@@ -919,7 +979,8 @@ static int hinic3_set_force_link_flag(struct net_device *netdev, u32 priv_flags)
}
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, nic_dev->link_status);
+ hinic3_notify_all_vfs_link_changed(
+ nic_dev->hwdev, nic_dev->link_status);
}
return 0;
@@ -942,7 +1003,6 @@ static int hinic3_set_priv_flags(struct net_device *netdev, u32 priv_flags)
#define PORT_DOWN_ERR_IDX 0
#define LP_DEFAULT_TIME 5 /* seconds */
-#define LP_PKT_LEN 60
#define TEST_TIME_MULTIPLE 5
static int hinic3_run_lp_test(struct hinic3_nic_dev *nic_dev, u32 test_time)
@@ -958,8 +1018,11 @@ static int hinic3_run_lp_test(struct hinic3_nic_dev *nic_dev, u32 test_time)
u8 j;
skb_tmp = alloc_skb(LP_PKT_LEN, GFP_ATOMIC);
- if (!skb_tmp)
+ if (!skb_tmp) {
+ nicif_err(nic_dev, drv, netdev,
+ "Alloc xmit skb template failed for loopback test\n");
return -ENOMEM;
+ }
eth_hdr = __skb_put(skb_tmp, ETH_HLEN);
eth_hdr->h_proto = htons(ETH_P_ARP);
@@ -1057,6 +1120,8 @@ static int do_lp_test(struct hinic3_nic_dev *nic_dev, u32 *flags, u32 test_time,
lb_test_rx_buf = vmalloc(LP_PKT_CNT * LP_PKT_LEN);
if (!lb_test_rx_buf) {
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to alloc RX buffer for loopback test\n");
err = -ENOMEM;
} else {
nic_dev->lb_test_rx_buf = lb_test_rx_buf;
@@ -1086,7 +1151,8 @@ static int do_lp_test(struct hinic3_nic_dev *nic_dev, u32 *flags, u32 test_time,
return err;
}
-static void hinic3_lp_test(struct net_device *netdev, struct ethtool_test *eth_test,
+static void hinic3_lp_test(struct net_device *netdev,
+ struct ethtool_test *eth_test,
u64 *data, u32 test_time)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
@@ -1109,7 +1175,8 @@ static void hinic3_lp_test(struct net_device *netdev, struct ethtool_test *eth_t
netif_carrier_off(netdev);
netif_tx_disable(netdev);
- err = do_lp_test(nic_dev, ð_test->flags, test_time_real, &test_index);
+ err = do_lp_test(nic_dev, ð_test->flags,
+ test_time_real, &test_index);
if (err) {
eth_test->flags |= ETH_TEST_FL_FAILED;
data[test_index] = 1;
@@ -1130,10 +1197,65 @@ static void hinic3_diag_test(struct net_device *netdev,
hinic3_lp_test(netdev, eth_test, data, 0);
}
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+static int hinic3_get_fecparam(struct net_device *netdev,
+ struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u8 advertised_fec = 0;
+ u8 supported_fec = 0;
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_GFECPARAM) {
+ nicif_err(nic_dev, drv, netdev,
+ "get fecparam cmd err.exp:0x%x,real:0x%x\n",
+ ETHTOOL_GFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = get_fecparam(nic_dev->hwdev, &advertised_fec, &supported_fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Get fec param failed\n");
+ return err;
+ }
+ fecparam->active_fec = (u32)advertised_fec;
+ fecparam->fec = (u32)supported_fec;
+
+ nicif_info(nic_dev, drv, netdev, "Get fec param success\n");
+ return 0;
+}
+
+static int hinic3_set_fecparam(struct net_device *netdev,
+ struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_SFECPARAM) {
+ nicif_err(nic_dev, drv, netdev,
+ "Set fecparam cmd err.exp:0x%x,real:0x%x\n",
+ ETHTOOL_SFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = set_fecparam(nic_dev->hwdev, (u8)fecparam->fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Set fec param failed\n");
+ return err;
+ }
+
+ nicif_info(nic_dev, drv, netdev, "Set fec param success\n");
+ return 0;
+}
+#endif
+
static const struct ethtool_ops hinic3_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1180,6 +1302,10 @@ static const struct ethtool_ops hinic3_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
@@ -1240,7 +1366,10 @@ static const struct ethtool_ops_ext hinic3_ethtool_ops_ext = {
static const struct ethtool_ops hinic3vf_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1267,6 +1396,11 @@ static const struct ethtool_ops hinic3vf_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
+
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
index b0e6aad..938cf2c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
@@ -24,11 +24,29 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
-#define FPGA_PORT_COUNTER 0
-#define EVB_PORT_COUNTER 1
-u16 mag_support_mode = EVB_PORT_COUNTER;
-module_param(mag_support_mode, ushort, 0444);
-MODULE_PARM_DESC(mag_support_mode, "Set mag port counter support mode, 0:FPGA 1:EVB, default is 1");
+#define HINIC_SET_LINK_STR_LEN 128
+#define HINIC_ETHTOOL_FEC_INFO_LEN 6
+#define HINIC_SUPPORTED_FEC_CMD 0
+#define HINIC_ADVERTISED_FEC_CMD 1
+
+struct hinic3_ethtool_fec {
+ u8 hinic_fec_offset;
+ u8 ethtool_bit_offset;
+};
+
+static struct hinic3_ethtool_fec
+ hinic3_ethtool_fec_info[HINIC_ETHTOOL_FEC_INFO_LEN] = {
+ /* The ethtool does not have the corresponding enumeration variable */
+ {PORT_FEC_NOT_SET, 0xFF},
+ {PORT_FEC_RSFEC, 0x32}, /* ETHTOOL_LINK_MODE_FEC_RS_BIT */
+ /* ETHTOOL_LINK_MODE_FEC_BASER_BIT */
+ {PORT_FEC_BASEFEC, 0x33},
+ {PORT_FEC_NOFEC, 0x31}, /* ETHTOOL_LINK_MODE_FEC_NONE_BIT */
+ /* ETHTOOL_LINK_MODE_FEC_LLRS_BIT: Available only in later versions */
+ {PORT_FEC_LLRSFEC, 0x4A},
+ /* The ethtool does not have the corresponding enumeration variable */
+ {PORT_FEC_AUTO, 0XFF}
+};
struct hinic3_stats {
char name[ETH_GSTRING_LEN];
@@ -36,9 +54,23 @@ struct hinic3_stats {
int offset;
};
+struct hinic3_netdev_link_count_str {
+ u64 link_down_events_phy;
+};
+
+#define HINIC3_NETDEV_LINK_COUNT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic3_netdev_link_count_str, _stat_item), \
+ .offset = offsetof(struct hinic3_netdev_link_count_str, _stat_item) \
+}
+
+static struct hinic3_stats hinic3_netdev_link_count[] = {
+ HINIC3_NETDEV_LINK_COUNT(link_down_events_phy),
+};
+
#define HINIC3_NETDEV_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct rtnl_link_stats64, _stat_item), \
+ .size = FIELD_SIZEOF(struct rtnl_link_stats64, _stat_item), \
.offset = offsetof(struct rtnl_link_stats64, _stat_item) \
}
@@ -67,7 +99,7 @@ static struct hinic3_stats hinic3_netdev_stats[] = {
#define HINIC3_NIC_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct hinic3_nic_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_nic_stats, _stat_item), \
.offset = offsetof(struct hinic3_nic_stats, _stat_item) \
}
@@ -84,17 +116,16 @@ static struct hinic3_stats hinic3_nic_dev_stats_extern[] = {
#define HINIC3_RXQ_STAT(_stat_item) { \
.name = "rxq%d_"#_stat_item, \
- .size = sizeof_field(struct hinic3_rxq_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_rxq_stats, _stat_item), \
.offset = offsetof(struct hinic3_rxq_stats, _stat_item) \
}
#define HINIC3_TXQ_STAT(_stat_item) { \
.name = "txq%d_"#_stat_item, \
- .size = sizeof_field(struct hinic3_txq_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_txq_stats, _stat_item), \
.offset = offsetof(struct hinic3_txq_stats, _stat_item) \
}
-/*lint -save -e786*/
static struct hinic3_stats hinic3_rx_queue_stats[] = {
HINIC3_RXQ_STAT(packets),
HINIC3_RXQ_STAT(bytes),
@@ -135,11 +166,9 @@ static struct hinic3_stats hinic3_tx_queue_stats_extern[] = {
HINIC3_TXQ_STAT(rsvd2),
};
-/*lint -restore*/
-
#define HINIC3_FUNC_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct hinic3_vport_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_vport_stats, _stat_item), \
.offset = offsetof(struct hinic3_vport_stats, _stat_item) \
}
@@ -166,7 +195,7 @@ static struct hinic3_stats hinic3_function_stats[] = {
#define HINIC3_PORT_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct mag_cmd_port_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct mag_cmd_port_stats, _stat_item), \
.offset = offsetof(struct mag_cmd_port_stats, _stat_item) \
}
@@ -260,49 +289,22 @@ static struct hinic3_stats hinic3_port_stats[] = {
HINIC3_PORT_STAT(mac_rx_unfilter_pkt_num),
};
-#define HINIC3_FGPA_PORT_STAT(_stat_item) { \
+#define HINIC3_RSFEC_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct hinic3_phy_fpga_port_stats, _stat_item), \
- .offset = offsetof(struct hinic3_phy_fpga_port_stats, _stat_item) \
+ .size = FIELD_SIZEOF(struct mag_cmd_rsfec_stats, _stat_item), \
+ .offset = offsetof(struct mag_cmd_rsfec_stats, _stat_item) \
}
-static struct hinic3_stats g_hinic3_fpga_port_stats[] = {
- HINIC3_FGPA_PORT_STAT(mac_rx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_under_frame_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_frag_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_crc_error_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_length_err_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_pause_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_unknown_mac_frame_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_underrun_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_pause_pkts_port),
+static struct hinic3_stats g_hinic3_rsfec_stats[] = {
+ HINIC3_RSFEC_STAT(rx_err_lane_phy),
};
+#define HINIC3_FGPA_PORT_STAT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic3_phy_fpga_port_stats, _stat_item), \
+ .offset = offsetof(struct hinic3_phy_fpga_port_stats, _stat_item) \
+}
+
static char g_hinic_priv_flags_strings[][ETH_GSTRING_LEN] = {
"Symmetric-RSS",
"Force-Link-up",
@@ -318,8 +320,7 @@ u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev)
(ARRAY_LEN(hinic3_tx_queue_stats) +
ARRAY_LEN(hinic3_tx_queue_stats_extern) +
ARRAY_LEN(hinic3_rx_queue_stats) +
- ARRAY_LEN(hinic3_rx_queue_stats_extern)) *
- nic_dev->max_qps;
+ ARRAY_LEN(hinic3_rx_queue_stats_extern)) * nic_dev->max_qps;
return count;
}
@@ -343,72 +344,87 @@ static int dev_stats_pack(struct hinic3_show_item *items, int len,
memcpy(items[item_idx].name, array[j].name,
HINIC3_SHOW_ITEM_LEN);
items[item_idx].hexadecimal = 0;
- items[item_idx].value = get_value_of_ptr(array[j].size,
- stats_ptr + array[j].offset);
+ items[item_idx].value =
+ get_value_of_ptr(array[j].size,
+ stats_ptr + array[j].offset);
item_idx++;
}
return item_idx;
}
-static int queue_stats_pack(struct hinic3_show_item *items, int len,
- struct hinic3_stats *array, void *stats_ptr,
- u16 qid)
+int hinic3_rx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat, struct hinic3_rxq_stats *rxq_stats, u16 qid)
{
- int j;
- int item_idx = 0;
+ snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
- for (j = 0; j < len; j++) {
- memcpy(items[item_idx].name, array[j].name,
- HINIC3_SHOW_ITEM_LEN);
- snprintf(items[item_idx].name, HINIC3_SHOW_ITEM_LEN,
- array[j].name, qid);
- items[item_idx].hexadecimal = 0;
- items[item_idx].value = get_value_of_ptr(array[j].size,
- stats_ptr + array[j].offset);
- item_idx++;
- }
+ item->hexadecimal = 0;
+ item->value = get_value_of_ptr(stat->size, (char *)(rxq_stats) +
+ stat->offset);
- return item_idx;
+ return 0;
+}
+
+int hinic3_tx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat, struct hinic3_txq_stats *txq_stats, u16 qid)
+{
+ snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
+
+ item->hexadecimal = 0;
+ item->value = get_value_of_ptr(stat->size, (char *)(txq_stats) +
+ stat->offset);
+
+ return 0;
}
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
{
struct hinic3_show_item *items = stats;
int item_idx = 0;
u16 qid;
+ int idx;
+ int ret;
- item_idx += dev_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_nic_dev_stats),
- hinic3_nic_dev_stats, &nic_dev->stats);
- item_idx += dev_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_nic_dev_stats_extern),
- hinic3_nic_dev_stats_extern,
- &nic_dev->stats);
+ dev_stats_pack(items, item_idx, hinic3_nic_dev_stats, &nic_dev->stats);
+ dev_stats_pack(items, item_idx, hinic3_nic_dev_stats_extern, &nic_dev->stats);
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_tx_queue_stats),
- hinic3_tx_queue_stats,
- &nic_dev->txqs[qid].txq_stats,
- qid);
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_tx_queue_stats_extern),
- hinic3_tx_queue_stats_extern,
- &nic_dev->txqs[qid].txq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++],
+ &hinic3_tx_queue_stats[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats_extern); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++],
+ &hinic3_tx_queue_stats_extern[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
}
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_rx_queue_stats),
- hinic3_rx_queue_stats,
- &nic_dev->rxqs[qid].rxq_stats,
- qid);
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_rx_queue_stats_extern),
- hinic3_rx_queue_stats_extern,
- &nic_dev->rxqs[qid].rxq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++],
+ &hinic3_rx_queue_stats[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats_extern); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++],
+ &hinic3_rx_queue_stats_extern[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
}
+
+ return 0;
}
static char g_hinic3_test_strings[][ETH_GSTRING_LEN] = {
@@ -428,16 +444,14 @@ int hinic3_get_sset_count(struct net_device *netdev, int sset)
q_num = nic_dev->q_params.num_qps;
count = ARRAY_LEN(hinic3_netdev_stats) +
ARRAY_LEN(hinic3_nic_dev_stats) +
+ ARRAY_LEN(hinic3_netdev_link_count) +
ARRAY_LEN(hinic3_function_stats) +
(ARRAY_LEN(hinic3_tx_queue_stats) +
- ARRAY_LEN(hinic3_rx_queue_stats)) *
- q_num;
+ ARRAY_LEN(hinic3_rx_queue_stats)) * q_num;
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER)
- count += ARRAY_LEN(g_hinic3_fpga_port_stats);
- else
- count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(g_hinic3_rsfec_stats);
}
return count;
@@ -486,9 +500,9 @@ static void get_drv_queue_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
}
}
-static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct hinic3_phy_fpga_port_stats *port_stats = NULL;
+ struct mag_cmd_port_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
@@ -496,19 +510,19 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
if (!port_stats) {
memset(&data[i], 0,
- ARRAY_LEN(g_hinic3_fpga_port_stats) * sizeof(*data));
- i += ARRAY_LEN(g_hinic3_fpga_port_stats);
+ ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
+ i += ARRAY_LEN(hinic3_port_stats);
return i;
}
- err = hinic3_get_fpga_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to get port stats from fw\n");
- for (j = 0; j < ARRAY_LEN(g_hinic3_fpga_port_stats); j++, i++) {
- p = (char *)(port_stats) + g_hinic3_fpga_port_stats[j].offset;
- data[i] = (g_hinic3_fpga_port_stats[j].size == sizeof(u64)) ?
+ for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
+ p = (char *)(port_stats) + hinic3_port_stats[j].offset;
+ data[i] = (hinic3_port_stats[j].size == sizeof(u64)) ?
*(u64 *)p :
*(u32 *)p;
}
@@ -518,34 +532,32 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
return i;
}
-static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_rsfec_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct mag_cmd_port_stats *port_stats = NULL;
+ struct mag_cmd_rsfec_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
- if (mag_support_mode == FPGA_PORT_COUNTER)
- return get_fpga_port_stats(nic_dev, data);
-
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
if (!port_stats) {
- memset(&data[i], 0,
- ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
- i += ARRAY_LEN(hinic3_port_stats);
- return i;
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to malloc port stats\n");
+ memset(&data[i], 0,
+ ARRAY_LEN(g_hinic3_rsfec_stats) * sizeof(*data));
+ i += ARRAY_LEN(g_hinic3_rsfec_stats);
+ return i;
}
- err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_rsfec_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to get port stats from fw\n");
+ "Failed to get rsfec stats from fw\n");
- for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
- p = (char *)(port_stats) + hinic3_port_stats[j].offset;
- data[i] = (hinic3_port_stats[j].size == sizeof(u64)) ?
- *(u64 *)p :
- *(u32 *)p;
+ for (j = 0; j < ARRAY_LEN(g_hinic3_rsfec_stats); j++, i++) {
+ p = (char *)(port_stats) + g_hinic3_rsfec_stats[j].offset;
+ data[i] = (g_hinic3_rsfec_stats[j].size ==
+ sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
kfree(port_stats);
@@ -569,6 +581,8 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
u16 i = 0, j = 0;
char *p = NULL;
int err;
+ int link_down_events_phy_tmp = 0;
+ struct hinic3_netdev_link_count_str link_count = {0};
#ifdef HAVE_NDO_GET_STATS64
net_stats = dev_get_stats(netdev, &temp);
@@ -586,6 +600,15 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = get_value_of_ptr(hinic3_nic_dev_stats[j].size, p);
}
+ err = hinic3_get_link_event_stats(nic_dev->hwdev,
+ &link_down_events_phy_tmp);
+
+ link_count.link_down_events_phy = (u64)link_down_events_phy_tmp;
+ for (j = 0; j < ARRAY_LEN(hinic3_netdev_link_count); j++, i++) {
+ p = (char *)(&link_count) + hinic3_netdev_link_count[j].offset;
+ data[i] = get_value_of_ptr(hinic3_netdev_link_count[j].size, p);
+ }
+
err = hinic3_get_vport_stats(nic_dev->hwdev,
hinic3_global_func_id(nic_dev->hwdev),
&vport_stats);
@@ -598,8 +621,10 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = get_value_of_ptr(hinic3_function_stats[j].size, p);
}
- if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
i += get_ethtool_port_stats(nic_dev, data + i);
+ i += get_ethtool_rsfec_stats(nic_dev, data + i);
+ }
get_drv_queue_stats(nic_dev, data + i);
}
@@ -620,6 +645,12 @@ static u16 get_drv_dev_strings(struct hinic3_nic_dev *nic_dev, char *p)
cnt++;
}
+ for (i = 0; i < ARRAY_LEN(hinic3_netdev_link_count); i++) {
+ memcpy(p, hinic3_netdev_link_count[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+
return cnt;
}
@@ -634,21 +665,16 @@ static u16 get_hw_stats_strings(struct hinic3_nic_dev *nic_dev, char *p)
}
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER) {
- for (i = 0; i < ARRAY_LEN(g_hinic3_fpga_port_stats);
- i++) {
- memcpy(p, g_hinic3_fpga_port_stats[i].name,
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
- } else {
- for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
- memcpy(p, hinic3_port_stats[i].name,
+ for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
+ memcpy(p, hinic3_port_stats[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+ for (i = 0; i < ARRAY_LEN(g_hinic3_rsfec_stats); i++) {
+ memcpy(p, g_hinic3_rsfec_stats[i].name,
ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
+ p += ETH_GSTRING_LEN;
+ cnt++;
}
}
@@ -664,7 +690,8 @@ static u16 get_qp_stats_strings(const struct hinic3_nic_dev *nic_dev, char *p)
for (j = 0; j < ARRAY_LEN(hinic3_tx_queue_stats); j++) {
err = sprintf(p, hinic3_tx_queue_stats[j].name, i);
if (err < 0)
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to sprintf tx queue stats name, idx_qps: %u, idx_stats: %u\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to sprintf tx queue stats name, idx_qps: %u, idx_stats: %u\n",
i, j);
p += ETH_GSTRING_LEN;
cnt++;
@@ -675,7 +702,8 @@ static u16 get_qp_stats_strings(const struct hinic3_nic_dev *nic_dev, char *p)
for (j = 0; j < ARRAY_LEN(hinic3_rx_queue_stats); j++) {
err = sprintf(p, hinic3_rx_queue_stats[j].name, i);
if (err < 0)
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to sprintf rx queue stats name, idx_qps: %u, idx_stats: %u\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to sprintf rx queue stats name, idx_qps: %u, idx_stats: %u\n",
i, j);
p += ETH_GSTRING_LEN;
cnt++;
@@ -791,7 +819,6 @@ struct hw2ethtool_link_mode {
u32 speed;
};
-/*lint -save -e26 */
static const struct hw2ethtool_link_mode
hw2ethtool_link_mode_table[LINK_MODE_MAX_NUMBERS] = {
[LINK_MODE_GE] = {
@@ -851,8 +878,6 @@ static const struct hw2ethtool_link_mode
},
};
-/*lint -restore */
-
#define GET_SUPPORTED_MODE 0
#define GET_ADVERTISED_MODE 1
@@ -867,21 +892,37 @@ struct cmd_link_settings {
};
#define ETHTOOL_ADD_SUPPORTED_LINK_MODE(ecmd, mode) \
- set_bit(ETHTOOL_LINK_##mode##_BIT, (ecmd)->supported)
+ set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->supported)
#define ETHTOOL_ADD_ADVERTISED_LINK_MODE(ecmd, mode) \
- set_bit(ETHTOOL_LINK_##mode##_BIT, (ecmd)->advertising)
+ set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->advertising)
-static void ethtool_add_speed_link_mode(__ETHTOOL_DECLARE_LINK_MODE_MASK(bitmap), u32 mode)
+static void ethtool_add_supported_speed_link_mode(
+ struct cmd_link_settings *link_settings,
+ u32 mode)
{
u32 i;
for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
- __ETHTOOL_LINK_MODE_MASK_NBITS)
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
continue;
+ set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
+ link_settings->supported);
+ }
+}
+static void ethtool_add_advertised_speed_link_mode(
+ struct cmd_link_settings *link_settings,
+ u32 mode)
+{
+ u32 i;
+
+ for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
+ if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
+ continue;
set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
- bitmap);
+ link_settings->advertising);
}
}
@@ -912,9 +953,11 @@ hinic3_add_ethtool_link_mode(struct cmd_link_settings *link_settings,
for (link_mode = 0; link_mode < LINK_MODE_MAX_NUMBERS; link_mode++) {
if (hw_link_mode & BIT(link_mode)) {
if (name == GET_SUPPORTED_MODE)
- ethtool_add_speed_link_mode(link_settings->supported, link_mode);
+ ethtool_add_supported_speed_link_mode(
+ link_settings, link_mode);
else
- ethtool_add_speed_link_mode(link_settings->advertising, link_mode);
+ ethtool_add_advertised_speed_link_mode(
+ link_settings, link_mode);
}
}
}
@@ -937,10 +980,15 @@ static int hinic3_link_speed_set(struct hinic3_nic_dev *nic_dev,
err = hinic3_get_link_state(nic_dev->hwdev, &link_state);
if (!err && link_state) {
- link_settings->speed =
- port_info->speed < ARRAY_LEN(hw_to_ethtool_speed) ?
+ if (hinic3_get_bond_create_mode(nic_dev->hwdev)) {
+ link_settings->speed = port_info->bond_speed;
+ } else {
+ link_settings->speed =
+ port_info->speed <
+ ARRAY_LEN(hw_to_ethtool_speed) ?
hw_to_ethtool_speed[port_info->speed] :
(u32)SPEED_UNKNOWN;
+ }
link_settings->duplex = port_info->duplex;
} else {
@@ -956,28 +1004,28 @@ static void hinic3_link_port_type(struct cmd_link_settings *link_settings,
{
switch (port_type) {
case MAG_CMD_WIRE_TYPE_ELECTRIC:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_TP);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_TP);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, TP);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, TP);
link_settings->port = PORT_TP;
break;
case MAG_CMD_WIRE_TYPE_AOC:
case MAG_CMD_WIRE_TYPE_MM:
case MAG_CMD_WIRE_TYPE_SM:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_FIBRE);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_FIBRE);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, FIBRE);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, FIBRE);
link_settings->port = PORT_FIBRE;
break;
case MAG_CMD_WIRE_TYPE_COPPER:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_FIBRE);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_FIBRE);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, FIBRE);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, FIBRE);
link_settings->port = PORT_DA;
break;
case MAG_CMD_WIRE_TYPE_BACKPLANE:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_Backplane);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Backplane);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Backplane);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Backplane);
link_settings->port = PORT_NONE;
break;
@@ -1000,19 +1048,58 @@ static int get_link_pause_settings(struct hinic3_nic_dev *nic_dev,
return err;
}
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_Pause);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Pause);
if (nic_pause.rx_pause && nic_pause.tx_pause) {
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Pause);
} else if (nic_pause.tx_pause) {
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Asym_Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Asym_Pause);
} else if (nic_pause.rx_pause) {
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Pause);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Asym_Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Asym_Pause);
}
return 0;
}
+static bool is_bit_offset_defined(u8 bit_offset)
+{
+ if (bit_offset < __ETHTOOL_LINK_MODE_MASK_NBITS)
+ return true;
+ return false;
+}
+
+static void ethtool_add_supported_advertised_fec(
+ struct cmd_link_settings *link_settings, u32 fec, u8 cmd)
+{
+ u8 i;
+
+ for (i = 0; i < HINIC_ETHTOOL_FEC_INFO_LEN; i++) {
+ if ((fec & BIT(hinic3_ethtool_fec_info[i].hinic_fec_offset)) == 0)
+ continue;
+ if ((is_bit_offset_defined(
+ hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true) &&
+ (cmd == HINIC_ADVERTISED_FEC_CMD)) {
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset,
+ link_settings->advertising);
+ return; /* There can be only one advertised fec mode. */
+ }
+ if ((is_bit_offset_defined(
+ hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true) &&
+ (cmd == HINIC_SUPPORTED_FEC_CMD))
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset,
+ link_settings->supported);
+ }
+}
+
+static void hinic3_link_fec_type(struct cmd_link_settings *link_settings,
+ u32 fec, u32 supported_fec)
+{
+ ethtool_add_supported_advertised_fec(link_settings, supported_fec,
+ HINIC_SUPPORTED_FEC_CMD);
+ ethtool_add_supported_advertised_fec(link_settings, fec,
+ HINIC_ADVERTISED_FEC_CMD);
+}
+
static int get_link_settings(struct net_device *netdev,
struct cmd_link_settings *link_settings)
{
@@ -1033,13 +1120,19 @@ static int get_link_settings(struct net_device *netdev,
hinic3_link_port_type(link_settings, port_info.port_type);
+ /* port_info.fec is bit offset, value is BIT(port_info.fec);
+ * but port_info.supported_fec_mode is bit value
+ */
+ hinic3_link_fec_type(link_settings, BIT(port_info.fec),
+ port_info.supported_fec_mode);
+
link_settings->autoneg = port_info.autoneg_state == PORT_CFG_AN_ON ?
AUTONEG_ENABLE :
AUTONEG_DISABLE;
if (port_info.autoneg_cap)
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_Autoneg);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Autoneg);
if (port_info.autoneg_state == PORT_CFG_AN_ON)
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Autoneg);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Autoneg);
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
err = get_link_pause_settings(nic_dev, link_settings);
@@ -1163,23 +1256,19 @@ static int hinic3_set_settings_to_hw(struct hinic3_nic_dev *nic_dev,
struct net_device *netdev = nic_dev->netdev;
struct hinic3_link_ksettings settings = { 0 };
int speed_level = 0;
- char set_link_str[128] = { 0 };
+ char set_link_str[HINIC_SET_LINK_STR_LEN] = {0};
+ char link_info[HINIC_SET_LINK_STR_LEN] = {0};
int err = 0;
- err = snprintf(set_link_str, sizeof(set_link_str) - 1, "%s",
+ snprintf(link_info, sizeof(link_info), "%s",
(bool)(set_settings & HILINK_LINK_SET_AUTONEG) ?
((bool)autoneg ? "autong enable " :
- "autong disable ") :
- "");
- if (err < 0)
- return -EINVAL;
+ "autong disable ") : "");
if (set_settings & HILINK_LINK_SET_SPEED) {
speed_level = hinic3_ethtool_to_hw_speed_level(speed);
- err = snprintf(set_link_str, sizeof(set_link_str) - 1,
- "%sspeed %u ", set_link_str, speed);
- if (err < 0)
- return -EINVAL;
+ snprintf(set_link_str, sizeof(set_link_str),
+ "%sspeed %u ", link_info, speed);
}
settings.valid_bitmap = set_settings;
@@ -1218,7 +1307,8 @@ static int set_link_settings(struct net_device *netdev, u8 autoneg, u32 speed)
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
int hinic3_set_link_ksettings(struct net_device *netdev,
- const struct ethtool_link_ksettings *link_settings)
+ const
+ struct ethtool_link_ksettings *link_settings)
{
/* Only support to set autoneg and speed */
return set_link_settings(netdev, link_settings->base.autoneg,
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
index 70346d6..2daa7f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
@@ -82,7 +82,7 @@ static struct hinic3_mac_filter *hinic3_add_filter(struct hinic3_nic_dev *nic_de
struct list_head *mac_filter_list,
u8 *addr)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
@@ -117,7 +117,7 @@ static void hinic3_del_filter(struct hinic3_nic_dev *nic_dev,
static struct hinic3_mac_filter *hinic3_mac_filter_entry_clone(const struct hinic3_mac_filter *src)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
index ef8c62b..a3136ce 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
@@ -40,6 +40,7 @@ enum hinic3_channel_id {
HINIC3_CHANNEL_DSW,
HINIC3_CHANNEL_MIG,
HINIC3_CHANNEL_CRYPT,
+ HINIC3_CHANNEL_VROCE,
HINIC3_CHANNEL_MAX = 32,
};
@@ -397,6 +398,16 @@ void hinic3_free_cmd_buf(void *hwdev, struct hinic3_cmd_buf *cmd_buf);
**/
int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read clear
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+
/**
* @brief hinic3_sm_ctr_rd32 - small single 32 counter read
* @param hwdev: device pointer to hwdev
@@ -810,6 +821,13 @@ int hinic3_dbg_lt_wr_16byte_mask(void *hwdev, u8 dest, u8 instance,
*/
void hinic3_link_event_stats(void *dev, u8 link);
+/**
+ * @brief hinic3_get_link_event_stats - link event stats
+ * @param hwdev: device pointer to hwdev
+ * @param link: link status
+ */
+int hinic3_get_link_event_stats(void *dev, int *link_state);
+
/**
* @brief hinic3_get_hw_pf_infos - get pf infos
* @param hwdev: device pointer to hwdev
@@ -856,4 +874,5 @@ void hinic3_set_api_stop(void *hwdev);
int hinic3_activate_firmware(void *hwdev, u8 cfg_index);
int hinic3_switch_config(void *hwdev, u8 cfg_index);
+bool hinic3_is_optical_module_mode(void *hwdev);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
index 7e59c81..6525b76 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
@@ -47,12 +47,16 @@ static void qp_add_napi(struct hinic3_irq *irq_cfg)
netif_napi_add_weight(nic_dev->netdev, &irq_cfg->napi,
hinic3_poll, nic_dev->poll_weight);
napi_enable(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_IS_REGIN;
}
-static void qp_del_napi(struct hinic3_irq *irq_cfg)
+void qp_del_napi(struct hinic3_irq *irq_cfg)
{
- napi_disable(&irq_cfg->napi);
- netif_napi_del(&irq_cfg->napi);
+ if (irq_cfg->napi_reign == NAPI_IS_REGIN) {
+ napi_disable(&irq_cfg->napi);
+ netif_napi_del(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_NOT_REGIN;
+ }
}
static irqreturn_t qp_irq(int irq, void *data)
@@ -60,7 +64,8 @@ static irqreturn_t qp_irq(int irq, void *data)
struct hinic3_irq *irq_cfg = (struct hinic3_irq *)data;
struct hinic3_nic_dev *nic_dev = netdev_priv(irq_cfg->netdev);
- hinic3_misx_intr_clear_resend_bit(nic_dev->hwdev, irq_cfg->msix_entry_idx, 1);
+ hinic3_misx_intr_clear_resend_bit(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx, 1);
napi_schedule(&irq_cfg->napi);
@@ -95,7 +100,8 @@ static int hinic3_request_irq(struct hinic3_irq *irq_cfg, u16 q_id)
return err;
}
- err = request_irq(irq_cfg->irq_id, &qp_irq, 0, irq_cfg->irq_name, irq_cfg);
+ err = request_irq(irq_cfg->irq_id, &qp_irq, 0,
+ irq_cfg->irq_name, irq_cfg);
if (err) {
nicif_err(nic_dev, drv, irq_cfg->netdev, "Failed to request Rx irq\n");
qp_del_napi(irq_cfg);
@@ -138,12 +144,8 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev)
local_cpu = cpumask_local_spread(q_id, dev_to_node(&pdev->dev));
cpumask_set_cpu(local_cpu, &irq_cfg->affinity_mask);
- err = snprintf(irq_cfg->irq_name, sizeof(irq_cfg->irq_name),
- "%s_qp%u", nic_dev->netdev->name, q_id);
- if (err < 0) {
- err = -EINVAL;
- goto req_tx_irq_err;
- }
+ snprintf(irq_cfg->irq_name, sizeof(irq_cfg->irq_name),
+ "%s_qp%u", nic_dev->netdev->name, q_id);
err = hinic3_request_irq(irq_cfg, q_id);
if (err) {
@@ -151,20 +153,25 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev)
goto req_tx_irq_err;
}
- hinic3_set_msix_auto_mask_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ hinic3_set_msix_auto_mask_state(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx,
HINIC3_SET_MSIX_AUTO_MASK);
- hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx, HINIC3_MSIX_ENABLE);
+ hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ HINIC3_MSIX_ENABLE);
}
- INIT_DELAYED_WORK(&nic_dev->moderation_task, hinic3_auto_moderation_work);
+ INIT_DELAYED_WORK(&nic_dev->moderation_task,
+ hinic3_auto_moderation_work);
return 0;
req_tx_irq_err:
for (i = 0; i < q_id; i++) {
irq_cfg = &nic_dev->q_params.irq_cfg[i];
- hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx, HINIC3_MSIX_DISABLE);
- hinic3_set_msix_auto_mask_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ HINIC3_MSIX_DISABLE);
+ hinic3_set_msix_auto_mask_state(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx,
HINIC3_CLR_MSIX_AUTO_MASK);
hinic3_release_irq(irq_cfg);
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
deleted file mode 100644
index 2482c5f..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_LLD_H
-#define HINIC3_LLD_H
-
-#include "hinic3_crm.h"
-
-struct hinic3_lld_dev {
- struct pci_dev *pdev;
- void *hwdev;
-};
-
-struct hinic3_uld_info {
- /* When the function does not need to initialize the corresponding uld,
- * @probe needs to return 0 and uld_dev is set to NULL;
- * if uld_dev is NULL, @remove will not be called when uninstalling
- */
- int (*probe)(struct hinic3_lld_dev *lld_dev, void **uld_dev, char *uld_dev_name);
- void (*remove)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- int (*suspend)(struct hinic3_lld_dev *lld_dev, void *uld_dev, pm_message_t state);
- int (*resume)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- void (*event)(struct hinic3_lld_dev *lld_dev, void *uld_dev,
- struct hinic3_event_info *event);
- int (*ioctl)(void *uld_dev, u32 cmd, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size);
-};
-
-/* hinic3_register_uld - register an upper-layer driver
- * @type: uld service type
- * @uld_info: uld callback
- *
- * Registers an upper-layer driver.
- * Traverse existing devices and call @probe to initialize the uld device.
- */
-int hinic3_register_uld(enum hinic3_service_type type, struct hinic3_uld_info *uld_info);
-
-/**
- * hinic3_unregister_uld - unregister an upper-layer driver
- * @type: uld service type
- *
- * Traverse existing devices and call @remove to uninstall the uld device.
- * Unregisters an existing upper-layer driver.
- */
-void hinic3_unregister_uld(enum hinic3_service_type type);
-
-void lld_hold(void);
-void lld_put(void);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_name - get lld device by chip name
- * @param chip_name: chip name
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_name(const char *chip_name);
-
-/**
- * @brief lld_dev_hold - get reference to lld_dev
- * @param dev: lld device
- *
- * Hold reference to device to keep it from being freed
- **/
-void lld_dev_hold(struct hinic3_lld_dev *dev);
-
-/**
- * @brief lld_dev_put - release reference to lld_dev
- * @param dev: lld device
- *
- * Release reference to device to allow it to be freed
- **/
-void lld_dev_put(struct hinic3_lld_dev *dev);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name_unsafe - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * hinic3_get_lld_dev_by_dev_name_unsafe() is completely analogous to
- * hinic3_get_lld_dev_by_dev_name(), The only difference is that the reference
- * of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that lld_dev will not be freed during the remove process
- * when using lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name_unsafe(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_and_port - get lld device by chip name and port id
- * @param chip_name: chip name
- * @param port_id: port id
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name, u8 port_id);
-
-/**
- * @brief hinic3_get_ppf_lld_dev - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief hinic3_get_ppf_lld_dev_unsafe - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * hinic3_get_ppf_lld_dev_unsafe() is completely analogous to hinic3_get_ppf_lld_dev(),
- * The only difference is that the reference of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that ppf's lld_dev will not be freed during the remove process
- * when using ppf lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev_unsafe(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief uld_dev_hold - get reference to uld_dev
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * Hold reference to uld device to keep it from being freed
- **/
-void uld_dev_hold(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief uld_dev_put - release reference to lld_dev
- * @param dev: lld device
- * @param type: uld service type
- *
- * Release reference to uld device to allow it to be freed
- **/
-void uld_dev_put(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * The value of uld_dev reference increases when uld_dev is obtained. The caller needs
- * to release the reference by calling uld_dev_put.
- **/
-void *hinic3_get_uld_dev(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev_unsafe - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * hinic3_get_uld_dev_unsafe() is completely analogous to hinic3_get_uld_dev(),
- * The only difference is that the reference of uld_dev is not increased when uld_dev is obtained.
- *
- * The caller must ensure that uld_dev will not be freed during the remove process
- * when using uld_dev.
- **/
-void *hinic3_get_uld_dev_unsafe(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_chip_name - get chip name by lld device
- * @param lld_dev: lld device
- * @param chip_name: String for storing the chip name
- * @param max_len: Maximum number of characters to be copied for chip_name
- **/
-int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len);
-
-struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev);
-
-struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev);
-
-bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service);
-
-int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
- bool vf_srv_load);
-
-int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id,
- u16 service, bool en);
-
-bool hinic3_get_vf_load_state(struct pci_dev *pdev);
-
-int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state);
-
-int hinic3_attach_nic(struct hinic3_lld_dev *lld_dev);
-
-void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
-
-int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-const char **hinic3_get_uld_names(void);
-int hinic3_lld_init(void);
-void hinic3_lld_exit(void);
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
index 2fe808b..5e4e184 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
@@ -17,11 +17,22 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_hw.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_common.h"
+#include "mag_mpu_cmd_defs.h"
+
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
+#define CAP_INFO_MAX_LEN 512
+#define DEVICE_VENDOR_MAX_LEN 17
+#define READ_RSFEC_REGISTER_DELAY_TIME_MS 500
+
+struct parse_tlv_info g_page_info = {0};
+struct drv_tag_mag_cmd_get_xsfp_tlv_rsp g_xsfp_tlv_info = {0};
static int mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
@@ -78,8 +89,10 @@ int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats)
return -ENOMEM;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
memset(&stats_info, 0, sizeof(stats_info));
stats_info.port_id = hinic3_physical_port_id(hwdev);
@@ -104,6 +117,64 @@ out:
}
EXPORT_SYMBOL(hinic3_get_phy_port_stats);
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats)
+{
+ struct mag_cmd_get_mag_cnt *port_stats = NULL;
+ struct mag_cmd_get_mag_cnt stats_info;
+ u16 out_size = sizeof(*port_stats);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !stats)
+ return -EINVAL;
+
+ port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
+ if (!port_stats)
+ return -ENOMEM;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ memset(&stats_info, 0, sizeof(stats_info));
+ stats_info.port_id = hinic3_physical_port_id(hwdev);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT,
+ &stats_info, sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+ /* 读2遍, 清除误码残留 */
+ msleep(READ_RSFEC_REGISTER_DELAY_TIME_MS);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT, &stats_info,
+ sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+
+ memcpy(stats, &port_stats->mag_csr[MAG_RX_RSFEC_ERR_CW_CNT],
+ sizeof(u32));
+
+out:
+ kfree(port_stats);
+
+ return err;
+}
+EXPORT_SYMBOL(hinic3_get_phy_rsfec_stats);
+
int hinic3_set_port_funcs_state(void *hwdev, bool enable)
{
return 0;
@@ -180,6 +251,8 @@ int hinic3_get_loopback_mode(void *hwdev, u8 *mode, u8 *enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_cfg_loopback_mode(nic_io, MGMT_MSG_CMD_OP_GET, mode,
enable);
@@ -195,6 +268,8 @@ int hinic3_set_loopback_mode(void *hwdev, u8 mode, u8 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) {
nic_err(nic_io->dev_hdl, "Invalid loopback mode %u to set\n",
@@ -218,6 +293,9 @@ int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&led_info, 0, sizeof(led_info));
led_info.function_id = hinic3_global_func_id(hwdev);
@@ -249,6 +327,8 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
memset(&port_msg, 0, sizeof(port_msg));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
port_msg.port_id = hinic3_physical_port_id(hwdev);
@@ -268,9 +348,12 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
port_info->port_type = port_msg.wire_type;
port_info->speed = port_msg.speed;
port_info->fec = port_msg.fec;
+ port_info->lanes = port_msg.lanes;
port_info->supported_mode = port_msg.supported_mode;
port_info->advertised_mode = port_msg.advertised_mode;
-
+ port_info->supported_fec_mode = port_msg.supported_fec_mode;
+ /* switch Gbps to Mbps */
+ port_info->bond_speed = (u32)port_msg.bond_speed * RATE_MBPS_TO_GBPS;
return 0;
}
@@ -306,6 +389,8 @@ int hinic3_set_link_settings(void *hwdev,
memset(&info, 0, sizeof(info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
info.port_id = hinic3_physical_port_id(hwdev);
info.config_bitmap = settings->valid_bitmap;
@@ -335,6 +420,8 @@ int hinic3_get_link_state(void *hwdev, u8 *link_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&get_link, 0, sizeof(get_link));
get_link.port_id = hinic3_physical_port_id(hwdev);
@@ -364,9 +451,10 @@ void hinic3_notify_vf_link_status(struct hinic3_nic_io *nic_io,
if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
link.status = link_status;
link.port_id = hinic3_physical_port_id(nic_io->hwdev);
- err = hinic3_mbox_to_vf(nic_io->hwdev, vf_id, HINIC3_MOD_HILINK,
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
MAG_CMD_GET_LINK_STATUS, &link,
- sizeof(link), &link, &out_size, 0,
+ sizeof(link), &link, &out_size,
HINIC3_CHANNEL_NIC);
if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
@@ -387,6 +475,8 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
u16 i;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
nic_io->link_status = link_status;
for (i = 1; i <= nic_io->max_vfs; i++) {
if (!nic_io->vf_infos[HW_VF_ID_TO_OS(i)].link_forced)
@@ -394,6 +484,165 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
}
}
+static char *g_hw_to_char_fec[HILINK_FEC_MAX_TYPE] = {
+ "not set", "rsfec", "basefec",
+ "nofec", "llrsfec"};
+static char *g_hw_to_speed_info[PORT_SPEED_UNKNOWN] = {
+ "not set", "10MB", "100MB", "1GB", "10GB",
+ "25GB", "40GB", "50GB", "100GB", "200GB"};
+static char *g_hw_to_an_state_info[PORT_CFG_AN_OFF + 1] = {
+ "not set", "on", "off"};
+
+struct port_type_table {
+ u32 port_type;
+ char *port_type_name;
+};
+
+static const struct port_type_table port_optical_type_table_s[] = {
+ {LINK_PORT_UNKNOWN, "UNKNOWN"},
+ {LINK_PORT_OPTICAL_MM, "optical_sr"},
+ {LINK_PORT_OPTICAL_SM, "optical_lr"},
+ {LINK_PORT_PAS_COPPER, "copper"},
+ {LINK_PORT_ACC, "ACC"},
+ {LINK_PORT_BASET, "baset"},
+ {LINK_PORT_AOC, "AOC"},
+ {LINK_PORT_ELECTRIC, "electric"},
+ {LINK_PORT_BACKBOARD_INTERFACE, "interface"},
+};
+
+static char *get_port_type_name(u32 type)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(port_optical_type_table_s); i++) {
+ if (type == port_optical_type_table_s[i].port_type)
+ return port_optical_type_table_s[i].port_type_name;
+ }
+ return "UNKNOWN TYPE";
+}
+
+static void get_port_type(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ char **port_type)
+{
+ if (info->port_type <= LINK_PORT_BACKBOARD_INTERFACE)
+ *port_type = get_port_type_name(info->port_type);
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown port type: %u\n", info->port_type);
+}
+
+static int get_port_temperature_power(struct mag_cmd_event_port_info *info,
+ char *str)
+{
+ char cap_info[CAP_INFO_MAX_LEN];
+
+ memset(cap_info, 0, sizeof(cap_info));
+ snprintf(cap_info, CAP_INFO_MAX_LEN, "%s, %s, Temperature: %u", str,
+ info->sfp_type ? "QSFP" : "SFP", info->cable_temp);
+
+ if (info->sfp_type)
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuw %uuW %uuW %uuW",
+ cap_info, info->power[0x0], info->power[0x1],
+ info->power[0x2], info->power[0x3]);
+ else
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuW, tx power: %uuW",
+ cap_info, info->power[0x0], info->power[0x1]);
+
+ return 0;
+}
+
+static void print_cable_info(struct hinic3_nic_io *nic_io, struct mag_cmd_event_port_info *info)
+{
+ char tmp_str[CAP_INFO_MAX_LEN] = {0};
+ char tmp_vendor[DEVICE_VENDOR_MAX_LEN] = {0};
+ char *port_type = "Unknown port type";
+ int i;
+ int err = 0;
+
+ if (info->gpio_insert) {
+ sdk_info(nic_io->dev_hdl, "Cable unpresent\n");
+ return;
+ }
+
+ get_port_type(nic_io, info, &port_type);
+
+ for (i = sizeof(info->vendor_name) - 1; i >= 0; i--) {
+ if (info->vendor_name[i] == ' ')
+ info->vendor_name[i] = '\0';
+ else
+ break;
+ }
+
+ memcpy(tmp_vendor, info->vendor_name, sizeof(info->vendor_name));
+ snprintf(tmp_str, CAP_INFO_MAX_LEN, "Vendor: %s, %s, length: %um, max_speed: %uGbps",
+ tmp_vendor, port_type, info->cable_length, info->max_speed);
+
+ if (info->port_type == LINK_PORT_OPTICAL_MM ||
+ info->port_type == LINK_PORT_AOC) {
+ err = get_port_temperature_power(info, tmp_str);
+ if (err)
+ return;
+ }
+
+ sdk_info(nic_io->dev_hdl, "Cable information: %s\n", tmp_str);
+}
+
+static void print_link_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ enum hinic3_nic_event_type type)
+{
+ char *fec = "None";
+ char *speed = "None";
+ char *an_state = "None";
+
+ if (info->fec < HILINK_FEC_MAX_TYPE)
+ fec = g_hw_to_char_fec[info->fec];
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown fec type: %u\n", info->fec);
+
+ if (info->an_state > PORT_CFG_AN_OFF) {
+ sdk_info(nic_io->dev_hdl, "an_state %d is invalid",
+ info->an_state);
+ return;
+ }
+
+ an_state = g_hw_to_an_state_info[info->an_state];
+
+ if (info->speed >= PORT_SPEED_UNKNOWN) {
+ sdk_info(nic_io->dev_hdl, "speed %u is invalid", info->speed);
+ return;
+ }
+
+ speed = g_hw_to_speed_info[info->speed];
+ sdk_info(nic_io->dev_hdl, "Link information: speed %s, %s, autoneg %s",
+ speed, fec, an_state);
+}
+
+void print_port_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *port_info,
+ enum hinic3_nic_event_type type)
+{
+ print_cable_info(nic_io, port_info);
+
+ print_link_info(nic_io, port_info, type);
+
+ if (type == EVENT_NIC_LINK_UP)
+ return;
+
+ sdk_info(nic_io->dev_hdl, "PMA ctrl: %s, tx %s, rx %s, PMA fifo reg: 0x%x, PMA signal ok reg: 0x%x, RF/LF status reg: 0x%x\n",
+ port_info->pma_ctrl == 1 ? "off" : "on",
+ port_info->tx_enable ? "enable" : "disable",
+ port_info->rx_enable ? "enable" : "disable", port_info->pma_fifo_reg,
+ port_info->pma_signal_ok_reg, port_info->rf_lf);
+ sdk_info(nic_io->dev_hdl, "alos: %u, rx_los: %u, PCS 64 66b reg: 0x%x, PCS link: 0x%x, MAC link: 0x%x PCS_err_cnt: 0x%x\n",
+ port_info->alos, port_info->rx_los, port_info->pcs_64_66b_reg,
+ port_info->pcs_link, port_info->pcs_mac_link,
+ port_info->pcs_err_cnt);
+ sdk_info(nic_io->dev_hdl, "his_link_machine_state = 0x%08x, cur_link_machine_state = 0x%08x\n",
+ port_info->his_link_machine_state,
+ port_info->cur_link_machine_state);
+}
+
static int hinic3_get_vf_link_status_msg_handler(struct hinic3_nic_io *nic_io,
u16 vf_id, void *buf_in,
u16 in_size, void *buf_out,
@@ -433,6 +682,10 @@ static void get_port_info(void *hwdev,
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (hinic3_func_type(hwdev) != TYPE_VF && link_status->status) {
err = hinic3_get_port_info(hwdev, &port_info, HINIC3_CHANNEL_NIC);
if (err) {
@@ -457,8 +710,18 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
struct hinic3_event_info event_info = {0};
struct hinic3_event_link_info *link_info = (void *)event_info.event_data;
struct hinic3_nic_io *nic_io = NULL;
+#ifndef __UEFI__
+ struct pci_dev *pdev = NULL;
+#endif
+ /* Ignore link change event */
+ if (hinic3_is_bm_slave_host(hwdev))
+ return;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
link_status = buf_in;
sdk_info(nic_io->dev_hdl, "Link status report received, func_id: %u, status: %u\n",
@@ -475,6 +738,15 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
hinic3_event_callback(hwdev, &event_info);
+#ifndef __UEFI__
+ if (nic_io->pcidev_hdl != NULL) {
+ pdev = nic_io->pcidev_hdl;
+ if (pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID) {
+ return;
+ }
+ }
+#endif
+
if (hinic3_func_type(hwdev) != TYPE_VF) {
hinic3_notify_all_vfs_link_changed(hwdev, link_status->status);
ret_link_status = buf_out;
@@ -483,20 +755,142 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
}
}
+static void port_info_event_printf(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_event_port_info *port_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info;
+ enum hinic3_nic_event_type type;
+
+ if (!hwdev) {
+ pr_err("hwdev is NULL\n");
+ return;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ if (in_size != sizeof(*port_info)) {
+ sdk_info(nic_io->dev_hdl, "Invalid port info message size %d, should be %ld\n",
+ in_size, sizeof(*port_info));
+ return;
+ }
+
+ ((struct mag_cmd_event_port_info *)buf_out)->head.status = 0;
+
+ type = port_info->event_type;
+ if (type < EVENT_NIC_LINK_DOWN || type > EVENT_NIC_LINK_UP) {
+ sdk_info(nic_io->dev_hdl, "Invalid hilink info report, type: %d\n",
+ type);
+ return;
+ }
+
+ print_port_info(nic_io, port_info, type);
+
+ memset(&event_info, 0, sizeof(event_info));
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = type;
+
+ *out_size = sizeof(*port_info);
+
+ hinic3_event_callback(hwdev, &event_info);
+}
+
+void hinic3_notify_vf_bond_status(struct hinic3_nic_io *nic_io,
+ u16 vf_id, u8 bond_status)
+{
+ struct mag_cmd_get_bond_status bond;
+ struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ u16 out_size = sizeof(bond);
+ int err;
+
+ memset(&bond, 0, sizeof(bond));
+ if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
+ bond.status = bond_status;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
+ MAG_CMD_GET_BOND_STATUS, &bond,
+ sizeof(bond), &bond, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF %u not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return;
+ }
+ if (err || !out_size || bond.head.status)
+ nic_err(nic_io->dev_hdl,
+ "Send bond change event to VF %hu failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err, bond.head.status,
+ out_size);
+ }
+}
+
+void hinic3_notify_all_vfs_bond_changed(void *hwdev, u8 bond_status)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 i;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ nic_io->link_status = bond_status;
+ for (i = 1; i <= nic_io->max_vfs; i++)
+ hinic3_notify_vf_bond_status(nic_io, i, bond_status);
+}
+
+static void bond_status_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_get_bond_status *bond_status = NULL;
+ struct hinic3_event_info event_info = {};
+ struct hinic3_nic_io *nic_io = NULL;
+ struct mag_cmd_get_bond_status *ret_bond_status = NULL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+
+ bond_status = (struct mag_cmd_get_bond_status *)buf_in;
+ sdk_info(nic_io->dev_hdl, "bond status report received, func_id: %u, status: %u\n",
+ hinic3_global_func_id(hwdev), bond_status->status);
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = bond_status->status ?
+ EVENT_NIC_BOND_UP : EVENT_NIC_BOND_DOWN;
+
+ hinic3_event_callback(hwdev, &event_info);
+
+ if (hinic3_func_type(hwdev) != TYPE_VF) {
+ hinic3_notify_all_vfs_bond_changed(hwdev, bond_status->status);
+ ret_bond_status = buf_out;
+ ret_bond_status->head.status = 0;
+ *out_size = sizeof(*ret_bond_status);
+ }
+}
+
static void cable_plug_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct mag_cmd_wire_event *plug_event = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_event_info event_info;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
rt_cmd->mpu_send_sfp_abs = false;
rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
memset(&event_info, 0, sizeof(event_info));
@@ -518,9 +912,12 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
{
struct mag_cmd_get_xsfp_info *sfp_info = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_info)) {
sdk_err(nic_io->dev_hdl, "Invalid sfp info cmd, length: %u, should be %ld\n",
in_size, sizeof(*sfp_info));
@@ -528,10 +925,41 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
}
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
memcpy(&rt_cmd->std_sfp_info, sfp_info,
sizeof(struct mag_cmd_get_xsfp_info));
rt_cmd->mpu_send_sfp_info = true;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+}
+
+static void port_xsfp_tlv_info_event(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *xsfp_tlv_info = buf_in;
+ struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
+ size_t cpy_len = in_size - sizeof(struct mgmt_msg_head) -
+ XSFP_TLV_PRE_INFO_LEN;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL)
+ return;
+
+ if (cpy_len > XSFP_CMIS_INFO_MAX_SIZE) {
+ sdk_err(nic_io->dev_hdl, "invalid cpy_len(%lu)\n", cpy_len);
+ return;
+ }
+ rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ rt_cmd_ext->std_xsfp_tlv_info.port_id = xsfp_tlv_info->port_id;
+ memcpy(&(rt_cmd_ext->std_xsfp_tlv_info.tlv_buf[0]),
+ &(xsfp_tlv_info->tlv_buf[0]), cpy_len);
+ rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = true;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
}
@@ -543,6 +971,8 @@ static void port_sfp_abs_event(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_abs)) {
sdk_err(nic_io->dev_hdl, "Invalid sfp absent cmd, length: %u, should be %ld\n",
in_size, sizeof(*sfp_abs));
@@ -564,9 +994,11 @@ bool hinic3_if_sfp_absent(void *hwdev)
u8 port_id = hinic3_physical_port_id(hwdev);
u16 out_size = sizeof(sfp_abs);
int err;
- bool sfp_abs_status;
+ bool sfp_abs_status = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return true;
memset(&sfp_abs, 0, sizeof(sfp_abs));
rt_cmd = &nic_io->nic_cfg.rt_cmd;
@@ -597,10 +1029,185 @@ bool hinic3_if_sfp_absent(void *hwdev)
return (sfp_abs.abs_status == 0 ? false : true);
}
+int hinic3_get_sfp_tlv_info(void *hwdev, struct drv_tag_mag_cmd_get_xsfp_tlv_rsp
+ *sfp_tlv_info,
+ const struct tag_mag_cmd_get_xsfp_tlv_req
+ *sfp_tlv_info_req)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ u16 out_size = sizeof(*sfp_tlv_info);
+ int err;
+
+ if ((hwdev == NULL) || (sfp_tlv_info == NULL))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL)
+ return -EINVAL;
+
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ if (rt_cmd_ext->mpu_send_xsfp_tlv_info == true) {
+ if (rt_cmd_ext->std_xsfp_tlv_info.head.status != 0) {
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return -EIO;
+ }
+
+ memcpy(sfp_tlv_info, &rt_cmd_ext->std_xsfp_tlv_info,
+ sizeof(*sfp_tlv_info));
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_TLV_INFO,
+ (void *)sfp_tlv_info_req,
+ sizeof(*sfp_tlv_info_req),
+ sfp_tlv_info, &out_size);
+ if ((sfp_tlv_info->head.status != 0) || (err != 0) || (out_size == 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get port%u tlv sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
+ hinic3_physical_port_id(hwdev), err,
+ sfp_tlv_info->head.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_get_page_pos(u32 page_id, u32 content_len, u32 *pos)
+{
+ if (page_id <= QSFP_CMIS_PAGE_03H) {
+ *pos = (page_id * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_11H) {
+ *pos = (QSFP_CMIS_PAGE_04H * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_12H) {
+ *pos = (QSFP_CMIS_PAGE_05H * content_len);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int hinic3_get_page_key_info(struct mgmt_tlv_info *tlv_info,
+ struct parse_tlv_info *page_info, u8 idx,
+ u32 *total_len)
+{
+ u8 *src_addr = NULL;
+ u8 *dst_addr = NULL;
+ u8 *tmp_addr = NULL;
+ u32 page_id = 0;
+ u32 content_len = 0;
+ u32 src_pos = 0;
+ int ret;
+
+ page_id = MGMT_TLV_GET_U32(tlv_info->value);
+ content_len = tlv_info->length - MGMT_TLV_U32_SIZE;
+ if (page_id == QSFP_CMIS_PAGE_00H) {
+ tmp_addr = (u8 *)(tlv_info + 1);
+ page_info->id = *(tmp_addr + MGMT_TLV_U32_SIZE);
+ }
+
+ ret = hinic3_trans_cmis_get_page_pos(page_id, content_len, &src_pos);
+ if (ret != 0)
+ return ret;
+
+ src_addr = page_info->tlv_page_info + src_pos;
+ tmp_addr = (u8 *)(tlv_info + 1);
+ dst_addr = tmp_addr + MGMT_TLV_U32_SIZE;
+ memcpy(src_addr, dst_addr, content_len);
+
+ if (idx < XSFP_CMIS_PARSE_PAGE_NUM)
+ page_info->tlv_page_num[idx] = page_id;
+
+ *total_len += content_len;
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_tlv_info_to_buf(u8 *sfp_tlv_info,
+ struct parse_tlv_info *page_info)
+{
+ struct mgmt_tlv_info *tlv_info = NULL;
+ u8 *tlv_buf = sfp_tlv_info;
+ u8 idx = 0;
+ u32 total_len = 0;
+ int ret = 0;
+ bool need_continue = true;
+
+ if ((sfp_tlv_info == NULL) || (page_info == NULL))
+ return -EIO;
+
+ while (need_continue) {
+ tlv_info = (struct mgmt_tlv_info *)tlv_buf;
+ switch (tlv_info->type) {
+ case MAG_XSFP_TYPE_PAGE:
+ ret = hinic3_get_page_key_info(
+ tlv_info, page_info, idx, &total_len);
+ if (ret != 0) {
+ pr_err("lib_get_page_key_info fail,ret:0x%x.\n",
+ ret);
+ break;
+ }
+ idx++;
+ break;
+
+ case MAG_XSFP_TYPE_WIRE_TYPE:
+ page_info->wire_type =
+ MGMT_TLV_GET_U32(&(tlv_info->value));
+ break;
+
+ case MAG_XSFP_TYPE_END:
+ need_continue = false;
+ break;
+
+ default:
+ break;
+ }
+
+ tlv_buf += (sizeof(struct mgmt_tlv_info) + tlv_info->length);
+ }
+
+ page_info->tlv_page_info_len = total_len;
+
+ return 0;
+}
+
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len)
+{
+ int err = 0;
+ struct tag_mag_cmd_get_xsfp_tlv_req xsfp_tlv_info_req = {0};
+
+ xsfp_tlv_info_req.rsp_buf_len = XSFP_CMIS_INFO_MAX_SIZE;
+ xsfp_tlv_info_req.port_id = hinic3_physical_port_id(hwdev);
+ err = hinic3_get_sfp_tlv_info(hwdev, &g_xsfp_tlv_info,
+ &xsfp_tlv_info_req);
+ if (err != 0)
+ return err;
+
+ err = hinic3_trans_cmis_tlv_info_to_buf(g_xsfp_tlv_info.tlv_buf,
+ &g_page_info);
+ if (err)
+ return -ENOMEM;
+
+ memcpy(data, g_page_info.tlv_page_info, len);
+
+ return (err == 0) ? 0 : -ENOMEM;
+}
+
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
{
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ u8 sfp_info_status = 0;
u16 out_size = sizeof(*sfp_info);
int err;
@@ -608,13 +1215,17 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ sfp_info_status = rt_cmd->std_sfp_info.head.status;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (sfp_info_status != 0) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return -EIO;
+ return (sfp_info_status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ ? HINIC3_MGMT_CMD_UNSUPPORTED : -EIO;
}
memcpy(sfp_info, &rt_cmd->std_sfp_info, sizeof(*sfp_info));
@@ -626,7 +1237,12 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
sfp_info->port_id = hinic3_physical_port_id(hwdev);
err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_INFO, sfp_info,
sizeof(*sfp_info), sfp_info, &out_size);
- if (sfp_info->head.status || err || !out_size) {
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ return HINIC3_MGMT_CMD_UNSUPPORTED;
+
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ return -EOPNOTSUPP;
+ if ((sfp_info->head.status != 0) || (err != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Failed to get port%u sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
hinic3_physical_port_id(hwdev), err,
@@ -642,7 +1258,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
struct mag_cmd_get_xsfp_info sfp_info;
int err;
- if (!hwdev || !data)
+ if (!hwdev || !data || len > PAGE_SIZE)
return -EINVAL;
if (hinic3_if_sfp_absent(hwdev))
@@ -654,7 +1270,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
if (err)
return err;
- memcpy(data, sfp_info.sfp_info, len);
+ memcpy(data, sfp_info.sfp_info, sizeof(sfp_info.sfp_info));
return 0;
}
@@ -664,7 +1280,7 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
- int err;
+ int err = 0;
if (!hwdev || !sfp_type || !sfp_type_ext)
return -EINVAL;
@@ -677,20 +1293,35 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (rt_cmd->std_sfp_info.head.status == 0) {
+ *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
+ *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ if (rt_cmd->std_sfp_info.head.status != HINIC3_MGMT_CMD_UNSUPPORTED) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
return -EIO;
}
- *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
- *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
- mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return 0;
+ err = HINIC3_MGMT_CMD_UNSUPPORTED; /* cmis */
}
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
- STD_SFP_INFO_MAX_SIZE);
+ if (err == 0) {
+ err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ } else {
+ /* mpu_send_sfp_info is false */
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ }
+
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+
if (err)
return err;
@@ -796,16 +1427,23 @@ int hinic3_set_pf_bw_limit(void *hwdev, u32 bw_limit)
return -EINVAL;
}
- old_bw_limit = nic_io->nic_cfg.pf_bw_limit;
- nic_io->nic_cfg.pf_bw_limit = bw_limit;
+ if (nic_io->direct == HINIC3_NIC_TX) {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_tx_limit;
+ nic_io->nic_cfg.pf_bw_tx_limit = bw_limit;
+ } else {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_rx_limit;
+ nic_io->nic_cfg.pf_bw_rx_limit = bw_limit;
+ }
err = hinic3_update_pf_bw(hwdev);
if (err) {
- nic_io->nic_cfg.pf_bw_limit = old_bw_limit;
- return err;
+ if (nic_io->direct == HINIC3_NIC_TX)
+ nic_io->nic_cfg.pf_bw_tx_limit = old_bw_limit;
+ else
+ nic_io->nic_cfg.pf_bw_rx_limit = old_bw_limit;
}
- return 0;
+ return err;
}
static const struct vf_msg_handler vf_mag_cmd_handler[] = {
@@ -828,6 +1466,9 @@ int hinic3_pf_mag_mbox_handler(void *hwdev, u16 vf_id,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
for (index = 0; index < cmd_size; index++) {
handler = &vf_mag_cmd_handler[index];
@@ -848,6 +1489,11 @@ static struct nic_event_handler mag_cmd_handler[] = {
.handler = link_status_event_handler,
},
+ {
+ .cmd = MAG_CMD_EVENT_PORT_INFO,
+ .handler = port_info_event_printf,
+ },
+
{
.cmd = MAG_CMD_WIRE_EVENT,
.handler = cable_plug_event,
@@ -862,6 +1508,16 @@ static struct nic_event_handler mag_cmd_handler[] = {
.cmd = MAG_CMD_GET_XSFP_PRESENT,
.handler = port_sfp_abs_event,
},
+
+ {
+ .cmd = MAG_CMD_GET_BOND_STATUS,
+ .handler = bond_status_event_handler,
+ },
+
+ {
+ .cmd = MAG_CMD_GET_XSFP_TLV_INFO,
+ .handler = port_xsfp_tlv_info_event,
+ },
};
static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
@@ -877,6 +1533,9 @@ static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
for (i = 0; i < size; i++) {
if (cmd == mag_cmd_handler[i].cmd) {
mag_cmd_handler[i].handler(hwdev, buf_in, in_size,
@@ -917,7 +1576,8 @@ static int _mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u32 i, cmd_cnt = ARRAY_LEN(vf_mag_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_mag_cmd_handler[i].cmd) {
cmd_to_pf = true;
@@ -949,3 +1609,124 @@ static int mag_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in,
return _mag_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out,
out_size, channel);
}
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+struct fecparam_value_map {
+ u8 hinic3_fec_offset;
+ u8 hinic3_fec_value;
+ u8 ethtool_fec_value;
+};
+
+static void fecparam_convert(u32 opcode, u8 in_fec_param, u8 *out_fec_param)
+{
+ u8 i;
+ u8 fec_value_table_lenth;
+ struct fecparam_value_map fec_value_table[] = {
+ {PORT_FEC_NOT_SET, BIT(PORT_FEC_NOT_SET), ETHTOOL_FEC_NONE},
+ {PORT_FEC_RSFEC, BIT(PORT_FEC_RSFEC), ETHTOOL_FEC_RS},
+ {PORT_FEC_BASEFEC, BIT(PORT_FEC_BASEFEC), ETHTOOL_FEC_BASER},
+ {PORT_FEC_NOFEC, BIT(PORT_FEC_NOFEC), ETHTOOL_FEC_OFF},
+#ifdef ETHTOOL_FEC_LLRS
+ {PORT_FEC_LLRSFEC, BIT(PORT_FEC_LLRSFEC), ETHTOOL_FEC_LLRS},
+#endif
+ {PORT_FEC_AUTO, BIT(PORT_FEC_AUTO), ETHTOOL_FEC_AUTO}
+ };
+
+ *out_fec_param = 0;
+ fec_value_table_lenth = (u8)(sizeof(fec_value_table) / sizeof(struct fecparam_value_map));
+
+ if (opcode == MAG_CMD_OPCODE_SET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].ethtool_fec_value) != 0)
+ /* The MPU uses the offset to determine the FEC mode. */
+ *out_fec_param =
+ fec_value_table[i].hinic3_fec_offset;
+ }
+ }
+
+ if (opcode == MAG_CMD_OPCODE_GET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].hinic3_fec_value) != 0)
+ *out_fec_param |=
+ fec_value_table[i].ethtool_fec_value;
+ }
+ }
+}
+
+/* When the ethtool is used to set the FEC mode */
+static bool check_fecparam_is_valid(u8 fec_param)
+{
+ if (
+#ifdef ETHTOOL_FEC_LLRS
+ (fec_param == ETHTOOL_FEC_LLRS) ||
+#endif
+ (fec_param == ETHTOOL_FEC_RS) ||
+ (fec_param == ETHTOOL_FEC_BASER) ||
+ (fec_param == ETHTOOL_FEC_OFF)) {
+ return true;
+ }
+ return false;
+}
+
+int set_fecparam(void *hwdev, u8 fecparam)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ u8 advertised_fec = 0;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (check_fecparam_is_valid(fecparam) == false) {
+ nic_err(nic_io->dev_hdl, "fec param is invalid, failed to set fec param\n");
+ return -EINVAL;
+ }
+ fecparam_convert(MAG_CMD_OPCODE_SET, fecparam, &advertised_fec);
+ fec_msg.opcode = MAG_CMD_OPCODE_SET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ fec_msg.advertised_fec = advertised_fec;
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0))
+ return -EINVAL;
+ return 0;
+}
+
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ fec_msg.opcode = MAG_CMD_OPCODE_GET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0))
+ return -EINVAL;
+
+ /* fec_msg.advertised_fec: bit offset,
+ *value is BIT(fec_msg.advertised_fec); fec_msg.supported_fec: value
+ */
+ fecparam_convert(MAG_CMD_OPCODE_GET, BIT(fec_msg.advertised_fec),
+ advertised_fec);
+ fecparam_convert(MAG_CMD_OPCODE_GET, fec_msg.supported_fec,
+ supported_fec);
+ return 0;
+}
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
index 6f90c86..9d14e0f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
@@ -20,6 +20,9 @@
#include <linux/debugfs.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#include "hinic3_hw.h"
#include "hinic3_crm.h"
#include "hinic3_mt.h"
@@ -35,8 +38,8 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
#include "hinic3_profile.h"
+#include "hinic3_bond.h"
-/*lint -e806*/
#define DEFAULT_POLL_WEIGHT 64
static unsigned int poll_weight = DEFAULT_POLL_WEIGHT;
module_param(poll_weight, uint, 0444);
@@ -68,7 +71,9 @@ static unsigned char set_link_status_follow = HINIC3_LINK_FOLLOW_STATUS_MAX;
module_param(set_link_status_follow, byte, 0444);
MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=default,1=follow,2=separate,3=unset");
-/*lint +e806*/
+static bool page_pool_enabled = true;
+module_param(page_pool_enabled, bool, 0444);
+MODULE_PARM_DESC(page_pool_enabled, "enable/disable page_pool feature for rxq page management (default enable)");
#define HINIC3_NIC_DEV_WQ_NAME "hinic3_nic_dev_wq"
@@ -80,6 +85,8 @@ MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=
#define HINIC3_SQ_DEPTH 1024
#define HINIC3_RQ_DEPTH 1024
+#define LRO_ENABLE 1
+
enum hinic3_rx_buff_len {
RX_BUFF_VALID_2KB = 2,
RX_BUFF_VALID_4KB = 4,
@@ -87,12 +94,15 @@ enum hinic3_rx_buff_len {
RX_BUFF_VALID_16KB = 16,
};
+#define NIC_MAX_PF_NUM 32
+
#define CONVERT_UNIT 1024
-#define BIFUR_RESOURCE_PF_SSID 0x5a1
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
-static int hinic3_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr);
+static int hinic3_netdev_event(struct notifier_block *notifier,
+ unsigned long event, void *ptr);
/* used for netdev notifier register/unregister */
static DEFINE_MUTEX(hinic3_netdev_notifiers_mutex);
@@ -101,6 +111,17 @@ static struct notifier_block hinic3_netdev_notifier = {
.notifier_call = hinic3_netdev_event,
};
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+static const struct udp_tunnel_nic_info hinic3_udp_tunnels = {
+ .set_port = hinic3_udp_tunnel_set_port,
+ .unset_port = hinic3_udp_tunnel_unset_port,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static void hinic3_register_notifier(struct hinic3_nic_dev *nic_dev)
{
int err;
@@ -134,7 +155,8 @@ static void hinic3_unregister_notifier(struct hinic3_nic_dev *nic_dev)
NETIF_F_SCTP_CRC | NETIF_F_RXCSUM | \
NETIF_F_ALL_TSO)
-static int hinic3_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr)
+static int hinic3_netdev_event(struct notifier_block *notifier,
+ unsigned long event, void *ptr)
{
struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
struct net_device *real_dev = NULL;
@@ -266,6 +288,11 @@ static void netdev_feature_init(struct net_device *netdev)
netdev->features |= dft_fts | cso_fts | tso_fts | vlan_fts;
netdev->vlan_features |= dft_fts | cso_fts | tso_fts;
+ if (nic_dev->nic_cap.lro_enable == LRO_ENABLE) {
+ netdev->features |= NETIF_F_LRO;
+ netdev->vlan_features |= NETIF_F_LRO;
+ }
+
#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT
hw_features |= get_netdev_hw_features(netdev);
#else
@@ -306,7 +333,8 @@ static void init_intr_coal_param(struct hinic3_nic_dev *nic_dev)
info->pending_limt = qp_pending_limit;
info->coalesce_timer_cfg = qp_coalesc_timer_cfg;
- info->resend_timer_cfg = HINIC3_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG;
+ info->resend_timer_cfg =
+ HINIC3_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG;
info->pkt_rate_high = HINIC3_RX_RATE_HIGH;
info->rx_usecs_high = HINIC3_RX_COAL_TIME_HIGH;
@@ -350,6 +378,7 @@ static int hinic3_init_intr_coalesce(struct hinic3_nic_dev *nic_dev)
static void hinic3_free_intr_coalesce(struct hinic3_nic_dev *nic_dev)
{
kfree(nic_dev->intr_coalesce);
+ nic_dev->intr_coalesce = NULL;
}
static int hinic3_alloc_txrxqs(struct hinic3_nic_dev *nic_dev)
@@ -396,15 +425,18 @@ static void hinic3_free_txrxqs(struct hinic3_nic_dev *nic_dev)
static void hinic3_tx_rx_ops_init(struct hinic3_nic_dev *nic_dev)
{
if (HINIC3_SUPPORT_TX_COMPACT_WQE_OL(nic_dev->hwdev)) {
- nic_dev->tx_rx_ops.tx_set_wqebb_cnt = hinic3_tx_set_compact_offload_wqebb_cnt;
- nic_dev->tx_rx_ops.tx_set_wqe_task = hinic3_tx_set_compact_offload_wqe_task;
+ nic_dev->tx_rx_ops.tx_set_wqebb_cnt =
+ hinic3_tx_set_compact_offload_wqebb_cnt;
+ nic_dev->tx_rx_ops.tx_set_wqe_task =
+ hinic3_tx_set_compact_offload_wqe_task;
} else {
nic_dev->tx_rx_ops.tx_set_wqebb_cnt = hinic3_tx_set_wqebb_cnt;
nic_dev->tx_rx_ops.tx_set_wqe_task = hinic3_tx_set_wqe_task;
}
if (HINIC3_SUPPORT_RX_COMPACT_CQE(nic_dev->hwdev))
- nic_dev->tx_rx_ops.rx_get_cqe_info = hinic3_rx_get_compact_cqe_info;
+ nic_dev->tx_rx_ops.rx_get_cqe_info =
+ hinic3_rx_get_compact_cqe_info;
else
nic_dev->tx_rx_ops.rx_get_cqe_info = hinic3_rx_get_cqe_info;
}
@@ -420,53 +452,47 @@ static void hinic3_sw_deinit(struct hinic3_nic_dev *nic_dev)
HINIC3_CHANNEL_NIC);
hinic3_clear_rss_config(nic_dev);
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+
+ hinic3_dcb_deinit(nic_dev);
}
-static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
+static void hinic3_netdev_mtu_init(struct net_device *netdev)
+{
+ /* MTU range: 384 - 9600 */
+#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
+ netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+
+#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
+ netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+}
+
+static int hinic3_set_default_mac(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
u8 mac_addr[ETH_ALEN];
- u64 nic_features;
int err = 0;
- nic_features = hinic3_get_feature_cap(nic_dev->hwdev);
- /* You can update the features supported by the driver according to the
- * scenario here
- */
- nic_features &= NIC_DRV_DEFAULT_FEATURE;
- hinic3_update_nic_feature(nic_dev->hwdev, nic_features);
-
- sema_init(&nic_dev->port_state_sem, 1);
-
- err = hinic3_dcb_init(nic_dev);
- if (err) {
- nic_err(&nic_dev->pdev->dev, "Failed to init dcb\n");
- return -EFAULT;
- }
-
- nic_dev->q_params.sq_depth = HINIC3_SQ_DEPTH;
- nic_dev->q_params.rq_depth = HINIC3_RQ_DEPTH;
-
- hinic3_try_to_enable_rss(nic_dev);
-
err = hinic3_get_default_mac(nic_dev->hwdev, mac_addr);
if (err) {
nic_err(&nic_dev->pdev->dev, "Failed to get MAC address\n");
- goto get_mac_err;
+ return err;
}
+
eth_hw_addr_set(netdev, mac_addr);
if (!is_valid_ether_addr(netdev->dev_addr)) {
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
nic_err(&nic_dev->pdev->dev, "Invalid MAC address %pM\n",
- netdev->dev_addr);
- err = -EIO;
- goto err_mac;
- }
+ netdev->dev_addr);
+ return -EIO;
+ }
- nic_info(&nic_dev->pdev->dev, "Invalid MAC address %pM, using random\n",
+ nic_info(&nic_dev->pdev->dev,
+ "Invalid MAC address %pM, using random\n",
netdev->dev_addr);
eth_hw_addr_random(netdev);
}
@@ -478,21 +504,62 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
* MAC, and we can't consider this condition is error status during
* driver probe procedure.
*/
- if (err && err != HINIC3_PF_SET_VF_ALREADY) {
+ if (err && err != HINIC3_PF_SET_VF_ALREADY)
nic_err(&nic_dev->pdev->dev, "Failed to set default MAC\n");
- goto set_mac_err;
+
+ if (err == HINIC3_PF_SET_VF_ALREADY)
+ return 0;
+
+ return err;
+}
+
+static void hinic3_outband_cfg_init(struct hinic3_nic_dev *nic_dev)
+{
+ u16 outband_default_vid = 0;
+ int err = 0;
+
+ if (!nic_dev->nic_cap.outband_vlan_cfg_en)
+ return;
+
+ err = hinic3_get_outband_vlan_cfg(nic_dev->hwdev, &outband_default_vid);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev,
+ "Failed to get_outband_cfg, err: %d\n", err);
+ return;
}
- /* MTU range: 384 - 9600 */
-#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
- netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
+ nic_dev->outband_cfg.outband_default_vid = outband_default_vid;
+}
-#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
- netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
+static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
+{
+ struct net_device *netdev = nic_dev->netdev;
+ u64 nic_features;
+ int err = 0;
+
+ nic_features = hinic3_get_feature_cap(nic_dev->hwdev);
+ /* You can update the features supported by the driver according to the
+ * scenario here
+ */
+ nic_features &= NIC_DRV_DEFAULT_FEATURE;
+ hinic3_update_nic_feature(nic_dev->hwdev, nic_features);
+
+ err = hinic3_dcb_init(nic_dev);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev, "Failed to init dcb\n");
+ return -EFAULT;
+ }
+
+ nic_dev->q_params.sq_depth = HINIC3_SQ_DEPTH;
+ nic_dev->q_params.rq_depth = HINIC3_RQ_DEPTH;
+
+ hinic3_try_to_enable_rss(nic_dev);
+
+ err = hinic3_set_default_mac(nic_dev);
+ if (err)
+ goto set_mac_err;
+
+ hinic3_netdev_mtu_init(netdev);
err = hinic3_alloc_txrxqs(nic_dev);
if (err) {
@@ -500,6 +567,8 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
goto alloc_qps_err;
}
+ hinic3_outband_cfg_init(nic_dev);
+
hinic3_tx_rx_ops_init(nic_dev);
return 0;
@@ -510,8 +579,6 @@ alloc_qps_err:
HINIC3_CHANNEL_NIC);
set_mac_err:
-err_mac:
-get_mac_err:
hinic3_clear_rss_config(nic_dev);
return err;
@@ -623,7 +690,8 @@ static void calc_coal_para(struct hinic3_nic_dev *nic_dev,
*pending_limt =
(u8)((rx_rate - q_coal->pkt_rate_low) *
- (q_coal->rx_pending_limt_high - q_coal->rx_pending_limt_low) /
+ (q_coal->rx_pending_limt_high -
+ q_coal->rx_pending_limt_low) /
(q_coal->pkt_rate_high - q_coal->pkt_rate_low) +
q_coal->rx_pending_limt_low);
}
@@ -637,8 +705,10 @@ static void update_queue_coal(struct hinic3_nic_dev *nic_dev, u16 qid,
q_coal = &nic_dev->intr_coalesce[qid];
- if (rx_rate > HINIC3_RX_RATE_THRESH && avg_pkt_size > HINIC3_AVG_PKT_SMALL) {
- calc_coal_para(nic_dev, q_coal, rx_rate, &coalesc_timer_cfg, &pending_limt);
+ if (rx_rate > HINIC3_RX_RATE_THRESH &&
+ avg_pkt_size > HINIC3_AVG_PKT_SMALL) {
+ calc_coal_para(nic_dev, q_coal, rx_rate,
+ &coalesc_timer_cfg, &pending_limt);
} else {
coalesc_timer_cfg = HINIC3_LOWEST_LATENCY;
pending_limt = q_coal->rx_pending_limt_low;
@@ -701,20 +771,55 @@ void hinic3_auto_moderation_work(struct work_struct *work)
static void hinic3_periodic_work_handler(struct work_struct *work)
{
struct delayed_work *delay = to_delayed_work(work);
- struct hinic3_nic_dev *nic_dev = container_of(delay, struct hinic3_nic_dev, periodic_work);
+ struct hinic3_nic_dev *nic_dev =
+ container_of(delay, struct hinic3_nic_dev, periodic_work);
if (test_and_clear_bit(EVENT_WORK_TX_TIMEOUT, &nic_dev->event_flag))
- hinic3_fault_event_report(nic_dev->hwdev, HINIC3_FAULT_SRC_TX_TIMEOUT,
+ hinic3_fault_event_report(nic_dev->hwdev,
+ HINIC3_FAULT_SRC_TX_TIMEOUT,
FAULT_LEVEL_SERIOUS_FLR);
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
}
+static void hinic3_vport_stats_work_handler(struct work_struct *work)
+{
+ int err;
+ struct hinic3_vport_stats vport_stats = {0};
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_nic_dev *nic_dev = container_of(delay,
+ struct hinic3_nic_dev,
+ vport_stats_work);
+ err = hinic3_get_vport_stats(nic_dev->hwdev,
+ hinic3_global_func_id(nic_dev->hwdev),
+ &vport_stats);
+ if (err)
+ nic_err(&nic_dev->pdev->dev, "Failed to get dropped stats from fw\n");
+ else
+ nic_dev->vport_stats.rx_discard_vport =
+ vport_stats.rx_discard_vport;
+ queue_delayed_work(nic_dev->workq, &nic_dev->vport_stats_work, HZ);
+}
+
+static void free_nic_dev_vram(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram = get_use_vram_flag();
+
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)nic_dev->nic_vram, nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ else
+ kfree(nic_dev->nic_vram);
+ nic_dev->nic_vram = NULL;
+}
+
static void free_nic_dev(struct hinic3_nic_dev *nic_dev)
{
hinic3_deinit_nic_prof_adapter(nic_dev);
destroy_workqueue(nic_dev->workq);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+ free_nic_dev_vram(nic_dev);
}
static int setup_nic_dev(struct net_device *netdev,
@@ -724,6 +829,10 @@ static int setup_nic_dev(struct net_device *netdev,
struct hinic3_nic_dev *nic_dev;
char *netdev_name_fmt;
u32 page_num;
+ u16 func_id;
+ int ret;
+ int is_in_kexec = vram_get_kexec_flag();
+ int is_use_vram = get_use_vram_flag();
nic_dev = (struct hinic3_nic_dev *)netdev_priv(netdev);
nic_dev->netdev = netdev;
@@ -738,22 +847,60 @@ static int setup_nic_dev(struct net_device *netdev,
nic_dev->dma_rx_buff_size = RX_BUFF_NUM_PER_PAGE * nic_dev->rx_buff_len;
page_num = nic_dev->dma_rx_buff_size / PAGE_SIZE;
nic_dev->page_order = page_num > 0 ? ilog2(page_num) : 0;
+ nic_dev->page_pool_enabled = page_pool_enabled;
+ nic_dev->outband_cfg.outband_default_vid = 0;
+
+ // value other than 0 indicates hot replace
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(nic_dev->nic_vram_name, VRAM_NAME_MAX_LEN,
+ "%s%hu", VRAM_NIC_VRAM, func_id);
+
+ nic_dev->nic_vram = (struct hinic3_vram *)hi_vram_kalloc(
+ nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+
+ if (is_in_kexec == 0)
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ else
+ netdev->mtu = nic_dev->nic_vram->vram_mtu;
+ } else {
+ nic_dev->nic_vram = kzalloc(sizeof(struct hinic3_vram),
+ GFP_KERNEL);
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ }
mutex_init(&nic_dev->nic_mutex);
nic_dev->vlan_bitmap = kzalloc(VLAN_BITMAP_SIZE(nic_dev), GFP_KERNEL);
- if (!nic_dev->vlan_bitmap)
- return -ENOMEM;
+ if (!nic_dev->vlan_bitmap) {
+ nic_err(&pdev->dev, "Failed to allocate vlan bitmap\n");
+ ret = -ENOMEM;
+ goto vlan_bitmap_error;
+ }
nic_dev->workq = create_singlethread_workqueue(HINIC3_NIC_DEV_WQ_NAME);
if (!nic_dev->workq) {
nic_err(&pdev->dev, "Failed to initialize nic workqueue\n");
- kfree(nic_dev->vlan_bitmap);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto create_workq_error;
}
- INIT_DELAYED_WORK(&nic_dev->periodic_work, hinic3_periodic_work_handler);
- INIT_DELAYED_WORK(&nic_dev->rxq_check_work, hinic3_rxq_check_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->periodic_work,
+ hinic3_periodic_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->rxq_check_work,
+ hinic3_rxq_check_work_handler);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ INIT_DELAYED_WORK(&nic_dev->vport_stats_work,
+ hinic3_vport_stats_work_handler);
INIT_LIST_HEAD(&nic_dev->uc_filter_list);
INIT_LIST_HEAD(&nic_dev->mc_filter_list);
@@ -766,10 +913,23 @@ static int setup_nic_dev(struct net_device *netdev,
hinic3_init_nic_prof_adapter(nic_dev);
netdev_name_fmt = hinic3_get_dft_netdev_name_fmt(nic_dev);
- if (netdev_name_fmt)
- strscpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (netdev_name_fmt) {
+ ret = strscpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (ret < 0)
+ goto get_netdev_name_error;
+ }
return 0;
+
+get_netdev_name_error:
+ hinic3_deinit_nic_prof_adapter(nic_dev);
+ destroy_workqueue(nic_dev->workq);
+create_workq_error:
+ kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+vlan_bitmap_error:
+ free_nic_dev_vram(nic_dev);
+ return ret;
}
static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
@@ -808,6 +968,31 @@ static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
return 0;
}
+static void hinic3_bond_init(struct hinic3_nic_dev *nic_dev)
+{
+ u32 bond_id = HINIC3_INVALID_BOND_ID;
+ int err = hinic3_create_bond(nic_dev->hwdev, &bond_id);
+
+ if (err != 0)
+ goto bond_init_failed;
+
+ /* bond id does not change, means this pf is not bond active pf, no log is generated */
+ if (bond_id == HINIC3_INVALID_BOND_ID)
+ return;
+
+ err = hinic3_open_close_bond(nic_dev->hwdev, true);
+ if (err != 0) {
+ hinic3_delete_bond(nic_dev->hwdev);
+ goto bond_init_failed;
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Bond %d init success\n", bond_id);
+ return;
+
+bond_init_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond init failed\n");
+}
+
static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
char *uld_dev_name)
{
@@ -838,6 +1023,12 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
goto err_out;
}
+ err = hinic3_get_dev_cap(lld_dev->hwdev);
+ if (err != 0) {
+ nic_err(&pdev->dev, "Failed to get dev cap\n");
+ goto err_out;
+ }
+
max_qps = hinic3_func_max_nic_qnum(lld_dev->hwdev);
netdev = alloc_etherdev_mq(sizeof(*nic_dev), max_qps);
if (!netdev) {
@@ -870,10 +1061,17 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
hinic3_assign_netdev_ops(nic_dev);
netdev_feature_init(netdev);
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+ netdev->udp_tunnel_nic_info = &hinic3_udp_tunnels;
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
err = hinic3_set_default_hw_feature(nic_dev);
if (err)
goto set_features_err;
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0)
+ hinic3_bond_init(nic_dev);
+
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
hinic3_register_notifier(nic_dev);
#endif
@@ -888,6 +1086,9 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
}
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->vport_stats_work, HZ);
netif_carrier_off(netdev);
*uld_dev = nic_dev;
@@ -920,6 +1121,25 @@ err_out:
return err;
}
+static void hinic3_bond_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ int ret = 0;
+
+ ret = hinic3_open_close_bond(nic_dev->hwdev, false);
+ if (ret != 0)
+ goto bond_deinit_failed;
+
+ ret = hinic3_delete_bond(nic_dev->hwdev);
+ if (ret != 0)
+ goto bond_deinit_failed;
+
+ nic_info(&nic_dev->pdev->dev, "Bond deinit success\n");
+ return;
+
+bond_deinit_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond deinit failed\n");
+}
+
static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
{
struct hinic3_nic_dev *nic_dev = adapter;
@@ -939,6 +1159,8 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_unregister_notifier(nic_dev);
#endif
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ cancel_delayed_work_sync(&nic_dev->vport_stats_work);
cancel_delayed_work_sync(&nic_dev->periodic_work);
cancel_delayed_work_sync(&nic_dev->rxq_check_work);
cancel_work_sync(&nic_dev->rx_mode_work);
@@ -946,6 +1168,9 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_flush_rx_flow_rule(nic_dev);
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0)
+ hinic3_bond_deinit(nic_dev);
+
hinic3_update_nic_feature(nic_dev->hwdev, 0);
hinic3_set_nic_feature_to_hw(nic_dev->hwdev);
@@ -955,6 +1180,7 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_deinit_nic_prof_adapter(nic_dev);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
free_netdev(netdev);
@@ -971,8 +1197,10 @@ static void sriov_state_change(struct hinic3_nic_dev *nic_dev,
static void hinic3_port_module_event_handler(struct hinic3_nic_dev *nic_dev,
struct hinic3_event_info *event)
{
- const char *g_hinic3_module_link_err[LINK_ERR_NUM] = { "Unrecognized module" };
- struct hinic3_port_module_event *module_event = (void *)event->event_data;
+ const char *g_hinic3_module_link_err[LINK_ERR_NUM] = {
+ "Unrecognized module" };
+ struct hinic3_port_module_event *module_event =
+ (void *)event->event_data;
enum port_module_event_type type = module_event->type;
enum link_err_type err_type = module_event->err_type;
@@ -1003,6 +1231,116 @@ static void hinic3_port_module_event_handler(struct hinic3_nic_dev *nic_dev,
}
}
+bool hinic3_need_proc_link_event(struct hinic3_lld_dev *lld_dev)
+{
+ int ret = 0;
+ u16 func_id;
+ u8 roce_enable = false;
+ bool is_slave_func = false;
+ struct hinic3_hw_bond_infos hw_bond_infos = {0};
+
+ if (!lld_dev)
+ return false;
+
+ /* 非slave设备需要处理link down事件 */
+ ret = hinic3_is_slave_func(lld_dev->hwdev, &is_slave_func);
+ if (ret != 0) {
+ nic_err(&lld_dev->pdev->dev, "NIC get info, lld_dev is null\n");
+ return true;
+ }
+
+ if (!is_slave_func)
+ return true;
+
+ /* 未使能了vroce功能,需处理link down事件 */
+ func_id = hinic3_global_func_id(lld_dev->hwdev);
+ ret = hinic3_get_func_vroce_enable(lld_dev->hwdev, func_id, &roce_enable);
+ if (ret != 0)
+ return true;
+
+ if (!roce_enable)
+ return true;
+
+ /* 未创建bond,需要处理link down事件 */
+ hw_bond_infos.bond_id = HINIC_OVS_BOND_DEFAULT_ID;
+
+ ret = hinic3_get_hw_bond_infos(lld_dev->hwdev, &hw_bond_infos, HINIC3_CHANNEL_COMM);
+ if (ret != 0) {
+ pr_err("[ROCE, ERR] Get chipf bond info failed (%d)\n", ret);
+ return true;
+ }
+
+ if (!hw_bond_infos.valid)
+ return true;
+
+ return false;
+}
+
+bool hinic3_need_proc_bond_event(struct hinic3_lld_dev *lld_dev)
+{
+ return !hinic3_need_proc_link_event(lld_dev);
+}
+
+static void hinic_porc_bond_state_change(struct hinic3_lld_dev *lld_dev, void *adapter,
+ struct hinic3_event_info *event)
+{
+ struct hinic3_nic_dev *nic_dev = adapter;
+
+ if (!nic_dev || !event || !hinic3_support_nic(lld_dev->hwdev, NULL))
+ return;
+
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond down\n");
+ hinic3_link_status_change(nic_dev, false);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond up\n");
+ hinic3_link_status_change(nic_dev, true);
+ break;
+ default:
+ break;
+ }
+}
+
+static void hinic3_outband_cfg_event_handler(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_outband_cfg_info *info)
+{
+ int err = 0;
+
+ if (!nic_dev || !info || !hinic3_support_nic(nic_dev->hwdev, NULL)) {
+ pr_err("Outband cfg event invalid param\n");
+ return;
+ }
+
+ if (hinic3_func_type(nic_dev->hwdev) != TYPE_VF &&
+ info->func_id >= NIC_MAX_PF_NUM) {
+ err = hinic3_notify_vf_outband_cfg(nic_dev->hwdev,
+ info->func_id,
+ info->outband_default_vid);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev,
+ "Outband cfg event notify vf err: %d, func_id: 0x%x, vid: 0x%x\n",
+ err, info->func_id, info->outband_default_vid);
+ return;
+ }
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Change outband default vid from %u to %u\n",
+ nic_dev->outband_cfg.outband_default_vid,
+ info->outband_default_vid);
+
+ nic_dev->outband_cfg.outband_default_vid = info->outband_default_vid;
+}
+
static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
struct hinic3_event_info *event)
{
@@ -1014,21 +1352,35 @@ static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_DOWN):
+ if (!hinic3_need_proc_link_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc link event\n");
+ return;
+ }
hinic3_link_status_change(nic_dev, false);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_UP):
hinic3_link_status_change(nic_dev, true);
break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ hinic_porc_bond_state_change(lld_dev, adapter, event);
+ break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_PORT_MODULE_EVENT):
hinic3_port_module_event_handler(nic_dev, event);
break;
- case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_SRIOV_STATE_CHANGE):
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_OUTBAND_CFG):
+ hinic3_outband_cfg_event_handler(nic_dev,
+ (void *)event->event_data);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM,
+ EVENT_COMM_SRIOV_STATE_CHANGE):
sriov_state_change(nic_dev, (void *)event->event_data);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_FAULT):
fault = (void *)event->event_data;
if (fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
- fault->event.chip.func_id == hinic3_global_func_id(lld_dev->hwdev))
+ fault->event.chip.func_id ==
+ hinic3_global_func_id(lld_dev->hwdev))
hinic3_link_status_change(nic_dev, false);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_PCIE_LINK_DOWN):
@@ -1081,7 +1433,7 @@ struct hinic3_uld_info g_nic_uld_info = {
.resume = NULL,
.event = nic_event,
.ioctl = nic_ioctl,
-}; /*lint -e766*/
+};
struct hinic3_uld_info *get_nic_uld_info(void)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
index 94e606e..668f30e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
@@ -9,6 +9,7 @@
/* Interrupt at most records, interrupt will be recorded in the FFM */
#define NICTOOL_CMD_TYPE (0x18)
+#define HINIC3_CARD_NAME_MAX_LEN (128)
struct api_cmd_rd {
u32 pf_id;
@@ -110,7 +111,8 @@ enum dbgtool_cmd {
DBGTOOL_CMD_NUM
};
-#define PF_MAX_SIZE (16)
+#define HINIC_PF_MAX_SIZE (16)
+#define HINIC_VF_MAX_SIZE (4096)
#define BUSINFO_LEN (32)
enum module_name {
@@ -132,7 +134,8 @@ enum module_name {
SEND_TO_MIGRATE_DRIVER,
SEND_TO_PPA_DRIVER,
SEND_TO_CUSTOM_DRIVER = SEND_TO_SRV_DRV_BASE + 11,
- SEND_TO_BIFUR_DRIVER = SEND_TO_SRV_DRV_BASE + 15,
+ SEND_TO_VSOCK_DRIVER = SEND_TO_SRV_DRV_BASE + 14,
+ SEND_TO_BIFUR_DRIVER,
SEND_TO_DRIVER_MAX = SEND_TO_SRV_DRV_BASE + 16, /* reserved */
};
@@ -160,7 +163,7 @@ enum driver_cmd_type {
GET_CHIP_FAULT_STATS,
NIC_RSVD1,
NIC_RSVD2,
- NIC_RSVD3,
+ GET_OS_HOT_REPLACE_INFO,
GET_CHIP_ID,
GET_SINGLE_CARD_INFO,
GET_FIRMWARE_ACTIVE_STATUS,
@@ -171,7 +174,7 @@ enum driver_cmd_type {
GET_LOOPBACK_MODE = 32,
SET_LOOPBACK_MODE,
SET_LINK_MODE,
- SET_PF_BW_LIMIT,
+ SET_TX_PF_BW_LIMIT,
GET_PF_BW_LIMIT,
ROCE_CMD,
GET_POLL_WEIGHT,
@@ -189,6 +192,7 @@ enum driver_cmd_type {
GET_NIC_STATS_STRING,
GET_NIC_STATS_INFO,
GET_PF_ID,
+ GET_MBOX_CNT,
NIC_RSVD4,
NIC_RSVD5,
DCB_QOS_INFO,
@@ -205,6 +209,8 @@ enum driver_cmd_type {
RSS_INDIR,
PORT_ID,
+ SET_RX_PF_BW_LIMIT = 0x43,
+
GET_FUNC_CAP = 0x50,
GET_XSFP_PRESENT = 0x51,
GET_XSFP_INFO = 0x52,
@@ -216,6 +222,38 @@ enum driver_cmd_type {
WIN_CSR_WRITE = 0x62,
WIN_API_CMD_RD = 0x63,
+ GET_FUSION_Q = 0x64,
+ ROCE_CMD_SET_LDCP_PARAM = 0x70,
+
+ ROCE_CMD_GET_QPC_FROM_CACHE = 0x80,
+ ROCE_CMD_GET_QPC_FROM_HOST = 0x81,
+ ROCE_CMD_GET_CQC_FROM_CACHE = 0x82,
+ ROCE_CMD_GET_CQC_FROM_HOST = 0x83,
+ ROCE_CMD_GET_SRQC_FROM_CACHE = 0x84,
+ ROCE_CMD_GET_SRQC_FROM_HOST = 0x85,
+ ROCE_CMD_GET_MPT_FROM_CACHE = 0x86,
+ ROCE_CMD_GET_MPT_FROM_HOST = 0x87,
+ ROCE_CMD_GET_GID_FROM_CACHE = 0x88,
+ ROCE_CMD_GET_QPC_CQC_PI_CI = 0x89,
+ ROCE_CMD_GET_QP_COUNT = 0x8a,
+ ROCE_CMD_GET_DEV_ALGO = 0x8b,
+
+ ROCE_CMD_START_CAP_PACKET = 0x90,
+ ROCE_CMD_STOP_CAP_PACKET = 0x91,
+ ROCE_CMD_QUERY_CAP_INFO = 0x92,
+ ROCE_CMD_ENABLE_QP_CAP_PACKET = 0x93,
+ ROCE_CMD_DISABLE_QP_CAP_PACKET = 0x94,
+ ROCE_CMD_QUERY_QP_CAP_INFO = 0x95,
+
+ ROCE_CMD_ENABLE_BW_CTRL = 0xa0,
+ ROCE_CMD_DISABLE_BW_CTRL = 0xa1,
+ ROCE_CMD_CHANGE_BW_CTRL_PARAM = 0xa2,
+ ROCE_CMD_QUERY_BW_CTRL_PARAM = 0xa3,
+
+ ROCE_CMD_TIMEOUT_ALARM = 0xb0,
+ ROCE_CMD_PORT_TRAFFIC = 0Xb1,
+ ROCE_CMD_BOND_HASH_TYPE_SET = 0xb2,
+
BIFUR_SET_ENABLE = 0xc0,
BIFUR_GET_ENABLE = 0xc1,
@@ -234,7 +272,8 @@ enum sm_cmd_type {
SM_CTR_RD64,
SM_CTR_RD32_CLEAR,
SM_CTR_RD64_PAIR_CLEAR,
- SM_CTR_RD64_CLEAR
+ SM_CTR_RD64_CLEAR,
+ SM_CTR_RD16_CLEAR,
};
struct cqm_stats {
@@ -321,10 +360,22 @@ struct pf_info {
};
struct card_info {
- struct pf_info pf[PF_MAX_SIZE];
+ struct pf_info pf[HINIC_PF_MAX_SIZE];
u32 pf_num;
};
+struct func_mbox_cnt_info {
+ char bus_info[BUSINFO_LEN];
+ u64 send_cnt;
+ u64 ack_cnt;
+};
+
+struct card_mbox_cnt_info {
+ struct func_mbox_cnt_info func_info[HINIC_PF_MAX_SIZE +
+ HINIC_VF_MAX_SIZE];
+ u32 func_num;
+};
+
struct hinic3_nic_loop_mode {
u32 loop_mode;
u32 loop_ctrl;
@@ -665,6 +716,161 @@ struct get_card_bond_msg_s {
struct bond_all_msg_s all_msg[MAX_BONDING_CNT_PER_CARD];
};
+#define MAX_FUSION_Q_STATS_STR_LEN 16
+#define MAX_FUSION_Q_NUM 256
+struct queue_status_s {
+ pid_t tgid;
+ char status[MAX_FUSION_Q_STATS_STR_LEN];
+};
+struct fusion_q_status_s {
+ u16 queue_num;
+ struct queue_status_s queue[MAX_FUSION_Q_NUM];
+};
+
+struct fusion_q_tx_hw_page {
+ u64 phy_addr;
+ u64 *map_addr;
+};
+
+struct fusion_sq_info {
+ u16 q_id;
+ u16 pi;
+ u16 ci; /* sw_ci */
+ u16 fi; /* hw_ci */
+ u32 q_depth;
+ u16 pi_reverse;
+ u16 wqebb_size;
+ u8 priority;
+ u16 *ci_addr;
+ u64 cla_addr;
+ void *slq_handle;
+ struct fusion_q_tx_hw_page direct_wqe;
+ struct fusion_q_tx_hw_page doorbell;
+ u32 page_idx;
+ u32 glb_sq_id;
+};
+
+struct fusion_q_tx_wqe {
+ u32 data[4];
+};
+
+struct fusion_rq_info {
+ u16 q_id;
+ u16 delta;
+ u16 hw_pi;
+ u16 ci; /* sw_ci */
+ u16 sw_pi;
+ u16 wqebb_size;
+ u16 q_depth;
+ u16 buf_len;
+
+ void *slq_handle;
+ u64 ci_wqe_page_addr;
+ u64 ci_cla_tbl_addr;
+
+ u8 coalesc_timer_cfg;
+ u8 pending_limt;
+ u16 msix_idx;
+ u32 msix_vector;
+};
+
+struct fusion_q_rx_wqe {
+ u32 data[8];
+};
+
+struct fusion_q_rx_cqe {
+ union {
+ struct {
+ unsigned int checksum_err : 16;
+ unsigned int lro_num : 8;
+ unsigned int rsvd1 : 7;
+ unsigned int rx_done : 1;
+ } bs;
+ unsigned int value;
+ } dw0;
+
+ union {
+ struct {
+ unsigned int vlan : 16;
+ unsigned int length : 16;
+ } bs;
+ unsigned int value;
+ } dw1;
+
+ union {
+ struct {
+ unsigned int pkt_types : 12;
+ unsigned int rsvd : 4;
+ unsigned int udp_0 : 1;
+ unsigned int ipv6_ex_add : 1;
+ unsigned int loopback : 1;
+ unsigned int umbcast : 2;
+ unsigned int vlan_offload_en : 1;
+ unsigned int tag_num : 2;
+ unsigned int rss_type : 8;
+ } bs;
+ unsigned int value;
+ } dw2;
+
+ union {
+ struct {
+ unsigned int rss_hash_value;
+ } bs;
+ unsigned int value;
+ } dw3;
+
+ union {
+ struct {
+ unsigned int tx_ts_seq : 16;
+ unsigned int message_1588_offset : 8;
+ unsigned int message_1588_type : 4;
+ unsigned int rsvd : 1;
+ unsigned int if_rx_ts : 1;
+ unsigned int if_tx_ts : 1;
+ unsigned int if_1588 : 1;
+ } bs;
+ unsigned int value;
+ } dw4;
+
+ union {
+ struct {
+ unsigned int ts;
+ } bs;
+ unsigned int value;
+ } dw5;
+
+ union {
+ struct {
+ unsigned int lro_ts;
+ } bs;
+ unsigned int value;
+ } dw6;
+
+ union {
+ struct {
+ unsigned int rsvd0;
+ } bs;
+ unsigned int value;
+ } dw7; /* 16Bytes Align */
+};
+
+struct os_hot_repalce_func_info {
+ char card_name[HINIC3_CARD_NAME_MAX_LEN];
+ u32 bus_num;
+ u32 valid;
+ u32 bdf;
+ int partition;
+ u16 backup_pf;
+ u16 pf_idx;
+ int port_id;
+};
+
+#define ALL_CARD_PF_NUM 2048 /* 64 card * 32 pf */
+struct os_hot_replace_info {
+ struct os_hot_repalce_func_info func_infos[ALL_CARD_PF_NUM];
+ u32 func_cnt;
+};
+
int alloc_buff_in(void *hwdev, struct msg_module *nt_msg, u32 in_size, void **buf_in);
int alloc_buff_out(void *hwdev, struct msg_module *nt_msg, u32 out_size, void **buf_out);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
index ea1d506..66c41f8 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
@@ -15,6 +15,9 @@
#include <linux/ip.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#ifdef HAVE_XDP_SUPPORT
#include <linux/bpf.h>
#endif
@@ -28,6 +31,10 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
+#include "nic_npu_cmd.h"
+
+#include "vram_common.h"
+
#define HINIC3_DEFAULT_RX_CSUM_OFFLOAD 0xFFF
#define HINIC3_LRO_DEFAULT_COAL_PKT_SIZE 32
@@ -47,8 +54,63 @@ static void hinic3_nic_set_rx_mode(struct net_device *netdev)
queue_work(nic_dev->workq, &nic_dev->rx_mode_work);
}
+static void hinic3_free_irq_vram(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_dyna_txrxq_params *in_q_params)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ struct hinic3_dyna_txrxq_params q_params = nic_dev->q_params;
+
+ if (q_params.irq_cfg == NULL)
+ return;
+
+ size = sizeof(struct hinic3_irq) * (q_params.num_qps);
+
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)q_params.irq_cfg, q_params.irq_cfg_vram_name, size);
+ q_params.irq_cfg = NULL;
+ } else {
+ kfree(in_q_params->irq_cfg);
+ in_q_params->irq_cfg = NULL;
+ }
+}
+
+static int hinic3_alloc_irq_vram(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_dyna_txrxq_params *q_params, bool is_up_eth)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ u16 func_id;
+
+ size = sizeof(struct hinic3_irq) * q_params->num_qps;
+
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(q_params->irq_cfg_vram_name, VRAM_NAME_MAX_LEN,
+ "%s%hu", VRAM_NIC_IRQ_VRAM, func_id);
+ q_params->irq_cfg = (struct hinic3_irq *)hi_vram_kalloc(
+ q_params->irq_cfg_vram_name, size);
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq vram alloc failed.\n");
+ return -ENOMEM;
+ }
+ /* in order to clear napi stored in vram, irq need to init when eth up */
+ if (is_up_eth)
+ memset(q_params->irq_cfg, 0, size);
+ } else {
+ q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq alloc failed.\n");
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_txrxq_params *q_params)
+ struct hinic3_dyna_txrxq_params *q_params,
+ bool is_up_eth)
{
u32 size;
int err;
@@ -70,12 +132,9 @@ static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
goto alloc_rxqs_res_arr_err;
}
- size = sizeof(*q_params->irq_cfg) * q_params->num_qps;
- q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
- if (!q_params->irq_cfg) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to alloc irq resource array\n");
- err = -ENOMEM;
+ err = hinic3_alloc_irq_vram(nic_dev, q_params, is_up_eth);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc irq resource array\n");
goto alloc_irq_cfg_err;
}
@@ -102,8 +161,7 @@ alloc_rxqs_res_err:
q_params->txqs_res);
alloc_txqs_res_err:
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ hinic3_free_irq_vram(nic_dev, q_params);
alloc_irq_cfg_err:
kfree(q_params->rxqs_res);
@@ -117,15 +175,17 @@ alloc_rxqs_res_arr_err:
}
static void hinic3_free_txrxq_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_txrxq_params *q_params)
+ struct hinic3_dyna_txrxq_params *q_params)
{
+ int is_in_kexec = vram_get_kexec_flag();
+
hinic3_free_rxqs_res(nic_dev, q_params->num_qps, q_params->rq_depth,
q_params->rxqs_res);
hinic3_free_txqs_res(nic_dev, q_params->num_qps, q_params->sq_depth,
q_params->txqs_res);
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ if (is_in_kexec == 0)
+ hinic3_free_irq_vram(nic_dev, q_params);
kfree(q_params->rxqs_res);
q_params->rxqs_res = NULL;
@@ -161,6 +221,7 @@ static int hinic3_configure_txrxqs(struct hinic3_nic_dev *nic_dev,
static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos;
if (!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
@@ -171,12 +232,13 @@ static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
num_cos = hinic3_get_dev_user_cos_num(nic_dev);
hinic3_update_qp_cos_cfg(nic_dev, num_cos);
/* For now, we don't support to change num_cos */
- if (num_cos > nic_dev->cos_config_num_max ||
+ if (num_cos > dcb->cos_config_num_max ||
nic_dev->q_params.num_qps < num_cos) {
nicif_err(nic_dev, drv, netdev, "Invalid num_cos: %u or num_qps: %u, disable DCB\n",
num_cos, nic_dev->q_params.num_qps);
nic_dev->q_params.num_cos = 0;
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
/* if we can't enable rss or get enough num_qps,
* need to sync default configure to hw
*/
@@ -190,17 +252,22 @@ static int hinic3_configure(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
- err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
- if (err) {
- nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
- return err;
+ if (is_in_kexec == 0) {
+ err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
+ return err;
+ }
}
config_dcb_qps_map(nic_dev);
/* rx rss init */
- err = hinic3_rx_configure(netdev, test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ err = hinic3_rx_configure(netdev,
+ test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)
+ ? 1 : 0);
if (err) {
nicif_err(nic_dev, drv, netdev, "Failed to configure rx\n");
return err;
@@ -256,10 +323,11 @@ static void config_dcb_num_qps(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dyna_txrxq_params *q_params,
u16 max_qps)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos = q_params->num_cos;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (!num_cos || num_cos > nic_dev->cos_config_num_max || num_cos > max_qps)
+ if (!num_cos || num_cos > dcb->cos_config_num_max || num_cos > max_qps)
return; /* will disable DCB in config_dcb_qps_map() */
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
@@ -313,8 +381,10 @@ static int hinic3_setup_num_qps(struct hinic3_nic_dev *nic_dev)
return -EINVAL;
}
nic_dev->qps_irq_info = kzalloc(irq_size, GFP_KERNEL);
- if (!nic_dev->qps_irq_info)
+ if (!nic_dev->qps_irq_info) {
+ nicif_err(nic_dev, drv, netdev, "Failed to alloc qps_irq_info\n");
return -ENOMEM;
+ }
hinic3_config_num_qps(nic_dev, &nic_dev->q_params);
@@ -332,57 +402,10 @@ static void hinic3_destroy_num_qps(struct hinic3_nic_dev *nic_dev)
kfree(nic_dev->qps_irq_info);
}
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev)
-{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- err = hinic3_set_port_enable(nic_dev->hwdev, false, HINIC3_CHANNEL_NIC);
- if (!err)
- nic_dev->force_port_disable = true;
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
-{
- int err = 0;
-
- down(&nic_dev->port_state_sem);
-
- nic_dev->force_port_disable = false;
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
- HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- /* Do nothing when force disable
- * Port will disable when call force port disable
- * and should not enable port when in force mode
- */
- if (nic_dev->force_port_disable) {
- up(&nic_dev->port_state_sem);
- return 0;
- }
-
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
- HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
+ return hinic3_set_port_enable(nic_dev->hwdev, enable,
+ HINIC3_CHANNEL_NIC);
}
static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
@@ -398,8 +421,8 @@ static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
}
static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+ struct hinic3_dyna_qp_params *qp_params,
+ struct hinic3_dyna_txrxq_params *trxq_params, bool is_up_eth)
{
int err;
@@ -414,7 +437,7 @@ static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
return err;
}
- err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params);
+ err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params, is_up_eth);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc txrxq resources\n");
hinic3_free_qps(nic_dev->hwdev, qp_params);
@@ -425,8 +448,8 @@ static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
}
static void hinic3_free_channel_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+ struct hinic3_dyna_qp_params *qp_params,
+ struct hinic3_dyna_txrxq_params *trxq_params)
{
mutex_lock(&nic_dev->nic_mutex);
hinic3_free_txrxq_resources(nic_dev, trxq_params);
@@ -521,7 +544,8 @@ int hinic3_vport_up(struct hinic3_nic_dev *nic_dev)
queue_delayed_work(nic_dev->workq, &nic_dev->moderation_task,
HINIC3_MODERATONE_DELAY);
if (test_bit(HINIC3_RXQ_RECOVERY, &nic_dev->flags))
- queue_delayed_work(nic_dev->workq, &nic_dev->rxq_check_work, HZ);
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->rxq_check_work, HZ);
hinic3_print_link_message(nic_dev, link_status);
@@ -542,9 +566,52 @@ vport_enable_err:
return err;
}
+static int hinic3_flush_rq_and_check(struct hinic3_nic_dev *nic_dev, u16 glb_func_id)
+{
+ struct hinic3_flush_rq *rq_flush_msg = NULL;
+ struct hinic3_cmd_buf *cmd_buf = NULL;
+ int out_buf_len = sizeof(struct hinic3_flush_rq);
+ u16 rq_id;
+ u64 out_param = 0;
+ int ret;
+
+ cmd_buf = hinic3_alloc_cmd_buf(nic_dev->hwdev);
+ if (!cmd_buf) {
+ nic_err(&nic_dev->pdev->dev, "Failed to allocate cmd buf\n");
+ return -ENOMEM;
+ }
+
+ cmd_buf->size = sizeof(struct hinic3_flush_rq);
+ rq_flush_msg = (struct hinic3_flush_rq *)cmd_buf->buf;
+ rq_flush_msg->dw.bs.func_id = glb_func_id;
+ for (rq_id = 0; rq_id < nic_dev->q_params.num_qps; rq_id++) {
+ rq_flush_msg->dw.bs.rq_id = rq_id;
+ hinic3_cpu_to_be32(rq_flush_msg, out_buf_len);
+ ret = hinic3_cmdq_direct_resp(nic_dev->hwdev, HINIC3_MOD_L2NIC,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ cmd_buf, &out_param, 0,
+ HINIC3_CHANNEL_NIC);
+ if (ret != 0 || out_param != 0) {
+ nic_err(&nic_dev->pdev->dev, "Failed to flush rq, ret:%d, func:%u, rq:%u\n",
+ ret, glb_func_id, rq_id);
+ goto err;
+ }
+ hinic3_be32_to_cpu(rq_flush_msg, out_buf_len);
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Func:%u rq_num:%u flush rq success\n",
+ glb_func_id, nic_dev->q_params.num_qps);
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return 0;
+err:
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return -1;
+}
+
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
{
u16 glb_func_id;
+ int is_in_kexec = vram_get_kexec_flag();
netif_carrier_off(nic_dev->netdev);
netif_tx_disable(nic_dev->netdev);
@@ -557,18 +624,21 @@ void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, 0);
- hinic3_maybe_set_port_state(nic_dev, false);
+ if (is_in_kexec != 0)
+ nicif_info(nic_dev, drv, nic_dev->netdev, "Skip changing mag status!\n");
+ else
+ hinic3_maybe_set_port_state(nic_dev, false);
glb_func_id = hinic3_global_func_id(nic_dev->hwdev);
hinic3_set_vport_enable(nic_dev->hwdev, glb_func_id, false,
HINIC3_CHANNEL_NIC);
hinic3_flush_txqs(nic_dev->netdev);
- /* After set vport disable 100ms,
- * no packets will be send to host
- * FPGA set 2000ms
- */
- msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+
+ if (is_in_kexec == 0)
+ msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+ else
+ (void)hinic3_flush_rq_and_check(nic_dev, glb_func_id);
hinic3_flush_qps_res(nic_dev->hwdev);
}
}
@@ -581,11 +651,12 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_qp_params new_qp_params = {0};
struct hinic3_dyna_qp_params cur_qp_params = {0};
int err;
+ bool is_free_resources = false;
hinic3_config_num_qps(nic_dev, trxq_params);
err = hinic3_alloc_channel_resources(nic_dev, &new_qp_params,
- trxq_params);
+ trxq_params, false);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc channel resources\n");
@@ -597,10 +668,19 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
hinic3_close_channel(nic_dev, &cur_qp_params);
hinic3_free_channel_resources(nic_dev, &cur_qp_params,
&nic_dev->q_params);
+ is_free_resources = true;
}
if (nic_dev->num_qp_irq > trxq_params->num_qps)
hinic3_qp_irq_change(nic_dev, trxq_params->num_qps);
+
+ if (is_free_resources) {
+ err = hinic3_alloc_irq_vram(nic_dev, trxq_params, false);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Change chl alloc irq failed\n");
+ goto alloc_irq_err;
+ }
+ }
nic_dev->q_params = *trxq_params;
if (reopen_handler)
@@ -621,7 +701,7 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
vport_up_err:
hinic3_close_channel(nic_dev, &new_qp_params);
-
+alloc_irq_err:
open_channel_err:
hinic3_free_channel_resources(nic_dev, &new_qp_params, trxq_params);
@@ -652,7 +732,7 @@ int hinic3_open(struct net_device *netdev)
}
err = hinic3_alloc_channel_resources(nic_dev, &qp_params,
- &nic_dev->q_params);
+ &nic_dev->q_params, true);
if (err)
goto alloc_channel_res_err;
@@ -691,12 +771,31 @@ setup_qps_err:
return err;
}
+static void hinic3_delete_napi(struct hinic3_nic_dev *nic_dev)
+{
+ u16 q_id;
+ int is_in_kexec = vram_get_kexec_flag();
+ struct hinic3_irq *irq_cfg = NULL;
+
+ if (is_in_kexec == 0 || nic_dev->q_params.irq_cfg == NULL)
+ return;
+
+ for (q_id = 0; q_id < nic_dev->q_params.num_qps; q_id++) {
+ irq_cfg = &(nic_dev->q_params.irq_cfg[q_id]);
+ qp_del_napi(irq_cfg);
+ }
+
+ hinic3_free_irq_vram(nic_dev, &nic_dev->q_params);
+}
+
int hinic3_close(struct net_device *netdev)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic3_dyna_qp_params qp_params = {0};
if (!test_and_clear_bit(HINIC3_INTF_UP, &nic_dev->flags)) {
+ /* delete napi in os hotreplace rollback */
+ hinic3_delete_napi(nic_dev);
nicif_info(nic_dev, drv, netdev, "Netdev already close, do nothing\n");
return 0;
}
@@ -776,7 +875,8 @@ static u8 parse_ipv6_info(struct sk_buff *skb, u32 *rss_tunple,
return 0;
}
-static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb,
+static u16 select_queue_by_hash_func(struct net_device *dev,
+ struct sk_buff *skb,
unsigned int num_tx_queues)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(dev);
@@ -831,17 +931,20 @@ static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb
}
#define GET_DSCP_PRI_OFFSET 2
-static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev, struct sk_buff *skb)
+static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev,
+ struct sk_buff *skb)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int dscp_cp;
if (skb->protocol == htons(ETH_P_IP))
dscp_cp = ipv4_get_dsfield(ip_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
else if (skb->protocol == htons(ETH_P_IPV6))
- dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
+ dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >>
+ GET_DSCP_PRI_OFFSET;
else
- return nic_dev->hw_dcb_cfg.default_cos;
- return nic_dev->hw_dcb_cfg.dscp2cos[dscp_cp];
+ return dcb->hw_dcb_cfg.default_cos;
+ return dcb->hw_dcb_cfg.dscp2cos[dscp_cp];
}
#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY)
@@ -867,11 +970,13 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif /* end of HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK */
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u16 txq;
u8 cos, qp_num;
if (test_bit(HINIC3_SAME_RXTX, &nic_dev->flags))
- return select_queue_by_hash_func(netdev, skb, netdev->real_num_tx_queues);
+ return select_queue_by_hash_func(netdev, skb,
+ netdev->real_num_tx_queues);
txq =
#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY)
@@ -887,18 +992,19 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (nic_dev->hw_dcb_cfg.trust == DCB_PCP) {
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP) {
if (skb->vlan_tci)
- cos = nic_dev->hw_dcb_cfg.pcp2cos[skb->vlan_tci >> VLAN_PRIO_SHIFT];
+ cos = dcb->hw_dcb_cfg.pcp2cos[skb->vlan_tci >>
+ VLAN_PRIO_SHIFT];
else
- cos = nic_dev->hw_dcb_cfg.default_cos;
+ cos = dcb->hw_dcb_cfg.default_cos;
} else {
cos = hinic3_get_dscp_up(nic_dev, skb);
}
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cos] ?
- txq % nic_dev->hw_dcb_cfg.cos_qp_num[cos] : 0;
- txq = nic_dev->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
+ qp_num = dcb->hw_dcb_cfg.cos_qp_num[cos] ?
+ txq % dcb->hw_dcb_cfg.cos_qp_num[cos] : 0;
+ txq = dcb->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
}
return txq;
@@ -976,7 +1082,7 @@ static struct net_device_stats *hinic3_get_stats(struct net_device *netdev)
stats->rx_packets = packets;
stats->rx_bytes = bytes;
stats->rx_errors = errors;
- stats->rx_dropped = dropped;
+ stats->rx_dropped = dropped + nic_dev->vport_stats.rx_discard_vport;
#ifndef HAVE_VOID_NDO_GET_STATS64
return stats;
@@ -1023,10 +1129,18 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
u32 mtu = (u32)new_mtu;
int err = 0;
+ int is_in_kexec = vram_get_kexec_flag();
#ifdef HAVE_XDP_SUPPORT
u32 xdp_max_mtu;
+#endif
+ if (is_in_kexec != 0) {
+ nicif_info(nic_dev, drv, netdev, "Hotreplace skip change mtu\n");
+ return err;
+ }
+
+#ifdef HAVE_XDP_SUPPORT
if (hinic3_is_xdp_enable(nic_dev)) {
xdp_max_mtu = hinic3_xdp_max_mtu(nic_dev);
if (mtu > xdp_max_mtu) {
@@ -1045,6 +1159,7 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
nicif_info(nic_dev, drv, nic_dev->netdev, "Change mtu from %u to %d\n",
netdev->mtu, new_mtu);
netdev->mtu = mtu;
+ nic_dev->nic_vram->vram_mtu = mtu;
}
return err;
@@ -1078,6 +1193,76 @@ static int hinic3_set_mac_addr(struct net_device *netdev, void *addr)
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+static int hinic3_udp_tunnel_port_config(struct net_device *netdev,
+ struct udp_tunnel_info *ti,
+ u8 action)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u16 func_id = hinic3_global_func_id(nic_dev->hwdev);
+ u16 dst_port;
+ int ret = 0;
+
+ switch (ti->type) {
+ case UDP_TUNNEL_TYPE_VXLAN:
+ dst_port = ntohs(ti->port);
+ ret = hinic3_vlxan_port_config(nic_dev->hwdev,
+ func_id, dst_port, action);
+ if (ret != 0) {
+ nicif_warn(nic_dev, drv, netdev,
+ "Failed to set vxlan port %u to device\n",
+ dst_port);
+ break;
+ }
+ nicif_info(nic_dev, link, netdev, "Vxlan dst port set to %u\n",
+ action == HINIC3_CMD_OP_ADD
+ ? dst_port : ntohs(VXLAN_OFFLOAD_PORT_LE));
+ break;
+ default:
+ nicif_err(nic_dev, drv, netdev, "Failed to add port, only vxlan dst port is supported\n");
+ ret = -EINVAL;
+ }
+ return ret;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+static void hinic3_udp_tunnel_add(struct net_device *netdev,
+ struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+static void hinic3_udp_tunnel_del(struct net_device *netdev,
+ struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD */
+
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev,
+ __always_unused unsigned int table,
+ __always_unused unsigned int entry,
+ struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev,
+ __always_unused unsigned int table,
+ __always_unused unsigned int entry,
+ struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static int
hinic3_vlan_rx_add_vid(struct net_device *netdev,
__always_unused __be16 proto,
@@ -1124,7 +1309,7 @@ hinic3_vlan_rx_kill_vid(struct net_device *netdev,
int err = 0;
col = VID_COL(nic_dev, vid);
- line = VID_LINE(nic_dev, vid);
+ line = (int)VID_LINE(nic_dev, vid);
/* In the broadcast scenario, ucode finds the corresponding function
* based on VLAN 0 of vlan table. If we delete VLAN 0, the VLAN function
@@ -1163,14 +1348,12 @@ static int hinic3_vlan_restore(struct net_device *netdev)
return -EFAULT;
rcu_read_lock();
for (i = 0; i < VLAN_N_VID; i++) {
-/* lint -e778 */
#ifdef HAVE_VLAN_FIND_DEV_DEEP_RCU
vlandev =
__vlan_find_dev_deep_rcu(netdev, htons(ETH_P_8021Q), i);
#else
vlandev = __vlan_find_dev_deep(netdev, htons(ETH_P_8021Q), i);
#endif
-/* lint +e778 */
col = VID_COL(nic_dev, i);
line = VID_LINE(nic_dev, i);
if (!vlandev && (vlan_bitmap[line] & (1UL << col)) != 0) {
@@ -1328,12 +1511,17 @@ static int set_feature_vlan_filter(struct hinic3_nic_dev *nic_dev,
return 0;
#ifdef NEED_VLAN_RESTORE
- if (en)
+ if (en) {
err = hinic3_vlan_restore(nic_dev->netdev);
+ if (err) {
+ hinic3_err(nic_dev, drv, "vlan restore failed\n");
+ *failed_features |= vlan_filter_feature;
+ return err;
+ }
+ }
#endif
- if (err == 0)
- err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
+ err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
if (err) {
hinic3_err(nic_dev, drv, "%s rx vlan filter failed\n",
SET_FEATURES_OP_STR(en));
@@ -1427,8 +1615,8 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
struct hinic3_nic_dev *adapter = netdev_priv(netdev);
int err;
- if (is_multicast_ether_addr(mac) || /*lint !e574*/
- vf >= pci_num_vf(adapter->pdev)) /*lint !e574*/
+ if (is_multicast_ether_addr(mac) ||
+ vf >= pci_num_vf(adapter->pdev))
return -EINVAL;
err = hinic3_set_vf_mac(adapter->hwdev, OS_VF_ID_TO_HW(vf), mac);
@@ -1446,7 +1634,6 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
return 0;
}
-/*lint -save -e574 -e734*/
#ifdef IFLA_VF_MAX
static int set_hw_vf_vlan(void *hwdev, u16 cur_vlanprio, int vf,
u16 vlan, u8 qos)
@@ -1529,7 +1716,8 @@ static int hinic3_ndo_set_vf_spoofchk(struct net_device *netdev, int vf,
#endif
#ifdef HAVE_NDO_SET_VF_TRUST
-static int hinic3_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting)
+static int hinic3_ndo_set_vf_trust(struct net_device *netdev, int vf,
+ bool setting)
{
struct hinic3_nic_dev *adapter = netdev_priv(netdev);
int err;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
index 11c1731..7288c5c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
@@ -10,6 +10,8 @@
#include "hinic3_common.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
/* ************************ array index define ********************* */
#define ARRAY_INDEX_0 0
@@ -21,6 +23,36 @@
#define ARRAY_INDEX_6 6
#define ARRAY_INDEX_7 7
+#define XSFP_TLV_PRE_INFO_LEN 4
+
+enum hinic3_link_port_type {
+ LINK_PORT_UNKNOWN,
+ LINK_PORT_OPTICAL_MM,
+ LINK_PORT_OPTICAL_SM,
+ LINK_PORT_PAS_COPPER,
+ LINK_PORT_ACC,
+ LINK_PORT_BASET,
+ LINK_PORT_AOC = 0x40,
+ LINK_PORT_ELECTRIC,
+ LINK_PORT_BACKBOARD_INTERFACE,
+};
+
+enum hilink_fibre_subtype {
+ FIBRE_SUBTYPE_SR = 1,
+ FIBRE_SUBTYPE_LR,
+ FIBRE_SUBTYPE_MAX,
+};
+
+enum hilink_fec_type {
+ HILINK_FEC_NOT_SET,
+ HILINK_FEC_RSFEC,
+ HILINK_FEC_BASEFEC,
+ HILINK_FEC_NOFEC,
+ HILINK_FEC_LLRSFE,
+ HILINK_FEC_MAX_TYPE,
+};
+
+
#define SQ_CI_ADDR_SHIFT 2
#define RQ_CI_ADDR_SHIFT 4
@@ -71,6 +103,12 @@ struct hinic3_port_routine_cmd {
struct mag_cmd_get_xsfp_present abs;
};
+struct hinic3_port_routine_cmd_extern {
+ bool mpu_send_xsfp_tlv_info;
+
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp std_xsfp_tlv_info;
+};
+
struct hinic3_nic_cfg {
struct semaphore cfg_lock;
@@ -84,11 +122,13 @@ struct hinic3_nic_cfg {
struct nic_port_info port_info;
/* percentage of pf link bandwidth */
- u32 pf_bw_limit;
- u32 rsvd2;
+ u32 pf_bw_tx_limit;
+ u32 pf_bw_rx_limit;
- struct hinic3_port_routine_cmd rt_cmd;
- struct mutex sfp_mutex; /* mutex used for copy sfp info */
+ struct hinic3_port_routine_cmd rt_cmd;
+ struct hinic3_port_routine_cmd_extern rt_cmd_ext;
+ /* mutex used for copy sfp info */
+ struct mutex sfp_mutex;
};
struct hinic3_nic_cmdq_ops;
@@ -98,7 +138,7 @@ struct hinic3_nic_io {
void *dev_hdl;
u8 link_status;
- u8 rsvd1;
+ u8 direct;
u32 rsvd2;
struct hinic3_io_queue *sq;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
index 747ac03..f136893 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
@@ -21,11 +21,132 @@
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_nic_cmdq.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_common.h"
#include "hinic3_nic_cfg.h"
-int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_sq_attr *attr)
+#include "vram_common.h"
+
+int hinic3_delete_bond(void *hwdev)
+{
+ struct hinic3_cmd_delete_bond cmd_delete_bond;
+ u16 out_size = sizeof(cmd_delete_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_delete_bond, 0, sizeof(cmd_delete_bond));
+ cmd_delete_bond.bond_id = HINIC3_INVALID_BOND_ID;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_DELETE,
+ &cmd_delete_bond, sizeof(cmd_delete_bond),
+ &cmd_delete_bond, &out_size);
+ if (err || !out_size || cmd_delete_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to delete bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_delete_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_delete_bond.bond_id != HINIC3_INVALID_BOND_ID)
+ nic_info(nic_io->dev_hdl, "Delete bond success\n");
+
+ return 0;
+}
+
+int hinic3_open_close_bond(void *hwdev, u32 bond_en)
+{
+ struct hinic3_cmd_open_close_bond cmd_open_close_bond;
+ u16 out_size = sizeof(cmd_open_close_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_open_close_bond, 0, sizeof(cmd_open_close_bond));
+ cmd_open_close_bond.open_close_bond_info.bond_id =
+ HINIC3_INVALID_BOND_ID;
+ cmd_open_close_bond.open_close_bond_info.open_close_flag = bond_en;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_OPEN_CLOSE,
+ &cmd_open_close_bond,
+ sizeof(cmd_open_close_bond),
+ &cmd_open_close_bond, &out_size);
+ if (err || !out_size || cmd_open_close_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to %s bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ bond_en == true ? "open" : "close", err,
+ cmd_open_close_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_open_close_bond.open_close_bond_info.bond_id !=
+ HINIC3_INVALID_BOND_ID) {
+ nic_info(nic_io->dev_hdl, "%s bond success\n", bond_en == true ? "Open" : "Close");
+ }
+
+ return 0;
+}
+
+int hinic3_create_bond(void *hwdev, u32 *bond_id)
+{
+ struct hinic3_cmd_create_bond cmd_create_bond;
+ u16 out_size = sizeof(cmd_create_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_create_bond, 0, sizeof(cmd_create_bond));
+ cmd_create_bond.create_bond_info.default_param_flag = true;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_CREATE,
+ &cmd_create_bond, sizeof(cmd_create_bond),
+ &cmd_create_bond, &out_size);
+ if (err || !out_size || cmd_create_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to create default bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_create_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_create_bond.create_bond_info.bond_id !=
+ HINIC3_INVALID_BOND_ID) {
+ *bond_id = cmd_create_bond.create_bond_info.bond_id;
+ nic_info(nic_io->dev_hdl, "Create bond success\n");
+ }
+
+ return 0;
+}
+
+int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io,
+ struct hinic3_sq_attr *attr)
{
struct hinic3_cmd_cons_idx_attr cons_idx_attr;
u16 out_size = sizeof(cons_idx_attr);
@@ -48,7 +169,8 @@ int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_sq_attr *at
cons_idx_attr.l2nic_sqn = attr->l2nic_sqn;
cons_idx_attr.ci_addr = attr->ci_dma_base >> SQ_CI_ADDR_SHIFT;
- err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_SQ_CI_ATTR_SET,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC3_NIC_CMD_SQ_CI_ATTR_SET,
&cons_idx_attr, sizeof(cons_idx_attr),
&cons_idx_attr, &out_size);
if (err || !out_size || cons_idx_attr.msg_head.status) {
@@ -61,7 +183,8 @@ int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_sq_attr *at
return 0;
}
-int hinic3_set_rq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_rq_attr *attr)
+int hinic3_set_rq_ci_ctx(struct hinic3_nic_io *nic_io,
+ struct hinic3_rq_attr *attr)
{
struct hinic3_rq_cqe_ctx cons_idx_ctx;
u16 out_size = sizeof(cons_idx_ctx);
@@ -76,15 +199,19 @@ int hinic3_set_rq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_rq_attr *at
cons_idx_ctx.timer_loop = attr->coalescing_time;
cons_idx_ctx.threshold_cqe_num = attr->pending_limit;
cons_idx_ctx.msix_entry_idx = attr->intr_idx;
- cons_idx_ctx.ci_addr_hi = upper_32_bits(attr->ci_dma_base >> RQ_CI_ADDR_SHIFT);
- cons_idx_ctx.ci_addr_lo = lower_32_bits(attr->ci_dma_base >> RQ_CI_ADDR_SHIFT);
+ cons_idx_ctx.ci_addr_hi = upper_32_bits(attr->ci_dma_base >>
+ RQ_CI_ADDR_SHIFT);
+ cons_idx_ctx.ci_addr_lo = lower_32_bits(attr->ci_dma_base >>
+ RQ_CI_ADDR_SHIFT);
- err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_SET_RQ_CI_CTX,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC3_NIC_CMD_SET_RQ_CI_CTX,
&cons_idx_ctx, sizeof(cons_idx_ctx),
&cons_idx_ctx, &out_size);
if (err || !out_size || cons_idx_ctx.msg_head.status) {
nic_err(nic_io->dev_hdl, "Set rq cqe ctx fail, qid: %d, err: %d, status: 0x%x, out_size: 0x%x",
- attr->l2nic_rqn, err, cons_idx_ctx.msg_head.status, out_size);
+ attr->l2nic_rqn, err,
+ cons_idx_ctx.msg_head.status, out_size);
return -EFAULT;
}
@@ -142,8 +269,8 @@ int hinic3_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
&mac_info, sizeof(mac_info),
&mac_info, &out_size, channel);
if (err || !out_size ||
- hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
- mac_info.vlan_id)) {
+ (hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
+ mac_info.vlan_id) != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, mac_info.msg_head.status, out_size, channel);
@@ -178,6 +305,8 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -193,7 +322,8 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
&mac_info, sizeof(mac_info), &mac_info,
&out_size, channel);
if (err || !out_size ||
- (mac_info.msg_head.status && !PF_SET_VF_MAC(hwdev, mac_info.msg_head.status))) {
+ (mac_info.msg_head.status &&
+ !PF_SET_VF_MAC(hwdev, mac_info.msg_head.status))) {
nic_err(nic_io->dev_hdl,
"Failed to delete MAC, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, mac_info.msg_head.status, out_size, channel);
@@ -223,6 +353,8 @@ int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -239,8 +371,8 @@ int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
&mac_info, sizeof(mac_info),
&mac_info, &out_size);
if (err || !out_size ||
- hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
- mac_info.vlan_id)) {
+ (hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
+ mac_info.vlan_id) != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x\n",
err, mac_info.msg_head.status, out_size);
@@ -273,6 +405,8 @@ int hinic3_get_default_mac(void *hwdev, u8 *mac_addr)
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
mac_info.func_id = hinic3_global_func_id(hwdev);
@@ -318,6 +452,44 @@ static int hinic3_config_vlan(struct hinic3_nic_io *nic_io, u8 opcode,
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action)
+{
+ struct hinic3_cmd_vxlan_port_info vxlan_port_info;
+ u16 out_size = sizeof(vxlan_port_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ memset(&vxlan_port_info, 0, sizeof(vxlan_port_info));
+ vxlan_port_info.opcode = action;
+ vxlan_port_info.cfg_mode = 0; // other tool set
+ vxlan_port_info.func_id = func_id;
+ vxlan_port_info.vxlan_port = port;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+ &vxlan_port_info, sizeof(vxlan_port_info), &vxlan_port_info, &out_size);
+ if (err || !out_size || vxlan_port_info.msg_head.status) {
+ if (vxlan_port_info.msg_head.status == 0x2) // other tool set failed
+ nic_warn(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port because it has already been set by hinicadm\n",
+ action == HINIC3_CMD_OP_ADD
+ ? "add" : "delete");
+ else
+ nic_err(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port, err: %d, status: 0x%x, out size: 0x%x\n",
+ action == HINIC3_CMD_OP_ADD ? "add" : "delete",
+ err, vxlan_port_info.msg_head.status, out_size);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
{
struct hinic3_nic_io *nic_io = NULL;
@@ -326,6 +498,8 @@ int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan_id, func_id);
}
@@ -337,6 +511,8 @@ int hinic3_del_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_DEL, vlan_id, func_id);
}
@@ -380,6 +556,8 @@ int hinic3_set_dcb_state(void *hwdev, struct hinic3_dcb_state *dcb_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (!memcmp(&nic_io->dcb_state, dcb_state, sizeof(nic_io->dcb_state)))
return 0;
@@ -423,7 +601,8 @@ int hinic3_get_cos_by_pri(void *hwdev, u8 pri, u8 *cos)
if (pri >= NIC_DCB_UP_MAX && nic_io->dcb_state.trust == HINIC3_DCB_PCP)
return -EINVAL;
- if (pri >= NIC_DCB_IP_PRI_MAX && nic_io->dcb_state.trust == HINIC3_DCB_DSCP)
+ if (pri >= NIC_DCB_IP_PRI_MAX &&
+ nic_io->dcb_state.trust == HINIC3_DCB_DSCP)
return -EINVAL;
/*lint -e662*/
@@ -541,13 +720,15 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_cfg = &nic_io->nic_cfg;
down(&nic_cfg->cfg_lock);
err = hinic3_cfg_hw_pause(nic_io, HINIC3_CMD_OP_SET, &nic_pause);
- if (err) {
+ if (err != 0) {
up(&nic_cfg->cfg_lock);
return err;
}
@@ -566,7 +747,6 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
{
- struct hinic3_nic_cfg *nic_cfg = NULL;
struct hinic3_nic_io *nic_io = NULL;
int err = 0;
@@ -574,17 +754,13 @@ int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- nic_cfg = &nic_io->nic_cfg;
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_hw_pause(nic_io, HINIC3_CMD_OP_GET, nic_pause);
- if (err)
+ if (err != 0)
return err;
- if (nic_cfg->pause_set || !nic_pause->auto_neg) {
- nic_pause->rx_pause = nic_cfg->nic_pause.rx_pause;
- nic_pause->tx_pause = nic_cfg->nic_pause.tx_pause;
- }
-
return 0;
}
@@ -599,6 +775,8 @@ int hinic3_sync_dcb_state(void *hwdev, u8 op_code, u8 state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&dcb_state, 0, sizeof(dcb_state));
@@ -607,7 +785,8 @@ int hinic3_sync_dcb_state(void *hwdev, u8 op_code, u8 state)
dcb_state.func_id = hinic3_global_func_id(hwdev);
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_QOS_DCB_STATE,
- &dcb_state, sizeof(dcb_state), &dcb_state, &out_size);
+ &dcb_state, sizeof(dcb_state),
+ &dcb_state, &out_size);
if (err || dcb_state.head.status || !out_size) {
nic_err(nic_io->dev_hdl,
"Failed to set dcb state, err: %d, status: 0x%x, out size: 0x%x\n",
@@ -675,7 +854,8 @@ int hinic3_cache_out_qps_res(void *hwdev)
qp_res.func_id = hinic3_global_func_id(hwdev);
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
- &qp_res, sizeof(qp_res), &qp_res, &out_size);
+ &qp_res, sizeof(qp_res),
+ &qp_res, &out_size);
if (err || !out_size || qp_res.msg_head.status) {
nic_err(nic_io->dev_hdl, "Failed to cache out qp resources, err: %d, status: 0x%x, out size: 0x%x\n",
err, qp_res.msg_head.status, out_size);
@@ -685,45 +865,8 @@ int hinic3_cache_out_qps_res(void *hwdev)
return 0;
}
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats)
-{
- struct hinic3_port_stats *port_stats = NULL;
- struct hinic3_port_stats_info stats_info;
- u16 out_size = sizeof(*port_stats);
- struct hinic3_nic_io *nic_io = NULL;
- int err;
-
- port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
- if (!port_stats)
- return -ENOMEM;
-
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
-
- memset(&stats_info, 0, sizeof(stats_info));
-
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_PORT_STAT,
- &stats_info, sizeof(stats_info),
- port_stats, &out_size);
- if (err || !out_size || port_stats->msg_head.status) {
- nic_err(nic_io->dev_hdl,
- "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
- err, port_stats->msg_head.status, out_size);
- err = -EIO;
- goto out;
- }
-
- memcpy(stats, &port_stats->stats, sizeof(*stats));
-
-out:
- kfree(port_stats);
-
- return err;
-}
-EXPORT_SYMBOL(hinic3_get_fpga_phy_port_stats);
-
-int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *stats)
+int hinic3_get_vport_stats(void *hwdev, u16 func_id,
+ struct hinic3_vport_stats *stats)
{
struct hinic3_port_stats_info stats_info;
struct hinic3_cmd_vport_stats vport_stats;
@@ -738,6 +881,8 @@ int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *
memset(&vport_stats, 0, sizeof(vport_stats));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
stats_info.func_id = func_id;
@@ -756,7 +901,8 @@ int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *
return 0;
}
-static int hinic3_set_function_table(struct hinic3_nic_io *nic_io, u32 cfg_bitmap,
+static int hinic3_set_function_table(struct hinic3_nic_io *nic_io,
+ u32 cfg_bitmap,
const struct hinic3_func_tbl_cfg *cfg)
{
struct hinic3_cmd_set_func_tbl cmd_func_tbl;
@@ -804,6 +950,8 @@ int hinic3_set_port_mtu(void *hwdev, u16 new_mtu)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (new_mtu < HINIC3_MIN_MTU_SIZE) {
nic_err(nic_io->dev_hdl,
@@ -834,6 +982,8 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&feature_nego, 0, sizeof(feature_nego));
feature_nego.func_id = hinic3_global_func_id(hwdev);
feature_nego.opcode = opcode;
@@ -855,29 +1005,24 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return 0;
}
-static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
+static int hinic3_get_bios_pf_bw_tx_limit(void *hwdev,
+ struct hinic3_nic_io *nic_io,
+ u16 func_id, u32 *pf_rate)
{
- struct hinic3_nic_io *nic_io = NULL;
+ int err = 0; // default success
struct nic_cmd_bios_cfg cfg = {{0}};
u16 out_size = sizeof(cfg);
- int err;
-
- if (!hwdev || !pf_bw_limit)
- return -EINVAL;
-
- if (hinic3_func_type(hwdev) == TYPE_VF || !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
- return 0;
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- cfg.bios_cfg.func_id = (u8)hinic3_global_func_id(hwdev);
+ cfg.bios_cfg.func_id = (u8)func_id;
cfg.bios_cfg.func_valid = 1;
- cfg.op_code = 0 | NIC_NVM_DATA_PF_SPEED_LIMIT;
+ cfg.op_code = 0 | NIC_NVM_DATA_PF_TX_SPEED_LIMIT;
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BIOS_CFG, &cfg, sizeof(cfg),
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BIOS_CFG,
+ &cfg, sizeof(cfg),
&cfg, &out_size);
if (err || !out_size || cfg.head.status) {
nic_err(nic_io->dev_hdl,
- "Failed to get bios pf bandwidth limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ "Failed to get bios pf bandwidth tx limit, err: %d, status: 0x%x, out size: 0x%x\n",
err, cfg.head.status, out_size);
return -EIO;
}
@@ -887,13 +1032,86 @@ static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
nic_warn(nic_io->dev_hdl, "Invalid bios configuration data, signature: 0x%x\n",
cfg.bios_cfg.signature);
- if (cfg.bios_cfg.pf_bw > MAX_LIMIT_BW) {
+ if (cfg.bios_cfg.pf_tx_bw > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
+ cfg.bios_cfg.pf_tx_bw);
+ return -EINVAL;
+ }
+
+ (*pf_rate) = cfg.bios_cfg.pf_tx_bw;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_rx_limit(void *hwdev,
+ struct hinic3_nic_io *nic_io,
+ u16 func_id, u32 *pf_rate)
+{
+ int err = 0; // default success
+ struct nic_rx_rate_bios_cfg rx_bios_conf = {{0}};
+ u16 out_size = sizeof(rx_bios_conf);
+
+ rx_bios_conf.func_id = (u8)func_id;
+ rx_bios_conf.op_code = 0; /* 1-save, 0-read */
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_RX_RATE_CFG,
+ &rx_bios_conf, sizeof(rx_bios_conf),
+ &rx_bios_conf, &out_size);
+ if (rx_bios_conf.msg_head.status == HINIC3_MGMT_CMD_UNSUPPORTED &&
+ err == 0) { // Compatible older firmware
+ nic_warn(nic_io->dev_hdl, "Not support get bios pf bandwidth rx limit\n");
+ return 0;
+ } else if (err || !out_size || rx_bios_conf.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get bios pf bandwidth rx limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, rx_bios_conf.msg_head.status, out_size);
+ return -EIO;
+ }
+ if (rx_bios_conf.rx_rate_limit > MAX_LIMIT_BW) {
nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
- cfg.bios_cfg.pf_bw);
+ rx_bios_conf.rx_rate_limit);
return -EINVAL;
}
- *pf_bw_limit = cfg.bios_cfg.pf_bw;
+ (*pf_rate) = rx_bios_conf.rx_rate_limit;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit, u8 direct)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u32 pf_rate = 0;
+ int err = 0;
+ u16 func_id;
+
+ func_id = hinic3_global_func_id(hwdev);
+
+ if (!hwdev || !pf_bw_limit)
+ return -EINVAL;
+
+ if (hinic3_func_type(hwdev) == TYPE_VF ||
+ !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
+ return 0;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (direct == HINIC3_NIC_TX)
+ err = hinic3_get_bios_pf_bw_tx_limit(hwdev, nic_io,
+ func_id, &pf_rate);
+ else if (direct == HINIC3_NIC_RX)
+ err = hinic3_get_bios_pf_bw_rx_limit(hwdev, nic_io,
+ func_id, &pf_rate);
+
+ if (err != 0)
+ return err;
+
+ if (pf_rate > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl,
+ "Invalid bios cfg pf bandwidth limit: %u\n", pf_rate);
+ return -EINVAL;
+ }
+
+ *pf_bw_limit = pf_rate;
return 0;
}
@@ -902,8 +1120,9 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
{
struct hinic3_cmd_tx_rate_cfg rate_cfg = {{0}};
struct hinic3_nic_io *nic_io = NULL;
+ u32 rate_limit;
u16 out_size = sizeof(rate_cfg);
- u32 pf_rate;
+ u32 pf_rate = 0;
int err;
u32 speed_convert[PORT_SPEED_UNKNOWN] = {
0, 10, 100, 1000, 10000, 25000, 40000, 50000, 100000, 200000
@@ -914,30 +1133,34 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
return -EINVAL;
if (speed_level >= PORT_SPEED_UNKNOWN) {
- nic_err(nic_io->dev_hdl, "Invalid speed level: %u\n", speed_level);
+ nic_err(nic_io->dev_hdl,
+ "Invalid speed level: %u\n", speed_level);
return -EINVAL;
}
- if (nic_io->nic_cfg.pf_bw_limit == MAX_LIMIT_BW) {
- pf_rate = 0;
- } else {
+ rate_limit = (nic_io->direct == HINIC3_NIC_TX) ?
+ nic_io->nic_cfg.pf_bw_tx_limit : nic_io->nic_cfg.pf_bw_rx_limit;
+ if (rate_limit != MAX_LIMIT_BW) {
/* divided by 100 to convert to percentage */
- pf_rate = (speed_convert[speed_level] / 100) * nic_io->nic_cfg.pf_bw_limit;
+ pf_rate = (speed_convert[speed_level] / 100) * rate_limit;
/* bandwidth limit is very small but not unlimit in this case */
- if (pf_rate == 0 && speed_level != PORT_SPEED_NOT_SET)
+ if ((pf_rate == 0) && (speed_level != PORT_SPEED_NOT_SET))
pf_rate = 1;
}
rate_cfg.func_id = hinic3_global_func_id(hwdev);
rate_cfg.min_rate = 0;
rate_cfg.max_rate = pf_rate;
+ rate_cfg.direct = nic_io->direct;
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_MAX_MIN_RATE, &rate_cfg,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
+ &rate_cfg,
sizeof(rate_cfg), &rate_cfg, &out_size);
if (err || !out_size || rate_cfg.msg_head.status) {
nic_err(nic_io->dev_hdl, "Failed to set rate(%u), err: %d, status: 0x%x, out size: 0x%x\n",
pf_rate, err, rate_cfg.msg_head.status, out_size);
- return rate_cfg.msg_head.status ? rate_cfg.msg_head.status : -EIO;
+ return rate_cfg.msg_head.status
+ ? rate_cfg.msg_head.status : -EIO;
}
return 0;
@@ -954,7 +1177,8 @@ int hinic3_set_nic_feature_to_hw(void *hwdev)
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- return nic_feature_nego(hwdev, HINIC3_CMD_OP_SET, &nic_io->feature_cap, 1);
+ return nic_feature_nego(hwdev, HINIC3_CMD_OP_SET,
+ &nic_io->feature_cap, 1);
}
u64 hinic3_get_feature_cap(void *hwdev)
@@ -962,6 +1186,8 @@ u64 hinic3_get_feature_cap(void *hwdev)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
return nic_io->feature_cap;
}
@@ -971,12 +1197,17 @@ void hinic3_update_nic_feature(void *hwdev, u64 s_feature)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
nic_io->feature_cap = s_feature;
- nic_info(nic_io->dev_hdl, "Update nic feature to 0x%llx\n", nic_io->feature_cap);
+ nic_info(nic_io->dev_hdl,
+ "Update nic feature to 0x%llx\n",
+ nic_io->feature_cap);
}
-static inline int init_nic_hwdev_param_valid(const void *hwdev, const void *pcidev_hdl,
+static inline int init_nic_hwdev_param_valid(const void *hwdev,
+ const void *pcidev_hdl,
const void *dev_hdl)
{
if (!hwdev || !pcidev_hdl || !dev_hdl)
@@ -1004,6 +1235,7 @@ static int hinic3_init_nic_io(void *hwdev, void *pcidev_hdl, void *dev_hdl,
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_abs = false;
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_info = false;
+ (*nic_io)->nic_cfg.rt_cmd_ext.mpu_send_xsfp_tlv_info = false;
return 0;
}
@@ -1020,27 +1252,34 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
{
struct hinic3_nic_io *nic_io = NULL;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
err = hinic3_init_nic_io(hwdev, pcidev_hdl, dev_hdl, &nic_io);
- if (err)
+ if (err != 0)
return err;
+ nic_io->rx_buff_len = rx_buff_len;
+
err = hinic3_register_service_adapter(hwdev, nic_io, SERVICE_T_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to register service adapter\n");
goto register_sa_err;
}
- err = hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 1, HINIC3_CHANNEL_NIC);
- if (err) {
+ err = hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC,
+ 1, HINIC3_CHANNEL_NIC);
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set function svc used state\n");
goto set_used_state_err;
}
- err = hinic3_init_function_table(nic_io);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to init function table\n");
- goto err_out;
+ if (is_in_kexec == 0) {
+ err = hinic3_init_function_table(nic_io);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to init function table\n");
+ goto err_out;
+ }
}
err = hinic3_get_nic_feature_from_hw(hwdev, &nic_io->feature_cap, 1);
@@ -1052,24 +1291,35 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
sdk_info(dev_hdl, "nic features: 0x%llx\n", nic_io->feature_cap);
hinic3_nic_cmdq_adapt_init(nic_io);
- err = hinic3_get_bios_pf_bw_limit(hwdev, &nic_io->nic_cfg.pf_bw_limit);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to get pf bandwidth limit\n");
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_tx_limit,
+ HINIC3_NIC_TX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf tx bandwidth limit\n");
+ goto err_out;
+ }
+
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_rx_limit,
+ HINIC3_NIC_RX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf rx bandwidth limit\n");
goto err_out;
}
err = hinic3_vf_func_init(nic_io);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to init vf info\n");
goto err_out;
}
- nic_io->rx_buff_len = rx_buff_len;
-
return 0;
err_out:
- hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 0, HINIC3_CHANNEL_NIC);
+ if (hinic3_set_func_svc_used_state(
+ hwdev, SVC_T_NIC, 0, HINIC3_CHANNEL_NIC) != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to set function svc used state\n");
+ }
set_used_state_err:
hinic3_unregister_service_adapter(hwdev, SERVICE_T_NIC);
@@ -1119,6 +1369,8 @@ int hinic3_force_drop_tx_pkt(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&pkt_drop, 0, sizeof(pkt_drop));
pkt_drop.port = hinic3_physical_port_id(hwdev);
@@ -1147,6 +1399,8 @@ int hinic3_set_rx_mode(void *hwdev, u32 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&rx_mode_cfg, 0, sizeof(rx_mode_cfg));
rx_mode_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1175,6 +1429,8 @@ int hinic3_set_rx_vlan_offload(void *hwdev, u8 en)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_cfg, 0, sizeof(vlan_cfg));
vlan_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1192,7 +1448,8 @@ int hinic3_set_rx_vlan_offload(void *hwdev, u8 en)
return 0;
}
-int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
+int hinic3_update_mac_vlan(void *hwdev, const u16 old_vlan,
+ u16 new_vlan, int vf_id)
{
struct vf_data_storage *vf_info = NULL;
struct hinic3_nic_io *nic_io = NULL;
@@ -1203,6 +1460,8 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
if (!nic_io->vf_infos || is_zero_ether_addr(vf_info->drv_mac_addr))
return 0;
@@ -1211,7 +1470,7 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
err = hinic3_del_mac(nic_io->hwdev, vf_info->drv_mac_addr,
old_vlan, func_id, HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to delete VF %d MAC %pM vlan %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->drv_mac_addr, old_vlan);
return err;
@@ -1219,7 +1478,7 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
err = hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
new_vlan, func_id, HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to add VF %d MAC %pM vlan %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->drv_mac_addr, new_vlan);
hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
@@ -1242,6 +1501,8 @@ static int hinic3_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en,
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_cfg, 0, sizeof(lro_cfg));
lro_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1273,6 +1534,8 @@ static int hinic3_set_rx_lro_timer(void *hwdev, u32 timer_value)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_timer, 0, sizeof(lro_timer));
lro_timer.opcode = HINIC3_CMD_OP_SET;
@@ -1305,12 +1568,14 @@ int hinic3_set_rx_lro_state(void *hwdev, u8 lro_en, u32 lro_timer,
ipv6_en = lro_en ? 1 : 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_info(nic_io->dev_hdl, "Set LRO max coalesce packet size to %uK\n",
lro_max_pkt_len);
err = hinic3_set_rx_lro(hwdev, ipv4_en, ipv6_en, (u8)lro_max_pkt_len);
- if (err)
+ if (err != 0)
return err;
/* we don't set LRO timer for VF */
@@ -1333,6 +1598,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_filter, 0, sizeof(vlan_filter));
vlan_filter.func_id = hinic3_global_func_id(hwdev);
@@ -1352,7 +1619,6 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
{
- // struct hinic_hwdev *dev = hwdev;
struct nic_cmd_capture_info cap_info = {{0}};
u16 out_size = sizeof(cap_info);
int err;
@@ -1361,7 +1627,6 @@ int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
return -EINVAL;
/* 2 function capture types */
- // cap_info.op_type = UP_UCAPTURE_OP_TYPE_FUNC;
cap_info.is_en_trx = cap_en;
cap_info.func_port = func_id;
@@ -1386,6 +1651,8 @@ int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (tcam_rule->index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to add is invalid\n");
return -EINVAL;
@@ -1421,6 +1688,8 @@ int hinic3_del_tcam_rule(void *hwdev, u32 index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to del is invalid\n");
return -EINVAL;
@@ -1470,6 +1739,8 @@ static int hinic3_mgmt_tcam_block(void *hwdev, u8 alloc_en, u16 *index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&tcam_block_info, 0,
sizeof(struct nic_cmd_ctrl_tcam_block_out));
@@ -1515,6 +1786,8 @@ int hinic3_set_fdir_tcam_rule_filter(void *hwdev, bool enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
port_tcam_cmd.func_id = hinic3_global_func_id(hwdev);
port_tcam_cmd.tcam_enable = (u8)enable;
@@ -1543,6 +1816,8 @@ int hinic3_flush_tcam_rule(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&tcam_flush, 0, sizeof(struct nic_cmd_flush_tcam_rules));
tcam_flush.func_id = hinic3_global_func_id(hwdev);
@@ -1560,7 +1835,8 @@ int hinic3_flush_tcam_rule(void *hwdev)
return 0;
}
-int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type)
+int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info,
+ u16 num_qps, u16 wqe_type)
{
struct hinic3_cmd_buf *cmd_buf = NULL;
struct hinic3_nic_io *nic_io = NULL;
@@ -1573,6 +1849,8 @@ int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -1587,9 +1865,11 @@ int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
cmd_buf->size = sizeof(struct hinic3_rxq_hw);
- err = hinic3_cmdq_detail_resp(hwdev, HINIC3_MOD_L2NIC, HINIC3_UCODE_CMD_RXQ_INFO_GET,
- cmd_buf, cmd_buf, NULL, 0, HINIC3_CHANNEL_NIC);
- if (err)
+ err = hinic3_cmdq_detail_resp(hwdev, HINIC3_MOD_L2NIC,
+ HINIC3_UCODE_CMD_RXQ_INFO_GET,
+ cmd_buf, cmd_buf, NULL, 0,
+ HINIC3_CHANNEL_NIC);
+ if (err != 0)
goto get_rxq_info_failed;
rxq_info_out = cmd_buf->buf;
@@ -1604,7 +1884,8 @@ get_rxq_info_failed:
return err;
}
-int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_state)
+int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced,
+ bool link_state)
{
struct hinic3_nic_io *nic_io = NULL;
struct vf_data_storage *vf_infos = NULL;
@@ -1615,8 +1896,10 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return -EINVAL;
}
- if (hinic3_func_type(hwdev) == TYPE_VF)
+ if (hinic3_func_type(hwdev) == TYPE_VF) {
+ pr_err("VF are not supported to set link state.\n");
return -EINVAL;
+ }
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
if (!nic_io) {
@@ -1633,3 +1916,35 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return 0;
}
EXPORT_SYMBOL(hinic3_pf_set_vf_link_state);
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid)
+{
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ u16 out_size = sizeof(outband_cfg_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !outband_default_vid)
+ return -EINVAL;
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_OUTBAND_CFG,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size);
+ if (err || !out_size || outband_cfg_info.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get outband cfg, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, outband_cfg_info.msg_head.status, out_size);
+ return -EINVAL;
+ }
+
+ *outband_default_vid = outband_cfg_info.outband_default_vid;
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
index dd2c2fd..e0350e3 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
@@ -7,9 +7,10 @@
#include <linux/types.h>
#include <linux/netdevice.h>
-#include "hinic3_mgmt_interface.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
+#include "nic_cfg_comm.h"
+#include "nic_mpu_cmd_defs.h"
#define OS_VF_ID_TO_HW(os_vf_id) ((os_vf_id) + 1)
#define HW_VF_ID_TO_OS(hw_vf_id) ((hw_vf_id) - 1)
@@ -54,6 +55,8 @@
#define MAX_LIMIT_BW 100
+#define HINIC3_INVALID_BOND_ID 0xffffffff
+
enum hinic3_valid_link_settings {
HILINK_LINK_SET_SPEED = 0x1,
HILINK_LINK_SET_AUTONEG = 0x2,
@@ -67,6 +70,11 @@ enum hinic3_link_follow_status {
HINIC3_LINK_FOLLOW_STATUS_MAX,
};
+enum hinic3_nic_pf_direct {
+ HINIC3_NIC_RX = 0,
+ HINIC3_NIC_TX,
+};
+
struct hinic3_link_ksettings {
u32 valid_bitmap;
u8 speed; /* enum nic_speed_level */
@@ -152,8 +160,12 @@ struct nic_port_info {
u8 duplex;
u8 speed;
u8 fec;
+ u8 lanes;
+ u8 rsvd;
u32 supported_mode;
u32 advertised_mode;
+ u32 supported_fec_mode;
+ u32 bond_speed;
};
struct nic_pause_config {
@@ -178,11 +190,17 @@ struct hinic3_rxq_hw {
#define MODULE_TYPE_QSFP28 0x11
#define MODULE_TYPE_QSFP 0x0C
#define MODULE_TYPE_QSFP_PLUS 0x0D
+#define MODULE_TYPE_DSFP 0x1B
+#define MODULE_TYPE_QSFP_CMIS 0x1E
#define TCAM_IP_TYPE_MASK 0x1
#define TCAM_TUNNEL_TYPE_MASK 0xF
#define TCAM_FUNC_ID_MASK 0x7FFF
+int hinic3_delete_bond(void *hwdev);
+int hinic3_open_close_bond(void *hwdev, u32 bond_en);
+int hinic3_create_bond(void *hwdev, u32 *bond_id);
+
int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule);
int hinic3_del_tcam_rule(void *hwdev, u32 index);
@@ -335,7 +353,7 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr);
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr);
/* *
* @brief hinic3_vf_info_vlanprio - get vf vlan priority
@@ -510,7 +528,14 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table);
*/
int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats);
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats);
+/* *
+ * @brief hinic3_get_phy_rsfec_stats - get rsfec stats
+ * @param hwdev: device pointer to hwdev
+ * @param stats: rsfec(Reed-Solomon Forward Error Correction) stats
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats);
int hinic3_set_port_funcs_state(void *hwdev, bool enable);
@@ -546,6 +571,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl);
void hinic3_clear_vfs_info(void *hwdev);
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id);
+
int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id);
int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
@@ -565,9 +592,13 @@ int hinic3_set_autoneg(void *hwdev, bool enable);
int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext);
int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len);
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len);
bool hinic3_if_sfp_absent(void *hwdev);
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info);
+int hinic3_get_sfp_tlv_info(void *hwdev,
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info,
+ const struct tag_mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req);
/* *
* @brief hinic3_set_nic_feature_to_hw - sync nic feature to hardware
@@ -620,4 +651,19 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level);
int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type);
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+/* *
+ * @brief hinic3_vlxan_port_config - add/del vxlan dst port
+ * @param hwdev: device pointer to hwdev
+ * @param func_id: function id
+ * @param port: vxlan dst port
+ * @param action: add or del, del will set to default value (0x12B5)
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action);
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
index 15d081b..c0e0a61 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
@@ -22,7 +22,8 @@
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_nic_cmdq.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
/*lint -e806*/
static unsigned char set_vf_link_state;
@@ -59,7 +60,8 @@ static int hinic3_set_vlan_ctx(struct hinic3_nic_io *nic_io, u16 func_id,
vlan_tag, q_id, vlan_mode);
err = hinic3_cmdq_direct_resp(nic_io->hwdev, HINIC3_MOD_L2NIC,
- cmd, cmd_buf, &out_param, 0, HINIC3_CHANNEL_NIC);
+ cmd, cmd_buf, &out_param,
+ 0, HINIC3_CHANNEL_NIC);
hinic3_free_cmd_buf(nic_io->hwdev, cmd_buf);
@@ -108,7 +110,7 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
err = hinic3_set_vlan_ctx(nic_io, glb_func_id, vlan_tag,
NIC_CONFIG_ALL_QUEUE_VLAN_CTX,
opcode == HINIC3_CMD_OP_ADD);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d vlan ctx, err: %d\n",
HW_VF_ID_TO_OS(vf_id), err);
@@ -129,12 +131,15 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
/* this function just be called by hinic3_ndo_set_vf_mac,
* others are not permitted.
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr)
{
- struct vf_data_storage *vf_info;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_info = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
#ifndef __VMWARE__
/* duplicate request, so just return success */
@@ -152,13 +157,15 @@ int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan, qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan = vlan;
@@ -172,17 +179,19 @@ int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
vf_infos = nic_io->vf_infos;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_DEL,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_info(nic_io->dev_hdl, "Remove VLAN %u on VF %d\n",
@@ -197,11 +206,13 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
u16 hinic3_vf_info_vlanprio(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
u16 pf_vlan, vlanprio;
u8 pf_qos;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
pf_vlan = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan;
pf_qos = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos;
@@ -214,9 +225,14 @@ int hinic3_set_vf_link_state(void *hwdev, u16 vf_id, int link)
{
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ struct vf_data_storage *vf_infos = NULL;
u8 link_status = 0;
+ if (!nic_io)
+ return -EINVAL;
+
+ vf_infos = nic_io->vf_infos;
+
switch (link) {
case HINIC3_IFLA_VF_LINK_STATE_AUTO:
vf_infos[HW_VF_ID_TO_OS(vf_id)].link_forced = false;
@@ -256,6 +272,8 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
vf_infos = nic_io->vf_infos;
memset(&spoofchk_cfg, 0, sizeof(spoofchk_cfg));
@@ -280,9 +298,11 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
bool hinic3_vf_info_spoofchk(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].spoofchk;
}
@@ -296,7 +316,7 @@ int hinic3_set_vf_trust(void *hwdev, u16 vf_id, bool trust)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
+ if (!nic_io || vf_id > nic_io->max_vfs)
return -EINVAL;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust = trust;
@@ -309,11 +329,11 @@ bool hinic3_get_vf_trust(void *hwdev, int vf_id)
struct hinic3_nic_io *nic_io = NULL;
if (!hwdev)
- return -EINVAL;
+ return false;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
- return -EINVAL;
+ if (!nic_io || vf_id > nic_io->max_vfs)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust;
}
@@ -331,6 +351,7 @@ static int hinic3_set_vf_tx_rate_max_min(struct hinic3_nic_io *nic_io,
rate_cfg.func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf_id;
rate_cfg.max_rate = max_rate;
rate_cfg.min_rate = min_rate;
+ rate_cfg.direct = HINIC3_NIC_TX;
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
&rate_cfg, sizeof(rate_cfg), &rate_cfg,
@@ -351,13 +372,15 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (!HINIC3_SUPPORT_RATE_LIMIT(hwdev)) {
nic_err(nic_io->dev_hdl, "Current function doesn't support to set vf rate limit\n");
return -EOPNOTSUPP;
}
err = hinic3_set_vf_tx_rate_max_min(nic_io, vf_id, max_rate, min_rate);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].max_rate = max_rate;
@@ -368,12 +391,16 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
void hinic3_get_vf_config(void *hwdev, u16 vf_id, struct ifla_vf_info *ivi)
{
- struct vf_data_storage *vfinfo;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vfinfo = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
vfinfo = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vfinfo)
+ return;
ivi->vf = HW_VF_ID_TO_OS(vf_id);
ether_addr_copy(ivi->mac, vfinfo->user_mac_addr);
@@ -446,13 +473,15 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
int err;
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
- nic_io->hwdev, hinic3_vf_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_vf_event_handler);
+ if (err != 0)
return err;
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
- nic_io->hwdev, hinic3_vf_mag_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_vf_mag_event_handler);
+ if (err != 0)
goto reg_hilink_err;
memset(®ister_info, 0, sizeof(register_info));
@@ -464,6 +493,11 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
®ister_info, &out_size, 0,
HINIC3_CHANNEL_NIC);
if (err || !out_size || register_info.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev)) {
+ nic_warn(nic_io->dev_hdl, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, register_info.msg_head.status, out_size);
+ return 0;
+ }
nic_err(nic_io->dev_hdl, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
err, register_info.msg_head.status, out_size);
err = -EIO;
@@ -498,18 +532,20 @@ static int pf_init_vf_infos(struct hinic3_nic_io *nic_io)
for (i = 0; i < nic_io->max_vfs; i++) {
err = hinic3_init_vf_infos(nic_io, i);
- if (err)
+ if (err != 0)
goto init_vf_infos_err;
}
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
- nic_io->hwdev, hinic3_pf_mbox_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_mbox_handler);
+ if (err != 0)
goto register_pf_mbox_cb_err;
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
- nic_io->hwdev, hinic3_pf_mag_mbox_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_mag_mbox_handler);
+ if (err != 0)
goto register_pf_mag_mbox_cb_err;
return 0;
@@ -531,17 +567,19 @@ int hinic3_vf_func_init(struct hinic3_nic_io *nic_io)
return vf_func_register(nic_io);
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
- nic_io->hwdev, hinic3_pf_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_event_handler);
+ if (err != 0)
return err;
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
- nic_io->hwdev, hinic3_pf_mag_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_mag_event_handler);
+ if (err != 0)
goto register_mgmt_msg_cb_err;
err = pf_init_vf_infos(nic_io);
- if (err)
+ if (err != 0)
goto pf_init_vf_infos_err;
return 0;
@@ -568,17 +606,24 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
&unregister, sizeof(unregister),
&unregister, &out_size, 0,
HINIC3_CHANNEL_NIC);
- if (err || !out_size || unregister.msg_head.status)
- nic_err(nic_io->dev_hdl, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
- err, unregister.msg_head.status, out_size);
-
+ if (err || !out_size || unregister.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev)) {
+ nic_info(nic_io->dev_hdl, "vRoCE VF notify PF unsuccessful is allowed");
+ } else {
+ nic_err(nic_io->dev_hdl, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, unregister.msg_head.status, out_size);
+ }
+ }
hinic3_unregister_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
} else {
if (nic_io->vf_infos) {
- hinic3_unregister_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK);
- hinic3_unregister_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
+ hinic3_unregister_pf_mbox_cb(nic_io->hwdev,
+ HINIC3_MOD_HILINK);
+ hinic3_unregister_pf_mbox_cb(nic_io->hwdev,
+ HINIC3_MOD_L2NIC);
hinic3_clear_vfs_info(nic_io->hwdev);
kfree(nic_io->vf_infos);
+ nic_io->vf_infos = NULL;
}
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
@@ -587,11 +632,15 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
static void clear_vf_infos(void *hwdev, u16 vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
u16 func_id;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
func_id = hinic3_glb_pf_vf_offset(hwdev) + vf_id;
vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
@@ -620,10 +669,59 @@ static void clear_vf_infos(void *hwdev, u16 vf_id)
void hinic3_clear_vfs_info(void *hwdev)
{
+ u16 i;
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- u16 i;
+
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
for (i = 0; i < nic_io->max_vfs; i++)
clear_vf_infos(hwdev, OS_VF_ID_TO_HW(i));
}
+
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id)
+{
+ int err = 0;
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ struct vf_data_storage *vf_infos = NULL;
+ u16 out_size = sizeof(outband_cfg_info);
+ u16 vf_id;
+ struct hinic3_nic_io *nic_io =
+ hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return 0;
+ }
+
+ vf_id = func_id - hinic3_glb_pf_vf_offset(nic_io->hwdev);
+ vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+ if (vf_infos->registered) {
+ outband_cfg_info.func_id = func_id;
+ outband_cfg_info.outband_default_vid = vlan_id;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_L2NIC,
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return 0;
+ }
+ if (err || !out_size || outband_cfg_info.msg_head.status)
+ nic_err(nic_io->dev_hdl,
+ "outband cfg event to VF %d failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err,
+ outband_cfg_info.msg_head.status, out_size);
+ }
+
+ return err;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
index 0ec4b32..b45c875 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
@@ -30,6 +30,8 @@ int hinic3_dbg_get_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (q_id >= nic_io->num_qps) {
pr_err("q_id[%u] > num_qps_cfg[%u].\n", q_id, nic_io->num_qps);
return -EINVAL;
@@ -69,6 +71,8 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -82,6 +86,8 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
sq = &nic_io->sq[q_id];
+ if (!sq)
+ return -EINVAL;
sq_info->q_id = q_id;
sq_info->pi = hinic3_get_sq_local_pi(sq);
@@ -112,6 +118,8 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -125,6 +133,8 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
rq = &nic_io->rq[q_id];
+ if (!rq)
+ return -EINVAL;
rq_info->q_id = q_id;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
index e76a66b..38aa8f7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
@@ -15,9 +15,10 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
#include "hinic3_dcb.h"
+#include "vram_common.h"
#define HINIC3_NIC_DRV_NAME "hinic3"
-#define HINIC3_NIC_DRV_VERSION HINIC3_DRV_VERSION
+#define HINIC3_NIC_DRV_VERSION "17.7.8.1"
#define HINIC3_FUNC_IS_VF(hwdev) (hinic3_func_type(hwdev) == TYPE_VF)
@@ -25,6 +26,10 @@
#define HINIC3_MODERATONE_DELAY HZ
#define LP_PKT_CNT 64
+#define LP_PKT_LEN 60
+
+#define NAPI_IS_REGIN 1
+#define NAPI_NOT_REGIN 0
enum hinic3_flags {
HINIC3_INTF_UP,
@@ -91,6 +96,8 @@ struct hinic3_irq {
u16 rsvd1;
u32 irq_id; /* The IRQ number from OS */
+ u32 napi_reign;
+
char irq_name[IFNAMSIZ + 16];
struct napi_struct napi;
cpumask_t affinity_mask;
@@ -123,6 +130,41 @@ struct hinic3_dyna_txrxq_params {
struct hinic3_dyna_txq_res *txqs_res;
struct hinic3_dyna_rxq_res *rxqs_res;
struct hinic3_irq *irq_cfg;
+ char irq_cfg_vram_name[VRAM_NAME_MAX_LEN];
+};
+
+struct hinic3_flush_rq {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 lb_proc : 1;
+ u32 rsvd : 10;
+ u32 rq_id : 8;
+ u32 func_id : 13;
+#else
+ u32 func_id : 13;
+ u32 rq_id : 8;
+ u32 rsvd : 10;
+ u32 lb_proc : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd2 : 2;
+ u32 src_chnl : 12;
+ u32 pkt_len : 18;
+#else
+ u32 pkt_len : 18;
+ u32 src_chnl : 12;
+ u32 rsvd2 : 2;
+#endif
+ } bs;
+ u32 value;
+ } lb_info0; /* loop back information, used by uCode */
};
#define HINIC3_NIC_STATS_INC(nic_dev, field) \
@@ -147,6 +189,11 @@ struct hinic3_nic_stats {
#endif
};
+struct hinic3_nic_vport_stats {
+ u64 rx_discard_vport;
+};
+
+
#define HINIC3_TCAM_DYNAMIC_BLOCK_SIZE 16
#define HINIC3_MAX_TCAM_FILTERS 512
@@ -185,6 +232,29 @@ struct hinic3_tcam_info {
struct hinic3_tcam_dynamic_block_info tcam_dynamic_info;
};
+struct hinic3_dcb {
+ u8 cos_config_num_max;
+ u8 func_dft_cos_bitmap;
+ /* used to tool validity check */
+ u16 port_dft_cos_bitmap;
+
+ struct hinic3_dcb_config hw_dcb_cfg;
+ struct hinic3_dcb_config wanted_dcb_cfg;
+ unsigned long dcb_flags;
+};
+
+struct hinic3_vram {
+ u32 vram_mtu;
+ u16 vram_num_qps;
+ unsigned long flags;
+};
+
+struct hinic3_outband_cfg {
+ u16 outband_default_vid;
+ u16 rsvd;
+};
+
+
struct hinic3_nic_dev {
struct pci_dev *pdev;
struct net_device *netdev;
@@ -204,6 +274,7 @@ struct hinic3_nic_dev {
u32 dma_rx_buff_size;
u16 rx_buff_len;
u32 page_order;
+ bool page_pool_enabled;
/* Rss related varibles */
u8 rss_hash_engine;
@@ -213,17 +284,13 @@ struct hinic3_nic_dev {
u32 *rss_hkey_be;
u32 *rss_indir;
- u8 cos_config_num_max;
- u8 func_dft_cos_bitmap;
- u16 port_dft_cos_bitmap; /* used to tool validity check */
+ struct hinic3_dcb *dcb;
+ char dcb_name[VRAM_NAME_MAX_LEN];
+
+ struct hinic3_vram *nic_vram;
+ char nic_vram_name[VRAM_NAME_MAX_LEN];
- struct hinic3_dcb_config hw_dcb_cfg;
- struct hinic3_dcb_config wanted_dcb_cfg;
- struct hinic3_dcb_config dcb_cfg;
- unsigned long dcb_flags;
int disable_port_cnt;
- /* lock for disable or enable traffic flow */
- struct semaphore dcb_sem;
struct hinic3_intr_coal_info *intr_coalesce;
unsigned long last_moder_jiffies;
@@ -235,11 +302,10 @@ struct hinic3_nic_dev {
#endif
struct hinic3_nic_stats stats;
+ struct hinic3_nic_vport_stats vport_stats;
/* lock for nic resource */
struct mutex nic_mutex;
- bool force_port_disable;
- struct semaphore port_state_sem;
u8 link_status;
struct nic_service_cap nic_cap;
@@ -281,9 +347,10 @@ struct hinic3_nic_dev {
struct hinic3_nic_prof_attr *prof_attr;
struct hinic3_prof_adapter *prof_adap;
u64 rsvd8[7];
- u32 rsvd9;
+ struct hinic3_outband_cfg outband_cfg;
u32 rxq_get_err_times;
struct delayed_work rxq_check_work;
+ struct delayed_work vport_stats_work;
struct hinic3_tx_rx_ops tx_rx_ops;
};
@@ -312,7 +379,7 @@ struct hinic3_uld_info *get_nic_uld_info(void);
u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev);
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
int hinic3_open(struct net_device *netdev);
@@ -331,6 +398,8 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev);
void hinic3_qps_irq_deinit(struct hinic3_nic_dev *nic_dev);
+void qp_del_napi(struct hinic3_irq *irq_cfg);
+
void hinic3_set_netdev_ops(struct hinic3_nic_dev *nic_dev);
bool hinic3_is_netdev_ops_match(const struct net_device *netdev);
@@ -348,10 +417,6 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
int hinic3_get_sset_count(struct net_device *netdev, int sset);
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev);
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
#ifdef ETHTOOL_GLINKSETTINGS
@@ -386,5 +451,18 @@ bool hinic3_is_xdp_enable(struct hinic3_nic_dev *nic_dev);
int hinic3_xdp_max_mtu(struct hinic3_nic_dev *nic_dev);
#endif
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+int set_fecparam(void *hwdev, u8 fecparam);
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec);
+#endif
+
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
index 57cf07c..c53c125 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
@@ -21,11 +21,12 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
{
- struct vf_data_storage *vf_info;
+ struct vf_data_storage *vf_info = NULL;
u16 func_id;
int err = 0;
@@ -38,7 +39,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
vf_info->pf_vlan, func_id,
HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d MAC\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -51,7 +52,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD,
vf_info->pf_vlan, vf_info->pf_qos,
vf_id);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to add VF %d VLAN_QOS\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -62,7 +63,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_vf_tx_rate(nic_io->hwdev, vf_id,
vf_info->max_rate,
vf_info->min_rate);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d max rate %u, min rate %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->max_rate,
vf_info->min_rate);
@@ -84,7 +85,7 @@ static int register_vf_msg_handler(struct hinic3_nic_io *nic_io, u16 vf_id)
}
err = hinic3_init_vf_config(nic_io, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].registered = true;
@@ -137,6 +138,9 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
int err;
+ if (!vf_info)
+ return -EINVAL;
+
if (register_vf->op_register) {
vf_info->support_extra_feature = register_vf->support_extra_feature;
err = register_vf_msg_handler(nic_io, vf_id);
@@ -145,7 +149,7 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
vf_info->support_extra_feature = 0;
}
- if (err)
+ if (err != 0)
register_info->msg_head.status = EFAULT;
*out_size = sizeof(*register_info);
@@ -157,6 +161,8 @@ void hinic3_unregister_vf(struct hinic3_nic_io *nic_io, u16 vf_id)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vf_info)
+ return;
unregister_vf_msg_handler(nic_io, vf_id);
vf_info->support_extra_feature = 0;
}
@@ -181,14 +187,21 @@ static int hinic3_get_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
void *buf_out, u16 *out_size)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf);
+ struct hinic3_port_mac_set *mac_in =
+ (struct hinic3_port_mac_set *)buf_in;
struct hinic3_port_mac_set *mac_info = buf_out;
int err;
+ if (!mac_info || !vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (HINIC3_SUPPORT_VF_MAC(nic_io->hwdev)) {
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_GET_MAC, buf_in,
in_size, buf_out, out_size);
- if (!err) {
+ if (err == 0) {
if (is_zero_ether_addr(mac_info->mac))
ether_addr_copy(mac_info->mac, vf_info->drv_mac_addr);
}
@@ -211,6 +224,11 @@ static int hinic3_set_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -247,6 +265,10 @@ static int hinic3_del_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -283,10 +305,13 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
struct hinic3_port_mac_update *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
if (!is_valid_ether_addr(mac_in->new_mac)) {
nic_err(nic_io->dev_hdl, "Update VF MAC is invalid.\n");
return -EINVAL;
}
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
#ifndef __VMWARE__
if (vf_info->use_specified_mac && !vf_info->trust) {
@@ -301,7 +326,7 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
HW_VF_ID_TO_OS(vf),
HINIC_CFG_VF_MAC_CHANGED,
(void *)mac_in->new_mac);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to config VF %d MAC request, err: %d\n",
HW_VF_ID_TO_OS(vf), err);
return err;
@@ -359,10 +384,11 @@ static int _l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u16 in_size, void *buf_out, u16 *out_size,
u16 channel)
{
- u32 i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
+ int i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_cmd_handler[i].cmd)
cmd_to_pf = true;
@@ -397,13 +423,15 @@ int hinic3_pf_mbox_handler(void *hwdev,
u16 vf_id, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- u32 index, cmd_size = ARRAY_LEN(vf_cmd_handler);
+ int index, cmd_size = ARRAY_LEN(vf_cmd_handler);
struct hinic3_nic_io *nic_io = NULL;
if (!hwdev)
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (index = 0; index < cmd_size; index++) {
if (cmd == vf_cmd_handler[index].cmd)
@@ -460,10 +488,14 @@ void hinic3_notify_dcb_state_event(struct hinic3_nic_io *nic_io,
static void dcb_state_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- struct hinic3_cmd_vf_dcb_state *vf_dcb;
- struct hinic3_nic_io *nic_io;
+ struct hinic3_cmd_vf_dcb_state *vf_dcb = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
vf_dcb = buf_in;
if (!vf_dcb)
@@ -479,6 +511,10 @@ static void tx_pause_excp_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*excp_info)) {
nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
@@ -501,6 +537,10 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_event_info event_info = {0};
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*active_info)) {
nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
@@ -515,6 +555,36 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
hinic3_event_callback(nic_io->hwdev, &event_info);
}
+static void outband_vlan_cfg_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out,
+ u16 *out_size)
+{
+ struct hinic3_outband_cfg_info *outband_cfg_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info = {0};
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ nic_info(nic_io->dev_hdl, "outband vlan cfg event received\n");
+
+ if (in_size != sizeof(*outband_cfg_info)) {
+ nic_err(nic_io->dev_hdl, "outband cfg info invalid in_size: %u, should be %lu\n",
+ in_size, sizeof(*outband_cfg_info));
+ return;
+ }
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = EVENT_NIC_OUTBAND_CFG;
+ memcpy((void *)event_info.event_data,
+ outband_cfg_info, sizeof(*outband_cfg_info));
+
+ hinic3_event_callback(nic_io->hwdev, &event_info);
+}
+
static const struct nic_event_handler nic_cmd_handler[] = {
{
.cmd = HINIC3_NIC_CMD_VF_COS,
@@ -529,6 +599,11 @@ static const struct nic_event_handler nic_cmd_handler[] = {
.cmd = HINIC3_NIC_CMD_BOND_ACTIVE_NOTICE,
.handler = bond_active_event_handler,
},
+
+ {
+ .cmd = HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ .handler = outband_vlan_cfg_event_handler,
+ },
};
static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
@@ -543,6 +618,8 @@ static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (i = 0; i < size; i++) {
if (cmd == nic_cmd_handler[i].cmd) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
index a827f44..f3bb4c5 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
@@ -16,9 +16,10 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
-#include "hinic3_nic_io.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_nic_cmdq.h"
+#include "hinic3_nic_io.h"
#define HINIC3_DEAULT_TX_CI_PENDING_LIMIT 1
#define HINIC3_DEAULT_TX_CI_COALESCING_TIME 1
@@ -35,7 +36,7 @@ MODULE_PARM_DESC(tx_coalescing_time, "TX CI coalescing parameter coalescing_time
static unsigned char rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
module_param(rq_wqe_type, byte, 0444);
-MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 0-8Bytes, 1-16Bytes, 2-32Bytes (default=1)");
+MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 1-16Bytes, 2-32Bytes (default=2)");
/*lint +e806*/
static u32 tx_drop_thd_on = HINIC3_DEAULT_DROP_THD_ON;
@@ -46,7 +47,7 @@ static u32 tx_drop_thd_off = HINIC3_DEAULT_DROP_THD_OFF;
module_param(tx_drop_thd_off, uint, 0644);
MODULE_PARM_DESC(tx_drop_thd_off, "TX parameter drop_thd_off (default=0)");
/* performance: ci addr RTE_CACHE_SIZE(64B) alignment */
-#define HINIC3_CI_Q_ADDR_SIZE (64)
+#define HINIC3_CI_Q_ADDR_SIZE (64U)
#define CI_TABLE_SIZE(num_qps, pg_sz) \
(ALIGN((num_qps) * HINIC3_CI_Q_ADDR_SIZE, pg_sz))
@@ -255,7 +256,7 @@ static int hinic3_create_sq(struct hinic3_nic_io *nic_io, struct hinic3_io_queue
err = hinic3_wq_create(nic_io->hwdev, &sq->wq, sq_depth,
(u16)BIT(HINIC3_SQ_WQEBB_SHIFT));
- if (err) {
+ if (err != 0) {
sdk_err(nic_io->dev_hdl, "Failed to create tx queue(%u) wq\n",
q_id);
return err;
@@ -291,13 +292,22 @@ static int hinic3_create_rq(struct hinic3_nic_io *nic_io, struct hinic3_io_queue
{
int err;
- rq->wqe_type = (u8)(hinic3_get_rq_wqe_type(nic_io->hwdev));
+ /* rq_wqe_type Only support type 1-16Bytes, 2-32Bytes */
+ if (rq_wqe_type != HINIC3_NORMAL_RQ_WQE &&
+ rq_wqe_type != HINIC3_EXTEND_RQ_WQE) {
+ sdk_warn(nic_io->dev_hdl, "Module Parameter rq_wqe_type value %d is out of range: [%d, %d].",
+ rq_wqe_type, HINIC3_NORMAL_RQ_WQE,
+ HINIC3_EXTEND_RQ_WQE);
+ rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
+ }
+
+ rq->wqe_type = rq_wqe_type;
rq->q_id = q_id;
rq->msix_entry_idx = rq_msix_idx;
err = hinic3_wq_create(nic_io->hwdev, &rq->wq, rq_depth,
(u16)BIT(HINIC3_RQ_WQEBB_SHIFT + rq->wqe_type));
- if (err) {
+ if (err != 0) {
sdk_err(nic_io->dev_hdl, "Failed to create rx queue(%u) wq\n",
q_id);
return err;
@@ -318,14 +328,14 @@ static int create_qp(struct hinic3_nic_io *nic_io, struct hinic3_io_queue *sq,
int err;
err = hinic3_create_sq(nic_io, sq, q_id, sq_depth, qp_msix_idx);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to create sq, qid: %u\n",
q_id);
return err;
}
err = hinic3_create_rq(nic_io, rq, q_id, rq_depth, qp_msix_idx);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to create rq, qid: %u\n",
q_id);
goto create_rq_err;
@@ -364,14 +374,14 @@ int hinic3_init_nicio_res(void *hwdev)
nic_io->max_qps = hinic3_func_max_qnum(hwdev);
err = hinic3_alloc_db_addr(hwdev, &db_base, NULL);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to allocate doorbell for sqs\n");
goto alloc_sq_db_fail;
}
nic_io->sqs_db_addr = (u8 *)db_base;
err = hinic3_alloc_db_addr(hwdev, &db_base, NULL);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to allocate doorbell for rqs\n");
goto alloc_rq_db_fail;
}
@@ -474,7 +484,7 @@ int hinic3_alloc_qps(void *hwdev, struct irq_info *qps_msix_arry,
for (q_id = 0; q_id < num_qps; q_id++) {
err = create_qp(nic_io, &sqs[q_id], &rqs[q_id], q_id, qp_params->sq_depth,
qp_params->rq_depth, qps_msix_arry[q_id].msix_entry_idx);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to allocate qp %u, err: %d\n", q_id, err);
goto create_qp_err;
}
@@ -599,14 +609,14 @@ int hinic3_create_qps(void *hwdev, u16 num_qp, u32 sq_depth, u32 rq_depth,
}
err = hinic3_init_nicio_res(hwdev);
- if (err)
+ if (err != 0)
return err;
qp_params.num_qps = num_qp;
qp_params.sq_depth = sq_depth;
qp_params.rq_depth = rq_depth;
err = hinic3_alloc_qps(hwdev, qps_msix_arry, &qp_params);
- if (err) {
+ if (err != 0) {
hinic3_deinit_nicio_res(hwdev);
nic_err(nic_io->dev_hdl,
"Failed to allocate qps, err: %d\n", err);
@@ -906,11 +916,11 @@ static int init_qp_ctxts(struct hinic3_nic_io *nic_io)
int err;
err = init_sq_ctxts(nic_io);
- if (err)
+ if (err != 0)
return err;
err = init_rq_ctxts(nic_io);
- if (err)
+ if (err != 0)
return err;
return 0;
@@ -1026,14 +1036,14 @@ int hinic3_init_qp_ctxts(void *hwdev)
return -EFAULT;
err = init_qp_ctxts(nic_io);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to init QP ctxts\n");
return err;
}
/* clean LRO/TSO context space */
err = clean_qp_offload_ctxt(nic_io);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to clean qp offload ctxts\n");
return err;
}
@@ -1042,13 +1052,13 @@ int hinic3_init_qp_ctxts(void *hwdev)
err = hinic3_set_root_ctxt(hwdev, rq_depth, nic_io->sq[0].wq.q_depth,
nic_io->rx_buff_len, HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set root context\n");
return err;
}
err = init_sq_ci_ctxts(nic_io);
- if (err)
+ if (err != 0)
goto clean_root_ctxt;
if (HINIC3_SUPPORT_RX_COMPACT_CQE(hwdev)) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
index 37f923d..c5e02ad 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
@@ -317,7 +317,7 @@ static inline void hinic3_write_db(struct hinic3_io_queue *queue, int cos,
wmb(); /* Write all before the doorbell */
- writeq(*((u64 *)&db), DB_ADDR(queue, pi));
+ writeq(*((u64 *)(u8 *)&db), DB_ADDR(queue, pi));
}
struct hinic3_dyna_qp_params {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
index 78d943d..9ea93a0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
@@ -32,7 +32,7 @@ struct hinic3_prof_adapter nic_prof_adap_objs[] = {
void hinic3_init_nic_prof_adapter(struct hinic3_nic_dev *nic_dev)
{
- u16 num_adap = ARRAY_SIZE(nic_prof_adap_objs);
+ int num_adap = ARRAY_LEN(nic_prof_adap_objs);
nic_dev->prof_adap = hinic3_prof_init(nic_dev, nic_prof_adap_objs, num_adap,
(void *)&nic_dev->prof_attr);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
index 6302fb8..dc4bb9e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
@@ -430,7 +430,8 @@ hinic3_dynamic_lookup_tcam_filter(struct hinic3_nic_dev *nic_dev,
list_for_each_entry(tmp,
&tcam_info->tcam_dynamic_info.tcam_dynamic_list,
block_list)
- if (tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)
+ if (tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE ||
+ !tmp)
break;
if (!tmp || tmp->dynamic_index_cnt >= HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) {
@@ -512,7 +513,7 @@ static int hinic3_add_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, queue: %d, tcam_rule_nums: %d succeed\n",
+ "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, queue: %u, tcam_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev),
tcam_filter->dynamic_block_id, index, fdir_tcam_rule->index,
fdir_tcam_rule->data.qid, tcam_info->tcam_rule_nums + 1);
@@ -579,7 +580,7 @@ static int hinic3_del_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, local_rules_nums: %d, global_rule_nums: %d succeed\n",
+ "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, local_rules_nums: %u, global_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev), dynamic_block_id,
tcam_filter->index, index, tmp->dynamic_index_cnt - 1,
tcam_info->tcam_rule_nums - 1);
@@ -605,7 +606,7 @@ static inline struct hinic3_tcam_filter *
hinic3_tcam_filter_lookup(const struct list_head *filter_list,
struct tag_tcam_key *key)
{
- struct hinic3_tcam_filter *iter;
+ struct hinic3_tcam_filter *iter = NULL;
list_for_each_entry(iter, filter_list, tcam_filter_list) {
if (memcmp(key, &iter->tcam_key,
@@ -630,7 +631,7 @@ static int hinic3_remove_one_rule(struct hinic3_nic_dev *nic_dev,
struct hinic3_ethtool_rx_flow_rule *eth_rule)
{
struct hinic3_tcam_info *tcam_info = &nic_dev->tcam;
- struct hinic3_tcam_filter *tcam_filter;
+ struct hinic3_tcam_filter *tcam_filter = NULL;
struct nic_tcam_cfg_rule fdir_tcam_rule;
struct tag_tcam_key tcam_key;
int err;
@@ -751,7 +752,7 @@ static int validate_flow(struct hinic3_nic_dev *nic_dev,
{
if (fs->location >= MAX_NUM_OF_ETHTOOL_NTUPLE_RULES) {
nicif_err(nic_dev, drv, nic_dev->netdev, "loc exceed limit[0,%lu]\n",
- MAX_NUM_OF_ETHTOOL_NTUPLE_RULES);
+ MAX_NUM_OF_ETHTOOL_NTUPLE_RULES - 1);
return -EINVAL;
}
@@ -872,7 +873,7 @@ int hinic3_ethtool_get_flow(const struct hinic3_nic_dev *nic_dev,
int hinic3_ethtool_get_all_flows(const struct hinic3_nic_dev *nic_dev,
struct ethtool_rxnfc *info, u32 *rule_locs)
{
- int idx = 0;
+ u32 idx = 0;
struct hinic3_ethtool_rx_flow_rule *eth_rule = NULL;
if (!HINIC3_SUPPORT_FDIR(nic_dev->hwdev)) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h b/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
index a93f3b6..9202218 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
@@ -38,13 +38,12 @@ struct hinic3_prof_adapter {
#define LLT_STATIC_DEF_SAVED
#endif
-/*lint -save -e661 */
static inline struct hinic3_prof_adapter *
hinic3_prof_init(void *device, struct hinic3_prof_adapter *adap_objs, int num_adap,
void **prof_attr)
{
struct hinic3_prof_adapter *prof_obj = NULL;
- u16 i;
+ int i;
for (i = 0; i < num_adap; i++) {
prof_obj = &adap_objs[i];
@@ -68,7 +67,6 @@ static inline void hinic3_prof_deinit(struct hinic3_prof_adapter *prof_obj, void
prof_obj->deinit(prof_attr);
}
-/*lint -restore*/
/* module-level interface */
#ifdef CONFIG_MODULE_PROF
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
index e4705c2..9b4eca8 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/dcbnl.h>
+#include <linux/init.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -23,8 +24,7 @@
#include "hinic3_hw.h"
#include "hinic3_rss.h"
-/*lint -e806*/
-static u16 num_qps;
+static u16 num_qps = 0;
module_param(num_qps, ushort, 0444);
MODULE_PARM_DESC(num_qps, "Number of Queue Pairs (default=0)");
@@ -104,88 +104,84 @@ static int hinic3_get_rq2iq_map(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev, u8 num_cos, u32 *indir)
+static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev,
+ u8 group_num, u32 *indir)
{
- u16 k, group_size, start_qid = 0, qp_num = 0;
- int i = 0;
- u8 j, cur_cos = 0, default_cos;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ u16 k, group_size, start_qid = 0, cur_cos_qnum = 0;
+ u32 i = 0;
+ u8 j, cur_cos = 0, group = 0;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
- if (num_cos == 0) {
+ if (group_num == 0) {
for (i = 0; i < NIC_RSS_INDIR_SIZE; i++)
indir[i] = i % nic_dev->q_params.num_qps;
} else {
- group_size = NIC_RSS_INDIR_SIZE / num_cos;
-
- for (j = 0; j < num_cos; j++) {
- while (cur_cos < NIC_DCB_COS_MAX &&
- nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos] == 0)
- cur_cos++;
-
- if (cur_cos >= NIC_DCB_COS_MAX) {
- if (BIT(nic_dev->hw_dcb_cfg.default_cos) & valid_cos_map)
- default_cos = nic_dev->hw_dcb_cfg.default_cos;
- else
- default_cos = (u8)fls(valid_cos_map) - 1;
+ group_size = NIC_RSS_INDIR_SIZE / group_num;
+
+ for (group = 0; group < group_num; group++) {
+ cur_cos = dcb->hw_dcb_cfg.default_cos;
+ for (j = 0; j < NIC_DCB_COS_MAX; j++) {
+ if ((BIT(j) & valid_cos_map) != 0) {
+ cur_cos = j;
+ valid_cos_map -= (u8)BIT(j);
+ break;
+ }
+ }
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[default_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[default_cos];
+ cur_cos_qnum = dcb->hw_dcb_cfg.cos_qp_num[cur_cos];
+ if (cur_cos_qnum > 0) {
+ start_qid =
+ dcb->hw_dcb_cfg.cos_qp_offset[cur_cos];
} else {
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[cur_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos];
+ start_qid = cur_cos % nic_dev->q_params.num_qps;
+ /* Ensure that the offset of start_id is 0. */
+ cur_cos_qnum = 1;
}
for (k = 0; k < group_size; k++)
- indir[i++] = start_qid + k % qp_num;
-
- cur_cos++;
+ indir[i++] = start_qid + k % cur_cos_qnum;
}
}
}
-/*lint -e528*/
int hinic3_rss_init(struct hinic3_nic_dev *nic_dev, u8 *rq2iq_map, u32 map_size, u8 dcb_en)
{
struct net_device *netdev = nic_dev->netdev;
- u8 i, cos_num;
- u8 cos_map[NIC_DCB_UP_MAX] = {0};
- u8 cfg_map[NIC_DCB_UP_MAX] = {0};
+ u8 i, group_num, cos_bitmap, group = 0;
+ u8 cos_group[NIC_DCB_UP_MAX] = {0};
int err;
- if (dcb_en) {
- cos_num = hinic3_get_dev_user_cos_num(nic_dev);
+ if (dcb_en != 0) {
+ group_num = (u8)roundup_pow_of_two(
+ hinic3_get_dev_user_cos_num(nic_dev));
- if (nic_dev->hw_dcb_cfg.trust == 0) {
- memcpy(cfg_map, nic_dev->hw_dcb_cfg.pcp2cos, sizeof(cfg_map));
- } else if (nic_dev->hw_dcb_cfg.trust == 1) {
- for (i = 0; i < NIC_DCB_UP_MAX; i++)
- cfg_map[i] = nic_dev->hw_dcb_cfg.dscp2cos[i * NIC_DCB_DSCP_NUM];
- }
-#define COS_CHANGE_OFFSET 4
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[COS_CHANGE_OFFSET + i] = cfg_map[i];
-
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[i] = cfg_map[NIC_DCB_UP_MAX - (i + 1)];
+ cos_bitmap = hinic3_get_dev_valid_cos_map(nic_dev);
- while (cos_num & (cos_num - 1))
- cos_num++;
+ for (i = 0; i < NIC_DCB_UP_MAX; i++) {
+ if ((BIT(i) & cos_bitmap) != 0)
+ cos_group[NIC_DCB_UP_MAX - i - 1] = group++;
+ else
+ cos_group[NIC_DCB_UP_MAX - i - 1] =
+ group_num - 1;
+ }
} else {
- cos_num = 0;
+ group_num = 0;
}
- err = hinic3_set_hw_rss_parameters(netdev, 1, cos_num, cos_map, dcb_en);
+ err = hinic3_set_hw_rss_parameters(netdev, 1, group_num,
+ cos_group, dcb_en);
if (err)
return err;
- err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps, cos_num, cos_map,
- NIC_DCB_UP_MAX, nic_dev->rss_indir, rq2iq_map, map_size);
+ err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps,
+ group_num, cos_group, NIC_DCB_UP_MAX,
+ nic_dev->rss_indir, rq2iq_map, map_size);
if (err)
nicif_err(nic_dev, drv, netdev, "Failed to get rq map\n");
return err;
}
-/*lint -e528*/
void hinic3_rss_deinit(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -246,11 +242,28 @@ discard_user_rss_indir:
hinic3_set_default_rss_indir(netdev);
}
+#ifdef HAVE_HOT_REPLACE_FUNC
+bool partition_slave_doing_hotupgrade(void)
+{
+ return get_partition_role() && partition_doing_hotupgrade();
+}
+#endif
+
static void decide_num_qps(struct hinic3_nic_dev *nic_dev)
{
u16 tmp_num_qps = nic_dev->max_qps;
u16 num_cpus = 0;
+ u16 max_num_cpus;
int i, node;
+ int is_in_kexec = vram_get_kexec_flag();
+
+ if (is_in_kexec != 0) {
+ nic_dev->q_params.num_qps = nic_dev->nic_vram->vram_num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Os hotreplace use vram to init num qps 1:%u 2:%u\n",
+ nic_dev->q_params.num_qps, nic_dev->nic_vram->vram_num_qps);
+ return;
+ }
if (nic_dev->nic_cap.default_num_queues != 0 &&
nic_dev->nic_cap.default_num_queues < nic_dev->max_qps)
@@ -258,16 +271,29 @@ static void decide_num_qps(struct hinic3_nic_dev *nic_dev)
MOD_PARA_VALIDATE_NUM_QPS(nic_dev, num_qps, tmp_num_qps);
- for (i = 0; i < (int)num_online_cpus(); i++) {
+#ifdef HAVE_HOT_REPLACE_FUNC
+ if (partition_slave_doing_hotupgrade())
+ max_num_cpus = (u16)num_present_cpus();
+ else
+ max_num_cpus = (u16)num_online_cpus();
+#else
+ max_num_cpus = (u16)num_online_cpus();
+#endif
+
+ for (i = 0; i < max_num_cpus; i++) {
node = (int)cpu_to_node(i);
if (node == dev_to_node(&nic_dev->pdev->dev))
num_cpus++;
}
if (!num_cpus)
- num_cpus = (u16)num_online_cpus();
+ num_cpus = max_num_cpus;
nic_dev->q_params.num_qps = (u16)min_t(u16, tmp_num_qps, num_cpus);
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "init num qps 1:%u 2:%u\n",
+ nic_dev->q_params.num_qps, nic_dev->nic_vram->vram_num_qps);
}
static void copy_value_to_rss_hkey(struct hinic3_nic_dev *nic_dev,
@@ -312,6 +338,8 @@ static int alloc_rss_resource(struct hinic3_nic_dev *nic_dev)
nic_dev->rss_indir = kzalloc(sizeof(u32) * NIC_RSS_INDIR_SIZE, GFP_KERNEL);
if (!nic_dev->rss_indir) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to alloc memory for rss_indir\n");
kfree(nic_dev->rss_hkey);
nic_dev->rss_hkey = NULL;
return -ENOMEM;
@@ -322,7 +350,6 @@ static int alloc_rss_resource(struct hinic3_nic_dev *nic_dev)
return 0;
}
-/*lint -e528*/
void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -361,6 +388,7 @@ void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
set_q_params:
clear_bit(HINIC3_RSS_ENABLE, &nic_dev->flags);
nic_dev->q_params.num_qps = nic_dev->max_qps;
+ nic_dev->nic_vram->vram_num_qps = nic_dev->max_qps;
}
static int hinic3_config_rss_hw_resource(struct hinic3_nic_dev *nic_dev,
@@ -754,6 +782,7 @@ int hinic3_set_channels(struct net_device *netdev,
nic_dev->q_params.num_qps = (u16)count;
}
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
return 0;
}
@@ -814,7 +843,7 @@ int hinic3_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
int err = 0;
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
@@ -921,7 +950,7 @@ int hinic3_get_rxfh_indir(struct net_device *netdev, u32 *indir)
indir = indir1->ring_index;
#endif
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
index 071418d..4f4b18c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
@@ -15,14 +15,15 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_nic_cfg.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_hw.h"
#include "hinic3_nic.h"
#include "hinic3_nic_cmdq.h"
#include "hinic3_common.h"
static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
- u8 *key)
+ u8 *key, u16 key_size)
{
struct hinic3_cmd_rss_hash_key hash_key;
u16 out_size = sizeof(hash_key);
@@ -33,7 +34,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
hash_key.opcode = opcode;
if (opcode == HINIC3_CMD_OP_SET)
- memcpy(hash_key.key, key, NIC_RSS_KEY_SIZE);
+ memcpy(hash_key.key, key, key_size);
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_CFG_RSS_HASH_KEY,
@@ -47,7 +48,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
}
if (opcode == HINIC3_CMD_OP_GET)
- memcpy(key, hash_key.key, NIC_RSS_KEY_SIZE);
+ memcpy(key, hash_key.key, key_size);
return 0;
}
@@ -61,8 +62,12 @@ int hinic3_rss_set_hash_key(void *hwdev, const u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memcpy(hash_key, key, NIC_RSS_KEY_SIZE);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET, hash_key);
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET,
+ hash_key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
@@ -73,7 +78,11 @@ int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET, key);
+ if (!nic_io)
+ return -EINVAL;
+
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET,
+ key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
@@ -89,6 +98,7 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
if (nic_io == NULL)
return -EINVAL;
+
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (cmd_buf == NULL) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -159,6 +169,8 @@ static int hinic3_cmdq_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
@@ -210,6 +222,9 @@ static int hinic3_mgmt_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&ctx_tbl, 0, sizeof(ctx_tbl));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
ctx |= HINIC3_RSS_TYPE_SET(1, VALID) |
@@ -259,6 +274,8 @@ int hinic3_get_rss_type(void *hwdev, struct nic_rss_type *rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&ctx_tbl, 0, sizeof(struct hinic3_rss_context_table));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
@@ -292,6 +309,9 @@ static int hinic3_rss_cfg_hash_engine(struct hinic3_nic_io *nic_io, u8 opcode,
u16 out_size = sizeof(hash_type);
int err;
+ if (!nic_io)
+ return -EINVAL;
+
memset(&hash_type, 0, sizeof(struct hinic3_cmd_rss_engine_type));
hash_type.func_id = hinic3_global_func_id(nic_io->hwdev);
@@ -325,6 +345,9 @@ int hinic3_rss_set_hash_engine(void *hwdev, u8 type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_SET, &type);
}
@@ -336,6 +359,9 @@ int hinic3_rss_get_hash_engine(void *hwdev, u8 *type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_GET, type);
}
@@ -351,6 +377,9 @@ int hinic3_rss_cfg(void *hwdev, u8 rss_en, u8 cos_num, u8 *prio_tc, u16 num_qps)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&rss_cfg, 0, sizeof(struct hinic3_cmd_rss_config));
rss_cfg.func_id = hinic3_global_func_id(hwdev);
rss_cfg.rss_en = rss_en;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
index f8a866d..9027a3d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
@@ -21,6 +21,7 @@
#include <linux/ipv6.h>
#include <linux/module.h>
#include <linux/compiler.h>
+#include <linux/filter.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -63,19 +64,31 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
struct pci_dev *pdev = nic_dev->pdev;
struct page *page = rx_info->page;
dma_addr_t dma = rx_info->buf_dma_addr;
+ u32 page_offset = 0;
if (likely(dma))
return true;
/* alloc new page for storage */
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page = page_pool_alloc_frag(rx_info->page_pool, &page_offset,
+ nic_dev->rx_buff_len,
+ GFP_ATOMIC | __GFP_COLD | __GFP_COMP);
+ if (unlikely(!page))
+ return false;
+ dma = page_pool_get_dma_addr(page);
+ goto set_rx_info;
+ }
+#endif
page = alloc_pages_node(NUMA_NO_NODE, GFP_ATOMIC | __GFP_COLD |
__GFP_COMP, nic_dev->page_order);
if (unlikely(!page))
return false;
/* map page for use */
- dma = dma_map_page(&pdev->dev, page, 0, nic_dev->dma_rx_buff_size,
- DMA_FROM_DEVICE);
+ dma = dma_map_page(&pdev->dev, page, page_offset,
+ nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
/* if mapping failed free memory back to system since
* there isn't much point in holding memory we can't use
*/
@@ -83,10 +96,12 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
__free_pages(page, nic_dev->page_order);
return false;
}
+ goto set_rx_info;
+set_rx_info:
rx_info->page = page;
rx_info->buf_dma_addr = dma;
- rx_info->page_offset = 0;
+ rx_info->page_offset = page_offset;
return true;
}
@@ -108,7 +123,7 @@ static u32 hinic3_rx_fill_wqe(struct hinic3_rxq *rxq)
/* unit of cqe length is 16B */
hinic3_set_sge(&rq_wqe->extend_wqe.cqe_sect.sge,
rx_info->cqe_dma,
- (sizeof(struct hinic3_rq_cqe) >>
+ (HINIC3_CQE_LEN >>
HINIC3_CQE_SIZE_SHIFT));
/* use fixed len */
rq_wqe->extend_wqe.buf_desc.sge.len =
@@ -169,7 +184,7 @@ static u32 hinic3_rx_fill_buffers(struct hinic3_rxq *rxq)
if (likely(i)) {
hinic3_write_db(rxq->rq,
- rxq->q_id & 3,
+ rxq->q_id & (NIC_RX_DB_COS_MAX - 1),
RQ_CFLAG_DP,
(u16)((u32)rxq->next_to_update <<
rxq->rq->wqe_type));
@@ -206,6 +221,18 @@ static void hinic3_rx_free_buffers(struct hinic3_nic_dev *nic_dev, u32 q_depth,
for (i = 0; i < q_depth; i++) {
rx_info = &rx_info_arr[i];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ if (rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool,
+ rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ }
+ continue;
+ }
+#endif
+
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev,
rx_info->buf_dma_addr,
@@ -265,8 +292,15 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
DMA_FROM_DEVICE);
if (size <= HINIC3_RX_HDR_SIZE && !skb_is_nonlinear(skb)) {
- memcpy(__skb_put(skb, size), va + offset,
- ALIGN(size, sizeof(long))); /*lint !e666*/
+ __skb_put_data(skb, va + offset, size);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool,
+ page, false);
+ return false;
+ }
+#endif
/* page is not reserved, we can reuse buffer as-is */
if (likely(page_to_nid(page) == numa_node_id()))
@@ -274,25 +308,38 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
/* this page cannot be reused so discard it */
put_page(page);
- return false;
+ goto discard_page;
}
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
- (int)(rx_info->page_offset + offset), (int)size, rxq->buf_len);
+ (int)(rx_info->page_offset + offset), (int)size,
+ rxq->buf_len);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
/* avoid re-using remote pages */
if (unlikely(page_to_nid(page) != numa_node_id()))
- return false;
+ goto discard_page;
/* if we are only owner of page we can reuse it */
if (unlikely(page_count(page) != 1))
- return false;
+ goto discard_page;
/* flip page offset to other buffer */
rx_info->page_offset ^= rxq->buf_len;
get_page(page);
return true;
+
+discard_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
}
static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
@@ -338,10 +385,6 @@ static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
if (likely(hinic3_add_rx_frag(rxq, rx_info, skb, frag_size, tmp_pkt_offset))) {
hinic3_reuse_rx_page(rxq, rx_info);
- } else {
- /* we are not reusing the buffer so unmap it */
- dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
- rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
}
/* clear contents of buffer_info */
rx_info->buf_dma_addr = 0;
@@ -486,9 +529,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
protocol = hdr.eth->h_proto;
/* L2 header */
- /*lint -save -e778*/
if (protocol == htons(ETH_P_8021_AD) ||
- protocol == htons(ETH_P_8021_Q)) { /*lint -restore*/
+ protocol == htons(ETH_P_8021_Q)) {
if (unlikely(max_len < ETH_HLEN + VLAN_HLEN))
return max_len;
@@ -500,9 +542,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
}
/* L3 header */
- /*lint -save -e778*/
switch (protocol) {
- case htons(ETH_P_IP): /*lint -restore*/
+ case htons(ETH_P_IP):
if ((int)(hdr.data - data) >
(int)(max_len - sizeof(struct iphdr)))
return max_len;
@@ -713,7 +754,10 @@ static inline void hinic3_lro_set_gso_params(struct sk_buff *skb, u16 num_lro)
}
#ifdef HAVE_XDP_SUPPORT
-enum hinic3_xdp_pkt {
+enum hinic3_xdp_status {
+ // bpf_prog status
+ HINIC3_XDP_PROG_EMPTY,
+ // pkt action
HINIC3_XDP_PKT_PASS,
HINIC3_XDP_PKT_DROP,
};
@@ -724,9 +768,15 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
while (weqbb_num) {
rx_info = &rxq->rx_info[rxq->cons_idx & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool)
+ goto discard_direct;
+#endif
if (likely(page_to_nid(rx_info->page) == numa_node_id()))
hinic3_reuse_rx_page(rxq, rx_info);
+ goto discard_direct;
+discard_direct:
rx_info->buf_dma_addr = 0;
rx_info->page = NULL;
rxq->cons_idx++;
@@ -736,11 +786,11 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
}
}
-int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
+int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len, struct xdp_buff *xdp)
{
struct bpf_prog *xdp_prog = NULL;
struct hinic3_rx_info *rx_info = NULL;
- struct xdp_buff xdp;
+ struct net_device *netdev = rxq->netdev;
int result = HINIC3_XDP_PKT_PASS;
u16 weqbb_num = 1; /* xdp can only use one rx_buff */
u8 *va = NULL;
@@ -748,13 +798,14 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
rcu_read_lock();
xdp_prog = READ_ONCE(rxq->xdp_prog);
- if (!xdp_prog)
+ if (!xdp_prog) {
+ result = HINIC3_XDP_PROG_EMPTY;
goto unlock_rcu;
+ }
if (unlikely(pkt_len > rxq->buf_len)) {
RXQ_STATS_INC(rxq, xdp_large_pkt);
- weqbb_num = (u16)(pkt_len >> rxq->rx_buff_shift) +
- ((pkt_len & (rxq->buf_len - 1)) ? 1 : 0);
+ weqbb_num = HINIC3_GET_SGE_NUM(pkt_len, rxq);
result = HINIC3_XDP_PKT_DROP;
goto xdp_out;
}
@@ -765,26 +816,27 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
dma_sync_single_range_for_cpu(rxq->dev, rx_info->buf_dma_addr,
rx_info->page_offset,
rxq->buf_len, DMA_FROM_DEVICE);
- xdp.data = va;
- xdp.data_hard_start = xdp.data;
- xdp.data_end = xdp.data + pkt_len;
+ xdp->data = va;
+ xdp->data_hard_start = xdp->data;
+ xdp->data_end = xdp->data + pkt_len;
#ifdef HAVE_XDP_FRAME_SZ
- xdp.frame_sz = rxq->buf_len;
+ xdp->frame_sz = rxq->buf_len;
#endif
#ifdef HAVE_XDP_DATA_META
- xdp_set_data_meta_invalid(&xdp);
+ xdp_set_data_meta_invalid(xdp);
#endif
- prefetchw(xdp.data_hard_start);
- act = bpf_prog_run_xdp(xdp_prog, &xdp);
+ prefetchw(xdp->data_hard_start);
+ act = bpf_prog_run_xdp(xdp_prog, xdp);
switch (act) {
case XDP_PASS:
+ result = HINIC3_XDP_PKT_PASS;
break;
case XDP_DROP:
result = HINIC3_XDP_PKT_DROP;
break;
default:
result = HINIC3_XDP_PKT_DROP;
- bpf_warn_invalid_xdp_action(rxq->netdev, xdp_prog, act);
+ bpf_warn_invalid_xdp_action(netdev, xdp_prog, act);
}
xdp_out:
@@ -798,9 +850,86 @@ unlock_rcu:
return result;
}
+
+static bool hinic3_add_rx_frag_with_xdp(struct hinic3_rxq *rxq, u32 pkt_len,
+ struct hinic3_rx_info *rx_info,
+ struct sk_buff *skb, struct xdp_buff *xdp)
+{
+ struct page *page = rx_info->page;
+
+ if (pkt_len <= HINIC3_RX_HDR_SIZE) {
+ __skb_put_data(skb, xdp->data, pkt_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool, page, false);
+ return false;
+ }
+#endif
+ if (likely(page_to_nid(page) == numa_node_id()))
+ return true;
+
+ put_page(page);
+ goto umap_page;
+ }
+
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
+ (int)(rx_info->page_offset +
+ (xdp->data - xdp->data_hard_start)),
+ (int)pkt_len, rxq->buf_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
+ if (unlikely(page_to_nid(page) != numa_node_id()))
+ goto umap_page;
+ if (unlikely(page_count(page) != 1))
+ goto umap_page;
+
+ rx_info->page_offset ^= rxq->buf_len;
+ get_page(page);
+
+ return true;
+umap_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
+}
+
+static struct sk_buff *hinic3_fetch_rx_buffer_xdp(struct hinic3_rxq *rxq,
+ u32 pkt_len,
+ struct xdp_buff *xdp)
+{
+ struct sk_buff *skb;
+ struct hinic3_rx_info *rx_info;
+ u32 sw_ci;
+ bool reuse;
+
+ sw_ci = rxq->cons_idx & rxq->q_mask;
+ rx_info = &rxq->rx_info[sw_ci];
+
+ skb = netdev_alloc_skb_ip_align(rxq->netdev, HINIC3_RX_HDR_SIZE);
+ if (unlikely(!skb))
+ return NULL;
+
+ reuse = hinic3_add_rx_frag_with_xdp(rxq, pkt_len, rx_info, skb, xdp);
+ if (likely(reuse))
+ hinic3_reuse_rx_page(rxq, rx_info);
+
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+
+ rxq->cons_idx += 1;
+ rxq->delta += 1;
+
+ return skb;
+}
+
#endif
-static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_cqe_info *cqe_info)
+static int recv_one_pkt(struct hinic3_rxq *rxq,
+ struct hinic3_cqe_info *cqe_info)
{
struct sk_buff *skb = NULL;
struct net_device *netdev = rxq->netdev;
@@ -808,13 +937,25 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_cqe_info *cqe_info
#ifdef HAVE_XDP_SUPPORT
u32 xdp_status;
+ struct xdp_buff xdp = { 0 };
- xdp_status = (u32)(hinic3_run_xdp(rxq, cqe_info->pkt_len));
+ xdp_status = (u32)(hinic3_run_xdp(rxq, cqe_info->pkt_len, &xdp));
if (xdp_status == HINIC3_XDP_PKT_DROP)
return 0;
-#endif
+ // build skb
+ if (xdp_status != HINIC3_XDP_PROG_EMPTY) {
+ // xdp_prog configured, build skb with xdp
+ skb = hinic3_fetch_rx_buffer_xdp(rxq, cqe_info->pkt_len, &xdp);
+ } else {
+ // xdp_prog not configured, build skb
+ skb = hinic3_fetch_rx_buffer(rxq, cqe_info);
+ }
+#else
+
+ // xdp is not supported
skb = hinic3_fetch_rx_buffer(rxq, cqe_info);
+#endif
if (unlikely(!skb)) {
RXQ_STATS_INC(rxq, alloc_skb_err);
return -ENOMEM;
@@ -842,7 +983,7 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_cqe_info *cqe_info
if (unlikely(test_bit(HINIC3_LP_TEST, &nic_dev->flags)))
hinic3_copy_lp_data(nic_dev, skb);
- if (cqe_info->lro_num)
+ if (cqe_info->lro_num > 1)
hinic3_lro_set_gso_params(skb, cqe_info->lro_num);
skb_record_rx_queue(skb, rxq->q_id);
@@ -1021,12 +1162,39 @@ int hinic3_rx_poll(struct hinic3_rxq *rxq, int budget)
return pkts;
}
+#ifdef HAVE_PAGE_POOL_SUPPORT
+static struct page_pool *hinic3_create_page_pool(struct hinic3_nic_dev *nic_dev,
+ u32 rq_depth,
+ struct hinic3_rx_info *rx_info_arr)
+{
+ struct page_pool_params pp_params = {
+ .flags = PP_FLAG_DMA_MAP | PP_FLAG_PAGE_FRAG | PP_FLAG_DMA_SYNC_DEV,
+ .order = nic_dev->page_order,
+ .pool_size = rq_depth * nic_dev->rx_buff_len /
+ (PAGE_SIZE << nic_dev->page_order),
+ .nid = dev_to_node(&(nic_dev->pdev->dev)),
+ .dev = &(nic_dev->pdev->dev),
+ .dma_dir = DMA_FROM_DEVICE,
+ .offset = 0,
+ .max_len = PAGE_SIZE << nic_dev->page_order,
+ };
+ struct page_pool *page_pool;
+ int i;
+
+ page_pool = nic_dev->page_pool_enabled ?
+ page_pool_create(&pp_params) : NULL;
+ for (i = 0; i < rq_depth; i++)
+ rx_info_arr[i].page_pool = page_pool;
+ return page_pool;
+}
+#endif
+
int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
u32 rq_depth, struct hinic3_dyna_rxq_res *rxqs_res)
{
struct hinic3_dyna_rxq_res *rqres = NULL;
u64 cqe_mem_size = sizeof(struct hinic3_rq_cqe) * rq_depth;
- int idx, i;
+ int idx;
u32 pkts;
u64 size;
@@ -1045,51 +1213,53 @@ int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
if (!rqres->rx_info) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx info\n", idx);
- goto err_out;
+ goto err_alloc_rx_info;
}
-
if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
rqres->cqe_start_vaddr =
- dma_zalloc_coherent(&nic_dev->pdev->dev, cqe_mem_size,
+ dma_zalloc_coherent(&nic_dev->pdev->dev,
+ cqe_mem_size,
&rqres->cqe_start_paddr,
GFP_KERNEL);
if (!rqres->cqe_start_vaddr) {
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d cqe\n", idx);
- goto err_out;
+ goto err_alloc_cqe;
}
}
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ rqres->page_pool = hinic3_create_page_pool(nic_dev, rq_depth,
+ rqres->rx_info);
+ if (nic_dev->page_pool_enabled && !rqres->page_pool) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to create rxq%d page pool\n", idx);
+ goto err_create_page_pool;
+ }
+#endif
pkts = hinic3_rx_alloc_buffers(nic_dev, rq_depth,
rqres->rx_info);
if (!pkts) {
- if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- }
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx buffers\n", idx);
- goto err_out;
+ goto err_alloc_buffers;
}
rqres->next_to_alloc = (u16)pkts;
}
return 0;
-err_out:
- for (i = 0; i < idx; i++) {
- rqres = &rxqs_res[i];
-
- hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
- if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- }
- kfree(rqres->rx_info);
- }
-
+err_alloc_buffers:
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ page_pool_destroy(rqres->page_pool);
+err_create_page_pool:
+#endif
+ dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
+ rqres->cqe_start_vaddr,
+ rqres->cqe_start_paddr);
+err_alloc_cqe:
+ kfree(rqres->rx_info);
+err_alloc_rx_info:
+ hinic3_free_rxqs_res(nic_dev, idx, rq_depth, rxqs_res);
return -ENOMEM;
}
@@ -1104,6 +1274,10 @@ void hinic3_free_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
rqres = &rxqs_res[idx];
hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rqres->page_pool)
+ page_pool_destroy(rqres->page_pool);
+#endif
if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
rqres->cqe_start_vaddr,
@@ -1191,6 +1365,7 @@ void hinic3_free_rxqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->rxqs);
+ nic_dev->rxqs = NULL;
}
int hinic3_alloc_rxqs(struct net_device *netdev)
@@ -1312,6 +1487,14 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
nic_info(&nic_dev->pdev->dev, "rxq %u restore_buf_num:%u\n", q_id, rxq->restore_buf_num);
rx_info = &rxq->rx_info[(hw_ci + rxq->q_depth - 1) & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool && rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool, rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ goto reset_rxq;
+ }
+#endif
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev, rx_info->buf_dma_addr,
nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
@@ -1322,7 +1505,9 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
__free_pages(rx_info->page, nic_dev->page_order);
rx_info->page = NULL;
}
+ goto reset_rxq;
+reset_rxq:
rxq->delta = 1;
rxq->next_to_update = (u16)((hw_ci + rxq->q_depth - 1) & rxq->q_mask);
rxq->cons_idx = (u16)((rxq->next_to_update + 1) & rxq->q_mask);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
index 586a221..480f787 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
@@ -4,6 +4,10 @@
#ifndef HINIC3_RX_H
#define HINIC3_RX_H
+#ifdef HAVE_PAGE_POOL_SUPPORT
+#include <net/page_pool/helpers.h>
+#endif
+
#include <linux/types.h>
#include <linux/device.h>
#include <linux/mm_types.h>
@@ -27,6 +31,7 @@
#define HINIC3_RX_CSUM_IPSU_OTHER_ERR BIT(8)
#define HINIC3_HEADER_DATA_UNIT 2
+#define HINIC3_CQE_LEN 32
#define HINIC3_COMPACT_CQE_8B 8
#define HINIC3_COMPACT_CQE_16B 16
@@ -35,20 +40,20 @@
#define HINIC3_RQ_CQE_INTEGRATE 1
struct hinic3_rxq_stats {
- u64 packets;
- u64 bytes;
- u64 errors;
- u64 csum_errors;
- u64 other_errors;
- u64 dropped;
- u64 xdp_dropped;
- u64 rx_buf_empty;
-
- u64 alloc_skb_err;
- u64 alloc_rx_buf_err;
- u64 xdp_large_pkt;
- u64 restore_drop_sge;
- u64 rsvd2;
+ u64 packets;
+ u64 bytes;
+ u64 errors;
+ u64 csum_errors;
+ u64 other_errors;
+ u64 dropped;
+ u64 xdp_dropped;
+ u64 rx_buf_empty;
+
+ u64 alloc_skb_err;
+ u64 alloc_rx_buf_err;
+ u64 xdp_large_pkt;
+ u64 restore_drop_sge;
+ u64 rsvd2;
#ifdef HAVE_NDO_GET_STATS64
struct u64_stats_sync syncp;
#else
@@ -62,6 +67,9 @@ struct hinic3_rx_info {
struct hinic3_rq_cqe *cqe;
dma_addr_t cqe_dma;
struct page *page;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
u32 page_offset;
u32 rsvd1;
struct hinic3_rq_wqe *rq_wqe;
@@ -102,7 +110,7 @@ struct hinic3_rxq {
u16 next_to_update;
struct device *dev; /* device for DMA mapping */
- unsigned long status;
+ u64 status;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
@@ -130,6 +138,9 @@ struct hinic3_dyna_rxq_res {
struct hinic3_rx_info *rx_info;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
};
int hinic3_alloc_rxqs(struct net_device *netdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
index bdd5a8e..d816609 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
@@ -11,10 +11,12 @@
#ifndef HINIC3_SRV_NIC_H
#define HINIC3_SRV_NIC_H
-#include "hinic3_mgmt_interface.h"
+#include <linux/netdevice.h>
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_lld.h"
+#include "nic_cfg_comm.h"
+#include "nic_mpu_cmd_defs.h"
enum hinic3_queue_type {
HINIC3_SQ,
@@ -64,6 +66,7 @@ enum hinic3_nic_event_type {
EVENT_NIC_DCB_STATE_CHANGE,
EVENT_NIC_BOND_DOWN,
EVENT_NIC_BOND_UP,
+ EVENT_NIC_OUTBAND_CFG,
};
/* *
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
index bc1a8ef..d05813e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
@@ -223,24 +223,72 @@ static void get_inner_l3_l4_type(struct sk_buff *skb, union hinic3_ip *ip,
enum sq_l3_type *l3_type, u8 *l4_proto)
{
unsigned char *exthdr = NULL;
- __be16 frag_off = 0;
if (ip->v4->version == IP4_VERSION) {
*l3_type = IPV4_PKT_WITH_CHKSUM_OFFLOAD;
*l4_proto = ip->v4->protocol;
+
+#ifdef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
+ /* inner_transport_header is wrong in centos7.0 and suse12.1 */
+ l4->hdr = ip->hdr + ((u8)ip->v4->ihl << IP_HDR_IHL_UNIT_SHIFT);
+#endif
} else if (ip->v4->version == IP6_VERSION) {
*l3_type = IPV6_PKT;
exthdr = ip->hdr + sizeof(*ip->v6);
*l4_proto = ip->v6->nexthdr;
- if (exthdr != l4->hdr)
+ if (exthdr != l4->hdr) {
+ __be16 frag_off = 0;
+#ifndef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
ipv6_skip_exthdr(skb, (int)(exthdr - skb->data),
- l4_proto, &frag_off);
+ l4_proto, &frag_off);
+#else
+ int pld_off = 0;
+
+ pld_off = ipv6_skip_exthdr(skb,
+ (int)(exthdr - skb->data),
+ l4_proto, &frag_off);
+ l4->hdr = skb->data + pld_off;
+#endif
+ }
} else {
*l3_type = UNKNOWN_L3TYPE;
*l4_proto = 0;
}
}
+static u8 hinic3_get_inner_l4_type(struct sk_buff *skb)
+{
+ enum sq_l3_type l3_type;
+ u8 l4_proto;
+ union hinic3_ip ip;
+ union hinic3_l4 l4;
+
+ ip.hdr = skb_inner_network_header(skb);
+ l4.hdr = skb_inner_transport_header(skb);
+
+ get_inner_l3_l4_type(skb, &ip, &l4, &l3_type, &l4_proto);
+
+ return l4_proto;
+}
+
+static void hinic3_set_unknown_tunnel_csum(struct sk_buff *skb)
+{
+ int csum_offset;
+ __sum16 skb_csum;
+ u8 l4_proto;
+
+ l4_proto = hinic3_get_inner_l4_type(skb);
+ /* Unsupport tunnel packet, disable csum offload */
+ skb_checksum_help(skb);
+ /* The value of csum is changed from 0xffff to 0 according to RFC1624. */
+ if (skb->ip_summed == CHECKSUM_NONE && l4_proto != IPPROTO_UDP) {
+ csum_offset = skb_checksum_start_offset(skb) + skb->csum_offset;
+ skb_csum = *(__sum16 *)(skb->data + csum_offset);
+ if (skb_csum == 0xffff)
+ *(__sum16 *)(skb->data + csum_offset) = 0;
+ }
+}
+
static int hinic3_tx_csum(struct hinic3_txq *txq, struct sk_buff *skb,
struct hinic3_offload_info *offload_info,
struct hinic3_queue_info *queue_info)
@@ -276,10 +324,9 @@ static int hinic3_tx_csum(struct hinic3_txq *txq, struct sk_buff *skb,
if (l4_proto == IPPROTO_UDP)
queue_info->udp_dp_en = 1;
- if (l4_proto != IPPROTO_UDP ||
- ((struct udphdr *)skb_transport_header(skb))->dest != VXLAN_OFFLOAD_PORT_LE) {
+ if (l4_proto != IPPROTO_UDP) {
TXQ_STATS_INC(txq, unknown_tunnel_pkt);
- skb_checksum_help(skb);
+ hinic3_set_unknown_tunnel_csum(skb);
return 0;
}
}
@@ -682,6 +729,14 @@ static netdev_tx_t hinic3_send_one_skb(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
+ /* l2nic outband vlan cfg enable */
+ if ((!skb_vlan_tag_present(skb)) &&
+ (nic_dev->nic_cap.outband_vlan_cfg_en == 1) &&
+ nic_dev->outband_cfg.outband_default_vid != 0) {
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+ (u16)nic_dev->outband_cfg.outband_default_vid);
+ }
+
offload = hinic3_tx_offload(skb, &offload_info, &queue_info, txq);
if (unlikely(offload == TX_OFFLOAD_INVALID)) {
TXQ_STATS_INC(txq, offload_cow_skb_err);
@@ -880,6 +935,7 @@ int hinic3_alloc_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
tqres->bds = kzalloc(size, GFP_KERNEL);
if (!tqres->bds) {
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc txq%d bds info\n", idx);
goto err_out;
@@ -893,7 +949,9 @@ err_out:
tqres = &txqs_res[i];
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
return -ENOMEM;
@@ -910,7 +968,9 @@ void hinic3_free_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
free_all_tx_skbs(nic_dev, sq_depth, tqres->tx_info);
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
}
@@ -982,6 +1042,7 @@ void hinic3_free_txqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->txqs);
+ nic_dev->txqs = NULL;
}
static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
@@ -998,7 +1059,7 @@ static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
static int hinic3_stop_sq(struct hinic3_txq *txq)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(txq->netdev);
- unsigned long timeout;
+ u64 timeout;
int err;
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -1007,7 +1068,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
return 0;
usleep_range(900, 1000); /* sleep 900 us ~ 1000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* force hardware to drop packets */
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -1020,7 +1081,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
break;
usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* Avoid msleep takes too long and get a fake result */
if (is_hw_complete_sq_process(txq->sq))
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
index 1b9e509..7ae029b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
@@ -29,7 +29,7 @@ struct hinic3_wq {
#define WQ_MASK_IDX(wq, idx) ((idx) & (wq)->idx_mask)
#define WQ_MASK_PAGE(wq, pg_idx) \
- ((pg_idx) < (wq)->num_wq_pages ? (pg_idx) : 0)
+ (((pg_idx) < ((wq)->num_wq_pages)) ? (pg_idx) : 0)
#define WQ_PAGE_IDX(wq, idx) ((idx) >> (wq)->wqebbs_per_page_shift)
#define WQ_OFFSET_IN_PAGE(wq, idx) ((idx) & (wq)->wqebbs_per_page_mask)
#define WQ_GET_WQEBB_ADDR(wq, pg_idx, idx_in_pg) \
@@ -75,7 +75,7 @@ static inline void *hinic3_wq_get_multi_wqebbs(struct hinic3_wq *wq,
pg_idx = WQ_PAGE_IDX(wq, *prod_idx);
off_in_page = WQ_OFFSET_IN_PAGE(wq, *prod_idx);
- if (off_in_page + num_wqebbs > wq->wqebbs_per_page) {
+ if ((off_in_page + num_wqebbs) > wq->wqebbs_per_page) {
/* wqe across wq page boundary */
*second_part_wqebbs_addr =
WQ_GET_WQEBB_ADDR(wq, WQ_MASK_PAGE(wq, pg_idx + 1), 0);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
index 597d3fe..468351f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
@@ -400,12 +400,15 @@ static int wait_for_status_poll(struct hinic3_api_cmd_chain *chain)
API_CMD_STATUS_TIMEOUT, 100); /* wait 100 us once */
}
-static void copy_resp_data(struct hinic3_api_cmd_cell_ctxt *ctxt, void *ack,
+static void copy_resp_data(struct hinic3_api_cmd_chain *chain,
+ struct hinic3_api_cmd_cell_ctxt *ctxt, void *ack,
u16 ack_size)
{
struct hinic3_api_cmd_resp_fmt *resp = ctxt->resp;
+ int rsp_size_align = chain->rsp_size_align - 0x8;
+ int rsp_size = (ack_size > rsp_size_align) ? rsp_size_align : ack_size;
- memcpy(ack, &resp->resp_data, ack_size);
+ memcpy(ack, &resp->resp_data, rsp_size);
ctxt->status = 0;
}
@@ -464,7 +467,7 @@ static int wait_for_api_cmd_completion(struct hinic3_api_cmd_chain *chain,
case HINIC3_API_CMD_POLL_READ:
err = wait_for_resp_polling(ctxt);
if (err == 0)
- copy_resp_data(ctxt, ack, ack_size);
+ copy_resp_data(chain, ctxt, ack, ack_size);
else
sdk_err(dev, "API CMD poll response timeout\n");
break;
@@ -1054,13 +1057,11 @@ alloc_cells_buf_err:
alloc_wb_status_err:
kfree(chain->cell_ctxt);
-/*lint -save -e548*/
alloc_cell_ctxt_err:
if (chain->chain_type == HINIC3_API_CMD_WRITE_ASYNC_TO_MGMT_CPU)
spin_lock_deinit(&chain->async_lock);
else
sema_deinit(&chain->sem);
-/*lint -restore*/
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
index 38474ba..9f10131 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
@@ -801,7 +801,7 @@ static int cmdq_sync_cmd(struct hinic3_cmdq *cmdq, u8 mod, u8 cmd,
hinic3_cmdq_fill_completion_info(cmd_info, &cmpt_code, &done, &errcode, out_param);
cmdq_set_cmd_buf(cmd_info, cmdq->hwdev, buf_in, buf_out);
- memcpy(&saved_cmd_info, cmd_info, sizeof(*cmd_info));
+ memcpy(&saved_cmd_info, cmd_info, sizeof(struct hinic3_cmdq_cmd_info));
cmdq_sync_wqe_prepare(cmdq, mod, cmd, buf_in, buf_out, curr_wqe, curr_pi, nic_cmd_type);
@@ -1075,6 +1075,7 @@ int hinic3_cmdq_async(void *hwdev, u8 mod, u8 cmd, struct hinic3_cmd_buf *buf_in
return cmdq_async_cmd(&cmdqs->cmdq[HINIC3_CMDQ_SYNC], mod,
cmd, buf_in, channel);
}
+EXPORT_SYMBOL(hinic3_cmdq_async);
int hinic3_cmdq_async_cos(void *hwdev, u8 mod, u8 cmd,
u8 cos_id, struct hinic3_cmd_buf *buf_in, u16 channel)
@@ -1320,6 +1321,7 @@ cmd_infos_err:
static void free_cmdq(struct hinic3_cmdq *cmdq)
{
kfree(cmdq->cmd_infos);
+ cmdq->cmd_infos = NULL;
spin_lock_deinit(&cmdq->cmdq_lock);
}
@@ -1530,7 +1532,7 @@ static int create_cmdq_wq(struct hinic3_cmdqs *cmdqs)
type = HINIC3_CMDQ_SYNC;
for (; type < cmdqs->cmdq_num; type++)
memcpy((u8 *)cmdqs->wq_block_vaddr +
- CMDQ_WQ_CLA_SIZE * type,
+ ((u64)type * CMDQ_WQ_CLA_SIZE),
cmdqs->cmdq[type].wq.wq_block_vaddr,
cmdqs->cmdq[type].wq.num_wq_pages * sizeof(u64));
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
index b9b884f..4f4639d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
@@ -15,11 +15,6 @@
#include "hinic3_common.h"
#include "hinic3_hwdev.h"
-struct dma_pool {
- unsigned int size;
- void *dev_hdl;
-};
-
#define HINIC3_SCMD_DATA_LEN 16
#define HINIC3_CMDQ_DEPTH 4096
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c
index c212bcc..d7e4985 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c
@@ -16,7 +16,6 @@
#include "ossl_knl.h"
#include "npu_cmdq_base_defs.h"
-#include "comm_defs.h"
#include "hinic3_crm.h"
#include "hinic3_hw.h"
#include "hinic3_hwdev.h"
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
index 5e0139a..f0b2b1a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
@@ -22,11 +22,15 @@
#include "hinic3_sriov.h"
#include "hinic3_nictool.h"
#include "hinic3_pci_id_tbl.h"
+#include "hinic3_hwdev.h"
+#include "cfg_mgmt_mpu_cmd_defs.h"
+#include "mpu_cmd_base_defs.h"
#include "hinic3_dev_mgmt.h"
#define HINIC3_WAIT_TOOL_CNT_TIMEOUT 10000
#define HINIC3_WAIT_TOOL_MIN_USLEEP_TIME 9900
#define HINIC3_WAIT_TOOL_MAX_USLEEP_TIME 10000
+#define HIGHT_BDF 8
static unsigned long card_bit_map;
@@ -60,14 +64,24 @@ void lld_dev_cnt_init(struct hinic3_pcidev *pci_adapter)
void lld_dev_hold(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_inc(&pci_adapter->ref_cnt);
}
void lld_dev_put(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_dec(&pci_adapter->ref_cnt);
}
@@ -236,6 +250,40 @@ void hinic3_get_all_chip_id(void *id_info)
card_id->num = (u32)i;
}
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+ u64 bar1_phy_addr = 0;
+ u64 bar3_phy_addr = 0;
+ u64 bar1_size = 0;
+ u64 bar3_size = 0;
+
+ lld_hold();
+
+ /* get PF bar1 or bar3 physical address to verify */
+ list_for_each_entry(chip_node, &g_hinic3_chip_list, node) {
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (hinic3_func_type(dev->hwdev) == TYPE_VF)
+ continue;
+
+ bar1_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+ bar1_size = pci_resource_len(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+
+ bar3_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ bar3_size = pci_resource_len(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ if ((phy_addr == bar1_phy_addr && vmsize <= bar1_size) ||
+ (phy_addr == bar3_phy_addr && vmsize <= bar3_size)) {
+ lld_put();
+ return 0;
+ }
+ }
+ }
+
+ lld_put();
+ return -EINVAL;
+}
+
void hinic3_get_card_func_info_by_card_name(const char *chip_name,
struct hinic3_card_func_info *card_func)
{
@@ -422,6 +470,29 @@ struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name
return NULL;
}
+void *hinic3_get_ppf_dev(void)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct list_head *chip_list = NULL;
+
+ lld_hold();
+ chip_list = get_hinic3_chip_list();
+
+ list_for_each_entry(chip_node, chip_list, node)
+ list_for_each_entry(pci_adapter, &chip_node->func_list, node)
+ if (hinic3_func_type(pci_adapter->hwdev) == TYPE_PPF) {
+ pr_info("Get ppf_func_id:%u",
+ hinic3_global_func_id(pci_adapter->hwdev));
+ lld_put();
+ return pci_adapter->lld_dev.hwdev;
+ }
+
+ lld_put();
+ return NULL;
+}
+EXPORT_SYMBOL(hinic3_get_ppf_dev);
+
struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
enum hinic3_service_type type)
{
@@ -518,6 +589,7 @@ EXPORT_SYMBOL(hinic3_get_ppf_lld_dev_unsafe);
int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len)
{
struct hinic3_pcidev *pci_adapter = NULL;
+ int ret = 0;
if (!lld_dev || !chip_name || !max_len)
return -EINVAL;
@@ -527,12 +599,18 @@ int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 ma
return -EFAULT;
lld_hold();
- strscpy(chip_name, pci_adapter->chip_node->chip_name, max_len);
+ if (strscpy(chip_name, pci_adapter->chip_node->chip_name, max_len) < 0)
+ goto RELEASE;
chip_name[max_len - 1] = '\0';
lld_put();
return 0;
+
+RELEASE:
+ lld_put();
+
+ return ret;
}
EXPORT_SYMBOL(hinic3_get_chip_name);
@@ -541,6 +619,87 @@ struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev)
return lld_dev->hwdev;
}
+void hinic3_write_oshr_info(struct os_hot_replace_info *out_oshr_info,
+ struct hw_pf_info *info,
+ struct hinic3_board_info *board_info,
+ struct card_node *chip_node, u32 serivce_enable,
+ u32 func_info_idx)
+{
+ out_oshr_info->func_infos[func_info_idx].pf_idx = info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].backup_pf =
+ (((info->glb_func_idx) / (board_info->port_num)) %
+ HOT_REPLACE_PARTITION_NUM == 0) ?
+ ((info->glb_func_idx) + (board_info->port_num)) :
+ ((info->glb_func_idx) - (board_info->port_num));
+ out_oshr_info->func_infos[func_info_idx].partition =
+ ((info->glb_func_idx) / (board_info->port_num)) %
+ HOT_REPLACE_PARTITION_NUM;
+ out_oshr_info->func_infos[func_info_idx].port_id = info->port_id;
+ out_oshr_info->func_infos[func_info_idx].bdf =
+ (info->bus_num << HIGHT_BDF) + info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].bus_num = chip_node->bus_num;
+ out_oshr_info->func_infos[func_info_idx].valid = serivce_enable;
+ memcpy(out_oshr_info->func_infos[func_info_idx].card_name,
+ chip_node->chip_name, IFNAMSIZ);
+}
+
+void hinic3_get_os_hot_replace_info(void *oshr_info)
+{
+ struct os_hot_replace_info *out_oshr_info =
+ (struct os_hot_replace_info *)oshr_info;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dst_dev = NULL;
+ struct hinic3_board_info *board_info = NULL;
+ struct hw_pf_info *infos = NULL;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ struct hinic3_hwdev *hwdev = NULL;
+ u32 func_info_idx = 0, func_id = 0, func_num, serivce_enable = 0;
+ struct list_head *hinic3_chip_list = get_hinic3_chip_list();
+ int err;
+
+ lld_hold();
+ pf_infos = kzalloc(sizeof(struct hinic3_hw_pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ pr_err("kzalloc pf_infos fail\n");
+ lld_put();
+ return;
+ }
+ list_for_each_entry(chip_node, hinic3_chip_list, node) {
+ list_for_each_entry(dst_dev, &chip_node->func_list, node) {
+ err = hinic3_get_hw_pf_infos(dst_dev->hwdev,
+ pf_infos,
+ HINIC3_CHANNEL_COMM);
+ if (err != 0) {
+ pr_err("get pf info failed\n");
+ break;
+ }
+ hwdev = (struct hinic3_hwdev *)dst_dev->hwdev;
+ serivce_enable = 0;
+ infos = pf_infos->infos;
+ board_info = &hwdev->board_info;
+ if (hwdev->hot_replace_mode == HOT_REPLACE_ENABLE)
+ serivce_enable = 1;
+ break;
+ }
+
+ func_num = pf_infos->num_pfs;
+ if (func_num <= 0) {
+ pr_err("get pf num failed\n");
+ break;
+ }
+
+ for (func_id = 0; func_id < func_num; func_id++) {
+ hinic3_write_oshr_info(out_oshr_info, &infos[func_id],
+ board_info, chip_node,
+ serivce_enable, func_info_idx);
+ func_info_idx++;
+ }
+ }
+ out_oshr_info->func_cnt = func_info_idx;
+ kfree(pf_infos);
+ lld_put();
+}
+
struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(lld_dev->pdev);
@@ -608,21 +767,24 @@ void hinic3_get_card_info(const void *hwdev, void *bufin)
if (hinic3_support_nic(fun_hwdev, NULL)) {
if (dev->uld_dev[SERVICE_T_NIC]) {
info->pf[i].pf_type |= (u32)BIT(SERVICE_T_NIC);
- get_dynamic_uld_dev_name(dev, SERVICE_T_NIC, info->pf[i].name);
+ get_dynamic_uld_dev_name(dev, SERVICE_T_NIC,
+ info->pf[i].name);
}
}
if (hinic3_support_ppa(fun_hwdev, NULL)) {
if (dev->uld_dev[SERVICE_T_PPA]) {
info->pf[i].pf_type |= (u32)BIT(SERVICE_T_PPA);
- get_dynamic_uld_dev_name(dev, SERVICE_T_PPA, info->pf[i].name);
+ get_dynamic_uld_dev_name(dev, SERVICE_T_PPA,
+ info->pf[i].name);
}
}
if (hinic3_func_for_mgmt(fun_hwdev))
strscpy(info->pf[i].name, "FOR_MGMT", IFNAMSIZ);
- if (dev->lld_dev.pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID)
+ if (dev->lld_dev.pdev->subsystem_device ==
+ BIFUR_RESOURCE_PF_SSID)
strscpy(info->pf[i].name, "bifur", IFNAMSIZ);
strscpy(info->pf[i].bus_info, pci_name(dev->pcidev),
@@ -721,6 +883,7 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
struct card_node *chip_node = NULL;
unsigned char i;
unsigned char bus_number = 0;
+ int err;
if (chip_node_is_exist(pci_adapter, &bus_number))
return 0;
@@ -746,7 +909,10 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
/* bus number */
chip_node->bus_num = bus_number;
- if (snprintf(chip_node->chip_name, IFNAMSIZ, "%s%u", HINIC3_CHIP_NAME, i) < 0) {
+ snprintf(chip_node->chip_name, IFNAMSIZ, "%s%u", HINIC3_CHIP_NAME, i);
+
+ err = sscanf(chip_node->chip_name, HINIC3_CHIP_NAME "%d", &(chip_node->chip_id));
+ if (err <= 0) {
clear_bit(i, &card_bit_map);
kfree(chip_node);
return -EINVAL;
@@ -803,3 +969,36 @@ int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *
return 0;
}
+
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin)
+{
+ struct card_node *chip_node = NULL;
+ struct card_mbox_cnt_info *info = (struct card_mbox_cnt_info *)bufin;
+ struct hinic3_pcidev *dev = NULL;
+ struct hinic3_hwdev *func_hwdev = NULL;
+ u32 i = 0;
+
+ info->func_num = 0;
+ chip_node = hinic3_get_chip_node_by_hwdev(hwdev);
+ if (chip_node == NULL)
+ return;
+
+ lld_hold();
+
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ func_hwdev = (struct hinic3_hwdev *)dev->hwdev;
+ strscpy(info->func_info[i].bus_info, pci_name(dev->pcidev),
+ sizeof(info->func_info[i].bus_info));
+
+ info->func_info[i].send_cnt = func_hwdev->mbox_send_cnt;
+ info->func_info[i].ack_cnt = func_hwdev->mbox_ack_cnt;
+ info->func_num++;
+ i = info->func_num;
+ if (i >= ARRAY_SIZE(info->func_info)) {
+ sdk_err(&dev->pcidev->dev, "chip_node->func_list bigger than pf_max + vf_max\n");
+ break;
+ }
+ }
+
+ lld_put();
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
index 5c7c7cd..9815082 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
@@ -22,8 +22,13 @@
#define BIFUR_RESOURCE_PF_SSID 0x05a1
-#define HINIC3_IS_VF_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_VF)
-#define HINIC3_IS_SPU_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_SPU)
+#define HINIC3_IS_VF_DEV(pdev) \
+ ((pdev)->device == HINIC3_DEV_ID_VF || \
+ (pdev)->device == HINIC3_DEV_SDI_5_1_ID_VF)
+#define HINIC3_IS_SPU_DEV(pdev) \
+ (((pdev)->device == HINIC3_DEV_ID_SPU) || \
+ ((pdev)->device == HINIC3_DEV_ID_SDI_5_0_PF) || \
+ (((pdev)->device == HINIC3_DEV_ID_DPU_PF)))
enum {
HINIC3_NOT_PROBE = 1,
@@ -79,6 +84,13 @@ struct hinic3_pcidev {
u16 probe_fault_level;
u16 rsvd2;
u64 rsvd4;
+
+ struct workqueue_struct *multi_host_mgmt_workq;
+ struct work_struct slave_nic_work;
+ struct work_struct slave_vroce_work;
+
+ struct workqueue_struct *migration_probe_workq;
+ struct delayed_work migration_probe_dwork;
};
struct hinic_chip_info {
@@ -104,4 +116,6 @@ void wait_lld_dev_unused(struct hinic3_pcidev *pci_adapter);
void *hinic3_get_hwdev_by_pcidev(struct pci_dev *pdev);
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
index 11561a0..59ff722 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
@@ -101,7 +101,8 @@ static bool check_image_device_type(struct hinic3_hwdev *hwdev, u32 device_type)
static void encapsulate_update_cmd(struct hinic3_cmd_update_firmware *msg,
struct firmware_section *section_info,
- int *remain_len, u32 *send_len, u32 *send_pos)
+ const int *remain_len, u32 *send_len,
+ u32 *send_pos)
{
memset(msg->data, 0, sizeof(msg->data));
msg->ctl_info.sf = (*remain_len == section_info->section_len) ? true : false;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
index 937d699..be7c82b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
@@ -26,6 +26,8 @@
#include "hinic3_prof_adap.h"
#include "hinic3_eqs.h"
+#include "vram_common.h"
+
#define HINIC3_EQS_WQ_NAME "hinic3_eqs"
#define AEQ_CTRL_0_INTR_IDX_SHIFT 0
@@ -66,7 +68,6 @@
#define HINIC3_TASK_PROCESS_EQE_LIMIT 1024
#define HINIC3_EQ_UPDATE_CI_STEP 64
-/*lint -e806*/
static uint g_aeq_len = HINIC3_DEFAULT_AEQ_LEN;
module_param(g_aeq_len, uint, 0444);
MODULE_PARM_DESC(g_aeq_len,
@@ -83,7 +84,6 @@ static uint g_num_ceqe_in_tasklet = HINIC3_TASK_PROCESS_EQE_LIMIT;
module_param(g_num_ceqe_in_tasklet, uint, 0444);
MODULE_PARM_DESC(g_num_ceqe_in_tasklet,
"The max number of ceqe can be processed in tasklet, default = 1024");
-/*lint +e806*/
#define CEQ_CTRL_0_INTR_IDX_SHIFT 0
#define CEQ_CTRL_0_DMA_ATTR_SHIFT 12
@@ -819,18 +819,22 @@ static int alloc_eq_pages(struct hinic3_eq *eq)
u32 reg, init_val;
u16 pg_idx, i;
int err;
+ gfp_t gfp_vram;
eq->eq_pages = kcalloc(eq->num_pages, sizeof(*eq->eq_pages),
GFP_KERNEL);
if (!eq->eq_pages)
return -ENOMEM;
+ gfp_vram = hi_vram_get_gfp_vram();
+
for (pg_idx = 0; pg_idx < eq->num_pages; pg_idx++) {
eq_page = &eq->eq_pages[pg_idx];
err = hinic3_dma_zalloc_coherent_align(eq->hwdev->dev_hdl,
eq->page_size,
HINIC3_MIN_EQ_PAGE_SIZE,
- GFP_KERNEL, eq_page);
+ GFP_KERNEL | gfp_vram,
+ eq_page);
if (err) {
sdk_err(eq->hwdev->dev_hdl, "Failed to alloc eq page, page index: %u\n",
pg_idx);
@@ -881,6 +885,7 @@ static void free_eq_pages(struct hinic3_eq *eq)
&eq->eq_pages[pg_idx]);
kfree(eq->eq_pages);
+ eq->eq_pages = NULL;
}
static inline u32 get_page_size(const struct hinic3_eq *eq)
@@ -1120,7 +1125,8 @@ int hinic3_aeqs_init(struct hinic3_hwdev *hwdev, u16 num_aeqs,
hwdev->aeqs = aeqs;
aeqs->hwdev = hwdev;
aeqs->num_aeqs = num_aeqs;
- aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME, WQ_MEM_RECLAIM,
+ aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME,
+ WQ_MEM_RECLAIM | WQ_HIGHPRI,
HINIC3_MAX_AEQS);
if (!aeqs->workq) {
sdk_err(hwdev->dev_hdl, "Failed to initialize aeq workqueue\n");
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
index a4cbac8..6b96b87 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
@@ -82,6 +82,48 @@ int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id,
return 0;
}
+/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read and clear to zero
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
+ u16 *value)
+{
+ struct chipif_sml_ctr_rd_req req;
+ union ctr_rd_rsp rsp;
+ int ret;
+
+ if (!hwdev || !value)
+ return -EFAULT;
+
+ if (!COMM_SUPPORT_API_CHAIN((struct hinic3_hwdev *)hwdev))
+ return -EPERM;
+
+ memset(&req, 0, sizeof(req));
+
+ hinic3_sml_ctr_read_build_req(&req, instance,
+ CHIPIF_SM_CTR_OP_READ_CLEAR,
+ CHIPIF_ACK, ctr_id, 0);
+
+ ret = hinic3_api_cmd_read_ack(hwdev, node, (u8 *)&req,
+ (unsigned short)sizeof(req),
+ (void *)&rsp,
+ (unsigned short)sizeof(rsp));
+ if (ret) {
+ sdk_err(((struct hinic3_hwdev *)hwdev)->dev_hdl,
+ "Sm 16bit counter clear fail, err(%d)\n", ret);
+ return ret;
+ }
+ sml_ctr_htonl_n((u32 *)&rsp, sizeof(rsp) / sizeof(u32));
+ *value = rsp.bs_ss16_rsp.value1;
+
+ return 0;
+}
+
/**
* hinic3_sm_ctr_rd32 - small single 32 counter read
* @hwdev: the hardware device
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
index 030ef6d..5a8d2a4 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
@@ -34,13 +34,18 @@ static void parse_pub_res_cap_dfx(struct hinic3_hwdev *hwdev,
cap->max_vf);
sdk_info(hwdev->dev_hdl, "Host_pf_num: 0x%x, pf_id_start: 0x%x, host_vf_num: 0x%x, vf_id_start: 0x%x\n",
cap->pf_num, cap->pf_id_start, cap->vf_num, cap->vf_id_start);
- sdk_info(hwdev->dev_hdl, "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x\n",
- cap->host_valid_bitmap, cap->master_host_id, cap->srv_multi_host_mode);
sdk_info(hwdev->dev_hdl,
- "fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
- cap->fake_vf_start_id, cap->fake_vf_num, cap->fake_vf_max_pctx);
- sdk_info(hwdev->dev_hdl, "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x\n",
- cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len);
+ "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x, hot_plug_disable: 0x%x\n",
+ cap->host_valid_bitmap, cap->master_host_id,
+ cap->srv_multi_host_mode, cap->hot_plug_disable);
+ sdk_info(hwdev->dev_hdl,
+ "os_hot_replace: 0x%x, fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
+ cap->os_hot_replace, cap->fake_vf_start_id,
+ cap->fake_vf_num, cap->fake_vf_max_pctx);
+ sdk_info(hwdev->dev_hdl,
+ "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x, bond_create_mode: 0x%x\n",
+ cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len,
+ cap->bond_create_mode);
}
static void parse_cqm_res_cap(struct hinic3_hwdev *hwdev, struct service_cap *cap,
@@ -109,6 +114,9 @@ static void parse_pub_res_cap(struct hinic3_hwdev *hwdev,
cap->host_valid_bitmap = dev_cap->host_valid_bitmap;
cap->master_host_id = dev_cap->master_host_id;
cap->srv_multi_host_mode = dev_cap->srv_multi_host_mode;
+ cap->hot_plug_disable = dev_cap->hot_plug_disable;
+ cap->bond_create_mode = dev_cap->bond_create_mode;
+ cap->os_hot_replace = dev_cap->os_hot_replace;
cap->fake_vf_en = dev_cap->fake_vf_en;
cap->fake_vf_start_bit = dev_cap->fake_vf_start_bit;
cap->fake_vf_end_bit = dev_cap->fake_vf_end_bit;
@@ -148,18 +156,27 @@ static void parse_l2nic_res_cap(struct hinic3_hwdev *hwdev,
nic_cap->max_sqs = dev_cap->nic_max_sq_id + 1;
nic_cap->max_rqs = dev_cap->nic_max_rq_id + 1;
nic_cap->default_num_queues = dev_cap->nic_default_num_queues;
+ nic_cap->outband_vlan_cfg_en = dev_cap->outband_vlan_cfg_en;
+ nic_cap->lro_enable = dev_cap->lro_enable;
sdk_info(hwdev->dev_hdl, "L2nic resource capbility, max_sqs: 0x%x, max_rqs: 0x%x\n",
nic_cap->max_sqs, nic_cap->max_rqs);
/* Check parameters from firmware */
- if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP ||
- nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
- sdk_info(hwdev->dev_hdl, "Number of qp exceed limit[1-%d]: sq: %u, rq: %u\n",
- HINIC3_CFG_MAX_QP, nic_cap->max_sqs, nic_cap->max_rqs);
+ if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of sq exceed limit[1-%d]: sq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_sqs);
nic_cap->max_sqs = HINIC3_CFG_MAX_QP;
+ }
+
+ if (nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of rq exceed limit[1-%d]: rq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_rqs);
nic_cap->max_rqs = HINIC3_CFG_MAX_QP;
}
+
+ if (nic_cap->outband_vlan_cfg_en)
+ sdk_info(hwdev->dev_hdl, "L2nic outband vlan cfg enabled\n");
}
static void parse_fc_res_cap(struct hinic3_hwdev *hwdev,
@@ -333,6 +350,28 @@ static void parse_ipsec_res_cap(struct hinic3_hwdev *hwdev,
dev_cap->ipsec_max_sactx, dev_cap->ipsec_max_cq);
}
+static void parse_vbs_res_cap(struct hinic3_hwdev *hwdev,
+ struct service_cap *cap,
+ struct cfg_cmd_dev_cap *dev_cap,
+ enum func_type type)
+{
+ struct vbs_service_cap *vbs_cap = &cap->vbs_cap;
+
+ vbs_cap->vbs_max_volq = dev_cap->vbs_max_volq;
+ vbs_cap->vbs_main_pf_enable = dev_cap->vbs_main_pf_enable;
+ vbs_cap->vbs_vsock_pf_enable = dev_cap->vbs_vsock_pf_enable;
+ vbs_cap->vbs_fushion_queue_pf_enable = dev_cap->vbs_fushion_queue_pf_enable;
+
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS resource capbility, vbs_max_volq: 0x%x\n",
+ dev_cap->vbs_max_volq);
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS pf info, vbs_main_pf_enable: 0x%x, vbs_vsock_pf_enable: 0x%x, vbs_fushion_queue_pf_enable: 0x%x\n",
+ dev_cap->vbs_main_pf_enable,
+ dev_cap->vbs_vsock_pf_enable,
+ dev_cap->vbs_fushion_queue_pf_enable);
+}
+
static void parse_dev_cap(struct hinic3_hwdev *dev,
struct cfg_cmd_dev_cap *dev_cap, enum func_type type)
{
@@ -375,6 +414,9 @@ static void parse_dev_cap(struct hinic3_hwdev *dev,
if (IS_PPA_TYPE(dev))
parse_ppa_res_cap(dev, cap, dev_cap, type);
+
+ if (IS_VBS_TYPE(dev))
+ parse_vbs_res_cap(dev, cap, dev_cap, type);
}
static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
@@ -404,6 +446,23 @@ static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
return 0;
}
+u8 hinic3_get_bond_create_mode(void *dev)
+{
+ struct hinic3_hwdev *hwdev = NULL;
+ struct service_cap *cap = NULL;
+
+ if (!dev) {
+ pr_err("pointer dev is NULL\n");
+ return -EINVAL;
+ }
+
+ hwdev = (struct hinic3_hwdev *)dev;
+ cap = &hwdev->cfg_mgmt->svc_cap;
+
+ return cap->bond_create_mode;
+}
+EXPORT_SYMBOL(hinic3_get_bond_create_mode);
+
int hinic3_get_dev_cap(void *dev)
{
enum func_type type;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
index 671eed6..2f2310a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
@@ -166,6 +166,11 @@ struct service_cap {
u8 srv_multi_host_mode;
u16 virtio_vq_size;
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 os_hot_replace;
+ u8 rsvd1;
+
u8 timer_pf_num;
u8 timer_pf_id_start;
u16 timer_vf_num;
@@ -335,5 +340,7 @@ void free_capability(struct hinic3_hwdev *dev);
int hinic3_init_vf_dev_cap(void *hwdev);
+u8 hinic3_get_bond_create_mode(void *dev);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
index 8a87d25..cb3b609 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
@@ -21,6 +21,7 @@
#include "hinic3_hw_cfg.h"
#include "hinic3_cmdq.h"
#include "mpu_inband_cmd_defs.h"
+#include "vram_common.h"
#include "hinic3_hw_comm.h"
#define HINIC3_MSIX_CNT_LLI_TIMER_SHIFT 0
@@ -242,12 +243,19 @@ int hinic3_func_reset(void *dev, u16 func_id, u64 reset_flag, u16 channel)
struct hinic3_hwdev *hwdev = dev;
u16 out_size = sizeof(func_reset);
int err = 0;
+ int is_in_kexec;
if (!dev) {
pr_err("Invalid para: dev is null.\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ sdk_info(hwdev->dev_hdl, "Skip function reset!\n");
+ return 0;
+ }
+
sdk_info(hwdev->dev_hdl, "Function is reset, flag: 0x%llx, channel:0x%x\n",
reset_flag, channel);
@@ -554,7 +562,7 @@ EXPORT_SYMBOL(hinic3_set_ppf_flr_type);
int hinic3_set_ppf_tbl_hotreplace_flag(void *hwdev, u8 flag)
{
- struct comm_cmd_ppf_tbl_htrp_config htr_info = {0};
+ struct comm_cmd_ppf_tbl_htrp_config htr_info = {};
u16 out_size = sizeof(struct comm_cmd_ppf_tbl_htrp_config);
struct hinic3_hwdev *dev = hwdev;
int ret;
@@ -899,11 +907,19 @@ static int set_ppf_tmr_status(struct hinic3_hwdev *hwdev,
int hinic3_ppf_tmr_start(void *hwdev)
{
+ int is_in_kexec;
+
if (!hwdev) {
pr_err("Hwdev pointer is NULL for starting ppf timer\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ pr_info("Skip starting ppt timer during kexec");
+ return 0;
+ }
+
return set_ppf_tmr_status(hwdev, HINIC_PPF_TMR_FLAG_START);
}
EXPORT_SYMBOL(hinic3_ppf_tmr_start);
@@ -919,18 +935,114 @@ int hinic3_ppf_tmr_stop(void *hwdev)
}
EXPORT_SYMBOL(hinic3_ppf_tmr_stop);
+static int hi_vram_kalloc_align(struct hinic3_hwdev *hwdev, char *name, u32 page_size, u32 page_num,
+ struct hinic3_dma_addr_align *mem_align)
+{
+ void *vaddr = NULL, *align_vaddr = NULL;
+ dma_addr_t paddr, align_paddr;
+ u64 real_size = page_size;
+ u64 align = page_size;
+
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ /* align */
+ if (align_paddr == paddr) {
+ align_vaddr = vaddr;
+ goto out;
+ }
+
+ hi_vram_kfree((void *)vaddr, name, real_size);
+
+ /* realloc memory for align */
+ real_size = page_size + align;
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc align failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ align_vaddr = (void *)((u64)vaddr + (align_paddr - paddr));
+
+out:
+ mem_align->real_size = (u32)real_size;
+ mem_align->ori_vaddr = vaddr;
+ mem_align->ori_paddr = paddr;
+ mem_align->align_vaddr = align_vaddr;
+ mem_align->align_paddr = align_paddr;
+
+ return 0;
+}
+
+static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
+{
+ u32 i;
+ struct hinic3_dma_addr_align *page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = hwdev->mqm_eqm_vram_name;
+
+ page_addr = hwdev->mqm_att.brm_srch_page_addr;
+
+ for (i = 0; i < hwdev->mqm_att.page_num; i++) {
+ if (is_use_vram != 0) {
+ hi_vram_kfree(page_addr->ori_vaddr, mqm_eqm_vram_name[i].vram_name,
+ page_addr->real_size);
+ } else {
+ hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
+ }
+ page_addr->ori_vaddr = NULL;
+ page_addr++;
+ }
+
+ kfree(mqm_eqm_vram_name);
+ hwdev->mqm_eqm_vram_name = NULL;
+}
+
static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
u32 page_num)
{
struct hinic3_dma_addr_align *page_addr = hwdev->mqm_att.brm_srch_page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = NULL;
u32 valid_num = 0;
u32 flag = 1;
u32 i = 0;
int err;
+ u16 func_id;
+
+ mqm_eqm_vram_name = kcalloc(page_num, sizeof(struct mqm_eqm_vram_name_s), GFP_KERNEL);
+ if (mqm_eqm_vram_name == NULL) {
+ sdk_err(hwdev->dev_hdl, "mqm eqm alloc vram name failed.\n");
+ return -ENOMEM;
+ }
+
+ hwdev->mqm_eqm_vram_name = mqm_eqm_vram_name;
+ func_id = hinic3_global_func_id(hwdev);
for (i = 0; i < page_num; i++) {
- err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl, page_size,
- page_size, GFP_KERNEL, page_addr);
+ if (is_use_vram != 0) {
+ snprintf(mqm_eqm_vram_name[i].vram_name,
+ VRAM_NAME_MAX_LEN, "%s%hu%s%u",
+ VRAM_CQM_GLB_FUNC_BASE, func_id,
+ VRAM_NIC_MQM, i);
+ err = hi_vram_kalloc_align(hwdev,
+ mqm_eqm_vram_name[i].vram_name,
+ page_size, page_num,
+ page_addr);
+ } else {
+ err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl,
+ page_size,
+ page_size,
+ GFP_KERNEL,
+ page_addr);
+ }
if (err) {
flag = 0;
break;
@@ -939,15 +1051,12 @@ static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
page_addr++;
}
+ hwdev->mqm_att.page_num = valid_num;
+
if (flag == 1) {
hwdev->mqm_att.page_size = page_size;
- hwdev->mqm_att.page_num = page_num;
} else {
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
- for (i = 0; i < valid_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
+ mqm_eqm_free_page_mem(hwdev);
return -EFAULT;
}
@@ -986,19 +1095,6 @@ static int mqm_eqm_alloc_page_mem(struct hinic3_hwdev *hwdev)
return ret;
}
-static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
-{
- u32 i;
- struct hinic3_dma_addr_align *page_addr;
-
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
-
- for (i = 0; i < hwdev->mqm_att.page_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
-}
-
static int mqm_eqm_set_cfg_2_hw(struct hinic3_hwdev *hwdev, u8 valid)
{
struct comm_cmd_eqm_cfg info_eqm_cfg;
@@ -1129,6 +1225,7 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
{
struct comm_cmd_get_eqm_num info_eqm_fix;
int ret;
+ int is_in_kexec;
if (hwdev->hwif->attr.func_type != TYPE_PPF)
return 0;
@@ -1158,10 +1255,16 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
goto err_page;
}
- ret = mqm_eqm_set_page_2_hw(hwdev);
- if (ret) {
- sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
- goto err_ecmd;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ ret = mqm_eqm_set_page_2_hw(hwdev);
+ if (ret) {
+ sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
+ goto err_ecmd;
+ }
+ } else {
+ sdk_info(hwdev->dev_hdl,
+ "Mqm db don't set to chip when os hot replace.\r\n");
}
ret = mqm_eqm_set_cfg_2_hw(hwdev, 1);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
index e8aa7ef..722fecd 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
@@ -252,97 +252,6 @@ static u32 get_up_timeout_val(enum hinic3_mod_type mod, u16 cmd)
return 0; /* use default mbox/apichain timeout time */
}
-static int api_csr_read(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
-{
- struct up_log_msg_st *up_log_msg = (struct up_log_msg_st *)buf_in;
- u8 *buf_out_tmp = (u8 *)buf_out;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
-
- if (!buf_in || !buf_out || in_size != sizeof(*up_log_msg) ||
- *out_size != up_log_msg->rd_len || up_log_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = up_log_msg->rd_len;
- rd_addr = up_log_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_rd32(hwdev, node_id,
- rd_addr + offset,
- (u32 *)(buf_out_tmp + offset));
- if (ret) {
- pr_err("Csr rd fail, err: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, node_id, rd_addr + offset);
- return ret;
- }
- offset += DW_WIDTH;
- }
- *out_size = rd_len;
-
- return ret;
-}
-
-static int api_csr_write(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out,
- u32 *out_size)
-{
- struct csr_write_st *csr_write_msg = (struct csr_write_st *)buf_in;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
- u8 *data = NULL;
-
- if (!buf_in || in_size != sizeof(*csr_write_msg) || csr_write_msg->rd_len == 0 ||
- csr_write_msg->rd_len > API_CSR_MAX_RD_LEN || csr_write_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = csr_write_msg->rd_len;
- rd_addr = csr_write_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- data = kzalloc(rd_len, GFP_KERNEL);
- if (!data)
- return -EFAULT;
-
- if (copy_from_user(data, (void *)csr_write_msg->data, rd_len)) {
- pr_err("Copy information from user failed\n");
- kfree(data);
- return -EFAULT;
- }
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_wr32(hwdev, node_id,
- rd_addr + offset,
- *((u32 *)(data + offset)));
- if (ret) {
- pr_err("Csr wr fail, ret: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, rd_addr + offset, node_id);
- kfree(data);
- return ret;
- }
- offset += DW_WIDTH;
- }
-
- *out_size = 0;
- kfree(data);
- return ret;
-}
-
int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
@@ -369,10 +278,8 @@ int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
return ret;
}
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_BYPASS) {
- if (nt_msg->mpu_cmd.cmd == API_CSR_WRITE)
- return api_csr_write(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
-
- ret = api_csr_read(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
+ pr_err("Unsupported api_type %u\n", nt_msg->mpu_cmd.api_type);
+ return -EINVAL;
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_TO_MPU) {
timeout = get_up_timeout_val(mod, cmd);
if (hinic3_pcie_itf_id(hwdev) != SPU_HOST_ID)
@@ -439,6 +346,23 @@ static int sm_rd16(void *hwdev, u32 id, u8 instance,
return ret;
}
+static int sm_rd16_clear(void *hwdev, u32 id, u8 instance,
+ u8 node, struct sm_out_st *buf_out)
+{
+ u16 val1;
+ int ret;
+
+ ret = hinic3_sm_ctr_rd16_clear(hwdev, node, instance, id, &val1);
+ if (ret != 0) {
+ pr_err("Get sm ctr clear information (16 bits)failed!\n");
+ val1 = 0xffff;
+ }
+
+ buf_out->val1 = val1;
+
+ return ret;
+}
+
static int sm_rd32(void *hwdev, u32 id, u8 instance,
u8 node, struct sm_out_st *buf_out)
{
@@ -558,6 +482,7 @@ const struct sm_module_handle sm_module_cmd_handle[] = {
{SM_CTR_RD32, sm_rd32},
{SM_CTR_RD64_PAIR, sm_rd64_pair},
{SM_CTR_RD64, sm_rd64},
+ {SM_CTR_RD16_CLEAR, sm_rd16_clear},
{SM_CTR_RD32_CLEAR, sm_rd32_clear},
{SM_CTR_RD64_PAIR_CLEAR, sm_rd64_pair_clear},
{SM_CTR_RD64_CLEAR, sm_rd64_clear}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
index 83e7b63..c317f4a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
@@ -101,6 +101,12 @@ enum hinic3_pcie_tph {
#define SLAVE_HOST_STATUS_SET(host_id, enable) (((u8)(enable) & 1U) << (host_id))
#define SLAVE_HOST_STATUS_GET(host_id, val) (!!((val) & (1U << (host_id))))
+#ifdef HAVE_HOT_REPLACE_FUNC
+ extern int get_partition_id(void);
+#else
+ static int get_partition_id(void) {return 0; }
+#endif
+
void set_slave_host_enable(void *hwdev, u8 host_id, bool enable)
{
u32 reg_val;
@@ -207,6 +213,27 @@ static void hinic3_init_host_mode_pre(struct hinic3_hwdev *hwdev)
}
}
+static void hinic3_init_hot_plug_status(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->hot_plug_disable)
+ hwdev->hot_plug_mode = HOT_PLUG_DISABLE;
+ else
+ hwdev->hot_plug_mode = HOT_PLUG_ENABLE;
+}
+
+static void hinic3_init_os_hot_replace(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->os_hot_replace) {
+ hwdev->hot_replace_mode = HOT_REPLACE_ENABLE;
+ } else {
+ hwdev->hot_replace_mode = HOT_REPLACE_DISABLE;
+ }
+}
+
static u8 hinic3_nic_sw_aeqe_handler(void *hwdev, u8 event, u8 *data)
{
struct hinic3_hwdev *dev = hwdev;
@@ -270,14 +297,20 @@ static void chip_fault_show(struct hinic3_hwdev *hwdev,
"fatal", "reset", "host", "flr", "general", "suggestion"};
char level_str[FAULT_SHOW_STR_LEN + 1];
u8 level;
+ int ret;
memset(level_str, 0, FAULT_SHOW_STR_LEN + 1);
level = event->event.chip.err_level;
- if (level < FAULT_LEVEL_MAX)
- strscpy(level_str, fault_level[level],
- FAULT_SHOW_STR_LEN);
- else
- strscpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (level < FAULT_LEVEL_MAX) {
+ ret = strscpy(level_str, fault_level[level],
+ FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ } else {
+ ret = strscpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ }
if (level == FAULT_LEVEL_SERIOUS_FLR)
dev_err(hwdev->dev_hdl, "err_level: %u [%s], flr func_id: %u\n",
@@ -299,6 +332,7 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
"reg rd timeout", "reg wr timeout", "phy fault", "tsensor fault"};
char type_str[FAULT_SHOW_STR_LEN + 1] = {0};
struct fault_event_stats *fault = NULL;
+ int ret;
sdk_err(hwdev->dev_hdl, "Fault event report received, func_id: %u\n",
hinic3_global_func_id(hwdev));
@@ -306,10 +340,14 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
fault = &hwdev->hw_stats.fault_event_stats;
if (event->type < FAULT_TYPE_MAX) {
- strscpy(type_str, fault_type[event->type], sizeof(type_str));
+ ret = strscpy(type_str, fault_type[event->type], sizeof(type_str));
+ if (ret < 0)
+ return;
atomic_inc(&fault->fault_type_stat[event->type]);
} else {
- strscpy(type_str, "Unknown", sizeof(type_str));
+ ret = strscpy(type_str, "Unknown", sizeof(type_str));
+ if (ret < 0)
+ return;
}
sdk_err(hwdev->dev_hdl, "Fault type: %u [%s]\n", event->type, type_str);
@@ -1536,15 +1574,29 @@ int hinic3_init_hwdev(struct hinic3_init_para *para)
hinic3_init_host_mode_pre(hwdev);
+ hinic3_init_hot_plug_status(hwdev);
+
+ hinic3_init_os_hot_replace(hwdev);
+
err = hinic3_multi_host_mgmt_init(hwdev);
if (err != 0) {
sdk_err(hwdev->dev_hdl, "Failed to init function mode\n");
goto init_multi_host_fail;
}
- err = hinic3_init_ppf_work(hwdev);
- if (err != 0)
- goto init_ppf_work_fail;
+ // hot_replace_mode is enable, run ppf function only when partition_id is 0
+ // or run ppf function directly
+ if (hwdev->hot_replace_mode == HOT_REPLACE_ENABLE) {
+ if (get_partition_id() == 0) {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0)
+ goto init_ppf_work_fail;
+ }
+ } else {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0)
+ goto init_ppf_work_fail;
+ }
err = hinic3_set_comm_features(hwdev, hwdev->features, COMM_MAX_FEATURE_QWORD);
if (err != 0) {
@@ -1948,6 +2000,19 @@ void hinic3_link_event_stats(void *dev, u8 link)
}
EXPORT_SYMBOL(hinic3_link_event_stats);
+int hinic3_get_link_event_stats(void *dev, int *link_state)
+{
+ struct hinic3_hwdev *hwdev = dev;
+
+ if (!hwdev || !link_state)
+ return -EINVAL;
+
+ *link_state = hwdev->hw_stats.link_event_stats.link_down_stats.counter;
+
+ return 0;
+}
+EXPORT_SYMBOL(hinic3_get_link_event_stats);
+
u8 hinic3_max_pf_num(void *hwdev)
{
if (!hwdev)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
index b8a3356..0ca639f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
@@ -10,6 +10,7 @@
#include "hinic3_hw.h"
#include "mpu_inband_cmd_defs.h"
#include "hinic3_profile.h"
+#include "vram_common.h"
struct cfg_mgmt_info;
@@ -82,6 +83,22 @@ enum hinic3_host_mode_e {
HINIC3_SDI_MODE_MAX,
};
+enum hinic3_hot_plug_mode {
+ HOT_PLUG_ENABLE,
+ HOT_PLUG_DISABLE,
+};
+
+enum hinic3_os_hot_replace_mode {
+ HOT_REPLACE_DISABLE,
+ HOT_REPLACE_ENABLE,
+};
+
+#define UNSUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_DISABLE)
+
+#define SUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_ENABLE)
+
#define MULTI_HOST_CHIP_MODE_SHIFT 0
#define MULTI_HOST_MASTER_MBX_STS_SHIFT 17
#define MULTI_HOST_PRIV_DATA_SHIFT 0x8
@@ -100,6 +117,10 @@ enum hinic3_host_mode_e {
((val) & (~(MULTI_HOST_##member##_MASK \
<< MULTI_HOST_##member##_SHIFT)))
+struct mqm_eqm_vram_name_s {
+ char vram_name[VRAM_NAME_MAX_LEN];
+};
+
struct hinic3_hwdev {
void *adapter_hdl; /* pointer to hinic3_pcidev or NDIS_Adapter */
void *pcidev_hdl; /* pointer to pcidev or Handler */
@@ -138,6 +159,9 @@ struct hinic3_hwdev {
u32 rsvd2;
struct hinic3_multi_host_mgmt *mhost_mgmt;
+ char mhost_mgmt_name[VRAM_NAME_MAX_LEN];
+
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name;
struct mutex stateful_mutex; /* protect cqm init and deinit */
@@ -170,6 +194,8 @@ struct hinic3_hwdev {
struct hinic3_devlink *devlink_dev;
enum hinic3_func_mode func_mode;
+ enum hinic3_hot_plug_mode hot_plug_mode;
+ enum hinic3_os_hot_replace_mode hot_replace_mode;
u32 rsvd3;
DECLARE_BITMAP(func_probe_in_host, MAX_FUNCTION_NUM);
@@ -179,7 +205,10 @@ struct hinic3_hwdev {
u64 last_recv_aeq_cnt;
u16 aeq_busy_cnt;
- u64 rsvd4[8];
+ u64 mbox_send_cnt;
+ u64 mbox_ack_cnt;
+
+ u64 rsvd4[5];
u8 cmdq_mode;
};
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
index 33f1210..8590f70 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
@@ -544,6 +544,7 @@ static void free_db_area(struct hinic3_free_db_area *free_db_area)
{
spin_lock_deinit(&free_db_area->idx_lock);
kfree(free_db_area->db_bitmap_array);
+ free_db_area->db_bitmap_array = NULL;
}
static int get_db_idx(struct hinic3_hwif *hwif, u32 *idx)
@@ -841,6 +842,7 @@ void hinic3_free_hwif(struct hinic3_hwdev *hwdev)
free_db_area(&hwdev->hwif->free_db_area);
enable_all_msix(hwdev);
kfree(hwdev->hwif);
+ hwdev->hwif = NULL;
}
u16 hinic3_global_func_id(void *hwdev)
@@ -856,6 +858,44 @@ u16 hinic3_global_func_id(void *hwdev)
}
EXPORT_SYMBOL(hinic3_global_func_id);
+/**
+ * get function id from register,used by sriov hot migration process
+ * @hwdev: the pointer to hw device
+ */
+u16 hinic3_global_func_id_hw(void *hwdev)
+{
+ u32 addr, attr0;
+ struct hinic3_hwdev *dev;
+
+ dev = (struct hinic3_hwdev *)hwdev;
+ addr = HINIC3_CSR_FUNC_ATTR0_ADDR;
+ attr0 = hinic3_hwif_read_reg(dev->hwif, addr);
+
+ return HINIC3_AF0_GET(attr0, FUNC_GLOBAL_IDX);
+}
+
+/**
+ * get function id, used by sriov hot migratition process.
+ * @hwdev: the pointer to hw device
+ * @func_id: function id
+ */
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id)
+{
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)hwdev;
+
+ if (!hwdev || !func_id)
+ return -EINVAL;
+
+ /* only vf get func_id from chip reg for sriov migrate */
+ if (!HINIC3_IS_VF(dev)) {
+ *func_id = hinic3_global_func_id(hwdev);
+ return 0;
+ }
+
+ *func_id = hinic3_global_func_id_hw(dev);
+ return 0;
+}
+
u16 hinic3_intr_num(void *hwdev)
{
struct hinic3_hwif *hwif = NULL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
index 6ab1b92..1f770db 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
@@ -16,6 +16,7 @@
#include <linux/rtc.h>
#include <linux/aer.h>
#include <linux/debugfs.h>
+#include <linux/notifier.h>
#include "ossl_knl.h"
#include "hinic3_mt.h"
@@ -26,28 +27,55 @@
#include "hinic3_dev_mgmt.h"
#include "hinic3_nictool.h"
#include "hinic3_hw.h"
+#include "hinic3_multi_host_mgmt.h"
+#include "hinic3_hw_cfg.h"
#include "hinic3_lld.h"
#include "hinic3_profile.h"
#include "hinic3_hwdev.h"
#include "hinic3_prof_adap.h"
-#include "comm_msg_intf.h"
+#include "hinic3_devlink.h"
+#include "vram_common.h"
-static bool disable_vf_load;
+
+enum partition_dev_type {
+ PARTITION_DEV_NONE = 0,
+ PARTITION_DEV_SHARED,
+ PARTITION_DEV_EXCLUSIVE,
+ PARTITION_DEV_BACKUP,
+};
+
+#ifdef HAVE_HOT_REPLACE_FUNC
+static int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type,
+ unsigned int partition_id);
+static int get_partition_id(void);
+#else
+static int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type,
+ unsigned int partition_id)
+{
+ return 0;
+}
+static int get_partition_id(void) { return 0; }
+#endif
+
+static bool g_is_pf_migrated = false;
+static bool disable_vf_load = false;
module_param(disable_vf_load, bool, 0444);
MODULE_PARM_DESC(disable_vf_load,
"Disable virtual functions probe or not - default is false");
-static bool disable_attach;
+static bool disable_attach = false;
module_param(disable_attach, bool, 0444);
MODULE_PARM_DESC(disable_attach, "disable_attach or not - default is false");
#define HINIC3_WAIT_SRIOV_CFG_TIMEOUT 15000
-MODULE_AUTHOR("Huawei Technologies CO., Ltd");
-MODULE_DESCRIPTION(HINIC3_DRV_DESC);
-MODULE_VERSION(HINIC3_DRV_VERSION);
-MODULE_LICENSE("GPL");
+#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
+static DEVICE_ATTR_RW(sriov_numvfs, 0644,
+ sriov_numvfs_show, sriov_numvfs_store);
+static DEVICE_ATTR_RO(sriov_totalvfs, 0444,
+ sriov_totalvfs_show, NULL);
+#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
static struct attribute *hinic3_attributes[] = {
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
@@ -64,7 +92,18 @@ static const struct attribute_group hinic3_attr_group = {
struct hinic3_uld_info g_uld_info[SERVICE_T_MAX] = { {0} };
#define HINIC3_EVENT_PROCESS_TIMEOUT 10000
+#define HINIC3_WAIT_EVENT_PROCESS_TIMEOUT 100
struct mutex g_uld_mutex; /* g_uld_info lock */
+#define BUS_MAX_DEV_NUM 256
+#define HINIC3_SLAVE_WORK_MAX_NUM 20
+
+struct vf_offset_info {
+ u8 valid;
+ u16 vf_offset_from_pf[CMD_MAX_MAX_PF_NUM];
+};
+
+static struct vf_offset_info g_vf_offset;
+DEFINE_MUTEX(g_vf_offset_lock);
void hinic3_uld_lock_init(void)
{
@@ -73,13 +112,23 @@ void hinic3_uld_lock_init(void)
static const char *s_uld_name[SERVICE_T_MAX] = {
"nic", "ovs", "roce", "toe", "ioe",
- "fc", "vbs", "ipsec", "virtio", "migrate", "ppa", "bifur", "custom"};
+ "fc", "vbs", "ipsec", "virtio", "migrate",
+ "ppa", "custom", "vroce", "crypt", "vsock", "bifur"};
const char **hinic3_get_uld_names(void)
{
return s_uld_name;
}
+#ifdef CONFIG_PCI_IOV
+static int hinic3_get_pf_device_id(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_dev = pci_physfn(pdev);
+
+ return pf_dev->device;
+}
+#endif
+
static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
const struct hinic3_uld_info *uld_info)
{
@@ -98,6 +147,10 @@ static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
atomic_set(&dev->uld_ref_cnt[type], 0);
+ if (!uld_info->probe) {
+ err = 0;
+ goto out_unlock;
+ }
err = uld_info->probe(&dev->lld_dev, &uld_dev, dev->uld_dev_name[type]);
if (err) {
sdk_err(&dev->pcidev->dev,
@@ -166,6 +219,10 @@ static void detach_uld(struct hinic3_pcidev *dev,
wait_uld_unused(dev, type);
+ if (!uld_info->remove) {
+ mutex_unlock(&dev->pdev_mutex);
+ return;
+ }
uld_info->remove(&dev->lld_dev, dev->uld_dev[type]);
dev->uld_dev[type] = NULL;
@@ -182,11 +239,14 @@ static void attach_ulds(struct hinic3_pcidev *dev)
{
enum hinic3_service_type type;
struct pci_dev *pdev = dev->pcidev;
+ int is_in_kexec = vram_get_kexec_flag();
+
+ if (is_in_kexec == 0)
+ lld_hold();
- lld_hold();
mutex_lock(&g_uld_mutex);
- for (type = SERVICE_T_NIC; type < SERVICE_T_MAX; type++) {
+ for (type = SERVICE_T_OVS; type < SERVICE_T_MAX; type++) {
if (g_uld_info[type].probe) {
if (pdev->is_virtfn &&
(!hinic3_get_vf_service_load(pdev, (u16)type))) {
@@ -198,7 +258,9 @@ static void attach_ulds(struct hinic3_pcidev *dev)
}
}
mutex_unlock(&g_uld_mutex);
- lld_put();
+
+ if (is_in_kexec == 0)
+ lld_put();
}
static void detach_ulds(struct hinic3_pcidev *dev)
@@ -305,7 +367,7 @@ void hinic3_unregister_uld(enum hinic3_service_type type)
}
uld_info = &g_uld_info[type];
- memset(uld_info, 0, sizeof(*uld_info));
+ memset(uld_info, 0, sizeof(struct hinic3_uld_info));
mutex_unlock(&g_uld_mutex);
lld_put();
}
@@ -359,6 +421,26 @@ void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_ser
}
EXPORT_SYMBOL(hinic3_detach_service);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ __module_get(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_get);
+
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ module_put(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_put);
+
static void hinic3_sync_time_to_fmw(struct hinic3_pcidev *pdev_pri)
{
struct timeval tv = {0};
@@ -441,23 +523,447 @@ static void send_event_to_all_pf(struct hinic3_pcidev *dev,
lld_put();
}
+u32 hinic3_pdev_is_virtfn(struct pci_dev *pdev)
+{
+#ifdef CONFIG_PCI_IOV
+ return pdev->is_virtfn;
+#else
+ return 0;
+#endif
+}
+
+static int hinic3_get_function_enable(struct pci_dev *pdev, bool *en)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+ int err;
+
+ /* PF in host os or function in guest os, probe sdk in default */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev) {
+ *en = true;
+ return 0;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev) {
+ /* vf in host and pf sdk not probed */
+ return -EFAULT;
+ }
+ pf_hwdev = pci_adapter->hwdev;
+
+ err = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (err) {
+ sdk_err(&pci_adapter->pcidev->dev,
+ "Func hinic3_get_vfid_by_vfpci fail %d\n", err);
+ return err;
+ }
+
+ err = hinic3_get_func_nic_enable(pf_hwdev, global_func_id, en);
+ if (!!err) {
+ sdk_info(&pdev->dev, "Failed to get function nic status, err %d.\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+int hinic3_set_func_probe_in_host(void *hwdev, u16 func_id, bool probe)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (hinic3_func_type(hwdev) != TYPE_PPF)
+ return -EINVAL;
+
+ if (probe)
+ set_bit(func_id, dev->func_probe_in_host);
+ else
+ clear_bit(func_id, dev->func_probe_in_host);
+
+ return 0;
+}
+
+bool hinic3_get_func_probe_in_host(void *hwdev, u16 func_id)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+ bool probed = false;
+
+ if (!hwdev)
+ return false;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return false;
+ }
+
+ probed = !!test_bit(func_id, ppf_dev->func_probe_in_host);
+ up(&dev->ppf_sem);
+
+ return probed;
+}
+
+void *hinic3_get_ppf_hwdev_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ chip_node = pci_adapter->chip_node;
+ lld_dev_hold(&pci_adapter->lld_dev);
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (dev->lld_state == HINIC3_IN_REMOVE)
+ continue;
+
+ if (dev->hwdev && hinic3_func_type(dev->hwdev) == TYPE_PPF) {
+ lld_dev_put(&pci_adapter->lld_dev);
+ return dev->hwdev;
+ }
+ }
+ lld_dev_put(&pci_adapter->lld_dev);
+
+ return NULL;
+}
+
+static int hinic3_set_vf_nic_used_state(void *hwdev, u16 func_id, bool opened)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+
+ if (!dev || func_id >= MAX_FUNCTION_NUM)
+ return -EINVAL;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return -EINVAL;
+ }
+
+ if (opened)
+ set_bit(func_id, ppf_dev->netdev_setup_state);
+ else
+ clear_bit(func_id, ppf_dev->netdev_setup_state);
+
+ up(&dev->ppf_sem);
+
+ return 0;
+}
+
+static void set_vf_func_in_use(struct pci_dev *pdev, bool in_use)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+
+ /* only need to be set when VF is on the host */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev)
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev)
+ return;
+
+ pf_hwdev = pci_adapter->hwdev;
+
+ global_func_id = (u16)pdev->devfn + hinic3_glb_pf_vf_offset(pf_hwdev);
+ (void)hinic3_set_vf_nic_used_state(pf_hwdev, global_func_id, in_use);
+}
+
+
+static int hinic3_pf_get_vf_offset_info(struct hinic3_pcidev *des_dev, u16 *vf_offset)
+{
+ int err, i;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ u16 pf_func_id;
+ struct hinic3_pcidev *pf_pci_adapter = NULL;
+
+ pf_pci_adapter = (hinic3_pdev_is_virtfn(des_dev->pcidev)) ?
+ pci_get_drvdata(des_dev->pcidev->physfn) : des_dev;
+ pf_func_id = hinic3_global_func_id(pf_pci_adapter->hwdev);
+ if (pf_func_id >= CMD_MAX_MAX_PF_NUM || !vf_offset)
+ return -EINVAL;
+
+ mutex_lock(&g_vf_offset_lock);
+ if (g_vf_offset.valid == 0) {
+ pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ sdk_err(&pf_pci_adapter->pcidev->dev, "Malloc pf_infos fail\n");
+ err = -ENOMEM;
+ goto err_malloc;
+ }
+
+ err = hinic3_get_hw_pf_infos(pf_pci_adapter->hwdev,
+ pf_infos, HINIC3_CHANNEL_COMM);
+ if (err) {
+ sdk_warn(&pf_pci_adapter->pcidev->dev,
+ "Hinic3_get_hw_pf_infos fail err %d\n", err);
+ err = -EFAULT;
+ goto err_out;
+ }
+
+ g_vf_offset.valid = 1;
+ for (i = 0; i < CMD_MAX_MAX_PF_NUM; i++)
+ g_vf_offset.vf_offset_from_pf[i] = pf_infos->infos[i].vf_offset;
+
+ kfree(pf_infos);
+ }
+
+ *vf_offset = g_vf_offset.vf_offset_from_pf[pf_func_id];
+
+ mutex_unlock(&g_vf_offset_lock);
+
+ return 0;
+
+err_out:
+ kfree(pf_infos);
+err_malloc:
+ mutex_unlock(&g_vf_offset_lock);
+ return err;
+}
+
+static struct pci_dev *get_vf_pdev_by_pf(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ int err;
+ u16 bus_num;
+ u16 vf_start, vf_end;
+ u16 des_fn, pf_func_id, vf_offset;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ pf_func_id = hinic3_global_func_id(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end || pf_func_id >= CMD_MAX_MAX_PF_NUM)
+ return NULL;
+
+ err = hinic3_pf_get_vf_offset_info(des_dev, &vf_offset);
+ if (err) {
+ sdk_warn(&des_dev->pcidev->dev, "Hinic3_pf_get_vf_offset_info fail\n");
+ return NULL;
+ }
+
+ des_fn = ((func_id - vf_start) - 1) + pf_func_id + vf_offset;
+ bus_num = des_dev->pcidev->bus->number + des_fn / BUS_MAX_DEV_NUM;
+
+ return pci_get_domain_bus_and_slot(0, bus_num, (des_fn % BUS_MAX_DEV_NUM));
+}
+
+static struct hinic3_pcidev *get_des_pci_adapter(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ struct pci_dev *des_pdev = NULL;
+ u16 vf_start, vf_end;
+ bool probe_in_host = false;
+
+ if (hinic3_global_func_id(des_dev->hwdev) == func_id)
+ return des_dev;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end)
+ return NULL;
+
+ des_pdev = get_vf_pdev_by_pf(des_dev, func_id);
+ if (!des_pdev)
+ return NULL;
+
+ pci_dev_put(des_pdev);
+
+ probe_in_host = hinic3_get_func_probe_in_host(des_dev->hwdev, func_id);
+ if (!probe_in_host)
+ return NULL;
+
+ return pci_get_drvdata(des_pdev);
+}
+
+int __set_vroce_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ u8 enable_vroce = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_vroce_enable(pci_adapter->hwdev,
+ func_id, &enable_vroce);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Failed to get vroce state.\n");
+ return err;
+ }
+
+ mutex_lock(&g_uld_mutex);
+
+ if (!!enable_vroce) {
+ if (!g_uld_info[SERVICE_T_ROCE].probe) {
+ sdk_info(&pdev->dev, "Uld(roce_info) has not been registered!\n");
+ mutex_unlock(&g_uld_mutex);
+ return 0;
+ }
+
+ err = attach_uld(pci_adapter, SERVICE_T_ROCE,
+ &g_uld_info[SERVICE_T_ROCE]);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Failed to initialize VROCE.\n");
+ mutex_unlock(&g_uld_mutex);
+ return err;
+ }
+ } else {
+ sdk_info(&pdev->dev, "Func %u vroce state: disable.\n", func_id);
+ if (g_uld_info[SERVICE_T_ROCE].remove)
+ detach_uld(pci_adapter, SERVICE_T_ROCE);
+ }
+
+ mutex_unlock(&g_uld_mutex);
+
+ return 0;
+}
+
+void slave_host_mgmt_vroce_work(struct work_struct *work)
+{
+#ifndef __HIFC__
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_vroce_work);
+
+ __set_vroce_func_state(pci_adapter);
+#endif
+}
+
+void *hinic3_get_roce_uld_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ return pci_adapter->uld_dev[SERVICE_T_ROCE];
+}
+
+static int func_service_state_process(struct hinic3_pcidev *event_dev,
+ struct hinic3_pcidev *des_dev,
+ struct hinic3_mhost_nic_func_state *state,
+ u16 cmd)
+{
+ int err = 0;
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)event_dev->hwdev;
+
+ switch (cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ state->enable = hinic3_get_roce_uld_by_pdev(des_dev->pcidev) ? 1 : 0;
+ break;
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive nic[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ if (event_dev->multi_host_mgmt_workq) {
+ queue_work(event_dev->multi_host_mgmt_workq,
+ &des_dev->slave_nic_work);
+ } else {
+ sdk_err(&des_dev->pcidev->dev, "Can not schedule slave nic work\n");
+ err = -EFAULT;
+ }
+ break;
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive vroce[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ queue_work_on(hisdk3_get_work_cpu_affinity(dev, WORK_TYPE_MBOX),
+ event_dev->multi_host_mgmt_workq,
+ &des_dev->slave_vroce_work);
+ break;
+ default:
+ sdk_warn(&des_dev->pcidev->dev,
+ "Service state process with unknown cmd: %u\n", cmd);
+ err = -EFAULT;
+ break;
+ }
+
+ return err;
+}
+
+static void multi_host_mgmt(struct hinic3_pcidev *dev,
+ struct hinic3_multi_host_mgmt_event *mhost_mgmt)
+{
+ struct hinic3_pcidev *cur_dev = NULL;
+ struct hinic3_pcidev *des_dev = NULL;
+ struct hinic3_mhost_nic_func_state *nic_state = NULL;
+ u16 sub_cmd = mhost_mgmt->sub_cmd;
+
+ switch (sub_cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ nic_state = mhost_mgmt->data;
+ nic_state->status = 0;
+ if (!dev->hwdev)
+ return;
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)dev->hwdev))
+ return;
+
+ /* find func_idx pci_adapter and disable or enable nic */
+ lld_dev_hold(&dev->lld_dev);
+ list_for_each_entry(cur_dev, &dev->chip_node->func_list, node) {
+ if (cur_dev->lld_state == HINIC3_IN_REMOVE ||
+ hinic3_pdev_is_virtfn(cur_dev->pcidev))
+ continue;
+
+ des_dev = get_des_pci_adapter(cur_dev, nic_state->func_idx);
+ if (!des_dev)
+ continue;
+
+ if (func_service_state_process(dev, des_dev, nic_state, sub_cmd))
+ nic_state->status = 1;
+ break;
+ }
+ lld_dev_put(&dev->lld_dev);
+ break;
+ default:
+ sdk_warn(&dev->pcidev->dev, "Received unknown multi-host mgmt event: %u\n",
+ mhost_mgmt->sub_cmd);
+ break;
+ }
+}
+
static void hinic3_event_process(void *adapter, struct hinic3_event_info *event)
{
struct hinic3_pcidev *dev = adapter;
struct hinic3_fault_event *fault = (void *)event->event_data;
+ struct hinic3_multi_host_mgmt_event *mhost_event =
+ (void *)event->event_data;
u16 func_id;
- if ((event->service == EVENT_SRV_COMM && event->type == EVENT_COMM_FAULT) &&
- fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
- fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
- func_id = fault->event.chip.func_id;
- return send_event_to_dst_pf(adapter, func_id, event);
- }
-
- if (event->type == EVENT_COMM_MGMT_WATCHDOG)
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MULTI_HOST_MGMT):
+ multi_host_mgmt(dev, mhost_event);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_FAULT):
+ if (fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
+ fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
+ func_id = fault->event.chip.func_id;
+ return send_event_to_dst_pf(adapter, func_id, event);
+ }
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MGMT_WATCHDOG):
send_event_to_all_pf(adapter, event);
- else
+ break;
+ default:
send_uld_dev_event(adapter, event);
+ break;
+ }
}
static void uld_def_init(struct hinic3_pcidev *pci_adapter)
@@ -605,31 +1111,70 @@ static void hinic3_pci_deinit(struct pci_dev *pdev)
kfree(pci_adapter);
}
-#ifdef CONFIG_X86
-/**
- * cfg_order_reg - when cpu model is haswell or broadwell, should configure dma
- * order register to zero
- * @pci_adapter: pci_adapter
- **/
-/*lint -save -e40 */
-static void cfg_order_reg(struct hinic3_pcidev *pci_adapter)
+static void set_vf_load_state(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
{
- u8 cpu_model[] = {0x3c, 0x3f, 0x45, 0x46, 0x3d, 0x47, 0x4f, 0x56};
- struct cpuinfo_x86 *cpuinfo = NULL;
- u32 i;
+ /* In bm mode, slave host will load vfs in default */
+ if (IS_BMGW_SLAVE_HOST(((struct hinic3_hwdev *)pci_adapter->hwdev)) &&
+ hinic3_func_type(pci_adapter->hwdev) != TYPE_VF)
+ hinic3_set_vf_load_state(pdev, false);
- if (hinic3_func_type(pci_adapter->hwdev) == TYPE_VF)
- return;
+ if (!disable_attach) {
+ if ((hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) &&
+ hinic3_is_bm_slave_host(pci_adapter->hwdev)) {
+ if (hinic3_func_max_vf(pci_adapter->hwdev) == 0) {
+ sdk_warn(&pdev->dev, "The sriov enabling process is skipped, vfs_num: 0.\n");
+ return;
+ }
+ hinic3_pci_sriov_enable(
+ pdev, hinic3_func_max_vf(pci_adapter->hwdev));
+ }
+ }
+}
- cpuinfo = &cpu_data(0);
- for (i = 0; i < sizeof(cpu_model); i++) {
- if (cpu_model[i] == cpuinfo->x86_model)
- hinic3_set_pcie_order_cfg(pci_adapter->hwdev);
+static void hinic3_init_ppf_hwdev(struct hinic3_hwdev *hwdev)
+{
+ if (!hwdev) {
+ pr_err("[%s:%d] null hwdev pointer\n", __FILE__, __LINE__);
+ return;
}
+
+ hwdev->ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(hwdev->pcidev_hdl);
}
-/*lint -restore*/
-#endif
+static int set_nic_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ bool enable_nic = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_nic_enable(pci_adapter->hwdev, func_id, &enable_nic);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Failed to get nic state.\n");
+ return err;
+ }
+
+ if (!enable_nic) {
+ sdk_info(&pdev->dev, "Func %u nic state: disable.\n", func_id);
+ detach_uld(pci_adapter, SERVICE_T_NIC);
+ return 0;
+ }
+
+ if (IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ (void)hinic3_init_vf_dev_cap(pci_adapter->hwdev);
+
+ if (g_uld_info[SERVICE_T_NIC].probe) {
+ err = attach_uld(pci_adapter, SERVICE_T_NIC, &g_uld_info[SERVICE_T_NIC]);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Initialize NIC failed\n");
+ return err;
+ }
+ }
+
+ return 0;
+}
static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
{
@@ -689,7 +1234,16 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
list_add_tail(&pci_adapter->node, &pci_adapter->chip_node->func_list);
lld_unlock_chip_node();
+ hinic3_init_ppf_hwdev((struct hinic3_hwdev *)pci_adapter->hwdev);
+
+ set_vf_load_state(pdev, pci_adapter);
+
if (!disable_attach) {
+ /* NIC is base driver, probe firstly */
+ err = set_nic_func_state(pci_adapter);
+ if (err)
+ goto set_nic_func_state_err;
+
attach_ulds(pci_adapter);
if (hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) {
@@ -700,10 +1254,6 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
goto create_sysfs_err;
}
}
-
-#ifdef CONFIG_X86
- cfg_order_reg(pci_adapter);
-#endif
}
return 0;
@@ -711,6 +1261,8 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
create_sysfs_err:
detach_ulds(pci_adapter);
+
+set_nic_func_state_err:
lld_lock_chip_node();
list_del(&pci_adapter->node);
lld_unlock_chip_node();
@@ -759,6 +1311,7 @@ static void hinic3_func_deinit(struct pci_dev *pdev)
hinic3_free_stateful(pci_adapter->hwdev);
hinic3_free_hwdev(pci_adapter->hwdev);
+ pci_adapter->hwdev = NULL;
}
static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
@@ -770,14 +1323,57 @@ static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
clear_bit(HINIC3_FUNC_PERSENT, &sriov_info->state);
usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- end = jiffies + msecs_to_jiffies(HINIC3_WAIT_SRIOV_CFG_TIMEOUT);
- do {
- if (!test_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state) &&
- !test_bit(HINIC3_SRIOV_DISABLE, &sriov_info->state))
- return;
+ end = jiffies + msecs_to_jiffies(HINIC3_WAIT_SRIOV_CFG_TIMEOUT);
+ do {
+ if (!test_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state) &&
+ !test_bit(HINIC3_SRIOV_DISABLE, &sriov_info->state))
+ return;
+
+ usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
+ } while (time_before(jiffies, end));
+}
+
+static bool hinic3_get_vf_nic_en_status(struct pci_dev *pdev)
+{
+ bool nic_en = false;
+ u16 global_func_id;
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev) {
+ pr_err("pdev is null.\n");
+ return false;
+ }
+
+ if (pdev->is_virtfn)
+ pf_pdev = pdev->physfn;
+ else
+ return false;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return false;
+ }
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ return false;
+
+ if (hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id)) {
+ sdk_err(&pdev->dev, "Get vf id by vfpci failed\n");
+ return false;
+ }
+
+ if (hinic3_get_mhost_func_nic_enable(pci_adapter->hwdev,
+ global_func_id, &nic_en)) {
+ sdk_err(&pdev->dev, "Get function nic status failed\n");
+ return false;
+ }
+
+ sdk_info(&pdev->dev, "Func %hu %s default probe in host\n",
+ global_func_id, (nic_en) ? "enable" : "disable");
- usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- } while (time_before(jiffies, end));
+ return nic_en;
}
bool hinic3_get_vf_load_state(struct pci_dev *pdev)
@@ -834,6 +1430,8 @@ int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state)
}
EXPORT_SYMBOL(hinic3_set_vf_load_state);
+
+
bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service)
{
struct hinic3_pcidev *pci_adapter = NULL;
@@ -897,6 +1495,32 @@ int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
}
EXPORT_SYMBOL(hinic3_set_vf_service_load);
+static bool hinic3_is_host_vmsec_enable(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct pci_dev *pf_pdev = NULL;
+
+ if (pdev->is_virtfn)
+ pf_pdev = pdev->physfn;
+ else
+ pf_pdev = pdev;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ pr_err("Pci_adapter is null.\n");
+ return false;
+ }
+
+ /* pf/vf used in host */
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ (hinic3_func_type(pci_adapter->hwdev) == TYPE_PF) &&
+ IS_RDMA_TYPE((struct hinic3_hwdev *)pci_adapter->hwdev)) {
+ return true;
+ }
+
+ return false;
+}
+
static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
@@ -910,6 +1534,13 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
pci_adapter->lld_state = HINIC3_IN_REMOVE;
mutex_unlock(&pci_adapter->pdev_mutex);
+ if (!(pdev->is_virtfn) && (hinic3_is_host_vmsec_enable(pdev) == true) &&
+ (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF)) {
+ cancel_delayed_work_sync(&pci_adapter->migration_probe_dwork);
+ flush_workqueue(pci_adapter->migration_probe_workq);
+ destroy_workqueue(pci_adapter->migration_probe_workq);
+ }
+
hinic3_detect_hw_present(pci_adapter->hwdev);
hisdk3_remove_pre_process(pci_adapter->hwdev);
@@ -934,23 +1565,128 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
sdk_info(&pdev->dev, "Pcie device removed function\n");
+ set_vf_func_in_use(pdev, false);
+
return 0;
}
+int hinic3_get_vfid_by_vfpci(void *hwdev, struct pci_dev *pdev, u16 *global_func_id)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ u16 pf_bus, vf_bus, vf_offset;
+ int err;
+
+ if (!pdev || !global_func_id || !hinic3_pdev_is_virtfn(pdev))
+ return -EINVAL;
+ (void)hwdev;
+ pf_pdev = pdev->physfn;
+
+ vf_bus = pdev->bus->number;
+ pf_bus = pf_pdev->bus->number;
+
+ if (pdev->vendor == HINIC3_VIRTIO_VNEDER_ID)
+ return -EPERM;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return -EINVAL;
+ }
+
+ err = hinic3_pf_get_vf_offset_info(pci_adapter, &vf_offset);
+ if (err) {
+ sdk_err(&pdev->dev, "Func hinic3_pf_get_vf_offset_info fail\n");
+ return -EFAULT;
+ }
+
+ *global_func_id = (u16)((vf_bus - pf_bus) * BUS_MAX_DEV_NUM) + (u16)pdev->devfn +
+ (u16)(CMD_MAX_MAX_PF_NUM - g_vf_offset.vf_offset_from_pf[0]);
+
+ return 0;
+}
+EXPORT_SYMBOL(hinic3_get_vfid_by_vfpci);
+
+static void hinic3_set_vf_status_in_host(struct pci_dev *pdev, bool status)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ void *ppf_hwdev = NULL;
+ u16 global_func_id;
+ int ret;
+
+ if (!pf_pdev)
+ return;
+
+ if (!hinic3_pdev_is_virtfn(pdev))
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ pf_hwdev = pci_adapter->hwdev;
+ ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(pf_pdev);
+ if (!pf_hwdev || !ppf_hwdev)
+ return;
+
+ ret = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (ret) {
+ sdk_err(&pci_adapter->pcidev->dev,
+ "Func hinic3_get_vfid_by_vfpci fail %d\n", ret);
+ return;
+ }
+
+ ret = hinic3_set_func_probe_in_host(ppf_hwdev, global_func_id, status);
+ if (ret)
+ sdk_err(&pci_adapter->pcidev->dev,
+ "Set the function probe status in host failed\n");
+}
+
+#ifdef CONFIG_PCI_IOV
+/* Check whether pdev is a VF and whether it belongs to the PF of the SDI card */
+static bool check_pdev_type_and_state(struct pci_dev *pdev)
+{
+ if (!(pdev->is_virtfn))
+ return false;
+
+ if ((hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_1_PF) &&
+ (hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_0_PF)) {
+ return false;
+ }
+
+ if (!hinic3_get_vf_load_state(pdev))
+ return false;
+
+ return true;
+}
+#endif
+
static void hinic3_remove(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
+ sdk_info(&pdev->dev, "Pcie device remove begin\n");
+
if (!pci_adapter)
- return;
+ goto out;
- sdk_info(&pdev->dev, "Pcie device remove begin\n");
+
+#ifdef CONFIG_PCI_IOV
+ if (check_pdev_type_and_state(pdev))
+ goto out;
+#endif
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
hinic3_remove_func(pci_adapter);
+ if (!pci_adapter->pcidev->is_virtfn &&
+ pci_adapter->multi_host_mgmt_workq)
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
hinic3_pci_deinit(pdev);
hinic3_probe_pre_unprocess(pdev);
+out:
+ hinic3_set_vf_status_in_host(pdev, false);
sdk_info(&pdev->dev, "Pcie device removed\n");
}
@@ -969,7 +1705,7 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
if (pci_adapter->lld_state >= HINIC3_PROBE_START) {
sdk_warn(&pdev->dev, "Don not probe repeat\n");
mutex_unlock(&pci_adapter->pdev_mutex);
- return 0;
+ return -EEXIST;
}
pci_adapter->lld_state = HINIC3_PROBE_START;
mutex_unlock(&pci_adapter->pdev_mutex);
@@ -977,15 +1713,28 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
return 0;
}
+static void hinic3_probe_success_process(struct hinic3_pcidev *pci_adapter)
+{
+ hinic3_probe_success(pci_adapter->hwdev);
+
+ mutex_lock(&pci_adapter->pdev_mutex);
+ pci_adapter->lld_state = HINIC3_PROBE_OK;
+ mutex_unlock(&pci_adapter->pdev_mutex);
+}
+
static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
int err;
err = probe_func_param_init(pci_adapter);
- if (err)
+ if (err == -EEXIST)
+ return 0;
+ else if (err)
return err;
+ set_vf_func_in_use(pdev, true);
+
err = mapping_bar(pdev, pci_adapter);
if (err) {
sdk_err(&pdev->dev, "Failed to map bar\n");
@@ -1017,11 +1766,7 @@ static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
}
}
- hinic3_probe_success(pci_adapter->hwdev);
-
- mutex_lock(&pci_adapter->pdev_mutex);
- pci_adapter->lld_state = HINIC3_PROBE_OK;
- mutex_unlock(&pci_adapter->pdev_mutex);
+ hinic3_probe_success_process(pci_adapter);
return 0;
@@ -1037,18 +1782,298 @@ alloc_chip_node_fail:
unmapping_bar(pci_adapter);
map_bar_failed:
+ set_vf_func_in_use(pdev, false);
sdk_err(&pdev->dev, "Pcie device probe function failed\n");
return err;
}
+void hinic3_set_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int err;
+ bool enable_func = false;
+
+ err = hinic3_get_function_enable(pdev, &enable_func);
+ if (err) {
+ sdk_info(&pdev->dev, "Get function enable failed\n");
+ return;
+ }
+
+ sdk_info(&pdev->dev, "%s function resource start\n",
+ enable_func ? "Initialize" : "Free");
+ if (enable_func) {
+ err = hinic3_probe_func(pci_adapter);
+ if (err)
+ sdk_info(&pdev->dev, "Function probe failed\n");
+ } else {
+ hinic3_remove_func(pci_adapter);
+ }
+ if (err == 0)
+ sdk_info(&pdev->dev, "%s function resource end\n",
+ enable_func ? "Initialize" : "Free");
+}
+
+void slave_host_mgmt_work(struct work_struct *work)
+{
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_nic_work);
+
+ if (hinic3_pdev_is_virtfn(pci_adapter->pcidev))
+ hinic3_set_func_state(pci_adapter);
+ else
+ set_nic_func_state(pci_adapter);
+}
+
+static int pci_adapter_assign_val(struct hinic3_pcidev **ppci_adapter,
+ struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ *ppci_adapter = pci_get_drvdata(pdev);
+ (*ppci_adapter)->disable_vf_load = disable_vf_load;
+ (*ppci_adapter)->id = *id;
+ (*ppci_adapter)->lld_state = HINIC3_NOT_PROBE;
+ (*ppci_adapter)->probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ lld_dev_cnt_init(*ppci_adapter);
+
+ (*ppci_adapter)->multi_host_mgmt_workq = alloc_workqueue(
+ "hinic_mhost_mgmt",
+ WQ_UNBOUND,
+ HINIC3_SLAVE_WORK_MAX_NUM);
+ if (!(*ppci_adapter)->multi_host_mgmt_workq) {
+ hinic3_pci_deinit(pdev);
+ sdk_err(&pdev->dev, "Alloc multi host mgmt workqueue failed\n");
+ return -ENOMEM;
+ }
+
+ INIT_WORK(&(*ppci_adapter)->slave_nic_work, slave_host_mgmt_work);
+ INIT_WORK(&(*ppci_adapter)->slave_vroce_work,
+ slave_host_mgmt_vroce_work);
+
+ return 0;
+}
+
+static void slave_host_vfio_probe_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_pcidev *pci_adapter = container_of(delay, struct hinic3_pcidev,
+ migration_probe_dwork);
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int (*dev_migration_probe)(struct pci_dev *pdev);
+ int rc;
+
+ if (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) != TYPE_PF)
+ return;
+
+ dev_migration_probe = __symbol_get("migration_dev_migration_probe");
+ if (!(dev_migration_probe)) {
+ sdk_err(&pdev->dev,
+ "Failed to find: migration_dev_migration_probe");
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork,
+ WAIT_TIME * HZ);
+ } else {
+ rc = dev_migration_probe(pdev);
+ __symbol_put("migration_dev_migration_probe");
+ if (rc) {
+ sdk_err(&pdev->dev,
+ "Failed to __dev_migration_probe, rc:0x%x, pf migrated(%d).\n",
+ rc, g_is_pf_migrated);
+ } else {
+ g_is_pf_migrated = true;
+ sdk_info(&pdev->dev,
+ "Succeeded in __dev_migration_probe, pf migrated(%d).\n",
+ g_is_pf_migrated);
+ }
+ }
+}
+
+struct vf_add_delaywork {
+ struct pci_dev *vf_pdev;
+ struct delayed_work migration_vf_add_dwork;
+};
+
+static void slave_host_migration_vf_add_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct vf_add_delaywork *vf_add = container_of(delay, struct vf_add_delaywork,
+ migration_vf_add_dwork);
+ struct pci_dev *vf_pdev = vf_add->vf_pdev;
+ struct pci_dev *pf_pdev = NULL;
+ int (*migration_dev_add_vf)(struct pci_dev *vf_pdev);
+ int ret;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!vf_pdev) {
+ pr_err("vf pdev is null.\n");
+ goto err1;
+ }
+ if (!vf_pdev->is_virtfn) {
+ sdk_err(&vf_pdev->dev, "Pdev is not virtfn.\n");
+ goto err1;
+ }
+
+ pf_pdev = vf_pdev->physfn;
+ if (!pf_pdev) {
+ sdk_err(&vf_pdev->dev, "pf_pdev is null.\n");
+ goto err1;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&vf_pdev->dev, "Pci_adapter is null.\n");
+ goto err1;
+ }
+
+ if (!g_is_pf_migrated) {
+ sdk_info(&vf_pdev->dev, "pf is not migrated yet, so vf continues to try again.\n");
+ goto delay_work;
+ }
+
+ migration_dev_add_vf = __symbol_get("migration_dev_add_vf");
+ if (migration_dev_add_vf) {
+ ret = migration_dev_add_vf(vf_pdev);
+ __symbol_put("migration_dev_add_vf");
+ if (ret)
+ sdk_err(&vf_pdev->dev, "vf get migration symbol succeeded, but dev add vf failed, ret:%d.\n",
+ ret);
+ else
+ sdk_info(&vf_pdev->dev, "vf get migration symbol succeeded, and dev add vf success.\n");
+ goto err1;
+ }
+ sdk_info(&vf_pdev->dev, "pf is migrated, but vf get migration symbol failed.\n");
+
+delay_work:
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork, WAIT_TIME * HZ);
+ return;
+
+err1:
+ kfree(vf_add);
+}
+
+static void hinic3_probe_vf_add_dwork(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!hinic3_is_host_vmsec_enable(pdev))
+ return;
+
+#if defined(CONFIG_SP_VID_DID)
+ if ((pdev->vendor == PCI_VENDOR_ID_SPNIC) && (pdev->device == HINIC3_DEV_SDI_5_1_ID_VF)) {
+#elif defined(CONFIG_NF_VID_DID)
+ if ((pdev->vendor == PCI_VENDOR_ID_NF) && (pdev->device == NFNIC_DEV_ID_VF)) {
+#else
+ if ((pdev->vendor == PCI_VENDOR_ID_HUAWEI) && (pdev->device == HINIC3_DEV_SDI_5_0_ID_VF)) {
+#endif
+ struct vf_add_delaywork *vf_add = kmalloc(sizeof(struct vf_add_delaywork),
+ GFP_ATOMIC);
+
+ if (!vf_add) {
+ sdk_info(&pdev->dev, "vf_add is null.\n");
+ return;
+ }
+ vf_add->vf_pdev = pdev;
+
+ pf_pdev = pdev->physfn;
+
+ if (!pf_pdev) {
+ sdk_info(&pdev->dev, "Vf-pf_pdev is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_info(&pdev->dev, "Pci_adapter is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ INIT_DELAYED_WORK(&vf_add->migration_vf_add_dwork,
+ slave_host_migration_vf_add_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork,
+ WAIT_TIME * HZ);
+ }
+}
+
+static int hinic3_probe_migration_dwork(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+{
+ if (!hinic3_is_host_vmsec_enable(pdev)) {
+ sdk_info(&pdev->dev, "Probe_migration : hinic3_is_host_vmsec_enable is (0).\n");
+ return 0;
+ }
+
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF) {
+ pci_adapter->migration_probe_workq =
+ create_singlethread_workqueue("hinic3_migration_probe_delay");
+ if (!pci_adapter->migration_probe_workq) {
+ sdk_err(&pdev->dev, "Failed to create work queue:%s\n",
+ "hinic3_migration_probe_delay");
+ return -EINVAL;
+ }
+
+ INIT_DELAYED_WORK(&pci_adapter->migration_probe_dwork,
+ slave_host_vfio_probe_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork, WAIT_TIME * HZ);
+ }
+
+ return 0;
+}
+
+static bool hinic3_os_hot_replace_allow(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_hwdev *hwdev = (struct hinic3_hwdev *)pci_adapter->hwdev;
+ // check service enable and dev is not VF
+ if (hinic3_func_type(hwdev) == TYPE_VF || hwdev->hot_replace_mode == HOT_REPLACE_DISABLE)
+ return false;
+
+ return true;
+}
+
+static bool hinic3_os_hot_replace_process(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_board_info *board_info;
+ u16 cur_pf_id = hinic3_global_func_id(pci_adapter->hwdev);
+ u8 cur_partion_id;
+
+ board_info = &((struct hinic3_hwdev *)(pci_adapter->hwdev))->board_info;
+ // probe to os
+ vpci_set_partition_attrs(pci_adapter->pcidev, PARTITION_DEV_EXCLUSIVE,
+ get_function_partition(cur_pf_id, board_info->port_num));
+
+ // check pf_id is in the right partition_id
+ cur_partion_id = get_partition_id();
+ if (get_function_partition(cur_pf_id, board_info->port_num) ==
+ cur_partion_id)
+ return true;
+
+ pci_adapter->probe_fault_level = FAULT_LEVEL_SUGGESTION;
+ return false;
+}
+
static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct hinic3_pcidev *pci_adapter = NULL;
u16 probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ u32 device_id, function_id;
int err;
sdk_info(&pdev->dev, "Pcie device probe begin\n");
+#ifdef CONFIG_PCI_IOV
+ hinic3_set_vf_status_in_host(pdev, true);
+ if (check_pdev_type_and_state(pdev)) {
+ sdk_info(&pdev->dev, "VFs are not binded to hinic\n");
+ hinic3_probe_vf_add_dwork(pdev);
+ return -EINVAL;
+ }
+#endif
+
err = hinic3_probe_pre_process(pdev);
if (err != 0 && err != HINIC3_NOT_PROBE)
goto out;
@@ -1060,26 +2085,48 @@ static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (err)
goto pci_init_err;
- pci_adapter = pci_get_drvdata(pdev);
- pci_adapter->disable_vf_load = disable_vf_load;
- pci_adapter->id = *id;
- pci_adapter->lld_state = HINIC3_NOT_PROBE;
- pci_adapter->probe_fault_level = probe_fault_level;
- lld_dev_cnt_init(pci_adapter);
+ err = pci_adapter_assign_val(&pci_adapter, pdev, id);
+ if (err)
+ goto allco_queue_err;
- if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev))) {
+ if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev)) &&
+ (!hinic3_get_vf_nic_en_status(pdev))) {
sdk_info(&pdev->dev, "VF device disable load in host\n");
return 0;
}
- err = hinic3_probe_func(pci_adapter);
- if (err)
+ if (hinic3_probe_func(pci_adapter))
+ goto hinic3_probe_func_fail;
+
+ if (hinic3_os_hot_replace_allow(pci_adapter)) {
+ if (!hinic3_os_hot_replace_process(pci_adapter)) {
+ device_id = PCI_SLOT(pdev->devfn);
+ function_id = PCI_FUNC(pdev->devfn);
+ sdk_info(&pdev->dev,
+ "os hot replace: skip function %d:%d for partition %d",
+ device_id, function_id, get_partition_id());
+ goto os_hot_repalce_not_allow;
+ }
+ }
+
+ if (hinic3_probe_migration_dwork(pdev, pci_adapter))
goto hinic3_probe_func_fail;
sdk_info(&pdev->dev, "Pcie device probed\n");
return 0;
+os_hot_repalce_not_allow:
+ hinic3_func_deinit(pdev);
+ lld_lock_chip_node();
+ free_chip_node(pci_adapter);
+ lld_unlock_chip_node();
+ unmapping_bar(pci_adapter);
+ set_vf_func_in_use(pdev, false);
hinic3_probe_func_fail:
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
+allco_queue_err:
probe_fault_level = pci_adapter->probe_fault_level;
hinic3_pci_deinit(pdev);
@@ -1105,6 +2152,11 @@ static int hinic3_get_pf_info(struct pci_dev *pdev, u16 service,
}
*pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (*pf_infos == NULL) {
+ sdk_err(&pdev->dev, "pf_infos kzalloc failed\n");
+ return -EFAULT;
+ }
+
err = hinic3_get_hw_pf_infos(dev->hwdev, *pf_infos, HINIC3_CHANNEL_COMM);
if (err) {
kfree(*pf_infos);
@@ -1120,6 +2172,7 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
{
int err;
+ mutex_lock(&dst_dev->pdev_mutex);
/* unload invalid vf func id */
if (!en && vf_func_id != hinic3_global_func_id(dst_dev->hwdev) &&
!strcmp(des_pdev->driver->name, HINIC3_DRV_NAME)) {
@@ -1137,6 +2190,8 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
err = hinic3_probe_func(dst_dev);
if (err)
return -EFAULT;
+ } else {
+ mutex_unlock(&dst_dev->pdev_mutex);
}
return 0;
@@ -1161,7 +2216,6 @@ static int get_vf_service_state_param(struct pci_dev *pdev, struct hinic3_pcidev
return 0;
}
-#define BUS_MAX_DEV_NUM 256
static int hinic3_dst_pdev_valid(struct hinic3_pcidev *dst_dev, struct pci_dev **des_pdev_ptr,
u16 vf_devfn, bool en)
{
@@ -1175,7 +2229,7 @@ static int hinic3_dst_pdev_valid(struct hinic3_pcidev *dst_dev, struct pci_dev
return -EFAULT;
}
- if (!(*des_pdev_ptr)->driver) {
+ if ((*des_pdev_ptr)->driver == NULL) {
pr_err("des_pdev_ptr->driver is NULL\n");
return -EFAULT;
}
@@ -1243,7 +2297,6 @@ int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id, u16 servic
if (en)
pci_dev_put(des_pdev);
- mutex_lock(&dst_dev->pdev_mutex);
find_dst_dev = true;
break;
}
@@ -1263,19 +2316,30 @@ free_pf_info:
}
EXPORT_SYMBOL(hinic3_set_vf_service_state);
-/*lint -save -e133 -e10*/
static const struct pci_device_id hinic3_pci_table[] = {
+#if defined(CONFIG_SP_VID_DID)
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_STANDARD), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_SDI_5_1_PF), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_SDI_5_0_PF), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_SPN120), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_VF), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_SDI_5_1_ID_VF), 0},
+#elif defined(CONFIG_NF_VID_DID)
+ {PCI_VDEVICE(NF, NFNIC_DEV_ID_STANDARD), 0},
+ {PCI_VDEVICE(NF, NFNIC_DEV_ID_VF), 0},
+#else
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SPU), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_STANDARD), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_1_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_SDI_5_1_ID_VF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_VF), 0},
+#endif
{0, 0}
};
-/*lint -restore*/
-
MODULE_DEVICE_TABLE(pci, hinic3_pci_table);
/**
@@ -1307,14 +2371,27 @@ static pci_ers_result_t hinic3_io_error_detected(struct pci_dev *pdev,
return PCI_ERS_RESULT_CAN_RECOVER;
}
+static void hinic3_timer_disable(void *hwdev)
+{
+ if (!hwdev)
+ return;
+
+ if (hinic3_get_stateful_enable(hwdev) && hinic3_get_timer_enable(hwdev))
+ (void)hinic3_func_tmr_bitmap_set(hwdev,
+ hinic3_global_func_id(hwdev),
+ false);
+}
+
static void hinic3_shutdown(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
sdk_info(&pdev->dev, "Shutdown device\n");
- if (pci_adapter)
+ if (pci_adapter) {
+ hinic3_timer_disable(pci_adapter->hwdev);
hinic3_shutdown_hwdev(pci_adapter->hwdev);
+ }
pci_disable_device(pdev);
@@ -1341,6 +2418,9 @@ static struct pci_driver hinic3_driver = {
.probe = hinic3_probe,
.remove = hinic3_remove,
.shutdown = hinic3_shutdown,
+#ifdef CONFIG_PARTITION_DEVICE
+ .driver.probe_concurrency = true,
+#endif
#if defined(HAVE_SRIOV_CONFIGURE)
.sriov_configure = hinic3_pci_sriov_configure,
#elif defined(HAVE_RHEL6_SRIOV_CONFIGURE)
@@ -1362,16 +2442,21 @@ int hinic3_lld_init(void)
err = hinic3_module_pre_init();
if (err) {
pr_err("Init custom failed\n");
- return err;
+ goto module_pre_init_err;
}
err = pci_register_driver(&hinic3_driver);
if (err) {
- hinic3_module_post_exit();
- return err;
+ pr_err("sdk3 pci register driver failed\n");
+ goto register_pci_driver_err;
}
return 0;
+
+register_pci_driver_err:
+ hinic3_module_post_exit();
+module_pre_init_err:
+ return err;
}
void hinic3_lld_exit(void)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
index b2851c6..3626262 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
@@ -584,6 +584,7 @@ static void free_recv_mbox(struct hinic3_recv_mbox *recv_msg)
kfree(recv_msg->resp_buff);
kfree(recv_msg->msg);
kfree(recv_msg);
+ recv_msg = NULL;
}
static void recv_func_mbox_work_handler(struct work_struct *work)
@@ -1232,6 +1233,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
set_mbox_to_func_event(func_to_func, EVENT_FAIL);
goto send_err;
}
+ func_to_func->hwdev->mbox_send_cnt++;
if (wait_mbox_msg_completion(func_to_func, timeout) != 0) {
sdk_err(func_to_func->hwdev->dev_hdl,
@@ -1240,6 +1242,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
err = -ETIMEDOUT;
goto send_err;
}
+ func_to_func->hwdev->mbox_ack_cnt++;
if (mod != msg_desc->mod || cmd != msg_desc->cmd) {
sdk_err(func_to_func->hwdev->dev_hdl,
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
index 2bd63f1..4718458 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
@@ -861,6 +861,7 @@ static int alloc_recv_msg(struct hinic3_recv_msg *recv_msg)
static void free_recv_msg(struct hinic3_recv_msg *recv_msg)
{
kfree(recv_msg->msg);
+ recv_msg->msg = NULL;
}
/**
@@ -932,6 +933,9 @@ static void free_msg_buf(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt)
free_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
+ pf_to_mgmt->mgmt_ack_buf = NULL;
+ pf_to_mgmt->sync_msg_buf = NULL;
+ pf_to_mgmt->async_msg_buf = NULL;
}
/**
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
index 3548410..a0f5e73 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
@@ -676,6 +676,9 @@ static int hinic3_register_slave_ppf(struct hinic3_hwdev *hwdev, bool registered
if (!IS_SLAVE_HOST(hwdev))
return -EINVAL;
+ if (UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev))
+ return 0;
+
host_info = kcalloc(1, sizeof(struct register_slave_host), GFP_KERNEL);
if (!host_info)
return -ENOMEM;
@@ -1075,7 +1078,8 @@ int hinic3_get_func_nic_enable(void *hwdev, u16 glb_func_idx, bool *en)
return -EINVAL;
/* if single host, return true. */
- if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev)) {
+ if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev) ||
+ UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev)) {
*en = true;
return 0;
}
@@ -1145,11 +1149,21 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
{
int err;
struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+ int is_use_vram, is_in_kexec;
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
- hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0) {
+ snprintf(hwdev->mhost_mgmt_name, VRAM_NAME_MAX_LEN, "%s",
+ VRAM_NIC_MHOST_MGMT);
+ hwdev->mhost_mgmt = hi_vram_kalloc(hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ } else {
+ hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ }
+
if (!hwdev->mhost_mgmt)
return -ENOMEM;
@@ -1165,8 +1179,11 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK, hwdev, hilink_ppf_mbox_handler);
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC, hwdev, sw_func_ppf_mbox_handler);
- bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
- bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ }
/* Slave host:
* register slave host ppf functions
@@ -1179,7 +1196,11 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
return 0;
out_free_mhost_mgmt:
- kfree(hwdev->mhost_mgmt);
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)hwdev->mhost_mgmt, hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ else
+ kfree(hwdev->mhost_mgmt);
hwdev->mhost_mgmt = NULL;
return err;
@@ -1187,6 +1208,8 @@ out_free_mhost_mgmt:
int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
{
+ int is_use_vram;
+
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
@@ -1203,7 +1226,13 @@ int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC);
- kfree(hwdev->mhost_mgmt);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)hwdev->mhost_mgmt, hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ else
+ kfree(hwdev->mhost_mgmt);
+
hwdev->mhost_mgmt = NULL;
return 0;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
index 5e4804a..a0340d9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
@@ -17,14 +17,13 @@
#include "hinic3_hwdev.h"
#include "hinic3_lld.h"
#include "hinic3_hw_mt.h"
+#include "hinic3_dev_mgmt.h"
#include "hinic3_nictool.h"
static int g_nictool_ref_cnt;
static dev_t g_dev_id = {0};
-/*lint -save -e104 -e808*/
static struct class *g_nictool_class;
-/*lint -restore*/
static struct cdev g_nictool_cdev;
#define HINIC3_MAX_BUF_SIZE (2048 * 1024)
@@ -92,6 +91,23 @@ static int get_all_chip_id_cmd(struct hinic3_lld_dev *lld_dev, const void *buf_i
return 0;
}
+#ifndef __HIFC__
+static int get_os_hot_replace_info(struct hinic3_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ if (*out_size != sizeof(struct os_hot_replace_info) || !buf_out) {
+ pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
+ *out_size, sizeof(struct os_hot_replace_info));
+ return -EFAULT;
+ }
+
+ hinic3_get_os_hot_replace_info(buf_out);
+
+ return 0;
+}
+#endif
+
static int get_card_usr_api_chain_mem(int card_idx)
{
unsigned char *tmp = NULL;
@@ -166,7 +182,7 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
if (!buf_out || *out_size != sizeof(struct pf_dev_info) * PF_DEV_INFO_NUM) {
pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
- *out_size, sizeof(dev_info) * PF_DEV_INFO_NUM);
+ *out_size, sizeof(*dev_info) * PF_DEV_INFO_NUM);
return -EFAULT;
}
@@ -193,13 +209,18 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
return 0;
}
-static long dbgtool_knl_free_mem(int id)
+static void dbgtool_knl_free_mem(int id)
{
unsigned char *tmp = NULL;
int i;
+ if (id < 0 || id >= MAX_CARD_NUM) {
+ pr_err("Invalid card id\n");
+ return;
+ }
+
if (!g_card_vir_addr[id])
- return 0;
+ return;
tmp = g_card_vir_addr[id];
for (i = 0; i < (1 << DBGTOOL_PAGE_ORDER); i++) {
@@ -211,7 +232,6 @@ static long dbgtool_knl_free_mem(int id)
g_card_vir_addr[id] = NULL;
g_card_phy_addr[id] = 0;
- return 0;
}
static int free_knl_mem(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_size,
@@ -337,7 +357,6 @@ static int get_hw_drv_version(struct hinic3_lld_dev *lld_dev, const void *buf_in
void *buf_out, u32 *out_size)
{
struct drv_version_info *ver_info = buf_out;
- int err;
if (!buf_out) {
pr_err("Buf_out is NULL.\n");
@@ -350,10 +369,8 @@ static int get_hw_drv_version(struct hinic3_lld_dev *lld_dev, const void *buf_in
return -EINVAL;
}
- err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s", HINIC3_DRV_VERSION,
- "2023-05-17_19:56:38");
- if (err < 0)
- return -EINVAL;
+ snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s", HINIC3_DRV_VERSION,
+ "2025-05-08_00:00:08");
return 0;
}
@@ -386,6 +403,22 @@ static int get_pf_id(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_
return 0;
}
+#ifndef __HIFC__
+/* not support fc yet */
+static int get_mbox_cnt(struct hinic3_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ if (buf_out == NULL || *out_size != sizeof(struct card_mbox_cnt_info)) {
+ pr_err("buf_out is NULL, or out_size != %lu\n", sizeof(struct card_info));
+ return -EINVAL;
+ }
+
+ hinic3_get_mbox_cnt(hinic3_get_sdk_hwdev_by_lld(lld_dev), buf_out);
+
+ return 0;
+}
+#endif
+
struct hw_drv_module_handle hw_driv_module_cmd_handle[] = {
{FUNC_TYPE, get_func_type},
{GET_FUNC_IDX, get_func_id},
@@ -402,6 +435,10 @@ struct hw_drv_module_handle hw_driv_module_cmd_handle[] = {
{GET_FUNC_CAP, get_pf_cap_info},
{GET_DRV_VERSION, get_hw_drv_version},
{GET_PF_ID, get_pf_id},
+#ifndef __HIFC__
+ {GET_OS_HOT_REPLACE_INFO, get_os_hot_replace_info},
+ {GET_MBOX_CNT, (hw_driv_module)get_mbox_cnt},
+#endif
};
static int alloc_tmp_buf(void *hwdev, struct msg_module *nt_msg, u32 in_size,
@@ -439,8 +476,8 @@ static void free_tmp_buf(void *hwdev, struct msg_module *nt_msg,
static int send_to_hw_driver(struct hinic3_lld_dev *lld_dev, struct msg_module *nt_msg,
const void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(hw_driv_module_cmd_handle) /
- sizeof(hw_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(hw_driv_module_cmd_handle) /
+ sizeof(hw_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type =
(enum driver_cmd_type)(nt_msg->msg_formate);
int err = 0;
@@ -482,8 +519,8 @@ static int send_to_service_driver(struct hinic3_lld_dev *lld_dev, struct msg_mod
if (nt_msg->msg_formate == GET_DRV_VERSION)
return 0;
- pr_err("Can not get the uld dev correctly: %s, %s driver may be not register\n",
- nt_msg->device_name, service_name[type]);
+ pr_err("Can not get the uld dev correctly: %s driver may be not register\n",
+ service_name[type]);
return -EINVAL;
}
@@ -566,8 +603,8 @@ static struct hinic3_lld_dev *get_lld_dev_by_nt_msg(struct msg_module *nt_msg)
} else {
lld_dev = hinic3_get_lld_dev_by_chip_name(nt_msg->device_name);
if (!lld_dev)
- lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
- SERVICE_T_MAX);
+ lld_dev = hinic3_get_lld_dev_by_dev_name(
+ nt_msg->device_name, SERVICE_T_MAX);
}
return lld_dev;
@@ -597,8 +634,10 @@ static long hinicadm_k_unlocked_ioctl(struct file *pfile, unsigned long arg)
return -ENODEV;
}
- if (nt_msg.msg_formate == DEV_NAME_TEST)
+ if (nt_msg.msg_formate == DEV_NAME_TEST) {
+ lld_dev_put(lld_dev);
return 0;
+ }
ret = alloc_tmp_buf(hinic3_get_sdk_hwdev_by_lld(lld_dev), &nt_msg,
in_size, &buf_in, out_size_expect, &buf_out);
@@ -642,6 +681,9 @@ out_free_lock:
static long dbgtool_knl_ffm_info_rd(struct dbgtool_param *para,
struct dbgtool_k_glb_info *dbgtool_info)
{
+ if (!para->param.ffm_rd || !dbgtool_info->ffm)
+ return -EINVAL;
+
/* Copy the ffm_info to user mode */
if (copy_to_user(para->param.ffm_rd, dbgtool_info->ffm,
(unsigned int)sizeof(struct ffm_record_info))) {
@@ -674,13 +716,14 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
card_info = (struct card_node *)g_card_node_array[i];
if (!card_info)
continue;
- if (!strncmp(param.chip_name, card_info->chip_name, IFNAMSIZ))
+ if (memcmp(param.chip_name, card_info->chip_name,
+ strlen(card_info->chip_name) + 1) == 0)
break;
}
if (i == MAX_CARD_NUM || !card_info) {
lld_put();
- pr_err("Can't find this card %s\n", param.chip_name);
+ pr_err("Can't find this card.\n");
return -EFAULT;
}
@@ -697,10 +740,10 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
pr_err("Not suppose to use this cmd(0x%x).\n", real_cmd);
ret = 0;
break;
-
default:
pr_err("Dbgtool cmd(0x%x) not support now\n", real_cmd);
ret = -EFAULT;
+ break;
}
up(&dbgtool_info->dbgtool_sem);
@@ -746,9 +789,11 @@ static long nictool_k_unlocked_ioctl(struct file *pfile,
static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
{
+ pgprot_t vm_page_prot;
unsigned long vmsize = vma->vm_end - vma->vm_start;
phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
phys_addr_t phy_addr;
+ int err = 0;
if (vmsize > (PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER))) {
pr_err("Map size = %lu is bigger than alloc\n", vmsize);
@@ -758,13 +803,18 @@ static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
/* old version of tool set vma->vm_pgoff to 0 */
phy_addr = offset ? offset : g_card_phy_addr[card_id];
- if (!phy_addr) {
- pr_err("Card_id = %d physical address is 0\n", card_id);
- return -EAGAIN;
+ /* check phy_addr valid */
+ if (phy_addr != g_card_phy_addr[card_id]) {
+ err = hinic3_bar_mmap_param_valid(phy_addr, vmsize);
+ if (err != 0) {
+ pr_err("mmap param invalid, err: %d\n", err);
+ return err;
+ }
}
/* Disable cache and write buffer in the mapping area */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_page_prot = vm_page_prot;
if (remap_pfn_range(vma, vma->vm_start, (phy_addr >> PAGE_SHIFT),
vmsize, vma->vm_page_prot)) {
pr_err("Remap pfn range failed.\n");
@@ -787,7 +837,6 @@ static const struct file_operations fifo_operations = {
static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
{
struct dbgtool_k_glb_info *dbgtool_info = NULL;
- int err, id;
if (hinic3_func_type(hwdev) != TYPE_VF)
chip_info->func_handle_array[hinic3_global_func_id(hwdev)] = NULL;
@@ -795,23 +844,22 @@ static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
if (--chip_info->func_num)
return;
- err = sscanf(chip_info->chip_name, HINIC3_CHIP_NAME "%d", &id);
- if (err < 0)
- pr_err("Failed to get card id\n");
-
- if (id < MAX_CARD_NUM)
- g_card_node_array[id] = NULL;
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ g_card_node_array[chip_info->chip_id] = NULL;
dbgtool_info = chip_info->dbgtool_info;
/* FFM deinit */
- kfree(dbgtool_info->ffm);
- dbgtool_info->ffm = NULL;
+ if (dbgtool_info && dbgtool_info->ffm) {
+ kfree(dbgtool_info->ffm);
+ dbgtool_info->ffm = NULL;
+ }
kfree(dbgtool_info);
+
chip_info->dbgtool_info = NULL;
- if (id < MAX_CARD_NUM)
- (void)dbgtool_knl_free_mem(id);
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ dbgtool_knl_free_mem(chip_info->chip_id);
}
static int alloc_dbgtool_info(void *hwdev, struct card_node *chip_info)
@@ -872,7 +920,7 @@ dbgtool_info_fail:
* nictool_k_init - initialize the hw interface
**/
/* temp for dbgtool_info */
-/*lint -e438*/
+
int nictool_k_init(void *hwdev, void *chip_node)
{
struct card_node *chip_info = (struct card_node *)chip_node;
@@ -895,9 +943,7 @@ int nictool_k_init(void *hwdev, void *chip_node)
}
/* Create equipment */
- /*lint -save -e160*/
g_nictool_class = class_create(HIADM3_DEV_CLASS);
- /*lint -restore*/
if (IS_ERR(g_nictool_class)) {
pr_err("Create nictool_class fail\n");
err = -EFAULT;
@@ -944,7 +990,7 @@ alloc_chdev_fail:
free_dbgtool_info(hwdev, chip_info);
return err;
-} /*lint +e438*/
+}
void nictool_k_uninit(void *hwdev, void *chip_node)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
index f368133..c943dfc 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
@@ -18,6 +18,8 @@
int nictool_k_init(void *hwdev, void *chip_node);
void nictool_k_uninit(void *hwdev, void *chip_node);
+void hinic3_get_os_hot_replace_info(void *oshr_info);
+
void hinic3_get_all_chip_id(void *id_info);
void hinic3_get_card_func_info_by_card_name
@@ -29,6 +31,8 @@ bool hinic3_is_in_host(void);
int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *isvalid);
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin);
+
extern struct hinic3_uld_info g_uld_info[SERVICE_T_MAX];
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
index 2d5423e..e961ef7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
@@ -19,6 +19,20 @@
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
+#elif defined(CONFIG_NF_VID_DID)
+#define PCI_VENDOR_ID_NF 0x2036
+#define NFNIC_DEV_ID_STANDARD 0x1618
+#define NFNIC_DEV_ID_SDI_5_1_PF 0x0226
+#define NFNIC_DEV_ID_SDI_5_0_PF 0x0225
+#define NFNIC_DEV_ID_DPU_PF 0x0224
+#define NFNIC_DEV_ID_VF 0x1619
+#define NFNIC_DEV_ID_VF_HV 0x379F
+#define NFNIC_DEV_SDI_5_1_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_0_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_1_ID_VF_HV 0x379F
+#define NFNIC_DEV_ID_SPU 0xAC00
+#define NFNIC_DEV_SDI_5_1_SSDID_VF 0x1000
+#define NFNIC_DEV_SDI_V100_SSDID_MASK (3 << 12)
#else
#define PCI_VENDOR_ID_HUAWEI 0x19e5
#define HINIC3_DEV_ID_STANDARD 0x0222
@@ -28,16 +42,33 @@
#define HINIC3_DEV_ID_VF 0x375F
#define HINIC3_DEV_ID_VF_HV 0x379F
#define HINIC3_DEV_SDI_5_1_ID_VF 0x375F
+#define HINIC3_DEV_SDI_5_0_ID_VF 0x375F
#define HINIC3_DEV_SDI_5_1_ID_VF_HV 0x379F
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
#endif
+#define NFNIC_DEV_SSID_2X25G_NF 0x0860
+#define NFNIC_DEV_SSID_4X25G_NF 0x0861
+#define NFNIC_DEV_SSID_2x100G_NF 0x0862
+#define NFNIC_DEV_SSID_2x200G_NF 0x0863
+
+#define HINIC3_DEV_SSID_2X10G 0x0035
#define HINIC3_DEV_SSID_2X25G 0x0051
#define HINIC3_DEV_SSID_4X25G 0x0052
+#define HINIC3_DEV_SSID_4X25G_BD 0x0252
+#define HINIC3_DEV_SSID_4X25G_SMARTNIC 0x0152
+#define HINIC3_DEV_SSID_6X25G_VL 0x0356
#define HINIC3_DEV_SSID_2X100G 0x00A1
+#define HINIC3_DEV_SSID_2X100G_SMARTNIC 0x01A1
+#define HINIC3_DEV_SSID_2X200G 0x04B1
#define HINIC3_DEV_SSID_2X100G_VF 0x1000
+#define HINIC3_DEV_SSID_HPC_4_HOST_NIC 0x005A
+#define HINIC3_DEV_SSID_2X200G_VL 0x00B1
+#define HINIC3_DEV_SSID_1X100G 0x02A4
+
+#define BIFUR_RESOURCE_PF_SSID 0x05a1
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
index b23b69f..056397f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
@@ -52,7 +52,7 @@ static int hinic3_deinit_vf_hw(void *hwdev, u16 start_vf_id, u16 end_vf_id)
}
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
-ssize_t hinic3_sriov_totalvfs_show(struct device *dev,
+ssize_t sriov_totalvfs_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
@@ -60,7 +60,7 @@ ssize_t hinic3_sriov_totalvfs_show(struct device *dev,
return sprintf(buf, "%d\n", pci_sriov_get_totalvfs(pdev));
}
-ssize_t hinic3_sriov_numvfs_show(struct device *dev,
+ssize_t sriov_numvfs_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
@@ -68,8 +68,7 @@ ssize_t hinic3_sriov_numvfs_show(struct device *dev,
return sprintf(buf, "%d\n", pci_num_vf(pdev));
}
-/*lint -save -e713*/
-ssize_t hinic3_sriov_numvfs_store(struct device *dev,
+ssize_t sriov_numvfs_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
@@ -116,7 +115,6 @@ ssize_t hinic3_sriov_numvfs_store(struct device *dev,
return count;
}
-/*lint -restore*/
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
int hinic3_pci_sriov_disable(struct pci_dev *dev)
@@ -174,24 +172,15 @@ int hinic3_pci_sriov_disable(struct pci_dev *dev)
return 0;
}
-int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
-{
#ifdef CONFIG_PCI_IOV
- struct hinic3_sriov_info *sriov_info = NULL;
- struct hinic3_event_info event = {0};
- void *hwdev = NULL;
- int pre_existing_vfs = 0;
- int err = 0;
-
- sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
- hwdev = hinic3_get_hwdev_by_pcidev(dev);
- if (!hwdev) {
- sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
- return -EPERM;
- }
+int hinic3_pci_sriov_check(struct hinic3_sriov_info *sriov_info, struct pci_dev *dev, int num_vfs)
+{
+ int pre_existing_vfs;
+ int err;
if (test_and_set_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state)) {
- sdk_err(&dev->dev, "SR-IOV enable in process, please wait, num_vfs %d\n",
+ sdk_err(&dev->dev,
+ "SR-IOV enable in process, please wait, num_vfs %d\n",
num_vfs);
return -EPERM;
}
@@ -202,6 +191,7 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
clear_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state);
return -ERANGE;
}
+
if (pre_existing_vfs && pre_existing_vfs != num_vfs) {
err = hinic3_pci_sriov_disable(dev);
if (err) {
@@ -213,6 +203,29 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
return num_vfs;
}
+ return 0;
+}
+#endif
+
+int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
+{
+#ifdef CONFIG_PCI_IOV
+ struct hinic3_sriov_info *sriov_info = NULL;
+ struct hinic3_event_info event = {0};
+ void *hwdev = NULL;
+ int err = 0;
+
+ sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
+ hwdev = hinic3_get_hwdev_by_pcidev(dev);
+ if (!hwdev) {
+ sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
+ return -EPERM;
+ }
+
+ err = hinic3_pci_sriov_check(sriov_info, dev, num_vfs);
+ if (err != 0)
+ return err;
+
err = hinic3_init_vf_hw(hwdev, 1, (u16)num_vfs);
if (err) {
sdk_err(&dev->dev, "Failed to init vf in hardware before enable sriov, error %d\n",
@@ -262,6 +275,3 @@ int hinic3_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
else
return hinic3_pci_sriov_enable(dev, num_vfs);
}
-
-/*lint -restore*/
-
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h
index 4a640ad..20eb728 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h
@@ -7,11 +7,11 @@
#include <linux/pci.h>
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
-ssize_t hinic3_sriov_totalvfs_show(struct device *dev,
+ssize_t sriov_totalvfs_show(struct device *dev,
struct device_attribute *attr, char *buf);
-ssize_t hinic3_sriov_numvfs_show(struct device *dev,
+ssize_t sriov_numvfs_show(struct device *dev,
struct device_attribute *attr, char *buf);
-ssize_t hinic3_sriov_numvfs_store(struct device *dev,
+ssize_t sriov_numvfs_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count);
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c b/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c
index f8aea696..be83022 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c
@@ -117,3 +117,4 @@ u64 ossl_get_real_time(void)
tv_msec = (u64)tv.tv_sec * MSEC_PER_SEC + (u64)tv.tv_usec / USEC_PER_MSEC;
return tv_msec;
}
+
diff --git a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
index 9e8fc75..01ab739 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
@@ -10,6 +10,10 @@
#define OVS_PORT_NUM_MAX BOND_PORT_MAX_NUM
#define DEFAULT_ROCE_BOND_FUNC 0xFFFFFFFF
+#define BOND_ID_IS_VALID(_id) \
+ (((_id) >= BOND_FIRST_ID) && ((_id) <= BOND_MAX_ID))
+#define BOND_ID_IS_INVALID(_id) (!(BOND_ID_IS_VALID(_id)))
+
enum bond_group_id {
BOND_FIRST_ID = 1,
BOND_MAX_ID = 4,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
index e7e16fc..f9737ea 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
@@ -52,6 +52,8 @@ enum scenes_id_define {
SCENES_ID_STORAGE_ROCE = 6,
SCENES_ID_COMPUTE_ROCE = 7,
SCENES_ID_STORAGE_TOE = 8,
+ SCENES_ID_COMPUTE_DPU = 100,
+ SCENES_ID_COMPUTE_SMART_NIC = 101,
SCENES_ID_MAX
};
@@ -122,13 +124,18 @@ struct cfg_cmd_dev_cap {
u8 srv_multi_host_mode;
u8 virtio_vq_size;
- u32 rsvd_func3[5];
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 lro_enable;
+ u8 os_hot_replace;
+
+ u32 rsvd_func3[4];
/* l2nic */
u16 nic_max_sq_id;
u16 nic_max_rq_id;
u16 nic_default_num_queues;
- u16 rsvd1_nic;
+ u16 outband_vlan_cfg_en;
u32 rsvd2_nic[2];
/* RoCE */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
index d9f67e2..6c5b995 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
@@ -37,7 +37,7 @@ static inline void hinic3_cpu_to_be32(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -59,7 +59,7 @@ static inline void hinic3_be32_to_cpu(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -86,52 +86,16 @@ static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
sge->len = (u32)len;
}
-#ifdef HW_CONVERT_ENDIAN
#define hinic3_hw_be32(val) (val)
#define hinic3_hw_cpu32(val) (val)
#define hinic3_hw_cpu16(val) (val)
-#else
-#define hinic3_hw_be32(val) cpu_to_be32(val)
-#define hinic3_hw_cpu32(val) be32_to_cpu(val)
-#define hinic3_hw_cpu16(val) be16_to_cpu(val)
-#endif
static inline void hinic3_hw_be32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_be32(*mem);
- mem++;
- }
-#endif
}
static inline void hinic3_hw_cpu32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_cpu32(*mem);
- mem++;
- }
-#endif
}
int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
@@ -149,6 +113,8 @@ int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
/* func_attr.glb_func_idx, global function index */
u16 hinic3_global_func_id(void *hwdev);
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id);
+
/* func_attr.p2p_idx, belongs to which pf */
u8 hinic3_pf_id_of_vf(void *hwdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
index 9a9bfe2..e36ba1d 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
@@ -219,5 +219,7 @@ void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
const char **hinic3_get_uld_names(void);
+int hinic3_lld_init(void);
+void hinic3_lld_exit(void);
#endif
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
index 97d34f0..4cd6f94 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
@@ -43,6 +43,10 @@ enum mag_cmd {
MAG_CMD_GET_XSFP_PRESENT = 62, /* get xsfp present status @see mag_cmd_get_xsfp_present */
MAG_CMD_SET_XSFP_RW = 63, /* sfp/qsfp single byte read/write, @see mag_cmd_set_xsfp_rw */
MAG_CMD_CFG_XSFP_TEMPERATURE = 64, /* get xsfp temp @see mag_cmd_sfp_temp_out_info */
+ /**< set xsfp tlv info @see struct mag_cmd_set_xsfp_tlv_req */
+ MAG_CMD_SET_XSFP_TLV_INFO = 65,
+ /**< get xsfp tlv info @see struct drv_tag_mag_cmd_get_xsfp_tlv_rsp */
+ MAG_CMD_GET_XSFP_TLV_INFO = 66,
/* Event reported 100-149 */
MAG_CMD_WIRE_EVENT = 100,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
index caaba5d..d33b9f4 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
@@ -31,17 +31,28 @@ enum board_type_define_e {
BOARD_TYPE_STRG_2X100G_ROCE_AA = 42, /* 2X100G SmartIO ROCE_AA Card */
BOARD_TYPE_CAL_2X25G_NIC_75MPPS = 100, /* 2X25G ETH Standard card 75MPPS */
BOARD_TYPE_CAL_2X25G_NIC_40MPPS = 101, /* 2X25G ETH Standard card 40MPPS */
- BOARD_TYPE_CAL_2X100G_DPU = 102, /* 2x100G DPU Card */
+ BOARD_TYPE_CAL_2X100G_DPU_VL = 102, /* 2x100G DPU Card */
BOARD_TYPE_CAL_4X25G_NIC_120MPPS = 105, /* 4X25G ETH Standard card 120MPPS */
BOARD_TYPE_CAL_4X25G_COMSTORAGE = 106, /* 4X25GE compute storage Onboard Card */
BOARD_TYPE_CAL_2X32G_FC_HBA = 110, /* 2X32G FC HBA card */
BOARD_TYPE_CAL_2X16G_FC_HBA = 111, /* 2X16G FC HBA card */
BOARD_TYPE_CAL_2X100G_NIC_120MPPS = 115, /* 2X100G ETH Standard card 120MPPS */
- BOARD_TYPE_CAL_2X25G_DPU = 116, /* 2x25G DPU Card */
- BOARD_TYPE_CAL_4X25G_DPU = 118, /* 4x25G DPU Card */
+ BOARD_TYPE_CAL_2X25G_DPU_BD = 116, /* 2x25G DPU Card */
+ BOARD_TYPE_CAL_2X100G_TCE_BACKPLANE = 117,
+ BOARD_TYPE_CAL_4X25G_DPU_VL = 118, /* 4x25G DPU Card */
+ BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS = 119,
+ BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS = 120,
+ BOARD_TYPE_CAL_6X25G_DPU_VL = 121, /* 6x25G DPU Card */
+ BOARD_TYPE_CAL_4X25G_DPU_BD = 122,
+ BOARD_TYPE_CAL_2X25G_NIC_4HOST = 123,
+ BOARD_TYPE_CAL_2X10G_LOW_POWER = 125,
+ BOARD_TYPE_CAL_2X200G_NIC_INTERNET = 127,
+ BOARD_TYPE_CAL_1X100GR2_OCP = 129, /* 1X100G ETH Standard card */
+ BOARD_TYPE_CAL_2X200G_DPU_VL = 130,
BOARD_TYPE_CLD_2X100G_SDI5_1 = 170, /* 2X100G SDI 5.1 Card */
BOARD_TYPE_CLD_2X25G_SDI5_0_LITE = 171, /* 2x25G SDI5.0 Lite Card */
BOARD_TYPE_CLD_2X100G_SDI5_0 = 172, /* 2x100G SDI5.0 Card */
+ BOARD_TYPE_CLD_4X25G_SDI5_0_C = 175,
BOARD_TYPE_MAX_INDEX = 0xFF
};
@@ -49,23 +60,62 @@ static inline u32 spu_board_type_valid(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
- ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
}
static inline int board_type_is_sdi(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_1) ||
((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
- ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0);
+ ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C);
+}
+
+static inline int board_type_is_dpu_spu(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
}
static inline int board_type_is_dpu(u32 board_type)
{
- return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_6X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
+}
+
+/* 此接口判断是否是分布式存储的标卡以及计算的标卡(含ROCE特性),
+ * 仅用于LLDP TX功能冲突命令字处理的判断
+ */
+static inline int board_type_is_compute(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_75MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_40MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_NIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_COMSTORAGE) ||
+ ((board_type) == BOARD_TYPE_CAL_2X10G_LOW_POWER) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_NIC_INTERNET) ||
+ ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_4HOST) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_NIC_120MPPS);
+}
+
+/* 此接口判断服务器输入reboot网卡是否需要复位 */
+static inline int board_type_is_multi_socket(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP);
}
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
index 291e475..4d4d543 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
@@ -4,8 +4,95 @@
#ifndef MPU_CMD_BASE_DEFS_H
#define MPU_CMD_BASE_DEFS_H
-#include "mgmt_msg_base.h"
-#include "comm_defs.h"
+/** MPU CMD MODULE TYPE */
+enum hinic3_mod_type {
+ HINIC3_MOD_COMM = 0, /* HW communication module */
+ HINIC3_MOD_L2NIC = 1, /* L2NIC module */
+ HINIC3_MOD_ROCE = 2,
+ HINIC3_MOD_PLOG = 3,
+ HINIC3_MOD_TOE = 4,
+ HINIC3_MOD_FLR = 5,
+ HINIC3_MOD_VROCE = 6,
+ HINIC3_MOD_CFGM = 7, /* Configuration management */
+ HINIC3_MOD_CQM = 8,
+ HINIC3_MOD_VMSEC = 9,
+ COMM_MOD_FC = 10,
+ HINIC3_MOD_OVS = 11,
+ HINIC3_MOD_DSW = 12,
+ HINIC3_MOD_MIGRATE = 13,
+ HINIC3_MOD_HILINK = 14,
+ HINIC3_MOD_CRYPT = 15, /* secure crypto module */
+ HINIC3_MOD_VIO = 16,
+ HINIC3_MOD_IMU = 17,
+ HINIC3_MOD_DFX = 18, /* DFX */
+ HINIC3_MOD_HW_MAX = 19, /* hardware max module id */
+ /* Software module id, for PF/VF and multi-host */
+ HINIC3_MOD_SW_FUNC = 20,
+ HINIC3_MOD_MAX,
+};
+
+/* func reset的flag ,用于指示清理哪种资源 */
+enum func_reset_flag_e {
+ RES_TYPE_FLUSH_BIT = 0,
+ RES_TYPE_MQM,
+ RES_TYPE_SMF,
+ RES_TYPE_PF_BW_CFG,
+
+ RES_TYPE_COMM = 10,
+ RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_NIC,
+ RES_TYPE_OVS,
+ RES_TYPE_VBS,
+ RES_TYPE_ROCE,
+ RES_TYPE_FC,
+ RES_TYPE_TOE,
+ RES_TYPE_IPSEC,
+ RES_TYPE_MAX,
+};
+
+#define HINIC3_COMM_RES \
+ ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
+ (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
+ (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
+
+#define HINIC3_NIC_RES (1 << RES_TYPE_NIC)
+#define HINIC3_OVS_RES (1 << RES_TYPE_OVS)
+#define HINIC3_VBS_RES (1 << RES_TYPE_VBS)
+#define HINIC3_ROCE_RES (1 << RES_TYPE_ROCE)
+#define HINIC3_FC_RES (1 << RES_TYPE_FC)
+#define HINIC3_TOE_RES (1 << RES_TYPE_TOE)
+#define HINIC3_IPSEC_RES (1 << RES_TYPE_IPSEC)
+
+/* MODE OVS、NIC、UNKNOWN */
+#define HINIC3_WORK_MODE_OVS 0
+#define HINIC3_WORK_MODE_UNKNOWN 1
+#define HINIC3_WORK_MODE_NIC 2
+
+#define DEVICE_TYPE_L2NIC 0
+#define DEVICE_TYPE_NVME 1
+#define DEVICE_TYPE_VIRTIO_NET 2
+#define DEVICE_TYPE_VIRTIO_BLK 3
+#define DEVICE_TYPE_VIRTIO_VSOCK 4
+#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
+#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
+#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
+#define DEVICE_TYPE_VIRTIO_HPC 8
+#define DEVICE_TYPE_VIRTIO_FS 9
+
+#define IS_STORAGE_DEVICE_TYPE(dev_type) \
+ ((dev_type) == DEVICE_TYPE_VIRTIO_BLK || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_BLK_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_SCSI_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_FS)
+
+#define MGMT_MSG_CMD_OP_SET 1
+#define MGMT_MSG_CMD_OP_GET 0
+
+#define MGMT_MSG_CMD_OP_START 1
+#define MGMT_MSG_CMD_OP_STOP 0
+
+#define HOT_REPLACE_PARTITION_NUM 2
enum hinic3_svc_type {
SVC_T_COMM = 0,
@@ -23,4 +110,54 @@ enum hinic3_svc_type {
SVC_T_MAX,
};
+/**
+ * Common header control information of the COMM message interaction
+ * command word between the driver and PF
+ * struct mgmt_msg_head and struct comm_info_head are the same structure
+ */
+struct mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+/**
+ * Common header control information of the COMM message interaction
+ * command word between the driver and PF
+ */
+struct comm_info_head {
+ /** response status code, 0: success, others: error code */
+ u8 status;
+
+ /** firmware version for command */
+ u8 version;
+
+ /** response aeq number, unused for now */
+ u8 rep_aeq_num;
+ u8 rsvd[5];
+};
+
+static inline u32 get_function_partition(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM;
+}
+
+static inline u32 is_primary_function(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0;
+}
+
+static inline u32 mpu_nic_get_primary_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ function_id : (function_id - port_num);
+}
+
+// when func_id is in partition 0/1, it will get its another func_id in partition 1/0
+static inline u32 mpu_nic_get_backup_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ (function_id + port_num) : (function_id - port_num);
+}
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
index a8e2d63..3841bb5 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
@@ -91,6 +91,10 @@ enum hinic3_mgmt_cmd {
* @see comm_read_ucode_sm_resp
*/
COMM_MGMT_CMD_CLEAR_LOG, /**< clear log @see comm_cmd_clear_log_s */
+ COMM_MGMT_CMD_UCODE_SM_COUNTER_PER,
+ /**< get ucode sm counter @see struct comm_read_ucode_sm_per_req
+ * @see struct comm_read_ucode_sm_per_resp
+ */
COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140, /* check if switch workmode reserved
* @see comm_cmd_check_if_switch_workmode
@@ -103,6 +107,7 @@ enum hinic3_mgmt_cmd {
COMM_MGMT_CMD_CPI_TCAM_DBG, /* enable or disable the scheduled cpi tcam task,
* set task interval time @see comm_cmd_cpi_tcam_dbg_s
*/
+ COMM_MGMT_CMD_LLDP_TX_FUNC_SET,
COMM_MGMT_CMD_SECTION_RSVD_0 = 160, /**< rsvd0 section */
COMM_MGMT_CMD_SECTION_RSVD_1 = 170, /**< rsvd1 section */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
index 674603d..698730f 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
@@ -338,7 +338,8 @@ struct comm_cmd_get_fw_version {
struct mgmt_msg_head head;
u16 fw_type; /**< firmware type @see enum hinic3_fw_ver_type */
- u16 rsvd1;
+ u16 fw_dfx_vld : 1; /**< 0: release, 1: debug */
+ u16 rsvd1 : 15;
u8 ver[HINIC3_FW_VERSION_LEN]; /**< firmware version */
u8 time[HINIC3_FW_COMPILE_TIME_LEN]; /**< firmware compile time */
};
@@ -430,6 +431,22 @@ struct comm_cmd_bdf_info {
u8 rsvd2[5];
};
+struct mpu_pcie_pf_info {
+ u32 device_id; /**< device id */
+ u32 vendor_id; /**< vendor id */
+};
+
+struct mpu_pcie_device_info {
+ u8 status;
+ u8 version;
+ u8 rep_aeq_num;
+ u8 rsvd[5];
+
+ struct mpu_pcie_pf_info pf_info[32];
+ u32 bus_id; /**< bus id */
+ u32 pf_num; /**< pf index */
+};
+
#define TABLE_INDEX_MAX 129
struct sml_table_id_info {
u8 node_id;
@@ -446,6 +463,13 @@ struct comm_cmd_sdi_info {
u32 cfg_sdi_mode; /**< host mode, 0:normal 1:virtual machine 2:bare metal */
};
+struct comm_cmd_root_ctx_load_req {
+ struct comm_info_head head;
+ u32 func_id; /**< function id */
+ u32 smf_id; /**< smf id */
+ u32 queue_id; /**< queue id */
+};
+
#define HINIC_OVS_BOND_DEFAULT_ID 1
struct hinic3_hw_bond_infos {
u8 bond_id;
@@ -685,6 +709,28 @@ struct comm_read_ucode_sm_resp {
u64 val2;
};
+#define PER_REQ_MAX_DATA_LEN 0x600
+
+struct comm_read_ucode_sm_per_req {
+ struct mgmt_msg_head msg_head;
+
+ u32 tbl_type;
+ u32 count_id;
+};
+
+struct comm_read_ucode_sm_per_resp {
+ struct mgmt_msg_head msg_head;
+
+ u8 data[PER_REQ_MAX_DATA_LEN];
+};
+
+struct ucode_sm_counter_get_info {
+ u32 width_type;
+ u32 tbl_type;
+ unsigned int base_count;
+ unsigned int count_num;
+};
+
enum log_type {
MPU_LOG_CLEAR = 0,
SMU_LOG_CLEAR = 1,
@@ -693,6 +739,11 @@ enum log_type {
ALL_LOG_CLEAR = 4,
};
+struct comm_cmd_clear_log {
+ struct comm_info_head head;
+ u32 type; /**< log type @see enum log_type */
+};
+
#define ABLESWITCH 1
#define IMABLESWITCH 2
enum switch_workmode_op {
@@ -717,6 +768,14 @@ struct comm_cmd_check_if_switch_workmode {
u32 rsvd3[3];
};
+struct comm_cmd_switch_workmode {
+ struct mgmt_msg_head head;
+ u8 operation;
+ u8 work_mode;
+ u16 rsvd1[3];
+ u32 rsvd2[3];
+};
+
#define MIG_NOR_VM_ONE_MAX_SGE_MEM (64 * 8)
#define MIG_NOR_VM_ONE_MAX_MEM (MIG_NOR_VM_ONE_MAX_SGE_MEM + 16)
#define MIG_VM_MAX_SML_ENTRY_NUM 24
@@ -755,6 +814,15 @@ struct cmd_get_bdf_info_s {
#define CPI_TCAM_DBG_CMD_TYPE_SET 0
#define CPI_TCAM_DBG_CMD_TYPE_GET 1
+struct comm_cmd_cpi_tcam_dbg {
+ struct comm_info_head head;
+ u8 type;
+ u8 set_bitmap;
+ u8 enable;
+ u8 rsvd;
+ u32 time_interval;
+};
+
#define UDIE_ID_DATA_LEN 8
#define TDIE_ID_DATA_LEN 18
struct comm_cmd_get_die_id {
@@ -808,6 +876,12 @@ struct cmd_query_fw {
u32 len; /**< length */
};
+struct comm_cmd_get_cfg_info_t {
+ struct comm_info_head head;
+ u8 rsvd[8];
+ u8 info[64]; /**< flash config info */
+};
+
struct nic_cmd_get_uart_log_info {
struct comm_info_head head;
struct {
@@ -969,6 +1043,7 @@ enum comm_virtio_dev_type {
COMM_VIRTIO_NET_TYPE = 0,
COMM_VIRTIO_BLK_TYPE = 1,
COMM_VIRTIO_SCSI_TYPE = 4,
+ COMM_VIRTIO_FS_TYPE = 5,
};
struct comm_virtio_dev_cmd {
@@ -1030,6 +1105,13 @@ struct cmd_patch_sram_optimize {
u32 data[4]; /**< reserved */
};
+struct comm_cmd_con_sel_sta {
+ struct comm_info_head head;
+ u8 valid;
+ u8 host_id; /**< host id, range[0,3] */
+ u8 rsvd[2];
+};
+
/* ncsi counter */
struct nsci_counter_in_info_s {
struct comm_info_head head;
@@ -1082,7 +1164,9 @@ struct comm_cmd_ncsi_settings {
u8 lldp_over_ncsi_enable;
u8 lldp_over_mctp_enable;
u32 magicwd;
- u8 rsvd[8];
+ u8 lldp_tx_enable;
+ u8 rsvd[3];
+ u32 crc;
struct tag_ncsi_chan_info ncsi_chan_info;
};
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
index fde8617..1ee44a8 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
@@ -114,6 +114,14 @@ struct tag_ncsi_client_info {
#define AEN_CTRL_CONFIG_REQ_SHIFT 1
#define AEN_CTRL_DRV_CHANGE_SHIFT 2
+/* AEN Type */
+enum aen_type_e {
+ AEN_LINK_STATUS_CHANGE_TYPE = 0x0,
+ AEN_CONFIG_REQUIRED_TYPE = 0x1,
+ OEM_AEN_CONFIG_REQUEST_TYPE = 0x80,
+ AEN_TYPE_MAX = 0x100
+};
+
/* get link status 0x0A */
#define GET_LINK_STATUS_REQ_LEN 0
#define GET_LINK_STATUS_RSP_LEN 16
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
index 0bd168c..5b2bdc8 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
@@ -36,6 +36,7 @@ enum nic_rss_hash_type {
#define NIC_RX_MODE_BC 0x04
#define NIC_RX_MODE_MC_ALL 0x08
#define NIC_RX_MODE_PROMISC 0x10
+#define NIC_RX_DB_COS_MAX 0x4
/* IEEE 802.1Qaz std */
#define NIC_DCB_COS_MAX 0x8
@@ -52,4 +53,7 @@ enum nic_rss_hash_type {
#define NIC_DCB_PRIO_STRICT 0x1
#define NIC_DCB_MAX_PFC_NUM 0x4
+
+#define NIC_ETS_PERCENT_WEIGHT 100
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
index 801aeed..5476287 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
@@ -23,7 +23,11 @@
#define VRAM_CQM_BITMAP_BASE "B"
#define VRAM_NIC_DCB "DCB"
+#define VRAM_NIC_MHOST_MGMT "MHOST_MGMT"
#define VRAM_NIC_VRAM "NIC_VRAM"
+#define VRAM_NIC_IRQ_VRAM "NIC_IRQ"
+
+#define VRAM_NIC_MQM "NM"
#define VRAM_VBS_BASE_IOCB "BASE_IOCB"
#define VRAM_VBS_EX_IOCB "EX_IOCB"
@@ -32,6 +36,9 @@
#define VRAM_VBS_VOLQ_MTT "VOLQ_MTT"
#define VRAM_VBS_VOLQ_MTT_PAGE "MTT_PAGE"
+#define VRAM_OVS_PORT_CONF "OVS_PORT_CONF"
+#define VRAM_OVS_DFX_MGR "OVS_DFX_MGR"
+
#define VRAM_VROCE_ENTRY_POOL "VROCE_ENTRY"
#define VRAM_VROCE_GROUP_POOL "VROCE_GROUP"
#define VRAM_VROCE_UUID "VROCE_UUID"
@@ -42,6 +49,17 @@
#define VRAM_VROCE_DEV "VROCE_DEV"
#define VRAM_VROCE_RGROUP_HT_CNT "RGROUP_CNT"
#define VRAM_VROCE_RACL_HT_CNT "RACL_CNT"
+#define VRAM_VROCE_MQM_ENQC "VROCE_MQM_ENQC"
+
+#define VRAM_DTOE_NUMA_MEM "DTOE_NUMA"
+#define VRAM_DTOE_CARD_MEM "DTOE_CARD"
+#define VRAM_DTOE_CONN_MEM "DTOE_CONN"
+#define VRAM_DTOE_SUB_LEN 10
+
+#define VRAM_VROCE_MIG_ENTRY_POOL "VROCE_MIG_ENTRY"
+#define VRAM_VROCE_MIG_ENTRY_HT_CNT "MIG_ENTRY_CNT"
+
+#define VRAM_VBS_DEV_INDEX "VBS_INDEX"
#define VRAM_NAME_APPLY_LEN 64
@@ -55,11 +73,16 @@ enum KUP_HOOK_POINT {
PRE_FREEZE,
FREEZE_TO_KILL,
PRE_UPDATE_KERNEL,
- FLUSH_DURING_KUP,
POST_UPDATE_KERNEL,
UNFREEZE_TO_RUN,
POST_RUN,
KUP_HOOK_MAX,
};
+#define hi_vram_kalloc(name, size) 0
+#define hi_vram_kfree(vaddr, name, size)
+#define get_use_vram_flag(void) 0
+#define vram_get_kexec_flag(void) 0
+#define hi_vram_get_gfp_vram(void) 0
+
#endif /* VRAM_COMMON_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
similarity index 79%
rename from drivers/net/ethernet/huawei/hinic3/mag_cmd.h
rename to drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
index 9649503..ead8e69 100644
--- a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
@@ -9,6 +9,7 @@
/* serdes cmd struct define */
#define CMD_ARRAY_BUF_SIZE 64
#define SERDES_CMD_DATA_BUF_SIZE 512
+#define RATE_MBPS_TO_GBPS 1000
struct serdes_in_info {
u32 chip_id : 16;
u32 macro_id : 16;
@@ -127,6 +128,7 @@ enum mag_cmd_cnt_type {
MAG_RX_PCS_E_BLK_CNT = 5,
MAG_RX_PCS_DEC_ERR_BLK_CNT = 6,
MAG_RX_PCS_LANE_BIP_ERR_CNT = 7,
+ MAG_RX_RSFEC_ERR_CW_CNT = 8,
MAG_CNT_NUM
};
@@ -208,7 +210,9 @@ struct mag_cmd_get_port_info {
u32 supported_mode;
u32 advertised_mode;
- u8 rsvd2[8];
+ u32 supported_fec_mode;
+ u16 bond_speed;
+ u8 rsvd2[2];
};
#define MAG_CMD_OPCODE_GET 0
@@ -330,8 +334,8 @@ struct mag_cmd_cfg_fec_mode {
u8 port_id;
u8 opcode; /* 0:get fec mode 1:set fec mode */
- u8 fec;
- u8 rsvd0;
+ u8 advertised_fec;
+ u8 supported_fec;
};
/* speed */
@@ -641,7 +645,7 @@ struct mag_cmd_event_port_info {
u32 cable_length; /* 1/3/5m */
u8 cable_temp; /* temp */
u8 max_speed; /* Maximum rate of an optical module */
- u8 sfp_type; /* sfp/qsfp */
+ u8 sfp_type; /* sfp/qsfp/dsfp */
u8 rsvd1;
u32 power[4]; /* Optical Power */
@@ -678,6 +682,10 @@ struct mag_cmd_event_port_info {
u8 rsvd3[360];
};
+struct mag_cmd_rsfec_stats {
+ u32 rx_err_lane_phy;
+};
+
struct mag_cmd_port_stats {
u64 mac_tx_fragment_pkt_num;
u64 mac_tx_undersize_pkt_num;
@@ -913,10 +921,223 @@ struct mag_cmd_sfp_temp_in_info {
};
struct mag_cmd_sfp_temp_out_info {
- struct mgmt_msg_head head; /* 8B */
- s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
- s32 max_temp; /* Chip optical module threshold */
- s32 min_temp; /* Chip optical module threshold */
+ struct mgmt_msg_head head; /* 8B */
+ s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
+ s32 max_temp; /* Chip optical module threshold */
+ s32 min_temp; /* Chip optical module threshold */
+};
+
+#define XSFP_CMIS_PARSE_PAGE_NUM 6
+#define XSFP_CMIS_INFO_MAX_SIZE 1536
+#define QSFP_CMIS_PAGE_SIZE 128
+#define QSFP_CMIS_MAX_CHANNEL_NUM 0x8
+
+/* Lower: Control and Essentials, Upper: Administrative Information */
+#define QSFP_CMIS_PAGE_00H 0x00
+/* Advertising */
+#define QSFP_CMIS_PAGE_01H 0x01
+/* Module and lane Thresholds */
+#define QSFP_CMIS_PAGE_02H 0x02
+/* User EEPROM */
+#define QSFP_CMIS_PAGE_03H 0x03
+/* Laser Capabilities Advertising (Page 04h, Optional) */
+#define QSFP_CMIS_PAGE_04H 0x04
+#define QSFP_CMIS_PAGE_05H 0x05
+/* Lane and Data Path Control */
+#define QSFP_CMIS_PAGE_10H 0x10
+/* Lane Status */
+#define QSFP_CMIS_PAGE_11H 0x11
+#define QSFP_CMIS_PAGE_12H 0x12
+
+#define MGMT_TLV_U8_SIZE 1
+#define MGMT_TLV_U16_SIZE 2
+#define MGMT_TLV_U32_SIZE 4
+
+#define MGMT_TLV_GET_U8(addr) (*((u8 *)(void *)(addr)))
+#define MGMT_TLV_SET_U8(addr, value) \
+ ((*((u8 *)(void *)(addr))) = ((u8)(value)))
+
+#define MGMT_TLV_GET_U16(addr) (*((u16 *)(void *)(addr)))
+#define MGMT_TLV_SET_U16(addr, value) \
+ ((*((u16 *)(void *)(addr))) = ((u16)(value)))
+
+#define MGMT_TLV_GET_U32(addr) (*((u32 *)(void *)(addr)))
+#define MGMT_TLV_SET_U32(addr, value) \
+ ((*((u32 *)(void *)(addr))) = ((u32)(value)))
+
+#define MGMT_TLV_TYPE_END 0xFFFF
+
+enum mag_xsfp_type {
+ MAG_XSFP_TYPE_PAGE = 0x01,
+ MAG_XSFP_TYPE_WIRE_TYPE = 0x02,
+ MAG_XSFP_TYPE_END = MGMT_TLV_TYPE_END
+};
+
+struct qsfp_cmis_lower_page_00_s {
+ u8 resv0[14];
+ u8 temperature_msb;
+ u8 temperature_lsb;
+ u8 volt_supply[2];
+ u8 resv1[67];
+ u8 media_type;
+ u8 electrical_interface_id;
+ u8 media_interface_id;
+ u8 lane_count;
+ u8 resv2[39];
+};
+
+struct qsfp_cmis_upper_page_00_s {
+ u8 identifier;
+ u8 vendor_name[16];
+ u8 vendor_oui[3];
+ u8 vendor_pn[16];
+ u8 vendor_rev[2];
+ u8 vendor_sn[16];
+ u8 date_code[8];
+ u8 clei_code[10];
+ u8 power_character[2];
+ u8 cable_len;
+ u8 connector;
+ u8 copper_cable_attenuation[6];
+ u8 near_end_implementation;
+ u8 far_end_config;
+ u8 media_technology;
+ u8 resv0[43];
+};
+
+struct qsfp_cmis_upper_page_01_s {
+ u8 firmware_rev[2];
+ u8 hardware_rev[2];
+ u8 smf_len_km;
+ u8 om5_len;
+ u8 om4_len;
+ u8 om3_len;
+ u8 om2_len;
+ u8 resv0;
+ u8 wavelength[2];
+ u8 wavelength_tolerance[2];
+ u8 pages_implement;
+ u8 resv1[16];
+ u8 monitor_implement[2];
+ u8 resv2[95];
+};
+
+struct qsfp_cmis_upper_page_02_s {
+ u8 temperature_high_alarm[2];
+ u8 temperature_low_alarm[2];
+ u8 temperature_high_warn[2];
+ u8 temperature_low_warn[2];
+ u8 volt_high_alarm[2];
+ u8 volt_low_alarm[2];
+ u8 volt_high_warn[2];
+ u8 volt_low_warn[2];
+ u8 resv0[32];
+ u8 tx_power_high_alarm[2];
+ u8 tx_power_low_alarm[2];
+ u8 tx_power_high_warn[2];
+ u8 tx_power_low_warn[2];
+ u8 tx_bias_high_alarm[2];
+ u8 tx_bias_low_alarm[2];
+ u8 tx_bias_high_warn[2];
+ u8 tx_bias_low_warn[2];
+ u8 rx_power_high_alarm[2];
+ u8 rx_power_low_alarm[2];
+ u8 rx_power_high_warn[2];
+ u8 rx_power_low_warn[2];
+ u8 resv1[56];
+};
+
+struct qsfp_cmis_upper_page_03_s {
+ u8 resv0[QSFP_CMIS_PAGE_SIZE]; /* Reg 128-255: Upper Memory: Page 03H */
+};
+
+struct qsfp_cmis_upper_page_10_s {
+ u8 resv0[2]; /* Reg 128-129: Upper Memory: Page 10H */
+ u8 tx_disable; /* Reg 130: Tx disable, 0b=enabled, 1b=disabled */
+ u8 resv1[125]; /* Reg 131-255 */
+};
+
+struct qsfp_cmis_upper_page_11_s {
+ u8 resv0[7];
+ u8 tx_fault;
+ u8 tx_los;
+ u8 resv1[10];
+ u8 rx_los;
+ u8 resv2[6];
+ u8 tx_power[16];
+ u8 tx_bias[16];
+ u8 rx_power[16];
+ u8 resv3[54];
+};
+
+struct qsfp_cmis_info_s {
+ struct qsfp_cmis_lower_page_00_s lower_page_00;
+ struct qsfp_cmis_upper_page_00_s upper_page_00;
+ struct qsfp_cmis_upper_page_01_s upper_page_01;
+ struct qsfp_cmis_upper_page_02_s upper_page_02;
+ struct qsfp_cmis_upper_page_10_s upper_page_10;
+ struct qsfp_cmis_upper_page_11_s upper_page_11;
+};
+
+struct qsfp_cmis_comm_power_s {
+ u32 chl_power[QSFP_CMIS_MAX_CHANNEL_NUM];
+};
+
+struct qsfp_cmis_wire_info_s {
+ struct qsfp_cmis_comm_power_s rx_power;
+ u8 rx_los;
+ u8 resv0[3];
+};
+
+struct mgmt_tlv_info {
+ u16 type;
+ u16 length;
+ u8 value[];
+};
+
+struct mag_cmd_set_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 tlv_buf[];
+};
+
+struct mag_cmd_set_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+};
+
+struct tag_mag_cmd_get_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd;
+ u16 rsp_buf_len;
+};
+
+struct mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[];
+};
+
+
+struct parse_tlv_info {
+ u8 tlv_page_info[XSFP_CMIS_INFO_MAX_SIZE + 1];
+ u32 tlv_page_info_len;
+ u32 tlv_page_num[XSFP_CMIS_PARSE_PAGE_NUM];
+ u32 wire_type;
+ u8 id;
+};
+
+struct drv_tag_mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[XSFP_CMIS_INFO_MAX_SIZE];
};
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h b/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
deleted file mode 100644
index 257bf67..0000000
--- a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : mgmt_msg_base.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef MGMT_MSG_BASE_H
-#define MGMT_MSG_BASE_H
-
-#define MGMT_MSG_CMD_OP_SET 1
-#define MGMT_MSG_CMD_OP_GET 0
-
-#define MGMT_MSG_CMD_OP_START 1
-#define MGMT_MSG_CMD_OP_STOP 0
-
-struct mgmt_msg_head {
- u8 status;
- u8 version;
- u8 rsvd0[6];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
deleted file mode 100644
index abcfa27..0000000
--- a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2001-2021, Huawei Tech. Co., Ltd.
- * File Name : nic_cfg_comm.h
- * Version : Initial Draft
- * Description : nic config common header file
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef NIC_CFG_COMM_H
-#define NIC_CFG_COMM_H
-
-#include <linux/types.h>
-
-/* rss */
-#define HINIC3_RSS_TYPE_VALID_SHIFT 23
-#define HINIC3_RSS_TYPE_TCP_IPV6_EXT_SHIFT 24
-#define HINIC3_RSS_TYPE_IPV6_EXT_SHIFT 25
-#define HINIC3_RSS_TYPE_TCP_IPV6_SHIFT 26
-#define HINIC3_RSS_TYPE_IPV6_SHIFT 27
-#define HINIC3_RSS_TYPE_TCP_IPV4_SHIFT 28
-#define HINIC3_RSS_TYPE_IPV4_SHIFT 29
-#define HINIC3_RSS_TYPE_UDP_IPV6_SHIFT 30
-#define HINIC3_RSS_TYPE_UDP_IPV4_SHIFT 31
-
-#define HINIC3_RSS_TYPE_SET(val, member) (((u32)(val) & 0x1) << HINIC3_RSS_TYPE_##member##_SHIFT)
-#define HINIC3_RSS_TYPE_GET(val, member) (((u32)(val) >> HINIC3_RSS_TYPE_##member##_SHIFT) & 0x1)
-
-enum nic_rss_hash_type {
- NIC_RSS_HASH_TYPE_XOR = 0,
- NIC_RSS_HASH_TYPE_TOEP,
-
- NIC_RSS_HASH_TYPE_MAX /* MUST BE THE LAST ONE */
-};
-
-#define NIC_RSS_INDIR_SIZE 256
-#define NIC_RSS_KEY_SIZE 40
-
-/* *
- * Definition of the NIC receiving mode
- */
-#define NIC_RX_MODE_UC 0x01
-#define NIC_RX_MODE_MC 0x02
-#define NIC_RX_MODE_BC 0x04
-#define NIC_RX_MODE_MC_ALL 0x08
-#define NIC_RX_MODE_PROMISC 0x10
-
-/* IEEE 802.1Qaz std */
-#define NIC_DCB_COS_MAX 0x8
-#define NIC_DCB_UP_MAX 0x8
-#define NIC_DCB_TC_MAX 0x8
-#define NIC_DCB_PG_MAX 0x8
-#define NIC_DCB_TSA_SP 0x0
-#define NIC_DCB_TSA_CBS 0x1
-#define NIC_DCB_TSA_ETS 0x2
-#define NIC_DCB_DSCP_NUM 0x8
-#define NIC_DCB_IP_PRI_MAX 0x40
-
-#define NIC_DCB_PRIO_DWRR 0x0
-#define NIC_DCB_PRIO_STRICT 0x1
-
-#define NIC_DCB_MAX_PFC_NUM 0x4
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
similarity index 77%
rename from drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
rename to drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
index c35bc82..a228522 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
- * File Name : hinic3_comm_cmd.h
+ * File Name : hinic3_nic_mpu_cmd.h
* Version : Initial Draft
* Created : 2019/4/25
* Last Modified :
@@ -33,10 +33,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_CFG_LOCAL_LRO_STATE,
HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
+ HINIC3_NIC_CMD_SET_FUNC_ER_FWD_ID,
HINIC3_NIC_CMD_SET_RQ_CI_CTX,
- /* MAC & VLAN CFG */
+ /* MAC & VLAN CFG & VXLAN CFG */
HINIC3_NIC_CMD_GET_MAC = 20,
HINIC3_NIC_CMD_SET_MAC,
HINIC3_NIC_CMD_DEL_MAC,
@@ -47,6 +48,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_VLAN_FILTER_EN,
HINIC3_NIC_CMD_SET_RX_VLAN_OFFLOAD,
HINIC3_NIC_CMD_SMAC_CHECK_STATE,
+ HINIC3_NIC_CMD_OUTBAND_SET_FUNC_VLAN,
+ HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+
+ HINIC3_NIC_CMD_RX_RATE_CFG,
+ HINIC3_NIC_CMD_WR_ORDERING_CFG,
/* SR-IOV */
HINIC3_NIC_CMD_CFG_VF_VLAN = 40,
@@ -63,6 +69,7 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC,
/* IP checksum error packets, enable rss quadruple hash */
HINIC3_NIC_CMD_IPCS_ERR_RSS_ENABLE_OP = 66,
+ HINIC3_NIC_CMD_GTP_INNER_PARSE_STATUS,
/* PPA/FDIR */
HINIC3_NIC_CMD_ADD_TC_FLOW = 80,
@@ -78,6 +85,10 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_CFG_PPA_FLUSH,
HINIC3_NIC_CMD_SET_FDIR_STATUS,
HINIC3_NIC_CMD_GET_PPA_COUNTER,
+ HINIC3_NIC_CMD_SET_FUNC_FLOW_BIFUR_ENABLE,
+ HINIC3_NIC_CMD_SET_BOND_MASK,
+ HINIC3_NIC_CMD_GET_BLOCK_TC_FLOWS,
+ HINIC3_NIC_CMD_GET_BOND_MASK,
/* PORT CFG */
HINIC3_NIC_CMD_SET_PORT_ENABLE = 100,
@@ -96,6 +107,8 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_QOS_PORT_CFG,
HINIC3_NIC_CMD_QOS_MAP_CFG,
HINIC3_NIC_CMD_FORCE_PKT_DROP,
+ HINIC3_NIC_CMD_CFG_TX_PROMISC_SKIP = 114,
+ HINIC3_NIC_CMD_SET_PORT_FLOW_BIFUR_ENABLE = 117,
HINIC3_NIC_CMD_TX_PAUSE_EXCP_NOTICE = 118,
HINIC3_NIC_CMD_INQUIRT_PAUSE_CFG = 119,
@@ -118,6 +131,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_UCAPTURE_OPT = 160, /* TODO: move to roce */
HINIC3_NIC_CMD_SET_VHD_CFG,
+ /* OUT OF BAND */
+ HINIC3_NIC_CMD_GET_OUTBAND_CFG = 170, /* Get outband vlan cfg info */
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE, /* Outband vlan cfg info report */
+
+
/* TODO: move to HILINK */
HINIC3_NIC_CMD_GET_PORT_STAT = 200,
HINIC3_NIC_CMD_CLEAN_PORT_STAT,
@@ -138,24 +156,23 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_LINK_ERR_EVENT,
HINIC3_NIC_CMD_SET_LED_STATUS,
- HINIC3_NIC_CMD_MAX = 256,
-};
+ /* mig */
+ HINIC3_NIC_CMD_MIG_SET_CEQ_CTRL = 230,
+ HINIC3_NIC_CMD_MIG_CFG_MSIX_INFO,
+ HINIC3_NIC_CMD_MIG_CFG_FUNC_VAT_TBL,
+ HINIC3_NIC_CMD_MIG_GET_VF_INFO,
+ HINIC3_NIC_CMD_MIG_CHK_MBX_EMPTY,
+ HINIC3_NIC_CMD_MIG_SET_VPORT_ENABLE,
+ HINIC3_NIC_CMD_MIG_CFG_SQ_CI,
+ HINIC3_NIC_CMD_MIG_CFG_RSS_TBL,
+ HINIC3_NIC_CMD_MIG_CFG_MAC_TBL,
+ HINIC3_NIC_CMD_MIG_TMP_SET_CMDQ_CTX,
+
+ HINIC3_OSHR_CMD_ACTIVE_FUNCTION = 240,
-/* NIC CMDQ MODE */
-enum hinic3_ucode_cmd {
- HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
- HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
- HINIC3_UCODE_CMD_ARM_SQ,
- HINIC3_UCODE_CMD_ARM_RQ,
- HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_SET_IQ_ENABLE,
- HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
- HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
- HINIC3_UCODE_CMD_PPA_HASH_TABLE,
- HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_NIC_CMD_GET_RQ_INFO = 241,
+
+ HINIC3_NIC_CMD_MAX = 256,
};
#endif /* HINIC3_NIC_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
similarity index 86%
rename from drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h
rename to drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
index 18a85f4..5c28573 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
@@ -20,6 +20,10 @@
#define NIC_TCAM_BLOCK_LARGE_NUM 256
#define NIC_TCAM_BLOCK_LARGE_SIZE 16
+#define TRAFFIC_BIFUR_MODEL_TYPE 2
+
+#define NIC_TCAM_FLOW_BIFUR_FLAG (1 << 0)
+
#ifndef BIT
#define BIT(n) (1UL << (n))
#endif
@@ -106,6 +110,7 @@ struct hinic3_port_state {
#define HINIC3_SET_PORT_CAR_PROFILE 0
#define HINIC3_SET_PORT_CAR_STATE 1
+#define HINIC3_GET_PORT_CAR_LIMIT_SPEED 2
struct hinic3_port_car_info {
u32 cir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
@@ -120,7 +125,7 @@ struct hinic3_cmd_set_port_car {
u8 port_id;
u8 opcode; /* 0--set car profile, 1--set car state */
u8 state; /* 0--disable, 1--enable */
- u8 rsvd;
+ u8 level;
struct hinic3_port_car_info car;
};
@@ -371,6 +376,14 @@ struct hinic3_cmd_local_lro_state {
u8 state; /* 0: disable, 1: enable */
};
+struct hinic3_cmd_gtp_inner_parse_status {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 status; /* 0: disable, 1: enable */
+};
+
struct hinic3_cmd_vf_vlan_config {
struct hinic3_mgmt_msg_head msg_head;
@@ -394,7 +407,8 @@ struct hinic3_cmd_tx_rate_cfg {
struct hinic3_mgmt_msg_head msg_head;
u16 func_id;
- u16 rsvd1;
+ u8 rsvd1;
+ u8 direct;
u32 min_rate;
u32 max_rate;
u8 rsvd2[8];
@@ -437,8 +451,22 @@ struct hinic3_cmd_vlan_config {
u16 func_id;
u8 opcode;
- u8 rsvd1;
+ u8 outband_defvid_flag;
u16 vlan_id;
+ u8 blacklist_flag;
+ u8 rsvd2;
+};
+
+#define VLAN_BLACKLIST_ENABLE 1
+#define VLAN_BLACKLIST_DISABLE 0
+
+struct hinic3_cmd_vxlan_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 cfg_mode;
+ u16 vxlan_port;
u16 rsvd2;
};
@@ -587,6 +615,7 @@ struct hinic3_up_ets_cfg { /* delet */
#define CMD_QOS_ETS_COS_PRIO BIT(2)
#define CMD_QOS_ETS_COS_BW BIT(3)
#define CMD_QOS_ETS_TC_PRIO BIT(4)
+#define CMD_QOS_ETS_TC_RATELIMIT BIT(5)
struct hinic3_cmd_ets_cfg {
struct hinic3_mgmt_msg_head head;
@@ -601,6 +630,7 @@ struct hinic3_cmd_ets_cfg {
u8 cos_prio[NIC_DCB_COS_MAX]; /* 0 - DWRR, 1 - STRICT */
u8 cos_bw[NIC_DCB_COS_MAX];
u8 tc_prio[NIC_DCB_TC_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 rate_limit[NIC_DCB_TC_MAX];
};
struct hinic3_cmd_set_dcb_state {
@@ -687,6 +717,8 @@ struct nic_cmd_pause_inquiry_cfg {
u32 type; /* 1: set, 2: get */
+ u32 cos_id;
+
u32 rx_inquiry_pause_drop_pkts_en;
u32 rx_inquiry_pause_period_ms;
u32 rx_inquiry_pause_times;
@@ -699,7 +731,7 @@ struct nic_cmd_pause_inquiry_cfg {
u32 tx_inquiry_pause_times; /* tx pause Default Times Period 5 */
u32 tx_inquiry_pause_frame_thd; /* tx pause Detection Threshold */
u32 tx_inquiry_rx_total_pkts;
- u32 rsvd[4];
+ u32 rsvd[3];
};
/* pfc/pause Storm TX exception reporting */
@@ -924,7 +956,9 @@ struct nic_cmd_fdir_get_block_rules {
};
struct hinic3_tcam_key_ipv4_mem {
- u32 rsvd1 : 4;
+ u32 rsvd1 : 1;
+ u32 bifur_flag : 2;
+ u32 model : 1;
u32 tunnel_type : 4;
u32 ip_proto : 8;
u32 rsvd0 : 16;
@@ -956,14 +990,16 @@ union hinic3_tag_tcam_ext_info {
u32 id : 16; /* id */
u32 type : 4; /* type: 0-func, 1-vmdq, 2-port, 3-rsvd, 4-trunk, 5-dp, 6-mc */
u32 host_id : 3;
- u32 rsv : 8;
+ u32 rss_q_num : 8; /* rss queue num */
u32 ext : 1;
} bs;
u32 value;
};
struct hinic3_tcam_key_ipv6_mem {
- u32 rsvd1 : 4;
+ u32 bifur_flag : 2;
+ u32 vlan_flag : 1;
+ u32 outer_ip_type : 1;
u32 tunnel_type : 4;
u32 ip_proto : 8;
u32 rsvd0 : 16;
@@ -1065,7 +1101,7 @@ struct hinic3_ppa_cfg_ppa_en_cmd {
u16 func_id;
u8 ppa_en;
- u8 rsvd;
+ u8 ppa_miss_drop_en;
};
struct hinic3_func_flow_bifur_en_cmd {
@@ -1079,7 +1115,8 @@ struct hinic3_port_flow_bifur_en_cmd {
struct hinic3_mgmt_msg_head msg_head;
u16 port_id;
u8 flow_bifur_en;
- u8 rsvd[5];
+ u8 flow_bifur_type; /* 0->vf bifur, 2->traffic bifur */
+ u8 rsvd[4];
};
struct hinic3_bond_mask_cmd {
@@ -1146,53 +1183,88 @@ enum {
NIC_NVM_DATA_VLAN_PRI = BIT(3),
NIC_NVM_DATA_VLAN_ID = BIT(4),
NIC_NVM_DATA_WORK_MODE = BIT(5),
- NIC_NVM_DATA_PF_SPEED_LIMIT = BIT(6),
+ NIC_NVM_DATA_PF_TX_SPEED_LIMIT = BIT(6),
NIC_NVM_DATA_GE_MODE = BIT(7),
NIC_NVM_DATA_AUTO_NEG = BIT(8),
NIC_NVM_DATA_LINK_FEC = BIT(9),
NIC_NVM_DATA_PF_ADAPTIVE_LINK = BIT(10),
NIC_NVM_DATA_SRIOV_CONTROL = BIT(11),
NIC_NVM_DATA_EXTEND_MODE = BIT(12),
+ NIC_NVM_DATA_LEGACY_VLAN = BIT(13),
+ NIC_NVM_DATA_LEGACY_VLAN_PRI = BIT(14),
+ NIC_NVM_DATA_LEGACY_VLAN_ID = BIT(15),
NIC_NVM_DATA_RESET = BIT(31),
};
-#define BIOS_CFG_SIGNATURE 0x1923E518
-#define BIOS_OP_CFG_ALL(op_code_val) ((((op_code_val) >> 1) & (0xFFFFFFFF)) != 0)
-#define BIOS_OP_CFG_WRITE(op_code_val) ((((op_code_val) & NIC_NVM_DATA_SET)) != 0)
-#define BIOS_OP_CFG_PXE_EN(op_code_val) (((op_code_val) & NIC_NVM_DATA_PXE) != 0)
-#define BIOS_OP_CFG_VLAN_EN(op_code_val) (((op_code_val) & NIC_NVM_DATA_VLAN) != 0)
-#define BIOS_OP_CFG_VLAN_PRI(op_code_val) (((op_code_val) & NIC_NVM_DATA_VLAN_PRI) != 0)
-#define BIOS_OP_CFG_VLAN_ID(op_code_val) (((op_code_val) & NIC_NVM_DATA_VLAN_ID) != 0)
-#define BIOS_OP_CFG_WORK_MODE(op_code_val) (((op_code_val) & NIC_NVM_DATA_WORK_MODE) != 0)
-#define BIOS_OP_CFG_PF_BW(op_code_val) (((op_code_val) & NIC_NVM_DATA_PF_SPEED_LIMIT) != 0)
-#define BIOS_OP_CFG_GE_SPEED(op_code_val) (((op_code_val) & NIC_NVM_DATA_GE_MODE) != 0)
-#define BIOS_OP_CFG_AUTO_NEG(op_code_val) (((op_code_val) & NIC_NVM_DATA_AUTO_NEG) != 0)
-#define BIOS_OP_CFG_LINK_FEC(op_code_val) (((op_code_val) & NIC_NVM_DATA_LINK_FEC) != 0)
-#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) (((op_code_val) & NIC_NVM_DATA_PF_ADAPTIVE_LINK) != 0)
-#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val) (((op_code_val) & NIC_NVM_DATA_SRIOV_CONTROL) != 0)
-#define BIOS_OP_CFG_EXTEND_MODE(op_code_val) (((op_code_val) & NIC_NVM_DATA_EXTEND_MODE) != 0)
-#define BIOS_OP_CFG_RST_DEF_SET(op_code_val) (((op_code_val) & (u32)NIC_NVM_DATA_RESET) != 0)
+#define BIOS_CFG_SIGNATURE 0x1923E518
+#define BIOS_OP_CFG_ALL(op_code_val) \
+ ((((op_code_val) >> 1) & (0xFFFFFFFF)) != 0)
+#define BIOS_OP_CFG_WRITE(op_code_val) \
+ ((((op_code_val) & NIC_NVM_DATA_SET)) != 0)
+#define BIOS_OP_CFG_PXE_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PXE) != 0)
+#define BIOS_OP_CFG_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN) != 0)
+#define BIOS_OP_CFG_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_ID) != 0)
+#define BIOS_OP_CFG_WORK_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_WORK_MODE) != 0)
+#define BIOS_OP_CFG_PF_BW(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_TX_SPEED_LIMIT) != 0)
+#define BIOS_OP_CFG_GE_SPEED(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_GE_MODE) != 0)
+#define BIOS_OP_CFG_AUTO_NEG(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_AUTO_NEG) != 0)
+#define BIOS_OP_CFG_LINK_FEC(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LINK_FEC) != 0)
+#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_ADAPTIVE_LINK) != 0)
+#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_SRIOV_CONTROL) != 0)
+#define BIOS_OP_CFG_EXTEND_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_EXTEND_MODE) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_ID) != 0)
+#define BIOS_OP_CFG_RST_DEF_SET(op_code_val) \
+ (((op_code_val) & (u32)NIC_NVM_DATA_RESET) != 0)
+
#define NIC_BIOS_CFG_MAX_PF_BW 100
+
+struct nic_legacy_vlan_cfg {
+ /* Legacy mode PXE VLAN enable: 0 - disable 1 - enable */
+ u8 pxe_vlan_en : 1;
+ /* Legacy mode PXE VLAN priority: 0-7 */
+ u8 pxe_vlan_pri : 3;
+ /* Legacy mode PXE VLAN ID 1-4094 */
+ u16 pxe_vlan_id : 12;
+};
+
/* Note: This structure must be 4-byte aligned. */
struct nic_bios_cfg {
u32 signature;
- u8 pxe_en; /* PXE enable: 0 - disable 1 - enable */
+ u8 pxe_en;
u8 extend_mode;
- u8 rsvd0[2];
- u8 pxe_vlan_en; /* PXE VLAN enable: 0 - disable 1 - enable */
- u8 pxe_vlan_pri; /* PXE VLAN priority: 0-7 */
- u16 pxe_vlan_id; /* PXE VLAN ID 1-4094 */
- u32 service_mode; /* @See CHIPIF_SERVICE_MODE_x */
- u32 pf_bw; /* PF rate, in percentage. The value ranges from 0 to 100. */
- u8 speed; /* enum of port speed */
- u8 auto_neg; /* Auto-Negotiation Switch 0 - Invalid Field 1 - On 2 - Off */
- u8 lanes; /* lane num */
- u8 fec; /* FEC mode, @See enum mag_cmd_port_fec */
- u8 auto_adapt; /* Adaptive Mode Configuration 0 - Invalid Configuration 1 - On 2 - Off */
- u8 func_valid; /* Whether func_id is valid; 0: invalid; other: valid */
- u8 func_id; /* This member is valid only when func_valid is not set to 0. */
- u8 sriov_en; /* SRIOV-EN: 0 - Invalid configuration, 1 - On, 2 - Off */
+ struct nic_legacy_vlan_cfg nlvc;
+ u8 pxe_vlan_en;
+ u8 pxe_vlan_pri;
+ u16 pxe_vlan_id;
+ u32 service_mode;
+ u32 pf_tx_bw;
+ u8 speed;
+ u8 auto_neg;
+ u8 lanes;
+ u8 fec;
+ u8 auto_adapt;
+ u8 func_valid;
+ u8 func_id;
+ u8 sriov_en;
};
struct nic_cmd_bios_cfg {
@@ -1201,6 +1273,14 @@ struct nic_cmd_bios_cfg {
struct nic_bios_cfg bios_cfg;
};
+struct nic_rx_rate_bios_cfg {
+ struct mgmt_msg_head msg_head;
+
+ u32 op_code; /* Operation Code:[0:read 1:write] */
+ u8 rx_rate_limit;
+ u8 func_id;
+};
+
struct nic_cmd_vhd_config {
struct hinic3_mgmt_msg_head head;
@@ -1222,7 +1302,8 @@ struct hinic3_create_bond_info {
u32 active_port_max_num; /* Maximum number of active bond member interfaces */
u32 active_port_min_num; /* Minimum number of active bond member interfaces */
u32 xmit_hash_policy;
- u32 rsvd[2];
+ u32 default_param_flag;
+ u32 rsvd;
};
struct hinic3_cmd_create_bond {
@@ -1317,7 +1398,8 @@ struct hinic3_smac_check_state {
struct hinic3_mgmt_msg_head head;
u8 smac_check_en; /* 1: enable 0: disable */
u8 op_code; /* 1: set 0: get */
- u8 rsvd[2];
+ u8 flash_en; /* 1: enable 0: disable */
+ u8 rsvd;
};
struct hinic3_clear_log_state {
@@ -1325,4 +1407,34 @@ struct hinic3_clear_log_state {
u32 type;
};
+struct hinic3_outband_cfg_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 outband_default_vid;
+ u16 func_id;
+};
+
+struct hinic3_wr_ordering {
+ struct hinic3_mgmt_msg_head head;
+ u8 op_code; /* 1: set 0: get */
+ u8 wr_pkt_so_ro;
+ u8 rd_pkt_so_ro;
+ u8 rsvd;
+};
+
+struct hinic3_function_active_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_rq_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rq_depth;
+ u16 rq_num;
+ u16 pf_num;
+ u16 port_num;
+};
+
#endif /* HINIC_MGMT_INTERFACE_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
new file mode 100644
index 0000000..3e625fc
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
+ * File Name : nic_npu_cmd.h
+ * Version : Initial Draft
+ * Created : 2019/4/25
+ * Last Modified :
+ * Description : NIC Commands between Driver and NPU
+ * Function List :
+ */
+
+#ifndef NIC_NPU_CMD_H
+#define NIC_NPU_CMD_H
+
+/* NIC CMDQ MODE */
+enum hinic3_ucode_cmd {
+ HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
+ HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
+ HINIC3_UCODE_CMD_ARM_SQ, /**< Unused */
+ HINIC3_UCODE_CMD_ARM_RQ, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_IQ_ENABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
+ HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
+ HINIC3_UCODE_CMD_PPA_HASH_TABLE,
+ HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_UCODE_MIG_CFG_Q_CTX = 14,
+ HINIC3_UCODE_MIG_CHK_SQ_STOP,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ HINIC3_UCODE_MIG_CFG_BAT_INFO,
+};
+
+#endif /* NIC_NPU_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
index 78a8d7f..00f4a24 100644
--- a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
+++ b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
@@ -4,7 +4,9 @@
#ifndef OSSL_KNL_LINUX_H_
#define OSSL_KNL_LINUX_H_
+#include <net/checksum.h>
#include <net/ipv6.h>
+#include <net/devlink.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/device.h>
@@ -18,6 +20,12 @@
#include <linux/list.h>
#include <linux/bitmap.h>
#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/filter.h>
+#include <linux/aer.h>
+#include <linux/socket.h>
#ifndef NETIF_F_SCTP_CSUM
#define NETIF_F_SCTP_CSUM 0
@@ -173,12 +181,10 @@ static inline void *_hinic3_dma_zalloc_coherent(struct device *dev,
}
#endif
-#ifndef DT_KNL_EMU
struct timeval {
__kernel_old_time_t tv_sec; /* seconds */
__kernel_suseconds_t tv_usec; /* microseconds */
};
-#endif
#ifndef do_gettimeofday
#define do_gettimeofday(time) _kc_do_gettimeofday(time)
@@ -196,6 +202,10 @@ static inline void _kc_do_gettimeofday(struct timeval *tv)
#define ETH_GET_HEADLEN_NEED_DEV
#define HAVE_GENL_OPS_FIELD_VALIDATE
+#ifndef FIELD_SIZEOF
+#define FIELD_SIZEOF(t, f) (sizeof(((t *)0)->f))
+#endif
+
#define HAVE_DEVLINK_FLASH_UPDATE_PARAMS
#ifndef rtc_time_to_tm
@@ -253,12 +263,12 @@ static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size,
size, vaddr, dma_handle);
}
-#define HAVE_DEVLINK_FW_FILE_NAME_MEMBER
-
#define HAVE_ENCAPSULATION_TSO
#define HAVE_ENCAPSULATION_CSUM
+#define HAVE_UDP_TUNNEL_NIC_INFO
+
#ifndef eth_zero_addr
static inline void hinic3_eth_zero_addr(u8 *addr)
{
@@ -333,4 +343,15 @@ u64 ossl_get_real_time(void);
#define tasklet_state(tasklet) ((tasklet)->state)
+dma_addr_t pci_map_single(struct pci_dev *pdev,
+ void *ptr, size_t size, int direction);
+int pci_dma_mapping_error(struct pci_dev *pdev,
+ dma_addr_t dma_addr);
+void pci_unmap_single(struct pci_dev *pdev,
+ dma_addr_t dma_addr, size_t size, int direction);
+void *pci_alloc_consistent(struct pci_dev *pdev,
+ size_t size, dma_addr_t *dma_handle);
+void pci_free_consistent(struct pci_dev *pdev,
+ size_t size, void *vaddr, dma_addr_t dma_handle);
+
#endif
--
2.43.0
2
1

08 May '25
From: z30065765 <zhuyikai1(a)h-partners.com>
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IC5K44?from=project-issue
CVE: NA
--------------------------------
Add optical module type adaptation.
Add ethtool fec function.
Add NIC XDP PASS function.
Add QoS persistence.
Add NIC out-of-band VLAN configuration function.
Fix NIC bifur bugs.
Fix performance test bugs.
Fix NIC RX bugs.
Fix NIC VF bugs.
Fix the bug of exiting when probing NIC.
Fix bond bugs.
Fix the bug of reading NIC status incorrectly.
Fix and add some statistics.
Signed-off-by: z30065765 <zhuyikai1(a)h-partners.com>
---
drivers/net/ethernet/huawei/hinic3/Makefile | 1 +
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c | 136 +-
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h | 1 +
drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h | 212 ---
drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h | 239 ----
drivers/net/ethernet/huawei/hinic3/comm_defs.h | 105 --
drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h | 103 --
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c | 51 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h | 2 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c | 86 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c | 1 -
drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c | 28 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c | 27 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c | 37 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c | 9 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c | 12 +-
drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h | 185 ---
drivers/net/ethernet/huawei/hinic3/hinic3_common.h | 118 --
drivers/net/ethernet/huawei/hinic3/hinic3_crm.h | 30 +-
drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c | 305 ++--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c | 267 ++--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h | 7 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c | 227 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c | 387 ++++--
drivers/net/ethernet/huawei/hinic3/hinic3_filter.c | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_hw.h | 18 +
drivers/net/ethernet/huawei/hinic3/hinic3_irq.c | 11 +-
drivers/net/ethernet/huawei/hinic3/hinic3_lld.h | 205 ---
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c | 836 ++++++++++-
drivers/net/ethernet/huawei/hinic3/hinic3_main.c | 476 ++++++-
drivers/net/ethernet/huawei/hinic3/hinic3_mt.h | 225 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c | 372 +++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic.h | 61 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c | 450 ++++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h | 55 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c | 167 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c | 13 +
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h | 221 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c | 119 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c | 18 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c | 18 +-
drivers/net/ethernet/huawei/hinic3/hinic3_profile.h | 146 --
drivers/net/ethernet/huawei/hinic3/hinic3_rss.c | 142 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c | 41 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rx.c | 357 +++--
drivers/net/ethernet/huawei/hinic3/hinic3_rx.h | 39 +-
drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h | 6 +-
drivers/net/ethernet/huawei/hinic3/hinic3_tx.c | 141 +-
drivers/net/ethernet/huawei/hinic3/hinic3_wq.h | 4 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c | 15 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c | 13 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h | 5 -
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c | 206 ++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h | 13 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c | 5 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c | 14 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c | 42 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c | 91 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h | 13 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c | 163 ++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c | 116 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c | 87 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h | 34 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c | 40 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c | 1223 +++++++++++++++--
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c | 3 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c | 6 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c | 44 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c | 182 ++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h | 4 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h | 31 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c | 52 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c | 2 +-
drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h | 4 +
.../include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h | 13 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h | 42 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h | 2 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h | 130 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h | 109 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h | 5 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h | 30 +-
.../include/mpu/mpu_outband_ncsi_cmd_defs.h | 8 +
drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h | 16 +-
drivers/net/ethernet/huawei/hinic3/include/vram_common.h | 11 +-
drivers/net/ethernet/huawei/hinic3/{mag_cmd.h => mag_mpu_cmd_defs.h} | 237 +++-
drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h | 27 -
drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h | 63 -
drivers/net/ethernet/huawei/hinic3/{hinic3_nic_cmd.h => nic_mpu_cmd.h} | 59 +-
...c3_mgmt_interface.h => nic_mpu_cmd_defs.h} | 218 ++-
drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h | 36 +
drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h | 94 +-
96 files changed, 7147 insertions(+), 3092 deletions(-)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_defs.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_common.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
rename drivers/net/ethernet/huawei/hinic3/{mag_cmd.h => mag_mpu_cmd_defs.h} (79%)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
rename drivers/net/ethernet/huawei/hinic3/{hinic3_nic_cmd.h => nic_mpu_cmd.h} (77%)
rename drivers/net/ethernet/huawei/hinic3/{hinic3_mgmt_interface.h => nic_mpu_cmd_defs.h} (84%)
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
diff --git a/drivers/net/ethernet/huawei/hinic3/Makefile b/drivers/net/ethernet/huawei/hinic3/Makefile
index 11fe010..21d8093 100644
--- a/drivers/net/ethernet/huawei/hinic3/Makefile
+++ b/drivers/net/ethernet/huawei/hinic3/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/hw/
+ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/bond/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/cqm/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/hinic3/include/cqm/
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
index ba3076c..a252e09 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
@@ -9,14 +9,18 @@
#include <linux/net.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
+#include <linux/version.h>
+#include "ossl_knl.h"
#include "hinic3_lld.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic_dev.h"
#include "hinic3_hw.h"
-#include "mpu_inband_cmd.h"
-#include "hinic3_hwdev.h"
#include "hinic3_bond.h"
+#include "hinic3_hwdev.h"
+
+#include "bond_common_defs.h"
+#include "vram_common.h"
#define PORT_INVALID_ID 0xFF
@@ -214,10 +218,10 @@ static void bond_dev_untrack_port(struct hinic3_bond_dev *bdev, u8 idx)
spin_lock(&bdev->lock);
if (bdev->tracker.ndev[idx]) {
- pr_info("hinic3_bond: untrack port:%u ndev:%s cnt:%d\n", idx,
- bdev->tracker.ndev[idx]->name, bdev->tracker.cnt);
bdev->tracker.ndev[idx] = NULL;
bdev->tracker.cnt--;
+ pr_info("hinic3_bond: untrack port:%u ndev:%s cnt:%d\n", idx,
+ bdev->tracker.ndev[idx]->name, bdev->tracker.cnt);
}
spin_unlock(&bdev->lock);
@@ -268,11 +272,16 @@ static void bond_master_event(struct hinic3_bond_dev *bdev,
queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
}
-static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
+static struct hinic3_bond_dev *bond_get_bdev(struct bonding *bond)
{
struct hinic3_bond_dev *bdev = NULL;
int bid;
+ if (bond == NULL) {
+ pr_err("hinic3_bond: bond is NULL\n");
+ return NULL;
+ }
+
mutex_lock(&g_bond_mutex);
for (bid = BOND_FIRST_ID; bid <= BOND_MAX_ID; bid++) {
bdev = bond_mngr.bond_dev[bid];
@@ -283,38 +292,72 @@ static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
mutex_unlock(&g_bond_mutex);
return bdev;
}
+
+ if (strncmp(bond->dev->name, bdev->name, BOND_NAME_MAX_LEN) == 0) {
+ bdev->bond = bond;
+ return bdev;
+ }
}
mutex_unlock(&g_bond_mutex);
return NULL;
}
-static void bond_handle_rtnl_event(struct net_device *ndev)
+static struct bonding *get_bonding_by_netdev(struct net_device *ndev)
{
- struct hinic3_bond_dev *bdev = NULL;
struct bonding *bond = NULL;
struct slave *slave = NULL;
if (netif_is_bond_master(ndev)) {
bond = netdev_priv(ndev);
- bdev = bond_get_bdev(bond);
} else if (netif_is_bond_slave(ndev)) {
- /*lint -e(160) */
slave = bond_slave_get_rtnl(ndev);
if (slave) {
bond = bond_get_bond_by_slave(slave);
- bdev = bond_get_bdev(bond);
}
}
- if (!bond || !bdev)
+ return bond;
+}
+/*lint -e580 -e546*/
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+
+ if (!ndev) {
+ pr_err("hinic3_bond: netdev is NULL\n");
+ return false;
+ }
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
+ return false;
+
+ return bdev->status == BOND_DEV_STATUS_ACTIVATED;
+}
+EXPORT_SYMBOL(hinic3_is_bond_dev_status_actived);
+/*lint +e580 +e546*/
+
+static void bond_handle_rtnl_event(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+ struct slave *slave = NULL;
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
return;
bond_update_attr(bdev, bond);
- if (slave)
+ if (netif_is_bond_slave(ndev)) {
+ slave = bond_slave_get_rtnl(ndev);
bond_slave_event(bdev, slave);
- else
+ } else {
bond_master_event(bdev, bond);
+ }
}
static void bond_rtnl_data_ready(struct sock *sk)
@@ -478,7 +521,11 @@ static void bond_update_slave_info(struct hinic3_bond_dev *bdev,
continue;
}
+ if (!bdev->tracker.ndev[i])
+ continue;
+
bond_pf_bitmap_set(bdev, i);
+
if (!bdev->tracker.netdev_state[i].tx_enabled)
continue;
@@ -516,6 +563,7 @@ static int bond_upcmd_config(struct hinic3_bond_dev *bdev,
attr->active_slaves,
attr->lacp_collect_slaves);
pr_info("bond_pf_bitmap: 0x%x\n", attr->bond_pf_bitmap);
+ pr_info("bond user_bitmap 0x%x\n", attr->user_bitmap);
err = bond_send_upcmd(bdev, attr, MPU_CMD_BOND_SET_ATTR);
if (!err)
@@ -560,17 +608,36 @@ static void bond_call_service_func(struct hinic3_bond_dev *bdev, struct bond_att
mutex_unlock(&g_bond_service_func_mutex);
}
+static u32 bond_get_user_bitmap(struct hinic3_bond_dev *bdev)
+{
+ u32 user_bitmap = 0;
+ u8 user;
+
+ for (user = HINIC3_BOND_USER_OVS; user < HINIC3_BOND_USER_NUM; user++) {
+ if (bdev->slot_used[user] == 1)
+ BITMAP_SET(user_bitmap, user);
+ }
+ return user_bitmap;
+}
+
static void bond_do_work(struct hinic3_bond_dev *bdev)
{
bool is_bonded = 0;
struct bond_attr attr;
+ int is_in_kexec;
int err = 0;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ pr_info("Skip changing bond status during os replace\n");
+ return;
+ }
+
spin_lock(&bdev->lock);
is_bonded = bdev->tracker.is_bonded;
attr = bdev->new_attr;
spin_unlock(&bdev->lock);
- attr.user_bitmap = 0;
+ attr.user_bitmap = bond_get_user_bitmap(bdev);
/* is_bonded indicates whether bond should be activated. */
if (is_bonded && !bond_dev_is_activated(bdev)) {
@@ -591,17 +658,21 @@ static void bond_do_work(struct hinic3_bond_dev *bdev)
pr_err("hinic3_bond: Do bond failed\n");
}
-#define MIN_BOND_SLAVE_CNT 2
static void bond_try_do_work(struct work_struct *work)
{
struct delayed_work *delayed_work = to_delayed_work(work);
struct hinic3_bond_dev *bdev =
container_of(delayed_work, struct hinic3_bond_dev, bond_work);
+ int status;
- if (g_bond_service_func[HINIC3_BOND_USER_ROCE] && bdev->tracker.cnt < MIN_BOND_SLAVE_CNT)
+ status = mutex_trylock(&g_bond_mutex);
+ if (status == 0) {
+ /* Delay 1 sec and retry */
queue_delayed_work(bdev->wq, &bdev->bond_work, HZ);
- else
+ } else {
bond_do_work(bdev);
+ mutex_unlock(&g_bond_mutex);
+ }
}
static int bond_dev_init(struct hinic3_bond_dev *bdev, const char *name)
@@ -630,6 +701,7 @@ static int bond_dev_release(struct hinic3_bond_dev *bdev)
err = bond_upcmd_deactivate(bdev);
if (err) {
pr_err("hinic3_bond: Failed to deactivate dev\n");
+ mutex_unlock(&g_bond_mutex);
return err;
}
@@ -764,20 +836,28 @@ static struct hinic3_bond_dev *bond_dev_by_name(const char *name)
static void bond_dev_user_attach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user)
{
+ u32 user_bitmap;
+
+ if (user < 0 || user >= HINIC3_BOND_USER_NUM)
+ return;
+
if (bdev->slot_used[user])
return;
bdev->slot_used[user] = 1;
if (!kref_get_unless_zero(&bdev->ref))
kref_init(&bdev->ref);
+ else {
+ user_bitmap = bond_get_user_bitmap(bdev);
+ pr_info("hinic3_bond: user %u attach bond %s, user_bitmap %#x\n",
+ user, bdev->name, user_bitmap);
+ queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
+ }
}
static void bond_dev_user_detach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user, bool *freed)
{
- if (user < 0 || user >= HINIC3_BOND_USER_NUM)
- return;
-
if (bdev->slot_used[user]) {
bdev->slot_used[user] = 0;
if (kref_read(&bdev->ref) == 1)
@@ -790,12 +870,15 @@ static struct bonding *bond_get_knl_bonding(const char *name)
{
struct net_device *ndev_tmp = NULL;
+ rcu_read_lock();
for_each_netdev(&init_net, ndev_tmp) {
if (netif_is_bond_master(ndev_tmp) &&
- !strcmp(ndev_tmp->name, name))
+ !strcmp(ndev_tmp->name, name)) {
+ rcu_read_unlock();
return netdev_priv(ndev_tmp);
+ }
}
-
+ rcu_read_unlock();
return NULL;
}
@@ -852,8 +935,9 @@ int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user)
int err = 0;
bool lock_freed = false;
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
- pr_warn("hinic3_bond: Invalid bond id:%u to delete\n", bond_id);
+ if (!BOND_ID_IS_VALID(bond_id) || user >= HINIC3_BOND_USER_NUM) {
+ pr_warn("hinic3_bond: Invalid bond id or user, bond_id: %u, user: %d\n",
+ bond_id, user);
return -EINVAL;
}
@@ -891,7 +975,7 @@ EXPORT_SYMBOL(hinic3_bond_clean_user);
int hinic3_bond_get_uplink_id(u16 bond_id, u32 *uplink_id)
{
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID || !uplink_id) {
+ if (!BOND_ID_IS_VALID(bond_id) || !uplink_id) {
pr_warn("hinic3_bond: Invalid args, id: %u, uplink: %d\n",
bond_id, !!uplink_id);
return -EINVAL;
@@ -941,7 +1025,7 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
int i;
int len;
- if (!info || bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
+ if (!info || !BOND_ID_IS_VALID(bond_id)) {
pr_warn("hinic3_bond: Invalid args, info: %d,id: %u\n",
!!info, bond_id);
return -EINVAL;
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
index 024de95..5ab36f7 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
@@ -82,6 +82,7 @@ struct hinic3_bond_cmd {
char bond_name[16];
};
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev);
void hinic3_bond_set_user_bitmap(struct bond_attr *attr, enum hinic3_bond_user user);
int hinic3_bond_attach(const char *name, enum hinic3_bond_user user, u16 *bond_id);
int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user);
diff --git a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h b/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
deleted file mode 100644
index 557f326..0000000
--- a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2016-2022. All rights reserved.
- * File name: Cfg_mgt_comm_pub.h
- * Version No.: Draft
- * Generation date: 2016 year 05 month 07 day
- * Latest modification:
- * Function description: Header file for communication between the: Host and FW
- * Function list:
- * Modification history:
- * 1. Date: 2016 May 07
- * Modify content: Create a file.
- */
-#ifndef CFG_MGT_COMM_PUB_H
-#define CFG_MGT_COMM_PUB_H
-
-#include "mgmt_msg_base.h"
-
-enum servic_bit_define {
- SERVICE_BIT_NIC = 0,
- SERVICE_BIT_ROCE = 1,
- SERVICE_BIT_VBS = 2,
- SERVICE_BIT_TOE = 3,
- SERVICE_BIT_IPSEC = 4,
- SERVICE_BIT_FC = 5,
- SERVICE_BIT_VIRTIO = 6,
- SERVICE_BIT_OVS = 7,
- SERVICE_BIT_NVME = 8,
- SERVICE_BIT_ROCEAA = 9,
- SERVICE_BIT_CURRENET = 10,
- SERVICE_BIT_PPA = 11,
- SERVICE_BIT_MIGRATE = 12,
- SERVICE_BIT_MAX
-};
-
-#define CFG_SERVICE_MASK_NIC (0x1 << SERVICE_BIT_NIC)
-#define CFG_SERVICE_MASK_ROCE (0x1 << SERVICE_BIT_ROCE)
-#define CFG_SERVICE_MASK_VBS (0x1 << SERVICE_BIT_VBS)
-#define CFG_SERVICE_MASK_TOE (0x1 << SERVICE_BIT_TOE)
-#define CFG_SERVICE_MASK_IPSEC (0x1 << SERVICE_BIT_IPSEC)
-#define CFG_SERVICE_MASK_FC (0x1 << SERVICE_BIT_FC)
-#define CFG_SERVICE_MASK_VIRTIO (0x1 << SERVICE_BIT_VIRTIO)
-#define CFG_SERVICE_MASK_OVS (0x1 << SERVICE_BIT_OVS)
-#define CFG_SERVICE_MASK_NVME (0x1 << SERVICE_BIT_NVME)
-#define CFG_SERVICE_MASK_ROCEAA (0x1 << SERVICE_BIT_ROCEAA)
-#define CFG_SERVICE_MASK_CURRENET (0x1 << SERVICE_BIT_CURRENET)
-#define CFG_SERVICE_MASK_PPA (0x1 << SERVICE_BIT_PPA)
-#define CFG_SERVICE_MASK_MIGRATE (0x1 << SERVICE_BIT_MIGRATE)
-
-/* Definition of the scenario ID in the cfg_data, which is used for SML memory allocation. */
-enum scenes_id_define {
- SCENES_ID_FPGA_ETH = 0,
- SCENES_ID_FPGA_TIOE = 1, /* Discarded */
- SCENES_ID_STORAGE_ROCEAA_2x100 = 2,
- SCENES_ID_STORAGE_ROCEAA_4x25 = 3,
- SCENES_ID_CLOUD = 4,
- SCENES_ID_FC = 5,
- SCENES_ID_STORAGE_ROCE = 6,
- SCENES_ID_COMPUTE_ROCE = 7,
- SCENES_ID_STORAGE_TOE = 8,
- SCENES_ID_MAX
-};
-
-/* struct cfg_cmd_dev_cap.sf_svc_attr */
-enum {
- SF_SVC_FT_BIT = (1 << 0),
- SF_SVC_RDMA_BIT = (1 << 1),
-};
-
-enum cfg_cmd {
- CFG_CMD_GET_DEV_CAP = 0,
- CFG_CMD_GET_HOST_TIMER = 1,
-};
-
-struct cfg_cmd_host_timer {
- struct mgmt_msg_head head;
-
- u8 host_id;
- u8 rsvd1;
-
- u8 timer_pf_num;
- u8 timer_pf_id_start;
- u16 timer_vf_num;
- u16 timer_vf_id_start;
- u32 rsvd2[8];
-};
-
-struct cfg_cmd_dev_cap {
- struct mgmt_msg_head head;
-
- u16 func_id;
- u16 rsvd1;
-
- /* Public resources */
- u8 host_id;
- u8 ep_id;
- u8 er_id;
- u8 port_id;
-
- u16 host_total_func;
- u8 host_pf_num;
- u8 pf_id_start;
- u16 host_vf_num;
- u16 vf_id_start;
- u8 host_oq_id_mask_val;
- u8 timer_en;
- u8 host_valid_bitmap;
- u8 rsvd_host;
-
- u16 svc_cap_en;
- u16 max_vf;
- u8 flexq_en;
- u8 valid_cos_bitmap;
- /* Reserved for func_valid_cos_bitmap */
- u8 port_cos_valid_bitmap;
- u8 rsvd_func1;
- u32 rsvd_func2;
-
- u8 sf_svc_attr;
- u8 func_sf_en;
- u8 lb_mode;
- u8 smf_pg;
-
- u32 max_conn_num;
- u16 max_stick2cache_num;
- u16 max_bfilter_start_addr;
- u16 bfilter_len;
- u16 hash_bucket_num;
-
- /* shared resource */
- u8 host_sf_en;
- u8 master_host_id;
- u8 srv_multi_host_mode;
- u8 virtio_vq_size;
-
- u32 rsvd_func3[5];
-
- /* l2nic */
- u16 nic_max_sq_id;
- u16 nic_max_rq_id;
- u16 nic_default_num_queues;
- u16 rsvd1_nic;
- u32 rsvd2_nic[2];
-
- /* RoCE */
- u32 roce_max_qp;
- u32 roce_max_cq;
- u32 roce_max_srq;
- u32 roce_max_mpt;
- u32 roce_max_drc_qp;
-
- u32 roce_cmtt_cl_start;
- u32 roce_cmtt_cl_end;
- u32 roce_cmtt_cl_size;
-
- u32 roce_dmtt_cl_start;
- u32 roce_dmtt_cl_end;
- u32 roce_dmtt_cl_size;
-
- u32 roce_wqe_cl_start;
- u32 roce_wqe_cl_end;
- u32 roce_wqe_cl_size;
- u8 roce_srq_container_mode;
- u8 rsvd_roce1[3];
- u32 rsvd_roce2[5];
-
- /* IPsec */
- u32 ipsec_max_sactx;
- u16 ipsec_max_cq;
- u16 rsvd_ipsec1;
- u32 rsvd_ipsec[2];
-
- /* OVS */
- u32 ovs_max_qpc;
- u32 rsvd_ovs1[3];
-
- /* ToE */
- u32 toe_max_pctx;
- u32 toe_max_cq;
- u16 toe_max_srq;
- u16 toe_srq_id_start;
- u16 toe_max_mpt;
- u16 toe_max_cctxt;
- u32 rsvd_toe[2];
-
- /* FC */
- u32 fc_max_pctx;
- u32 fc_max_scq;
- u32 fc_max_srq;
-
- u32 fc_max_cctx;
- u32 fc_cctx_id_start;
-
- u8 fc_vp_id_start;
- u8 fc_vp_id_end;
- u8 rsvd_fc1[2];
- u32 rsvd_fc2[5];
-
- /* VBS */
- u16 vbs_max_volq;
- u16 rsvd0_vbs;
- u32 rsvd1_vbs[3];
-
- u16 fake_vf_start_id;
- u16 fake_vf_num;
- u32 fake_vf_max_pctx;
- u16 fake_vf_bfilter_start_addr;
- u16 fake_vf_bfilter_len;
- u32 rsvd_glb[8];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
deleted file mode 100644
index 6f5f87b..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/******************************************************************************
- * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
- ******************************************************************************
- File Name : comm_cmdq_intf.h
- Version : Initial Draft
- Description : common command queue interface
- Function List :
- History :
- Modification: Created file
-
-******************************************************************************/
-
-#ifndef COMM_CMDQ_INTF_H
-#define COMM_CMDQ_INTF_H
-
-/* Cmdq ack type */
-enum hinic3_ack_type {
- HINIC3_ACK_TYPE_CMDQ,
- HINIC3_ACK_TYPE_SHARE_CQN,
- HINIC3_ACK_TYPE_APP_CQN,
-
- HINIC3_MOD_ACK_MAX = 15,
-};
-
-/* Defines the queue type of the set arm bit. */
-enum {
- SET_ARM_BIT_FOR_CMDQ = 0,
- SET_ARM_BIT_FOR_L2NIC_SQ,
- SET_ARM_BIT_FOR_L2NIC_RQ,
- SET_ARM_BIT_TYPE_NUM
-};
-
-/* Defines the type. Each function supports a maximum of eight CMDQ types. */
-enum {
- CMDQ_0 = 0,
- CMDQ_1 = 1, /* dedicated and non-blocking queues */
- CMDQ_NUM
-};
-
-/* *******************cmd common command data structure ************************ */
-// Func->ucode, which is used to set arm bit data,
-// The microcode needs to perform big-endian conversion.
-struct comm_info_ucode_set_arm_bit {
- u32 q_type;
- u32 q_id;
-};
-
-/* *******************WQE data structure ************************ */
-union cmdq_wqe_cs_dw0 {
- struct {
- u32 err_status : 29;
- u32 error_code : 2;
- u32 rsvd : 1;
- } bs;
- u32 val;
-};
-
-union cmdq_wqe_cs_dw1 {
- // This structure is used when the driver writes the wqe.
- struct {
- u32 token : 16; // [15:0]
- u32 cmd : 8; // [23:16]
- u32 mod : 5; // [28:24]
- u32 ack_type : 2; // [30:29]
- u32 obit : 1; // [31]
- } drv_wr;
-
- /* The uCode writes back the structure of the CS_DW1.
- * The driver reads and uses the structure. */
- struct {
- u32 mod : 5; // [4:0]
- u32 ack_type : 3; // [7:5]
- u32 cmd : 8; // [15:8]
- u32 arm : 1; // [16]
- u32 rsvd : 14; // [30:17]
- u32 obit : 1; // [31]
- } wb;
- u32 val;
-};
-
-/* CmdQ BD information or write back buffer information */
-struct cmdq_sge {
- u32 pa_h; // Upper 32 bits of the physical address
- u32 pa_l; // Upper 32 bits of the physical address
- u32 len; // Invalid bit[31].
- u32 resv;
-};
-
-/* Ctrls section definition of WQE */
-struct cmdq_wqe_ctrls {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
-};
-
-/* Complete section definition of WQE */
-struct cmdq_wqe_cs {
- union cmdq_wqe_cs_dw0 dw0;
- union cmdq_wqe_cs_dw1 dw1;
- union {
- struct cmdq_sge sge;
- u32 dw2_5[4];
- } ack;
-};
-
-/* Inline header in WQE inline, describing the length of inline data */
-union cmdq_wqe_inline_header {
- struct {
- u32 buf_len : 11; // [10:0] inline data len
- u32 rsv : 21; // [31:11]
- } bs;
- u32 val;
-};
-
-/* Definition of buffer descriptor section in WQE */
-union cmdq_wqe_bds {
- struct {
- struct cmdq_sge bds_sge;
- u32 rsvd[4]; /* Zwy is used to transfer the virtual address of the buffer. */
- } lcmd; /* Long command, non-inline, and SGE describe the buffer information. */
-};
-
-/* Definition of CMDQ WQE */
-/* (long cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(16B) |
- * | |
- * +----------------------------------------+
- * | driver section(16B) |
- * +----------------------------------------+
- *
- *
- * (middle cmd, 128B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(88B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- *
- *
- * (short cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(24B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- */
-struct cmdq_wqe {
- struct cmdq_wqe_ctrls ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds bds;
-};
-
-/* Definition of ctrls section in inline WQE */
-struct cmdq_wqe_ctrls_inline {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
- u64 db;
-};
-
-/* Buffer descriptor section definition of WQE */
-union cmdq_wqe_bds_inline {
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[80];
- } mcmd; /* Middle command, inline mode */
-
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[16];
- } scmd; /* Short command, inline mode */
-};
-
-struct cmdq_wqe_inline {
- struct cmdq_wqe_ctrls_inline ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds_inline bds;
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_defs.h b/drivers/net/ethernet/huawei/hinic3/comm_defs.h
deleted file mode 100644
index 91d298d..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_defs.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_defs.h
- * Version : Initial Draft
- * Description : common definitions
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef COMM_DEFS_H
-#define COMM_DEFS_H
-
-/* CMDQ MODULE_TYPE */
-enum hinic3_mod_type {
- HINIC3_MOD_COMM = 0, /* HW communication module */
- HINIC3_MOD_L2NIC = 1, /* L2NIC module */
- HINIC3_MOD_ROCE = 2,
- HINIC3_MOD_PLOG = 3,
- HINIC3_MOD_TOE = 4,
- HINIC3_MOD_FLR = 5,
- HINIC3_MOD_RSVD1 = 6,
- HINIC3_MOD_CFGM = 7, /* Configuration module */
- HINIC3_MOD_CQM = 8,
- HINIC3_MOD_RSVD2 = 9,
- COMM_MOD_FC = 10,
- HINIC3_MOD_OVS = 11,
- HINIC3_MOD_DSW = 12,
- HINIC3_MOD_MIGRATE = 13,
- HINIC3_MOD_HILINK = 14,
- HINIC3_MOD_CRYPT = 15, /* secure crypto module */
- HINIC3_MOD_VIO = 16,
- HINIC3_MOD_IMU = 17,
- HINIC3_MOD_DFT = 18, /* DFT */
- HINIC3_MOD_HW_MAX = 19, /* hardware max module id */
- /* Software module id, for PF/VF and multi-host */
- HINIC3_MOD_SW_FUNC = 20,
- HINIC3_MOD_MAX,
-};
-
-/* func reset的flag ,用于指示清理哪种资源 */
-enum func_reset_flag {
- RES_TYPE_FLUSH_BIT = 0,
- RES_TYPE_MQM,
- RES_TYPE_SMF,
- RES_TYPE_PF_BW_CFG,
-
- RES_TYPE_COMM = 10,
- RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_NIC,
- RES_TYPE_OVS,
- RES_TYPE_VBS,
- RES_TYPE_ROCE,
- RES_TYPE_FC,
- RES_TYPE_TOE,
- RES_TYPE_IPSEC,
- RES_TYPE_MAX,
-};
-
-#define HINIC3_COMM_RES \
- ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
- (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
- (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
-
-#define HINIC3_NIC_RES (1 << RES_TYPE_NIC)
-#define HINIC3_OVS_RES (1 << RES_TYPE_OVS)
-#define HINIC3_VBS_RES (1 << RES_TYPE_VBS)
-#define HINIC3_ROCE_RES (1 << RES_TYPE_ROCE)
-#define HINIC3_FC_RES (1 << RES_TYPE_FC)
-#define HINIC3_TOE_RES (1 << RES_TYPE_TOE)
-#define HINIC3_IPSEC_RES (1 << RES_TYPE_IPSEC)
-
-/* MODE OVS、NIC、UNKNOWN */
-#define HINIC3_WORK_MODE_OVS 0
-#define HINIC3_WORK_MODE_UNKNOWN 1
-#define HINIC3_WORK_MODE_NIC 2
-
-#define DEVICE_TYPE_L2NIC 0
-#define DEVICE_TYPE_NVME 1
-#define DEVICE_TYPE_VIRTIO_NET 2
-#define DEVICE_TYPE_VIRTIO_BLK 3
-#define DEVICE_TYPE_VIRTIO_VSOCK 4
-#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
-#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
-#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
-#define DEVICE_TYPE_VIRTIO_HPC 8
-
-#define IS_STORAGE_DEVICE_TYPE(dev_type) \
- ((dev_type) == DEVICE_TYPE_VIRTIO_BLK || \
- (dev_type) == DEVICE_TYPE_VIRTIO_BLK_TRANSITION || \
- (dev_type) == DEVICE_TYPE_VIRTIO_SCSI_TRANSITION)
-
-/* Common header control information of the COMM message
- * interaction command word between the driver and PF
- */
-struct comm_info_head {
- u8 status;
- u8 version;
- u8 rep_aeq_num;
- u8 rsvd[5];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
deleted file mode 100644
index ae998cf..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_msg_intf.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef COMM_MSG_INTF_H
-#define COMM_MSG_INTF_H
-
-#include "comm_defs.h"
-#include "mgmt_msg_base.h"
-#include "mpu_cmd_base_defs.h"
-#include "mpu_inband_cmd_defs.h"
-
-struct spu_cmd_freq_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: check */
- u8 rsvd[3];
- u32 freq;
-};
-
-struct spu_cmd_power_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: init */
- u8 slave_addr;
- u8 cmd_id;
- u8 size;
- u32 value;
-};
-
-struct spu_cmd_tsensor_operation {
- struct comm_info_head head;
-
- u8 op_code;
- u8 rsvd[3];
- s16 fabric_tsensor_temp_avg;
- s16 fabric_tsensor_temp;
- s16 sys_tsensor_temp_avg;
- s16 sys_tsensor_temp;
-};
-
-enum cfg_msix_operation {
- CFG_MSIX_OPERATION_FREE = 0,
- CFG_MSIX_OPERATION_ALLOC = 1,
-};
-
-struct comm_cmd_ffm_info {
- struct mgmt_msg_head head;
-
- u8 node_id;
- /* error level of the interrupt source */
- u8 err_level;
- /* Classification by interrupt source properties */
- u16 err_type;
- u32 err_csr_addr;
- u32 err_csr_value;
- u32 rsvd1;
-};
-
-struct hinic3_cmd_update_firmware {
- struct mgmt_msg_head msg_head;
-
- struct {
- u32 sl : 1;
- u32 sf : 1;
- u32 flag : 1;
- u32 bit_signed : 1;
- u32 reserved : 12;
- u32 fragment_len : 16;
- } ctl_info;
-
- struct {
- u32 section_crc;
- u32 section_type;
- } section_info;
-
- u32 total_len;
- u32 section_len;
- u32 section_version;
- u32 section_offset;
- u32 data[384];
-};
-
-struct hinic3_cmd_activate_firmware {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-struct hinic3_cmd_switch_config {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
index 76e128e..1562c59 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
@@ -28,6 +28,8 @@
#include "cqm_npu_cmd.h"
#include "cqm_npu_cmd_defs.h"
+#include "vram_common.h"
+
static void cqm_bat_fill_cla_common_gpa(struct tag_cqm_handle *cqm_handle,
struct tag_cqm_cla_table *cla_table,
struct tag_cqm_bat_entry_standerd *bat_entry_standerd)
@@ -367,6 +369,14 @@ static s32 cqm_bat_update_cmd(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
struct tag_cqm_cmdq_bat_update *bat_update_cmd = NULL;
s32 ret = CQM_FAIL;
+ int is_in_kexec;
+
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip updating the cqm_bat to chip during kexec!\n");
+ return CQM_SUCCESS;
+ }
+
bat_update_cmd = (struct tag_cqm_cmdq_bat_update *)(buf_in->buf);
bat_update_cmd->offset = 0;
@@ -644,6 +654,7 @@ void cqm_bat_uninit(struct tag_cqm_handle *cqm_handle)
static s32 cqm_cla_fill_buf(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *cla_base_buf,
struct tag_cqm_buf *cla_sub_buf, u8 gpa_check_enable)
{
+ struct hinic3_hwdev *handle = cqm_handle->ex_handle;
struct hinic3_func_attr *func_attr = NULL;
dma_addr_t *base = NULL;
u64 fake_en = 0;
@@ -655,13 +666,17 @@ static s32 cqm_cla_fill_buf(struct tag_cqm_handle *cqm_handle, struct tag_cqm_bu
/* Apply for space for base_buf */
if (!cla_base_buf->buf_list) {
- if (cqm_buf_alloc(cqm_handle, cla_base_buf, false) == CQM_FAIL)
+ if (cqm_buf_alloc(cqm_handle, cla_base_buf, false) ==
+ CQM_FAIL) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(cla_base_buf));
return CQM_FAIL;
+ }
}
/* Apply for space for sub_buf */
if (!cla_sub_buf->buf_list) {
if (cqm_buf_alloc(cqm_handle, cla_sub_buf, false) == CQM_FAIL) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(cla_sub_buf));
cqm_buf_free(cla_base_buf, cqm_handle);
return CQM_FAIL;
}
@@ -768,8 +783,10 @@ static s32 cqm_cla_xyz_lvl1(struct tag_cqm_handle *cqm_handle,
/* Applying for CLA_Z_BUF Space */
cla_z_buf = &cla_table->cla_z_buf;
cla_z_buf->buf_size = trunk_size;
- cla_z_buf->buf_number = (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
- cla_z_buf->page_number = cla_z_buf->buf_number << cla_table->trunk_order;
+ cla_z_buf->buf_number =
+ (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
+ cla_z_buf->page_number = cla_z_buf->buf_number <<
+ cla_table->trunk_order;
/* All buffer space must be statically allocated. */
if (cla_table->alloc_static) {
@@ -785,6 +802,7 @@ static s32 cqm_cla_xyz_lvl1(struct tag_cqm_handle *cqm_handle,
cla_z_buf->buf_list = vmalloc(cla_z_buf->buf_number *
sizeof(struct tag_cqm_buf_list));
if (!cla_z_buf->buf_list) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_1_z_buf));
cqm_buf_free(cla_y_buf, cqm_handle);
return CQM_FAIL;
}
@@ -840,6 +858,7 @@ static s32 cqm_cla_xyz_lvl2_xyz_apply(struct tag_cqm_handle *cqm_handle,
cla_x_buf->buf_size = trunk_size;
cla_x_buf->buf_number = 1;
cla_x_buf->page_number = cla_x_buf->buf_number << cla_table->trunk_order;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
ret = cqm_buf_alloc(cqm_handle, cla_x_buf, false);
if (ret != CQM_SUCCESS)
return CQM_FAIL;
@@ -869,14 +888,20 @@ static s32 cqm_cla_xyz_vram_name_init(struct tag_cqm_cla_table *cla_table,
cla_x_buf = &cla_table->cla_x_buf;
cla_z_buf = &cla_table->cla_z_buf;
cla_y_buf = &cla_table->cla_y_buf;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_x_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_X);
+ VRAM_NAME_APPLY_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_X);
+ cla_y_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_y_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Y);
+ VRAM_NAME_APPLY_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Y);
+ cla_z_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_z_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Z);
+ VRAM_NAME_APPLY_LEN, "%s%s",
+ cla_table->name, VRAM_CQM_CLA_COORD_Z);
return CQM_SUCCESS;
}
@@ -925,6 +950,7 @@ static s32 cqm_cla_xyz_lvl2(struct tag_cqm_handle *cqm_handle,
cla_z_buf->buf_list = vmalloc(cla_z_buf->buf_number *
sizeof(struct tag_cqm_buf_list));
if (!cla_z_buf->buf_list) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_2_z_buf));
cqm_buf_free(cla_x_buf, cqm_handle);
return CQM_FAIL;
}
@@ -934,6 +960,7 @@ static s32 cqm_cla_xyz_lvl2(struct tag_cqm_handle *cqm_handle,
cla_y_buf->buf_list = vmalloc(cla_y_buf->buf_number *
sizeof(struct tag_cqm_buf_list));
if (!cla_y_buf->buf_list) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_2_y_buf));
cqm_buf_free(cla_z_buf, cqm_handle);
cqm_buf_free(cla_x_buf, cqm_handle);
return CQM_FAIL;
@@ -1188,7 +1215,7 @@ static void cqm_cla_init_entry_extern(struct tag_cqm_handle *cqm_handle,
* exceed 128 x 4 KB. Otherwise, clearing the timer buffer of
* the function is complex.
*/
- cla_table->trunk_order = CQM_4K_PAGE_ORDER;
+ cla_table->trunk_order = CQM_8K_PAGE_ORDER;
cla_table->max_buffer_size = capability->timer_number *
capability->timer_basic_size;
cla_table->obj_size = capability->timer_basic_size;
@@ -1237,7 +1264,7 @@ static s32 cqm_cla_init_entry_condition(struct tag_cqm_handle *cqm_handle, u32 e
memcpy(cla_table_timer, cla_table, sizeof(struct tag_cqm_cla_table));
snprintf(cla_table_timer->name,
- VRAM_NAME_MAX_LEN - 1, "%s%s%01u", cla_table->name,
+ VRAM_NAME_APPLY_LEN, "%s%s%01u", cla_table->name,
VRAM_CQM_CLA_SMF_BASE, i);
if (cqm_cla_xyz(cqm_handle, cla_table_timer) ==
@@ -1268,7 +1295,7 @@ static s32 cqm_cla_init_entry(struct tag_cqm_handle *cqm_handle,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
cla_table->type = bat_table->bat_entry_type[i];
- snprintf(cla_table->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(cla_table->name, VRAM_NAME_APPLY_LEN,
"%s%s%s%02u", cqm_handle->name, VRAM_CQM_CLA_BASE,
VRAM_CQM_CLA_TYPE_BASE, cla_table->type);
@@ -1485,11 +1512,11 @@ static s32 cqm_cla_update(struct tag_cqm_handle *cqm_handle,
spu_en = 0;
pa = ((buf_node_parent->pa + (child_index * sizeof(dma_addr_t))) |
- (u32)spu_en);
+ spu_en);
cmd.gpa_h = CQM_ADDR_HI(pa);
cmd.gpa_l = CQM_ADDR_LW(pa);
- pa = (buf_node_child->pa | (u32)spu_en);
+ pa = (buf_node_child->pa | spu_en);
cmd.value_h = CQM_ADDR_HI(pa);
cmd.value_l = CQM_ADDR_LW(pa);
@@ -1980,7 +2007,7 @@ struct tag_cqm_cla_table *cqm_cla_table_get(struct tag_cqm_bat_table *bat_table,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
- if (cla_table && entry_type == cla_table->type)
+ if ((cla_table != NULL) && (entry_type == cla_table->type))
return cla_table;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
index dd0766e..a51c1dc 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
@@ -9,6 +9,7 @@
#include "cqm_bitmap_table.h"
#include "cqm_object.h"
+#include "vram_common.h"
/* When the connection check is enabled, the maximum number of connections
* supported by the chip is 1M - 63, which cannot reach 1M
@@ -19,6 +20,7 @@
#define CLA_TABLE_PAGE_ORDER 0
#define CQM_4K_PAGE_ORDER 0
#define CQM_4K_PAGE_SIZE 4096
+#define CQM_8K_PAGE_ORDER 1
#define CQM_BAT_ENTRY_MAX 16
#define CQM_BAT_ENTRY_SIZE 16
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
index f4844d5..86b268c 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
@@ -254,8 +254,10 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
}
pages = vmalloc(sizeof(struct page *) * buf->page_number);
- if (!pages)
+ if (!pages) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(pages));
return CQM_FAIL;
+ }
for (i = 0; i < buf->buf_number; i++) {
for (j = 0; j < ((u32)1 << order); j++)
@@ -273,6 +275,11 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
return CQM_SUCCESS;
}
+static bool check_use_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ return buf->buf_info.use_vram ? true : false;
+}
+
static bool check_use_non_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
{
return buf->buf_info.use_vram ? false : true;
@@ -294,11 +301,48 @@ static bool check_for_nouse_node_alloc(struct hinic3_hwdev *handle, struct tag_c
return false;
}
+static s32 cqm_buf_vram_kalloc(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ void *vaddr = NULL;
+ int i;
+
+ vaddr = hi_vram_kalloc(buf->buf_info.buf_vram_name, (u64)buf->buf_size * buf->buf_number);
+ if (!vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
+ return CQM_FAIL;
+ }
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = (void *)((char *)vaddr + i * (u64)buf->buf_size);
+
+ return CQM_SUCCESS;
+}
+
+static void cqm_buf_vram_free(struct tag_cqm_buf *buf)
+{
+ s32 i;
+
+ if (buf->buf_list == NULL) {
+ return;
+ }
+
+ if (buf->buf_list[0].va)
+ hi_vram_kfree(buf->buf_list[0].va, buf->buf_info.buf_vram_name,
+ (u64)buf->buf_size * buf->buf_number);
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = NULL;
+}
+
static void cqm_buf_free_page_common(struct tag_cqm_buf *buf)
{
u32 order;
s32 i;
+ if (buf->buf_list == NULL) {
+ return;
+ }
+
order = (u32)get_order(buf->buf_size);
for (i = 0; i < (s32)buf->buf_number; i++) {
@@ -320,8 +364,10 @@ static s32 cqm_buf_use_node_alloc_page(struct hinic3_hwdev *handle, struct tag_c
node = dev_to_node(handle->dev_hdl);
for (i = 0; i < (s32)buf->buf_number; i++) {
newpage = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, order);
- if (!newpage)
+ if (!newpage) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
va = (void *)page_address(newpage);
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
@@ -349,8 +395,10 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
for (i = 0; i < (s32)buf->buf_number; i++) {
va = (void *)ossl_get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
- if (!va)
+ if (!va) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
* value must be 0.
@@ -367,21 +415,21 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
return CQM_SUCCESS;
}
-#define MALLOC_FUNCS_COUNT 2
-#define FREE_FUNCS_COUNT 1
-static const struct malloc_memory g_malloc_funcs[MALLOC_FUNCS_COUNT] = {
+static const struct malloc_memory g_malloc_funcs[] = {
+ {check_use_vram, cqm_buf_vram_kalloc},
{check_for_use_node_alloc, cqm_buf_use_node_alloc_page},
{check_for_nouse_node_alloc, cqm_buf_unused_node_alloc_page}
};
-static const struct free_memory g_free_funcs[FREE_FUNCS_COUNT] = {
+static const struct free_memory g_free_funcs[] = {
+ {check_use_vram, cqm_buf_vram_free},
{check_use_non_vram, cqm_buf_free_page_common}
};
static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *buf)
{
struct hinic3_hwdev *handle = cqm_handle->ex_handle;
- u32 malloc_funcs_num = MALLOC_FUNCS_COUNT;
+ u32 malloc_funcs_num = ARRAY_SIZE(g_malloc_funcs);
u32 i;
for (i = 0; i < malloc_funcs_num; i++) {
@@ -398,7 +446,7 @@ static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
static void cqm_buf_free_page(struct tag_cqm_buf *buf)
{
- u32 free_funcs_num = FREE_FUNCS_COUNT;
+ u32 free_funcs_num = ARRAY_SIZE(g_free_funcs);
u32 i;
for (i = 0; i < free_funcs_num; i++) {
@@ -447,8 +495,11 @@ static s32 cqm_buf_get_secure_mem_pages(struct tag_cqm_handle *cqm_handle, struc
cqm_get_secure_mem_pages(handle,
(u32)get_order(buf->buf_size),
&buf->buf_list[i].pa);
- if (!buf->buf_list[i].va)
+ if (!buf->buf_list[i].va) {
+ cqm_err(handle->dev_hdl,
+ CQM_ALLOC_FAIL(cqm_get_secure_mem_pages));
break;
+ }
}
if (i != buf->buf_number) {
@@ -780,7 +831,10 @@ static s32 cqm_single_bitmap_init(struct tag_cqm_bitmap *bitmap)
*/
bit_number = (ALIGN(bitmap->max_num, CQM_NUM_BIT_BYTE) >>
CQM_BYTE_BIT_SHIFT);
- bitmap->table = vmalloc(bit_number);
+ if (bitmap->bitmap_info.use_vram != 0)
+ bitmap->table = hi_vram_kalloc(bitmap->bitmap_info.buf_vram_name, bit_number);
+ else
+ bitmap->table = vmalloc(bit_number);
if (!bitmap->table)
return CQM_FAIL;
memset(bitmap->table, 0, bit_number);
@@ -859,7 +913,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
}
bitmap = &cla_table->bitmap;
- snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_APPLY_LEN,
"%s%s%02d", cla_table->name,
VRAM_CQM_BITMAP_BASE, cla_table->type);
@@ -869,6 +923,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
bitmap->reserved_top = capability->qpc_reserved;
bitmap->reserved_back = capability->qpc_reserved_back;
bitmap->last = capability->qpc_reserved;
+ bitmap->bitmap_info.use_vram = get_use_vram_flag();
cqm_info(handle->dev_hdl,
"Bitmap init: cla_table_type=%u, max_num=0x%x\n",
cla_table->type, bitmap->max_num);
@@ -948,7 +1003,12 @@ void cqm_bitmap_uninit(struct tag_cqm_handle *cqm_handle)
if (cla_table->type != CQM_BAT_ENTRY_T_INVALID &&
bitmap->table) {
spin_lock_deinit(&bitmap->lock);
- vfree(bitmap->table);
+ if (bitmap->bitmap_info.use_vram != 0)
+ hi_vram_kfree(bitmap->table, bitmap->bitmap_info.buf_vram_name,
+ ALIGN(bitmap->max_num, CQM_NUM_BIT_BYTE) >>
+ CQM_BYTE_BIT_SHIFT);
+ else
+ vfree(bitmap->table);
bitmap->table = NULL;
}
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
index 7febf76..06b8661 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
@@ -9,6 +9,7 @@
#include <linux/spinlock.h>
#include "cqm_object.h"
+#include "vram_common.h"
struct tag_cqm_bitmap {
ulong *table;
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c
index cf7df37..3d38edc 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c
@@ -15,7 +15,6 @@
#include "cqm_bitmap_table.h"
#include "cqm_bat_cla.h"
#include "cqm_main.h"
-#include "cqm_cmd.h"
/**
* cqm_cmd_alloc - Apply for a cmd buffer. The buffer size is fixed to 2 KB,
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
index 9a13ae0..db65c8b 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
@@ -196,6 +196,12 @@ void *cqm_get_db_addr(void *ex_handle, u32 service_type)
pr_err("[CQM]%s: ex_handle is null\n", __func__);
return NULL;
}
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return NULL;
+ }
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -218,6 +224,17 @@ s32 cqm_ring_hardware_db(void *ex_handle, u32 service_type, u8 db_count, u64 db)
struct tag_cqm_service *service = NULL;
struct hinic3_hwdev *handle = NULL;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -278,6 +295,17 @@ s32 cqm_ring_direct_wqe_db(void *ex_handle, u32 service_type, u8 db_count,
u64 *tmp = (u64 *)direct_wqe;
int i;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
index 19a8b56..0e8a579 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
@@ -23,6 +23,8 @@
#include "cqm_memsec.h"
#include "cqm_main.h"
+#include "vram_common.h"
+
static unsigned char roce_qpc_rsv_mode = CQM_QPC_ROCE_NORMAL;
module_param(roce_qpc_rsv_mode, byte, 0644);
MODULE_PARM_DESC(roce_qpc_rsv_mode,
@@ -98,10 +100,17 @@ static s32 cqm_set_timer_enable(void *ex_handle)
{
struct hinic3_hwdev *handle = (struct hinic3_hwdev *)ex_handle;
struct tag_cqm_handle *cqm_handle = NULL;
+ int is_in_kexec;
if (!ex_handle)
return CQM_FAIL;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip starting cqm timer during kexec\n");
+ return CQM_SUCCESS;
+ }
+
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
if (cqm_handle->func_capability.fake_func_type == CQM_FAKE_FUNC_PARENT &&
cqm_set_fake_vf_timer(cqm_handle) != CQM_SUCCESS)
@@ -456,7 +465,7 @@ static void cqm_service_capability_init_roce(struct tag_cqm_handle *cqm_handle,
cqm_info(handle->dev_hdl, "Cap init: roce qpc 0x%x, scqc 0x%x, srqc 0x%x, drc_qp 0x%x\n",
roce_own_cap->max_qps, roce_own_cap->max_cqs,
roce_own_cap->max_srqs, roce_own_cap->max_drc_qps);
- cqm_info(handle->dev_hdl, "Cap init: type 0x%x, scenes:0x%x, qpc_rsv:0x%x, srv_bmp:0x%x\n",
+ cqm_info(handle->dev_hdl, "Cap init: board_type 0x%x, scenes_id:0x%x, qpc_rsv_mode:0x%x, srv_bmp:0x%x\n",
board_info->board_type, board_info->scenes_id,
roce_qpc_rsv_mode, board_info->service_en_bitmap);
@@ -610,7 +619,7 @@ static void cqm_service_capability_init_ipsec(struct tag_cqm_handle *cqm_handle,
func_cap->scqc_basic_size);
func_cap->scqc_alloc_static = true;
cqm_info(handle->dev_hdl, "Cap init: ipsec is valid\n");
- cqm_info(handle->dev_hdl, "Cap init: ipsec 0x%x, childc %d, scqc 0x%x, scqc_bsize %d\n",
+ cqm_info(handle->dev_hdl, "Cap init: ipsec childc_num 0x%x, childc_bsize %d, scqc_num 0x%x, scqc_bsize %d\n",
ipsec_srvcap->max_sactxs, func_cap->childc_basic_size,
ipsec_srvcap->max_cqs, func_cap->scqc_basic_size);
}
@@ -812,7 +821,7 @@ static int cqm_capability_init_bloomfilter(struct hinic3_hwdev *handle)
func_cap->bloomfilter_addr = service_capability->bfilter_start_addr;
if (func_cap->bloomfilter_length != 0 &&
!cqm_check_align(func_cap->bloomfilter_length)) {
- cqm_err(handle->dev_hdl, "Cap bloomfilter len %u is not the power of 2\n",
+ cqm_err(handle->dev_hdl, "Cap init: bloomfilter_length %u is not the power of 2\n",
func_cap->bloomfilter_length);
return CQM_FAIL;
@@ -883,7 +892,7 @@ static int cqm_capability_init_timer(struct hinic3_hwdev *handle)
func_cap->timer_vf_num = service_capability->timer_vf_num;
func_cap->timer_vf_id_start = service_capability->timer_vf_id_start;
cqm_info(handle->dev_hdl,
- "timer init: pf_num 0x%x, pf_start 0x%x, vf_num 0x%x, vf_start 0x%x\n",
+ "host timer init: timer_pf_num 0x%x, timer_pf_id_start 0x%x, timer_vf_num 0x%x, timer_vf_id_start 0x%x\n",
func_cap->timer_pf_num, func_cap->timer_pf_id_start,
func_cap->timer_vf_num, func_cap->timer_vf_id_start);
@@ -891,7 +900,7 @@ static int cqm_capability_init_timer(struct hinic3_hwdev *handle)
if (IS_SLAVE_HOST(handle)) {
total_timer_num *= CQM_TIMER_NUM_MULTI;
cqm_info(handle->dev_hdl,
- "timer init: need double tw resources, total_timer_num=0x%x\n",
+ "host timer init: need double tw resources, total_timer_num=0x%x\n",
total_timer_num);
}
}
@@ -1059,8 +1068,10 @@ static s32 cqm_fake_init(struct tag_cqm_handle *cqm_handle)
for (i = 0; i < (u32)child_func_number; i++) {
fake_cqm_handle = kmalloc(sizeof(*fake_cqm_handle), GFP_KERNEL | __GFP_ZERO);
- if (!fake_cqm_handle)
+ if (!fake_cqm_handle) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(fake_cqm_handle));
goto err;
+ }
/* Copy the attributes of the parent CQM handle to the child CQM
* handle and modify the values of function.
@@ -1129,7 +1140,7 @@ static s32 cqm_fake_mem_init(struct tag_cqm_handle *cqm_handle)
for (i = 0; i < (u32)child_func_number; i++) {
fake_cqm_handle = cqm_handle->fake_cqm_handle[i];
- snprintf(fake_cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(fake_cqm_handle->name, VRAM_NAME_APPLY_LEN,
"%s%s%02u", cqm_handle->name, VRAM_CQM_FAKE_MEM_BASE, i);
if (cqm_bat_init(fake_cqm_handle) != CQM_SUCCESS) {
@@ -1174,7 +1185,7 @@ s32 cqm_mem_init(void *ex_handle)
struct tag_cqm_handle *cqm_handle = NULL;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
- snprintf(cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(cqm_handle->name, VRAM_NAME_APPLY_LEN,
"%s%02u", VRAM_CQM_GLB_FUNC_BASE, hinic3_global_func_id(handle));
if (cqm_fake_init(cqm_handle) != CQM_SUCCESS) {
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
index 4f87bd1..8d1e481 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
@@ -362,6 +362,7 @@ s32 cqm_fake_vf_num_set(void *ex_handle, u16 fake_vf_num_cfg);
#define CQM_LOG_ID 0
#define CQM_PTR_NULL(x) "%s: " #x " is null\n", __func__
+#define CQM_ALLOC_FAIL(x) "%s: " #x " alloc fail\n", __func__
#define CQM_MAP_FAIL(x) "%s: " #x " map fail\n", __func__
#define CQM_FUNCTION_FAIL(x) "%s: " #x " return failure\n", __func__
#define CQM_WRONG_VALUE(x) "%s: " #x " %u is wrong\n", __func__, (u32)(x)
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
index 4888b0a..d3def81 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
@@ -21,6 +21,7 @@
#include "cqm_bloomfilter.h"
#include "cqm_db.h"
#include "cqm_main.h"
+#include "vram_common.h"
#include "vmsec_mpu_common.h"
#include "cqm_memsec.h"
@@ -34,6 +35,8 @@
#define STD_INPUT_ONE_PARA 1
#define STD_INPUT_TWO_PARA 2
#define MR_KEY_2_INDEX_SHIFT 8
+#define IS_ADDR_IN_MEMSEC(va, len, start, end) \
+ ((va) >= (start) && (va) + (len) < (end))
static int memsec_proc_show(struct seq_file *seq, void *offset);
static int memsec_proc_open(struct inode *inode, struct file *file);
@@ -46,15 +49,24 @@ static int hinic3_secure_mem_proc_node_add(void *hwdev);
static ssize_t memsec_proc_write(struct file *file, const char __user *data, size_t len,
loff_t *pff);
-static struct proc_dir_entry *g_hinic3_memsec_proc_ent; /* proc dir */
+static struct proc_dir_entry *g_hinic3_memsec_proc_ent = NULL; /* proc dir */
static atomic_t g_memsec_proc_refcnt = ATOMIC_INIT(0);
+#if KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE
+static const struct file_operations memsec_proc_fops = {
+ .open = memsec_proc_open,
+ .read = seq_read,
+ .write = memsec_proc_write,
+ .release = memsec_proc_release,
+};
+#else
static const struct proc_ops memsec_proc_fops = {
.proc_open = memsec_proc_open,
.proc_read = seq_read,
.proc_write = memsec_proc_write,
.proc_release = memsec_proc_release,
};
+#endif
bool cqm_need_secure_mem(void *hwdev)
{
@@ -63,6 +75,9 @@ bool cqm_need_secure_mem(void *hwdev)
struct hinic3_hwdev *handle = (struct hinic3_hwdev *)hwdev;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (cqm_handle == NULL) {
+ return false;
+ }
info = &cqm_handle->secure_mem;
return ((info->need_secure_mem) && hinic3_is_guest_vmsec_enable(hwdev));
}
@@ -275,9 +290,10 @@ static int test_query_context(struct hinic3_hwdev *handle, char *data, size_t le
case CQM_OBJECT_SERVICE_CTX:
case CQM_OBJECT_MPT:
qpc_mpt = (struct tag_cqm_qpc_mpt *)cqm_obj;
- if (qpc_mpt->vaddr >= (u8 *)info->va_base &&
- (qpc_mpt->vaddr + cqm_obj->object_size) < (u8 *)info->va_end)
- in_secmem = true;
+ in_secmem = IS_ADDR_IN_MEMSEC(qpc_mpt->vaddr,
+ cqm_obj->object_size,
+ (u8 *)info->va_base,
+ (u8 *)info->va_end);
cqm_info(handle->dev_hdl,
"[memsec_dfx]Query %s:0x%x, va=%p %sin secure mem\n",
query_type == CQM_OBJECT_MPT ? "MPT, mpt_index" : "QPC, qpn",
@@ -286,9 +302,10 @@ static int test_query_context(struct hinic3_hwdev *handle, char *data, size_t le
case CQM_OBJECT_RDMA_SRQ:
case CQM_OBJECT_RDMA_SCQ:
cqm_queue = (struct tag_cqm_queue *)cqm_obj;
- if (cqm_queue->q_ctx_vaddr >= (u8 *)info->va_base &&
- (cqm_queue->q_ctx_vaddr + cqm_obj->object_size) < (u8 *)info->va_end)
- in_secmem = true;
+ in_secmem = IS_ADDR_IN_MEMSEC(cqm_queue->q_ctx_vaddr,
+ cqm_obj->object_size,
+ (u8 *)info->va_base,
+ (u8 *)info->va_end);
cqm_info(handle->dev_hdl,
"[memsec_dfx]Query %s:0x%x, va=%p %sin secure mem\n",
query_type == CQM_OBJECT_RDMA_SRQ ? "SRQC, srqn " : "SCQC, scqn",
@@ -378,7 +395,7 @@ static int hinic3_secure_mem_proc_node_remove(void *hwdev)
atomic_dec(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
@@ -401,7 +418,7 @@ static int hinic3_secure_mem_proc_node_add(void *hwdev)
atomic_inc(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
/* 0400 Read by owner */
@@ -653,7 +670,7 @@ void cqm_free_secure_mem_pages(struct hinic3_hwdev *handle, void *va, u32 order)
return;
}
- if (va < info->va_base || va > (info->va_end - PAGE_SIZE) ||
+ if (va < info->va_base || (va > (info->va_end - PAGE_SIZE)) ||
!PAGE_ALIGNED((va - info->va_base)))
cqm_err(handle->dev_hdl, "%s va wrong value\n", __func__);
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c
index 7d1bd35..86359c0 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c
@@ -180,8 +180,10 @@ struct tag_cqm_queue *cqm_object_recv_queue_create(void *ex_handle, u32 service_
rq_qinfo->common.q_header_vaddr =
cqm_kmalloc_align(sizeof(struct tag_cqm_queue_header),
GFP_KERNEL | __GFP_ZERO, CQM_QHEAD_ALIGN_ORDER);
- if (!rq_qinfo->common.q_header_vaddr)
+ if (!rq_qinfo->common.q_header_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_header_vaddr));
goto err1;
+ }
rq_qinfo->common.q_header_paddr =
pci_map_single(cqm_handle->dev, rq_qinfo->common.q_header_vaddr,
@@ -484,7 +486,8 @@ static bool cqm_object_nonrdma_queue_param_check(struct hinic3_hwdev *handle, u3
struct tag_cqm_handle *cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
/* exception of service registrion check */
- if (!cqm_handle->service[service_type].has_register) {
+ if (service_type >= CQM_SERVICE_T_MAX ||
+ !cqm_handle->service[service_type].has_register) {
cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(service_type));
return false;
}
@@ -1487,4 +1490,4 @@ void cqm_srq_used_rq_container_delete(struct tag_cqm_object *object, u8 *contain
}
kfree((void *)addr);
}
-EXPORT_SYMBOL(cqm_srq_used_rq_container_delete);
+EXPORT_SYMBOL(cqm_srq_used_rq_container_delete);
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c
index 92c19c4..1007b44 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c
@@ -127,8 +127,10 @@ s32 cqm_container_create(struct tag_cqm_object *object, u8 **container_addr, boo
* of the Container.
*/
new_container = kmalloc(qinfo->container_size, GFP_ATOMIC | __GFP_ZERO);
- if (!new_container)
+ if (!new_container) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(new_container));
return CQM_FAIL;
+ }
/* Container PCI mapping */
new_container_pa = pci_map_single(cqm_handle->dev, new_container,
@@ -299,8 +301,10 @@ s32 cqm_share_recv_queue_create(struct tag_cqm_object *object)
/* apply for buffer for SRQC */
common->q_ctx_vaddr = kmalloc(qinfo->q_ctx_size,
GFP_KERNEL | __GFP_ZERO);
- if (!common->q_ctx_vaddr)
+ if (!common->q_ctx_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_ctx_vaddr));
goto err2;
+ }
return CQM_SUCCESS;
err2:
@@ -808,8 +812,10 @@ static s32 cqm_nonrdma_queue_ctx_create(struct tag_cqm_object *object)
common->q_ctx_vaddr = cqm_kmalloc_align(qinfo->q_ctx_size,
GFP_KERNEL | __GFP_ZERO,
(u16)shift);
- if (!common->q_ctx_vaddr)
+ if (!common->q_ctx_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_ctx_vaddr));
return CQM_FAIL;
+ }
common->q_ctx_paddr = pci_map_single(cqm_handle->dev, common->q_ctx_vaddr,
qinfo->q_ctx_size, PCI_DMA_BIDIRECTIONAL);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h b/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
deleted file mode 100644
index ad732c3..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2019-2022. All rights reserved.
- * File Name : hinic3_comm_cmd.h
- * Version : Initial Draft
- * Created : 2019/4/25
- * Last Modified :
- * Description : COMM Commands between Driver and MPU
- * Function List :
- */
-
-#ifndef HINIC3_COMMON_CMD_H
-#define HINIC3_COMMON_CMD_H
-
-/* COMM Commands between Driver to MPU */
-enum hinic3_mgmt_cmd {
- /* flr及资源清理相关命令 */
- COMM_MGMT_CMD_FUNC_RESET = 0,
- COMM_MGMT_CMD_FEATURE_NEGO,
- COMM_MGMT_CMD_FLUSH_DOORBELL,
- COMM_MGMT_CMD_START_FLUSH,
- COMM_MGMT_CMD_SET_FUNC_FLR,
- COMM_MGMT_CMD_GET_GLOBAL_ATTR,
- COMM_MGMT_CMD_SET_PPF_FLR_TYPE,
- COMM_MGMT_CMD_SET_FUNC_SVC_USED_STATE,
-
- /* 分配msi-x中断资源 */
- COMM_MGMT_CMD_CFG_MSIX_NUM = 10,
-
- /* 驱动相关配置命令 */
- COMM_MGMT_CMD_SET_CMDQ_CTXT = 20,
- COMM_MGMT_CMD_SET_VAT,
- COMM_MGMT_CMD_CFG_PAGESIZE,
- COMM_MGMT_CMD_CFG_MSIX_CTRL_REG,
- COMM_MGMT_CMD_SET_CEQ_CTRL_REG,
- COMM_MGMT_CMD_SET_DMA_ATTR,
-
- /* INFRA配置相关命令字 */
- COMM_MGMT_CMD_GET_MQM_FIX_INFO = 40,
- COMM_MGMT_CMD_SET_MQM_CFG_INFO,
- COMM_MGMT_CMD_SET_MQM_SRCH_GPA,
- COMM_MGMT_CMD_SET_PPF_TMR,
- COMM_MGMT_CMD_SET_PPF_HT_GPA,
- COMM_MGMT_CMD_SET_FUNC_TMR_BITMAT,
- COMM_MGMT_CMD_SET_MBX_CRDT,
- COMM_MGMT_CMD_CFG_TEMPLATE,
- COMM_MGMT_CMD_SET_MQM_LIMIT,
-
- /* 信息获取相关命令字 */
- COMM_MGMT_CMD_GET_FW_VERSION = 60,
- COMM_MGMT_CMD_GET_BOARD_INFO,
- COMM_MGMT_CMD_SYNC_TIME,
- COMM_MGMT_CMD_GET_HW_PF_INFOS,
- COMM_MGMT_CMD_SEND_BDF_INFO,
- COMM_MGMT_CMD_GET_VIRTIO_BDF_INFO,
- COMM_MGMT_CMD_GET_SML_TABLE_INFO,
- COMM_MGMT_CMD_GET_SDI_INFO,
-
- /* 升级相关命令字 */
- COMM_MGMT_CMD_UPDATE_FW = 80,
- COMM_MGMT_CMD_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_DONE_NOTICE,
- COMM_MGMT_CMD_SWITCH_CFG,
- COMM_MGMT_CMD_CHECK_FLASH,
- COMM_MGMT_CMD_CHECK_FLASH_RW,
- COMM_MGMT_CMD_RESOURCE_CFG,
- COMM_MGMT_CMD_UPDATE_BIOS, /* TODO: merge to COMM_MGMT_CMD_UPDATE_FW */
- COMM_MGMT_CMD_MPU_GIT_CODE,
-
- /* chip reset相关 */
- COMM_MGMT_CMD_FAULT_REPORT = 100,
- COMM_MGMT_CMD_WATCHDOG_INFO,
- COMM_MGMT_CMD_MGMT_RESET,
- COMM_MGMT_CMD_FFM_SET, /* TODO: check if needed */
-
- /* chip info/log 相关 */
- COMM_MGMT_CMD_GET_LOG = 120,
- COMM_MGMT_CMD_TEMP_OP,
- COMM_MGMT_CMD_EN_AUTO_RST_CHIP,
- COMM_MGMT_CMD_CFG_REG,
- COMM_MGMT_CMD_GET_CHIP_ID,
- COMM_MGMT_CMD_SYSINFO_DFX,
- COMM_MGMT_CMD_PCIE_DFX_NTC,
- COMM_MGMT_CMD_DICT_LOG_STATUS, /* LOG STATUS 127 */
- COMM_MGMT_CMD_MSIX_INFO,
- COMM_MGMT_CMD_CHANNEL_DETECT,
- COMM_MGMT_CMD_DICT_COUNTER_STATUS,
-
- /* switch workmode 相关 */
- COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140,
- COMM_MGMT_CMD_SWITCH_WORKMODE,
-
- /* mpu 相关 */
- COMM_MGMT_CMD_MIGRATE_DFX_HPA = 150,
- COMM_MGMT_CMD_BDF_INFO,
- COMM_MGMT_CMD_NCSI_CFG_INFO_GET_PROC,
-
- /* rsvd0 section */
- COMM_MGMT_CMD_SECTION_RSVD_0 = 160,
-
- /* rsvd1 section */
- COMM_MGMT_CMD_SECTION_RSVD_1 = 170,
-
- /* rsvd2 section */
- COMM_MGMT_CMD_SECTION_RSVD_2 = 180,
-
- /* rsvd3 section */
- COMM_MGMT_CMD_SECTION_RSVD_3 = 190,
-
- /* TODO: move to DFT mode */
- COMM_MGMT_CMD_GET_DIE_ID = 200,
- COMM_MGMT_CMD_GET_EFUSE_TEST,
- COMM_MGMT_CMD_EFUSE_INFO_CFG,
- COMM_MGMT_CMD_GPIO_CTL,
- COMM_MGMT_CMD_HI30_SERLOOP_START, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_SERLOOP_STOP, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_SET_FLAG, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_GET_RESULT, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_ECC_TEST,
- COMM_MGMT_CMD_FUNC_BIST_TEST, /* 209 */
-
- COMM_MGMT_CMD_VPD_SET = 210,
- COMM_MGMT_CMD_VPD_GET,
-
- COMM_MGMT_CMD_ERASE_FLASH,
- COMM_MGMT_CMD_QUERY_FW_INFO,
- COMM_MGMT_CMD_GET_CFG_INFO,
- COMM_MGMT_CMD_GET_UART_LOG,
- COMM_MGMT_CMD_SET_UART_CMD,
- COMM_MGMT_CMD_SPI_TEST,
-
- /* TODO: ALL reg read/write merge to COMM_MGMT_CMD_CFG_REG */
- COMM_MGMT_CMD_UP_REG_GET,
- COMM_MGMT_CMD_UP_REG_SET, /* 219 */
-
- COMM_MGMT_CMD_REG_READ = 220,
- COMM_MGMT_CMD_REG_WRITE,
- COMM_MGMT_CMD_MAG_REG_WRITE,
- COMM_MGMT_CMD_ANLT_REG_WRITE,
-
- COMM_MGMT_CMD_HEART_EVENT, /* TODO: delete */
- COMM_MGMT_CMD_NCSI_OEM_GET_DRV_INFO, /* TODO: delete */
- COMM_MGMT_CMD_LASTWORD_GET,
- COMM_MGMT_CMD_READ_BIN_DATA, /* TODO: delete */
- /* COMM_MGMT_CMD_WWPN_GET, TODO: move to FC? */
- /* COMM_MGMT_CMD_WWPN_SET, TODO: move to FC? */ /* 229 */
-
- /* TODO: check if needed */
- COMM_MGMT_CMD_SET_VIRTIO_DEV = 230,
- COMM_MGMT_CMD_SET_MAC,
- /* MPU patch cmd */
- COMM_MGMT_CMD_LOAD_PATCH,
- COMM_MGMT_CMD_REMOVE_PATCH,
- COMM_MGMT_CMD_PATCH_ACTIVE,
- COMM_MGMT_CMD_PATCH_DEACTIVE,
- COMM_MGMT_CMD_PATCH_SRAM_OPTIMIZE,
- /* container host process */
- COMM_MGMT_CMD_CONTAINER_HOST_PROC,
- /* nsci counter */
- COMM_MGMT_CMD_NCSI_COUNTER_PROC,
- COMM_MGMT_CMD_CHANNEL_STATUS_CHECK, /* 239 */
-
- /* hot patch rsvd cmd */
- COMM_MGMT_CMD_RSVD_0 = 240,
- COMM_MGMT_CMD_RSVD_1,
- COMM_MGMT_CMD_RSVD_2,
- COMM_MGMT_CMD_RSVD_3,
- COMM_MGMT_CMD_RSVD_4,
- /* 无效字段,版本收编删除,编译使用 */
- COMM_MGMT_CMD_SEND_API_ACK_BY_UP,
-
- /* 注:添加cmd,不能修改已有命令字的值,请在前方rsvd
- * section中添加;原则上所有分支cmd表完全一致
- */
- COMM_MGMT_CMD_MAX = 255,
-};
-
-/* CmdQ Common subtype */
-enum comm_cmdq_cmd {
- COMM_CMD_UCODE_ARM_BIT_SET = 2,
- COMM_CMD_SEND_NPU_DFT_CMD,
-};
-
-#endif /* HINIC3_COMMON_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
deleted file mode 100644
index 9ce908e..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_COMMON_H
-#define HINIC3_COMMON_H
-
-#include <linux/types.h>
-
-struct hinic3_dma_addr_align {
- u32 real_size;
-
- void *ori_vaddr;
- dma_addr_t ori_paddr;
-
- void *align_vaddr;
- dma_addr_t align_paddr;
-};
-
-enum hinic3_wait_return {
- WAIT_PROCESS_CPL = 0,
- WAIT_PROCESS_WAITING = 1,
- WAIT_PROCESS_ERR = 2,
-};
-
-struct hinic3_sge {
- u32 hi_addr;
- u32 lo_addr;
- u32 len;
-};
-
-#ifdef static
-#undef static
-#define LLT_STATIC_DEF_SAVED
-#endif
-
-/* *
- * hinic_cpu_to_be32 - convert data to big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert, must be Multiple of 4B
- */
-static inline void hinic3_cpu_to_be32(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = cpu_to_be32(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_cpu_to_be32 - convert data from big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert
- */
-static inline void hinic3_be32_to_cpu(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = be32_to_cpu(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_set_sge - set dma area in scatter gather entry
- * @sge: scatter gather entry
- * @addr: dma address
- * @len: length of relevant data in the dma address
- */
-static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
- int len)
-{
- sge->hi_addr = upper_32_bits(addr);
- sge->lo_addr = lower_32_bits(addr);
- sge->len = len;
-}
-
-#define hinic3_hw_be32(val) (val)
-#define hinic3_hw_cpu32(val) (val)
-#define hinic3_hw_cpu16(val) (val)
-
-static inline void hinic3_hw_be32_len(void *data, int len)
-{
-}
-
-static inline void hinic3_hw_cpu32_len(void *data, int len)
-{
-}
-
-int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
- unsigned int flag,
- struct hinic3_dma_addr_align *mem_align);
-
-void hinic3_dma_free_coherent_align(void *dev_hdl,
- struct hinic3_dma_addr_align *mem_align);
-
-typedef enum hinic3_wait_return (*wait_cpl_handler)(void *priv_data);
-
-int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
- u32 wait_total_ms, u32 wait_once_us);
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
index f269691..7979244 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
@@ -8,7 +8,7 @@
#include "mpu_cmd_base_defs.h"
-#define HINIC3_DRV_VERSION "15.17.1.1"
+#define HINIC3_DRV_VERSION "17.7.8.1"
#define HINIC3_DRV_DESC "Intelligent Network Interface Card Driver"
#define HIUDK_DRV_DESC "Intelligent Network Unified Driver"
@@ -45,6 +45,8 @@ enum hinic3_service_type {
SERVICE_T_CUSTOM,
SERVICE_T_VROCE,
SERVICE_T_CRYPT,
+ SERVICE_T_VSOCK,
+ SERVICE_T_BIFUR,
SERVICE_T_MAX,
/* Only used for interruption resource management,
@@ -63,6 +65,9 @@ struct nic_service_cap {
u16 max_sqs;
u16 max_rqs;
u16 default_num_queues;
+ u16 outband_vlan_cfg_en;
+ u8 lro_enable;
+ u8 rsvd1[3];
};
struct ppa_service_cap {
@@ -76,6 +81,10 @@ struct ppa_service_cap {
u16 rsvd1;
};
+struct bifur_service_cap {
+ u8 rsvd;
+};
+
struct vbs_service_cap {
u16 vbs_max_volq;
u8 vbs_main_pf_enable;
@@ -785,6 +794,15 @@ bool hinic3_support_toe(void *hwdev, struct toe_service_cap *cap);
*/
bool hinic3_support_ppa(void *hwdev, struct ppa_service_cap *cap);
+/* *
+ * @brief hinic3_support_bifur - function support bifur
+ * @param hwdev: device pointer to hwdev
+ * @param cap: bifur service capbility
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+bool hinic3_support_bifur(void *hwdev, struct bifur_service_cap *cap);
+
/* *
* @brief hinic3_support_migr - function support migrate
* @param hwdev: device pointer to hwdev
@@ -895,6 +913,13 @@ int hinic3_get_mgmt_version(void *hwdev, u8 *mgmt_ver, u8 version_size,
int hinic3_get_fw_version(void *hwdev, struct hinic3_fw_version *fw_ver,
u16 channel);
+/* *
+ * @brief hinic3_get_bond_create_mode - get bond create mode
+ * @param hwdev: device pointer to hwdev
+ * @retval global function id
+ */
+u8 hinic3_get_bond_create_mode(void *udkdev);
+
/* *
* @brief hinic3_global_func_id - get global function id
* @param hwdev: device pointer to hwdev
@@ -1249,4 +1274,7 @@ int hinic3_mbox_to_host_sync(void *hwdev, enum hinic3_mod_type mod,
int hinic3_get_func_vroce_enable(void *hwdev, u16 glb_func_idx, u8 *en);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type);
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
index 5863bee..9b5f017 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
@@ -18,9 +18,8 @@
#include "hinic3_tx.h"
#include "hinic3_dcb.h"
#include "hinic3_nic.h"
-#include "hinic3_mgmt_interface.h"
-#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "hinic3_bond.h"
+#include "nic_mpu_cmd_defs.h"
typedef int (*nic_driv_module)(struct hinic3_nic_dev *nic_dev,
const void *buf_in, u32 in_size,
@@ -48,7 +47,7 @@ static int get_nic_drv_version(void *buf_out, const u32 *out_size)
}
err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
- HINIC3_NIC_DRV_VERSION, "2024-07-03_09:33:00");
+ HINIC3_NIC_DRV_VERSION, "2025-05-01_00:00:03");
if (err < 0)
return -EINVAL;
@@ -94,13 +93,13 @@ static int get_q_num(struct hinic3_nic_dev *nic_dev,
return -EFAULT;
}
- if (!buf_out) {
+ if (!buf_out || !out_size) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Get queue number para buf_out is NULL.\n");
return -EINVAL;
}
- if (!out_size || *out_size != sizeof(u16)) {
+ if (*out_size != sizeof(u16)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user: %u, expect: %lu\n",
*out_size, sizeof(u16));
@@ -126,7 +125,8 @@ static int get_tx_wqe_info(struct hinic3_nic_dev *nic_dev,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -178,7 +178,8 @@ static int get_rx_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
rq_info->delta = (u16)nic_dev->rxqs[q_id].delta;
- rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx & nic_dev->rxqs[q_id].q_mask);
+ rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx &
+ nic_dev->rxqs[q_id].q_mask);
rq_info->sw_pi = nic_dev->rxqs[q_id].next_to_update;
rq_info->msix_vector = nic_dev->rxqs[q_id].irq_id;
@@ -201,7 +202,8 @@ static int get_rx_wqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -230,7 +232,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EFAULT;
}
- if (!buf_in || !buf_out) {
+ if (!buf_in || !buf_out || !out_size) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Buf_in or buf_out is NULL.\n");
return -EINVAL;
@@ -243,7 +245,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EINVAL;
}
- if (!out_size || *out_size != sizeof(struct hinic3_rq_cqe)) {
+ if (*out_size != sizeof(struct hinic3_rq_cqe)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(struct hinic3_rq_cqe));
@@ -252,10 +254,16 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
q_id = (u16)info->q_id;
idx = (u16)info->wqe_id;
- if (q_id >= nic_dev->q_params.num_qps || idx >= nic_dev->rxqs[q_id].q_depth) {
+ if (q_id >= nic_dev->q_params.num_qps) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid q_id[%u] >= %u.\n", q_id,
+ nic_dev->q_params.num_qps);
+ return -EFAULT;
+ }
+ if (idx >= nic_dev->rxqs[q_id].q_depth) {
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Invalid q_id[%u] >= %u, or wqe idx[%u] >= %u.\n",
- q_id, nic_dev->q_params.num_qps, idx, nic_dev->rxqs[q_id].q_depth);
+ "Invalid wqe idx[%u] >= %u.\n", idx,
+ nic_dev->rxqs[q_id].q_depth);
return -EFAULT;
}
@@ -338,7 +346,8 @@ static int set_loopback_mode(struct hinic3_nic_dev *nic_dev, const void *buf_in,
err = hinic3_set_loopback_mode(nic_dev->hwdev, (u8)mode->loop_mode,
(u8)mode->loop_ctrl);
if (err == 0)
- nicif_info(nic_dev, drv, nic_dev->netdev, "Set loopback mode %u en %u succeed\n",
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Set loopback mode %u en %u succeed\n",
mode->loop_mode, mode->loop_ctrl);
return err;
@@ -417,6 +426,59 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
{
u32 pf_bw_limit;
int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
+
+ if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To set VF bandwidth rate, please use ip link cmd\n");
+ return -EINVAL;
+ }
+
+ if (!buf_in || !buf_out || in_size != sizeof(u32) ||
+ !out_size || *out_size != sizeof(u8))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_TX;
+ pf_bw_limit = *((u32 *)buf_in);
+
+ err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
+ if (err) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %u%%\n",
+ pf_bw_limit);
+ if (err < 0)
+ return err;
+ }
+
+ *((u8 *)buf_out) = (u8)err;
+
+ return 0;
+}
+
+static int set_rx_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ u32 pf_bw_limit;
+ int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
nicif_err(nic_dev, drv, nic_dev->netdev, "To set VF bandwidth rate, please use ip link cmd\n");
@@ -426,11 +488,16 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || !buf_out || in_size != sizeof(u32) || !out_size || *out_size != sizeof(u8))
return -EINVAL;
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_RX;
pf_bw_limit = *((u32 *)buf_in);
err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %d%%\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to set pf bandwidth limit to %d%%\n",
pf_bw_limit);
if (err < 0)
return err;
@@ -445,19 +512,21 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
struct hinic3_nic_io *nic_io = NULL;
+ u32 *rate_limit = (u32 *)buf_out;
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "To get VF bandwidth rate, please use ip link cmd\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To get VF bandwidth rate, please use ip link cmd\n");
return -EINVAL;
}
if (!buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(u32)) {
+ if (*out_size != sizeof(u32) * 2) { // 2:Stored in an array, TX and RX, both length are u32
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user: %d, expect: %lu\n",
- *out_size, sizeof(u32));
+ *out_size, sizeof(u32) * 2);
return -EFAULT;
}
@@ -465,8 +534,12 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!nic_io)
return -EINVAL;
- *((u32 *)buf_out) = nic_io->nic_cfg.pf_bw_limit;
+ rate_limit[HINIC3_NIC_RX] = nic_io->nic_cfg.pf_bw_rx_limit;
+ rate_limit[HINIC3_NIC_TX] = nic_io->nic_cfg.pf_bw_tx_limit;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "read rate cfg success rx rate is: %u, tx rate is : %u\n",
+ rate_limit[HINIC3_NIC_RX], rate_limit[HINIC3_NIC_TX]);
return 0;
}
@@ -477,8 +550,8 @@ static int get_sset_count(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || in_size != sizeof(u32) || !out_size ||
*out_size != sizeof(u32) || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
@@ -504,16 +577,16 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
int err;
if (!buf_in || in_size != sizeof(u32) || !out_size || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
size = sizeof(u32);
err = get_sset_count(nic_dev, buf_in, in_size, &count, &size);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Get sset count failed, ret=%d\n",
- err);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Get sset count failed, ret=%d\n", err);
return -EINVAL;
}
if (count * sizeof(*items) != *out_size) {
@@ -527,12 +600,14 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
switch (sset) {
case HINIC3_SHOW_SSET_IO_STATS:
- hinic3_get_io_stats(nic_dev, items);
+ err = hinic3_get_io_stats(nic_dev, items);
+ if (err < 0)
+ return -EINVAL;
break;
default:
- nicif_err(nic_dev, drv, nic_dev->netdev, "Unknown %u to get stats\n",
- sset);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unknown %u to get stats\n", sset);
err = -EINVAL;
break;
}
@@ -544,15 +619,18 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int i;
u8 cos_num = 0, valid_cos_bitmap = 0;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_PCP2COS) {
for (i = 0; i < NIC_DCB_UP_MAX; i++) {
- if (!(nic_dev->func_dft_cos_bitmap & BIT(qos_in->pcp2cos[i]))) {
+ if (!(dcb->func_dft_cos_bitmap &
+ BIT(qos_in->pcp2cos[i]))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- qos_in->pcp2cos[i], nic_dev->func_dft_cos_bitmap);
+ qos_in->pcp2cos[i],
+ dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -562,7 +640,8 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
}
- memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos, sizeof(qos_in->pcp2cos));
+ memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos,
+ sizeof(qos_in->pcp2cos));
wanted_dcb_cfg->pcp_user_cos_num = cos_num;
wanted_dcb_cfg->pcp_valid_cos_map = valid_cos_bitmap;
}
@@ -572,12 +651,14 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = 0;
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++) {
u8 cos = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->wanted_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ dcb->wanted_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
- if (cos >= NIC_DCB_UP_MAX || !(nic_dev->func_dft_cos_bitmap & BIT(cos))) {
+ if (cos >= NIC_DCB_UP_MAX ||
+ !(dcb->func_dft_cos_bitmap & BIT(cos))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- cos, nic_dev->func_dft_cos_bitmap);
+ cos, dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -588,8 +669,10 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- wanted_dcb_cfg->dscp2cos[i] = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->hw_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ wanted_dcb_cfg->dscp2cos[i] =
+ qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
+ dcb->hw_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
wanted_dcb_cfg->dscp_user_cos_num = cos_num;
wanted_dcb_cfg->dscp_valid_cos_map = valid_cos_bitmap;
}
@@ -601,11 +684,12 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int ret;
u8 cos_num, valid_cos_bitmap;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_TRUST) {
- if (qos_in->trust > DCB_DSCP) {
+ if (qos_in->trust > HINIC3_DCB_DSCP) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid trust=%u\n", qos_in->trust);
return -EINVAL;
@@ -615,7 +699,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
}
if (qos_in->cfg_bitmap & CMD_QOS_DEV_DFT_COS) {
- if (!(BIT(qos_in->dft_cos) & nic_dev->func_dft_cos_bitmap)) {
+ if (!(BIT(qos_in->dft_cos) & dcb->func_dft_cos_bitmap)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid dft_cos=%u\n", qos_in->dft_cos);
return -EINVAL;
@@ -628,7 +712,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
if (ret)
return ret;
- if (wanted_dcb_cfg->trust == DCB_PCP) {
+ if (wanted_dcb_cfg->trust == HINIC3_DCB_PCP) {
cos_num = wanted_dcb_cfg->pcp_user_cos_num;
valid_cos_bitmap = wanted_dcb_cfg->pcp_valid_cos_map;
} else {
@@ -636,18 +720,11 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = wanted_dcb_cfg->dscp_valid_cos_map;
}
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "DCB is on, cos num should not more than channel num:%u\n",
- nic_dev->q_params.num_qps);
- return -EOPNOTSUPP;
- }
- }
-
if (!(BIT(wanted_dcb_cfg->default_cos) & valid_cos_bitmap)) {
- nicif_info(nic_dev, drv, nic_dev->netdev, "Current default_cos=%u, change to %u\n",
- wanted_dcb_cfg->default_cos, (u8)fls(valid_cos_bitmap) - 1);
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Current default_cos=%u, change to %u\n",
+ wanted_dcb_cfg->default_cos,
+ (u8)fls(valid_cos_bitmap) - 1);
wanted_dcb_cfg->default_cos = (u8)fls(valid_cos_bitmap) - 1;
}
@@ -657,6 +734,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_dev_cfg *qos_in = buf_in;
struct hinic3_mt_qos_dev_cfg *qos_out = buf_out;
u8 i;
@@ -675,9 +753,10 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(qos_out, qos_in, sizeof(*qos_in));
qos_out->head.status = 0;
if (qos_in->op_code & MT_DCB_OPCODE_WR) {
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg,
+ memcpy(&dcb->wanted_dcb_cfg, &dcb->hw_dcb_cfg,
sizeof(struct hinic3_dcb_config));
- err = update_wanted_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg, qos_in);
+ err = update_wanted_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg,
+ qos_in);
if (err) {
qos_out->head.status = MT_EINVAL;
return 0;
@@ -687,12 +766,12 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
qos_out->head.status = MT_EIO;
} else {
- qos_out->dft_cos = nic_dev->hw_dcb_cfg.default_cos;
- qos_out->trust = nic_dev->hw_dcb_cfg.trust;
+ qos_out->dft_cos = dcb->hw_dcb_cfg.default_cos;
+ qos_out->trust = dcb->hw_dcb_cfg.trust;
for (i = 0; i < NIC_DCB_UP_MAX; i++)
- qos_out->pcp2cos[i] = nic_dev->hw_dcb_cfg.pcp2cos[i];
+ qos_out->pcp2cos[i] = dcb->hw_dcb_cfg.pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- qos_out->dscp2cos[i] = nic_dev->hw_dcb_cfg.dscp2cos[i];
+ qos_out->dscp2cos[i] = dcb->hw_dcb_cfg.dscp2cos[i];
}
return 0;
@@ -721,27 +800,17 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(dcb_out, dcb_in, sizeof(*dcb_in));
dcb_out->head.status = 0;
if (dcb_in->op_code & MT_DCB_OPCODE_WR) {
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) == dcb_in->state)
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ==
+ dcb_in->state)
return 0;
- if (dcb_in->state) {
- if (user_cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "cos num %u should not more than channel num %u\n",
- user_cos_num,
- nic_dev->q_params.num_qps);
-
- return -EOPNOTSUPP;
- }
- }
-
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? user_cos_num : 0,
+ err = hinic3_setup_cos(nic_dev->netdev,
+ dcb_in->state ? user_cos_num : 0,
netif_run);
if (err)
goto setup_cos_fail;
@@ -751,7 +820,6 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
goto vport_up_fail;
}
- rtnl_unlock();
} else {
dcb_out->state = !!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
}
@@ -759,12 +827,12 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
vport_up_fail:
- hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num,
+ netif_run);
setup_cos_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
return err;
}
@@ -772,13 +840,15 @@ setup_cos_fail:
static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_cos_cfg *cos_cfg_in = buf_in;
struct hinic3_mt_qos_cos_cfg *cos_cfg_out = buf_out;
if (!buf_in || !buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(*cos_cfg_out) || in_size != sizeof(*cos_cfg_in)) {
+ if (*out_size != sizeof(*cos_cfg_out) ||
+ in_size != sizeof(*cos_cfg_in)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
in_size, *out_size, sizeof(*cos_cfg_in));
@@ -789,9 +859,9 @@ static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
cos_cfg_out->head.status = 0;
cos_cfg_out->port_id = hinic3_physical_port_id(nic_dev->hwdev);
- cos_cfg_out->func_cos_bitmap = (u8)nic_dev->func_dft_cos_bitmap;
- cos_cfg_out->port_cos_bitmap = (u8)nic_dev->port_dft_cos_bitmap;
- cos_cfg_out->func_max_cos_num = nic_dev->cos_config_num_max;
+ cos_cfg_out->func_cos_bitmap = (u8)dcb->func_dft_cos_bitmap;
+ cos_cfg_out->port_cos_bitmap = (u8)dcb->port_dft_cos_bitmap;
+ cos_cfg_out->func_max_cos_num = dcb->cos_config_num_max;
return 0;
}
@@ -803,7 +873,13 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
intr_num = hinic3_intr_num(nic_dev->hwdev);
- if (!buf_out || !out_size || *out_size != sizeof(u16)) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != sizeof(u16)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(u16));
@@ -817,20 +893,27 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
static int get_netdev_name(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- if (!buf_out || !out_size || *out_size != IFNAMSIZ) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != IFNAMSIZ) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %u\n",
*out_size, IFNAMSIZ);
return -EFAULT;
}
- strlcpy(buf_out, nic_dev->netdev->name, IFNAMSIZ);
+ strscpy(buf_out, nic_dev->netdev->name, IFNAMSIZ);
return 0;
}
-static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
int *tx_timeout = buf_out;
@@ -839,7 +922,8 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (*out_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, out_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, out_size: %u, expect: %lu\n",
*out_size, sizeof(int));
return -EINVAL;
}
@@ -849,8 +933,9 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return 0;
}
-static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
const int *tx_timeout = buf_in;
@@ -859,13 +944,15 @@ static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (in_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, in_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, in_size: %u, expect: %lu\n",
in_size, sizeof(int));
return -EINVAL;
}
net_dev->watchdog_timeo = *tx_timeout * HZ;
- nicif_info(nic_dev, drv, net_dev, "Set tx timeout check period to %ds\n", *tx_timeout);
+ nicif_info(nic_dev, drv, net_dev,
+ "Set tx timeout check period to %ds\n", *tx_timeout);
return 0;
}
@@ -891,6 +978,34 @@ static int get_xsfp_present(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
}
+static int get_xsfp_tlv_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct drv_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info = buf_out;
+ const struct mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req = buf_in;
+ int err;
+
+ if ((buf_in == NULL) || (buf_out == NULL) || (out_size == NULL))
+ return -EINVAL;
+
+ if (*out_size != sizeof(*sfp_tlv_info) ||
+ in_size != sizeof(*sfp_tlv_info_req)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
+ in_size, *out_size, sizeof(*sfp_tlv_info));
+ return -EINVAL;
+ }
+
+ err = hinic3_get_sfp_tlv_info(nic_dev->hwdev,
+ sfp_tlv_info, sfp_tlv_info_req);
+ if (err != 0) {
+ sfp_tlv_info->head.status = MT_EIO;
+ return 0;
+ }
+
+ return 0;
+}
+
static int get_xsfp_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
@@ -928,7 +1043,7 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{GET_LOOPBACK_MODE, get_loopback_mode},
{SET_LOOPBACK_MODE, set_loopback_mode},
{SET_LINK_MODE, set_link_mode},
- {SET_PF_BW_LIMIT, set_pf_bw_limit},
+ {SET_TX_PF_BW_LIMIT, set_pf_bw_limit},
{GET_PF_BW_LIMIT, get_pf_bw_limit},
{GET_SSET_COUNT, get_sset_count},
{GET_SSET_ITEMS, get_sset_stats},
@@ -940,17 +1055,22 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{SET_TX_TIMEOUT, set_netdev_tx_timeout},
{GET_XSFP_PRESENT, get_xsfp_present},
{GET_XSFP_INFO, get_xsfp_info},
+ {GET_XSFP_INFO_COMP_CMIS, get_xsfp_tlv_info},
+ {SET_RX_PF_BW_LIMIT, set_rx_pf_bw_limit}
};
static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
u32 cmd, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(nic_driv_module_cmd_handle) /
- sizeof(nic_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(nic_driv_module_cmd_handle) /
+ sizeof(nic_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type = (enum driver_cmd_type)cmd;
int err = 0;
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_lock();
+
mutex_lock(&nic_dev->nic_mutex);
for (index = 0; index < num_cmds; index++) {
if (cmd_type ==
@@ -963,6 +1083,9 @@ static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
}
mutex_unlock(&nic_dev->nic_mutex);
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_unlock();
+
if (index == num_cmds) {
pr_err("Can't find callback for %d\n", cmd_type);
return -EINVAL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
index a1fb4af..aa53c19 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
@@ -24,82 +24,80 @@
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_user_cos_num;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_user_cos_num;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_user_cos_num;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_user_cos_num;
return 0;
}
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_valid_cos_map;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_valid_cos_map;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_valid_cos_map;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_valid_cos_map;
return 0;
}
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
- u8 i, remainder, num_sq_per_cos, cur_cos_num = 0;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ struct hinic3_dcb_config *wanted_dcb_cfg =
+ &nic_dev->dcb->wanted_dcb_cfg;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
+ u8 cos_qp_num, cos_qp_offset = 0;
+ u8 i, remainder, num_qp_per_cos;
- if (num_cos == 0)
- return;
-
- num_sq_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
- if (num_sq_per_cos == 0)
+ if (num_cos == 0 || nic_dev->q_params.num_qps == 0)
return;
- remainder = nic_dev->q_params.num_qps % num_sq_per_cos;
+ num_qp_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
+ remainder = nic_dev->q_params.num_qps % num_cos;
- memset(dcb_cfg->cos_qp_offset, 0, sizeof(dcb_cfg->cos_qp_offset));
- memset(dcb_cfg->cos_qp_num, 0, sizeof(dcb_cfg->cos_qp_num));
+ memset(hw_dcb_cfg->cos_qp_offset, 0, sizeof(hw_dcb_cfg->cos_qp_offset));
+ memset(hw_dcb_cfg->cos_qp_num, 0, sizeof(hw_dcb_cfg->cos_qp_num));
for (i = 0; i < PCP_MAX_UP; i++) {
if (BIT(i) & valid_cos_map) {
- u8 cos_qp_num = num_sq_per_cos;
- u8 cos_qp_offset = (u8)(cur_cos_num * num_sq_per_cos);
-
- if (cur_cos_num < remainder) {
- cos_qp_num++;
- cos_qp_offset += cur_cos_num;
- } else {
- cos_qp_offset += remainder;
- }
-
- cur_cos_num++;
- valid_cos_map -= (u8)BIT(i);
+ cos_qp_num = num_qp_per_cos + ((remainder > 0) ?
+ (remainder--, 1) : 0);
- dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
- dcb_cfg->cos_qp_num[i] = cos_qp_num;
+ hw_dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
+ hw_dcb_cfg->cos_qp_num[i] = cos_qp_num;
hinic3_info(nic_dev, drv, "cos %u, cos_qp_offset=%u cos_qp_num=%u\n",
i, cos_qp_offset, cos_qp_num);
+
+ cos_qp_offset += cos_qp_num;
+ valid_cos_map -= (int)BIT(i);
}
}
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_offset, dcb_cfg->cos_qp_offset,
- sizeof(dcb_cfg->cos_qp_offset));
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_num, dcb_cfg->cos_qp_num,
- sizeof(dcb_cfg->cos_qp_num));
+ memcpy(wanted_dcb_cfg->cos_qp_offset, hw_dcb_cfg->cos_qp_offset,
+ sizeof(hw_dcb_cfg->cos_qp_offset));
+ memcpy(wanted_dcb_cfg->cos_qp_num, hw_dcb_cfg->cos_qp_num,
+ sizeof(hw_dcb_cfg->cos_qp_num));
}
void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
u8 i;
u16 start_qid, q_num;
hinic3_set_txq_cos(nic_dev, 0, nic_dev->q_params.num_qps,
- nic_dev->hw_dcb_cfg.default_cos);
+ hw_dcb_cfg->default_cos);
if (!dcb_en)
return;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- q_num = (u16)nic_dev->hw_dcb_cfg.cos_qp_num[i];
+ q_num = (u16)hw_dcb_cfg->cos_qp_num[i];
if (q_num) {
- start_qid = (u16)nic_dev->hw_dcb_cfg.cos_qp_offset[i];
+ start_qid = (u16)hw_dcb_cfg->cos_qp_offset[i];
hinic3_set_txq_cos(nic_dev, start_qid, q_num, i);
hinic3_info(nic_dev, drv, "update tx db cos, start_qid %u, q_num=%u cos=%u\n",
@@ -110,30 +108,29 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ struct hinic3_dcb_config *hw_dcb_cfg = &dcb->hw_dcb_cfg;
struct hinic3_dcb_state dcb_state = {0};
u8 i;
int err;
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- /* VF does not support DCB, use the default cos */
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
-
- return 0;
- }
+ u32 pcp2cos_size = sizeof(dcb_state.pcp2cos);
+ u32 dscp2cos_size = sizeof(dcb_state.dscp2cos);
dcb_state.dcb_on = dcb_en;
- dcb_state.default_cos = dcb_cfg->default_cos;
- dcb_state.trust = dcb_cfg->trust;
+ dcb_state.default_cos = hw_dcb_cfg->default_cos;
+ dcb_state.trust = hw_dcb_cfg->trust;
if (dcb_en) {
for (i = 0; i < NIC_DCB_COS_MAX; i++)
- dcb_state.pcp2cos[i] = dcb_cfg->pcp2cos[i];
+ dcb_state.pcp2cos[i] = hw_dcb_cfg->pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- dcb_state.dscp2cos[i] = dcb_cfg->dscp2cos[i];
+ dcb_state.dscp2cos[i] = hw_dcb_cfg->dscp2cos[i];
} else {
- memset(dcb_state.pcp2cos, dcb_cfg->default_cos, sizeof(dcb_state.pcp2cos));
- memset(dcb_state.dscp2cos, dcb_cfg->default_cos, sizeof(dcb_state.dscp2cos));
+ memset(dcb_state.pcp2cos, hw_dcb_cfg->default_cos,
+ pcp2cos_size);
+ memset(dcb_state.dscp2cos, hw_dcb_cfg->default_cos,
+ dscp2cos_size);
}
err = hinic3_set_dcb_state(nic_dev->hwdev, &dcb_state);
@@ -143,7 +140,7 @@ static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
return err;
}
-static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
int err;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
@@ -169,11 +166,13 @@ static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
goto rx_configure_fail;
}
- if (dcb_en)
+ if (dcb_en) {
set_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
- else
+ set_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ } else {
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
-
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ }
return 0;
rx_configure_fail:
hinic3_set_tx_cos_state(nic_dev, dcb_en ? 0 : 1);
@@ -188,6 +187,7 @@ set_tx_cos_fail:
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err;
if (cos && test_bit(HINIC3_SAME_RXTX, &nic_dev->flags)) {
@@ -195,9 +195,10 @@ int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
return -EOPNOTSUPP;
}
- if (cos > nic_dev->cos_config_num_max) {
- nicif_err(nic_dev, drv, netdev, "Invalid num_tc: %u, max cos: %u\n",
- cos, nic_dev->cos_config_num_max);
+ if (cos > dcb->cos_config_num_max) {
+ nicif_err(nic_dev, drv, netdev,
+ "Invalid num_tc: %u, max cos: %u\n",
+ cos, dcb->cos_config_num_max);
return -EINVAL;
}
@@ -223,36 +224,48 @@ static u8 get_cos_num(u8 hw_valid_cos_bitmap)
static void hinic3_sync_dcb_cfg(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dcb_config *dcb_cfg)
{
- struct hinic3_dcb_config *hw_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
- memcpy(hw_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(hw_dcb_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
}
static int init_default_dcb_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *dcb_cfg)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 i, hw_dft_cos_map, port_cos_bitmap, dscp_ind;
int err;
+ int is_in_kexec;
- err = hinic3_cos_valid_bitmap(nic_dev->hwdev, &hw_dft_cos_map, &port_cos_bitmap);
+ err = hinic3_cos_valid_bitmap(nic_dev->hwdev,
+ &hw_dft_cos_map, &port_cos_bitmap);
if (err) {
hinic3_err(nic_dev, drv, "None cos supported\n");
return -EFAULT;
}
- nic_dev->func_dft_cos_bitmap = hw_dft_cos_map;
- nic_dev->port_dft_cos_bitmap = port_cos_bitmap;
- nic_dev->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+ is_in_kexec = vram_get_kexec_flag();
- dcb_cfg->trust = DCB_PCP;
- dcb_cfg->pcp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->dscp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
+ dcb->func_dft_cos_bitmap = hw_dft_cos_map;
+ dcb->port_dft_cos_bitmap = port_cos_bitmap;
+
+ dcb->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+
+ if (is_in_kexec == 0) {
+ dcb_cfg->trust = HINIC3_DCB_PCP;
+ dcb_cfg->default_cos = (u8)fls(dcb->func_dft_cos_bitmap) - 1;
+ } else {
+ dcb_cfg->trust = nic_dev->dcb->hw_dcb_cfg.trust;
+ dcb_cfg->default_cos = nic_dev->dcb->hw_dcb_cfg.default_cos;
+ }
+ dcb_cfg->pcp_user_cos_num = dcb->cos_config_num_max;
+ dcb_cfg->dscp_user_cos_num = dcb->cos_config_num_max;
dcb_cfg->pcp_valid_cos_map = hw_dft_cos_map;
dcb_cfg->dscp_valid_cos_map = hw_dft_cos_map;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i) ? i : dcb_cfg->default_cos;
+ dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i)
+ ? i : (u8)fls(dcb->func_dft_cos_bitmap) - 1;
for (dscp_ind = 0; dscp_ind < NIC_DCB_COS_MAX; dscp_ind++)
dcb_cfg->dscp2cos[i * NIC_DCB_DSCP_NUM + dscp_ind] = dcb_cfg->pcp2cos[i];
}
@@ -276,58 +289,121 @@ int hinic3_configure_dcb(struct net_device *netdev)
int err;
err = hinic3_sync_dcb_state(nic_dev->hwdev, 1,
- test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)
+ ? 1 : 0);
if (err) {
hinic3_err(nic_dev, drv, "Set dcb state failed\n");
return err;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ hinic3_sync_dcb_cfg(nic_dev, &nic_dev->dcb->wanted_dcb_cfg);
else
hinic3_dcb_reset_hw_config(nic_dev);
return 0;
}
+static int hinic3_dcb_alloc(struct hinic3_nic_dev *nic_dev)
+{
+ u16 func_id;
+ int is_use_vram;
+ int ret;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ ret = snprintf(nic_dev->dcb_name, VRAM_NAME_MAX_LEN,
+ "%s%u%s", VRAM_CQM_GLB_FUNC_BASE, func_id,
+ VRAM_NIC_DCB);
+ if (ret < 0) {
+ hinic3_err(nic_dev, drv, "Nic dcb snprintf failed, ret:%d.\n", ret);
+ return ret;
+ }
+
+ nic_dev->dcb = (struct hinic3_dcb *)hi_vram_kalloc(nic_dev->dcb_name,
+ sizeof(*nic_dev->dcb));
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to vram alloc dcb.\n");
+ return -EFAULT;
+ }
+ } else {
+ nic_dev->dcb = kzalloc(sizeof(*nic_dev->dcb), GFP_KERNEL);
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to create dcb.\n");
+ return -EFAULT;
+ }
+ }
+
+ return 0;
+}
+
+static void hinic3_dcb_free(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram)
+ hi_vram_kfree((void *)nic_dev->dcb, nic_dev->dcb_name, sizeof(*nic_dev->dcb));
+ else
+ kfree(nic_dev->dcb);
+ nic_dev->dcb = NULL;
+}
+
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
+ hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+
+ hinic3_dcb_free(nic_dev);
+}
+
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = NULL;
int err;
u8 dcb_en = test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0;
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- return hinic3_set_tx_cos_state(nic_dev, dcb_en);
+ err = hinic3_dcb_alloc(nic_dev);
+ if (err != 0) {
+ hinic3_err(nic_dev, drv, "Dcb alloc failed.\n");
+ return err;
+ }
- err = init_default_dcb_cfg(nic_dev, dcb_cfg);
+ hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ err = init_default_dcb_cfg(nic_dev, hw_dcb_cfg);
if (err) {
- hinic3_err(nic_dev, drv, "Initialize dcb configuration failed\n");
+ hinic3_err(nic_dev, drv,
+ "Initialize dcb configuration failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&nic_dev->dcb->wanted_dcb_cfg, hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
hinic3_info(nic_dev, drv, "Support num cos %u, default cos %u\n",
- nic_dev->cos_config_num_max, dcb_cfg->default_cos);
+ nic_dev->dcb->cos_config_num_max, hw_dcb_cfg->default_cos);
err = hinic3_set_tx_cos_state(nic_dev, dcb_en);
if (err) {
hinic3_err(nic_dev, drv, "Set tx cos state failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- sema_init(&nic_dev->dcb_sem, 1);
-
return 0;
}
-static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dcb_config *dcb_cfg)
+static int change_qos_cfg(struct hinic3_nic_dev *nic_dev,
+ const struct hinic3_dcb_config *dcb_cfg)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err = 0;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags)) {
+ if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags)) {
nicif_warn(nic_dev, drv, netdev,
"Cos_up map setting in inprocess, please try again later\n");
return -EFAULT;
@@ -337,40 +413,44 @@ static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dc
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
- clear_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags);
+ clear_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags);
return err;
}
int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err, rollback_err;
u8 netif_run = 0;
struct hinic3_dcb_config old_dcb_cfg;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- memcpy(&old_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&old_dcb_cfg, &dcb->hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
- if (!memcmp(&nic_dev->wanted_dcb_cfg, &old_dcb_cfg, sizeof(struct hinic3_dcb_config))) {
+ if (!memcmp(&dcb->wanted_dcb_cfg, &old_dcb_cfg,
+ sizeof(struct hinic3_dcb_config))) {
nicif_info(nic_dev, drv, nic_dev->netdev,
"Same valid up bitmap, don't need to change anything\n");
return 0;
}
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = change_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ err = change_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Set cos_up map to hw failed\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Set cos_up map to hw failed\n");
goto change_qos_cfg_fail;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- err = hinic3_setup_cos(nic_dev->netdev, user_cos_num, netif_run);
+ err = hinic3_setup_cos(nic_dev->netdev,
+ user_cos_num, netif_run);
if (err)
goto set_err;
}
@@ -381,13 +461,12 @@ int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
goto vport_up_fail;
}
- rtnl_unlock();
-
return 0;
vport_up_fail:
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_setup_cos(nic_dev->netdev, user_cos_num ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, user_cos_num
+ ? 0 : user_cos_num, netif_run);
set_err:
rollback_err = change_qos_cfg(nic_dev, &old_dcb_cfg);
@@ -399,7 +478,5 @@ change_qos_cfg_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
-
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
index 7987f56..e0b35cb 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
@@ -24,11 +24,6 @@ struct hinic3_tc_cfg {
u16 rsvd;
};
-enum HINIC3_DCB_TRUST {
- DCB_PCP,
- DCB_DSCP,
-};
-
#define PCP_MAX_UP 8
#define DSCP_MAC_UP 64
#define DBG_DFLT_DSCP_VAL 0xFF
@@ -50,6 +45,7 @@ struct hinic3_dcb_config {
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev);
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev);
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev);
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev);
void hinic3_dcb_reset_hw_config(struct hinic3_nic_dev *nic_dev);
int hinic3_configure_dcb(struct net_device *netdev);
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run);
@@ -75,4 +71,5 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos);
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev);
int hinic3_vport_up(struct hinic3_nic_dev *nic_dev);
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
index 2b3561e..548d67d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
@@ -44,9 +44,9 @@ static void hinic3_get_drvinfo(struct net_device *netdev,
u8 mgmt_ver[HINIC3_MGMT_VERSION_MAX_LEN] = {0};
int err;
- strlcpy(info->driver, HINIC3_NIC_DRV_NAME, sizeof(info->driver));
- strlcpy(info->version, HINIC3_NIC_DRV_VERSION, sizeof(info->version));
- strlcpy(info->bus_info, pci_name(pdev), sizeof(info->bus_info));
+ strscpy(info->driver, HINIC3_NIC_DRV_NAME, sizeof(info->driver));
+ strscpy(info->version, HINIC3_NIC_DRV_VERSION, sizeof(info->version));
+ strscpy(info->bus_info, pci_name(pdev), sizeof(info->bus_info));
err = hinic3_get_mgmt_version(nic_dev->hwdev, mgmt_ver,
HINIC3_MGMT_VERSION_MAX_LEN,
@@ -123,10 +123,15 @@ reset_err:
return err;
}
+#ifdef HAVE_ETHTOOL_RINGPARAM_EXTACK
static void hinic3_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring,
struct kernel_ethtool_ringparam *kernel_ring,
struct netlink_ext_ack *extack)
+#else
+static void hinic3_get_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+#endif
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
@@ -176,10 +181,15 @@ static int check_ringparam_valid(struct net_device *netdev,
return 0;
}
+#ifdef HAVE_ETHTOOL_RINGPARAM_EXTACK
static int hinic3_set_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring,
struct kernel_ethtool_ringparam *kernel_ring,
struct netlink_ext_ack *extack)
+#else
+static int hinic3_set_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+#endif
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic3_dyna_txrxq_params q_params = {0};
@@ -273,7 +283,7 @@ static int get_coalesce(struct net_device *netdev,
static int set_queue_coalesce(struct hinic3_nic_dev *nic_dev, u16 q_id,
struct hinic3_intr_coal_info *coal)
{
- struct hinic3_intr_coal_info *intr_coal;
+ struct hinic3_intr_coal_info *intr_coal = NULL;
struct interrupt_info info = {0};
struct net_device *netdev = nic_dev->netdev;
int err;
@@ -367,24 +377,11 @@ static int is_coalesce_exceed_limit(struct net_device *netdev,
return 0;
}
-static int is_coalesce_legal(struct net_device *netdev,
- const struct ethtool_coalesce *coal)
+static int is_coalesce_allowed_change(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct ethtool_coalesce tmp_coal = {0};
- int err;
-
- if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
- nicif_err(nic_dev, drv, netdev,
- "tx-usecs must be equal to rx-usecs\n");
- return -EINVAL;
- }
-
- if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
- nicif_err(nic_dev, drv, netdev,
- "tx-frames must be equal to rx-frames\n");
- return -EINVAL;
- }
tmp_coal.cmd = coal->cmd;
tmp_coal.rx_coalesce_usecs = coal->rx_coalesce_usecs;
@@ -409,6 +406,31 @@ static int is_coalesce_legal(struct net_device *netdev,
return -EOPNOTSUPP;
}
+ return 0;
+}
+
+static int is_coalesce_legal(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-usecs must be equal to rx-usecs\n");
+ return -EINVAL;
+ }
+
+ if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-frames must be equal to rx-frames\n");
+ return -EINVAL;
+ }
+
+ err = is_coalesce_allowed_change(netdev, coal);
+ if (err)
+ return err;
+
err = is_coalesce_exceed_limit(netdev, coal);
if (err)
return err;
@@ -491,19 +513,10 @@ static int set_hw_coal_param(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static int set_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *coal, u16 queue)
+static void check_coalesce_align(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
- struct hinic3_intr_coal_info intr_coal = {0};
- struct hinic3_intr_coal_info *ori_intr_coal = NULL;
- u32 last_adaptive_rx;
- char obj_str[32] = {0};
- int err = 0;
-
- err = is_coalesce_legal(netdev, coal);
- if (err)
- return err;
CHECK_COALESCE_ALIGN(coal, rx_coalesce_usecs, COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal, rx_max_coalesced_frames,
@@ -516,6 +529,14 @@ static int set_coalesce(struct net_device *netdev,
COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal, rx_max_coalesced_frames_low,
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int check_coalesce_change(struct net_device *netdev,
+ u16 queue, struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info *ori_intr_coal = NULL;
+ char obj_str[32] = {0};
if (queue == COALESCE_ALL_QUEUE) {
ori_intr_coal = &nic_dev->intr_coalesce[0];
@@ -524,6 +545,7 @@ static int set_coalesce(struct net_device *netdev,
ori_intr_coal = &nic_dev->intr_coalesce[queue];
snprintf(obj_str, sizeof(obj_str), "for queue %u", queue);
}
+
CHECK_COALESCE_CHANGED(coal, rx_coalesce_usecs, COALESCE_TIMER_CFG_UNIT,
ori_intr_coal->coalesce_timer_cfg, obj_str);
CHECK_COALESCE_CHANGED(coal, rx_max_coalesced_frames,
@@ -545,28 +567,52 @@ static int set_coalesce(struct net_device *netdev,
CHECK_COALESCE_CHANGED(coal, rx_max_coalesced_frames_low,
COALESCE_PENDING_LIMIT_UNIT,
ori_intr_coal->rx_pending_limt_low, obj_str);
+ return 0;
+}
- intr_coal.coalesce_timer_cfg =
+static void init_intr_coal_params(struct hinic3_intr_coal_info *intr_coal,
+ struct ethtool_coalesce *coal)
+{
+ intr_coal->coalesce_timer_cfg =
(u8)(coal->rx_coalesce_usecs / COALESCE_TIMER_CFG_UNIT);
- intr_coal.pending_limt = (u8)(coal->rx_max_coalesced_frames /
- COALESCE_PENDING_LIMIT_UNIT);
+ intr_coal->pending_limt = (u8)(coal->rx_max_coalesced_frames /
+ COALESCE_PENDING_LIMIT_UNIT);
- last_adaptive_rx = nic_dev->adaptive_rx_coal;
- nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
-
- intr_coal.pkt_rate_high = coal->pkt_rate_high;
- intr_coal.rx_usecs_high =
+ intr_coal->pkt_rate_high = coal->pkt_rate_high;
+ intr_coal->rx_usecs_high =
(u8)(coal->rx_coalesce_usecs_high / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_high =
+ intr_coal->rx_pending_limt_high =
(u8)(coal->rx_max_coalesced_frames_high /
COALESCE_PENDING_LIMIT_UNIT);
- intr_coal.pkt_rate_low = coal->pkt_rate_low;
- intr_coal.rx_usecs_low =
+ intr_coal->pkt_rate_low = coal->pkt_rate_low;
+ intr_coal->rx_usecs_low =
(u8)(coal->rx_coalesce_usecs_low / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_low =
+ intr_coal->rx_pending_limt_low =
(u8)(coal->rx_max_coalesced_frames_low /
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal, u16 queue)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info intr_coal = {0};
+ u32 last_adaptive_rx;
+ int err = 0;
+
+ err = is_coalesce_legal(netdev, coal);
+ if (err)
+ return err;
+
+ check_coalesce_align(netdev, coal);
+
+ check_coalesce_change(netdev, queue, coal);
+
+ init_intr_coal_params(&intr_coal, coal);
+
+ last_adaptive_rx = nic_dev->adaptive_rx_coal;
+ nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
/* coalesce timer or pending set to zero will disable coalesce */
if (!nic_dev->adaptive_rx_coal &&
@@ -588,18 +634,28 @@ static int set_coalesce(struct net_device *netdev,
return set_hw_coal_param(nic_dev, &intr_coal, queue);
}
+#ifdef HAVE_ETHTOOL_COALESCE_EXTACK
static int hinic3_get_coalesce(struct net_device *netdev,
struct ethtool_coalesce *coal,
struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack)
+#else
+static int hinic3_get_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
+#endif
{
return get_coalesce(netdev, coal, COALESCE_ALL_QUEUE);
}
+#ifdef HAVE_ETHTOOL_COALESCE_EXTACK
static int hinic3_set_coalesce(struct net_device *netdev,
struct ethtool_coalesce *coal,
struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack)
+#else
+static int hinic3_set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
+#endif
{
return set_coalesce(netdev, coal, COALESCE_ALL_QUEUE);
}
@@ -762,6 +818,14 @@ static int hinic3_get_module_info(struct net_device *netdev,
modinfo->type = ETH_MODULE_SFF_8636;
modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
break;
+ case MODULE_TYPE_DSFP:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
+ case MODULE_TYPE_QSFP_CMIS:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
default:
nicif_warn(nic_dev, drv, netdev,
"Optical module unknown: 0x%x\n", sfp_type);
@@ -784,6 +848,9 @@ static int hinic3_get_module_eeprom(struct net_device *netdev,
memset(data, 0, ee->len);
err = hinic3_get_sfp_eeprom(nic_dev->hwdev, (u8 *)sfp_data, ee->len);
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(nic_dev->hwdev, (u8 *)sfp_data, sizeof(sfp_data));
+
if (err)
return err;
@@ -814,7 +881,7 @@ static u32 hinic3_get_priv_flags(struct net_device *netdev)
return priv_flags;
}
-int hinic3_set_rxq_recovery_flag(struct net_device *netdev, u32 priv_flags)
+static int hinic3_set_rxq_recovery_flag(struct net_device *netdev, u32 priv_flags)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
@@ -844,12 +911,14 @@ static int hinic3_set_symm_rss_flag(struct net_device *netdev, u32 priv_flags)
if (priv_flags & HINIC3_PRIV_FLAGS_SYMM_RSS) {
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, netdev, "Failed to open Symmetric RSS while DCB is enabled\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to open Symmetric RSS while DCB is enabled\n");
return -EOPNOTSUPP;
}
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, netdev, "Failed to open Symmetric RSS while RSS is disabled\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to open Symmetric RSS while RSS is disabled\n");
return -EOPNOTSUPP;
}
@@ -1129,10 +1198,61 @@ static void hinic3_diag_test(struct net_device *netdev,
hinic3_lp_test(netdev, eth_test, data, 0);
}
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+static int hinic3_get_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u8 advertised_fec = 0;
+ u8 supported_fec = 0;
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_GFECPARAM) {
+ nicif_err(nic_dev, drv, netdev,
+ "get fecparam cmd err.exp:0x%x,real:0x%x\n",
+ ETHTOOL_GFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = get_fecparam(nic_dev->hwdev, &advertised_fec, &supported_fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Get fec param failed\n");
+ return err;
+ }
+ fecparam->active_fec = (u32)advertised_fec;
+ fecparam->fec = (u32)supported_fec;
+
+ nicif_info(nic_dev, drv, netdev, "Get fec param success\n");
+ return 0;
+}
+
+static int hinic3_set_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_SFECPARAM) {
+ nicif_err(nic_dev, drv, netdev, "Set fecparam cmd err.exp:0x%x,real:0x%x\n", ETHTOOL_SFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = set_fecparam(nic_dev->hwdev, (u8)fecparam->fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Set fec param failed\n");
+ return err;
+ }
+
+ nicif_info(nic_dev, drv, netdev, "Set fec param success\n");
+ return 0;
+}
+#endif
+
static const struct ethtool_ops hinic3_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1179,6 +1299,11 @@ static const struct ethtool_ops hinic3_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
+
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
@@ -1239,7 +1364,10 @@ static const struct ethtool_ops_ext hinic3_ethtool_ops_ext = {
static const struct ethtool_ops hinic3vf_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1266,6 +1394,11 @@ static const struct ethtool_ops hinic3vf_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
+
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
index de59b76..ec89f62 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
@@ -24,11 +24,24 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
-#define FPGA_PORT_COUNTER 0
-#define EVB_PORT_COUNTER 1
-u16 mag_support_mode = EVB_PORT_COUNTER;
-module_param(mag_support_mode, ushort, 0444);
-MODULE_PARM_DESC(mag_support_mode, "Set mag port counter support mode, 0:FPGA 1:EVB, default is 1");
+#define HINIC_SET_LINK_STR_LEN 128
+#define HINIC_ETHTOOL_FEC_INFO_LEN 6
+#define HINIC_SUPPORTED_FEC_CMD 0
+#define HINIC_ADVERTISED_FEC_CMD 1
+
+struct hinic3_ethtool_fec {
+ u8 hinic_fec_offset;
+ u8 ethtool_bit_offset;
+};
+
+static struct hinic3_ethtool_fec hinic3_ethtool_fec_info[HINIC_ETHTOOL_FEC_INFO_LEN] = {
+ {PORT_FEC_NOT_SET, 0xFF}, /* The ethtool does not have the corresponding enumeration variable */
+ {PORT_FEC_RSFEC, 0x32}, /* ETHTOOL_LINK_MODE_FEC_RS_BIT */
+ {PORT_FEC_BASEFEC, 0x33}, /* ETHTOOL_LINK_MODE_FEC_BASER_BIT */
+ {PORT_FEC_NOFEC, 0x31}, /* ETHTOOL_LINK_MODE_FEC_NONE_BIT */
+ {PORT_FEC_LLRSFEC, 0x4A}, /* ETHTOOL_LINK_MODE_FEC_LLRS_BIT: Available only in later versions */
+ {PORT_FEC_AUTO, 0XFF} /* The ethtool does not have the corresponding enumeration variable */
+};
struct hinic3_stats {
char name[ETH_GSTRING_LEN];
@@ -36,6 +49,20 @@ struct hinic3_stats {
int offset;
};
+struct hinic3_netdev_link_count_str {
+ u64 link_down_events_phy;
+};
+
+#define HINIC3_NETDEV_LINK_COUNT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic3_netdev_link_count_str, _stat_item), \
+ .offset = offsetof(struct hinic3_netdev_link_count_str, _stat_item) \
+}
+
+static struct hinic3_stats hinic3_netdev_link_count[] = {
+ HINIC3_NETDEV_LINK_COUNT(link_down_events_phy),
+};
+
#define HINIC3_NETDEV_STAT(_stat_item) { \
.name = #_stat_item, \
.size = FIELD_SIZEOF(struct rtnl_link_stats64, _stat_item), \
@@ -94,7 +121,6 @@ static struct hinic3_stats hinic3_nic_dev_stats_extern[] = {
.offset = offsetof(struct hinic3_txq_stats, _stat_item) \
}
-/*lint -save -e786*/
static struct hinic3_stats hinic3_rx_queue_stats[] = {
HINIC3_RXQ_STAT(packets),
HINIC3_RXQ_STAT(bytes),
@@ -135,8 +161,6 @@ static struct hinic3_stats hinic3_tx_queue_stats_extern[] = {
HINIC3_TXQ_STAT(rsvd2),
};
-/*lint -restore*/
-
#define HINIC3_FUNC_STAT(_stat_item) { \
.name = #_stat_item, \
.size = FIELD_SIZEOF(struct hinic3_vport_stats, _stat_item), \
@@ -260,49 +284,22 @@ static struct hinic3_stats hinic3_port_stats[] = {
HINIC3_PORT_STAT(mac_rx_unfilter_pkt_num),
};
+#define HINIC3_RSFEC_STAT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct mag_cmd_rsfec_stats, _stat_item), \
+ .offset = offsetof(struct mag_cmd_rsfec_stats, _stat_item) \
+}
+
+static struct hinic3_stats g_hinic3_rsfec_stats[] = {
+ HINIC3_RSFEC_STAT(rx_err_lane_phy),
+};
+
#define HINIC3_FGPA_PORT_STAT(_stat_item) { \
.name = #_stat_item, \
.size = FIELD_SIZEOF(struct hinic3_phy_fpga_port_stats, _stat_item), \
.offset = offsetof(struct hinic3_phy_fpga_port_stats, _stat_item) \
}
-static struct hinic3_stats g_hinic3_fpga_port_stats[] = {
- HINIC3_FGPA_PORT_STAT(mac_rx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_under_frame_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_frag_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_crc_error_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_length_err_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_pause_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_unknown_mac_frame_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_underrun_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_pause_pkts_port),
-};
-
static char g_hinic_priv_flags_strings[][ETH_GSTRING_LEN] = {
"Symmetric-RSS",
"Force-Link-up",
@@ -313,12 +310,12 @@ u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev)
{
u32 count;
- count = ARRAY_LEN(hinic3_nic_dev_stats) +
+ count = (u32)(ARRAY_LEN(hinic3_nic_dev_stats) +
ARRAY_LEN(hinic3_nic_dev_stats_extern) +
(ARRAY_LEN(hinic3_tx_queue_stats) +
ARRAY_LEN(hinic3_tx_queue_stats_extern) +
ARRAY_LEN(hinic3_rx_queue_stats) +
- ARRAY_LEN(hinic3_rx_queue_stats_extern)) * nic_dev->max_qps;
+ ARRAY_LEN(hinic3_rx_queue_stats_extern)) * nic_dev->max_qps);
return count;
}
@@ -342,46 +339,81 @@ u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev)
} \
} while (0)
-#define QUEUE_STATS_PACK(items, item_idx, array, stats_ptr, qid) do { \
- int j; \
- for (j = 0; j < ARRAY_LEN(array); j++) { \
- memcpy((items)[item_idx].name, (array)[j].name, \
- HINIC3_SHOW_ITEM_LEN); \
- snprintf((items)[item_idx].name, HINIC3_SHOW_ITEM_LEN, \
- (array)[j].name, (qid)); \
- (items)[item_idx].hexadecimal = 0; \
- (items)[item_idx].value = \
- GET_VALUE_OF_PTR((array)[j].size, \
- (char *)(stats_ptr) + (array)[j].offset); \
- (item_idx)++; \
- } \
-} while (0)
+int hinic3_rx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat, struct hinic3_rxq_stats *rxq_stats, u16 qid)
+{
+ int ret;
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
+ ret = snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
+ if (ret < 0)
+ return -EINVAL;
+
+ item->hexadecimal = 0;
+ item->value = GET_VALUE_OF_PTR(stat->size, (char *)(rxq_stats) + stat->offset);
+
+ return 0;
+}
+
+int hinic3_tx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat, struct hinic3_txq_stats *txq_stats, u16 qid)
+{
+ int ret;
+
+ ret = snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
+ if (ret < 0)
+ return -EINVAL;
+
+ item->hexadecimal = 0;
+ item->value = GET_VALUE_OF_PTR(stat->size, (char *)(txq_stats) + stat->offset);
+
+ return 0;
+}
+
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
{
struct hinic3_show_item *items = stats;
int item_idx = 0;
u16 qid;
+ int idx;
+ int ret;
DEV_STATS_PACK(items, item_idx, hinic3_nic_dev_stats, &nic_dev->stats);
- DEV_STATS_PACK(items, item_idx, hinic3_nic_dev_stats_extern,
- &nic_dev->stats);
+ DEV_STATS_PACK(items, item_idx, hinic3_nic_dev_stats_extern, &nic_dev->stats);
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- QUEUE_STATS_PACK(items, item_idx, hinic3_tx_queue_stats,
- &nic_dev->txqs[qid].txq_stats, qid);
- QUEUE_STATS_PACK(items, item_idx, hinic3_tx_queue_stats_extern,
- &nic_dev->txqs[qid].txq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++], &hinic3_tx_queue_stats[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats_extern); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++], &hinic3_tx_queue_stats_extern[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
}
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- QUEUE_STATS_PACK(items, item_idx, hinic3_rx_queue_stats,
- &nic_dev->rxqs[qid].rxq_stats, qid);
- QUEUE_STATS_PACK(items, item_idx, hinic3_rx_queue_stats_extern,
- &nic_dev->rxqs[qid].rxq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++], &hinic3_rx_queue_stats[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats_extern); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++], &hinic3_rx_queue_stats_extern[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
}
-}
+ return 0;
+}
static char g_hinic3_test_strings[][ETH_GSTRING_LEN] = {
"Internal lb test (on/offline)",
"External lb test (external_lb)",
@@ -398,16 +430,15 @@ int hinic3_get_sset_count(struct net_device *netdev, int sset)
case ETH_SS_STATS:
q_num = nic_dev->q_params.num_qps;
count = ARRAY_LEN(hinic3_netdev_stats) +
- ARRAY_LEN(hinic3_nic_dev_stats) +
+ ARRAY_LEN(hinic3_nic_dev_stats) +
+ ARRAY_LEN(hinic3_netdev_link_count) +
ARRAY_LEN(hinic3_function_stats) +
(ARRAY_LEN(hinic3_tx_queue_stats) +
ARRAY_LEN(hinic3_rx_queue_stats)) * q_num;
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER)
- count += ARRAY_LEN(g_hinic3_fpga_port_stats);
- else
- count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(g_hinic3_rsfec_stats);
}
return count;
@@ -452,9 +483,9 @@ static void get_drv_queue_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
}
}
-static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct hinic3_phy_fpga_port_stats *port_stats = NULL;
+ struct mag_cmd_port_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
@@ -464,19 +495,19 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to malloc port stats\n");
memset(&data[i], 0,
- ARRAY_LEN(g_hinic3_fpga_port_stats) * sizeof(*data));
- i += ARRAY_LEN(g_hinic3_fpga_port_stats);
+ ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
+ i += ARRAY_LEN(hinic3_port_stats);
return i;
}
- err = hinic3_get_fpga_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to get port stats from fw\n");
- for (j = 0; j < ARRAY_LEN(g_hinic3_fpga_port_stats); j++, i++) {
- p = (char *)(port_stats) + g_hinic3_fpga_port_stats[j].offset;
- data[i] = (g_hinic3_fpga_port_stats[j].size ==
+ for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
+ p = (char *)(port_stats) + hinic3_port_stats[j].offset;
+ data[i] = (hinic3_port_stats[j].size ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
@@ -485,35 +516,32 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
return i;
}
-static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_rsfec_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct mag_cmd_port_stats *port_stats = NULL;
+ struct mag_cmd_rsfec_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
- if (mag_support_mode == FPGA_PORT_COUNTER)
- return get_fpga_port_stats(nic_dev, data);
-
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
if (!port_stats) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to malloc port stats\n");
memset(&data[i], 0,
- ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
- i += ARRAY_LEN(hinic3_port_stats);
+ ARRAY_LEN(g_hinic3_rsfec_stats) * sizeof(*data));
+ i += ARRAY_LEN(g_hinic3_rsfec_stats);
return i;
- }
+ }
- err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_rsfec_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to get port stats from fw\n");
+ "Failed to get rsfec stats from fw\n");
- for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
- p = (char *)(port_stats) + hinic3_port_stats[j].offset;
- data[i] = (hinic3_port_stats[j].size ==
- sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+ for (j = 0; j < ARRAY_LEN(g_hinic3_rsfec_stats); j++, i++) {
+ p = (char *)(port_stats) + g_hinic3_rsfec_stats[j].offset;
+ data[i] = (g_hinic3_rsfec_stats[j].size ==
+ sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
kfree(port_stats);
@@ -537,6 +565,8 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
u16 i = 0, j = 0;
char *p = NULL;
int err;
+ int link_down_events_phy_tmp = 0;
+ struct hinic3_netdev_link_count_str link_count = {0};
#ifdef HAVE_NDO_GET_STATS64
net_stats = dev_get_stats(netdev, &temp);
@@ -554,6 +584,14 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = GET_VALUE_OF_PTR(hinic3_nic_dev_stats[j].size, p);
}
+ err = hinic3_get_link_event_stats(nic_dev->hwdev, &link_down_events_phy_tmp);
+
+ link_count.link_down_events_phy = (u64)link_down_events_phy_tmp;
+ for (j = 0; j < ARRAY_LEN(hinic3_netdev_link_count); j++, i++) {
+ p = (char *)(&link_count) + hinic3_netdev_link_count[j].offset;
+ data[i] = GET_VALUE_OF_PTR(hinic3_netdev_link_count[j].size, p);
+ }
+
err = hinic3_get_vport_stats(nic_dev->hwdev, hinic3_global_func_id(nic_dev->hwdev),
&vport_stats);
if (err)
@@ -565,8 +603,10 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = GET_VALUE_OF_PTR(hinic3_function_stats[j].size, p);
}
- if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
i += get_ethtool_port_stats(nic_dev, data + i);
+ i += get_ethtool_rsfec_stats(nic_dev, data + i);
+ }
get_drv_queue_stats(nic_dev, data + i);
}
@@ -588,6 +628,12 @@ static u16 get_drv_dev_strings(struct hinic3_nic_dev *nic_dev, char *p)
cnt++;
}
+ for (i = 0; i < ARRAY_LEN(hinic3_netdev_link_count); i++) {
+ memcpy(p, hinic3_netdev_link_count[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+
return cnt;
}
@@ -603,18 +649,16 @@ static u16 get_hw_stats_strings(struct hinic3_nic_dev *nic_dev, char *p)
}
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER) {
- for (i = 0; i < ARRAY_LEN(g_hinic3_fpga_port_stats); i++) {
- memcpy(p, g_hinic3_fpga_port_stats[i].name, ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
- } else {
- for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
- memcpy(p, hinic3_port_stats[i].name, ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
+ for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
+ memcpy(p, hinic3_port_stats[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+ for (i = 0; i < ARRAY_LEN(g_hinic3_rsfec_stats); i++) {
+ memcpy(p, g_hinic3_rsfec_stats[i].name,
+ ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
}
}
@@ -758,7 +802,6 @@ struct hw2ethtool_link_mode {
u32 speed;
};
-/*lint -save -e26 */
static const struct hw2ethtool_link_mode
hw2ethtool_link_mode_table[LINK_MODE_MAX_NUMBERS] = {
[LINK_MODE_GE] = {
@@ -818,8 +861,6 @@ static const struct hw2ethtool_link_mode
},
};
-/*lint -restore */
-
#define GET_SUPPORTED_MODE 0
#define GET_ADVERTISED_MODE 1
@@ -838,29 +879,33 @@ struct cmd_link_settings {
#define ETHTOOL_ADD_ADVERTISED_LINK_MODE(ecmd, mode) \
set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->advertising)
-#define ETHTOOL_ADD_SUPPORTED_SPEED_LINK_MODE(ecmd, mode) \
-do { \
- u32 i; \
- for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) { \
- if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >= \
- __ETHTOOL_LINK_MODE_MASK_NBITS) \
- continue; \
- set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i], \
- (ecmd)->supported); \
- } \
-} while (0)
+static void ethtool_add_supported_speed_link_mode(struct cmd_link_settings *link_settings,
+ u32 mode)
+{
+ u32 i;
-#define ETHTOOL_ADD_ADVERTISED_SPEED_LINK_MODE(ecmd, mode) \
-do { \
- u32 i; \
- for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) { \
- if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >= \
- __ETHTOOL_LINK_MODE_MASK_NBITS) \
- continue; \
- set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i], \
- (ecmd)->advertising); \
- } \
-} while (0)
+ for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
+ if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
+ continue;
+ set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
+ link_settings->supported);
+ }
+}
+
+static void ethtool_add_advertised_speed_link_mode(struct cmd_link_settings *link_settings,
+ u32 mode)
+{
+ u32 i;
+
+ for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
+ if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
+ continue;
+ set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
+ link_settings->advertising);
+ }
+}
/* Related to enum mag_cmd_port_speed */
static u32 hw_to_ethtool_speed[] = {
@@ -888,11 +933,11 @@ static void hinic3_add_ethtool_link_mode(struct cmd_link_settings *link_settings
for (link_mode = 0; link_mode < LINK_MODE_MAX_NUMBERS; link_mode++) {
if (hw_link_mode & BIT(link_mode)) {
if (name == GET_SUPPORTED_MODE)
- ETHTOOL_ADD_SUPPORTED_SPEED_LINK_MODE
- (link_settings, link_mode);
+ ethtool_add_supported_speed_link_mode(
+ link_settings, link_mode);
else
- ETHTOOL_ADD_ADVERTISED_SPEED_LINK_MODE
- (link_settings, link_mode);
+ ethtool_add_advertised_speed_link_mode(
+ link_settings, link_mode);
}
}
}
@@ -915,10 +960,15 @@ static int hinic3_link_speed_set(struct hinic3_nic_dev *nic_dev,
err = hinic3_get_link_state(nic_dev->hwdev, &link_state);
if (!err && link_state) {
- link_settings->speed =
- port_info->speed < ARRAY_LEN(hw_to_ethtool_speed) ?
- hw_to_ethtool_speed[port_info->speed] :
- (u32)SPEED_UNKNOWN;
+ if (hinic3_get_bond_create_mode(nic_dev->hwdev)) {
+ link_settings->speed = port_info->bond_speed;
+ } else {
+ link_settings->speed =
+ port_info->speed <
+ ARRAY_LEN(hw_to_ethtool_speed) ?
+ hw_to_ethtool_speed[port_info->speed] :
+ (u32)SPEED_UNKNOWN;
+ }
link_settings->duplex = port_info->duplex;
} else {
@@ -993,6 +1043,39 @@ static int get_link_pause_settings(struct hinic3_nic_dev *nic_dev,
return 0;
}
+static bool is_bit_offset_defined(u8 bit_offset)
+{
+ if (bit_offset < __ETHTOOL_LINK_MODE_MASK_NBITS)
+ return true;
+ return false;
+}
+
+static void
+ethtool_add_supported_advertised_fec(struct cmd_link_settings *link_settings,
+ u32 fec, u8 cmd)
+{
+ u8 i;
+ for (i = 0; i < HINIC_ETHTOOL_FEC_INFO_LEN; i++) {
+ if ((fec & BIT(hinic3_ethtool_fec_info[i].hinic_fec_offset)) == 0)
+ continue;
+ if ((is_bit_offset_defined(hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true) &&
+ (cmd == HINIC_ADVERTISED_FEC_CMD)) {
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset, link_settings->advertising);
+ return; /* There can be only one advertised fec mode. */
+ }
+ if ((is_bit_offset_defined(hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true) &&
+ (cmd == HINIC_SUPPORTED_FEC_CMD))
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset, link_settings->supported);
+ }
+}
+
+static void hinic3_link_fec_type(struct cmd_link_settings *link_settings,
+ u32 fec, u32 supported_fec)
+{
+ ethtool_add_supported_advertised_fec(link_settings, supported_fec, HINIC_SUPPORTED_FEC_CMD);
+ ethtool_add_supported_advertised_fec(link_settings, fec, HINIC_ADVERTISED_FEC_CMD);
+}
+
static int get_link_settings(struct net_device *netdev,
struct cmd_link_settings *link_settings)
{
@@ -1013,6 +1096,9 @@ static int get_link_settings(struct net_device *netdev,
hinic3_link_port_type(link_settings, port_info.port_type);
+ hinic3_link_fec_type(link_settings, BIT(port_info.fec),
+ port_info.supported_fec_mode);
+
link_settings->autoneg = port_info.autoneg_state == PORT_CFG_AN_ON ?
AUTONEG_ENABLE : AUTONEG_DISABLE;
if (port_info.autoneg_cap)
@@ -1138,10 +1224,11 @@ static int hinic3_set_settings_to_hw(struct hinic3_nic_dev *nic_dev,
struct net_device *netdev = nic_dev->netdev;
struct hinic3_link_ksettings settings = {0};
int speed_level = 0;
- char set_link_str[128] = {0};
+ char set_link_str[HINIC_SET_LINK_STR_LEN] = {0};
+ char link_info[HINIC_SET_LINK_STR_LEN] = {0};
int err = 0;
- err = snprintf(set_link_str, sizeof(set_link_str) - 1, "%s",
+ err = snprintf(link_info, sizeof(link_info), "%s",
(bool)(set_settings & HILINK_LINK_SET_AUTONEG) ?
((bool)autoneg ? "autong enable " : "autong disable ") : "");
if (err < 0)
@@ -1149,8 +1236,8 @@ static int hinic3_set_settings_to_hw(struct hinic3_nic_dev *nic_dev,
if (set_settings & HILINK_LINK_SET_SPEED) {
speed_level = hinic3_ethtool_to_hw_speed_level(speed);
- err = snprintf(set_link_str, sizeof(set_link_str) - 1,
- "%sspeed %u ", set_link_str, speed);
+ err = snprintf(set_link_str, sizeof(set_link_str),
+ "%sspeed %u ", link_info, speed);
if (err < 0)
return -EINVAL;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
index 70346d6..2daa7f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
@@ -82,7 +82,7 @@ static struct hinic3_mac_filter *hinic3_add_filter(struct hinic3_nic_dev *nic_de
struct list_head *mac_filter_list,
u8 *addr)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
@@ -117,7 +117,7 @@ static void hinic3_del_filter(struct hinic3_nic_dev *nic_dev,
static struct hinic3_mac_filter *hinic3_mac_filter_entry_clone(const struct hinic3_mac_filter *src)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
index ef8c62b..7fed1c1 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
@@ -40,6 +40,7 @@ enum hinic3_channel_id {
HINIC3_CHANNEL_DSW,
HINIC3_CHANNEL_MIG,
HINIC3_CHANNEL_CRYPT,
+ HINIC3_CHANNEL_VROCE,
HINIC3_CHANNEL_MAX = 32,
};
@@ -397,6 +398,16 @@ void hinic3_free_cmd_buf(void *hwdev, struct hinic3_cmd_buf *cmd_buf);
**/
int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read clear
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+
/**
* @brief hinic3_sm_ctr_rd32 - small single 32 counter read
* @param hwdev: device pointer to hwdev
@@ -810,6 +821,13 @@ int hinic3_dbg_lt_wr_16byte_mask(void *hwdev, u8 dest, u8 instance,
*/
void hinic3_link_event_stats(void *dev, u8 link);
+/**
+ * @brief hinic3_get_link_event_stats - link event stats
+ * @param hwdev: device pointer to hwdev
+ * @param link: link status
+ */
+int hinic3_get_link_event_stats(void *dev, int *link_state);
+
/**
* @brief hinic3_get_hw_pf_infos - get pf infos
* @param hwdev: device pointer to hwdev
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
index 3c835ff..7a2644c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
@@ -12,6 +12,7 @@
#include <linux/netdevice.h>
#include <linux/debugfs.h>
+#include "ossl_knl.h"
#include "hinic3_hw.h"
#include "hinic3_crm.h"
#include "hinic3_nic_io.h"
@@ -47,12 +48,16 @@ static void qp_add_napi(struct hinic3_irq *irq_cfg)
netif_napi_add(nic_dev->netdev, &irq_cfg->napi,
hinic3_poll, nic_dev->poll_weight);
napi_enable(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_IS_REGIN;
}
-static void qp_del_napi(struct hinic3_irq *irq_cfg)
+void qp_del_napi(struct hinic3_irq *irq_cfg)
{
- napi_disable(&irq_cfg->napi);
- netif_napi_del(&irq_cfg->napi);
+ if (irq_cfg->napi_reign == NAPI_IS_REGIN) {
+ napi_disable(&irq_cfg->napi);
+ netif_napi_del(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_NOT_REGIN;
+ }
}
static irqreturn_t qp_irq(int irq, void *data)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
deleted file mode 100644
index 2482c5f..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_LLD_H
-#define HINIC3_LLD_H
-
-#include "hinic3_crm.h"
-
-struct hinic3_lld_dev {
- struct pci_dev *pdev;
- void *hwdev;
-};
-
-struct hinic3_uld_info {
- /* When the function does not need to initialize the corresponding uld,
- * @probe needs to return 0 and uld_dev is set to NULL;
- * if uld_dev is NULL, @remove will not be called when uninstalling
- */
- int (*probe)(struct hinic3_lld_dev *lld_dev, void **uld_dev, char *uld_dev_name);
- void (*remove)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- int (*suspend)(struct hinic3_lld_dev *lld_dev, void *uld_dev, pm_message_t state);
- int (*resume)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- void (*event)(struct hinic3_lld_dev *lld_dev, void *uld_dev,
- struct hinic3_event_info *event);
- int (*ioctl)(void *uld_dev, u32 cmd, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size);
-};
-
-/* hinic3_register_uld - register an upper-layer driver
- * @type: uld service type
- * @uld_info: uld callback
- *
- * Registers an upper-layer driver.
- * Traverse existing devices and call @probe to initialize the uld device.
- */
-int hinic3_register_uld(enum hinic3_service_type type, struct hinic3_uld_info *uld_info);
-
-/**
- * hinic3_unregister_uld - unregister an upper-layer driver
- * @type: uld service type
- *
- * Traverse existing devices and call @remove to uninstall the uld device.
- * Unregisters an existing upper-layer driver.
- */
-void hinic3_unregister_uld(enum hinic3_service_type type);
-
-void lld_hold(void);
-void lld_put(void);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_name - get lld device by chip name
- * @param chip_name: chip name
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_name(const char *chip_name);
-
-/**
- * @brief lld_dev_hold - get reference to lld_dev
- * @param dev: lld device
- *
- * Hold reference to device to keep it from being freed
- **/
-void lld_dev_hold(struct hinic3_lld_dev *dev);
-
-/**
- * @brief lld_dev_put - release reference to lld_dev
- * @param dev: lld device
- *
- * Release reference to device to allow it to be freed
- **/
-void lld_dev_put(struct hinic3_lld_dev *dev);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name_unsafe - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * hinic3_get_lld_dev_by_dev_name_unsafe() is completely analogous to
- * hinic3_get_lld_dev_by_dev_name(), The only difference is that the reference
- * of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that lld_dev will not be freed during the remove process
- * when using lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name_unsafe(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_and_port - get lld device by chip name and port id
- * @param chip_name: chip name
- * @param port_id: port id
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name, u8 port_id);
-
-/**
- * @brief hinic3_get_ppf_lld_dev - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief hinic3_get_ppf_lld_dev_unsafe - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * hinic3_get_ppf_lld_dev_unsafe() is completely analogous to hinic3_get_ppf_lld_dev(),
- * The only difference is that the reference of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that ppf's lld_dev will not be freed during the remove process
- * when using ppf lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev_unsafe(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief uld_dev_hold - get reference to uld_dev
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * Hold reference to uld device to keep it from being freed
- **/
-void uld_dev_hold(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief uld_dev_put - release reference to lld_dev
- * @param dev: lld device
- * @param type: uld service type
- *
- * Release reference to uld device to allow it to be freed
- **/
-void uld_dev_put(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * The value of uld_dev reference increases when uld_dev is obtained. The caller needs
- * to release the reference by calling uld_dev_put.
- **/
-void *hinic3_get_uld_dev(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev_unsafe - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * hinic3_get_uld_dev_unsafe() is completely analogous to hinic3_get_uld_dev(),
- * The only difference is that the reference of uld_dev is not increased when uld_dev is obtained.
- *
- * The caller must ensure that uld_dev will not be freed during the remove process
- * when using uld_dev.
- **/
-void *hinic3_get_uld_dev_unsafe(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_chip_name - get chip name by lld device
- * @param lld_dev: lld device
- * @param chip_name: String for storing the chip name
- * @param max_len: Maximum number of characters to be copied for chip_name
- **/
-int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len);
-
-struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev);
-
-struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev);
-
-bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service);
-
-int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
- bool vf_srv_load);
-
-int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id,
- u16 service, bool en);
-
-bool hinic3_get_vf_load_state(struct pci_dev *pdev);
-
-int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state);
-
-int hinic3_attach_nic(struct hinic3_lld_dev *lld_dev);
-
-void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
-
-int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-const char **hinic3_get_uld_names(void);
-int hinic3_lld_init(void);
-void hinic3_lld_exit(void);
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
index 2fe808b..8cd891e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
@@ -17,12 +17,22 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_hw.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_common.h"
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
+#define CAP_INFO_MAX_LEN 512
+#define DEVICE_VENDOR_MAX_LEN 17
+#define READ_RSFEC_REGISTER_DELAY_TIME_MS 500
+
+struct parse_tlv_info g_page_info = {0};
+struct drv_mag_cmd_get_xsfp_tlv_rsp g_xsfp_tlv_info = {0};
+
static int mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
static int mag_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in,
@@ -78,8 +88,10 @@ int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats)
return -ENOMEM;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
memset(&stats_info, 0, sizeof(stats_info));
stats_info.port_id = hinic3_physical_port_id(hwdev);
@@ -104,6 +116,64 @@ out:
}
EXPORT_SYMBOL(hinic3_get_phy_port_stats);
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats)
+{
+ struct mag_cmd_get_mag_cnt *port_stats = NULL;
+ struct mag_cmd_get_mag_cnt stats_info;
+ u16 out_size = sizeof(*port_stats);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !stats)
+ return -EINVAL;
+
+ port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
+ if (!port_stats)
+ return -ENOMEM;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ memset(&stats_info, 0, sizeof(stats_info));
+ stats_info.port_id = hinic3_physical_port_id(hwdev);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT,
+ &stats_info, sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+ /* 读2遍, 清除误码残留 */
+ msleep(READ_RSFEC_REGISTER_DELAY_TIME_MS);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT, &stats_info,
+ sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+
+ memcpy(stats, &port_stats->mag_csr[MAG_RX_RSFEC_ERR_CW_CNT],
+ sizeof(u32));
+
+out:
+ kfree(port_stats);
+
+ return err;
+}
+EXPORT_SYMBOL(hinic3_get_phy_rsfec_stats);
+
int hinic3_set_port_funcs_state(void *hwdev, bool enable)
{
return 0;
@@ -180,6 +250,8 @@ int hinic3_get_loopback_mode(void *hwdev, u8 *mode, u8 *enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_cfg_loopback_mode(nic_io, MGMT_MSG_CMD_OP_GET, mode,
enable);
@@ -195,6 +267,8 @@ int hinic3_set_loopback_mode(void *hwdev, u8 mode, u8 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) {
nic_err(nic_io->dev_hdl, "Invalid loopback mode %u to set\n",
@@ -218,6 +292,9 @@ int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&led_info, 0, sizeof(led_info));
led_info.function_id = hinic3_global_func_id(hwdev);
@@ -249,6 +326,8 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
memset(&port_msg, 0, sizeof(port_msg));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
port_msg.port_id = hinic3_physical_port_id(hwdev);
@@ -268,9 +347,12 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
port_info->port_type = port_msg.wire_type;
port_info->speed = port_msg.speed;
port_info->fec = port_msg.fec;
+ port_info->lanes = port_msg.lanes;
port_info->supported_mode = port_msg.supported_mode;
port_info->advertised_mode = port_msg.advertised_mode;
-
+ port_info->supported_fec_mode = port_msg.supported_fec_mode;
+ /* switch Gbps to Mbps */
+ port_info->bond_speed = (u32)port_msg.bond_speed * RATE_MBPS_TO_GBPS;
return 0;
}
@@ -306,6 +388,8 @@ int hinic3_set_link_settings(void *hwdev,
memset(&info, 0, sizeof(info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
info.port_id = hinic3_physical_port_id(hwdev);
info.config_bitmap = settings->valid_bitmap;
@@ -335,6 +419,8 @@ int hinic3_get_link_state(void *hwdev, u8 *link_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&get_link, 0, sizeof(get_link));
get_link.port_id = hinic3_physical_port_id(hwdev);
@@ -364,9 +450,10 @@ void hinic3_notify_vf_link_status(struct hinic3_nic_io *nic_io,
if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
link.status = link_status;
link.port_id = hinic3_physical_port_id(nic_io->hwdev);
- err = hinic3_mbox_to_vf(nic_io->hwdev, vf_id, HINIC3_MOD_HILINK,
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
MAG_CMD_GET_LINK_STATUS, &link,
- sizeof(link), &link, &out_size, 0,
+ sizeof(link), &link, &out_size,
HINIC3_CHANNEL_NIC);
if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
@@ -387,6 +474,9 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
u16 i;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
+
nic_io->link_status = link_status;
for (i = 1; i <= nic_io->max_vfs; i++) {
if (!nic_io->vf_infos[HW_VF_ID_TO_OS(i)].link_forced)
@@ -394,6 +484,167 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
}
}
+static char *g_hw_to_char_fec[HILINK_FEC_MAX_TYPE] = {
+ "not set", "rsfec", "basefec",
+ "nofec", "llrsfec"};
+static char *g_hw_to_speed_info[PORT_SPEED_UNKNOWN] = {
+ "not set", "10MB", "100MB", "1GB", "10GB",
+ "25GB", "40GB", "50GB", "100GB", "200GB"};
+static char *g_hw_to_an_state_info[PORT_CFG_AN_OFF + 1] = {
+ "not set", "on", "off"};
+
+struct port_type_table {
+ u32 port_type;
+ char *port_type_name;
+};
+
+static const struct port_type_table port_optical_type_table_s[] = {
+ {LINK_PORT_UNKNOWN, "UNKNOWN"},
+ {LINK_PORT_OPTICAL_MM, "optical_sr"},
+ {LINK_PORT_OPTICAL_SM, "optical_lr"},
+ {LINK_PORT_PAS_COPPER, "copper"},
+ {LINK_PORT_ACC, "ACC"},
+ {LINK_PORT_BASET, "baset"},
+ {LINK_PORT_AOC, "AOC"},
+ {LINK_PORT_ELECTRIC, "electric"},
+ {LINK_PORT_BACKBOARD_INTERFACE, "interface"},
+};
+
+static char *get_port_type_name(u32 type)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(port_optical_type_table_s); i++) {
+ if (type == port_optical_type_table_s[i].port_type)
+ return port_optical_type_table_s[i].port_type_name;
+ }
+ return "UNKNOWN TYPE";
+}
+
+static void get_port_type(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ char **port_type)
+{
+ if (info->port_type <= LINK_PORT_BACKBOARD_INTERFACE)
+ *port_type = get_port_type_name(info->port_type);
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown port type: %u\n",
+ info->port_type);
+}
+
+static int get_port_temperature_power(struct mag_cmd_event_port_info *info,
+ char *str)
+{
+ char cap_info[CAP_INFO_MAX_LEN];
+
+ memset(cap_info, 0, sizeof(cap_info));
+ snprintf(cap_info, CAP_INFO_MAX_LEN, "%s, %s, Temperature: %u", str,
+ info->sfp_type ? "QSFP" : "SFP", info->cable_temp);
+
+ if (info->sfp_type)
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuw %uuW %uuW %uuW",
+ cap_info, info->power[0x0], info->power[0x1],
+ info->power[0x2], info->power[0x3]);
+ else
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuW, tx power: %uuW",
+ cap_info, info->power[0x0], info->power[0x1]);
+
+ return 0;
+}
+
+static void print_cable_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info)
+{
+ char tmp_str[CAP_INFO_MAX_LEN] = {0};
+ char tmp_vendor[DEVICE_VENDOR_MAX_LEN] = {0};
+ char *port_type = "Unknown port type";
+ int i;
+ int err = 0;
+
+ if (info->gpio_insert) {
+ sdk_info(nic_io->dev_hdl, "Cable unpresent\n");
+ return;
+ }
+
+ get_port_type(nic_io, info, &port_type);
+
+ for (i = sizeof(info->vendor_name) - 1; i >= 0; i--) {
+ if (info->vendor_name[i] == ' ')
+ info->vendor_name[i] = '\0';
+ else
+ break;
+ }
+
+ memcpy(tmp_vendor, info->vendor_name, sizeof(info->vendor_name));
+ snprintf(tmp_str, CAP_INFO_MAX_LEN, "Vendor: %s, %s, length: %um, max_speed: %uGbps",
+ tmp_vendor, port_type, info->cable_length, info->max_speed);
+
+ if (info->port_type == LINK_PORT_OPTICAL_MM ||
+ info->port_type == LINK_PORT_AOC) {
+ err = get_port_temperature_power(info, tmp_str);
+ if (err)
+ return;
+ }
+
+ sdk_info(nic_io->dev_hdl, "Cable information: %s\n", tmp_str);
+}
+
+static void print_link_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ enum hinic3_nic_event_type type)
+{
+ char *fec = "None";
+ char *speed = "None";
+ char *an_state = "None";
+
+ if (info->fec < HILINK_FEC_MAX_TYPE)
+ fec = g_hw_to_char_fec[info->fec];
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown fec type: %u\n", info->fec);
+
+ if (info->an_state > PORT_CFG_AN_OFF) {
+ sdk_info(nic_io->dev_hdl, "an_state %u is invalid",
+ info->an_state);
+ return;
+ }
+
+ an_state = g_hw_to_an_state_info[info->an_state];
+
+ if (info->speed >= PORT_SPEED_UNKNOWN) {
+ sdk_info(nic_io->dev_hdl, "speed %u is invalid", info->speed);
+ return;
+ }
+
+ speed = g_hw_to_speed_info[info->speed];
+ sdk_info(nic_io->dev_hdl, "Link information: speed %s, %s, autoneg %s",
+ speed, fec, an_state);
+}
+
+void print_port_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *port_info,
+ enum hinic3_nic_event_type type)
+{
+ print_cable_info(nic_io, port_info);
+
+ print_link_info(nic_io, port_info, type);
+
+ if (type == EVENT_NIC_LINK_UP)
+ return;
+
+ sdk_info(nic_io->dev_hdl, "PMA ctrl: %s, tx %s, rx %s, PMA fifo reg: 0x%x, PMA signal ok reg: 0x%x, RF/LF status reg: 0x%x\n",
+ port_info->pma_ctrl == 1 ? "off" : "on",
+ port_info->tx_enable ? "enable" : "disable",
+ port_info->rx_enable ? "enable" : "disable", port_info->pma_fifo_reg,
+ port_info->pma_signal_ok_reg, port_info->rf_lf);
+ sdk_info(nic_io->dev_hdl, "alos: %u, rx_los: %u, PCS 64 66b reg: 0x%x, PCS link: 0x%x, MAC link: 0x%x PCS_err_cnt: 0x%x\n",
+ port_info->alos, port_info->rx_los, port_info->pcs_64_66b_reg,
+ port_info->pcs_link, port_info->pcs_mac_link,
+ port_info->pcs_err_cnt);
+ sdk_info(nic_io->dev_hdl, "his_link_machine_state = 0x%08x, cur_link_machine_state = 0x%08x\n",
+ port_info->his_link_machine_state,
+ port_info->cur_link_machine_state);
+}
+
static int hinic3_get_vf_link_status_msg_handler(struct hinic3_nic_io *nic_io,
u16 vf_id, void *buf_in,
u16 in_size, void *buf_out,
@@ -433,6 +684,10 @@ static void get_port_info(void *hwdev,
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (hinic3_func_type(hwdev) != TYPE_VF && link_status->status) {
err = hinic3_get_port_info(hwdev, &port_info, HINIC3_CHANNEL_NIC);
if (err) {
@@ -457,8 +712,17 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
struct hinic3_event_info event_info = {0};
struct hinic3_event_link_info *link_info = (void *)event_info.event_data;
struct hinic3_nic_io *nic_io = NULL;
+ struct pci_dev *pdev = NULL;
+
+ /* Ignore link change event */
+ if (hinic3_is_bm_slave_host(hwdev))
+ return;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
link_status = buf_in;
sdk_info(nic_io->dev_hdl, "Link status report received, func_id: %u, status: %u\n",
@@ -475,6 +739,13 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
hinic3_event_callback(hwdev, &event_info);
+ if (nic_io->pcidev_hdl != NULL) {
+ pdev = nic_io->pcidev_hdl;
+ if (pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID) {
+ return;
+ }
+ }
+
if (hinic3_func_type(hwdev) != TYPE_VF) {
hinic3_notify_all_vfs_link_changed(hwdev, link_status->status);
ret_link_status = buf_out;
@@ -483,20 +754,142 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
}
}
+static void port_info_event_printf(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_event_port_info *port_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info;
+ enum hinic3_nic_event_type type;
+
+ if (!hwdev) {
+ pr_err("hwdev is NULL\n");
+ return;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ if (in_size != sizeof(*port_info)) {
+ sdk_info(nic_io->dev_hdl, "Invalid port info message size %u, should be %lu\n",
+ in_size, sizeof(*port_info));
+ return;
+ }
+
+ ((struct mag_cmd_event_port_info *)buf_out)->head.status = 0;
+
+ type = port_info->event_type;
+ if (type < EVENT_NIC_LINK_DOWN || type > EVENT_NIC_LINK_UP) {
+ sdk_info(nic_io->dev_hdl, "Invalid hilink info report, type: %d\n",
+ type);
+ return;
+ }
+
+ print_port_info(nic_io, port_info, type);
+
+ memset(&event_info, 0, sizeof(event_info));
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = type;
+
+ *out_size = sizeof(*port_info);
+
+ hinic3_event_callback(hwdev, &event_info);
+}
+
+void hinic3_notify_vf_bond_status(struct hinic3_nic_io *nic_io,
+ u16 vf_id, u8 bond_status)
+{
+ struct mag_cmd_get_bond_status bond;
+ struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ u16 out_size = sizeof(bond);
+ int err;
+
+ memset(&bond, 0, sizeof(bond));
+ if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
+ bond.status = bond_status;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
+ MAG_CMD_GET_BOND_STATUS, &bond,
+ sizeof(bond), &bond, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF %hu not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return;
+ }
+ if (err || !out_size || bond.head.status)
+ nic_err(nic_io->dev_hdl,
+ "Send bond change event to VF %hu failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err, bond.head.status,
+ out_size);
+ }
+}
+
+void hinic3_notify_all_vfs_bond_changed(void *hwdev, u8 bond_status)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 i;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ nic_io->link_status = bond_status;
+ for (i = 1; i <= nic_io->max_vfs; i++)
+ hinic3_notify_vf_bond_status(nic_io, i, bond_status);
+}
+
+static void bond_status_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_get_bond_status *bond_status = NULL;
+ struct hinic3_event_info event_info = {};
+ struct hinic3_nic_io *nic_io = NULL;
+ struct mag_cmd_get_bond_status *ret_bond_status = NULL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+
+ bond_status = (struct mag_cmd_get_bond_status *)buf_in;
+ sdk_info(nic_io->dev_hdl, "bond status report received, func_id: %u, status: %u\n",
+ hinic3_global_func_id(hwdev), bond_status->status);
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = bond_status->status ?
+ EVENT_NIC_BOND_UP : EVENT_NIC_BOND_DOWN;
+
+ hinic3_event_callback(hwdev, &event_info);
+
+ if (hinic3_func_type(hwdev) != TYPE_VF) {
+ hinic3_notify_all_vfs_bond_changed(hwdev, bond_status->status);
+ ret_bond_status = buf_out;
+ ret_bond_status->head.status = 0;
+ *out_size = sizeof(*ret_bond_status);
+ }
+}
+
static void cable_plug_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct mag_cmd_wire_event *plug_event = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_event_info event_info;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
rt_cmd->mpu_send_sfp_abs = false;
rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
memset(&event_info, 0, sizeof(event_info));
@@ -518,20 +911,54 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
{
struct mag_cmd_get_xsfp_info *sfp_info = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_info)) {
- sdk_err(nic_io->dev_hdl, "Invalid sfp info cmd, length: %u, should be %ld\n",
+ sdk_err(nic_io->dev_hdl, "Invalid sfp info cmd, length: %u, should be %lu\n",
in_size, sizeof(*sfp_info));
return;
}
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
memcpy(&rt_cmd->std_sfp_info, sfp_info,
sizeof(struct mag_cmd_get_xsfp_info));
rt_cmd->mpu_send_sfp_info = true;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+}
+
+static void port_xsfp_tlv_info_event(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_get_xsfp_tlv_rsp *xsfp_tlv_info = buf_in;
+ struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
+ size_t cpy_len = in_size - sizeof(struct mgmt_msg_head) -
+ XSFP_TLV_PRE_INFO_LEN;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL)
+ return;
+
+ if (cpy_len > XSFP_CMIS_INFO_MAX_SIZE) {
+ sdk_err(nic_io->dev_hdl, "invalid cpy_len(%lu)\n", cpy_len);
+ return;
+ }
+ rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ rt_cmd_ext->std_xsfp_tlv_info.port_id = xsfp_tlv_info->port_id;
+ memcpy(&(rt_cmd_ext->std_xsfp_tlv_info.tlv_buf[0]),
+ &(xsfp_tlv_info->tlv_buf[0]), cpy_len);
+ rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = true;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
}
@@ -543,8 +970,10 @@ static void port_sfp_abs_event(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_abs)) {
- sdk_err(nic_io->dev_hdl, "Invalid sfp absent cmd, length: %u, should be %ld\n",
+ sdk_err(nic_io->dev_hdl, "Invalid sfp absent cmd, length: %u, should be %lu\n",
in_size, sizeof(*sfp_abs));
return;
}
@@ -564,9 +993,11 @@ bool hinic3_if_sfp_absent(void *hwdev)
u8 port_id = hinic3_physical_port_id(hwdev);
u16 out_size = sizeof(sfp_abs);
int err;
- bool sfp_abs_status;
+ bool sfp_abs_status = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return true;
memset(&sfp_abs, 0, sizeof(sfp_abs));
rt_cmd = &nic_io->nic_cfg.rt_cmd;
@@ -597,10 +1028,187 @@ bool hinic3_if_sfp_absent(void *hwdev)
return (sfp_abs.abs_status == 0 ? false : true);
}
+int hinic3_get_sfp_tlv_info(void *hwdev, struct drv_mag_cmd_get_xsfp_tlv_rsp
+ *sfp_tlv_info,
+ const struct mag_cmd_get_xsfp_tlv_req
+ *sfp_tlv_info_req)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ u16 out_size = sizeof(*sfp_tlv_info);
+ int err;
+
+ if ((hwdev == NULL) || (sfp_tlv_info == NULL))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL)
+ return -EINVAL;
+
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ if (rt_cmd_ext->mpu_send_xsfp_tlv_info == true) {
+ if (rt_cmd_ext->std_xsfp_tlv_info.head.status != 0) {
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return -EIO;
+ }
+
+ memcpy(sfp_tlv_info, &rt_cmd_ext->std_xsfp_tlv_info,
+ sizeof(*sfp_tlv_info));
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_TLV_INFO,
+ (void *)sfp_tlv_info_req,
+ sizeof(*sfp_tlv_info_req),
+ sfp_tlv_info, &out_size);
+ if ((sfp_tlv_info->head.status != 0) || (err != 0) || (out_size == 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get port%u tlv sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
+ hinic3_physical_port_id(hwdev), err,
+ sfp_tlv_info->head.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_get_page_pos(u32 page_id, u32 content_len, u32 *pos)
+{
+ if (page_id <= QSFP_CMIS_PAGE_03H) {
+ *pos = (page_id * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_11H) {
+ *pos = (QSFP_CMIS_PAGE_04H * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_12H) {
+ *pos = (QSFP_CMIS_PAGE_05H * content_len);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int hinic3_get_page_key_info(struct mgmt_tlv_info *tlv_info,
+ struct parse_tlv_info *page_info, u8 idx,
+ u32 *total_len)
+{
+ u8 *src_addr = NULL;
+ u8 *dst_addr = NULL;
+ u8 *tmp_addr = NULL;
+ u32 page_id = 0;
+ u32 content_len = 0;
+ u32 src_pos = 0;
+ int ret;
+
+ page_id = MGMT_TLV_GET_U32(tlv_info->value);
+ content_len = tlv_info->length - MGMT_TLV_U32_SIZE;
+ if (page_id == QSFP_CMIS_PAGE_00H) {
+ tmp_addr = (u8 *)(tlv_info + 1);
+ page_info->id = *(tmp_addr + MGMT_TLV_U32_SIZE);
+ }
+
+ ret = hinic3_trans_cmis_get_page_pos(page_id, content_len, &src_pos);
+ if (ret != 0)
+ return ret;
+
+ src_addr = page_info->tlv_page_info + src_pos;
+ tmp_addr = (u8 *)(tlv_info + 1);
+ dst_addr = tmp_addr + MGMT_TLV_U32_SIZE;
+ memcpy(src_addr, dst_addr, content_len);
+ if (ret != 0)
+ return ret;
+
+ if (idx < XSFP_CMIS_PARSE_PAGE_NUM)
+ page_info->tlv_page_num[idx] = page_id;
+
+ *total_len += content_len;
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_tlv_info_to_buf(u8 *sfp_tlv_info,
+ struct parse_tlv_info *page_info)
+{
+ struct mgmt_tlv_info *tlv_info = NULL;
+ u8 *tlv_buf = sfp_tlv_info;
+ u8 idx = 0;
+ u32 total_len = 0;
+ int ret = 0;
+ bool need_continue = true;
+
+ if ((sfp_tlv_info == NULL) || (page_info == NULL))
+ return -EIO;
+
+ while (need_continue) {
+ tlv_info = (struct mgmt_tlv_info *)tlv_buf;
+ switch (tlv_info->type) {
+ case MAG_XSFP_TYPE_PAGE:
+ ret = hinic3_get_page_key_info(
+ tlv_info, page_info, idx, &total_len);
+ if (ret != 0) {
+ pr_err("lib_get_page_key_info fail,ret:0x%x.\n",
+ ret);
+ break;
+ }
+ idx++;
+ break;
+
+ case MAG_XSFP_TYPE_WIRE_TYPE:
+ page_info->wire_type =
+ MGMT_TLV_GET_U32(&(tlv_info->value[0]));
+ break;
+
+ case MAG_XSFP_TYPE_END:
+ need_continue = false;
+ break;
+
+ default:
+ break;
+ }
+
+ tlv_buf += (sizeof(struct mgmt_tlv_info) + tlv_info->length);
+ }
+
+ page_info->tlv_page_info_len = total_len;
+
+ return 0;
+}
+
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len)
+{
+ int err = 0;
+ struct mag_cmd_get_xsfp_tlv_req xsfp_tlv_info_req = {0};
+
+ xsfp_tlv_info_req.rsp_buf_len = XSFP_CMIS_INFO_MAX_SIZE;
+ xsfp_tlv_info_req.port_id = hinic3_physical_port_id(hwdev);
+ err = hinic3_get_sfp_tlv_info(hwdev, &g_xsfp_tlv_info,
+ &xsfp_tlv_info_req);
+ if (err != 0)
+ return err;
+
+ err = hinic3_trans_cmis_tlv_info_to_buf(g_xsfp_tlv_info.tlv_buf,
+ &g_page_info);
+ if (err)
+ return -ENOMEM;
+
+ memcpy(data, g_page_info.tlv_page_info, len);
+
+ return (err == 0) ? 0 : -ENOMEM;
+}
+
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
{
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ u8 sfp_info_status = 0;
u16 out_size = sizeof(*sfp_info);
int err;
@@ -608,13 +1216,17 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ sfp_info_status = rt_cmd->std_sfp_info.head.status;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (sfp_info_status != 0) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return -EIO;
+ return (sfp_info_status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ ? HINIC3_MGMT_CMD_UNSUPPORTED : -EIO;
}
memcpy(sfp_info, &rt_cmd->std_sfp_info, sizeof(*sfp_info));
@@ -626,7 +1238,14 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
sfp_info->port_id = hinic3_physical_port_id(hwdev);
err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_INFO, sfp_info,
sizeof(*sfp_info), sfp_info, &out_size);
- if (sfp_info->head.status || err || !out_size) {
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED) {
+ return HINIC3_MGMT_CMD_UNSUPPORTED;
+ }
+
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED) {
+ return -EOPNOTSUPP;
+ }
+ if ((sfp_info->head.status != 0) || (err != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Failed to get port%u sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
hinic3_physical_port_id(hwdev), err,
@@ -642,7 +1261,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
struct mag_cmd_get_xsfp_info sfp_info;
int err;
- if (!hwdev || !data)
+ if (!hwdev || !data || len > PAGE_SIZE)
return -EINVAL;
if (hinic3_if_sfp_absent(hwdev))
@@ -654,7 +1273,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
if (err)
return err;
- memcpy(data, sfp_info.sfp_info, len);
+ memcpy(data, sfp_info.sfp_info, sizeof(sfp_info.sfp_info));
return 0;
}
@@ -664,7 +1283,7 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
- int err;
+ int err = 0;
if (!hwdev || !sfp_type || !sfp_type_ext)
return -EINVAL;
@@ -673,24 +1292,41 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
return -ENXIO;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (rt_cmd->std_sfp_info.head.status == 0) {
+ *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
+ *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ if (rt_cmd->std_sfp_info.head.status != HINIC3_MGMT_CMD_UNSUPPORTED) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
return -EIO;
}
- *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
- *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
- mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return 0;
+ err = HINIC3_MGMT_CMD_UNSUPPORTED; /* cmis */
}
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
- STD_SFP_INFO_MAX_SIZE);
+ if (err == 0) {
+ err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ } else {
+ /* mpu_send_sfp_info is false */
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ }
+
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+
if (err)
return err;
@@ -796,12 +1432,20 @@ int hinic3_set_pf_bw_limit(void *hwdev, u32 bw_limit)
return -EINVAL;
}
- old_bw_limit = nic_io->nic_cfg.pf_bw_limit;
- nic_io->nic_cfg.pf_bw_limit = bw_limit;
+ if (nic_io->direct == HINIC3_NIC_TX) {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_tx_limit;
+ nic_io->nic_cfg.pf_bw_tx_limit = bw_limit;
+ } else {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_rx_limit;
+ nic_io->nic_cfg.pf_bw_rx_limit = bw_limit;
+ }
err = hinic3_update_pf_bw(hwdev);
if (err) {
- nic_io->nic_cfg.pf_bw_limit = old_bw_limit;
+ if (nic_io->direct == HINIC3_NIC_TX)
+ nic_io->nic_cfg.pf_bw_tx_limit = old_bw_limit;
+ else
+ nic_io->nic_cfg.pf_bw_rx_limit = old_bw_limit;
return err;
}
@@ -828,6 +1472,8 @@ int hinic3_pf_mag_mbox_handler(void *hwdev, u16 vf_id,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (index = 0; index < cmd_size; index++) {
handler = &vf_mag_cmd_handler[index];
@@ -848,6 +1494,11 @@ static struct nic_event_handler mag_cmd_handler[] = {
.handler = link_status_event_handler,
},
+ {
+ .cmd = MAG_CMD_EVENT_PORT_INFO,
+ .handler = port_info_event_printf,
+ },
+
{
.cmd = MAG_CMD_WIRE_EVENT,
.handler = cable_plug_event,
@@ -862,6 +1513,16 @@ static struct nic_event_handler mag_cmd_handler[] = {
.cmd = MAG_CMD_GET_XSFP_PRESENT,
.handler = port_sfp_abs_event,
},
+
+ {
+ .cmd = MAG_CMD_GET_BOND_STATUS,
+ .handler = bond_status_event_handler,
+ },
+
+ {
+ .cmd = MAG_CMD_GET_XSFP_TLV_INFO,
+ .handler = port_xsfp_tlv_info_event,
+ },
};
static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
@@ -877,6 +1538,9 @@ static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
for (i = 0; i < size; i++) {
if (cmd == mag_cmd_handler[i].cmd) {
mag_cmd_handler[i].handler(hwdev, buf_in, in_size,
@@ -917,7 +1581,8 @@ static int _mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u32 i, cmd_cnt = ARRAY_LEN(vf_mag_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_mag_cmd_handler[i].cmd) {
cmd_to_pf = true;
@@ -949,3 +1614,124 @@ static int mag_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in,
return _mag_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out,
out_size, channel);
}
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+struct fecparam_value_map {
+ u8 hinic3_fec_offset;
+ u8 hinic3_fec_value;
+ u8 ethtool_fec_value;
+};
+
+static void fecparam_convert(u32 opcode, u8 in_fec_param, u8 *out_fec_param)
+{
+ u8 i;
+ u8 fec_value_table_lenth;
+ struct fecparam_value_map fec_value_table[] = {
+ {PORT_FEC_NOT_SET, BIT(PORT_FEC_NOT_SET), ETHTOOL_FEC_NONE},
+ {PORT_FEC_RSFEC, BIT(PORT_FEC_RSFEC), ETHTOOL_FEC_RS},
+ {PORT_FEC_BASEFEC, BIT(PORT_FEC_BASEFEC), ETHTOOL_FEC_BASER},
+ {PORT_FEC_NOFEC, BIT(PORT_FEC_NOFEC), ETHTOOL_FEC_OFF},
+#ifdef ETHTOOL_FEC_LLRS
+ {PORT_FEC_LLRSFEC, BIT(PORT_FEC_LLRSFEC), ETHTOOL_FEC_LLRS},
+#endif
+ {PORT_FEC_AUTO, BIT(PORT_FEC_AUTO), ETHTOOL_FEC_AUTO}
+ };
+
+ *out_fec_param = 0;
+ fec_value_table_lenth = (u8)(sizeof(fec_value_table) / sizeof(struct fecparam_value_map));
+
+ if (opcode == MAG_CMD_OPCODE_SET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].ethtool_fec_value) != 0)
+ /* The MPU uses the offset to determine the FEC mode. */
+ *out_fec_param =
+ fec_value_table[i].hinic3_fec_offset;
+ }
+ }
+
+ if (opcode == MAG_CMD_OPCODE_GET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].hinic3_fec_value) != 0)
+ *out_fec_param |=
+ fec_value_table[i].ethtool_fec_value;
+ }
+ }
+}
+
+/* When the ethtool is used to set the FEC mode */
+static bool check_fecparam_is_valid(u8 fec_param)
+{
+ if (
+#ifdef ETHTOOL_FEC_LLRS
+ (fec_param == ETHTOOL_FEC_LLRS) ||
+#endif
+ (fec_param == ETHTOOL_FEC_RS) ||
+ (fec_param == ETHTOOL_FEC_BASER) ||
+ (fec_param == ETHTOOL_FEC_OFF)) {
+ return true;
+ }
+ return false;
+}
+
+int set_fecparam(void *hwdev, u8 fecparam)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ u8 advertised_fec = 0;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (check_fecparam_is_valid(fecparam) == false) {
+ nic_err(nic_io->dev_hdl, "fec param is invalid, failed to set fec param\n");
+ return -EINVAL;
+ }
+ fecparam_convert(MAG_CMD_OPCODE_SET, fecparam, &advertised_fec);
+ fec_msg.opcode = MAG_CMD_OPCODE_SET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ fec_msg.advertised_fec = advertised_fec;
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0))
+ return -EINVAL;
+ return 0;
+}
+
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ fec_msg.opcode = MAG_CMD_OPCODE_GET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0))
+ return -EINVAL;
+
+ /* fec_msg.advertised_fec: bit offset,
+ *value is BIT(fec_msg.advertised_fec); fec_msg.supported_fec: value
+ */
+ fecparam_convert(MAG_CMD_OPCODE_GET, BIT(fec_msg.advertised_fec),
+ advertised_fec);
+ fecparam_convert(MAG_CMD_OPCODE_GET, fec_msg.supported_fec,
+ supported_fec);
+ return 0;
+}
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
index 307ad8d..7790ae2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
@@ -20,6 +20,9 @@
#include <linux/debugfs.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#include "hinic3_hw.h"
#include "hinic3_crm.h"
#include "hinic3_mt.h"
@@ -35,8 +38,8 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
#include "hinic3_profile.h"
+#include "hinic3_bond.h"
-/*lint -e806*/
#define DEFAULT_POLL_WEIGHT 64
static unsigned int poll_weight = DEFAULT_POLL_WEIGHT;
module_param(poll_weight, uint, 0444);
@@ -68,7 +71,9 @@ static unsigned char set_link_status_follow = HINIC3_LINK_FOLLOW_STATUS_MAX;
module_param(set_link_status_follow, byte, 0444);
MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=default,1=follow,2=separate,3=unset");
-/*lint +e806*/
+static bool page_pool_enabled = true;
+module_param(page_pool_enabled, bool, 0444);
+MODULE_PARM_DESC(page_pool_enabled, "enable/disable page_pool feature for rxq page management (default enable)");
#define HINIC3_NIC_DEV_WQ_NAME "hinic3_nic_dev_wq"
@@ -80,6 +85,8 @@ MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=
#define HINIC3_SQ_DEPTH 1024
#define HINIC3_RQ_DEPTH 1024
+#define LRO_ENABLE 1
+
enum hinic3_rx_buff_len {
RX_BUFF_VALID_2KB = 2,
RX_BUFF_VALID_4KB = 4,
@@ -88,6 +95,9 @@ enum hinic3_rx_buff_len {
};
#define CONVERT_UNIT 1024
+#define NIC_MAX_PF_NUM 32
+
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
static int hinic3_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr);
@@ -99,6 +109,17 @@ static struct notifier_block hinic3_netdev_notifier = {
.notifier_call = hinic3_netdev_event,
};
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+static const struct udp_tunnel_nic_info hinic3_udp_tunnels = {
+ .set_port = hinic3_udp_tunnel_set_port,
+ .unset_port = hinic3_udp_tunnel_unset_port,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static void hinic3_register_notifier(struct hinic3_nic_dev *nic_dev)
{
int err;
@@ -264,6 +285,11 @@ static void netdev_feature_init(struct net_device *netdev)
netdev->features |= dft_fts | cso_fts | tso_fts | vlan_fts;
netdev->vlan_features |= dft_fts | cso_fts | tso_fts;
+ if (nic_dev->nic_cap.lro_enable == LRO_ENABLE) {
+ netdev->features |= NETIF_F_LRO;
+ netdev->vlan_features |= NETIF_F_LRO;
+ }
+
#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT
hw_features |= get_netdev_hw_features(netdev);
#else
@@ -350,6 +376,7 @@ static int hinic3_init_intr_coalesce(struct hinic3_nic_dev *nic_dev)
static void hinic3_free_intr_coalesce(struct hinic3_nic_dev *nic_dev)
{
kfree(nic_dev->intr_coalesce);
+ nic_dev->intr_coalesce = NULL;
}
static int hinic3_alloc_txrxqs(struct hinic3_nic_dev *nic_dev)
@@ -404,8 +431,85 @@ static void hinic3_sw_deinit(struct hinic3_nic_dev *nic_dev)
HINIC3_CHANNEL_NIC);
hinic3_clear_rss_config(nic_dev);
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+ hinic3_dcb_deinit(nic_dev);
+}
+
+static void hinic3_netdev_mtu_init(struct net_device *netdev)
+{
+ /* MTU range: 384 - 9600 */
+#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
+ netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+
+#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
+ netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+}
+
+static int hinic3_set_default_mac(struct hinic3_nic_dev *nic_dev)
+{
+ struct net_device *netdev = nic_dev->netdev;
+ u8 mac_addr[ETH_ALEN];
+ int err = 0;
+
+ err = hinic3_get_default_mac(nic_dev->hwdev, mac_addr);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev, "Failed to get MAC address\n");
+ return err;
+ }
+
+ ether_addr_copy(netdev->dev_addr, mac_addr);
+
+ if (!is_valid_ether_addr(netdev->dev_addr)) {
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
+ nic_err(&nic_dev->pdev->dev,
+ "Invalid MAC address %pM\n",
+ netdev->dev_addr);
+ return -EIO;
+ }
+
+ nic_info(&nic_dev->pdev->dev,
+ "Invalid MAC address %pM, using random\n",
+ netdev->dev_addr);
+ eth_hw_addr_random(netdev);
+ }
+
+ err = hinic3_set_mac(nic_dev->hwdev, netdev->dev_addr, 0,
+ hinic3_global_func_id(nic_dev->hwdev),
+ HINIC3_CHANNEL_NIC);
+ /* When this is VF driver, we must consider that PF has already set VF
+ * MAC, and we can't consider this condition is error status during
+ * driver probe procedure.
+ */
+ if (err && err != HINIC3_PF_SET_VF_ALREADY) {
+ nic_err(&nic_dev->pdev->dev, "Failed to set default MAC\n");
+ }
+
+ if (err == HINIC3_PF_SET_VF_ALREADY)
+ return 0;
+
+ return err;
+}
+
+static void hinic3_outband_cfg_init(struct hinic3_nic_dev *nic_dev)
+{
+ u16 outband_default_vid = 0;
+ int err = 0;
+
+ if (!nic_dev->nic_cap.outband_vlan_cfg_en)
+ return;
+
+ err = hinic3_get_outband_vlan_cfg(nic_dev->hwdev, &outband_default_vid);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev, "Failed to get_outband_cfg, err: %d\n", err);
+ return;
+ }
+
+ nic_dev->outband_cfg.outband_default_vid = outband_default_vid;
+
+ return;
}
static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
@@ -421,8 +525,6 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
nic_features &= NIC_DRV_DEFAULT_FEATURE;
hinic3_update_nic_feature(nic_dev->hwdev, nic_features);
- sema_init(&nic_dev->port_state_sem, 1);
-
err = hinic3_dcb_init(nic_dev);
if (err) {
nic_err(&nic_dev->pdev->dev, "Failed to init dcb\n");
@@ -434,47 +536,12 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
hinic3_try_to_enable_rss(nic_dev);
- err = hinic3_get_default_mac(nic_dev->hwdev, netdev->dev_addr);
+ err = hinic3_set_default_mac(nic_dev);
if (err) {
- nic_err(&nic_dev->pdev->dev, "Failed to get MAC address\n");
- goto get_mac_err;
- }
-
- if (!is_valid_ether_addr(netdev->dev_addr)) {
- if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- nic_err(&nic_dev->pdev->dev, "Invalid MAC address %pM\n",
- netdev->dev_addr);
- err = -EIO;
- goto err_mac;
- }
-
- nic_info(&nic_dev->pdev->dev, "Invalid MAC address %pM, using random\n",
- netdev->dev_addr);
- eth_hw_addr_random(netdev);
- }
-
- err = hinic3_set_mac(nic_dev->hwdev, netdev->dev_addr, 0,
- hinic3_global_func_id(nic_dev->hwdev),
- HINIC3_CHANNEL_NIC);
- /* When this is VF driver, we must consider that PF has already set VF
- * MAC, and we can't consider this condition is error status during
- * driver probe procedure.
- */
- if (err && err != HINIC3_PF_SET_VF_ALREADY) {
- nic_err(&nic_dev->pdev->dev, "Failed to set default MAC\n");
goto set_mac_err;
}
- /* MTU range: 384 - 9600 */
-#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
- netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
-
-#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
- netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
+ hinic3_netdev_mtu_init(netdev);
err = hinic3_alloc_txrxqs(nic_dev);
if (err) {
@@ -482,6 +549,8 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
goto alloc_qps_err;
}
+ hinic3_outband_cfg_init(nic_dev);
+
return 0;
alloc_qps_err:
@@ -490,8 +559,6 @@ alloc_qps_err:
HINIC3_CHANNEL_NIC);
set_mac_err:
-err_mac:
-get_mac_err:
hinic3_clear_rss_config(nic_dev);
return err;
@@ -690,20 +757,51 @@ static void hinic3_periodic_work_handler(struct work_struct *work)
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
}
+static void hinic3_vport_stats_work_handler(struct work_struct *work)
+{
+ int err;
+ struct hinic3_vport_stats vport_stats = {0};
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_nic_dev *nic_dev = container_of(delay, struct hinic3_nic_dev, vport_stats_work);
+ err = hinic3_get_vport_stats(nic_dev->hwdev, hinic3_global_func_id(nic_dev->hwdev), &vport_stats);
+ if (err)
+ nic_err(&nic_dev->pdev->dev, "Failed to get dropped stats from fw\n");
+ else
+ nic_dev->vport_stats.rx_discard_vport = vport_stats.rx_discard_vport;
+ queue_delayed_work(nic_dev->workq, &nic_dev->vport_stats_work, HZ);
+}
+
+static void free_nic_dev_vram(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)nic_dev->nic_vram, nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ else
+ kfree(nic_dev->nic_vram);
+ nic_dev->nic_vram = NULL;
+}
+
static void free_nic_dev(struct hinic3_nic_dev *nic_dev)
{
hinic3_deinit_nic_prof_adapter(nic_dev);
destroy_workqueue(nic_dev->workq);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+ free_nic_dev_vram(nic_dev);
}
static int setup_nic_dev(struct net_device *netdev,
struct hinic3_lld_dev *lld_dev)
{
struct pci_dev *pdev = lld_dev->pdev;
- struct hinic3_nic_dev *nic_dev;
- char *netdev_name_fmt;
+ struct hinic3_nic_dev *nic_dev = NULL;
+ char *netdev_name_fmt = NULL;
u32 page_num;
+ u16 func_id;
+ int ret;
+ int is_in_kexec = vram_get_kexec_flag();
+ int is_use_vram = get_use_vram_flag();
nic_dev = (struct hinic3_nic_dev *)netdev_priv(netdev);
nic_dev->netdev = netdev;
@@ -718,24 +816,65 @@ static int setup_nic_dev(struct net_device *netdev,
nic_dev->dma_rx_buff_size = RX_BUFF_NUM_PER_PAGE * nic_dev->rx_buff_len;
page_num = nic_dev->dma_rx_buff_size / PAGE_SIZE;
nic_dev->page_order = page_num > 0 ? ilog2(page_num) : 0;
+ nic_dev->page_pool_enabled = page_pool_enabled;
+ nic_dev->outband_cfg.outband_default_vid = 0;
+
+ // value other than 0 indicates hot replace
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ ret = snprintf(nic_dev->nic_vram_name,
+ VRAM_NAME_MAX_LEN,
+ "%s%u", VRAM_NIC_VRAM, func_id);
+ if (ret < 0) {
+ nic_err(&pdev->dev, "NIC vram name snprintf failed, ret:%d.\n",
+ ret);
+ return -EINVAL;
+ }
+
+ nic_dev->nic_vram = (struct hinic3_vram *)hi_vram_kalloc(nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+
+ if (is_in_kexec == 0)
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ else
+ netdev->mtu = nic_dev->nic_vram->vram_mtu;
+ } else {
+ nic_dev->nic_vram = kzalloc(sizeof(struct hinic3_vram),
+ GFP_KERNEL);
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ }
mutex_init(&nic_dev->nic_mutex);
nic_dev->vlan_bitmap = kzalloc(VLAN_BITMAP_SIZE(nic_dev), GFP_KERNEL);
if (!nic_dev->vlan_bitmap) {
nic_err(&pdev->dev, "Failed to allocate vlan bitmap\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto vlan_bitmap_error;
}
nic_dev->workq = create_singlethread_workqueue(HINIC3_NIC_DEV_WQ_NAME);
if (!nic_dev->workq) {
nic_err(&pdev->dev, "Failed to initialize nic workqueue\n");
- kfree(nic_dev->vlan_bitmap);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto create_workq_error;
}
- INIT_DELAYED_WORK(&nic_dev->periodic_work, hinic3_periodic_work_handler);
- INIT_DELAYED_WORK(&nic_dev->rxq_check_work, hinic3_rxq_check_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->periodic_work,
+ hinic3_periodic_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->rxq_check_work,
+ hinic3_rxq_check_work_handler);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ INIT_DELAYED_WORK(&nic_dev->vport_stats_work,
+ hinic3_vport_stats_work_handler);
INIT_LIST_HEAD(&nic_dev->uc_filter_list);
INIT_LIST_HEAD(&nic_dev->mc_filter_list);
@@ -748,10 +887,23 @@ static int setup_nic_dev(struct net_device *netdev,
hinic3_init_nic_prof_adapter(nic_dev);
netdev_name_fmt = hinic3_get_dft_netdev_name_fmt(nic_dev);
- if (netdev_name_fmt)
- strncpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (netdev_name_fmt) {
+ ret = strscpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (ret < 0)
+ goto get_netdev_name_error;
+ }
return 0;
+
+get_netdev_name_error:
+ hinic3_deinit_nic_prof_adapter(nic_dev);
+ destroy_workqueue(nic_dev->workq);
+create_workq_error:
+ kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+vlan_bitmap_error:
+ free_nic_dev_vram(nic_dev);
+ return ret;
}
static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
@@ -790,6 +942,32 @@ static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
return 0;
}
+static void hinic3_bond_init(struct hinic3_nic_dev *nic_dev)
+{
+ u32 bond_id = HINIC3_INVALID_BOND_ID;
+ int err = hinic3_create_bond(nic_dev->hwdev, &bond_id);
+ if (err != 0) {
+ goto bond_init_failed;
+ }
+
+ /* bond id does not change, means this pf is not bond active pf, no log is generated */
+ if (bond_id == HINIC3_INVALID_BOND_ID) {
+ return;
+ }
+
+ err = hinic3_open_close_bond(nic_dev->hwdev, true);
+ if (err != 0) {
+ hinic3_delete_bond(nic_dev->hwdev);
+ goto bond_init_failed;
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Bond %d init success\n", bond_id);
+ return;
+
+bond_init_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond init failed\n");
+}
+
static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
char *uld_dev_name)
{
@@ -820,6 +998,12 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
goto err_out;
}
+ err = hinic3_get_dev_cap(lld_dev->hwdev);
+ if (err != 0) {
+ nic_err(&pdev->dev, "Failed to get dev cap\n");
+ goto err_out;
+ }
+
max_qps = hinic3_func_max_nic_qnum(lld_dev->hwdev);
netdev = alloc_etherdev_mq(sizeof(*nic_dev), max_qps);
if (!netdev) {
@@ -851,23 +1035,35 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
hinic3_assign_netdev_ops(nic_dev);
netdev_feature_init(netdev);
-
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+ netdev->udp_tunnel_nic_info = &hinic3_udp_tunnels;
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
err = hinic3_set_default_hw_feature(nic_dev);
if (err)
goto set_features_err;
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0) {
+ hinic3_bond_init(nic_dev);
+ }
+
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
hinic3_register_notifier(nic_dev);
#endif
- err = register_netdev(netdev);
- if (err) {
- nic_err(&pdev->dev, "Failed to register netdev\n");
- err = -ENOMEM;
- goto netdev_err;
+ if (pdev->subsystem_device != BIFUR_RESOURCE_PF_SSID) {
+ err = register_netdev(netdev);
+ if (err) {
+ nic_err(&pdev->dev, "Failed to register netdev\n");
+ err = -ENOMEM;
+ goto netdev_err;
+ }
}
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->vport_stats_work, HZ);
+
netif_carrier_off(netdev);
*uld_dev = nic_dev;
@@ -900,6 +1096,27 @@ err_out:
return err;
}
+static void hinic3_bond_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ int ret = 0;
+
+ ret = hinic3_open_close_bond(nic_dev->hwdev, false);
+ if (ret != 0) {
+ goto bond_deinit_failed;
+ }
+
+ ret = hinic3_delete_bond(nic_dev->hwdev);
+ if (ret != 0) {
+ goto bond_deinit_failed;
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Bond deinit success\n");
+ return;
+
+bond_deinit_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond deinit failed\n");
+}
+
static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
{
struct hinic3_nic_dev *nic_dev = adapter;
@@ -912,11 +1129,16 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
netdev = nic_dev->netdev;
- unregister_netdev(netdev);
+ if (lld_dev->pdev->subsystem_device != BIFUR_RESOURCE_PF_SSID) {
+ unregister_netdev(netdev);
+ }
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
hinic3_unregister_notifier(nic_dev);
#endif
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ cancel_delayed_work_sync(&nic_dev->vport_stats_work);
+
cancel_delayed_work_sync(&nic_dev->periodic_work);
cancel_delayed_work_sync(&nic_dev->rxq_check_work);
cancel_work_sync(&nic_dev->rx_mode_work);
@@ -924,6 +1146,10 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_flush_rx_flow_rule(nic_dev);
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0) {
+ hinic3_bond_deinit(nic_dev);
+ }
+
hinic3_update_nic_feature(nic_dev->hwdev, 0);
hinic3_set_nic_feature_to_hw(nic_dev->hwdev);
@@ -933,6 +1159,7 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_deinit_nic_prof_adapter(nic_dev);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
free_netdev(netdev);
@@ -981,6 +1208,120 @@ static void hinic3_port_module_event_handler(struct hinic3_nic_dev *nic_dev,
}
}
+bool hinic3_need_proc_link_event(struct hinic3_lld_dev *lld_dev)
+{
+ int ret = 0;
+ u16 func_id;
+ u8 roce_enable = false;
+ bool is_slave_func = false;
+ struct hinic3_hw_bond_infos hw_bond_infos = {0};
+
+ if (!lld_dev)
+ return false;
+
+ /* 非slave设备需要处理link down事件 */
+ ret = hinic3_is_slave_func(lld_dev->hwdev, &is_slave_func);
+ if (ret != 0) {
+ nic_err(&lld_dev->pdev->dev, "NIC get info, lld_dev is null\n");
+ return true;
+ }
+
+ if (!is_slave_func)
+ return true;
+
+ /* 未使能了vroce功能,需处理link down事件 */
+ func_id = hinic3_global_func_id(lld_dev->hwdev);
+ ret = hinic3_get_func_vroce_enable(lld_dev->hwdev, func_id,
+ &roce_enable);
+ if (ret != 0)
+ return true;
+
+ if (!roce_enable)
+ return true;
+
+ /* 未创建bond,需要处理link down事件 */
+ hw_bond_infos.bond_id = HINIC_OVS_BOND_DEFAULT_ID;
+
+ ret = hinic3_get_hw_bond_infos(lld_dev->hwdev, &hw_bond_infos,
+ HINIC3_CHANNEL_COMM);
+ if (ret != 0) {
+ pr_err("[ROCE, ERR] Get chipf bond info failed (%d)\n", ret);
+ return true;
+ }
+
+ if (!hw_bond_infos.valid)
+ return true;
+
+ return false;
+}
+
+bool hinic3_need_proc_bond_event(struct hinic3_lld_dev *lld_dev)
+{
+ return !hinic3_need_proc_link_event(lld_dev);
+}
+
+static void hinic_porc_bond_state_change(struct hinic3_lld_dev *lld_dev,
+ void *adapter,
+ struct hinic3_event_info *event)
+{
+ struct hinic3_nic_dev *nic_dev = adapter;
+
+ if (!nic_dev || !event || !hinic3_support_nic(lld_dev->hwdev, NULL))
+ return;
+
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond down\n");
+ hinic3_link_status_change(nic_dev, false);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond up\n");
+ hinic3_link_status_change(nic_dev, true);
+ break;
+ default:
+ break;
+ }
+}
+
+static void hinic3_outband_cfg_event_handler(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_outband_cfg_info *info)
+{
+ int err = 0;
+ if (!nic_dev || !info || !hinic3_support_nic(nic_dev->hwdev, NULL)) {
+ pr_err("Outband cfg event invalid param\n");
+ return;
+ }
+
+ if (hinic3_func_type(nic_dev->hwdev) != TYPE_VF &&
+ info->func_id >= NIC_MAX_PF_NUM) {
+ err = hinic3_notify_vf_outband_cfg(nic_dev->hwdev,
+ info->func_id,
+ info->outband_default_vid);
+ if (err)
+ nic_err(&nic_dev->pdev->dev, "Outband cfg event notify vf err: %d,"
+ "func_id: 0x%x, vid: 0x%x\n",
+ err, info->func_id, info->outband_default_vid);
+ return;
+ }
+
+ nic_info(&nic_dev->pdev->dev,
+ "Change outband default vid from %u to %u\n",
+ nic_dev->outband_cfg.outband_default_vid,
+ info->outband_default_vid);
+
+ nic_dev->outband_cfg.outband_default_vid = info->outband_default_vid;
+
+ return;
+}
+
static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
struct hinic3_event_info *event)
{
@@ -992,14 +1333,25 @@ static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_DOWN):
+ if (!hinic3_need_proc_link_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc link event\n");
+ return;
+ }
hinic3_link_status_change(nic_dev, false);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_UP):
hinic3_link_status_change(nic_dev, true);
break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ hinic_porc_bond_state_change(lld_dev, adapter, event);
+ break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_PORT_MODULE_EVENT):
hinic3_port_module_event_handler(nic_dev, event);
break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_OUTBAND_CFG):
+ hinic3_outband_cfg_event_handler(nic_dev, (void *)event->event_data);
+ break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_SRIOV_STATE_CHANGE):
sriov_state_change(nic_dev, (void *)event->event_data);
break;
@@ -1059,7 +1411,7 @@ struct hinic3_uld_info g_nic_uld_info = {
.resume = NULL,
.event = nic_event,
.ioctl = nic_ioctl,
-}; /*lint -e766*/
+};
struct hinic3_uld_info *get_nic_uld_info(void)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
index 774193a..7bc9376 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
@@ -4,11 +4,12 @@
#ifndef HINIC3_MT_H
#define HINIC3_MT_H
-#define HINIC3_DRV_NAME "hisdk3"
+#define HINIC3_DRV_NAME "hinic3"
#define HINIC3_CHIP_NAME "hinic"
/* Interrupt at most records, interrupt will be recorded in the FFM */
#define NICTOOL_CMD_TYPE (0x18)
+#define HINIC3_CARD_NAME_MAX_LEN (128)
struct api_cmd_rd {
u32 pf_id;
@@ -110,7 +111,8 @@ enum dbgtool_cmd {
DBGTOOL_CMD_NUM
};
-#define PF_MAX_SIZE (16)
+#define HINIC_PF_MAX_SIZE (16)
+#define HINIC_VF_MAX_SIZE (4096)
#define BUSINFO_LEN (32)
enum module_name {
@@ -132,7 +134,9 @@ enum module_name {
SEND_TO_MIGRATE_DRIVER,
SEND_TO_PPA_DRIVER,
SEND_TO_CUSTOM_DRIVER = SEND_TO_SRV_DRV_BASE + 11,
- SEND_TO_DRIVER_MAX = SEND_TO_SRV_DRV_BASE + 15, /* reserved */
+ SEND_TO_VSOCK_DRIVER = SEND_TO_SRV_DRV_BASE + 14,
+ SEND_TO_BIFUR_DRIVER,
+ SEND_TO_DRIVER_MAX = SEND_TO_SRV_DRV_BASE + 16, /* reserved */
};
enum driver_cmd_type {
@@ -159,7 +163,7 @@ enum driver_cmd_type {
GET_CHIP_FAULT_STATS,
NIC_RSVD1,
NIC_RSVD2,
- NIC_RSVD3,
+ GET_OS_HOT_REPLACE_INFO,
GET_CHIP_ID,
GET_SINGLE_CARD_INFO,
GET_FIRMWARE_ACTIVE_STATUS,
@@ -170,7 +174,7 @@ enum driver_cmd_type {
GET_LOOPBACK_MODE = 32,
SET_LOOPBACK_MODE,
SET_LINK_MODE,
- SET_PF_BW_LIMIT,
+ SET_TX_PF_BW_LIMIT,
GET_PF_BW_LIMIT,
ROCE_CMD,
GET_POLL_WEIGHT,
@@ -188,6 +192,7 @@ enum driver_cmd_type {
GET_NIC_STATS_STRING,
GET_NIC_STATS_INFO,
GET_PF_ID,
+ GET_MBOX_CNT,
NIC_RSVD4,
NIC_RSVD5,
DCB_QOS_INFO,
@@ -204,16 +209,54 @@ enum driver_cmd_type {
RSS_INDIR,
PORT_ID,
+ SET_RX_PF_BW_LIMIT = 0x43,
+
GET_FUNC_CAP = 0x50,
GET_XSFP_PRESENT = 0x51,
GET_XSFP_INFO = 0x52,
DEV_NAME_TEST = 0x53,
+ GET_XSFP_INFO_COMP_CMIS = 0x54,
GET_WIN_STAT = 0x60,
WIN_CSR_READ = 0x61,
WIN_CSR_WRITE = 0x62,
WIN_API_CMD_RD = 0x63,
+ GET_FUSION_Q = 0x64,
+ ROCE_CMD_SET_LDCP_PARAM = 0x70,
+
+ ROCE_CMD_GET_QPC_FROM_CACHE = 0x80,
+ ROCE_CMD_GET_QPC_FROM_HOST = 0x81,
+ ROCE_CMD_GET_CQC_FROM_CACHE = 0x82,
+ ROCE_CMD_GET_CQC_FROM_HOST = 0x83,
+ ROCE_CMD_GET_SRQC_FROM_CACHE = 0x84,
+ ROCE_CMD_GET_SRQC_FROM_HOST = 0x85,
+ ROCE_CMD_GET_MPT_FROM_CACHE = 0x86,
+ ROCE_CMD_GET_MPT_FROM_HOST = 0x87,
+ ROCE_CMD_GET_GID_FROM_CACHE = 0x88,
+ ROCE_CMD_GET_QPC_CQC_PI_CI = 0x89,
+ ROCE_CMD_GET_QP_COUNT = 0x8a,
+ ROCE_CMD_GET_DEV_ALGO = 0x8b,
+
+ ROCE_CMD_START_CAP_PACKET = 0x90,
+ ROCE_CMD_STOP_CAP_PACKET = 0x91,
+ ROCE_CMD_QUERY_CAP_INFO = 0x92,
+ ROCE_CMD_ENABLE_QP_CAP_PACKET = 0x93,
+ ROCE_CMD_DISABLE_QP_CAP_PACKET = 0x94,
+ ROCE_CMD_QUERY_QP_CAP_INFO = 0x95,
+
+ ROCE_CMD_ENABLE_BW_CTRL = 0xa0,
+ ROCE_CMD_DISABLE_BW_CTRL = 0xa1,
+ ROCE_CMD_CHANGE_BW_CTRL_PARAM = 0xa2,
+ ROCE_CMD_QUERY_BW_CTRL_PARAM = 0xa3,
+
+ ROCE_CMD_TIMEOUT_ALARM = 0xb0,
+ ROCE_CMD_PORT_TRAFFIC = 0Xb1,
+ ROCE_CMD_BOND_HASH_TYPE_SET = 0xb2,
+
+ BIFUR_SET_ENABLE = 0xc0,
+ BIFUR_GET_ENABLE = 0xc1,
+
VM_COMPAT_TEST = 0xFF
};
@@ -229,7 +272,8 @@ enum sm_cmd_type {
SM_CTR_RD64,
SM_CTR_RD32_CLEAR,
SM_CTR_RD64_PAIR_CLEAR,
- SM_CTR_RD64_CLEAR
+ SM_CTR_RD64_CLEAR,
+ SM_CTR_RD16_CLEAR,
};
struct cqm_stats {
@@ -317,10 +361,22 @@ struct pf_info {
};
struct card_info {
- struct pf_info pf[PF_MAX_SIZE];
+ struct pf_info pf[HINIC_PF_MAX_SIZE];
u32 pf_num;
};
+struct func_mbox_cnt_info {
+ char bus_info[BUSINFO_LEN];
+ u64 send_cnt;
+ u64 ack_cnt;
+};
+
+struct card_mbox_cnt_info {
+ struct func_mbox_cnt_info func_info[HINIC_PF_MAX_SIZE +
+ HINIC_VF_MAX_SIZE];
+ u32 func_num;
+};
+
struct hinic3_nic_loop_mode {
u32 loop_mode;
u32 loop_ctrl;
@@ -661,6 +717,161 @@ struct get_card_bond_msg_s {
struct bond_all_msg_s all_msg[MAX_BONDING_CNT_PER_CARD];
};
+#define MAX_FUSION_Q_STATS_STR_LEN 16
+#define MAX_FUSION_Q_NUM 256
+struct queue_status_s {
+ pid_t tgid;
+ char status[MAX_FUSION_Q_STATS_STR_LEN];
+};
+struct fusion_q_status_s {
+ u16 queue_num;
+ struct queue_status_s queue[MAX_FUSION_Q_NUM];
+};
+
+struct fusion_q_tx_hw_page {
+ u64 phy_addr;
+ u64 *map_addr;
+};
+
+struct fusion_sq_info {
+ u16 q_id;
+ u16 pi;
+ u16 ci; /* sw_ci */
+ u16 fi; /* hw_ci */
+ u32 q_depth;
+ u16 pi_reverse;
+ u16 wqebb_size;
+ u8 priority;
+ u16 *ci_addr;
+ u64 cla_addr;
+ void *slq_handle;
+ struct fusion_q_tx_hw_page direct_wqe;
+ struct fusion_q_tx_hw_page doorbell;
+ u32 page_idx;
+ u32 glb_sq_id;
+};
+
+struct fusion_q_tx_wqe {
+ u32 data[4];
+};
+
+struct fusion_rq_info {
+ u16 q_id;
+ u16 delta;
+ u16 hw_pi;
+ u16 ci; /* sw_ci */
+ u16 sw_pi;
+ u16 wqebb_size;
+ u16 q_depth;
+ u16 buf_len;
+
+ void *slq_handle;
+ u64 ci_wqe_page_addr;
+ u64 ci_cla_tbl_addr;
+
+ u8 coalesc_timer_cfg;
+ u8 pending_limt;
+ u16 msix_idx;
+ u32 msix_vector;
+};
+
+struct fusion_q_rx_wqe {
+ u32 data[8];
+};
+
+struct fusion_q_rx_cqe {
+ union {
+ struct {
+ unsigned int checksum_err : 16;
+ unsigned int lro_num : 8;
+ unsigned int rsvd1 : 7;
+ unsigned int rx_done : 1;
+ } bs;
+ unsigned int value;
+ } dw0;
+
+ union {
+ struct {
+ unsigned int vlan : 16;
+ unsigned int length : 16;
+ } bs;
+ unsigned int value;
+ } dw1;
+
+ union {
+ struct {
+ unsigned int pkt_types : 12;
+ unsigned int rsvd : 4;
+ unsigned int udp_0 : 1;
+ unsigned int ipv6_ex_add : 1;
+ unsigned int loopback : 1;
+ unsigned int umbcast : 2;
+ unsigned int vlan_offload_en : 1;
+ unsigned int tag_num : 2;
+ unsigned int rss_type : 8;
+ } bs;
+ unsigned int value;
+ } dw2;
+
+ union {
+ struct {
+ unsigned int rss_hash_value;
+ } bs;
+ unsigned int value;
+ } dw3;
+
+ union {
+ struct {
+ unsigned int tx_ts_seq : 16;
+ unsigned int message_1588_offset : 8;
+ unsigned int message_1588_type : 4;
+ unsigned int rsvd : 1;
+ unsigned int if_rx_ts : 1;
+ unsigned int if_tx_ts : 1;
+ unsigned int if_1588 : 1;
+ } bs;
+ unsigned int value;
+ } dw4;
+
+ union {
+ struct {
+ unsigned int ts;
+ } bs;
+ unsigned int value;
+ } dw5;
+
+ union {
+ struct {
+ unsigned int lro_ts;
+ } bs;
+ unsigned int value;
+ } dw6;
+
+ union {
+ struct {
+ unsigned int rsvd0;
+ } bs;
+ unsigned int value;
+ } dw7; /* 16Bytes Align */
+};
+
+struct os_hot_repalce_func_info {
+ char card_name[HINIC3_CARD_NAME_MAX_LEN];
+ int bus_num;
+ int valid;
+ int bdf;
+ int partition;
+ int backup_pf;
+ int pf_idx;
+ int port_id;
+};
+
+#define ALL_CARD_PF_NUM 2048 /* 64 card * 32 pf */
+struct os_hot_replace_info {
+ struct os_hot_repalce_func_info func_infos[ALL_CARD_PF_NUM];
+ u32 func_cnt;
+};
+
int alloc_buff_in(void *hwdev, struct msg_module *nt_msg, u32 in_size, void **buf_in);
int alloc_buff_out(void *hwdev, struct msg_module *nt_msg, u32 out_size, void **buf_out);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
index 81e4030..7cd9e4d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
@@ -15,6 +15,9 @@
#include <linux/ip.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#ifdef HAVE_XDP_SUPPORT
#include <linux/bpf.h>
#endif
@@ -28,6 +31,10 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
+#include "nic_npu_cmd.h"
+
+#include "vram_common.h"
+
#define HINIC3_DEFAULT_RX_CSUM_OFFLOAD 0xFFF
#define HINIC3_LRO_DEFAULT_COAL_PKT_SIZE 32
@@ -47,8 +54,64 @@ static void hinic3_nic_set_rx_mode(struct net_device *netdev)
queue_work(nic_dev->workq, &nic_dev->rx_mode_work);
}
+static void hinic3_free_irq_vram(struct hinic3_nic_dev *nic_dev, struct hinic3_dyna_txrxq_params *in_q_params)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ struct hinic3_dyna_txrxq_params q_params = nic_dev->q_params;
+
+ if (q_params.irq_cfg == NULL)
+ return;
+
+ size = sizeof(struct hinic3_irq) * (q_params.num_qps);
+
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)q_params.irq_cfg, q_params.irq_cfg_vram_name, size);
+ q_params.irq_cfg = NULL;
+ } else {
+ kfree(in_q_params->irq_cfg);
+ in_q_params->irq_cfg = NULL;
+ }
+}
+
+static int hinic3_alloc_irq_vram(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_dyna_txrxq_params *q_params, bool is_up_eth)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ u16 func_id;
+
+ size = sizeof(struct hinic3_irq) * q_params->num_qps;
+
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(q_params->irq_cfg_vram_name,
+ VRAM_NAME_MAX_LEN, "%s%u",
+ VRAM_NIC_IRQ_VRAM, func_id);
+ q_params->irq_cfg = (struct hinic3_irq *)hi_vram_kalloc(
+ q_params->irq_cfg_vram_name, size);
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq vram alloc failed.\n");
+ return -ENOMEM;
+ }
+ /* in order to clear napi stored in vram, irq need to init when eth up */
+ if (is_up_eth) {
+ memset(q_params->irq_cfg, 0, size);
+ }
+ } else {
+ q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq alloc failed.\n");
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_txrxq_params *q_params)
+ struct hinic3_dyna_txrxq_params *q_params,
+ bool is_up_eth)
{
u32 size;
int err;
@@ -70,12 +133,9 @@ static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
goto alloc_rxqs_res_arr_err;
}
- size = sizeof(*q_params->irq_cfg) * q_params->num_qps;
- q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
- if (!q_params->irq_cfg) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to alloc irq resource array\n");
- err = -ENOMEM;
+ err = hinic3_alloc_irq_vram(nic_dev, q_params, is_up_eth);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc irq resource array\n");
goto alloc_irq_cfg_err;
}
@@ -102,8 +162,7 @@ alloc_rxqs_res_err:
q_params->txqs_res);
alloc_txqs_res_err:
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ hinic3_free_irq_vram(nic_dev, q_params);
alloc_irq_cfg_err:
kfree(q_params->rxqs_res);
@@ -119,13 +178,14 @@ alloc_rxqs_res_arr_err:
static void hinic3_free_txrxq_resources(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_txrxq_params *q_params)
{
+ int is_in_kexec = vram_get_kexec_flag();
hinic3_free_rxqs_res(nic_dev, q_params->num_qps, q_params->rq_depth,
q_params->rxqs_res);
hinic3_free_txqs_res(nic_dev, q_params->num_qps, q_params->sq_depth,
q_params->txqs_res);
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ if (is_in_kexec == 0)
+ hinic3_free_irq_vram(nic_dev, q_params);
kfree(q_params->rxqs_res);
q_params->rxqs_res = NULL;
@@ -161,6 +221,7 @@ static int hinic3_configure_txrxqs(struct hinic3_nic_dev *nic_dev,
static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos;
if (!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
@@ -171,12 +232,13 @@ static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
num_cos = hinic3_get_dev_user_cos_num(nic_dev);
hinic3_update_qp_cos_cfg(nic_dev, num_cos);
/* For now, we don't support to change num_cos */
- if (num_cos > nic_dev->cos_config_num_max ||
+ if (num_cos > dcb->cos_config_num_max ||
nic_dev->q_params.num_qps < num_cos) {
nicif_err(nic_dev, drv, netdev, "Invalid num_cos: %u or num_qps: %u, disable DCB\n",
num_cos, nic_dev->q_params.num_qps);
nic_dev->q_params.num_cos = 0;
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
/* if we can't enable rss or get enough num_qps,
* need to sync default configure to hw
*/
@@ -190,11 +252,14 @@ static int hinic3_configure(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
- err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
- if (err) {
- nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
- return err;
+ if (is_in_kexec == 0) {
+ err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
+ return err;
+ }
}
config_dcb_qps_map(nic_dev);
@@ -256,10 +321,11 @@ static void config_dcb_num_qps(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dyna_txrxq_params *q_params,
u16 max_qps)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos = q_params->num_cos;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (!num_cos || num_cos > nic_dev->cos_config_num_max || num_cos > max_qps)
+ if (!num_cos || num_cos > dcb->cos_config_num_max || num_cos > max_qps)
return; /* will disable DCB in config_dcb_qps_map() */
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
@@ -334,57 +400,10 @@ static void hinic3_destroy_num_qps(struct hinic3_nic_dev *nic_dev)
kfree(nic_dev->qps_irq_info);
}
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev)
-{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- err = hinic3_set_port_enable(nic_dev->hwdev, false, HINIC3_CHANNEL_NIC);
- if (!err)
- nic_dev->force_port_disable = true;
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
-{
- int err = 0;
-
- down(&nic_dev->port_state_sem);
-
- nic_dev->force_port_disable = false;
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
- HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- /* Do nothing when force disable
- * Port will disable when call force port disable
- * and should not enable port when in force mode
- */
- if (nic_dev->force_port_disable) {
- up(&nic_dev->port_state_sem);
- return 0;
- }
-
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
+ return hinic3_set_port_enable(nic_dev->hwdev, enable,
HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
}
static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
@@ -401,7 +420,8 @@ static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+ struct hinic3_dyna_txrxq_params *trxq_params,
+ bool is_up_eth)
{
int err;
@@ -416,7 +436,7 @@ static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
return err;
}
- err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params);
+ err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params, is_up_eth);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc txrxq resources\n");
hinic3_free_qps(nic_dev->hwdev, qp_params);
@@ -544,9 +564,53 @@ vport_enable_err:
return err;
}
+static int hinic3_flush_rq_and_check(struct hinic3_nic_dev *nic_dev,
+ u16 glb_func_id)
+{
+ struct hinic3_flush_rq *rq_flush_msg = NULL;
+ struct hinic3_cmd_buf *cmd_buf = NULL;
+ int out_buf_len = sizeof(struct hinic3_flush_rq);
+ u16 rq_id;
+ u64 out_param = 0;
+ int ret;
+
+ cmd_buf = hinic3_alloc_cmd_buf(nic_dev->hwdev);
+ if (!cmd_buf) {
+ nic_err(&nic_dev->pdev->dev, "Failed to allocate cmd buf\n");
+ return -ENOMEM;
+ }
+
+ cmd_buf->size = sizeof(struct hinic3_flush_rq);
+ rq_flush_msg = (struct hinic3_flush_rq *)cmd_buf->buf;
+ rq_flush_msg->dw.bs.func_id = glb_func_id;
+ for (rq_id = 0; rq_id < nic_dev->q_params.num_qps; rq_id++) {
+ rq_flush_msg->dw.bs.rq_id = rq_id;
+ hinic3_cpu_to_be32(rq_flush_msg, out_buf_len);
+ ret = hinic3_cmdq_direct_resp(nic_dev->hwdev, HINIC3_MOD_L2NIC,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ cmd_buf, &out_param, 0,
+ HINIC3_CHANNEL_NIC);
+ if (ret != 0 || out_param != 0) {
+ nic_err(&nic_dev->pdev->dev, "Failed to flush rq, ret:%d, func:%u, rq:%u\n",
+ ret, glb_func_id, rq_id);
+ goto err;
+ }
+ hinic3_be32_to_cpu(rq_flush_msg, out_buf_len);
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Func:%u rq_num:%u flush rq success\n",
+ glb_func_id, nic_dev->q_params.num_qps);
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return 0;
+err:
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return -1;
+}
+
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
{
u16 glb_func_id;
+ int is_in_kexec = vram_get_kexec_flag();
netif_carrier_off(nic_dev->netdev);
netif_tx_disable(nic_dev->netdev);
@@ -559,18 +623,21 @@ void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, 0);
- hinic3_maybe_set_port_state(nic_dev, false);
+ if (is_in_kexec != 0)
+ nicif_info(nic_dev, drv, nic_dev->netdev, "Skip changing mag status!\n");
+ else
+ hinic3_maybe_set_port_state(nic_dev, false);
glb_func_id = hinic3_global_func_id(nic_dev->hwdev);
hinic3_set_vport_enable(nic_dev->hwdev, glb_func_id, false,
HINIC3_CHANNEL_NIC);
hinic3_flush_txqs(nic_dev->netdev);
- /* After set vport disable 100ms,
- * no packets will be send to host
- * FPGA set 2000ms
- */
- msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+ if (is_in_kexec == 0) {
+ msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+ } else {
+ (void)hinic3_flush_rq_and_check(nic_dev, glb_func_id);
+ }
hinic3_flush_qps_res(nic_dev->hwdev);
}
}
@@ -583,11 +650,12 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_qp_params new_qp_params = {0};
struct hinic3_dyna_qp_params cur_qp_params = {0};
int err;
+ bool is_free_resources = false;
hinic3_config_num_qps(nic_dev, trxq_params);
err = hinic3_alloc_channel_resources(nic_dev, &new_qp_params,
- trxq_params);
+ trxq_params, false);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc channel resources\n");
@@ -599,10 +667,19 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
hinic3_close_channel(nic_dev, &cur_qp_params);
hinic3_free_channel_resources(nic_dev, &cur_qp_params,
&nic_dev->q_params);
+ is_free_resources = true;
}
if (nic_dev->num_qp_irq > trxq_params->num_qps)
hinic3_qp_irq_change(nic_dev, trxq_params->num_qps);
+
+ if (is_free_resources) {
+ err = hinic3_alloc_irq_vram(nic_dev, trxq_params, false);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Change chl alloc irq failed\n");
+ goto alloc_irq_err;
+ }
+ }
nic_dev->q_params = *trxq_params;
if (reopen_handler)
@@ -623,7 +700,7 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
vport_up_err:
hinic3_close_channel(nic_dev, &new_qp_params);
-
+alloc_irq_err:
open_channel_err:
hinic3_free_channel_resources(nic_dev, &new_qp_params, trxq_params);
@@ -654,7 +731,7 @@ int hinic3_open(struct net_device *netdev)
}
err = hinic3_alloc_channel_resources(nic_dev, &qp_params,
- &nic_dev->q_params);
+ &nic_dev->q_params, true);
if (err)
goto alloc_channel_res_err;
@@ -693,12 +770,31 @@ setup_qps_err:
return err;
}
+static void hinic3_delete_napi(struct hinic3_nic_dev *nic_dev)
+{
+ u16 q_id;
+ int is_in_kexec = vram_get_kexec_flag();
+ struct hinic3_irq *irq_cfg = NULL;
+
+ if (is_in_kexec == 0 || nic_dev->q_params.irq_cfg == NULL)
+ return;
+
+ for (q_id = 0; q_id < nic_dev->q_params.num_qps; q_id++) {
+ irq_cfg = &(nic_dev->q_params.irq_cfg[q_id]);
+ qp_del_napi(irq_cfg);
+ }
+
+ hinic3_free_irq_vram(nic_dev, &nic_dev->q_params);
+}
+
int hinic3_close(struct net_device *netdev)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic3_dyna_qp_params qp_params = {0};
if (!test_and_clear_bit(HINIC3_INTF_UP, &nic_dev->flags)) {
+ /* delete napi in os hotreplace rollback */
+ hinic3_delete_napi(nic_dev);
nicif_info(nic_dev, drv, netdev, "Netdev already close, do nothing\n");
return 0;
}
@@ -835,6 +931,7 @@ static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb
#define GET_DSCP_PRI_OFFSET 2
static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev, struct sk_buff *skb)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int dscp_cp;
if (skb->protocol == htons(ETH_P_IP))
@@ -842,8 +939,8 @@ static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev, struct sk_buff *skb
else if (skb->protocol == htons(ETH_P_IPV6))
dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
else
- return nic_dev->hw_dcb_cfg.default_cos;
- return nic_dev->hw_dcb_cfg.dscp2cos[dscp_cp];
+ return dcb->hw_dcb_cfg.default_cos;
+ return dcb->hw_dcb_cfg.dscp2cos[dscp_cp];
}
#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY)
@@ -869,6 +966,7 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif /* end of HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK */
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u16 txq;
u8 cos, qp_num;
@@ -889,18 +987,19 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (nic_dev->hw_dcb_cfg.trust == DCB_PCP) {
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP) {
if (skb->vlan_tci)
- cos = nic_dev->hw_dcb_cfg.pcp2cos[skb->vlan_tci >> VLAN_PRIO_SHIFT];
+ cos = dcb->hw_dcb_cfg.pcp2cos[skb->vlan_tci >>
+ VLAN_PRIO_SHIFT];
else
- cos = nic_dev->hw_dcb_cfg.default_cos;
+ cos = dcb->hw_dcb_cfg.default_cos;
} else {
cos = hinic3_get_dscp_up(nic_dev, skb);
}
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cos] ?
- txq % nic_dev->hw_dcb_cfg.cos_qp_num[cos] : 0;
- txq = nic_dev->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
+ qp_num = dcb->hw_dcb_cfg.cos_qp_num[cos] ?
+ txq % dcb->hw_dcb_cfg.cos_qp_num[cos] : 0;
+ txq = dcb->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
}
return txq;
@@ -978,7 +1077,7 @@ static struct net_device_stats *hinic3_get_stats(struct net_device *netdev)
stats->rx_packets = packets;
stats->rx_bytes = bytes;
stats->rx_errors = errors;
- stats->rx_dropped = dropped;
+ stats->rx_dropped = dropped + nic_dev->vport_stats.rx_discard_vport;
#ifndef HAVE_VOID_NDO_GET_STATS64
return stats;
@@ -1025,10 +1124,17 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
u32 mtu = (u32)new_mtu;
int err = 0;
-
+ int is_in_kexec = vram_get_kexec_flag();
#ifdef HAVE_XDP_SUPPORT
u32 xdp_max_mtu;
+#endif
+ if (is_in_kexec != 0) {
+ nicif_info(nic_dev, drv, netdev, "Hotreplace skip change mtu\n");
+ return err;
+ }
+
+#ifdef HAVE_XDP_SUPPORT
if (hinic3_is_xdp_enable(nic_dev)) {
xdp_max_mtu = hinic3_xdp_max_mtu(nic_dev);
if (mtu > xdp_max_mtu) {
@@ -1047,6 +1153,7 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
nicif_info(nic_dev, drv, nic_dev->netdev, "Change mtu from %u to %d\n",
netdev->mtu, new_mtu);
netdev->mtu = mtu;
+ nic_dev->nic_vram->vram_mtu = mtu;
}
return err;
@@ -1080,6 +1187,71 @@ static int hinic3_set_mac_addr(struct net_device *netdev, void *addr)
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+static int hinic3_udp_tunnel_port_config(struct net_device *netdev,
+ struct udp_tunnel_info *ti,
+ u8 action)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u16 func_id = hinic3_global_func_id(nic_dev->hwdev);
+ u16 dst_port;
+ int ret = 0;
+
+ switch (ti->type) {
+ case UDP_TUNNEL_TYPE_VXLAN:
+ dst_port = ntohs(ti->port);
+ ret = hinic3_vlxan_port_config(nic_dev->hwdev, func_id,
+ dst_port, action);
+ if (ret != 0) {
+ nicif_warn(nic_dev, drv, netdev,
+ "Failed to set vxlan port %u to device(%d)\n",
+ dst_port, ret);
+ break;
+ }
+ nicif_info(nic_dev, link, netdev, "Vxlan dst port set to %u\n",
+ action == HINIC3_CMD_OP_ADD ?
+ dst_port : ntohs(VXLAN_OFFLOAD_PORT_LE));
+ break;
+ default:
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to add port, only vxlan dst port is supported\n");
+ ret = -EINVAL;
+ }
+ return ret;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+static void hinic3_udp_tunnel_add(struct net_device *netdev, struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+static void hinic3_udp_tunnel_del(struct net_device *netdev, struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD */
+
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev, __attribute__((unused)) unsigned int table,
+ __attribute__((unused))unsigned int entry, struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev, __attribute__((unused)) unsigned int table,
+ __attribute__((unused)) unsigned int entry, struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static int
hinic3_vlan_rx_add_vid(struct net_device *netdev,
__always_unused __be16 proto,
@@ -1126,7 +1298,7 @@ hinic3_vlan_rx_kill_vid(struct net_device *netdev,
int err = 0;
col = VID_COL(nic_dev, vid);
- line = VID_LINE(nic_dev, vid);
+ line = (int)VID_LINE(nic_dev, vid);
/* In the broadcast scenario, ucode finds the corresponding function
* based on VLAN 0 of vlan table. If we delete VLAN 0, the VLAN function
@@ -1165,14 +1337,12 @@ static int hinic3_vlan_restore(struct net_device *netdev)
return -EFAULT;
rcu_read_lock();
for (i = 0; i < VLAN_N_VID; i++) {
-/* lint -e778 */
#ifdef HAVE_VLAN_FIND_DEV_DEEP_RCU
vlandev =
__vlan_find_dev_deep_rcu(netdev, htons(ETH_P_8021Q), i);
#else
vlandev = __vlan_find_dev_deep(netdev, htons(ETH_P_8021Q), i);
#endif
-/* lint +e778 */
col = VID_COL(nic_dev, i);
line = VID_LINE(nic_dev, i);
if (!vlandev && (vlan_bitmap[line] & (1UL << col)) != 0) {
@@ -1330,12 +1500,17 @@ static int set_feature_vlan_filter(struct hinic3_nic_dev *nic_dev,
return 0;
#ifdef NEED_VLAN_RESTORE
- if (en)
+ if (en) {
err = hinic3_vlan_restore(nic_dev->netdev);
+ if (err) {
+ hinic3_err(nic_dev, drv, "vlan restore failed\n");
+ *failed_features |= vlan_filter_feature;
+ return err;
+ }
+ }
#endif
- if (err == 0)
- err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
+ err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
if (err) {
hinic3_err(nic_dev, drv, "%s rx vlan filter failed\n",
SET_FEATURES_OP_STR(en));
@@ -1429,8 +1604,8 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
struct hinic3_nic_dev *adapter = netdev_priv(netdev);
int err;
- if (is_multicast_ether_addr(mac) || /*lint !e574*/
- vf >= pci_num_vf(adapter->pdev)) /*lint !e574*/
+ if (is_multicast_ether_addr(mac) ||
+ vf >= pci_num_vf(adapter->pdev))
return -EINVAL;
err = hinic3_set_vf_mac(adapter->hwdev, OS_VF_ID_TO_HW(vf), mac);
@@ -1448,7 +1623,6 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
return 0;
}
-/*lint -save -e574 -e734*/
#ifdef IFLA_VF_MAX
static int set_hw_vf_vlan(void *hwdev, u16 cur_vlanprio, int vf,
u16 vlan, u8 qos)
@@ -1670,7 +1844,7 @@ static int hinic3_ndo_set_vf_bw(struct net_device *netdev, int vf,
return -EIO;
/* rate limit cannot be less than 0 and greater than link speed */
- if (max_tx_rate < 0 || max_tx_rate > speeds[port_info.speed]) {
+ if (max_tx_rate < 0 || max_tx_rate > (int)(speeds[port_info.speed])) {
nicif_err(adapter, drv, netdev, "Set vf max tx rate must be in [0 - %u]\n",
speeds[port_info.speed]);
return -EINVAL;
@@ -1719,7 +1893,7 @@ static int hinic3_xdp_setup(struct hinic3_nic_dev *nic_dev,
int max_mtu = hinic3_xdp_max_mtu(nic_dev);
int q_id;
- if (nic_dev->netdev->mtu > max_mtu) {
+ if (nic_dev->netdev->mtu > (u32)max_mtu) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to setup xdp program, the current MTU %d is larger than max allowed MTU %d\n",
nic_dev->netdev->mtu, max_mtu);
@@ -1844,6 +2018,10 @@ static const struct net_device_ops hinic3_netdev_ops = {
.ndo_xdp = hinic3_xdp,
#endif
#endif
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+ .ndo_udp_tunnel_add = hinic3_udp_tunnel_add,
+ .ndo_udp_tunnel_del = hinic3_udp_tunnel_del,
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD */
#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT
};
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
index cc00bdc..1bc6a14 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
@@ -10,6 +10,8 @@
#include "hinic3_common.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
/* ************************ array index define ********************* */
#define ARRAY_INDEX_0 0
@@ -21,6 +23,35 @@
#define ARRAY_INDEX_6 6
#define ARRAY_INDEX_7 7
+#define XSFP_TLV_PRE_INFO_LEN 4
+
+enum hinic3_link_port_type {
+ LINK_PORT_UNKNOWN,
+ LINK_PORT_OPTICAL_MM,
+ LINK_PORT_OPTICAL_SM,
+ LINK_PORT_PAS_COPPER,
+ LINK_PORT_ACC,
+ LINK_PORT_BASET,
+ LINK_PORT_AOC = 0x40,
+ LINK_PORT_ELECTRIC,
+ LINK_PORT_BACKBOARD_INTERFACE,
+};
+
+enum hilink_fibre_subtype {
+ FIBRE_SUBTYPE_SR = 1,
+ FIBRE_SUBTYPE_LR,
+ FIBRE_SUBTYPE_MAX,
+};
+
+enum hilink_fec_type {
+ HILINK_FEC_NOT_SET,
+ HILINK_FEC_RSFEC,
+ HILINK_FEC_BASEFEC,
+ HILINK_FEC_NOFEC,
+ HILINK_FEC_LLRSFE,
+ HILINK_FEC_MAX_TYPE,
+};
+
struct hinic3_sq_attr {
u8 dma_attr_off;
u8 pending_limit;
@@ -58,24 +89,32 @@ struct hinic3_port_routine_cmd {
struct mag_cmd_get_xsfp_present abs;
};
+struct hinic3_port_routine_cmd_extern {
+ bool mpu_send_xsfp_tlv_info;
+
+ struct drv_mag_cmd_get_xsfp_tlv_rsp std_xsfp_tlv_info;
+};
+
struct hinic3_nic_cfg {
- struct semaphore cfg_lock;
+ struct semaphore cfg_lock;
/* Valid when pfc is disable */
- bool pause_set;
- struct nic_pause_config nic_pause;
+ bool pause_set;
+ struct nic_pause_config nic_pause;
- u8 pfc_en;
- u8 pfc_bitmap;
+ u8 pfc_en;
+ u8 pfc_bitmap;
- struct nic_port_info port_info;
+ struct nic_port_info port_info;
/* percentage of pf link bandwidth */
- u32 pf_bw_limit;
- u32 rsvd2;
+ u32 pf_bw_tx_limit;
+ u32 pf_bw_rx_limit;
- struct hinic3_port_routine_cmd rt_cmd;
- struct mutex sfp_mutex; /* mutex used for copy sfp info */
+ struct hinic3_port_routine_cmd rt_cmd;
+ struct hinic3_port_routine_cmd_extern rt_cmd_ext;
+ /* mutex used for copy sfp info */
+ struct mutex sfp_mutex;
};
struct hinic3_nic_io {
@@ -84,7 +123,7 @@ struct hinic3_nic_io {
void *dev_hdl;
u8 link_status;
- u8 rsvd1;
+ u8 direct;
u32 rsvd2;
struct hinic3_io_queue *sq;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
index 2c1b565..525a353 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
@@ -20,10 +20,126 @@
#include "hinic3_nic_io.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_common.h"
#include "hinic3_nic_cfg.h"
+#include "vram_common.h"
+
+int hinic3_delete_bond(void *hwdev)
+{
+ struct hinic3_cmd_delete_bond cmd_delete_bond;
+ u16 out_size = sizeof(cmd_delete_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_delete_bond, 0, sizeof(cmd_delete_bond));
+ cmd_delete_bond.bond_id = HINIC3_INVALID_BOND_ID;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_DELETE,
+ &cmd_delete_bond, sizeof(cmd_delete_bond),
+ &cmd_delete_bond, &out_size);
+ if (err || !out_size || cmd_delete_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to delete bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_delete_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_delete_bond.bond_id != HINIC3_INVALID_BOND_ID) {
+ nic_info(nic_io->dev_hdl, "Delete bond success\n");
+ }
+
+ return 0;
+}
+
+int hinic3_open_close_bond(void *hwdev, u32 bond_en)
+{
+ struct hinic3_cmd_open_close_bond cmd_open_close_bond;
+ u16 out_size = sizeof(cmd_open_close_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_open_close_bond, 0, sizeof(cmd_open_close_bond));
+ cmd_open_close_bond.open_close_bond_info.bond_id = HINIC3_INVALID_BOND_ID;
+ cmd_open_close_bond.open_close_bond_info.open_close_flag = bond_en;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_OPEN_CLOSE,
+ &cmd_open_close_bond, sizeof(cmd_open_close_bond),
+ &cmd_open_close_bond, &out_size);
+ if (err || !out_size || cmd_open_close_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to %s bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ bond_en == true ? "open" : "close", err, cmd_open_close_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_open_close_bond.open_close_bond_info.bond_id != HINIC3_INVALID_BOND_ID) {
+ nic_info(nic_io->dev_hdl, "%s bond success\n", bond_en == true ? "Open" : "Close");
+ }
+
+ return 0;
+}
+
+int hinic3_create_bond(void *hwdev, u32 *bond_id)
+{
+ struct hinic3_cmd_create_bond cmd_create_bond;
+ u16 out_size = sizeof(cmd_create_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_create_bond, 0, sizeof(cmd_create_bond));
+ cmd_create_bond.create_bond_info.default_param_flag = true;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_CREATE,
+ &cmd_create_bond, sizeof(cmd_create_bond),
+ &cmd_create_bond, &out_size);
+ if (err || !out_size || cmd_create_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to create default bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_create_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_create_bond.create_bond_info.bond_id != HINIC3_INVALID_BOND_ID) {
+ *bond_id = cmd_create_bond.create_bond_info.bond_id;
+ nic_info(nic_io->dev_hdl, "Create bond success\n");
+ }
+
+ return 0;
+}
+
int hinic3_set_ci_table(void *hwdev, struct hinic3_sq_attr *attr)
{
struct hinic3_cmd_cons_idx_attr cons_idx_attr;
@@ -37,6 +153,8 @@ int hinic3_set_ci_table(void *hwdev, struct hinic3_sq_attr *attr)
memset(&cons_idx_attr, 0, sizeof(cons_idx_attr));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cons_idx_attr.func_idx = hinic3_global_func_id(hwdev);
@@ -152,6 +270,8 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -183,7 +303,7 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
}
EXPORT_SYMBOL(hinic3_del_mac);
-int hinic3_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
+int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
u16 func_id)
{
struct hinic3_port_mac_update mac_info;
@@ -197,6 +317,8 @@ int hinic3_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -247,6 +369,8 @@ int hinic3_get_default_mac(void *hwdev, u8 *mac_addr)
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
mac_info.func_id = hinic3_global_func_id(hwdev);
@@ -292,6 +416,45 @@ static int hinic3_config_vlan(struct hinic3_nic_io *nic_io, u8 opcode,
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action)
+{
+ struct hinic3_cmd_vxlan_port_info vxlan_port_info;
+ u16 out_size = sizeof(vxlan_port_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ memset(&vxlan_port_info, 0, sizeof(vxlan_port_info));
+ vxlan_port_info.opcode = action;
+ vxlan_port_info.cfg_mode = 0; // other ethtool set
+ vxlan_port_info.func_id = func_id;
+ vxlan_port_info.vxlan_port = port;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+ &vxlan_port_info, sizeof(vxlan_port_info),
+ &vxlan_port_info, &out_size);
+ if (err || !out_size || vxlan_port_info.msg_head.status) {
+ if (vxlan_port_info.msg_head.status == 0x2) {
+ nic_warn(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port because it has already been set by hinicadm\n",
+ action == HINIC3_CMD_OP_ADD ? "add" : "delete");
+ } else {
+ nic_err(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port, err: %d, status: 0x%x, out size: 0x%x\n",
+ action == HINIC3_CMD_OP_ADD ? "add" : "delete",
+ err, vxlan_port_info.msg_head.status, out_size);
+ }
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
{
struct hinic3_nic_io *nic_io = NULL;
@@ -300,6 +463,9 @@ int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan_id, func_id);
}
@@ -311,6 +477,9 @@ int hinic3_del_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_DEL, vlan_id, func_id);
}
@@ -354,6 +523,9 @@ int hinic3_set_dcb_state(void *hwdev, struct hinic3_dcb_state *dcb_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (!memcmp(&nic_io->dcb_state, dcb_state, sizeof(nic_io->dcb_state)))
return 0;
@@ -515,6 +687,8 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_cfg = &nic_io->nic_cfg;
@@ -540,7 +714,6 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
{
- struct hinic3_nic_cfg *nic_cfg = NULL;
struct hinic3_nic_io *nic_io = NULL;
int err = 0;
@@ -548,17 +721,13 @@ int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- nic_cfg = &nic_io->nic_cfg;
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_hw_pause(nic_io, HINIC3_CMD_OP_GET, nic_pause);
if (err)
return err;
- if (nic_cfg->pause_set || !nic_pause->auto_neg) {
- nic_pause->rx_pause = nic_cfg->nic_pause.rx_pause;
- nic_pause->tx_pause = nic_cfg->nic_pause.tx_pause;
- }
-
return 0;
}
@@ -573,6 +742,8 @@ int hinic3_sync_dcb_state(void *hwdev, u8 op_code, u8 state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&dcb_state, 0, sizeof(dcb_state));
@@ -659,44 +830,6 @@ int hinic3_cache_out_qps_res(void *hwdev)
return 0;
}
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats)
-{
- struct hinic3_port_stats *port_stats = NULL;
- struct hinic3_port_stats_info stats_info;
- u16 out_size = sizeof(*port_stats);
- struct hinic3_nic_io *nic_io = NULL;
- int err;
-
- port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
- if (!port_stats)
- return -ENOMEM;
-
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
-
- memset(&stats_info, 0, sizeof(stats_info));
-
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_PORT_STAT,
- &stats_info, sizeof(stats_info),
- port_stats, &out_size);
- if (err || !out_size || port_stats->msg_head.status) {
- nic_err(nic_io->dev_hdl,
- "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
- err, port_stats->msg_head.status, out_size);
- err = -EIO;
- goto out;
- }
-
- memcpy(stats, &port_stats->stats, sizeof(*stats));
-
-out:
- kfree(port_stats);
-
- return err;
-}
-EXPORT_SYMBOL(hinic3_get_fpga_phy_port_stats);
-
int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *stats)
{
struct hinic3_port_stats_info stats_info;
@@ -712,6 +845,8 @@ int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *
memset(&vport_stats, 0, sizeof(vport_stats));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
stats_info.func_id = func_id;
@@ -778,6 +913,8 @@ int hinic3_set_port_mtu(void *hwdev, u16 new_mtu)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (new_mtu < HINIC3_MIN_MTU_SIZE) {
nic_err(nic_io->dev_hdl,
@@ -808,6 +945,9 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&feature_nego, 0, sizeof(feature_nego));
feature_nego.func_id = hinic3_global_func_id(hwdev);
feature_nego.opcode = opcode;
@@ -829,29 +969,21 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return 0;
}
-static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
+static int hinic3_get_bios_pf_bw_tx_limit(void *hwdev, struct hinic3_nic_io *nic_io, u16 func_id, u32 *pf_rate)
{
- struct hinic3_nic_io *nic_io = NULL;
+ int err = 0; // default success
struct nic_cmd_bios_cfg cfg = {{0}};
u16 out_size = sizeof(cfg);
- int err;
- if (!hwdev || !pf_bw_limit)
- return -EINVAL;
-
- if (hinic3_func_type(hwdev) == TYPE_VF || !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
- return 0;
-
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- cfg.bios_cfg.func_id = (u8)hinic3_global_func_id(hwdev);
+ cfg.bios_cfg.func_id = (u8)func_id;
cfg.bios_cfg.func_valid = 1;
- cfg.op_code = 0 | NIC_NVM_DATA_PF_SPEED_LIMIT;
+ cfg.op_code = 0 | NIC_NVM_DATA_PF_TX_SPEED_LIMIT;
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BIOS_CFG, &cfg, sizeof(cfg),
&cfg, &out_size);
if (err || !out_size || cfg.head.status) {
nic_err(nic_io->dev_hdl,
- "Failed to get bios pf bandwidth limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ "Failed to get bios pf bandwidth tx limit, err: %d, status: 0x%x, out size: 0x%x\n",
err, cfg.head.status, out_size);
return -EIO;
}
@@ -861,13 +993,77 @@ static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
nic_warn(nic_io->dev_hdl, "Invalid bios configuration data, signature: 0x%x\n",
cfg.bios_cfg.signature);
- if (cfg.bios_cfg.pf_bw > MAX_LIMIT_BW) {
+ if (cfg.bios_cfg.pf_tx_bw > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
+ cfg.bios_cfg.pf_tx_bw);
+ return -EINVAL;
+ }
+
+ (*pf_rate) = cfg.bios_cfg.pf_tx_bw;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_rx_limit(void *hwdev, struct hinic3_nic_io *nic_io, u16 func_id, u32 *pf_rate)
+{
+ int err = 0; // default success
+ struct nic_rx_rate_bios_cfg rx_bios_conf = {{0}};
+ u16 out_size = sizeof(rx_bios_conf);
+
+ rx_bios_conf.func_id = (u8)func_id;
+ rx_bios_conf.op_code = 0; /* 1-save, 0-read */
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_RX_RATE_CFG, &rx_bios_conf, sizeof(rx_bios_conf),
+ &rx_bios_conf, &out_size);
+ if (rx_bios_conf.msg_head.status == HINIC3_MGMT_CMD_UNSUPPORTED && err == 0) { // Compatible older firmware
+ nic_warn(nic_io->dev_hdl, "Not support get bios pf bandwidth rx limit\n");
+ return 0;
+ } else if (err || !out_size || rx_bios_conf.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get bios pf bandwidth rx limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, rx_bios_conf.msg_head.status, out_size);
+ return -EIO;
+ }
+ if (rx_bios_conf.rx_rate_limit > MAX_LIMIT_BW) {
nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
- cfg.bios_cfg.pf_bw);
+ rx_bios_conf.rx_rate_limit);
return -EINVAL;
}
- *pf_bw_limit = cfg.bios_cfg.pf_bw;
+ (*pf_rate) = rx_bios_conf.rx_rate_limit;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit, u8 direct)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u32 pf_rate = 0;
+ int err = 0;
+ u16 func_id;
+ func_id = hinic3_global_func_id(hwdev);
+
+ if (!hwdev || !pf_bw_limit)
+ return -EINVAL;
+
+ if (hinic3_func_type(hwdev) == TYPE_VF || !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
+ return 0;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (direct == HINIC3_NIC_TX) {
+ err = hinic3_get_bios_pf_bw_tx_limit(hwdev, nic_io, func_id, &pf_rate);
+ } else if (direct == HINIC3_NIC_RX) {
+ err = hinic3_get_bios_pf_bw_rx_limit(hwdev, nic_io, func_id, &pf_rate);
+ }
+
+ if (err != 0)
+ return err;
+
+ if (pf_rate > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n", pf_rate);
+ return -EINVAL;
+ }
+ *pf_bw_limit = pf_rate;
return 0;
}
@@ -876,8 +1072,9 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
{
struct hinic3_cmd_tx_rate_cfg rate_cfg = {{0}};
struct hinic3_nic_io *nic_io = NULL;
+ u32 rate_limit;
u16 out_size = sizeof(rate_cfg);
- u32 pf_rate;
+ u32 pf_rate = 0;
int err;
u32 speed_convert[PORT_SPEED_UNKNOWN] = {
0, 10, 100, 1000, 10000, 25000, 40000, 50000, 100000, 200000
@@ -892,19 +1089,21 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
return -EINVAL;
}
- if (nic_io->nic_cfg.pf_bw_limit == MAX_LIMIT_BW) {
- pf_rate = 0;
- } else {
+ rate_limit = (nic_io->direct == HINIC3_NIC_TX) ?
+ nic_io->nic_cfg.pf_bw_tx_limit : nic_io->nic_cfg.pf_bw_rx_limit;
+
+ if (rate_limit != MAX_LIMIT_BW) {
/* divided by 100 to convert to percentage */
- pf_rate = (speed_convert[speed_level] / 100) * nic_io->nic_cfg.pf_bw_limit;
+ pf_rate = (speed_convert[speed_level] / 100) * rate_limit;
/* bandwidth limit is very small but not unlimit in this case */
- if (pf_rate == 0 && speed_level != PORT_SPEED_NOT_SET)
+ if ((pf_rate == 0) && (speed_level != PORT_SPEED_NOT_SET))
pf_rate = 1;
}
rate_cfg.func_id = hinic3_global_func_id(hwdev);
rate_cfg.min_rate = 0;
rate_cfg.max_rate = pf_rate;
+ rate_cfg.direct = nic_io->direct;
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_MAX_MIN_RATE, &rate_cfg,
sizeof(rate_cfg), &rate_cfg, &out_size);
@@ -927,6 +1126,8 @@ int hinic3_set_nic_feature_to_hw(void *hwdev)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return nic_feature_nego(hwdev, HINIC3_CMD_OP_SET, &nic_io->feature_cap, 1);
}
@@ -936,6 +1137,8 @@ u64 hinic3_get_feature_cap(void *hwdev)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
return nic_io->feature_cap;
}
@@ -945,6 +1148,9 @@ void hinic3_update_nic_feature(void *hwdev, u64 s_feature)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
+
nic_io->feature_cap = s_feature;
nic_info(nic_io->dev_hdl, "Update nic feature to 0x%llx\n", nic_io->feature_cap);
@@ -978,6 +1184,7 @@ static int hinic3_init_nic_io(void *hwdev, void *pcidev_hdl, void *dev_hdl,
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_abs = false;
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_info = false;
+ (*nic_io)->nic_cfg.rt_cmd_ext.mpu_send_xsfp_tlv_info = false;
return 0;
}
@@ -994,11 +1201,14 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
{
struct hinic3_nic_io *nic_io = NULL;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
err = hinic3_init_nic_io(hwdev, pcidev_hdl, dev_hdl, &nic_io);
if (err)
return err;
+ nic_io->rx_buff_len = rx_buff_len;
+
err = hinic3_register_service_adapter(hwdev, nic_io, SERVICE_T_NIC);
if (err) {
nic_err(nic_io->dev_hdl, "Failed to register service adapter\n");
@@ -1011,10 +1221,12 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
goto set_used_state_err;
}
- err = hinic3_init_function_table(nic_io);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to init function table\n");
- goto err_out;
+ if (is_in_kexec == 0) {
+ err = hinic3_init_function_table(nic_io);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to init function table\n");
+ goto err_out;
+ }
}
err = hinic3_get_nic_feature_from_hw(hwdev, &nic_io->feature_cap, 1);
@@ -1025,9 +1237,19 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
sdk_info(dev_hdl, "nic features: 0x%llx\n", nic_io->feature_cap);
- err = hinic3_get_bios_pf_bw_limit(hwdev, &nic_io->nic_cfg.pf_bw_limit);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to get pf bandwidth limit\n");
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_tx_limit,
+ HINIC3_NIC_TX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf tx bandwidth limit\n");
+ goto err_out;
+ }
+
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_rx_limit,
+ HINIC3_NIC_RX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf rx bandwidth limit\n");
goto err_out;
}
@@ -1037,12 +1259,13 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
goto err_out;
}
- nic_io->rx_buff_len = rx_buff_len;
-
return 0;
err_out:
- hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 0, HINIC3_CHANNEL_NIC);
+ if (hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 0,
+ HINIC3_CHANNEL_NIC) != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to set function svc used state\n");
+ }
set_used_state_err:
hinic3_unregister_service_adapter(hwdev, SERVICE_T_NIC);
@@ -1092,6 +1315,8 @@ int hinic3_force_drop_tx_pkt(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&pkt_drop, 0, sizeof(pkt_drop));
pkt_drop.port = hinic3_physical_port_id(hwdev);
@@ -1120,6 +1345,8 @@ int hinic3_set_rx_mode(void *hwdev, u32 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&rx_mode_cfg, 0, sizeof(rx_mode_cfg));
rx_mode_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1148,6 +1375,8 @@ int hinic3_set_rx_vlan_offload(void *hwdev, u8 en)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_cfg, 0, sizeof(vlan_cfg));
vlan_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1176,6 +1405,9 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
if (!nic_io->vf_infos || is_zero_ether_addr(vf_info->drv_mac_addr))
return 0;
@@ -1215,6 +1447,8 @@ static int hinic3_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en,
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_cfg, 0, sizeof(lro_cfg));
lro_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1246,6 +1480,8 @@ static int hinic3_set_rx_lro_timer(void *hwdev, u32 timer_value)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_timer, 0, sizeof(lro_timer));
lro_timer.opcode = HINIC3_CMD_OP_SET;
@@ -1278,6 +1514,8 @@ int hinic3_set_rx_lro_state(void *hwdev, u8 lro_en, u32 lro_timer,
ipv6_en = lro_en ? 1 : 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_info(nic_io->dev_hdl, "Set LRO max coalesce packet size to %uK\n",
lro_max_pkt_len);
@@ -1306,6 +1544,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_filter, 0, sizeof(vlan_filter));
vlan_filter.func_id = hinic3_global_func_id(hwdev);
@@ -1325,7 +1565,6 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
{
- // struct hinic_hwdev *dev = hwdev;
struct nic_cmd_capture_info cap_info = {{0}};
u16 out_size = sizeof(cap_info);
int err;
@@ -1334,7 +1573,6 @@ int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
return -EINVAL;
/* 2 function capture types */
- // cap_info.op_type = UP_UCAPTURE_OP_TYPE_FUNC;
cap_info.is_en_trx = cap_en;
cap_info.func_port = func_id;
@@ -1359,6 +1597,8 @@ int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (tcam_rule->index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to add is invalid\n");
return -EINVAL;
@@ -1394,6 +1634,8 @@ int hinic3_del_tcam_rule(void *hwdev, u32 index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to del is invalid\n");
return -EINVAL;
@@ -1443,6 +1685,8 @@ static int hinic3_mgmt_tcam_block(void *hwdev, u8 alloc_en, u16 *index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&tcam_block_info, 0,
sizeof(struct nic_cmd_ctrl_tcam_block_out));
@@ -1488,6 +1732,8 @@ int hinic3_set_fdir_tcam_rule_filter(void *hwdev, bool enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
port_tcam_cmd.func_id = hinic3_global_func_id(hwdev);
port_tcam_cmd.tcam_enable = (u8)enable;
@@ -1516,6 +1762,9 @@ int hinic3_flush_tcam_rule(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&tcam_flush, 0, sizeof(struct nic_cmd_flush_tcam_rules));
tcam_flush.func_id = hinic3_global_func_id(hwdev);
@@ -1546,6 +1795,9 @@ int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -1588,8 +1840,10 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return -EINVAL;
}
- if (hinic3_func_type(hwdev) == TYPE_VF)
+ if (hinic3_func_type(hwdev) == TYPE_VF) {
+ pr_err("VF are not supported to set link state.\n");
return -EINVAL;
+ }
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
if (!nic_io) {
@@ -1606,3 +1860,35 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return 0;
}
EXPORT_SYMBOL(hinic3_pf_set_vf_link_state);
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid)
+{
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ u16 out_size = sizeof(outband_cfg_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !outband_default_vid)
+ return -EINVAL;
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_OUTBAND_CFG,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size);
+ if (err || !out_size || outband_cfg_info.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get outband cfg, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, outband_cfg_info.msg_head.status, out_size);
+ return -EINVAL;
+ }
+
+ *outband_default_vid = outband_cfg_info.outband_default_vid;
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
index ee0587c..0fe7b9f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
@@ -7,9 +7,9 @@
#include <linux/types.h>
#include <linux/netdevice.h>
-#include "hinic3_mgmt_interface.h"
+#include "nic_mpu_cmd_defs.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#define OS_VF_ID_TO_HW(os_vf_id) ((os_vf_id) + 1)
#define HW_VF_ID_TO_OS(hw_vf_id) ((hw_vf_id) - 1)
@@ -54,6 +54,8 @@
#define MAX_LIMIT_BW 100
+#define HINIC3_INVALID_BOND_ID 0xffffffff
+
enum hinic3_valid_link_settings {
HILINK_LINK_SET_SPEED = 0x1,
HILINK_LINK_SET_AUTONEG = 0x2,
@@ -67,6 +69,11 @@ enum hinic3_link_follow_status {
HINIC3_LINK_FOLLOW_STATUS_MAX,
};
+enum hinic3_nic_pf_direct {
+ HINIC3_NIC_RX = 0,
+ HINIC3_NIC_TX,
+};
+
struct hinic3_link_ksettings {
u32 valid_bitmap;
u8 speed; /* enum nic_speed_level */
@@ -150,8 +157,12 @@ struct nic_port_info {
u8 duplex;
u8 speed;
u8 fec;
+ u8 lanes;
+ u8 rsvd;
u32 supported_mode;
u32 advertised_mode;
+ u32 supported_fec_mode;
+ u32 bond_speed;
};
struct nic_pause_config {
@@ -176,11 +187,17 @@ struct hinic3_rxq_hw {
#define MODULE_TYPE_QSFP28 0x11
#define MODULE_TYPE_QSFP 0x0C
#define MODULE_TYPE_QSFP_PLUS 0x0D
+#define MODULE_TYPE_DSFP 0x1B
+#define MODULE_TYPE_QSFP_CMIS 0x1E
#define TCAM_IP_TYPE_MASK 0x1
#define TCAM_TUNNEL_TYPE_MASK 0xF
#define TCAM_FUNC_ID_MASK 0x7FFF
+int hinic3_delete_bond(void *hwdev);
+int hinic3_open_close_bond(void *hwdev, u32 bond_en);
+int hinic3_create_bond(void *hwdev, u32 *bond_id);
+
int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule);
int hinic3_del_tcam_rule(void *hwdev, u32 index);
@@ -201,7 +218,7 @@ int hinic3_flush_tcam_rule(void *hwdev);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic3_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
+int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
u16 func_id);
/* *
@@ -333,7 +350,7 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr);
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr);
/* *
* @brief hinic3_vf_info_vlanprio - get vf vlan priority
@@ -508,7 +525,14 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table);
*/
int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats);
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats);
+/* *
+ * @brief hinic3_get_phy_rsfec_stats - get rsfec stats
+ * @param hwdev: device pointer to hwdev
+ * @param stats: rsfec(Reed-Solomon Forward Error Correction) stats
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats);
int hinic3_set_port_funcs_state(void *hwdev, bool enable);
@@ -544,6 +568,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl);
void hinic3_clear_vfs_info(void *hwdev);
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id);
+
int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id);
int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
@@ -563,10 +589,13 @@ int hinic3_set_autoneg(void *hwdev, bool enable);
int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext);
int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len);
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len);
bool hinic3_if_sfp_absent(void *hwdev);
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info);
-
+int hinic3_get_sfp_tlv_info(void *hwdev,
+ struct drv_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info,
+ const struct mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req);
/* *
* @brief hinic3_set_nic_feature_to_hw - sync nic feature to hardware
* @param hwdev: device pointer to hwdev
@@ -618,4 +647,18 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level);
int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type);
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+/* *
+ * @brief hinic3_vlxan_port_config - add/del vxlan dst port
+ * @param hwdev: device pointer to hwdev
+ * @param func_id: function id
+ * @param port: vxlan dst port
+ * @param action: add or del, del will set to default value (0x12B5)
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action);
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
index b46cf78..654673f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
@@ -21,7 +21,8 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
/*lint -e806*/
static unsigned char set_vf_link_state;
@@ -116,7 +117,7 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
err = hinic3_set_vlan_ctx(nic_io, glb_func_id, vlan_tag,
NIC_CONFIG_ALL_QUEUE_VLAN_CTX,
opcode == HINIC3_CMD_OP_ADD);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d vlan ctx, err: %d\n",
HW_VF_ID_TO_OS(vf_id), err);
@@ -137,22 +138,21 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
/* this function just be called by hinic3_ndo_set_vf_mac,
* others are not permitted.
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr)
{
- struct vf_data_storage *vf_info;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_info = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
-#ifndef __VMWARE__
+
/* duplicate request, so just return success */
if (ether_addr_equal(vf_info->user_mac_addr, mac_addr))
return 0;
-#else
- if (ether_addr_equal(vf_info->user_mac_addr, mac_addr))
- return 0;
-#endif
ether_addr_copy(vf_info->user_mac_addr, mac_addr);
return 0;
@@ -160,13 +160,15 @@ int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan, qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan = vlan;
@@ -180,17 +182,20 @@ int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_infos = nic_io->vf_infos;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_DEL,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_info(nic_io->dev_hdl, "Remove VLAN %u on VF %d\n",
@@ -205,11 +210,13 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
u16 hinic3_vf_info_vlanprio(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
u16 pf_vlan, vlanprio;
u8 pf_qos;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
pf_vlan = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan;
pf_qos = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos;
@@ -222,9 +229,14 @@ int hinic3_set_vf_link_state(void *hwdev, u16 vf_id, int link)
{
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ struct vf_data_storage *vf_infos = NULL;
u8 link_status = 0;
+ if (!nic_io)
+ return -EINVAL;
+
+ vf_infos = nic_io->vf_infos;
+
switch (link) {
case HINIC3_IFLA_VF_LINK_STATE_AUTO:
vf_infos[HW_VF_ID_TO_OS(vf_id)].link_forced = false;
@@ -264,6 +276,9 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_infos = nic_io->vf_infos;
memset(&spoofchk_cfg, 0, sizeof(spoofchk_cfg));
@@ -288,9 +303,11 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
bool hinic3_vf_info_spoofchk(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].spoofchk;
}
@@ -304,7 +321,7 @@ int hinic3_set_vf_trust(void *hwdev, u16 vf_id, bool trust)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
+ if (!nic_io || vf_id > nic_io->max_vfs)
return -EINVAL;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust = trust;
@@ -317,11 +334,11 @@ bool hinic3_get_vf_trust(void *hwdev, int vf_id)
struct hinic3_nic_io *nic_io = NULL;
if (!hwdev)
- return -EINVAL;
+ return false;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
- return -EINVAL;
+ if (!nic_io || vf_id > nic_io->max_vfs)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust;
}
@@ -339,6 +356,7 @@ static int hinic3_set_vf_tx_rate_max_min(struct hinic3_nic_io *nic_io,
rate_cfg.func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf_id;
rate_cfg.max_rate = max_rate;
rate_cfg.min_rate = min_rate;
+ rate_cfg.direct = HINIC3_NIC_TX;
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
&rate_cfg, sizeof(rate_cfg), &rate_cfg,
@@ -359,13 +377,16 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (!HINIC3_SUPPORT_RATE_LIMIT(hwdev)) {
nic_err(nic_io->dev_hdl, "Current function doesn't support to set vf rate limit\n");
return -EOPNOTSUPP;
}
err = hinic3_set_vf_tx_rate_max_min(nic_io, vf_id, max_rate, min_rate);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].max_rate = max_rate;
@@ -376,12 +397,16 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
void hinic3_get_vf_config(void *hwdev, u16 vf_id, struct ifla_vf_info *ivi)
{
- struct vf_data_storage *vfinfo;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vfinfo = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
vfinfo = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vfinfo)
+ return;
ivi->vf = HW_VF_ID_TO_OS(vf_id);
ether_addr_copy(ivi->mac, vfinfo->user_mac_addr);
@@ -455,12 +480,12 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
nic_io->hwdev, hinic3_vf_event_handler);
- if (err)
+ if (err != 0)
return err;
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
nic_io->hwdev, hinic3_vf_mag_event_handler);
- if (err)
+ if (err != 0)
goto reg_hilink_err;
memset(®ister_info, 0, sizeof(register_info));
@@ -472,6 +497,12 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
®ister_info, &out_size, 0,
HINIC3_CHANNEL_NIC);
if (err || !out_size || register_info.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev)) {
+ nic_warn(nic_io->dev_hdl,
+ "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, register_info.msg_head.status, out_size);
+ return 0;
+ }
nic_err(nic_io->dev_hdl, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
err, register_info.msg_head.status, out_size);
err = -EIO;
@@ -506,18 +537,18 @@ static int pf_init_vf_infos(struct hinic3_nic_io *nic_io)
for (i = 0; i < nic_io->max_vfs; i++) {
err = hinic3_init_vf_infos(nic_io, i);
- if (err)
+ if (err != 0)
goto init_vf_infos_err;
}
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
nic_io->hwdev, hinic3_pf_mbox_handler);
- if (err)
+ if (err != 0)
goto register_pf_mbox_cb_err;
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
nic_io->hwdev, hinic3_pf_mag_mbox_handler);
- if (err)
+ if (err != 0)
goto register_pf_mag_mbox_cb_err;
return 0;
@@ -540,16 +571,16 @@ int hinic3_vf_func_init(struct hinic3_nic_io *nic_io)
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
nic_io->hwdev, hinic3_pf_event_handler);
- if (err)
+ if (err != 0)
return err;
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
nic_io->hwdev, hinic3_pf_mag_event_handler);
- if (err)
+ if (err != 0)
goto register_mgmt_msg_cb_err;
err = pf_init_vf_infos(nic_io);
- if (err)
+ if (err != 0)
goto pf_init_vf_infos_err;
return 0;
@@ -576,9 +607,15 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
&unregister, sizeof(unregister),
&unregister, &out_size, 0,
HINIC3_CHANNEL_NIC);
- if (err || !out_size || unregister.msg_head.status)
- nic_err(nic_io->dev_hdl, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
- err, unregister.msg_head.status, out_size);
+ if (err || !out_size || unregister.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev))
+ nic_info(nic_io->dev_hdl,
+ "vRoCE VF notify PF unsuccessful is allowed");
+ else
+ nic_err(nic_io->dev_hdl,
+ "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, unregister.msg_head.status, out_size);
+ }
hinic3_unregister_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
} else {
@@ -587,6 +624,7 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
hinic3_unregister_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
hinic3_clear_vfs_info(nic_io->hwdev);
kfree(nic_io->vf_infos);
+ nic_io->vf_infos = NULL;
}
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
@@ -595,11 +633,15 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
static void clear_vf_infos(void *hwdev, u16 vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
u16 func_id;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
func_id = hinic3_glb_pf_vf_offset(hwdev) + vf_id;
vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
@@ -628,10 +670,57 @@ static void clear_vf_infos(void *hwdev, u16 vf_id)
void hinic3_clear_vfs_info(void *hwdev)
{
+ u16 i;
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- u16 i;
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
for (i = 0; i < nic_io->max_vfs; i++)
clear_vf_infos(hwdev, OS_VF_ID_TO_HW(i));
}
+
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id)
+{
+ int err = 0;
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ struct vf_data_storage *vf_infos = NULL;
+ u16 out_size = sizeof(outband_cfg_info);
+ u16 vf_id;
+ struct hinic3_nic_io *nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return 0;
+ }
+
+ vf_id = func_id - hinic3_glb_pf_vf_offset(nic_io->hwdev);
+ vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+ if (vf_infos->registered) {
+ outband_cfg_info.func_id = func_id;
+ outband_cfg_info.outband_default_vid = vlan_id;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_L2NIC,
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return 0;
+ }
+ if (err || !out_size || outband_cfg_info.msg_head.status)
+ nic_err(nic_io->dev_hdl,
+ "outband cfg event to VF %d failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err,
+ outband_cfg_info.msg_head.status, out_size);
+ }
+
+ return err;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
index 17d48c4..2878f66 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
@@ -30,6 +30,9 @@ int hinic3_dbg_get_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (q_id >= nic_io->num_qps) {
pr_err("q_id[%u] > num_qps_cfg[%u].\n", q_id, nic_io->num_qps);
return -EINVAL;
@@ -69,6 +72,9 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -82,6 +88,8 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
sq = &nic_io->sq[q_id];
+ if (!sq)
+ return -EINVAL;
sq_info->q_id = q_id;
sq_info->pi = hinic3_get_sq_local_pi(sq);
@@ -112,6 +120,9 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -125,6 +136,8 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
rq = &nic_io->rq[q_id];
+ if (!rq)
+ return -EINVAL;
rq_info->q_id = q_id;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
index 800fa73..137098b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
@@ -15,9 +15,10 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
#include "hinic3_dcb.h"
+#include "vram_common.h"
#define HINIC3_NIC_DRV_NAME "hinic3"
-#define HINIC3_NIC_DRV_VERSION "15.17.1.1"
+#define HINIC3_NIC_DRV_VERSION "17.7.8.1"
#define HINIC3_FUNC_IS_VF(hwdev) (hinic3_func_type(hwdev) == TYPE_VF)
@@ -25,6 +26,10 @@
#define HINIC3_MODERATONE_DELAY HZ
#define LP_PKT_CNT 64
+#define LP_PKT_LEN 60
+
+#define NAPI_IS_REGIN 1
+#define NAPI_NOT_REGIN 0
enum hinic3_flags {
HINIC3_INTF_UP,
@@ -91,6 +96,8 @@ struct hinic3_irq {
u16 rsvd1;
u32 irq_id; /* The IRQ number from OS */
+ u32 napi_reign;
+
char irq_name[IFNAMSIZ + 16];
struct napi_struct napi;
cpumask_t affinity_mask;
@@ -123,6 +130,41 @@ struct hinic3_dyna_txrxq_params {
struct hinic3_dyna_txq_res *txqs_res;
struct hinic3_dyna_rxq_res *rxqs_res;
struct hinic3_irq *irq_cfg;
+ char irq_cfg_vram_name[VRAM_NAME_MAX_LEN];
+};
+
+struct hinic3_flush_rq {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 lb_proc : 1;
+ u32 rsvd : 10;
+ u32 rq_id : 8;
+ u32 func_id : 13;
+#else
+ u32 func_id : 13;
+ u32 rq_id : 8;
+ u32 rsvd : 10;
+ u32 lb_proc : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd2 : 2;
+ u32 src_chnl : 12;
+ u32 pkt_len : 18;
+#else
+ u32 pkt_len : 18;
+ u32 src_chnl : 12;
+ u32 rsvd2 : 2;
+#endif
+ } bs;
+ u32 value;
+ } lb_info0; /* loop back information, used by uCode */
};
#define HINIC3_NIC_STATS_INC(nic_dev, field) \
@@ -147,6 +189,10 @@ struct hinic3_nic_stats {
#endif
};
+struct hinic3_nic_vport_stats {
+ u64 rx_discard_vport;
+};
+
#define HINIC3_TCAM_DYNAMIC_BLOCK_SIZE 16
#define HINIC3_MAX_TCAM_FILTERS 512
@@ -185,104 +231,123 @@ struct hinic3_tcam_info {
struct hinic3_tcam_dynamic_block_info tcam_dynamic_info;
};
+struct hinic3_dcb {
+ u8 cos_config_num_max;
+ u8 func_dft_cos_bitmap;
+ /* used to tool validity check */
+ u16 port_dft_cos_bitmap;
+
+ struct hinic3_dcb_config hw_dcb_cfg;
+ struct hinic3_dcb_config wanted_dcb_cfg;
+ unsigned long dcb_flags;
+};
+
+struct hinic3_vram {
+ u32 vram_mtu;
+ u16 vram_num_qps;
+ unsigned long flags;
+};
+
+struct hinic3_outband_cfg {
+ u16 outband_default_vid;
+ u16 rsvd;
+};
+
struct hinic3_nic_dev {
- struct pci_dev *pdev;
- struct net_device *netdev;
- struct hinic3_lld_dev *lld_dev;
- void *hwdev;
+ struct pci_dev *pdev;
+ struct net_device *netdev;
+ struct hinic3_lld_dev *lld_dev;
+ void *hwdev;
- int poll_weight;
- u32 rsvd1;
- unsigned long *vlan_bitmap;
+ int poll_weight;
+ u32 rsvd1;
+ unsigned long *vlan_bitmap;
- u16 max_qps;
+ u16 max_qps;
- u32 msg_enable;
- unsigned long flags;
+ u32 msg_enable;
+ unsigned long flags;
- u32 lro_replenish_thld;
- u32 dma_rx_buff_size;
- u16 rx_buff_len;
- u32 page_order;
+ u32 lro_replenish_thld;
+ u32 dma_rx_buff_size;
+ u16 rx_buff_len;
+ u32 page_order;
+ bool page_pool_enabled;
/* Rss related varibles */
- u8 rss_hash_engine;
- struct nic_rss_type rss_type;
- u8 *rss_hkey;
+ u8 rss_hash_engine;
+ struct nic_rss_type rss_type;
+ u8 *rss_hkey;
/* hkey in big endian */
- u32 *rss_hkey_be;
- u32 *rss_indir;
+ u32 *rss_hkey_be;
+ u32 *rss_indir;
- u8 cos_config_num_max;
- u8 func_dft_cos_bitmap;
- u16 port_dft_cos_bitmap; /* used to tool validity check */
+ struct hinic3_dcb *dcb;
+ char dcb_name[VRAM_NAME_MAX_LEN];
- struct hinic3_dcb_config hw_dcb_cfg;
- struct hinic3_dcb_config wanted_dcb_cfg;
- struct hinic3_dcb_config dcb_cfg;
- unsigned long dcb_flags;
- int disable_port_cnt;
- /* lock for disable or enable traffic flow */
- struct semaphore dcb_sem;
+ struct hinic3_vram *nic_vram;
+ char nic_vram_name[VRAM_NAME_MAX_LEN];
- struct hinic3_intr_coal_info *intr_coalesce;
- unsigned long last_moder_jiffies;
- u32 adaptive_rx_coal;
- u8 intr_coal_set_flag;
+ int disable_port_cnt;
+
+ struct hinic3_intr_coal_info *intr_coalesce;
+ unsigned long last_moder_jiffies;
+ u32 adaptive_rx_coal;
+ u8 intr_coal_set_flag;
#ifndef HAVE_NETDEV_STATS_IN_NETDEV
- struct net_device_stats net_stats;
+ struct net_device_stats net_stats;
#endif
- struct hinic3_nic_stats stats;
+ struct hinic3_nic_stats stats;
+ struct hinic3_nic_vport_stats vport_stats;
/* lock for nic resource */
- struct mutex nic_mutex;
- bool force_port_disable;
- struct semaphore port_state_sem;
- u8 link_status;
+ struct mutex nic_mutex;
+ u8 link_status;
- struct nic_service_cap nic_cap;
+ struct nic_service_cap nic_cap;
- struct hinic3_txq *txqs;
- struct hinic3_rxq *rxqs;
+ struct hinic3_txq *txqs;
+ struct hinic3_rxq *rxqs;
struct hinic3_dyna_txrxq_params q_params;
- u16 num_qp_irq;
- struct irq_info *qps_irq_info;
+ u16 num_qp_irq;
+ struct irq_info *qps_irq_info;
- struct workqueue_struct *workq;
+ struct workqueue_struct *workq;
- struct work_struct rx_mode_work;
- struct delayed_work moderation_task;
+ struct work_struct rx_mode_work;
+ struct delayed_work moderation_task;
- struct list_head uc_filter_list;
- struct list_head mc_filter_list;
- unsigned long rx_mod_state;
- int netdev_uc_cnt;
- int netdev_mc_cnt;
+ struct list_head uc_filter_list;
+ struct list_head mc_filter_list;
+ unsigned long rx_mod_state;
+ int netdev_uc_cnt;
+ int netdev_mc_cnt;
- int lb_test_rx_idx;
- int lb_pkt_len;
- u8 *lb_test_rx_buf;
+ int lb_test_rx_idx;
+ int lb_pkt_len;
+ u8 *lb_test_rx_buf;
- struct hinic3_tcam_info tcam;
- struct hinic3_rx_flow_rule rx_flow_rule;
+ struct hinic3_tcam_info tcam;
+ struct hinic3_rx_flow_rule rx_flow_rule;
#ifdef HAVE_XDP_SUPPORT
- struct bpf_prog *xdp_prog;
+ struct bpf_prog *xdp_prog;
#endif
- struct delayed_work periodic_work;
+ struct delayed_work periodic_work;
/* reference to enum hinic3_event_work_flags */
- unsigned long event_flag;
-
- struct hinic3_nic_prof_attr *prof_attr;
- struct hinic3_prof_adapter *prof_adap;
- u64 rsvd8[7];
- u32 rsvd9;
- u32 rxq_get_err_times;
- struct delayed_work rxq_check_work;
+ unsigned long event_flag;
+
+ struct hinic3_nic_prof_attr *prof_attr;
+ struct hinic3_prof_adapter *prof_adap;
+ u64 rsvd8[7];
+ struct hinic3_outband_cfg outband_cfg;
+ u32 rxq_get_err_times;
+ struct delayed_work rxq_check_work;
+ struct delayed_work vport_stats_work;
};
#define hinic_msg(level, nic_dev, msglvl, format, arg...) \
@@ -309,7 +374,7 @@ struct hinic3_uld_info *get_nic_uld_info(void);
u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev);
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
int hinic3_open(struct net_device *netdev);
@@ -328,6 +393,8 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev);
void hinic3_qps_irq_deinit(struct hinic3_nic_dev *nic_dev);
+void qp_del_napi(struct hinic3_irq *irq_cfg);
+
void hinic3_set_netdev_ops(struct hinic3_nic_dev *nic_dev);
bool hinic3_is_netdev_ops_match(const struct net_device *netdev);
@@ -345,10 +412,6 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
int hinic3_get_sset_count(struct net_device *netdev, int sset);
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev);
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
#ifdef ETHTOOL_GLINKSETTINGS
@@ -383,5 +446,17 @@ bool hinic3_is_xdp_enable(struct hinic3_nic_dev *nic_dev);
int hinic3_xdp_max_mtu(struct hinic3_nic_dev *nic_dev);
#endif
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+int set_fecparam(void *hwdev, u8 fecparam);
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec);
+#endif
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
index 57cf07c..6cc294e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
@@ -21,11 +21,12 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
{
- struct vf_data_storage *vf_info;
+ struct vf_data_storage *vf_info = NULL;
u16 func_id;
int err = 0;
@@ -38,7 +39,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
vf_info->pf_vlan, func_id,
HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d MAC\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -51,7 +52,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD,
vf_info->pf_vlan, vf_info->pf_qos,
vf_id);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to add VF %d VLAN_QOS\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -62,7 +63,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_vf_tx_rate(nic_io->hwdev, vf_id,
vf_info->max_rate,
vf_info->min_rate);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d max rate %u, min rate %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->max_rate,
vf_info->min_rate);
@@ -84,7 +85,7 @@ static int register_vf_msg_handler(struct hinic3_nic_io *nic_io, u16 vf_id)
}
err = hinic3_init_vf_config(nic_io, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].registered = true;
@@ -137,6 +138,9 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
int err;
+ if (!vf_info)
+ return -EINVAL;
+
if (register_vf->op_register) {
vf_info->support_extra_feature = register_vf->support_extra_feature;
err = register_vf_msg_handler(nic_io, vf_id);
@@ -145,7 +149,7 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
vf_info->support_extra_feature = 0;
}
- if (err)
+ if (err != 0)
register_info->msg_head.status = EFAULT;
*out_size = sizeof(*register_info);
@@ -157,6 +161,9 @@ void hinic3_unregister_vf(struct hinic3_nic_io *nic_io, u16 vf_id)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vf_info)
+ return;
+
unregister_vf_msg_handler(nic_io, vf_id);
vf_info->support_extra_feature = 0;
}
@@ -181,14 +188,21 @@ static int hinic3_get_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
void *buf_out, u16 *out_size)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf);
+ struct hinic3_port_mac_set *mac_in =
+ (struct hinic3_port_mac_set *)buf_in;
struct hinic3_port_mac_set *mac_info = buf_out;
int err;
- if (HINIC3_SUPPORT_VF_MAC(nic_io->hwdev)) {
+ if (!mac_info || !vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
+ if (HINIC3_SUPPORT_VF_MAC(nic_io->hwdev) != 0) {
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_GET_MAC, buf_in,
in_size, buf_out, out_size);
- if (!err) {
+ if (err == 0) {
if (is_zero_ether_addr(mac_info->mac))
ether_addr_copy(mac_info->mac, vf_info->drv_mac_addr);
}
@@ -211,6 +225,11 @@ static int hinic3_set_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -247,6 +266,11 @@ static int hinic3_del_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -283,12 +307,15 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
struct hinic3_port_mac_update *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
if (!is_valid_ether_addr(mac_in->new_mac)) {
nic_err(nic_io->dev_hdl, "Update VF MAC is invalid.\n");
return -EINVAL;
}
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
-#ifndef __VMWARE__
if (vf_info->use_specified_mac && !vf_info->trust) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
HW_VF_ID_TO_OS(vf));
@@ -296,17 +323,7 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
*out_size = sizeof(*mac_out);
return 0;
}
-#else
- err = hinic_config_vf_request(nic_io->hwdev->pcidev_hdl,
- HW_VF_ID_TO_OS(vf),
- HINIC_CFG_VF_MAC_CHANGED,
- (void *)mac_in->new_mac);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to config VF %d MAC request, err: %d\n",
- HW_VF_ID_TO_OS(vf), err);
- return err;
- }
-#endif
+
mac_in->vlan_id = vf_info->pf_vlan;
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_UPDATE_MAC,
buf_in, in_size, buf_out, out_size);
@@ -362,7 +379,8 @@ static int _l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u32 i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_cmd_handler[i].cmd)
cmd_to_pf = true;
@@ -404,6 +422,8 @@ int hinic3_pf_mbox_handler(void *hwdev,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (index = 0; index < cmd_size; index++) {
if (cmd == vf_cmd_handler[index].cmd)
@@ -460,10 +480,14 @@ void hinic3_notify_dcb_state_event(struct hinic3_nic_io *nic_io,
static void dcb_state_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- struct hinic3_cmd_vf_dcb_state *vf_dcb;
- struct hinic3_nic_io *nic_io;
+ struct hinic3_cmd_vf_dcb_state *vf_dcb = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
vf_dcb = buf_in;
if (!vf_dcb)
@@ -479,9 +503,13 @@ static void tx_pause_excp_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*excp_info)) {
- nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
+ nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %lu\n",
in_size, sizeof(*excp_info));
return;
}
@@ -501,6 +529,10 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_event_info event_info = {0};
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*active_info)) {
nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
@@ -515,6 +547,36 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
hinic3_event_callback(nic_io->hwdev, &event_info);
}
+static void outband_vlan_cfg_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out,
+ u16 *out_size)
+{
+ struct hinic3_outband_cfg_info *outband_cfg_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info = {0};
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ nic_info(nic_io->dev_hdl, "outband vlan cfg event received\n");
+
+ if (in_size != sizeof(*outband_cfg_info)) {
+ nic_err(nic_io->dev_hdl, "outband cfg info invalid in_size: %u, should be %lu\n",
+ in_size, sizeof(*outband_cfg_info));
+ return;
+ }
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = EVENT_NIC_OUTBAND_CFG;
+ memcpy((void *)event_info.event_data,
+ outband_cfg_info, sizeof(*outband_cfg_info));
+
+ hinic3_event_callback(nic_io->hwdev, &event_info);
+}
+
static const struct nic_event_handler nic_cmd_handler[] = {
{
.cmd = HINIC3_NIC_CMD_VF_COS,
@@ -529,6 +591,11 @@ static const struct nic_event_handler nic_cmd_handler[] = {
.cmd = HINIC3_NIC_CMD_BOND_ACTIVE_NOTICE,
.handler = bond_active_event_handler,
},
+
+ {
+ .cmd = HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ .handler = outband_vlan_cfg_event_handler,
+ },
};
static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
@@ -543,6 +610,8 @@ static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (i = 0; i < size; i++) {
if (cmd == nic_cmd_handler[i].cmd) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
index 22670ff..a9768b7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
@@ -16,7 +16,8 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_nic_io.h"
#define HINIC3_DEAULT_TX_CI_PENDING_LIMIT 1
@@ -34,7 +35,7 @@ MODULE_PARM_DESC(tx_coalescing_time, "TX CI coalescing parameter coalescing_time
static unsigned char rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
module_param(rq_wqe_type, byte, 0444);
-MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 0-8Bytes, 1-16Bytes, 2-32Bytes (default=2)");
+MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 1-16Bytes, 2-32Bytes (default=2)");
/*lint +e806*/
static u32 tx_drop_thd_on = HINIC3_DEAULT_DROP_THD_ON;
@@ -45,7 +46,7 @@ static u32 tx_drop_thd_off = HINIC3_DEAULT_DROP_THD_OFF;
module_param(tx_drop_thd_off, uint, 0644);
MODULE_PARM_DESC(tx_drop_thd_off, "TX parameter drop_thd_off (default=0)");
/* performance: ci addr RTE_CACHE_SIZE(64B) alignment */
-#define HINIC3_CI_Q_ADDR_SIZE (64)
+#define HINIC3_CI_Q_ADDR_SIZE (64U)
#define CI_TABLE_SIZE(num_qps, pg_sz) \
(ALIGN((num_qps) * HINIC3_CI_Q_ADDR_SIZE, pg_sz))
@@ -350,6 +351,13 @@ static int hinic3_create_rq(struct hinic3_nic_io *nic_io, struct hinic3_io_queue
{
int err;
+ /* rq_wqe_type Only support type 1-16Bytes, 2-32Bytes */
+ if (rq_wqe_type != HINIC3_NORMAL_RQ_WQE && rq_wqe_type != HINIC3_EXTEND_RQ_WQE) {
+ sdk_warn(nic_io->dev_hdl, "Module Parameter rq_wqe_type value %d is out of range: [%d, %d].",
+ rq_wqe_type, HINIC3_NORMAL_RQ_WQE, HINIC3_EXTEND_RQ_WQE);
+ rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
+ }
+
rq->wqe_type = rq_wqe_type;
rq->q_id = q_id;
rq->msix_entry_idx = rq_msix_idx;
@@ -1044,8 +1052,8 @@ static int clean_queue_offload_ctxt(struct hinic3_nic_io *nic_io,
static int clean_qp_offload_ctxt(struct hinic3_nic_io *nic_io)
{
/* clean LRO/TSO context space */
- return (clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_SQ) ||
- clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_RQ));
+ return ((clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_SQ) != 0) ||
+ (clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_RQ) != 0));
}
/* init qps ctxt and set sq ci attr and arm all sq */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
index 5c5585a..943a736 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
@@ -303,7 +303,7 @@ static inline void hinic3_write_db(struct hinic3_io_queue *queue, int cos,
wmb(); /* Write all before the doorbell */
- writeq(*((u64 *)&db), DB_ADDR(queue, pi));
+ writeq(*((u64 *)(u8 *)&db), DB_ADDR(queue, pi));
}
struct hinic3_dyna_qp_params {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
index 78d943d..9ea93a0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
@@ -32,7 +32,7 @@ struct hinic3_prof_adapter nic_prof_adap_objs[] = {
void hinic3_init_nic_prof_adapter(struct hinic3_nic_dev *nic_dev)
{
- u16 num_adap = ARRAY_SIZE(nic_prof_adap_objs);
+ int num_adap = ARRAY_LEN(nic_prof_adap_objs);
nic_dev->prof_adap = hinic3_prof_init(nic_dev, nic_prof_adap_objs, num_adap,
(void *)&nic_dev->prof_attr);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
index 283c544..6d9b0c1 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
@@ -394,7 +394,8 @@ hinic3_alloc_dynamic_block_resource(struct hinic3_nic_dev *nic_dev,
dynamic_block_ptr = kzalloc(sizeof(*dynamic_block_ptr), GFP_KERNEL);
if (!dynamic_block_ptr) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "fdir filter dynamic alloc block index %d memory failed\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "fdir filter dynamic alloc block index %u memory failed\n",
dynamic_block_id);
return NULL;
}
@@ -433,7 +434,8 @@ hinic3_dynamic_lookup_tcam_filter(struct hinic3_nic_dev *nic_dev,
list_for_each_entry(tmp,
&tcam_info->tcam_dynamic_info.tcam_dynamic_list,
block_list)
- if (tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)
+ if (!tmp ||
+ tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)
break;
if (!tmp || tmp->dynamic_index_cnt >= HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) {
@@ -515,7 +517,7 @@ static int hinic3_add_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, queue: %d, tcam_rule_nums: %d succeed\n",
+ "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, queue: %u, tcam_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev),
tcam_filter->dynamic_block_id, index, fdir_tcam_rule->index,
fdir_tcam_rule->data.qid, tcam_info->tcam_rule_nums + 1);
@@ -582,7 +584,7 @@ static int hinic3_del_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, local_rules_nums: %d, global_rule_nums: %d succeed\n",
+ "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, local_rules_nums: %u, global_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev), dynamic_block_id,
tcam_filter->index, index, tmp->dynamic_index_cnt - 1,
tcam_info->tcam_rule_nums - 1);
@@ -608,7 +610,7 @@ static inline struct hinic3_tcam_filter *
hinic3_tcam_filter_lookup(const struct list_head *filter_list,
struct tag_tcam_key *key)
{
- struct hinic3_tcam_filter *iter;
+ struct hinic3_tcam_filter *iter = NULL;
list_for_each_entry(iter, filter_list, tcam_filter_list) {
if (memcmp(key, &iter->tcam_key,
@@ -633,7 +635,7 @@ static int hinic3_remove_one_rule(struct hinic3_nic_dev *nic_dev,
struct hinic3_ethtool_rx_flow_rule *eth_rule)
{
struct hinic3_tcam_info *tcam_info = &nic_dev->tcam;
- struct hinic3_tcam_filter *tcam_filter;
+ struct hinic3_tcam_filter *tcam_filter = NULL;
struct nic_tcam_cfg_rule fdir_tcam_rule;
struct tag_tcam_key tcam_key;
int err;
@@ -754,7 +756,7 @@ static int validate_flow(struct hinic3_nic_dev *nic_dev,
{
if (fs->location >= MAX_NUM_OF_ETHTOOL_NTUPLE_RULES) {
nicif_err(nic_dev, drv, nic_dev->netdev, "loc exceed limit[0,%lu]\n",
- MAX_NUM_OF_ETHTOOL_NTUPLE_RULES);
+ MAX_NUM_OF_ETHTOOL_NTUPLE_RULES - 1);
return -EINVAL;
}
@@ -875,7 +877,7 @@ int hinic3_ethtool_get_flow(const struct hinic3_nic_dev *nic_dev,
int hinic3_ethtool_get_all_flows(const struct hinic3_nic_dev *nic_dev,
struct ethtool_rxnfc *info, u32 *rule_locs)
{
- int idx = 0;
+ u32 idx = 0;
struct hinic3_ethtool_rx_flow_rule *eth_rule = NULL;
if (!HINIC3_SUPPORT_FDIR(nic_dev->hwdev)) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h b/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
deleted file mode 100644
index a93f3b6..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_PROFILE_H
-#define HINIC3_PROFILE_H
-
-typedef bool (*hinic3_is_match_prof)(void *device);
-typedef void *(*hinic3_init_prof_attr)(void *device);
-typedef void (*hinic3_deinit_prof_attr)(void *porf_attr);
-
-enum prof_adapter_type {
- PROF_ADAP_TYPE_INVALID,
- PROF_ADAP_TYPE_PANGEA = 1,
-
- /* Add prof adapter type before default */
- PROF_ADAP_TYPE_DEFAULT,
-};
-
-/**
- * struct hinic3_prof_adapter - custom scene's profile adapter
- * @type: adapter type
- * @match: Check whether the current function is used in the custom scene.
- * Implemented in the current source file
- * @init: When @match return true, the initialization function called in probe.
- * Implemented in the source file of the custom scene
- * @deinit: When @match return true, the deinitialization function called when
- * remove. Implemented in the source file of the custom scene
- */
-struct hinic3_prof_adapter {
- enum prof_adapter_type type;
- hinic3_is_match_prof match;
- hinic3_init_prof_attr init;
- hinic3_deinit_prof_attr deinit;
-};
-
-#ifdef static
-#undef static
-#define LLT_STATIC_DEF_SAVED
-#endif
-
-/*lint -save -e661 */
-static inline struct hinic3_prof_adapter *
-hinic3_prof_init(void *device, struct hinic3_prof_adapter *adap_objs, int num_adap,
- void **prof_attr)
-{
- struct hinic3_prof_adapter *prof_obj = NULL;
- u16 i;
-
- for (i = 0; i < num_adap; i++) {
- prof_obj = &adap_objs[i];
- if (!(prof_obj->match && prof_obj->match(device)))
- continue;
-
- *prof_attr = prof_obj->init ? prof_obj->init(device) : NULL;
-
- return prof_obj;
- }
-
- return NULL;
-}
-
-static inline void hinic3_prof_deinit(struct hinic3_prof_adapter *prof_obj, void *prof_attr)
-{
- if (!prof_obj)
- return;
-
- if (prof_obj->deinit)
- prof_obj->deinit(prof_attr);
-}
-
-/*lint -restore*/
-
-/* module-level interface */
-#ifdef CONFIG_MODULE_PROF
-struct hinic3_module_ops {
- int (*module_prof_init)(void);
- void (*module_prof_exit)(void);
- void (*probe_fault_process)(void *pdev, u16 level);
- int (*probe_pre_process)(void *pdev);
- void (*probe_pre_unprocess)(void *pdev);
-};
-
-struct hinic3_module_ops *hinic3_get_module_prof_ops(void);
-
-static inline void hinic3_probe_fault_process(void *pdev, u16 level)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (ops && ops->probe_fault_process)
- ops->probe_fault_process(pdev, level);
-}
-
-static inline int hinic3_module_pre_init(void)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (!ops || !ops->module_prof_init)
- return -EINVAL;
-
- return ops->module_prof_init();
-}
-
-static inline void hinic3_module_post_exit(void)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (ops && ops->module_prof_exit)
- ops->module_prof_exit();
-}
-
-static inline int hinic3_probe_pre_process(void *pdev)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (!ops || !ops->probe_pre_process)
- return -EINVAL;
-
- return ops->probe_pre_process(pdev);
-}
-
-static inline void hinic3_probe_pre_unprocess(void *pdev)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (ops && ops->probe_pre_unprocess)
- ops->probe_pre_unprocess(pdev);
-}
-#else
-static inline void hinic3_probe_fault_process(void *pdev, u16 level) { };
-
-static inline int hinic3_module_pre_init(void)
-{
- return 0;
-}
-
-static inline void hinic3_module_post_exit(void) { };
-
-static inline int hinic3_probe_pre_process(void *pdev)
-{
- return 0;
-}
-
-static inline void hinic3_probe_pre_unprocess(void *pdev) { };
-#endif
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
index 6bf3b11..655d2b8 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/dcbnl.h>
+#include <linux/init.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -23,8 +24,9 @@
#include "hinic3_hw.h"
#include "hinic3_rss.h"
-/*lint -e806*/
-static u16 num_qps;
+#include "vram_common.h"
+
+static u16 num_qps = 0;
module_param(num_qps, ushort, 0444);
MODULE_PARM_DESC(num_qps, "Number of Queue Pairs (default=0)");
@@ -104,88 +106,84 @@ static int hinic3_get_rq2iq_map(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev, u8 num_cos, u32 *indir)
+static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev,
+ u8 group_num, u32 *indir)
{
- u16 k, group_size, start_qid = 0, qp_num = 0;
- int i = 0;
- u8 j, cur_cos = 0, default_cos;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ u16 k, group_size, start_qid = 0, cur_cos_qnum = 0;
+ u32 i = 0;
+ u8 j, cur_cos = 0, group = 0;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
- if (num_cos == 0) {
+ if (group_num == 0) {
for (i = 0; i < NIC_RSS_INDIR_SIZE; i++)
indir[i] = i % nic_dev->q_params.num_qps;
} else {
- group_size = NIC_RSS_INDIR_SIZE / num_cos;
-
- for (j = 0; j < num_cos; j++) {
- while (cur_cos < NIC_DCB_COS_MAX &&
- nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos] == 0)
- cur_cos++;
-
- if (cur_cos >= NIC_DCB_COS_MAX) {
- if (BIT(nic_dev->hw_dcb_cfg.default_cos) & valid_cos_map)
- default_cos = nic_dev->hw_dcb_cfg.default_cos;
- else
- default_cos = (u8)fls(valid_cos_map) - 1;
+ group_size = NIC_RSS_INDIR_SIZE / group_num;
+
+ for (group = 0; group < group_num; group++) {
+ cur_cos = dcb->hw_dcb_cfg.default_cos;
+ for (j = 0; j < NIC_DCB_COS_MAX; j++) {
+ if ((BIT(j) & valid_cos_map) != 0) {
+ cur_cos = j;
+ valid_cos_map -= (u8)BIT(j);
+ break;
+ }
+ }
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[default_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[default_cos];
+ cur_cos_qnum = dcb->hw_dcb_cfg.cos_qp_num[cur_cos];
+ if (cur_cos_qnum > 0) {
+ start_qid =
+ dcb->hw_dcb_cfg.cos_qp_offset[cur_cos];
} else {
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[cur_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos];
+ start_qid = cur_cos % nic_dev->q_params.num_qps;
+ /* Ensure that the offset of start_id is 0. */
+ cur_cos_qnum = 1;
}
for (k = 0; k < group_size; k++)
- indir[i++] = start_qid + k % qp_num;
-
- cur_cos++;
+ indir[i++] = start_qid + k % cur_cos_qnum;
}
}
}
-/*lint -e528*/
int hinic3_rss_init(struct hinic3_nic_dev *nic_dev, u8 *rq2iq_map, u32 map_size, u8 dcb_en)
{
struct net_device *netdev = nic_dev->netdev;
- u8 i, cos_num;
- u8 cos_map[NIC_DCB_UP_MAX] = {0};
- u8 cfg_map[NIC_DCB_UP_MAX] = {0};
+ u8 i, group_num, cos_bitmap, group = 0;
+ u8 cos_group[NIC_DCB_UP_MAX] = {0};
int err;
- if (dcb_en) {
- cos_num = hinic3_get_dev_user_cos_num(nic_dev);
-
- if (nic_dev->hw_dcb_cfg.trust == 0) {
- memcpy(cfg_map, nic_dev->hw_dcb_cfg.pcp2cos, sizeof(cfg_map));
- } else if (nic_dev->hw_dcb_cfg.trust == 1) {
- for (i = 0; i < NIC_DCB_UP_MAX; i++)
- cfg_map[i] = nic_dev->hw_dcb_cfg.dscp2cos[i * NIC_DCB_DSCP_NUM];
- }
-#define COS_CHANGE_OFFSET 4
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[COS_CHANGE_OFFSET + i] = cfg_map[i];
+ if (dcb_en != 0) {
+ group_num = (u8)roundup_pow_of_two(
+ hinic3_get_dev_user_cos_num(nic_dev));
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[i] = cfg_map[NIC_DCB_UP_MAX - (i + 1)];
+ cos_bitmap = hinic3_get_dev_valid_cos_map(nic_dev);
- while (cos_num & (cos_num - 1))
- cos_num++;
+ for (i = 0; i < NIC_DCB_UP_MAX; i++) {
+ if ((BIT(i) & cos_bitmap) != 0)
+ cos_group[NIC_DCB_UP_MAX - i - 1] = group++;
+ else
+ cos_group[NIC_DCB_UP_MAX - i - 1] =
+ group_num - 1;
+ }
} else {
- cos_num = 0;
+ group_num = 0;
}
- err = hinic3_set_hw_rss_parameters(netdev, 1, cos_num, cos_map, dcb_en);
+ err = hinic3_set_hw_rss_parameters(netdev, 1, group_num,
+ cos_group, dcb_en);
if (err)
return err;
- err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps, cos_num, cos_map,
- NIC_DCB_UP_MAX, nic_dev->rss_indir, rq2iq_map, map_size);
+ err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps,
+ group_num, cos_group, NIC_DCB_UP_MAX,
+ nic_dev->rss_indir, rq2iq_map, map_size);
if (err)
nicif_err(nic_dev, drv, netdev, "Failed to get rq map\n");
return err;
}
-/*lint -e528*/
void hinic3_rss_deinit(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -246,28 +244,59 @@ discard_user_rss_indir:
hinic3_set_default_rss_indir(netdev);
}
+#ifdef HAVE_HOT_REPLACE_FUNC
+bool partition_slave_doing_hotupgrade(void)
+{
+ return get_partition_role() && partition_doing_hotupgrade();
+}
+#endif
+
static void decide_num_qps(struct hinic3_nic_dev *nic_dev)
{
u16 tmp_num_qps = nic_dev->max_qps;
u16 num_cpus = 0;
+ u16 max_num_cpus;
int i, node;
+ int is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ nic_dev->q_params.num_qps = nic_dev->nic_vram->vram_num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Os hotreplace use vram to init num qps 1:%hu 2:%hu\n",
+ nic_dev->q_params.num_qps,
+ nic_dev->nic_vram->vram_num_qps);
+ return;
+ }
+
if (nic_dev->nic_cap.default_num_queues != 0 &&
nic_dev->nic_cap.default_num_queues < nic_dev->max_qps)
tmp_num_qps = nic_dev->nic_cap.default_num_queues;
MOD_PARA_VALIDATE_NUM_QPS(nic_dev, num_qps, tmp_num_qps);
- for (i = 0; i < (int)num_online_cpus(); i++) {
+#ifdef HAVE_HOT_REPLACE_FUNC
+ if (partition_slave_doing_hotupgrade())
+ max_num_cpus = (u16)num_present_cpus();
+ else
+ max_num_cpus = (u16)num_online_cpus();
+#else
+ max_num_cpus = (u16)num_online_cpus();
+#endif
+
+ for (i = 0; i < max_num_cpus; i++) {
node = (int)cpu_to_node(i);
if (node == dev_to_node(&nic_dev->pdev->dev))
num_cpus++;
}
if (!num_cpus)
- num_cpus = (u16)num_online_cpus();
+ num_cpus = max_num_cpus;
nic_dev->q_params.num_qps = (u16)min_t(u16, tmp_num_qps, num_cpus);
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "init num qps 1:%u 2:%u\n",
+ nic_dev->q_params.num_qps, nic_dev->nic_vram->vram_num_qps);
}
static void copy_value_to_rss_hkey(struct hinic3_nic_dev *nic_dev,
@@ -324,7 +353,6 @@ static int alloc_rss_resource(struct hinic3_nic_dev *nic_dev)
return 0;
}
-/*lint -e528*/
void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -363,6 +391,7 @@ void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
set_q_params:
clear_bit(HINIC3_RSS_ENABLE, &nic_dev->flags);
nic_dev->q_params.num_qps = nic_dev->max_qps;
+ nic_dev->nic_vram->vram_num_qps = nic_dev->max_qps;
}
static int hinic3_config_rss_hw_resource(struct hinic3_nic_dev *nic_dev,
@@ -756,6 +785,7 @@ int hinic3_set_channels(struct net_device *netdev,
nic_dev->q_params.num_qps = (u16)count;
}
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
return 0;
}
@@ -816,7 +846,7 @@ int hinic3_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
int err = 0;
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
@@ -923,7 +953,7 @@ int hinic3_get_rxfh_indir(struct net_device *netdev, u32 *indir)
indir = indir1->ring_index;
#endif
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
index 175c4d6..902d7e2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
@@ -15,13 +15,14 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_nic_cfg.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_hw.h"
#include "hinic3_nic.h"
#include "hinic3_common.h"
static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
- u8 *key)
+ u8 *key, u16 key_size)
{
struct hinic3_cmd_rss_hash_key hash_key;
u16 out_size = sizeof(hash_key);
@@ -32,7 +33,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
hash_key.opcode = opcode;
if (opcode == HINIC3_CMD_OP_SET)
- memcpy(hash_key.key, key, NIC_RSS_KEY_SIZE);
+ memcpy(hash_key.key, key, key_size);
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_CFG_RSS_HASH_KEY,
@@ -46,7 +47,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
}
if (opcode == HINIC3_CMD_OP_GET)
- memcpy(key, hash_key.key, NIC_RSS_KEY_SIZE);
+ memcpy(key, hash_key.key, key_size);
return 0;
}
@@ -60,8 +61,11 @@ int hinic3_rss_set_hash_key(void *hwdev, const u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memcpy(hash_key, key, NIC_RSS_KEY_SIZE);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET, hash_key);
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET,
+ hash_key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
@@ -72,7 +76,10 @@ int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET, key);
+ if (!nic_io)
+ return -EINVAL;
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET,
+ key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
@@ -86,6 +93,9 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -126,6 +136,8 @@ int hinic3_rss_set_indir_tbl(void *hwdev, const u32 *indir_table)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd buf\n");
@@ -170,6 +182,8 @@ static int hinic3_cmdq_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
@@ -221,6 +235,8 @@ static int hinic3_mgmt_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&ctx_tbl, 0, sizeof(ctx_tbl));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
ctx |= HINIC3_RSS_TYPE_SET(1, VALID) |
@@ -270,6 +286,8 @@ int hinic3_get_rss_type(void *hwdev, struct nic_rss_type *rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&ctx_tbl, 0, sizeof(struct hinic3_rss_context_table));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
@@ -303,6 +321,9 @@ static int hinic3_rss_cfg_hash_engine(struct hinic3_nic_io *nic_io, u8 opcode,
u16 out_size = sizeof(hash_type);
int err;
+ if (!nic_io)
+ return -EINVAL;
+
memset(&hash_type, 0, sizeof(struct hinic3_cmd_rss_engine_type));
hash_type.func_id = hinic3_global_func_id(nic_io->hwdev);
@@ -336,6 +357,9 @@ int hinic3_rss_set_hash_engine(void *hwdev, u8 type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_SET, &type);
}
@@ -347,6 +371,9 @@ int hinic3_rss_get_hash_engine(void *hwdev, u8 *type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_GET, type);
}
@@ -362,6 +389,8 @@ int hinic3_rss_cfg(void *hwdev, u8 rss_en, u8 cos_num, u8 *prio_tc, u16 num_qps)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&rss_cfg, 0, sizeof(struct hinic3_cmd_rss_config));
rss_cfg.func_id = hinic3_global_func_id(hwdev);
rss_cfg.rss_en = rss_en;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
index 5c60d01..4dbd6dd 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
@@ -10,6 +10,7 @@
#include <linux/interrupt.h>
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
+#include <net/xdp.h>
#include <linux/device.h>
#include <linux/pci.h>
#include <linux/u64_stats_sync.h>
@@ -20,6 +21,7 @@
#include <linux/ipv6.h>
#include <linux/module.h>
#include <linux/compiler.h>
+#include <linux/filter.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -31,10 +33,6 @@
#include "hinic3_rss.h"
#include "hinic3_rx.h"
-static u32 rq_pi_rd_en;
-module_param(rq_pi_rd_en, uint, 0644);
-MODULE_PARM_DESC(rq_pi_rd_en, "Enable rq read pi from host, defaut update pi by doorbell (default=0)");
-
/* performance: ci addr RTE_CACHE_SIZE(64B) alignment */
#define HINIC3_RX_HDR_SIZE 256
#define HINIC3_RX_BUFFER_WRITE 16
@@ -63,19 +61,34 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
struct pci_dev *pdev = nic_dev->pdev;
struct page *page = rx_info->page;
dma_addr_t dma = rx_info->buf_dma_addr;
+ u32 page_offset = 0;
if (likely(dma))
return true;
/* alloc new page for storage */
- page = alloc_pages_node(NUMA_NO_NODE, GFP_ATOMIC | __GFP_COLD |
- __GFP_COMP, nic_dev->page_order);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page = page_pool_alloc_frag(rx_info->page_pool, &page_offset,
+ nic_dev->rx_buff_len,
+ GFP_ATOMIC | __GFP_COLD |
+ __GFP_COMP);
+ if (unlikely(!page))
+ return false;
+ dma = page_pool_get_dma_addr(page);
+ goto set_rx_info;
+ }
+#endif
+ page = alloc_pages_node(NUMA_NO_NODE,
+ GFP_ATOMIC | __GFP_COLD | __GFP_COMP,
+ nic_dev->page_order);
+
if (unlikely(!page))
return false;
/* map page for use */
- dma = dma_map_page(&pdev->dev, page, 0, nic_dev->dma_rx_buff_size,
- DMA_FROM_DEVICE);
+ dma = dma_map_page(&pdev->dev, page, page_offset,
+ nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
/* if mapping failed free memory back to system since
* there isn't much point in holding memory we can't use
*/
@@ -83,10 +96,12 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
__free_pages(page, nic_dev->page_order);
return false;
}
+ goto set_rx_info;
+set_rx_info:
rx_info->page = page;
rx_info->buf_dma_addr = dma;
- rx_info->page_offset = 0;
+ rx_info->page_offset = page_offset;
return true;
}
@@ -108,8 +123,8 @@ static u32 hinic3_rx_fill_wqe(struct hinic3_rxq *rxq)
/* unit of cqe length is 16B */
hinic3_set_sge(&rq_wqe->extend_wqe.cqe_sect.sge,
rx_info->cqe_dma,
- (sizeof(struct hinic3_rq_cqe) >>
- HINIC3_CQE_SIZE_SHIFT));
+ (HINIC3_CQE_LEN >>
+ HINIC3_CQE_SIZE_SHIFT));
/* use fixed len */
rq_wqe->extend_wqe.buf_desc.sge.len =
nic_dev->rx_buff_len;
@@ -163,18 +178,11 @@ static u32 hinic3_rx_fill_buffers(struct hinic3_rxq *rxq)
}
if (likely(i)) {
- if (!rq_pi_rd_en) {
- hinic3_write_db(rxq->rq,
- rxq->q_id & (NIC_DCB_COS_MAX - 1),
- RQ_CFLAG_DP,
- (u16)((u32)rxq->next_to_update <<
- rxq->rq->wqe_type));
- } else {
- /* Write all the wqes before pi update */
- wmb();
-
- hinic3_update_rq_hw_pi(rxq->rq, rxq->next_to_update);
- }
+ hinic3_write_db(rxq->rq,
+ rxq->q_id & (NIC_RX_DB_COS_MAX - 1),
+ RQ_CFLAG_DP,
+ (u16)((u32)rxq->next_to_update <<
+ rxq->rq->wqe_type));
rxq->delta -= i;
rxq->next_to_alloc = rxq->next_to_update;
} else if (free_wqebbs == rxq->q_depth - 1) {
@@ -208,6 +216,18 @@ static void hinic3_rx_free_buffers(struct hinic3_nic_dev *nic_dev, u32 q_depth,
for (i = 0; i < q_depth; i++) {
rx_info = &rx_info_arr[i];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ if (rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool,
+ rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ }
+ continue;
+ }
+#endif
+
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev,
rx_info->buf_dma_addr,
@@ -226,7 +246,7 @@ static void hinic3_rx_free_buffers(struct hinic3_nic_dev *nic_dev, u32 q_depth,
static void hinic3_reuse_rx_page(struct hinic3_rxq *rxq,
struct hinic3_rx_info *old_rx_info)
{
- struct hinic3_rx_info *new_rx_info;
+ struct hinic3_rx_info *new_rx_info = NULL;
u16 nta = rxq->next_to_alloc;
new_rx_info = &rxq->rx_info[nta];
@@ -250,8 +270,8 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
struct hinic3_rx_info *rx_info,
struct sk_buff *skb, u32 size)
{
- struct page *page;
- u8 *va;
+ struct page *page = NULL;
+ u8 *va = NULL;
page = rx_info->page;
va = (u8 *)page_address(page) + rx_info->page_offset;
@@ -267,8 +287,15 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
DMA_FROM_DEVICE);
if (size <= HINIC3_RX_HDR_SIZE && !skb_is_nonlinear(skb)) {
- memcpy(__skb_put(skb, size), va,
- ALIGN(size, sizeof(long))); /*lint !e666*/
+ __skb_put_data(skb, va, size);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool,
+ page, false);
+ return false;
+ }
+#endif
/* page is not reserved, we can reuse buffer as-is */
if (likely(page_to_nid(page) == numa_node_id()))
@@ -276,25 +303,37 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
/* this page cannot be reused so discard it */
put_page(page);
- return false;
+ goto discard_page;
}
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
(int)rx_info->page_offset, (int)size, rxq->buf_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
+
/* avoid re-using remote pages */
if (unlikely(page_to_nid(page) != numa_node_id()))
- return false;
+ goto discard_page;
/* if we are only owner of page we can reuse it */
if (unlikely(page_count(page) != 1))
- return false;
+ goto discard_page;
/* flip page offset to other buffer */
rx_info->page_offset ^= rxq->buf_len;
get_page(page);
return true;
+
+discard_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
}
static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
@@ -334,13 +373,9 @@ static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
head_skb->truesize += rxq->buf_len;
}
- if (likely(hinic3_add_rx_frag(rxq, rx_info, skb, size))) {
+ if (likely(hinic3_add_rx_frag(rxq, rx_info, skb, size)))
hinic3_reuse_rx_page(rxq, rx_info);
- } else {
- /* we are not reusing the buffer so unmap it */
- dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
- rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
- }
+
/* clear contents of buffer_info */
rx_info->buf_dma_addr = 0;
rx_info->page = NULL;
@@ -481,9 +516,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
protocol = hdr.eth->h_proto;
/* L2 header */
- /*lint -save -e778*/
if (protocol == htons(ETH_P_8021_AD) ||
- protocol == htons(ETH_P_8021_Q)) { /*lint -restore*/
+ protocol == htons(ETH_P_8021_Q)) {
if (unlikely(max_len < ETH_HLEN + VLAN_HLEN))
return max_len;
@@ -495,9 +529,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
}
/* L3 header */
- /*lint -save -e778*/
switch (protocol) {
- case htons(ETH_P_IP): /*lint -restore*/
+ case htons(ETH_P_IP):
if ((int)(hdr.data - data) >
(int)(max_len - sizeof(struct iphdr)))
return max_len;
@@ -680,7 +713,7 @@ static void hinic3_copy_lp_data(struct hinic3_nic_dev *nic_dev,
nicif_warn(nic_dev, rx_err, netdev, "Loopback test warning, receive too many test pkts\n");
}
- if (skb->len != nic_dev->lb_pkt_len) {
+ if (skb->len != (u32)(nic_dev->lb_pkt_len)) {
nicif_warn(nic_dev, rx_err, netdev, "Wrong packet length\n");
nic_dev->lb_test_rx_idx++;
return;
@@ -714,7 +747,10 @@ static inline void hinic3_lro_set_gso_params(struct sk_buff *skb, u16 num_lro)
}
#ifdef HAVE_XDP_SUPPORT
-enum hinic3_xdp_pkt {
+enum hinic3_xdp_status {
+ // bpf_prog status
+ HINIC3_XDP_PROG_EMPTY,
+ // pkt action
HINIC3_XDP_PKT_PASS,
HINIC3_XDP_PKT_DROP,
};
@@ -725,9 +761,15 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
while (weqbb_num) {
rx_info = &rxq->rx_info[rxq->cons_idx & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool)
+ goto discard_direct;
+#endif
if (likely(page_to_nid(rx_info->page) == numa_node_id()))
hinic3_reuse_rx_page(rxq, rx_info);
+ goto discard_direct;
+discard_direct:
rx_info->buf_dma_addr = 0;
rx_info->page = NULL;
rxq->cons_idx++;
@@ -737,11 +779,10 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
}
}
-int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
+int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len, struct xdp_buff *xdp)
{
struct bpf_prog *xdp_prog = NULL;
struct hinic3_rx_info *rx_info = NULL;
- struct xdp_buff xdp;
int result = HINIC3_XDP_PKT_PASS;
u16 weqbb_num = 1; /* xdp can only use one rx_buff */
u8 *va = NULL;
@@ -749,13 +790,14 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
rcu_read_lock();
xdp_prog = READ_ONCE(rxq->xdp_prog);
- if (!xdp_prog)
+ if (!xdp_prog) {
+ result = HINIC3_XDP_PROG_EMPTY;
goto unlock_rcu;
+ }
if (unlikely(pkt_len > rxq->buf_len)) {
RXQ_STATS_INC(rxq, xdp_large_pkt);
- weqbb_num = (u16)(pkt_len >> rxq->rx_buff_shift) +
- ((pkt_len & (rxq->buf_len - 1)) ? 1 : 0);
+ weqbb_num = HINIC3_GET_SGE_NUM(pkt_len, rxq);
result = HINIC3_XDP_PKT_DROP;
goto xdp_out;
}
@@ -766,19 +808,20 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
dma_sync_single_range_for_cpu(rxq->dev, rx_info->buf_dma_addr,
rx_info->page_offset,
rxq->buf_len, DMA_FROM_DEVICE);
- xdp.data = va;
- xdp.data_hard_start = xdp.data;
- xdp.data_end = xdp.data + pkt_len;
+ xdp->data = va;
+ xdp->data_hard_start = xdp->data;
+ xdp->data_end = xdp->data + pkt_len;
#ifdef HAVE_XDP_FRAME_SZ
- xdp.frame_sz = rxq->buf_len;
+ xdp->frame_sz = rxq->buf_len;
#endif
#ifdef HAVE_XDP_DATA_META
- xdp_set_data_meta_invalid(&xdp);
+ xdp_set_data_meta_invalid(xdp);
#endif
- prefetchw(xdp.data_hard_start);
- act = bpf_prog_run_xdp(xdp_prog, &xdp);
+ prefetchw(xdp->data_hard_start);
+ act = bpf_prog_run_xdp(xdp_prog, xdp);
switch (act) {
case XDP_PASS:
+ result = HINIC3_XDP_PKT_PASS;
break;
case XDP_DROP:
result = HINIC3_XDP_PKT_DROP;
@@ -799,12 +842,94 @@ unlock_rcu:
return result;
}
+
+static bool hinic3_add_rx_frag_with_xdp(struct hinic3_rxq *rxq, u32 pkt_len,
+ struct hinic3_rx_info *rx_info,
+ struct sk_buff *skb,
+ struct xdp_buff *xdp)
+{
+ struct page *page = rx_info->page;
+
+ if (pkt_len <= HINIC3_RX_HDR_SIZE) {
+ __skb_put_data(skb, xdp->data, pkt_len);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool,
+ page, false);
+ return false;
+ }
+#endif
+
+ if (likely(page_to_nid(page) == numa_node_id()))
+ return true;
+
+ put_page(page);
+ goto umap_page;
+ }
+
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
+ (int)(rx_info->page_offset +
+ (xdp->data - xdp->data_hard_start)),
+ (int)pkt_len, rxq->buf_len);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
+ if (unlikely(page_to_nid(page) != numa_node_id()))
+ goto umap_page;
+ if (unlikely(page_count(page) != 1))
+ goto umap_page;
+
+ rx_info->page_offset ^= rxq->buf_len;
+ get_page(page);
+
+ return true;
+
+umap_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
+}
+
+static struct sk_buff *hinic3_fetch_rx_buffer_xdp(struct hinic3_rxq *rxq,
+ u32 pkt_len,
+ struct xdp_buff *xdp)
+{
+ struct sk_buff *skb;
+ struct hinic3_rx_info *rx_info;
+ u32 sw_ci;
+ bool reuse;
+
+ sw_ci = rxq->cons_idx & rxq->q_mask;
+ rx_info = &rxq->rx_info[sw_ci];
+
+ skb = netdev_alloc_skb_ip_align(rxq->netdev, HINIC3_RX_HDR_SIZE);
+ if (unlikely(!skb))
+ return NULL;
+
+ reuse = hinic3_add_rx_frag_with_xdp(rxq, pkt_len, rx_info, skb, xdp);
+ if (likely(reuse))
+ hinic3_reuse_rx_page(rxq, rx_info);
+
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+
+ rxq->cons_idx += 1;
+ rxq->delta += 1;
+
+ return skb;
+}
+
#endif
static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_rq_cqe *rx_cqe,
u32 pkt_len, u32 vlan_len, u32 status)
{
- struct sk_buff *skb;
+ struct sk_buff *skb = NULL;
struct net_device *netdev = rxq->netdev;
u32 offload_type;
u16 num_lro;
@@ -812,13 +937,25 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_rq_cqe *rx_cqe,
#ifdef HAVE_XDP_SUPPORT
u32 xdp_status;
+ struct xdp_buff xdp = { 0 };
- xdp_status = hinic3_run_xdp(rxq, pkt_len);
+ xdp_status = (u32)(hinic3_run_xdp(rxq, pkt_len, &xdp));
if (xdp_status == HINIC3_XDP_PKT_DROP)
return 0;
-#endif
+ // build skb
+ if (xdp_status != HINIC3_XDP_PROG_EMPTY) {
+ // xdp_prog configured, build skb with xdp
+ skb = hinic3_fetch_rx_buffer_xdp(rxq, pkt_len, &xdp);
+ } else {
+ // xdp_prog not configured, build skb
+ skb = hinic3_fetch_rx_buffer(rxq, pkt_len);
+ }
+#else
+
+ // xdp is not supported
skb = hinic3_fetch_rx_buffer(rxq, pkt_len);
+#endif
if (unlikely(!skb)) {
RXQ_STATS_INC(rxq, alloc_skb_err);
return -ENOMEM;
@@ -852,7 +989,7 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_rq_cqe *rx_cqe,
hinic3_copy_lp_data(nic_dev, skb);
num_lro = HINIC3_GET_RX_NUM_LRO(status);
- if (num_lro)
+ if (num_lro > 1)
hinic3_lro_set_gso_params(skb, num_lro);
skb_record_rx_queue(skb, rxq->q_id);
@@ -931,12 +1068,40 @@ int hinic3_rx_poll(struct hinic3_rxq *rxq, int budget)
return pkts;
}
+#ifdef HAVE_PAGE_POOL_SUPPORT
+static struct page_pool *hinic3_create_page_pool(struct hinic3_nic_dev *nic_dev,
+ u32 rq_depth,
+ struct hinic3_rx_info *rx_info_arr)
+{
+ struct page_pool_params pp_params = {
+ .flags = PP_FLAG_DMA_MAP | PP_FLAG_PAGE_FRAG |
+ PP_FLAG_DMA_SYNC_DEV,
+ .order = nic_dev->page_order,
+ .pool_size = rq_depth * nic_dev->rx_buff_len /
+ (PAGE_SIZE << nic_dev->page_order),
+ .nid = dev_to_node(&(nic_dev->pdev->dev)),
+ .dev = &(nic_dev->pdev->dev),
+ .dma_dir = DMA_FROM_DEVICE,
+ .offset = 0,
+ .max_len = PAGE_SIZE << nic_dev->page_order,
+ };
+ struct page_pool *page_pool;
+ int i;
+
+ page_pool = nic_dev->page_pool_enabled ?
+ page_pool_create(&pp_params) : NULL;
+ for (i = 0; i < rq_depth; i++)
+ rx_info_arr[i].page_pool = page_pool;
+ return page_pool;
+}
+#endif
+
int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
u32 rq_depth, struct hinic3_dyna_rxq_res *rxqs_res)
{
struct hinic3_dyna_rxq_res *rqres = NULL;
u64 cqe_mem_size = sizeof(struct hinic3_rq_cqe) * rq_depth;
- int idx, i;
+ int idx;
u32 pkts;
u64 size;
@@ -947,46 +1112,49 @@ int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
if (!rqres->rx_info) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx info\n", idx);
- goto err_out;
+ goto err_alloc_rx_info;
}
-
rqres->cqe_start_vaddr =
dma_zalloc_coherent(&nic_dev->pdev->dev, cqe_mem_size,
&rqres->cqe_start_paddr,
GFP_KERNEL);
if (!rqres->cqe_start_vaddr) {
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d cqe\n", idx);
- goto err_out;
+ goto err_alloc_cqe;
}
-
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ rqres->page_pool = hinic3_create_page_pool(nic_dev, rq_depth,
+ rqres->rx_info);
+ if (nic_dev->page_pool_enabled && !rqres->page_pool) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to create rxq%d page pool\n", idx);
+ goto err_create_page_pool;
+ }
+#endif
pkts = hinic3_rx_alloc_buffers(nic_dev, rq_depth,
rqres->rx_info);
if (!pkts) {
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx buffers\n", idx);
- goto err_out;
+ goto err_alloc_buffers;
}
rqres->next_to_alloc = (u16)pkts;
}
return 0;
-err_out:
- for (i = 0; i < idx; i++) {
- rqres = &rxqs_res[i];
-
- hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- kfree(rqres->rx_info);
- }
-
+err_alloc_buffers:
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ page_pool_destroy(rqres->page_pool);
+err_create_page_pool:
+#endif
+ dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
+ rqres->cqe_start_vaddr,
+ rqres->cqe_start_paddr);
+err_alloc_cqe:
+ kfree(rqres->rx_info);
+err_alloc_rx_info:
+ hinic3_free_rxqs_res(nic_dev, idx, rq_depth, rxqs_res);
return -ENOMEM;
}
@@ -1001,6 +1169,10 @@ void hinic3_free_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
rqres = &rxqs_res[idx];
hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rqres->page_pool)
+ page_pool_destroy(rqres->page_pool);
+#endif
dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
rqres->cqe_start_vaddr,
rqres->cqe_start_paddr);
@@ -1084,6 +1256,7 @@ void hinic3_free_rxqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->rxqs);
+ nic_dev->rxqs = NULL;
}
int hinic3_alloc_rxqs(struct net_device *netdev)
@@ -1207,6 +1380,15 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
nic_info(&nic_dev->pdev->dev, "rxq %u restore_buf_num:%u\n", q_id, rxq->restore_buf_num);
rx_info = &rxq->rx_info[(hw_ci + rxq->q_depth - 1) & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool && rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool,
+ rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ goto reset_rxq;
+ }
+#endif
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev, rx_info->buf_dma_addr,
nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
@@ -1217,7 +1399,9 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
__free_pages(rx_info->page, nic_dev->page_order);
rx_info->page = NULL;
}
+ goto reset_rxq;
+reset_rxq:
rxq->delta = 1;
rxq->next_to_update = (u16)((hw_ci + rxq->q_depth - 1) & rxq->q_mask);
rxq->cons_idx = (u16)((rxq->next_to_update + 1) & rxq->q_mask);
@@ -1238,15 +1422,10 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
return err;
}
- if (!rq_pi_rd_en) {
- hinic3_write_db(rxq->rq, rxq->q_id & (NIC_DCB_COS_MAX - 1),
- RQ_CFLAG_DP, (u16)((u32)rxq->next_to_update << rxq->rq->wqe_type));
- } else {
- /* Write all the wqes before pi update */
- wmb();
+ hinic3_write_db(rxq->rq, rxq->q_id & (NIC_DCB_COS_MAX - 1),
+ RQ_CFLAG_DP,
+ (u16)((u32)rxq->next_to_update << rxq->rq->wqe_type));
- hinic3_update_rq_hw_pi(rxq->rq, rxq->next_to_update);
- }
return 0;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
index f4d6f4f..7dd4618 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
@@ -4,6 +4,9 @@
#ifndef HINIC3_RX_H
#define HINIC3_RX_H
+#ifdef HAVE_PAGE_POOL_SUPPORT
+#include <net/page_pool.h>
+#endif
#include <linux/types.h>
#include <linux/device.h>
#include <linux/mm_types.h>
@@ -27,22 +30,22 @@
#define HINIC3_RX_CSUM_IPSU_OTHER_ERR BIT(8)
#define HINIC3_HEADER_DATA_UNIT 2
+#define HINIC3_CQE_LEN 32
struct hinic3_rxq_stats {
- u64 packets;
- u64 bytes;
- u64 errors;
- u64 csum_errors;
- u64 other_errors;
- u64 dropped;
- u64 xdp_dropped;
- u64 rx_buf_empty;
-
- u64 alloc_skb_err;
- u64 alloc_rx_buf_err;
- u64 xdp_large_pkt;
- u64 restore_drop_sge;
- u64 rsvd2;
+ u64 packets;
+ u64 bytes;
+ u64 errors;
+ u64 csum_errors;
+ u64 other_errors;
+ u64 dropped;
+ u64 xdp_dropped;
+ u64 rx_buf_empty;
+ u64 alloc_skb_err;
+ u64 alloc_rx_buf_err;
+ u64 xdp_large_pkt;
+ u64 restore_drop_sge;
+ u64 rsvd2;
#ifdef HAVE_NDO_GET_STATS64
struct u64_stats_sync syncp;
#else
@@ -56,6 +59,9 @@ struct hinic3_rx_info {
struct hinic3_rq_cqe *cqe;
dma_addr_t cqe_dma;
struct page *page;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
u32 page_offset;
u32 rsvd1;
struct hinic3_rq_wqe *rq_wqe;
@@ -96,7 +102,7 @@ struct hinic3_rxq {
u16 next_to_update;
struct device *dev; /* device for DMA mapping */
- unsigned long status;
+ u64 status;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
@@ -124,6 +130,9 @@ struct hinic3_dyna_rxq_res {
struct hinic3_rx_info *rx_info;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
};
int hinic3_alloc_rxqs(struct net_device *netdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
index bdd5a8e..051f05d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
@@ -11,9 +11,10 @@
#ifndef HINIC3_SRV_NIC_H
#define HINIC3_SRV_NIC_H
-#include "hinic3_mgmt_interface.h"
+#include <linux/netdevice.h>
+#include "nic_mpu_cmd_defs.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_lld.h"
enum hinic3_queue_type {
@@ -64,6 +65,7 @@ enum hinic3_nic_event_type {
EVENT_NIC_DCB_STATE_CHANGE,
EVENT_NIC_BOND_DOWN,
EVENT_NIC_BOND_UP,
+ EVENT_NIC_OUTBAND_CFG,
};
/* *
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
index e958782..d3f8696 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
@@ -218,6 +218,77 @@ static void get_inner_l4_info(struct sk_buff *skb, union hinic3_l4 *l4,
}
}
+static void get_inner_l3_l4_type(struct sk_buff *skb, union hinic3_ip *ip,
+ union hinic3_l4 *l4,
+ enum sq_l3_type *l3_type, u8 *l4_proto)
+{
+ unsigned char *exthdr = NULL;
+
+ if (ip->v4->version == IP4_VERSION) {
+ *l3_type = IPV4_PKT_WITH_CHKSUM_OFFLOAD;
+ *l4_proto = ip->v4->protocol;
+
+#ifdef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
+ /* inner_transport_header is wrong in centos7.0 and suse12.1 */
+ l4->hdr = ip->hdr + ((u8)ip->v4->ihl << IP_HDR_IHL_UNIT_SHIFT);
+#endif
+ } else if (ip->v4->version == IP6_VERSION) {
+ *l3_type = IPV6_PKT;
+ exthdr = ip->hdr + sizeof(*ip->v6);
+ *l4_proto = ip->v6->nexthdr;
+ if (exthdr != l4->hdr) {
+ __be16 frag_off = 0;
+#ifndef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
+ ipv6_skip_exthdr(skb, (int)(exthdr - skb->data),
+ l4_proto, &frag_off);
+#else
+ int pld_off = 0;
+
+ pld_off = ipv6_skip_exthdr(skb,
+ (int)(exthdr - skb->data),
+ l4_proto, &frag_off);
+ l4->hdr = skb->data + pld_off;
+#endif
+ }
+ } else {
+ *l3_type = UNKNOWN_L3TYPE;
+ *l4_proto = 0;
+ }
+}
+
+static u8 hinic3_get_inner_l4_type(struct sk_buff *skb)
+{
+ enum sq_l3_type l3_type;
+ u8 l4_proto;
+ union hinic3_ip ip;
+ union hinic3_l4 l4;
+
+ ip.hdr = skb_inner_network_header(skb);
+ l4.hdr = skb_inner_transport_header(skb);
+
+ get_inner_l3_l4_type(skb, &ip, &l4, &l3_type, &l4_proto);
+ return l4_proto;
+}
+
+static void hinic3_set_unknown_tunnel_csum(struct sk_buff *skb)
+{
+ int csum_offset;
+ __sum16 skb_csum;
+ u8 l4_proto;
+
+ l4_proto = hinic3_get_inner_l4_type(skb);
+ /* Unsupport tunnel packet, disable csum offload */
+ skb_checksum_help(skb);
+ /* The value of csum is changed from 0xffff to 0 according to RFC1624 */
+ if (skb->ip_summed == CHECKSUM_NONE && l4_proto != IPPROTO_UDP) {
+ csum_offset = skb_checksum_start_offset(skb) + skb->csum_offset;
+ skb_csum = *(__sum16 *)(skb->data + csum_offset);
+ if (skb_csum == 0xffff) {
+ *(__sum16 *)(skb->data + csum_offset) = 0;
+ }
+ }
+}
+
static int hinic3_tx_csum(struct hinic3_txq *txq, struct hinic3_sq_task *task,
struct sk_buff *skb)
{
@@ -251,11 +322,9 @@ static int hinic3_tx_csum(struct hinic3_txq *txq, struct hinic3_sq_task *task,
l4_proto = IPPROTO_RAW;
}
- if (l4_proto != IPPROTO_UDP ||
- ((struct udphdr *)skb_transport_header(skb))->dest != VXLAN_OFFLOAD_PORT_LE) {
+ if (l4_proto != IPPROTO_UDP) {
TXQ_STATS_INC(txq, unknown_tunnel_pkt);
- /* Unsupport tunnel packet, disable csum offload */
- skb_checksum_help(skb);
+ hinic3_set_unknown_tunnel_csum(skb);
return 0;
}
}
@@ -265,44 +334,6 @@ static int hinic3_tx_csum(struct hinic3_txq *txq, struct hinic3_sq_task *task,
return 1;
}
-static void get_inner_l3_l4_type(struct sk_buff *skb, union hinic3_ip *ip,
- union hinic3_l4 *l4,
- enum sq_l3_type *l3_type, u8 *l4_proto)
-{
- unsigned char *exthdr = NULL;
-
- if (ip->v4->version == IP4_VERSION) {
- *l3_type = IPV4_PKT_WITH_CHKSUM_OFFLOAD;
- *l4_proto = ip->v4->protocol;
-
-#ifdef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
- /* inner_transport_header is wrong in centos7.0 and suse12.1 */
- l4->hdr = ip->hdr + ((u8)ip->v4->ihl << IP_HDR_IHL_UNIT_SHIFT);
-#endif
- } else if (ip->v4->version == IP6_VERSION) {
- *l3_type = IPV6_PKT;
- exthdr = ip->hdr + sizeof(*ip->v6);
- *l4_proto = ip->v6->nexthdr;
- if (exthdr != l4->hdr) {
- __be16 frag_off = 0;
-#ifndef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
- ipv6_skip_exthdr(skb, (int)(exthdr - skb->data),
- l4_proto, &frag_off);
-#else
- int pld_off = 0;
-
- pld_off = ipv6_skip_exthdr(skb,
- (int)(exthdr - skb->data),
- l4_proto, &frag_off);
- l4->hdr = skb->data + pld_off;
-#endif
- }
- } else {
- *l3_type = UNKNOWN_L3TYPE;
- *l4_proto = 0;
- }
-}
-
static void hinic3_set_tso_info(struct hinic3_sq_task *task, u32 *queue_info,
enum sq_l4offload_type l4_offload,
u32 offset, u32 mss)
@@ -463,7 +494,8 @@ static void get_pkt_stats(struct hinic3_tx_info *tx_info, struct sk_buff *skb)
#endif
} else {
#endif
- ihs = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ ihs = (u32)(skb_transport_offset(skb)) +
+ tcp_hdrlen(skb);
#if (defined(HAVE_SKB_INNER_TRANSPORT_HEADER) && \
defined(HAVE_SK_BUFF_ENCAPSULATION))
}
@@ -471,7 +503,8 @@ static void get_pkt_stats(struct hinic3_tx_info *tx_info, struct sk_buff *skb)
hdr_len = (skb_shinfo(skb)->gso_segs - 1) * ihs;
tx_info->num_bytes = skb->len + (u64)hdr_len;
} else {
- tx_info->num_bytes = skb->len > ETH_ZLEN ? skb->len : ETH_ZLEN;
+ tx_info->num_bytes = (skb->len > ETH_ZLEN) ?
+ skb->len : ETH_ZLEN;
}
tx_info->num_pkts = 1;
@@ -626,6 +659,14 @@ static netdev_tx_t hinic3_send_one_skb(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
+ /* l2nic outband vlan cfg enable */
+ if ((!skb_vlan_tag_present(skb)) &&
+ (nic_dev->nic_cap.outband_vlan_cfg_en == 1) &&
+ nic_dev->outband_cfg.outband_default_vid != 0) {
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+ (u16)nic_dev->outband_cfg.outband_default_vid);
+ }
+
offload = hinic3_tx_offload(skb, &task, &queue_info, txq);
if (unlikely(offload == TX_OFFLOAD_INVALID)) {
TXQ_STATS_INC(txq, offload_cow_skb_err);
@@ -834,6 +875,7 @@ int hinic3_alloc_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
tqres->bds = kzalloc(size, GFP_KERNEL);
if (!tqres->bds) {
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc txq%d bds info\n", idx);
goto err_out;
@@ -847,7 +889,9 @@ err_out:
tqres = &txqs_res[i];
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
return -ENOMEM;
@@ -864,7 +908,9 @@ void hinic3_free_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
free_all_tx_skbs(nic_dev, sq_depth, tqres->tx_info);
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
}
@@ -938,6 +984,7 @@ void hinic3_free_txqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->txqs);
+ nic_dev->txqs = NULL;
}
static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
@@ -954,7 +1001,7 @@ static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
static int hinic3_stop_sq(struct hinic3_txq *txq)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(txq->netdev);
- unsigned long timeout;
+ u64 timeout;
int err;
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -963,7 +1010,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
return 0;
usleep_range(900, 1000); /* sleep 900 us ~ 1000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* force hardware to drop packets */
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -976,7 +1023,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
break;
usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* Avoid msleep takes too long and get a fake result */
if (is_hw_complete_sq_process(txq->sq))
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
index 1b9e509..7ae029b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
@@ -29,7 +29,7 @@ struct hinic3_wq {
#define WQ_MASK_IDX(wq, idx) ((idx) & (wq)->idx_mask)
#define WQ_MASK_PAGE(wq, pg_idx) \
- ((pg_idx) < (wq)->num_wq_pages ? (pg_idx) : 0)
+ (((pg_idx) < ((wq)->num_wq_pages)) ? (pg_idx) : 0)
#define WQ_PAGE_IDX(wq, idx) ((idx) >> (wq)->wqebbs_per_page_shift)
#define WQ_OFFSET_IN_PAGE(wq, idx) ((idx) & (wq)->wqebbs_per_page_mask)
#define WQ_GET_WQEBB_ADDR(wq, pg_idx, idx_in_pg) \
@@ -75,7 +75,7 @@ static inline void *hinic3_wq_get_multi_wqebbs(struct hinic3_wq *wq,
pg_idx = WQ_PAGE_IDX(wq, *prod_idx);
off_in_page = WQ_OFFSET_IN_PAGE(wq, *prod_idx);
- if (off_in_page + num_wqebbs > wq->wqebbs_per_page) {
+ if ((off_in_page + num_wqebbs) > wq->wqebbs_per_page) {
/* wqe across wq page boundary */
*second_part_wqebbs_addr =
WQ_GET_WQEBB_ADDR(wq, WQ_MASK_PAGE(wq, pg_idx + 1), 0);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
index b742f8a..0419fc2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
@@ -400,12 +400,16 @@ static int wait_for_status_poll(struct hinic3_api_cmd_chain *chain)
API_CMD_STATUS_TIMEOUT, 100); /* wait 100 us once */
}
-static void copy_resp_data(struct hinic3_api_cmd_cell_ctxt *ctxt, void *ack,
- u16 ack_size)
+static void copy_resp_data(struct hinic3_api_cmd_chain *chain,
+ struct hinic3_api_cmd_cell_ctxt *ctxt,
+ void *ack, u16 ack_size)
{
struct hinic3_api_cmd_resp_fmt *resp = ctxt->resp;
+ int rsp_size_align = chain->rsp_size_align - 0x8;
+ int rsp_size = (ack_size > rsp_size_align) ? rsp_size_align : ack_size;
+
+ memcpy(ack, &resp->resp_data, rsp_size);
- memcpy(ack, &resp->resp_data, ack_size);
ctxt->status = 0;
}
@@ -464,7 +468,7 @@ static int wait_for_api_cmd_completion(struct hinic3_api_cmd_chain *chain,
case HINIC3_API_CMD_POLL_READ:
err = wait_for_resp_polling(ctxt);
if (err == 0)
- copy_resp_data(ctxt, ack, ack_size);
+ copy_resp_data(chain, ctxt, ack, ack_size);
else
sdk_err(dev, "API CMD poll response timeout\n");
break;
@@ -1055,13 +1059,11 @@ alloc_cells_buf_err:
alloc_wb_status_err:
kfree(chain->cell_ctxt);
-/*lint -save -e548*/
alloc_cell_ctxt_err:
if (chain->chain_type == HINIC3_API_CMD_WRITE_ASYNC_TO_MGMT_CPU)
spin_lock_deinit(&chain->async_lock);
else
sema_deinit(&chain->sem);
-/*lint -restore*/
return err;
}
@@ -1078,6 +1080,7 @@ static void api_chain_free(struct hinic3_api_cmd_chain *chain)
dma_free_coherent(dev, sizeof(*chain->wb_status),
chain->wb_status, chain->wb_status_paddr);
kfree(chain->cell_ctxt);
+ chain->cell_ctxt = NULL;
if (chain->chain_type == HINIC3_API_CMD_WRITE_ASYNC_TO_MGMT_CPU)
spin_lock_deinit(&chain->async_lock);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
index 0878186..ceb7636 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
@@ -657,7 +657,7 @@ static int cmdq_sync_cmd_direct_resp(struct hinic3_cmdq *cmdq, u8 mod,
cmd_info->channel = channel;
cmdq_set_cmd_buf(cmd_info, cmdq->hwdev, buf_in, NULL);
- memcpy(&saved_cmd_info, cmd_info, sizeof(*cmd_info));
+ memcpy(&saved_cmd_info, cmd_info, sizeof(struct hinic3_cmdq_cmd_info));
cmdq_set_lcmd_wqe(&wqe, SYNC_CMD_DIRECT_RESP, buf_in, NULL,
wrapped, mod, cmd, curr_prod_idx);
@@ -745,7 +745,7 @@ static int cmdq_sync_cmd_detail_resp(struct hinic3_cmdq *cmdq, u8 mod, u8 cmd,
cmd_info->channel = channel;
cmdq_set_cmd_buf(cmd_info, cmdq->hwdev, buf_in, buf_out);
- memcpy(&saved_cmd_info, cmd_info, sizeof(*cmd_info));
+ memcpy(&saved_cmd_info, cmd_info, sizeof(struct hinic3_cmdq_cmd_info));
cmdq_set_lcmd_wqe(&wqe, SYNC_CMD_SGE_RESP, buf_in, buf_out,
wrapped, mod, cmd, curr_prod_idx);
@@ -994,9 +994,11 @@ int hinic3_cmdq_async(void *hwdev, u8 mod, u8 cmd, struct hinic3_cmd_buf *buf_in
return cmdq_async_cmd(&cmdqs->cmdq[HINIC3_CMDQ_SYNC], mod,
cmd, buf_in, channel);
}
+EXPORT_SYMBOL(hinic3_cmdq_async);
int hinic3_cmdq_async_cos(void *hwdev, u8 mod, u8 cmd,
- u8 cos_id, struct hinic3_cmd_buf *buf_in, u16 channel)
+ u8 cos_id, struct hinic3_cmd_buf *buf_in,
+ u16 channel)
{
struct hinic3_cmdqs *cmdqs = NULL;
int err;
@@ -1136,7 +1138,7 @@ void hinic3_cmdq_ceq_handler(void *handle, u32 ceqe_data)
break;
case HINIC3_CMD_TYPE_SET_ARM:
/* arm_bit was set until here */
- if (cmdq_arm_ceq_handler(cmdq, wqe, ci))
+ if (cmdq_arm_ceq_handler(cmdq, wqe, ci) != 0)
return;
break;
default:
@@ -1221,6 +1223,7 @@ cmd_infos_err:
static void free_cmdq(struct hinic3_cmdq *cmdq)
{
kfree(cmdq->cmd_infos);
+ cmdq->cmd_infos = NULL;
spin_lock_deinit(&cmdq->cmdq_lock);
}
@@ -1425,7 +1428,7 @@ static int create_cmdq_wq(struct hinic3_cmdqs *cmdqs)
type = HINIC3_CMDQ_SYNC;
for (; type < cmdqs->cmdq_num; type++)
memcpy((u8 *)cmdqs->wq_block_vaddr +
- CMDQ_WQ_CLA_SIZE * type,
+ ((u64)type * CMDQ_WQ_CLA_SIZE),
cmdqs->cmdq[type].wq.wq_block_vaddr,
cmdqs->cmdq[type].wq.num_wq_pages * sizeof(u64));
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
index b0344ea..b174ad2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
@@ -14,11 +14,6 @@
#include "hinic3_common.h"
#include "hinic3_hwdev.h"
-struct dma_pool {
- unsigned int size;
- void *dev_hdl;
-};
-
#define HINIC3_SCMD_DATA_LEN 16
#define HINIC3_CMDQ_DEPTH 4096
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
index 4c13a2e..af336f2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
@@ -22,11 +22,15 @@
#include "hinic3_sriov.h"
#include "hinic3_nictool.h"
#include "hinic3_pci_id_tbl.h"
+#include "hinic3_hwdev.h"
+#include "cfg_mgmt_mpu_cmd_defs.h"
+#include "mpu_cmd_base_defs.h"
#include "hinic3_dev_mgmt.h"
#define HINIC3_WAIT_TOOL_CNT_TIMEOUT 10000
#define HINIC3_WAIT_TOOL_MIN_USLEEP_TIME 9900
#define HINIC3_WAIT_TOOL_MAX_USLEEP_TIME 10000
+#define HIGHT_BDF 8
static unsigned long card_bit_map;
@@ -60,15 +64,23 @@ void lld_dev_cnt_init(struct hinic3_pcidev *pci_adapter)
void lld_dev_hold(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_inc(&pci_adapter->ref_cnt);
}
void lld_dev_put(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_dec(&pci_adapter->ref_cnt);
}
@@ -236,6 +248,40 @@ void hinic3_get_all_chip_id(void *id_info)
card_id->num = (u32)i;
}
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+ u64 bar1_phy_addr = 0;
+ u64 bar3_phy_addr = 0;
+ u64 bar1_size = 0;
+ u64 bar3_size = 0;
+
+ lld_hold();
+
+ /* get PF bar1 or bar3 physical address to verify */
+ list_for_each_entry(chip_node, &g_hinic3_chip_list, node) {
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (hinic3_func_type(dev->hwdev) == TYPE_VF)
+ continue;
+
+ bar1_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+ bar1_size = pci_resource_len(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+
+ bar3_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ bar3_size = pci_resource_len(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ if ((phy_addr == bar1_phy_addr && vmsize <= bar1_size) ||
+ (phy_addr == bar3_phy_addr && vmsize <= bar3_size)) {
+ lld_put();
+ return 0;
+ }
+ }
+ }
+
+ lld_put();
+ return -EINVAL;
+}
+
void hinic3_get_card_func_info_by_card_name(const char *chip_name,
struct hinic3_card_func_info *card_func)
{
@@ -328,7 +374,6 @@ out:
if (dev)
lld_dev_hold(dev);
lld_put();
-
return dev;
}
@@ -422,6 +467,28 @@ struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name
return NULL;
}
+void *hinic3_get_ppf_dev(void)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct list_head *chip_list = NULL;
+
+ lld_hold();
+ chip_list = get_hinic3_chip_list();
+
+ list_for_each_entry(chip_node, chip_list, node)
+ list_for_each_entry(pci_adapter, &chip_node->func_list, node)
+ if (hinic3_func_type(pci_adapter->hwdev) == TYPE_PPF) {
+ pr_info("Get ppf_func_id:%u", hinic3_global_func_id(pci_adapter->hwdev));
+ lld_put();
+ return pci_adapter->lld_dev.hwdev;
+ }
+
+ lld_put();
+ return NULL;
+}
+EXPORT_SYMBOL(hinic3_get_ppf_dev);
+
struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
enum hinic3_service_type type)
{
@@ -518,6 +585,7 @@ EXPORT_SYMBOL(hinic3_get_ppf_lld_dev_unsafe);
int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len)
{
struct hinic3_pcidev *pci_adapter = NULL;
+ int ret = 0;
if (!lld_dev || !chip_name || !max_len)
return -EINVAL;
@@ -527,12 +595,18 @@ int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 ma
return -EFAULT;
lld_hold();
- strncpy(chip_name, pci_adapter->chip_node->chip_name, max_len);
+ if (strscpy(chip_name, pci_adapter->chip_node->chip_name, max_len) < 0)
+ goto RELEASE;
chip_name[max_len - 1] = '\0';
lld_put();
return 0;
+
+RELEASE:
+ lld_put();
+
+ return ret;
}
EXPORT_SYMBOL(hinic3_get_chip_name);
@@ -541,6 +615,81 @@ struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev)
return lld_dev->hwdev;
}
+void hinic3_write_oshr_info(struct os_hot_replace_info *out_oshr_info,
+ struct hw_pf_info *info,
+ struct hinic3_board_info *board_info,
+ struct card_node *chip_node, u32 serivce_enable,
+ u32 func_info_idx)
+{
+ out_oshr_info->func_infos[func_info_idx].pf_idx = info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].backup_pf =
+ (((info->glb_func_idx) / (board_info->port_num)) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ ((info->glb_func_idx) + (board_info->port_num)) :
+ ((info->glb_func_idx) - (board_info->port_num));
+ out_oshr_info->func_infos[func_info_idx].partition =
+ ((info->glb_func_idx) / (board_info->port_num)) % HOT_REPLACE_PARTITION_NUM;
+ out_oshr_info->func_infos[func_info_idx].port_id = info->port_id;
+ out_oshr_info->func_infos[func_info_idx].bdf = (info->bus_num << HIGHT_BDF) + info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].bus_num = chip_node->bus_num;
+ out_oshr_info->func_infos[func_info_idx].valid = serivce_enable;
+ memcpy(out_oshr_info->func_infos[func_info_idx].card_name,
+ chip_node->chip_name, IFNAMSIZ);
+}
+
+void hinic3_get_os_hot_replace_info(void *oshr_info)
+{
+ struct os_hot_replace_info *out_oshr_info = (struct os_hot_replace_info *)oshr_info;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dst_dev = NULL;
+ struct hinic3_board_info *board_info = NULL;
+ struct hw_pf_info *infos = NULL;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ u32 func_info_idx = 0, func_id = 0, func_num, serivce_enable = 0;
+ struct list_head *hinic3_chip_list = get_hinic3_chip_list();
+ int err;
+
+ lld_hold();
+ pf_infos = kzalloc(sizeof(struct hinic3_hw_pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ pr_err("kzalloc pf_infos fail\n");
+ lld_put();
+ return;
+ }
+ list_for_each_entry(chip_node, hinic3_chip_list, node) {
+ list_for_each_entry(dst_dev, &chip_node->func_list, node) { // get all pf infos in one time by one pf_id
+ err = hinic3_get_hw_pf_infos(dst_dev->hwdev, pf_infos, HINIC3_CHANNEL_COMM);
+ if (err != 0) {
+ pr_err("get pf info failed\n");
+ break;
+ }
+
+ serivce_enable = 0;
+ infos = pf_infos->infos;
+ board_info = &((struct hinic3_hwdev *)(dst_dev->hwdev))->board_info;
+ if (((struct hinic3_hwdev *)(dst_dev->hwdev))->hot_replace_mode == HOT_REPLACE_ENABLE) {
+ serivce_enable = 1;
+ }
+ break;
+ }
+
+ func_num = pf_infos->num_pfs;
+ if (func_num <= 0) {
+ pr_err("get pf num failed\n");
+ break;
+ }
+
+ for (func_id = 0; func_id < func_num; func_id++) {
+ hinic3_write_oshr_info(out_oshr_info, &infos[func_id],
+ board_info, chip_node,
+ serivce_enable, func_info_idx);
+ func_info_idx++;
+ }
+ }
+ out_oshr_info->func_cnt = func_info_idx;
+ kfree(pf_infos);
+ lld_put();
+}
+
struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(lld_dev->pdev);
@@ -620,9 +769,13 @@ void hinic3_get_card_info(const void *hwdev, void *bufin)
}
if (hinic3_func_for_mgmt(fun_hwdev))
- strlcpy(info->pf[i].name, "FOR_MGMT", IFNAMSIZ);
+ strscpy(info->pf[i].name, "FOR_MGMT", IFNAMSIZ);
+
+ if (dev->lld_dev.pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID) {
+ strscpy(info->pf[i].name, "bifur", IFNAMSIZ);
+ }
- strlcpy(info->pf[i].bus_info, pci_name(dev->pcidev),
+ strscpy(info->pf[i].bus_info, pci_name(dev->pcidev),
sizeof(info->pf[i].bus_info));
info->pf_num++;
i = info->pf_num;
@@ -719,6 +872,7 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
struct card_node *chip_node = NULL;
unsigned char i;
unsigned char bus_number = 0;
+ int err;
if (chip_node_is_exist(pci_adapter, &bus_number))
return 0;
@@ -750,6 +904,13 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
return -EINVAL;
}
+ err = sscanf(chip_node->chip_name, HINIC3_CHIP_NAME "%d", &(chip_node->chip_id));
+ if (err <= 0) {
+ clear_bit(i, &card_bit_map);
+ kfree(chip_node);
+ return -EINVAL;
+ }
+
sdk_info(&pci_adapter->pcidev->dev,
"Add new chip %s to global list succeed\n",
chip_node->chip_name);
@@ -801,3 +962,36 @@ int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *
return 0;
}
+
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin)
+{
+ struct card_node *chip_node = NULL;
+ struct card_mbox_cnt_info *info = (struct card_mbox_cnt_info *)bufin;
+ struct hinic3_pcidev *dev = NULL;
+ struct hinic3_hwdev *func_hwdev = NULL;
+ u32 i = 0;
+
+ info->func_num = 0;
+ chip_node = hinic3_get_chip_node_by_hwdev(hwdev);
+ if (chip_node == NULL)
+ return;
+
+ lld_hold();
+
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ func_hwdev = (struct hinic3_hwdev *)dev->hwdev;
+ strscpy(info->func_info[i].bus_info, pci_name(dev->pcidev),
+ sizeof(info->func_info[i].bus_info));
+
+ info->func_info[i].send_cnt = func_hwdev->mbox_send_cnt;
+ info->func_info[i].ack_cnt = func_hwdev->mbox_ack_cnt;
+ info->func_num++;
+ i = info->func_num;
+ if (i >= ARRAY_SIZE(info->func_info)) {
+ sdk_err(&dev->pcidev->dev, "chip_node->func_list bigger than pf_max + vf_max\n");
+ break;
+ }
+ }
+
+ lld_put();
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
index a327c4a..bfa8f3e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
@@ -19,8 +19,10 @@
#define PRINT_ULD_DETACH_TIMEOUT_INTERVAL 1000 /* 1 second */
#define ULD_LOCK_MIN_USLEEP_TIME 900
#define ULD_LOCK_MAX_USLEEP_TIME 1000
+#define BIFUR_RESOURCE_PF_SSID 0x05a1
-#define HINIC3_IS_VF_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_VF)
+#define HINIC3_IS_VF_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_VF || \
+ (pdev)->device == HINIC3_DEV_SDI_5_1_ID_VF)
#define HINIC3_IS_SPU_DEV(pdev) \
(((pdev)->device == HINIC3_DEV_ID_SPU) || ((pdev)->device == HINIC3_DEV_ID_SDI_5_0_PF) || \
(((pdev)->device == HINIC3_DEV_ID_DPU_PF)))
@@ -79,6 +81,13 @@ struct hinic3_pcidev {
u16 probe_fault_level;
u16 rsvd2;
u64 rsvd4;
+
+ struct workqueue_struct *multi_host_mgmt_workq;
+ struct work_struct slave_nic_work;
+ struct work_struct slave_vroce_work;
+
+ struct workqueue_struct *migration_probe_workq;
+ struct delayed_work migration_probe_dwork;
};
struct hinic_chip_info {
@@ -104,4 +113,6 @@ void wait_lld_dev_unused(struct hinic3_pcidev *pci_adapter);
void *hinic3_get_hwdev_by_pcidev(struct pci_dev *pdev);
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
index 1949ab8..8f9d00a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
@@ -101,7 +101,8 @@ static bool check_image_device_type(struct hinic3_hwdev *hwdev, u32 device_type)
static void encapsulate_update_cmd(struct hinic3_cmd_update_firmware *msg,
struct firmware_section *section_info,
- int *remain_len, u32 *send_len, u32 *send_pos)
+ const int *remain_len, u32 *send_len,
+ u32 *send_pos)
{
memset(msg->data, 0, sizeof(msg->data));
msg->ctl_info.sf = (*remain_len == section_info->section_len) ? true : false;
@@ -380,6 +381,7 @@ int hinic3_init_devlink(struct hinic3_hwdev *hwdev)
struct pci_dev *pdev = NULL;
int err;
+ pdev = hwdev->hwif->pdev;
devlink = devlink_alloc(&hinic3_devlink_ops, sizeof(struct hinic3_devlink));
if (!devlink) {
sdk_err(hwdev->dev_hdl, "Failed to alloc devlink\n");
@@ -391,7 +393,6 @@ int hinic3_init_devlink(struct hinic3_hwdev *hwdev)
hwdev->devlink_dev->activate_fw = FW_CFG_DEFAULT_INDEX;
hwdev->devlink_dev->switch_cfg = FW_CFG_DEFAULT_INDEX;
- pdev = hwdev->hwif->pdev;
err = devlink_register(devlink, &pdev->dev);
if (err) {
sdk_err(hwdev->dev_hdl, "Failed to register devlink\n");
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
index 4b08aa0..caa99e3 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
@@ -26,6 +26,8 @@
#include "hinic3_prof_adap.h"
#include "hinic3_eqs.h"
+#include "vram_common.h"
+
#define HINIC3_EQS_WQ_NAME "hinic3_eqs"
#define AEQ_CTRL_0_INTR_IDX_SHIFT 0
@@ -66,7 +68,6 @@
#define HINIC3_TASK_PROCESS_EQE_LIMIT 1024
#define HINIC3_EQ_UPDATE_CI_STEP 64
-/*lint -e806*/
static uint g_aeq_len = HINIC3_DEFAULT_AEQ_LEN;
module_param(g_aeq_len, uint, 0444);
MODULE_PARM_DESC(g_aeq_len,
@@ -83,7 +84,6 @@ static uint g_num_ceqe_in_tasklet = HINIC3_TASK_PROCESS_EQE_LIMIT;
module_param(g_num_ceqe_in_tasklet, uint, 0444);
MODULE_PARM_DESC(g_num_ceqe_in_tasklet,
"The max number of ceqe can be processed in tasklet, default = 1024");
-/*lint +e806*/
#define CEQ_CTRL_0_INTR_IDX_SHIFT 0
#define CEQ_CTRL_0_DMA_ATTR_SHIFT 12
@@ -801,6 +801,7 @@ static int alloc_eq_pages(struct hinic3_eq *eq)
u32 reg, init_val;
u16 pg_idx, i;
int err;
+ gfp_t gfp_vram;
eq->eq_pages = kcalloc(eq->num_pages, sizeof(*eq->eq_pages),
GFP_KERNEL);
@@ -809,12 +810,15 @@ static int alloc_eq_pages(struct hinic3_eq *eq)
return -ENOMEM;
}
+ gfp_vram = hi_vram_get_gfp_vram();
+
for (pg_idx = 0; pg_idx < eq->num_pages; pg_idx++) {
eq_page = &eq->eq_pages[pg_idx];
err = hinic3_dma_zalloc_coherent_align(eq->hwdev->dev_hdl,
eq->page_size,
HINIC3_MIN_EQ_PAGE_SIZE,
- GFP_KERNEL, eq_page);
+ GFP_KERNEL | gfp_vram,
+ eq_page);
if (err) {
sdk_err(eq->hwdev->dev_hdl, "Failed to alloc eq page, page index: %hu\n",
pg_idx);
@@ -865,6 +869,7 @@ static void free_eq_pages(struct hinic3_eq *eq)
&eq->eq_pages[pg_idx]);
kfree(eq->eq_pages);
+ eq->eq_pages = NULL;
}
static inline u32 get_page_size(const struct hinic3_eq *eq)
@@ -1104,7 +1109,8 @@ int hinic3_aeqs_init(struct hinic3_hwdev *hwdev, u16 num_aeqs,
hwdev->aeqs = aeqs;
aeqs->hwdev = hwdev;
aeqs->num_aeqs = num_aeqs;
- aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME, WQ_MEM_RECLAIM,
+ aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME,
+ WQ_MEM_RECLAIM | WQ_HIGHPRI,
HINIC3_MAX_AEQS);
if (!aeqs->workq) {
sdk_err(hwdev->dev_hdl, "Failed to initialize aeq workqueue\n");
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
index a4cbac8..6b96b87 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
@@ -82,6 +82,48 @@ int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id,
return 0;
}
+/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read and clear to zero
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
+ u16 *value)
+{
+ struct chipif_sml_ctr_rd_req req;
+ union ctr_rd_rsp rsp;
+ int ret;
+
+ if (!hwdev || !value)
+ return -EFAULT;
+
+ if (!COMM_SUPPORT_API_CHAIN((struct hinic3_hwdev *)hwdev))
+ return -EPERM;
+
+ memset(&req, 0, sizeof(req));
+
+ hinic3_sml_ctr_read_build_req(&req, instance,
+ CHIPIF_SM_CTR_OP_READ_CLEAR,
+ CHIPIF_ACK, ctr_id, 0);
+
+ ret = hinic3_api_cmd_read_ack(hwdev, node, (u8 *)&req,
+ (unsigned short)sizeof(req),
+ (void *)&rsp,
+ (unsigned short)sizeof(rsp));
+ if (ret) {
+ sdk_err(((struct hinic3_hwdev *)hwdev)->dev_hdl,
+ "Sm 16bit counter clear fail, err(%d)\n", ret);
+ return ret;
+ }
+ sml_ctr_htonl_n((u32 *)&rsp, sizeof(rsp) / sizeof(u32));
+ *value = rsp.bs_ss16_rsp.value1;
+
+ return 0;
+}
+
/**
* hinic3_sm_ctr_rd32 - small single 32 counter read
* @hwdev: the hardware device
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
index cea7581..2d4a9f6 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
@@ -34,13 +34,16 @@ static void parse_pub_res_cap_dfx(struct hinic3_hwdev *hwdev,
cap->max_vf);
sdk_info(hwdev->dev_hdl, "Host_pf_num: 0x%x, pf_id_start: 0x%x, host_vf_num: 0x%x, vf_id_start: 0x%x\n",
cap->pf_num, cap->pf_id_start, cap->vf_num, cap->vf_id_start);
- sdk_info(hwdev->dev_hdl, "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x\n",
- cap->host_valid_bitmap, cap->master_host_id, cap->srv_multi_host_mode);
sdk_info(hwdev->dev_hdl,
- "fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
- cap->fake_vf_start_id, cap->fake_vf_num, cap->fake_vf_max_pctx);
- sdk_info(hwdev->dev_hdl, "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x\n",
- cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len);
+ "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x, hot_plug_disable: 0x%x\n",
+ cap->host_valid_bitmap, cap->master_host_id, cap->srv_multi_host_mode,
+ cap->hot_plug_disable);
+ sdk_info(hwdev->dev_hdl,
+ "os_hot_replace: 0x%x, fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
+ cap->os_hot_replace, cap->fake_vf_start_id, cap->fake_vf_num, cap->fake_vf_max_pctx);
+ sdk_info(hwdev->dev_hdl,
+ "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x, bond_create_mode: 0x%x\n",
+ cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len, cap->bond_create_mode);
}
static void parse_cqm_res_cap(struct hinic3_hwdev *hwdev, struct service_cap *cap,
@@ -109,6 +112,9 @@ static void parse_pub_res_cap(struct hinic3_hwdev *hwdev,
cap->host_valid_bitmap = dev_cap->host_valid_bitmap;
cap->master_host_id = dev_cap->master_host_id;
cap->srv_multi_host_mode = dev_cap->srv_multi_host_mode;
+ cap->hot_plug_disable = dev_cap->hot_plug_disable;
+ cap->bond_create_mode = dev_cap->bond_create_mode;
+ cap->os_hot_replace = dev_cap->os_hot_replace;
cap->fake_vf_en = dev_cap->fake_vf_en;
cap->fake_vf_start_bit = dev_cap->fake_vf_start_bit;
cap->fake_vf_end_bit = dev_cap->fake_vf_end_bit;
@@ -148,18 +154,27 @@ static void parse_l2nic_res_cap(struct hinic3_hwdev *hwdev,
nic_cap->max_sqs = dev_cap->nic_max_sq_id + 1;
nic_cap->max_rqs = dev_cap->nic_max_rq_id + 1;
nic_cap->default_num_queues = dev_cap->nic_default_num_queues;
+ nic_cap->outband_vlan_cfg_en = dev_cap->outband_vlan_cfg_en;
+ nic_cap->lro_enable = dev_cap->lro_enable;
sdk_info(hwdev->dev_hdl, "L2nic resource capbility, max_sqs: 0x%x, max_rqs: 0x%x\n",
nic_cap->max_sqs, nic_cap->max_rqs);
/* Check parameters from firmware */
- if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP ||
- nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
- sdk_info(hwdev->dev_hdl, "Number of qp exceed limit[1-%d]: sq: %u, rq: %u\n",
- HINIC3_CFG_MAX_QP, nic_cap->max_sqs, nic_cap->max_rqs);
+ if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of sq exceed limit[1-%d]: sq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_sqs);
nic_cap->max_sqs = HINIC3_CFG_MAX_QP;
+ }
+
+ if (nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of rq exceed limit[1-%d]: rq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_rqs);
nic_cap->max_rqs = HINIC3_CFG_MAX_QP;
}
+
+ if (nic_cap->outband_vlan_cfg_en)
+ sdk_info(hwdev->dev_hdl, "L2nic outband vlan cfg enabled\n");
}
static void parse_fc_res_cap(struct hinic3_hwdev *hwdev,
@@ -333,6 +348,28 @@ static void parse_ipsec_res_cap(struct hinic3_hwdev *hwdev,
dev_cap->ipsec_max_sactx, dev_cap->ipsec_max_cq);
}
+static void parse_vbs_res_cap(struct hinic3_hwdev *hwdev,
+ struct service_cap *cap,
+ struct cfg_cmd_dev_cap *dev_cap,
+ enum func_type type)
+{
+ struct vbs_service_cap *vbs_cap = &cap->vbs_cap;
+
+ vbs_cap->vbs_max_volq = dev_cap->vbs_max_volq;
+ vbs_cap->vbs_main_pf_enable = dev_cap->vbs_main_pf_enable;
+ vbs_cap->vbs_vsock_pf_enable = dev_cap->vbs_vsock_pf_enable;
+ vbs_cap->vbs_fushion_queue_pf_enable = dev_cap->vbs_fushion_queue_pf_enable;
+
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS resource capbility, vbs_max_volq: 0x%x\n",
+ dev_cap->vbs_max_volq);
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS pf info, vbs_main_pf_enable: 0x%x, vbs_vsock_pf_enable: 0x%x, vbs_fushion_queue_pf_enable: 0x%x\n",
+ dev_cap->vbs_main_pf_enable,
+ dev_cap->vbs_vsock_pf_enable,
+ dev_cap->vbs_fushion_queue_pf_enable);
+}
+
static void parse_dev_cap(struct hinic3_hwdev *dev,
struct cfg_cmd_dev_cap *dev_cap, enum func_type type)
{
@@ -375,6 +412,9 @@ static void parse_dev_cap(struct hinic3_hwdev *dev,
if (IS_PPA_TYPE(dev))
parse_ppa_res_cap(dev, cap, dev_cap, type);
+
+ if (IS_VBS_TYPE(dev))
+ parse_vbs_res_cap(dev, cap, dev_cap, type);
}
static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
@@ -404,6 +444,23 @@ static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
return 0;
}
+u8 hinic3_get_bond_create_mode(void *dev)
+{
+ struct hinic3_hwdev *hwdev = NULL;
+ struct service_cap *cap = NULL;
+
+ if (!dev) {
+ pr_err("pointer dev is NULL\n");
+ return -EINVAL;
+ }
+
+ hwdev = (struct hinic3_hwdev *)dev;
+ cap = &hwdev->cfg_mgmt->svc_cap;
+
+ return cap->bond_create_mode;
+}
+EXPORT_SYMBOL(hinic3_get_bond_create_mode);
+
int hinic3_get_dev_cap(void *dev)
{
enum func_type type;
@@ -1173,6 +1230,20 @@ bool hinic3_support_ppa(void *hwdev, struct ppa_service_cap *cap)
}
EXPORT_SYMBOL(hinic3_support_ppa);
+bool hinic3_support_bifur(void *hwdev, struct bifur_service_cap *cap)
+{
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)hwdev;
+
+ if (!hwdev)
+ return false;
+
+ if (!IS_BIFUR_TYPE(dev))
+ return false;
+
+ return true;
+}
+EXPORT_SYMBOL(hinic3_support_bifur);
+
bool hinic3_support_migr(void *hwdev, struct migr_service_cap *cap)
{
struct hinic3_hwdev *dev = hwdev;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
index db6e3ca..7157e97 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
@@ -166,6 +166,11 @@ struct service_cap {
u8 srv_multi_host_mode;
u16 virtio_vq_size;
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 os_hot_replace;
+ u8 rsvd1;
+
u8 timer_pf_num;
u8 timer_pf_id_start;
u16 timer_vf_num;
@@ -319,9 +324,11 @@ struct cfg_mgmt_info {
#define IS_RDMA_ENABLE(dev) \
((dev)->cfg_mgmt->svc_cap.sf_svc_attr.rdma_en)
#define IS_PPA_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_PPA)
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_PPA)
#define IS_MIGR_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_MIGRATE)
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_MIGRATE)
+#define IS_BIFUR_TYPE(dev) \
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_BIFUR)
int init_cfg_mgmt(struct hinic3_hwdev *dev);
@@ -333,5 +340,7 @@ void free_capability(struct hinic3_hwdev *dev);
int hinic3_init_vf_dev_cap(void *hwdev);
+u8 hinic3_get_bond_create_mode(void *dev);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
index d8a1a28..47264f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
@@ -21,7 +21,9 @@
#include "hinic3_hw_cfg.h"
#include "hinic3_cmdq.h"
#include "mpu_inband_cmd_defs.h"
+#include "mpu_board_defs.h"
#include "hinic3_hw_comm.h"
+#include "vram_common.h"
#define HINIC3_MSIX_CNT_LLI_TIMER_SHIFT 0
#define HINIC3_MSIX_CNT_LLI_CREDIT_SHIFT 8
@@ -242,12 +244,19 @@ int hinic3_func_reset(void *dev, u16 func_id, u64 reset_flag, u16 channel)
struct hinic3_hwdev *hwdev = dev;
u16 out_size = sizeof(func_reset);
int err = 0;
+ int is_in_kexec;
if (!dev) {
pr_err("Invalid para: dev is null.\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ sdk_info(hwdev->dev_hdl, "Skip function reset!\n");
+ return 0;
+ }
+
sdk_info(hwdev->dev_hdl, "Function is reset, flag: 0x%llx, channel:0x%x\n",
reset_flag, channel);
@@ -523,7 +532,7 @@ EXPORT_SYMBOL(hinic3_set_ppf_flr_type);
int hinic3_set_ppf_tbl_hotreplace_flag(void *hwdev, u8 flag)
{
- struct comm_cmd_ppf_tbl_htrp_config htr_info = {0};
+ struct comm_cmd_ppf_tbl_htrp_config htr_info = {};
u16 out_size = sizeof(struct comm_cmd_ppf_tbl_htrp_config);
struct hinic3_hwdev *dev = hwdev;
int ret;
@@ -868,11 +877,19 @@ static int set_ppf_tmr_status(struct hinic3_hwdev *hwdev,
int hinic3_ppf_tmr_start(void *hwdev)
{
+ int is_in_kexec;
+
if (!hwdev) {
pr_err("Hwdev pointer is NULL for starting ppf timer\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ pr_info("Skip starting ppt timer during kexec");
+ return 0;
+ }
+
return set_ppf_tmr_status(hwdev, HINIC_PPF_TMR_FLAG_START);
}
EXPORT_SYMBOL(hinic3_ppf_tmr_start);
@@ -888,18 +905,110 @@ int hinic3_ppf_tmr_stop(void *hwdev)
}
EXPORT_SYMBOL(hinic3_ppf_tmr_stop);
+static int hi_vram_kalloc_align(struct hinic3_hwdev *hwdev, char *name,
+ u32 page_size, u32 page_num,
+ struct hinic3_dma_addr_align *mem_align)
+{
+ void *vaddr = NULL, *align_vaddr = NULL;
+ dma_addr_t paddr, align_paddr;
+ u64 real_size = page_size;
+ u64 align = page_size;
+
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ /* align */
+ if (align_paddr == paddr) {
+ align_vaddr = vaddr;
+ goto out;
+ }
+
+ hi_vram_kfree((void *)vaddr, name, real_size);
+
+ /* realloc memory for align */
+ real_size = page_size + align;
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc align failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ align_vaddr = (void *)((u64)vaddr + (align_paddr - paddr));
+
+out:
+ mem_align->real_size = (u32)real_size;
+ mem_align->ori_vaddr = vaddr;
+ mem_align->ori_paddr = paddr;
+ mem_align->align_vaddr = align_vaddr;
+ mem_align->align_paddr = align_paddr;
+
+ return 0;
+}
+
+static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
+{
+ u32 i;
+ struct hinic3_dma_addr_align *page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = hwdev->mqm_eqm_vram_name;
+
+ page_addr = hwdev->mqm_att.brm_srch_page_addr;
+
+ for (i = 0; i < hwdev->mqm_att.page_num; i++) {
+ if (is_use_vram != 0) {
+ hi_vram_kfree(page_addr->ori_vaddr, mqm_eqm_vram_name[i].vram_name,
+ page_addr->real_size);
+ } else {
+ hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
+ }
+ page_addr->ori_vaddr = NULL;
+ page_addr++;
+ }
+
+ kfree(mqm_eqm_vram_name);
+ hwdev->mqm_eqm_vram_name = NULL;
+}
+
static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
u32 page_num)
{
struct hinic3_dma_addr_align *page_addr = hwdev->mqm_att.brm_srch_page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = NULL;
u32 valid_num = 0;
u32 flag = 1;
u32 i = 0;
int err;
+ u16 func_id;
+
+ mqm_eqm_vram_name = kzalloc(sizeof(struct mqm_eqm_vram_name_s) * page_num, GFP_KERNEL);
+ if (mqm_eqm_vram_name == NULL) {
+ sdk_err(hwdev->dev_hdl, "mqm eqm alloc vram name failed.\n");
+ return -ENOMEM;
+ }
+
+ hwdev->mqm_eqm_vram_name = mqm_eqm_vram_name;
+ func_id = hinic3_global_func_id(hwdev);
for (i = 0; i < page_num; i++) {
- err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl, page_size,
- page_size, GFP_KERNEL, page_addr);
+ if (is_use_vram != 0) {
+ snprintf(mqm_eqm_vram_name[i].vram_name,
+ VRAM_NAME_MAX_LEN, "%s%u%s%u",
+ VRAM_CQM_GLB_FUNC_BASE, func_id, VRAM_NIC_MQM, i);
+ err = hi_vram_kalloc_align(
+ hwdev, mqm_eqm_vram_name[i].vram_name,
+ page_size, page_num, page_addr);
+ } else {
+ err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl, page_size,
+ page_size, GFP_KERNEL, page_addr);
+ }
if (err) {
flag = 0;
break;
@@ -908,15 +1017,12 @@ static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
page_addr++;
}
+ hwdev->mqm_att.page_num = valid_num;
+
if (flag == 1) {
hwdev->mqm_att.page_size = page_size;
- hwdev->mqm_att.page_num = page_num;
} else {
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
- for (i = 0; i < valid_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
+ mqm_eqm_free_page_mem(hwdev);
return -EFAULT;
}
@@ -955,19 +1061,6 @@ static int mqm_eqm_alloc_page_mem(struct hinic3_hwdev *hwdev)
return ret;
}
-static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
-{
- u32 i;
- struct hinic3_dma_addr_align *page_addr;
-
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
-
- for (i = 0; i < hwdev->mqm_att.page_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
-}
-
static int mqm_eqm_set_cfg_2_hw(struct hinic3_hwdev *hwdev, u8 valid)
{
struct comm_cmd_eqm_cfg info_eqm_cfg;
@@ -1098,6 +1191,7 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
{
struct comm_cmd_get_eqm_num info_eqm_fix;
int ret;
+ int is_in_kexec;
if (hwdev->hwif->attr.func_type != TYPE_PPF)
return 0;
@@ -1127,10 +1221,15 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
goto err_page;
}
- ret = mqm_eqm_set_page_2_hw(hwdev);
- if (ret) {
- sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
- goto err_ecmd;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ ret = mqm_eqm_set_page_2_hw(hwdev);
+ if (ret) {
+ sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
+ goto err_ecmd;
+ }
+ } else {
+ sdk_info(hwdev->dev_hdl, "Mqm db don't set to chip when os hot replace.\r\n");
}
ret = mqm_eqm_set_cfg_2_hw(hwdev, 1);
@@ -1568,3 +1667,15 @@ int hinic3_switch_config(void *hwdev, u8 cfg_index)
return 0;
}
+
+bool hinic3_is_optical_module_mode(void *hwdev)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (dev->board_info.board_type == BOARD_TYPE_STRG_4X25G_COMSTORAGE ||
+ dev->board_info.board_type == BOARD_TYPE_CAL_4X25G_COMSTORAGE ||
+ dev->board_info.board_type == BOARD_TYPE_CAL_2X100G_TCE_BACKPLANE)
+ return false;
+
+ return true;
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
index baa1ce0..722fecd 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
@@ -252,98 +252,6 @@ static u32 get_up_timeout_val(enum hinic3_mod_type mod, u16 cmd)
return 0; /* use default mbox/apichain timeout time */
}
-static int api_csr_read(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
-{
- struct up_log_msg_st *up_log_msg = (struct up_log_msg_st *)buf_in;
- u8 *buf_out_tmp = (u8 *)buf_out;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
-
- if (!buf_in || !buf_out || in_size != sizeof(*up_log_msg) ||
- *out_size != up_log_msg->rd_len || up_log_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = up_log_msg->rd_len;
- rd_addr = up_log_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_rd32(hwdev, node_id,
- rd_addr + offset,
- (u32 *)(buf_out_tmp + offset));
- if (ret) {
- pr_err("Csr rd fail, err: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, node_id, rd_addr + offset);
- return ret;
- }
- offset += DW_WIDTH;
- }
- *out_size = rd_len;
-
- return ret;
-}
-
-static int api_csr_write(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out,
- u32 *out_size)
-{
- struct csr_write_st *csr_write_msg = (struct csr_write_st *)buf_in;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
- u8 *data = NULL;
-
- if (!buf_in || in_size != sizeof(*csr_write_msg) || csr_write_msg->rd_len == 0 ||
- csr_write_msg->rd_len > API_CSR_MAX_RD_LEN || csr_write_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = csr_write_msg->rd_len;
- rd_addr = csr_write_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- data = kzalloc(rd_len, GFP_KERNEL);
- if (!data) {
- pr_err("No more memory\n");
- return -EFAULT;
- }
- if (copy_from_user(data, (void *)csr_write_msg->data, rd_len)) {
- pr_err("Copy information from user failed\n");
- kfree(data);
- return -EFAULT;
- }
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_wr32(hwdev, node_id,
- rd_addr + offset,
- *((u32 *)(data + offset)));
- if (ret) {
- pr_err("Csr wr fail, ret: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, rd_addr + offset, node_id);
- kfree(data);
- return ret;
- }
- offset += DW_WIDTH;
- }
-
- *out_size = 0;
- kfree(data);
- return ret;
-}
-
int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
@@ -370,10 +278,8 @@ int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
return ret;
}
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_BYPASS) {
- if (nt_msg->mpu_cmd.cmd == API_CSR_WRITE)
- return api_csr_write(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
-
- ret = api_csr_read(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
+ pr_err("Unsupported api_type %u\n", nt_msg->mpu_cmd.api_type);
+ return -EINVAL;
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_TO_MPU) {
timeout = get_up_timeout_val(mod, cmd);
if (hinic3_pcie_itf_id(hwdev) != SPU_HOST_ID)
@@ -440,6 +346,23 @@ static int sm_rd16(void *hwdev, u32 id, u8 instance,
return ret;
}
+static int sm_rd16_clear(void *hwdev, u32 id, u8 instance,
+ u8 node, struct sm_out_st *buf_out)
+{
+ u16 val1;
+ int ret;
+
+ ret = hinic3_sm_ctr_rd16_clear(hwdev, node, instance, id, &val1);
+ if (ret != 0) {
+ pr_err("Get sm ctr clear information (16 bits)failed!\n");
+ val1 = 0xffff;
+ }
+
+ buf_out->val1 = val1;
+
+ return ret;
+}
+
static int sm_rd32(void *hwdev, u32 id, u8 instance,
u8 node, struct sm_out_st *buf_out)
{
@@ -559,6 +482,7 @@ const struct sm_module_handle sm_module_cmd_handle[] = {
{SM_CTR_RD32, sm_rd32},
{SM_CTR_RD64_PAIR, sm_rd64_pair},
{SM_CTR_RD64, sm_rd64},
+ {SM_CTR_RD16_CLEAR, sm_rd16_clear},
{SM_CTR_RD32_CLEAR, sm_rd32_clear},
{SM_CTR_RD64_PAIR_CLEAR, sm_rd64_pair_clear},
{SM_CTR_RD64_CLEAR, sm_rd64_clear}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
index 620136a..ac80b63 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
@@ -101,6 +101,12 @@ enum hinic3_pcie_tph {
#define SLAVE_HOST_STATUS_SET(host_id, enable) (((u8)(enable) & 1U) << (host_id))
#define SLAVE_HOST_STATUS_GET(host_id, val) (!!((val) & (1U << (host_id))))
+#ifdef HAVE_HOT_REPLACE_FUNC
+ extern int get_partition_id(void);
+#else
+ static int get_partition_id(void) { return 0; }
+#endif
+
void set_slave_host_enable(void *hwdev, u8 host_id, bool enable)
{
u32 reg_val;
@@ -207,6 +213,28 @@ static void hinic3_init_host_mode_pre(struct hinic3_hwdev *hwdev)
}
}
+static void hinic3_init_hot_plug_status(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->hot_plug_disable) {
+ hwdev->hot_plug_mode = HOT_PLUG_DISABLE;
+ } else {
+ hwdev->hot_plug_mode = HOT_PLUG_ENABLE;
+ }
+}
+
+static void hinic3_init_os_hot_replace(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->os_hot_replace) {
+ hwdev->hot_replace_mode = HOT_REPLACE_ENABLE;
+ } else {
+ hwdev->hot_replace_mode = HOT_REPLACE_DISABLE;
+ }
+}
+
static u8 hinic3_nic_sw_aeqe_handler(void *hwdev, u8 event, u8 *data)
{
struct hinic3_hwdev *dev = hwdev;
@@ -270,14 +298,20 @@ static void chip_fault_show(struct hinic3_hwdev *hwdev,
"fatal", "reset", "host", "flr", "general", "suggestion"};
char level_str[FAULT_SHOW_STR_LEN + 1];
u8 level;
+ int ret;
memset(level_str, 0, FAULT_SHOW_STR_LEN + 1);
level = event->event.chip.err_level;
- if (level < FAULT_LEVEL_MAX)
- strncpy(level_str, fault_level[level],
- FAULT_SHOW_STR_LEN);
- else
- strncpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (level < FAULT_LEVEL_MAX) {
+ ret = strscpy(level_str, fault_level[level],
+ FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ } else {
+ ret = strscpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ }
if (level == FAULT_LEVEL_SERIOUS_FLR)
dev_err(hwdev->dev_hdl, "err_level: %u [%s], flr func_id: %u\n",
@@ -299,6 +333,7 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
"reg rd timeout", "reg wr timeout", "phy fault", "tsensor fault"};
char type_str[FAULT_SHOW_STR_LEN + 1] = {0};
struct fault_event_stats *fault = NULL;
+ int ret;
sdk_err(hwdev->dev_hdl, "Fault event report received, func_id: %u\n",
hinic3_global_func_id(hwdev));
@@ -306,10 +341,14 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
fault = &hwdev->hw_stats.fault_event_stats;
if (event->type < FAULT_TYPE_MAX) {
- strncpy(type_str, fault_type[event->type], sizeof(type_str));
+ ret = strscpy(type_str, fault_type[event->type], sizeof(type_str));
+ if (ret < 0)
+ return;
atomic_inc(&fault->fault_type_stat[event->type]);
} else {
- strncpy(type_str, "Unknown", sizeof(type_str));
+ ret = strscpy(type_str, "Unknown", sizeof(type_str));
+ if (ret < 0)
+ return;
}
sdk_err(hwdev->dev_hdl, "Fault type: %u [%s]\n", event->type, type_str);
@@ -1536,15 +1575,30 @@ int hinic3_init_hwdev(struct hinic3_init_para *para)
hinic3_init_host_mode_pre(hwdev);
+ hinic3_init_hot_plug_status(hwdev);
+
+ hinic3_init_os_hot_replace(hwdev);
+
err = hinic3_multi_host_mgmt_init(hwdev);
if (err != 0) {
sdk_err(hwdev->dev_hdl, "Failed to init function mode\n");
goto init_multi_host_fail;
}
- err = hinic3_init_ppf_work(hwdev);
- if (err != 0)
- goto init_ppf_work_fail;
+ // hot_replace_mode is enable, run ppf function only when partition_id is 0
+ // or run ppf function directly
+ if (hwdev->hot_replace_mode == HOT_REPLACE_ENABLE) {
+ if (get_partition_id() == 0) {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0) {
+ goto init_ppf_work_fail;
+ }
+ }
+ } else {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0)
+ goto init_ppf_work_fail;
+ }
err = hinic3_set_comm_features(hwdev, hwdev->features, COMM_MAX_FEATURE_QWORD);
if (err != 0) {
@@ -1948,6 +2002,19 @@ void hinic3_link_event_stats(void *dev, u8 link)
}
EXPORT_SYMBOL(hinic3_link_event_stats);
+int hinic3_get_link_event_stats(void *dev, int *link_state)
+{
+ struct hinic3_hwdev *hwdev = dev;
+
+ if (!hwdev || !link_state)
+ return -EINVAL;
+
+ *link_state = hwdev->hw_stats.link_event_stats.link_down_stats.counter;
+
+ return 0;
+}
+EXPORT_SYMBOL(hinic3_get_link_event_stats);
+
u8 hinic3_max_pf_num(void *hwdev)
{
if (!hwdev)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
index e739767..7c2cfc2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
@@ -10,6 +10,7 @@
#include "hinic3_hw.h"
#include "mpu_inband_cmd_defs.h"
#include "hinic3_profile.h"
+#include "vram_common.h"
struct cfg_mgmt_info;
@@ -82,6 +83,22 @@ enum hinic3_host_mode_e {
HINIC3_SDI_MODE_MAX,
};
+enum hinic3_hot_plug_mode {
+ HOT_PLUG_ENABLE,
+ HOT_PLUG_DISABLE,
+};
+
+enum hinic3_os_hot_replace_mode {
+ HOT_REPLACE_DISABLE,
+ HOT_REPLACE_ENABLE,
+};
+
+#define UNSUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_DISABLE)
+
+#define SUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_ENABLE)
+
#define MULTI_HOST_CHIP_MODE_SHIFT 0
#define MULTI_HOST_MASTER_MBX_STS_SHIFT 17
#define MULTI_HOST_PRIV_DATA_SHIFT 0x8
@@ -100,6 +117,10 @@ enum hinic3_host_mode_e {
((val) & (~(MULTI_HOST_##member##_MASK \
<< MULTI_HOST_##member##_SHIFT)))
+struct mqm_eqm_vram_name_s {
+ char vram_name[VRAM_NAME_MAX_LEN];
+};
+
struct hinic3_hwdev {
void *adapter_hdl; /* pointer to hinic3_pcidev or NDIS_Adapter */
void *pcidev_hdl; /* pointer to pcidev or Handler */
@@ -138,6 +159,9 @@ struct hinic3_hwdev {
u32 rsvd2;
struct hinic3_multi_host_mgmt *mhost_mgmt;
+ char mhost_mgmt_name[VRAM_NAME_MAX_LEN];
+
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name;
struct mutex stateful_mutex; /* protect cqm init and deinit */
@@ -170,7 +194,10 @@ struct hinic3_hwdev {
struct hinic3_devlink *devlink_dev;
enum hinic3_func_mode func_mode;
- u32 rsvd3;
+ enum hinic3_hot_plug_mode hot_plug_mode;
+
+ enum hinic3_os_hot_replace_mode hot_replace_mode;
+ u32 rsvd5;
DECLARE_BITMAP(func_probe_in_host, MAX_FUNCTION_NUM);
DECLARE_BITMAP(netdev_setup_state, MAX_FUNCTION_NUM);
@@ -179,7 +206,10 @@ struct hinic3_hwdev {
u64 last_recv_aeq_cnt;
u16 aeq_busy_cnt;
- u64 rsvd4[8];
+ u64 mbox_send_cnt;
+ u64 mbox_ack_cnt;
+
+ u64 rsvd4[5];
};
#define HINIC3_DRV_FEATURE_QW0 \
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
index 33f1210..8590f70 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
@@ -544,6 +544,7 @@ static void free_db_area(struct hinic3_free_db_area *free_db_area)
{
spin_lock_deinit(&free_db_area->idx_lock);
kfree(free_db_area->db_bitmap_array);
+ free_db_area->db_bitmap_array = NULL;
}
static int get_db_idx(struct hinic3_hwif *hwif, u32 *idx)
@@ -841,6 +842,7 @@ void hinic3_free_hwif(struct hinic3_hwdev *hwdev)
free_db_area(&hwdev->hwif->free_db_area);
enable_all_msix(hwdev);
kfree(hwdev->hwif);
+ hwdev->hwif = NULL;
}
u16 hinic3_global_func_id(void *hwdev)
@@ -856,6 +858,44 @@ u16 hinic3_global_func_id(void *hwdev)
}
EXPORT_SYMBOL(hinic3_global_func_id);
+/**
+ * get function id from register,used by sriov hot migration process
+ * @hwdev: the pointer to hw device
+ */
+u16 hinic3_global_func_id_hw(void *hwdev)
+{
+ u32 addr, attr0;
+ struct hinic3_hwdev *dev;
+
+ dev = (struct hinic3_hwdev *)hwdev;
+ addr = HINIC3_CSR_FUNC_ATTR0_ADDR;
+ attr0 = hinic3_hwif_read_reg(dev->hwif, addr);
+
+ return HINIC3_AF0_GET(attr0, FUNC_GLOBAL_IDX);
+}
+
+/**
+ * get function id, used by sriov hot migratition process.
+ * @hwdev: the pointer to hw device
+ * @func_id: function id
+ */
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id)
+{
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)hwdev;
+
+ if (!hwdev || !func_id)
+ return -EINVAL;
+
+ /* only vf get func_id from chip reg for sriov migrate */
+ if (!HINIC3_IS_VF(dev)) {
+ *func_id = hinic3_global_func_id(hwdev);
+ return 0;
+ }
+
+ *func_id = hinic3_global_func_id_hw(dev);
+ return 0;
+}
+
u16 hinic3_intr_num(void *hwdev)
{
struct hinic3_hwif *hwif = NULL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
index 321a3b7..4e2e8b0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
@@ -16,6 +16,7 @@
#include <linux/rtc.h>
#include <linux/aer.h>
#include <linux/debugfs.h>
+#include <linux/notifier.h>
#include "ossl_knl.h"
#include "hinic3_mt.h"
@@ -29,26 +30,41 @@
#include "hinic3_lld.h"
#include "hinic3_profile.h"
+#include "hinic3_hw_cfg.h"
+#include "hinic3_multi_host_mgmt.h"
#include "hinic3_hwdev.h"
#include "hinic3_prof_adap.h"
-#include "comm_msg_intf.h"
+#include "hinic3_devlink.h"
-static bool disable_vf_load;
+#include "vram_common.h"
+
+enum partition_dev_type {
+ PARTITION_DEV_NONE = 0,
+ PARTITION_DEV_SHARED,
+ PARTITION_DEV_EXCLUSIVE,
+ PARTITION_DEV_BACKUP,
+};
+
+#ifdef HAVE_HOT_REPLACE_FUNC
+extern int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type, unsigned int partition_id);
+extern int get_partition_id(void);
+#else
+static int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type, unsigned int partition_id) { return 0; }
+static int get_partition_id(void) { return 0; }
+#endif
+
+static bool disable_vf_load = false;
module_param(disable_vf_load, bool, 0444);
MODULE_PARM_DESC(disable_vf_load,
"Disable virtual functions probe or not - default is false");
+static bool g_is_pf_migrated = false;
static bool disable_attach;
module_param(disable_attach, bool, 0444);
MODULE_PARM_DESC(disable_attach, "disable_attach or not - default is false");
#define HINIC3_WAIT_SRIOV_CFG_TIMEOUT 15000
-MODULE_AUTHOR("Huawei Technologies CO., Ltd");
-MODULE_DESCRIPTION(HINIC3_DRV_DESC);
-MODULE_VERSION(HINIC3_DRV_VERSION);
-MODULE_LICENSE("GPL");
-
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
static DEVICE_ATTR(sriov_numvfs, 0664,
hinic3_sriov_numvfs_show, hinic3_sriov_numvfs_store);
@@ -71,7 +87,18 @@ static const struct attribute_group hinic3_attr_group = {
struct hinic3_uld_info g_uld_info[SERVICE_T_MAX] = { {0} };
#define HINIC3_EVENT_PROCESS_TIMEOUT 10000
+#define HINIC3_WAIT_EVENT_PROCESS_TIMEOUT 100
struct mutex g_uld_mutex;
+#define BUS_MAX_DEV_NUM 256
+#define HINIC3_SLAVE_WORK_MAX_NUM 20
+
+typedef struct vf_offset_info {
+ u8 valid;
+ u16 vf_offset_from_pf[CMD_MAX_MAX_PF_NUM];
+} VF_OFFSET_INFO_S;
+
+static VF_OFFSET_INFO_S g_vf_offset;
+DEFINE_MUTEX(g_vf_offset_lock);
void hinic3_uld_lock_init(void)
{
@@ -80,13 +107,23 @@ void hinic3_uld_lock_init(void)
static const char *s_uld_name[SERVICE_T_MAX] = {
"nic", "ovs", "roce", "toe", "ioe",
- "fc", "vbs", "ipsec", "virtio", "migrate", "ppa", "custom"};
+ "fc", "vbs", "ipsec", "virtio", "migrate",
+ "ppa", "custom", "vroce", "crypt", "vsock", "bifur"};
const char **hinic3_get_uld_names(void)
{
return s_uld_name;
}
+#ifdef CONFIG_PCI_IOV
+static int hinic3_get_pf_device_id(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_dev = pci_physfn(pdev);
+
+ return pf_dev->device;
+}
+#endif
+
static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
const struct hinic3_uld_info *uld_info)
{
@@ -105,6 +142,10 @@ static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
atomic_set(&dev->uld_ref_cnt[type], 0);
+ if (!uld_info->probe) {
+ err = 0;
+ goto out_unlock;
+ }
err = uld_info->probe(&dev->lld_dev, &uld_dev, dev->uld_dev_name[type]);
if (err) {
sdk_err(&dev->pcidev->dev,
@@ -173,6 +214,10 @@ static void detach_uld(struct hinic3_pcidev *dev,
wait_uld_unused(dev, type);
+ if (!uld_info->remove) {
+ mutex_unlock(&dev->pdev_mutex);
+ return;
+ }
uld_info->remove(&dev->lld_dev, dev->uld_dev[type]);
dev->uld_dev[type] = NULL;
@@ -190,10 +235,15 @@ static void attach_ulds(struct hinic3_pcidev *dev)
enum hinic3_service_type type;
struct pci_dev *pdev = dev->pcidev;
- lld_hold();
+ int is_in_kexec = vram_get_kexec_flag();
+ /* don't need hold when driver parallel load during spu hot replace */
+ if (is_in_kexec == 0) {
+ lld_hold();
+ }
+
mutex_lock(&g_uld_mutex);
- for (type = SERVICE_T_NIC; type < SERVICE_T_MAX; type++) {
+ for (type = SERVICE_T_OVS; type < SERVICE_T_MAX; type++) {
if (g_uld_info[type].probe) {
if (pdev->is_virtfn &&
(!hinic3_get_vf_service_load(pdev, (u16)type))) {
@@ -205,7 +255,10 @@ static void attach_ulds(struct hinic3_pcidev *dev)
}
}
mutex_unlock(&g_uld_mutex);
- lld_put();
+
+ if (is_in_kexec == 0) {
+ lld_put();
+ }
}
static void detach_ulds(struct hinic3_pcidev *dev)
@@ -255,10 +308,10 @@ int hinic3_register_uld(enum hinic3_service_type type,
}
chip_list = get_hinic3_chip_list();
- memcpy(&g_uld_info[type], uld_info, sizeof(*uld_info));
+ memcpy(&g_uld_info[type], uld_info, sizeof(struct hinic3_uld_info));
list_for_each_entry(chip_node, chip_list, node) {
list_for_each_entry(dev, &chip_node->func_list, node) {
- if (attach_uld(dev, type, uld_info)) {
+ if (attach_uld(dev, type, uld_info) != 0) {
sdk_err(&dev->pcidev->dev,
"Attach %s driver to pcie device failed\n",
s_uld_name[type]);
@@ -312,7 +365,7 @@ void hinic3_unregister_uld(enum hinic3_service_type type)
}
uld_info = &g_uld_info[type];
- memset(uld_info, 0, sizeof(*uld_info));
+ memset(uld_info, 0, sizeof(struct hinic3_uld_info));
mutex_unlock(&g_uld_mutex);
lld_put();
}
@@ -366,6 +419,26 @@ void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_ser
}
EXPORT_SYMBOL(hinic3_detach_service);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ __module_get(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_get);
+
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ module_put(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_put);
+
static void hinic3_sync_time_to_fmw(struct hinic3_pcidev *pdev_pri)
{
struct timeval tv = {0};
@@ -382,7 +455,8 @@ static void hinic3_sync_time_to_fmw(struct hinic3_pcidev *pdev_pri)
err);
} else {
rtc_time_to_tm((unsigned long)(tv.tv_sec), &rt_time);
- sdk_info(&pdev_pri->pcidev->dev, "Synchronize UTC time to firmware succeed. UTC time %d-%02d-%02d %02d:%02d:%02d.\n",
+ sdk_info(&pdev_pri->pcidev->dev,
+ "Synchronize UTC time to firmware succeed. UTC time %d-%02d-%02d %02d:%02d:%02d.\n",
rt_time.tm_year + HINIC3_SYNC_YEAR_OFFSET,
rt_time.tm_mon + HINIC3_SYNC_MONTH_OFFSET,
rt_time.tm_mday, rt_time.tm_hour,
@@ -448,23 +522,434 @@ static void send_event_to_all_pf(struct hinic3_pcidev *dev,
lld_put();
}
+u32 hinic3_pdev_is_virtfn(struct pci_dev *pdev)
+{
+#ifdef CONFIG_PCI_IOV
+ return pdev->is_virtfn;
+#else
+ return 0;
+#endif
+}
+
+static int hinic3_get_function_enable(struct pci_dev *pdev, bool *en)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+ int err;
+
+ /* PF in host os or function in guest os, probe sdk in default */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev) {
+ *en = true;
+ return 0;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev) {
+ /* vf in host and pf sdk not probed */
+ return -EFAULT;
+ }
+ pf_hwdev = pci_adapter->hwdev;
+
+ err = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (err) {
+ sdk_err(&pci_adapter->pcidev->dev, "Func hinic3_get_vfid_by_vfpci fail %d \n", err);
+ return err;
+ }
+
+ err = hinic3_get_func_nic_enable(pf_hwdev, global_func_id, en);
+ if (!!err) {
+ sdk_info(&pdev->dev, "Failed to get function nic status, err %d.\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+int hinic3_set_func_probe_in_host(void *hwdev, u16 func_id, bool probe)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (hinic3_func_type(hwdev) != TYPE_PPF)
+ return -EINVAL;
+
+ if (probe)
+ set_bit(func_id, dev->func_probe_in_host);
+ else
+ clear_bit(func_id, dev->func_probe_in_host);
+
+ return 0;
+}
+
+bool hinic3_get_func_probe_in_host(void *hwdev, u16 func_id)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+ bool probed = false;
+
+ if (!hwdev)
+ return false;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return false;
+ }
+
+ probed = !!test_bit(func_id, ppf_dev->func_probe_in_host);
+ up(&dev->ppf_sem);
+
+ return probed;
+}
+
+void *hinic3_get_ppf_hwdev_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ chip_node = pci_adapter->chip_node;
+ lld_dev_hold(&pci_adapter->lld_dev);
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (dev->lld_state == HINIC3_IN_REMOVE)
+ continue;
+
+ if (dev->hwdev && hinic3_func_type(dev->hwdev) == TYPE_PPF) {
+ lld_dev_put(&pci_adapter->lld_dev);
+ return dev->hwdev;
+ }
+ }
+ lld_dev_put(&pci_adapter->lld_dev);
+
+ return NULL;
+}
+
+static int hinic3_set_vf_nic_used_state(void *hwdev, u16 func_id, bool opened)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+
+ if (!dev || func_id >= MAX_FUNCTION_NUM)
+ return -EINVAL;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return -EINVAL;
+ }
+
+ if (opened)
+ set_bit(func_id, ppf_dev->netdev_setup_state);
+ else
+ clear_bit(func_id, ppf_dev->netdev_setup_state);
+
+ up(&dev->ppf_sem);
+
+ return 0;
+}
+
+static void set_vf_func_in_use(struct pci_dev *pdev, bool in_use)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+
+ /* only need to be set when VF is on the host */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev)
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev)
+ return;
+
+ pf_hwdev = pci_adapter->hwdev;
+
+ global_func_id = (u16)pdev->devfn + hinic3_glb_pf_vf_offset(pf_hwdev);
+ (void)hinic3_set_vf_nic_used_state(pf_hwdev, global_func_id, in_use);
+}
+
+static int hinic3_pf_get_vf_offset_info(struct hinic3_pcidev *des_dev, u16 *vf_offset)
+{
+ int err, i;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ u16 pf_func_id;
+ struct hinic3_pcidev *pf_pci_adapter = NULL;
+
+ pf_pci_adapter = (hinic3_pdev_is_virtfn(des_dev->pcidev)) ? pci_get_drvdata(des_dev->pcidev->physfn) : des_dev;
+ pf_func_id = hinic3_global_func_id(pf_pci_adapter->hwdev);
+ if (pf_func_id >= CMD_MAX_MAX_PF_NUM || !vf_offset)
+ return -EINVAL;
+
+ mutex_lock(&g_vf_offset_lock);
+ if (g_vf_offset.valid == 0) {
+ pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ sdk_err(&pf_pci_adapter->pcidev->dev, "Malloc pf_infos fail\n");
+ err = -ENOMEM;
+ goto err_malloc;
+ }
+
+ err = hinic3_get_hw_pf_infos(pf_pci_adapter->hwdev, pf_infos, HINIC3_CHANNEL_COMM);
+ if (err) {
+ sdk_warn(&pf_pci_adapter->pcidev->dev, "Hinic3_get_hw_pf_infos fail err %d\n", err);
+ err = -EFAULT;
+ goto err_out;
+ }
+
+ g_vf_offset.valid = 1;
+ for (i = 0; i < CMD_MAX_MAX_PF_NUM; i++) {
+ g_vf_offset.vf_offset_from_pf[i] = pf_infos->infos[i].vf_offset;
+ }
+
+ kfree(pf_infos);
+ }
+
+ *vf_offset = g_vf_offset.vf_offset_from_pf[pf_func_id];
+
+ mutex_unlock(&g_vf_offset_lock);
+
+ return 0;
+
+err_out:
+ kfree(pf_infos);
+err_malloc:
+ mutex_unlock(&g_vf_offset_lock);
+ return err;
+}
+
+static struct pci_dev *get_vf_pdev_by_pf(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ int err;
+ u16 bus_num;
+ u16 vf_start, vf_end;
+ u16 des_fn, pf_func_id, vf_offset;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ pf_func_id = hinic3_global_func_id(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end || pf_func_id >= CMD_MAX_MAX_PF_NUM)
+ return NULL;
+
+ err = hinic3_pf_get_vf_offset_info(des_dev, &vf_offset);
+ if (err) {
+ sdk_warn(&des_dev->pcidev->dev, "Hinic3_pf_get_vf_offset_info fail\n");
+ return NULL;
+ }
+
+ des_fn = ((func_id - vf_start) - 1) + pf_func_id + vf_offset;
+ bus_num = des_dev->pcidev->bus->number + des_fn / BUS_MAX_DEV_NUM;
+
+ return pci_get_domain_bus_and_slot(0, bus_num, (des_fn % BUS_MAX_DEV_NUM));
+}
+
+static struct hinic3_pcidev *get_des_pci_adapter(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ struct pci_dev *des_pdev = NULL;
+ u16 vf_start, vf_end;
+ bool probe_in_host = false;
+
+ if (hinic3_global_func_id(des_dev->hwdev) == func_id)
+ return des_dev;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end)
+ return NULL;
+
+ des_pdev = get_vf_pdev_by_pf(des_dev, func_id);
+ if (!des_pdev)
+ return NULL;
+
+ pci_dev_put(des_pdev);
+
+ probe_in_host = hinic3_get_func_probe_in_host(des_dev->hwdev, func_id);
+ if (!probe_in_host)
+ return NULL;
+
+ return pci_get_drvdata(des_pdev);
+}
+
+int __set_vroce_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ u8 enable_vroce = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_vroce_enable(pci_adapter->hwdev, func_id, &enable_vroce);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Failed to get vroce state.\n");
+ return err;
+ }
+
+ mutex_lock(&g_uld_mutex);
+
+ if (!!enable_vroce) {
+ if (!g_uld_info[SERVICE_T_ROCE].probe) {
+ sdk_info(&pdev->dev, "Uld(roce_info) has not been registered!\n");
+ mutex_unlock(&g_uld_mutex);
+ return 0;
+ }
+
+ err = attach_uld(pci_adapter, SERVICE_T_ROCE, &g_uld_info[SERVICE_T_ROCE]);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Failed to initialize VROCE.\n");
+ mutex_unlock(&g_uld_mutex);
+ return err;
+ }
+ } else {
+ sdk_info(&pdev->dev, "Func %hu vroce state: disable.\n", func_id);
+ if (g_uld_info[SERVICE_T_ROCE].remove)
+ detach_uld(pci_adapter, SERVICE_T_ROCE);
+ }
+
+ mutex_unlock(&g_uld_mutex);
+
+ return 0;
+}
+
+void slave_host_mgmt_vroce_work(struct work_struct *work)
+{
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_vroce_work);
+
+ __set_vroce_func_state(pci_adapter);
+}
+
+void *hinic3_get_roce_uld_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ return pci_adapter->uld_dev[SERVICE_T_ROCE];
+}
+
+static int __func_service_state_process(struct hinic3_pcidev *event_dev,
+ struct hinic3_pcidev *des_dev,
+ struct hinic3_mhost_nic_func_state *state, u16 cmd)
+{
+ int err = 0;
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)event_dev->hwdev;
+
+ switch (cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ state->enable = hinic3_get_roce_uld_by_pdev(des_dev->pcidev) ? 1 : 0;
+ break;
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive nic[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ if (event_dev->multi_host_mgmt_workq) {
+ queue_work(event_dev->multi_host_mgmt_workq, &des_dev->slave_nic_work);
+ } else {
+ sdk_err(&des_dev->pcidev->dev, "Can not schedule slave nic work\n");
+ err = -EFAULT;
+ }
+ break;
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive vroce[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ queue_work_on(hisdk3_get_work_cpu_affinity(dev, WORK_TYPE_MBOX),
+ event_dev->multi_host_mgmt_workq,
+ &des_dev->slave_vroce_work);
+ break;
+ default:
+ sdk_warn(&des_dev->pcidev->dev, "Service state process with unknown cmd: %u\n", cmd);
+ err = -EFAULT;
+ break;
+ }
+
+ return err;
+}
+
+static void __multi_host_mgmt(struct hinic3_pcidev *dev,
+ struct hinic3_multi_host_mgmt_event *mhost_mgmt)
+{
+ struct hinic3_pcidev *cur_dev = NULL;
+ struct hinic3_pcidev *des_dev = NULL;
+ struct hinic3_mhost_nic_func_state *nic_state = NULL;
+ u16 sub_cmd = mhost_mgmt->sub_cmd;
+
+ switch (sub_cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ nic_state = mhost_mgmt->data;
+ nic_state->status = 0;
+ if (!dev->hwdev)
+ return;
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)dev->hwdev))
+ return;
+
+ /* find func_idx pci_adapter and disable or enable nic */
+ lld_dev_hold(&dev->lld_dev);
+ list_for_each_entry(cur_dev, &dev->chip_node->func_list, node) {
+ if (cur_dev->lld_state == HINIC3_IN_REMOVE || hinic3_pdev_is_virtfn(cur_dev->pcidev))
+ continue;
+
+ des_dev = get_des_pci_adapter(cur_dev, nic_state->func_idx);
+ if (!des_dev)
+ continue;
+
+ if (__func_service_state_process(dev, des_dev, nic_state, sub_cmd))
+ nic_state->status = 1;
+ break;
+ }
+ lld_dev_put(&dev->lld_dev);
+ break;
+ default:
+ sdk_warn(&dev->pcidev->dev, "Received unknown multi-host mgmt event: %u\n",
+ mhost_mgmt->sub_cmd);
+ break;
+ }
+}
+
static void hinic3_event_process(void *adapter, struct hinic3_event_info *event)
{
struct hinic3_pcidev *dev = adapter;
struct hinic3_fault_event *fault = (void *)event->event_data;
+ struct hinic3_multi_host_mgmt_event *mhost_event = (void *)event->event_data;
u16 func_id;
- if ((event->service == EVENT_SRV_COMM && event->type == EVENT_COMM_FAULT) &&
- fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
- fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
- func_id = fault->event.chip.func_id;
- return send_event_to_dst_pf(adapter, func_id, event);
- }
-
- if (event->type == EVENT_COMM_MGMT_WATCHDOG)
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MULTI_HOST_MGMT):
+ __multi_host_mgmt(dev, mhost_event);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_FAULT):
+ if (fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
+ fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
+ func_id = fault->event.chip.func_id;
+ return send_event_to_dst_pf(adapter, func_id, event);
+ }
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MGMT_WATCHDOG):
send_event_to_all_pf(adapter, event);
- else
+ break;
+ default:
send_uld_dev_event(adapter, event);
+ break;
+ }
}
static void uld_def_init(struct hinic3_pcidev *pci_adapter)
@@ -631,36 +1116,75 @@ static void hinic3_pci_deinit(struct pci_dev *pdev)
kfree(pci_adapter);
}
-#ifdef CONFIG_X86
-/**
- * cfg_order_reg - when cpu model is haswell or broadwell, should configure dma
- * order register to zero
- * @pci_adapter: pci_adapter
- **/
-/*lint -save -e40 */
-static void cfg_order_reg(struct hinic3_pcidev *pci_adapter)
+static void set_vf_load_state(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
{
- u8 cpu_model[] = {0x3c, 0x3f, 0x45, 0x46, 0x3d, 0x47, 0x4f, 0x56};
- struct cpuinfo_x86 *cpuinfo = NULL;
- u32 i;
-
- if (hinic3_func_type(pci_adapter->hwdev) == TYPE_VF)
- return;
+ /* In bm mode, slave host will load vfs in default */
+ if (IS_BMGW_SLAVE_HOST(((struct hinic3_hwdev *)pci_adapter->hwdev)) &&
+ hinic3_func_type(pci_adapter->hwdev) != TYPE_VF)
+ hinic3_set_vf_load_state(pdev, false);
- cpuinfo = &cpu_data(0);
- for (i = 0; i < sizeof(cpu_model); i++) {
- if (cpu_model[i] == cpuinfo->x86_model)
- hinic3_set_pcie_order_cfg(pci_adapter->hwdev);
+ if (!disable_attach) {
+ if ((hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) &&
+ hinic3_is_bm_slave_host(pci_adapter->hwdev)) {
+ if (hinic3_func_max_vf(pci_adapter->hwdev) == 0) {
+ sdk_warn(&pdev->dev, "The sriov enabling process is skipped, vfs_num: 0.\n");
+ return;
+ }
+ hinic3_pci_sriov_enable(pdev, hinic3_func_max_vf(pci_adapter->hwdev));
+ }
}
}
-/*lint -restore*/
-#endif
-
-static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+static void hinic3_init_ppf_hwdev(struct hinic3_hwdev *hwdev)
{
- struct hinic3_init_para init_para = {0};
- bool cqm_init_en = false;
+ if (!hwdev) {
+ pr_err("[%s:%d] null hwdev pointer\n", __FILE__, __LINE__);
+ return;
+ }
+
+ hwdev->ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(hwdev->pcidev_hdl);
+ return;
+}
+
+static int set_nic_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ bool enable_nic = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_nic_enable(pci_adapter->hwdev, func_id, &enable_nic);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Failed to get nic state.\n");
+ return err;
+ }
+
+ if (!enable_nic) {
+ sdk_info(&pdev->dev, "Func %hu nic state: disable.\n", func_id);
+ detach_uld(pci_adapter, SERVICE_T_NIC);
+ return 0;
+ }
+
+ if (IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ (void)hinic3_init_vf_dev_cap(pci_adapter->hwdev);
+
+ if (g_uld_info[SERVICE_T_NIC].probe) {
+ err = attach_uld(pci_adapter, SERVICE_T_NIC, &g_uld_info[SERVICE_T_NIC]);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Initialize NIC failed\n");
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_init_para init_para = {0};
+ bool cqm_init_en = false;
int err;
init_para.adapter_hdl = pci_adapter;
@@ -715,7 +1239,16 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
list_add_tail(&pci_adapter->node, &pci_adapter->chip_node->func_list);
lld_unlock_chip_node();
+ hinic3_init_ppf_hwdev((struct hinic3_hwdev *)pci_adapter->hwdev);
+
+ set_vf_load_state(pdev, pci_adapter);
+
if (!disable_attach) {
+ /* NIC is base driver, probe firstly */
+ err = set_nic_func_state(pci_adapter);
+ if (err)
+ goto set_nic_func_state_err;
+
attach_ulds(pci_adapter);
if (hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) {
@@ -726,10 +1259,6 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
goto create_sysfs_err;
}
}
-
-#ifdef CONFIG_X86
- cfg_order_reg(pci_adapter);
-#endif
}
return 0;
@@ -737,6 +1266,7 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
create_sysfs_err:
detach_ulds(pci_adapter);
+set_nic_func_state_err:
lld_lock_chip_node();
list_del(&pci_adapter->node);
lld_unlock_chip_node();
@@ -785,6 +1315,7 @@ static void hinic3_func_deinit(struct pci_dev *pdev)
hinic3_free_stateful(pci_adapter->hwdev);
hinic3_free_hwdev(pci_adapter->hwdev);
+ pci_adapter->hwdev = NULL;
}
static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
@@ -806,6 +1337,49 @@ static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
} while (time_before(jiffies, end));
}
+static bool hinic3_get_vf_nic_en_status(struct pci_dev *pdev)
+{
+ bool nic_en = false;
+ u16 global_func_id;
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev) {
+ pr_err("pdev is null.\n");
+ return false;
+ }
+
+ if (pdev->is_virtfn)
+ pf_pdev = pdev->physfn;
+ else
+ return false;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return false;
+ }
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ return false;
+
+ if (hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id)) {
+ sdk_err(&pdev->dev, "Get vf id by vfpci failed\n");
+ return false;
+ }
+
+ if (hinic3_get_mhost_func_nic_enable(pci_adapter->hwdev,
+ global_func_id, &nic_en)) {
+ sdk_err(&pdev->dev, "Get function nic status failed\n");
+ return false;
+ }
+
+ sdk_info(&pdev->dev, "Func %hu %s default probe in host\n",
+ global_func_id, (nic_en) ? "enable" : "disable");
+
+ return nic_en;
+}
+
bool hinic3_get_vf_load_state(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = NULL;
@@ -860,6 +1434,8 @@ int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state)
}
EXPORT_SYMBOL(hinic3_set_vf_load_state);
+
+
bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service)
{
struct hinic3_pcidev *pci_adapter = NULL;
@@ -923,6 +1499,33 @@ int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
}
EXPORT_SYMBOL(hinic3_set_vf_service_load);
+static bool hinic3_is_host_vmsec_enable(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct pci_dev *pf_pdev = NULL;
+
+ if (pdev->is_virtfn) {
+ pf_pdev = pdev->physfn;
+ } else {
+ pf_pdev = pdev;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ pr_err("Pci_adapter is null.\n");
+ return false;
+ }
+
+ /* pf/vf used in host */
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ (hinic3_func_type(pci_adapter->hwdev) == TYPE_PF) &&
+ IS_RDMA_TYPE((struct hinic3_hwdev *)pci_adapter->hwdev)) {
+ return true;
+ }
+
+ return false;
+}
+
static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
@@ -936,6 +1539,13 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
pci_adapter->lld_state = HINIC3_IN_REMOVE;
mutex_unlock(&pci_adapter->pdev_mutex);
+ if (!(pdev->is_virtfn) && (hinic3_is_host_vmsec_enable(pdev) == true) &&
+ (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF)) {
+ cancel_delayed_work_sync(&pci_adapter->migration_probe_dwork);
+ flush_workqueue(pci_adapter->migration_probe_workq);
+ destroy_workqueue(pci_adapter->migration_probe_workq);
+ }
+
hinic3_detect_hw_present(pci_adapter->hwdev);
hisdk3_remove_pre_process(pci_adapter->hwdev);
@@ -960,23 +1570,129 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
sdk_info(&pdev->dev, "Pcie device removed function\n");
+ set_vf_func_in_use(pdev, false);
+
+ return 0;
+}
+
+int hinic3_get_vfid_by_vfpci(void *hwdev, struct pci_dev *pdev, u16 *global_func_id)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ u16 pf_bus, vf_bus, vf_offset;
+ int err;
+
+ if (!pdev || !global_func_id || !hinic3_pdev_is_virtfn(pdev))
+ return -EINVAL;
+ (void)hwdev;
+ pf_pdev = pdev->physfn;
+
+ vf_bus = pdev->bus->number;
+ pf_bus = pf_pdev->bus->number;
+
+ if (pdev->vendor == HINIC3_VIRTIO_VNEDER_ID) {
+ return -EPERM;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return -EINVAL;
+ }
+
+ err = hinic3_pf_get_vf_offset_info(pci_adapter, &vf_offset);
+ if (err) {
+ sdk_err(&pdev->dev, "Func hinic3_pf_get_vf_offset_info fail\n");
+ return -EFAULT;
+ }
+
+ *global_func_id = (u16)((vf_bus - pf_bus) * BUS_MAX_DEV_NUM) + (u16)pdev->devfn +
+ (u16)(CMD_MAX_MAX_PF_NUM - g_vf_offset.vf_offset_from_pf[0]);
+
return 0;
}
+EXPORT_SYMBOL(hinic3_get_vfid_by_vfpci);
+
+static void hinic3_set_vf_status_in_host(struct pci_dev *pdev, bool status)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ void *ppf_hwdev = NULL;
+ u16 global_func_id;
+ int ret;
+
+ if (!pf_pdev)
+ return;
+
+ if (!hinic3_pdev_is_virtfn(pdev))
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ pf_hwdev = pci_adapter->hwdev;
+ ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(pf_pdev);
+ if (!pf_hwdev || !ppf_hwdev)
+ return;
+
+ ret = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (ret) {
+ sdk_err(&pci_adapter->pcidev->dev, "Func hinic3_get_vfid_by_vfpci fail %d \n", ret);
+ return;
+ }
+
+ ret = hinic3_set_func_probe_in_host(ppf_hwdev, global_func_id, status);
+ if (ret)
+ sdk_err(&pci_adapter->pcidev->dev, "Set the function probe status in host failed\n");
+}
+#ifdef CONFIG_PCI_IOV
+static bool check_pdev_type_and_state(struct pci_dev *pdev)
+{
+ if (!(pdev->is_virtfn)) {
+ return false;
+ }
+
+ if ((hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_1_PF) &&
+ (hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_0_PF)) {
+ return false;
+ }
+
+ if (!hinic3_get_vf_load_state(pdev)) {
+ return false;
+ }
+
+ return true;
+}
+#endif
static void hinic3_remove(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
+ sdk_info(&pdev->dev, "Pcie device remove begin\n");
+
if (!pci_adapter)
- return;
+ goto out;
+#ifdef CONFIG_PCI_IOV
+ if (check_pdev_type_and_state(pdev)) {
+ goto out;
+ }
+#endif
- sdk_info(&pdev->dev, "Pcie device remove begin\n");
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
hinic3_remove_func(pci_adapter);
+ if (!pci_adapter->pcidev->is_virtfn &&
+ pci_adapter->multi_host_mgmt_workq)
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
+
hinic3_pci_deinit(pdev);
hinic3_probe_pre_unprocess(pdev);
+out:
+ hinic3_set_vf_status_in_host(pdev, false);
+
sdk_info(&pdev->dev, "Pcie device removed\n");
}
@@ -995,7 +1711,7 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
if (pci_adapter->lld_state >= HINIC3_PROBE_START) {
sdk_warn(&pdev->dev, "Don not probe repeat\n");
mutex_unlock(&pci_adapter->pdev_mutex);
- return 0;
+ return -EEXIST;
}
pci_adapter->lld_state = HINIC3_PROBE_START;
mutex_unlock(&pci_adapter->pdev_mutex);
@@ -1003,15 +1719,28 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
return 0;
}
+static void hinic3_probe_success_process(struct hinic3_pcidev *pci_adapter)
+{
+ hinic3_probe_success(pci_adapter->hwdev);
+
+ mutex_lock(&pci_adapter->pdev_mutex);
+ pci_adapter->lld_state = HINIC3_PROBE_OK;
+ mutex_unlock(&pci_adapter->pdev_mutex);
+}
+
static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
int err;
err = probe_func_param_init(pci_adapter);
- if (err)
+ if (err == -EEXIST)
+ return 0;
+ else if (err)
return err;
+ set_vf_func_in_use(pdev, true);
+
err = mapping_bar(pdev, pci_adapter);
if (err) {
sdk_err(&pdev->dev, "Failed to map bar\n");
@@ -1043,11 +1772,7 @@ static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
}
}
- hinic3_probe_success(pci_adapter->hwdev);
-
- mutex_lock(&pci_adapter->pdev_mutex);
- pci_adapter->lld_state = HINIC3_PROBE_OK;
- mutex_unlock(&pci_adapter->pdev_mutex);
+ hinic3_probe_success_process(pci_adapter);
return 0;
@@ -1063,18 +1788,299 @@ alloc_chip_node_fail:
unmapping_bar(pci_adapter);
map_bar_failed:
+ set_vf_func_in_use(pdev, false);
sdk_err(&pdev->dev, "Pcie device probe function failed\n");
return err;
}
+void hinic3_set_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int err;
+ bool enable_func = false;
+
+ err = hinic3_get_function_enable(pdev, &enable_func);
+ if (err) {
+ sdk_info(&pdev->dev, "Get function enable failed\n");
+ return;
+ }
+
+ sdk_info(&pdev->dev, "%s function resource start\n",
+ enable_func ? "Initialize" : "Free");
+ if (enable_func) {
+ err = hinic3_probe_func(pci_adapter);
+ if (err)
+ sdk_info(&pdev->dev, "Function probe failed\n");
+ } else {
+ hinic3_remove_func(pci_adapter);
+ }
+ if (err == 0)
+ sdk_info(&pdev->dev, "%s function resource end\n",
+ enable_func ? "Initialize" : "Free");
+}
+
+void slave_host_mgmt_work(struct work_struct *work)
+{
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_nic_work);
+
+ if (hinic3_pdev_is_virtfn(pci_adapter->pcidev))
+ hinic3_set_func_state(pci_adapter);
+ else
+ set_nic_func_state(pci_adapter);
+}
+
+static int pci_adapter_assign_val(struct hinic3_pcidev **ppci_adapter,
+ struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ *ppci_adapter = pci_get_drvdata(pdev);
+ (*ppci_adapter)->disable_vf_load = disable_vf_load;
+ (*ppci_adapter)->id = *id;
+ (*ppci_adapter)->lld_state = HINIC3_NOT_PROBE;
+ (*ppci_adapter)->probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ lld_dev_cnt_init(*ppci_adapter);
+
+ (*ppci_adapter)->multi_host_mgmt_workq =
+ alloc_workqueue("hinic_mhost_mgmt", WQ_UNBOUND,
+ HINIC3_SLAVE_WORK_MAX_NUM);
+ if (!(*ppci_adapter)->multi_host_mgmt_workq) {
+ hinic3_pci_deinit(pdev);
+ sdk_err(&pdev->dev, "Alloc multi host mgmt workqueue failed\n");
+ return -ENOMEM;
+ }
+
+ INIT_WORK(&(*ppci_adapter)->slave_nic_work, slave_host_mgmt_work);
+ INIT_WORK(&(*ppci_adapter)->slave_vroce_work,
+ slave_host_mgmt_vroce_work);
+
+ return 0;
+}
+
+static void slave_host_vfio_probe_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_pcidev *pci_adapter = container_of(delay, struct hinic3_pcidev, migration_probe_dwork);
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int (*dev_migration_probe)(struct pci_dev *);
+ int rc;
+
+ if (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) != TYPE_PF) {
+ return;
+ }
+
+ dev_migration_probe = __symbol_get("migration_dev_migration_probe");
+ if (!(dev_migration_probe)) {
+ sdk_err(&pdev->dev,
+ "Failed to find: migration_dev_migration_probe");
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork, WAIT_TIME * HZ);
+ } else {
+ rc = dev_migration_probe(pdev);
+ __symbol_put("migration_dev_migration_probe");
+ if (rc) {
+ sdk_err(&pdev->dev,
+ "Failed to __dev_migration_probe, rc:0x%x, pf migrated(%d).\n",
+ rc, g_is_pf_migrated);
+ } else {
+ g_is_pf_migrated = true;
+ sdk_info(&pdev->dev,
+ "Successed in __dev_migration_probe, pf migrated(%d).\n",
+ g_is_pf_migrated);
+ }
+ }
+
+ return;
+}
+
+struct vf_add_delaywork {
+ struct pci_dev *vf_pdev;
+ struct delayed_work migration_vf_add_dwork;
+};
+
+static void slave_host_migration_vf_add_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct vf_add_delaywork *vf_add = container_of(delay, struct vf_add_delaywork, migration_vf_add_dwork);
+ struct pci_dev *vf_pdev = vf_add->vf_pdev;
+ struct pci_dev *pf_pdev = NULL;
+ int (*migration_dev_add_vf)(struct pci_dev *);
+ int ret;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!vf_pdev) {
+ pr_err("vf pdev is null.\n");
+ goto err1;
+ }
+ if (!vf_pdev->is_virtfn) {
+ sdk_err(&vf_pdev->dev, "Pdev is not virtfn.\n");
+ goto err1;
+ }
+
+ pf_pdev = vf_pdev->physfn;
+ if (!pf_pdev) {
+ sdk_err(&vf_pdev->dev, "pf_pdev is null.\n");
+ goto err1;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&vf_pdev->dev, "Pci_adapter is null.\n");
+ goto err1;
+ }
+
+ if (!g_is_pf_migrated) {
+ sdk_info(&vf_pdev->dev, "pf is not migrated yet, so vf continues to try again.\n");
+ goto delay_work;
+ }
+
+ migration_dev_add_vf = __symbol_get("migration_dev_add_vf");
+ if (migration_dev_add_vf) {
+ ret = migration_dev_add_vf(vf_pdev);
+ __symbol_put("migration_dev_add_vf");
+ if (ret) {
+ sdk_err(&vf_pdev->dev,
+ "vf get migration symbol successed, but dev add vf failed, ret:%d.\n",
+ ret);
+ } else {
+ sdk_info(&vf_pdev->dev,
+ "vf get migration symbol successed, and dev add vf success.\n");
+ }
+ goto err1;
+ }
+ sdk_info(&vf_pdev->dev, "pf is migrated, but vf get migration symbol failed.\n");
+
+delay_work:
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork, WAIT_TIME * HZ);
+ return;
+
+err1:
+ kfree(vf_add);
+ return;
+}
+
+static void hinic3_probe_vf_add_dwork(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!hinic3_is_host_vmsec_enable(pdev)) {
+ return;
+ }
+
+#if defined(CONFIG_SP_VID_DID)
+ if ((pdev->vendor == PCI_VENDOR_ID_SPNIC) && (pdev->device == HINIC3_DEV_SDI_5_1_ID_VF)) {
+#elif defined(CONFIG_NF_VID_DID)
+ if ((pdev->vendor == PCI_VENDOR_ID_NF) && (pdev->device == NFNIC_DEV_ID_VF)) {
+#else
+ if ((pdev->vendor == PCI_VENDOR_ID_HUAWEI) && (pdev->device == HINIC3_DEV_SDI_5_0_ID_VF)) {
+#endif
+ struct vf_add_delaywork *vf_add = kmalloc(sizeof(struct vf_add_delaywork), GFP_ATOMIC);
+ if (!vf_add) {
+ sdk_info(&pdev->dev, "vf_add is null.\n");
+ return;
+ }
+ vf_add->vf_pdev = pdev;
+
+ pf_pdev = pdev->physfn;
+
+ if (!pf_pdev) {
+ sdk_info(&pdev->dev, "Vf-pf_pdev is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_info(&pdev->dev, "Pci_adapter is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ INIT_DELAYED_WORK(&vf_add->migration_vf_add_dwork,
+ slave_host_migration_vf_add_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork,
+ WAIT_TIME * HZ);
+ }
+
+ return;
+}
+
+static int hinic3_probe_migration_dwork(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+{
+ if (!hinic3_is_host_vmsec_enable(pdev)) {
+ sdk_info(&pdev->dev, "Probe_migration : hinic3_is_host_vmsec_enable is (0).\n");
+ return 0;
+ }
+
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF) {
+ pci_adapter->migration_probe_workq =
+ create_singlethread_workqueue("hinic3_migration_probe_delay");
+ if (!pci_adapter->migration_probe_workq) {
+ sdk_err(&pdev->dev, "Failed to create work queue:%s\n",
+ "hinic3_migration_probe_delay");
+ return -EINVAL;
+ }
+
+ INIT_DELAYED_WORK(&pci_adapter->migration_probe_dwork,
+ slave_host_vfio_probe_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork, WAIT_TIME * HZ);
+ }
+
+ return 0;
+}
+
+static bool hinic3_os_hot_replace_allow(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_hwdev *hwdev = (struct hinic3_hwdev *)pci_adapter->hwdev;
+ // check service enable and dev is not VF
+ if (hinic3_func_type(hwdev) == TYPE_VF || hwdev->hot_replace_mode == HOT_REPLACE_DISABLE)
+ return false;
+
+ return true;
+}
+
+static bool hinic3_os_hot_replace_process(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_board_info *board_info;
+ u16 cur_pf_id = hinic3_global_func_id(pci_adapter->hwdev);
+ u8 cur_partion_id;
+ board_info = &((struct hinic3_hwdev *)(pci_adapter->hwdev))->board_info;
+ // probe to os
+ vpci_set_partition_attrs(pci_adapter->pcidev, PARTITION_DEV_EXCLUSIVE,
+ get_function_partition(cur_pf_id, board_info->port_num));
+
+ // check pf_id is in the right partition_id
+ cur_partion_id = get_partition_id();
+ if (get_function_partition(cur_pf_id, board_info->port_num) == cur_partion_id) {
+ return true;
+ }
+
+ pci_adapter->probe_fault_level = FAULT_LEVEL_SUGGESTION;
+ return false;
+}
+
static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct hinic3_pcidev *pci_adapter = NULL;
u16 probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ u32 device_id, function_id;
int err;
sdk_info(&pdev->dev, "Pcie device probe begin\n");
-
+#ifdef CONFIG_PCI_IOV
+ hinic3_set_vf_status_in_host(pdev, true);
+ if (check_pdev_type_and_state(pdev)) {
+ sdk_info(&pdev->dev, "VFs are not binded to hinic\n");
+ hinic3_probe_vf_add_dwork(pdev);
+ return -EINVAL;
+ }
+#endif
err = hinic3_probe_pre_process(pdev);
if (err != 0 && err != HINIC3_NOT_PROBE)
goto out;
@@ -1082,33 +2088,53 @@ static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (err == HINIC3_NOT_PROBE)
return 0;
- err = hinic3_pci_init(pdev);
- if (err)
+ if (hinic3_pci_init(pdev))
goto pci_init_err;
- pci_adapter = pci_get_drvdata(pdev);
- pci_adapter->disable_vf_load = disable_vf_load;
- pci_adapter->id = *id;
- pci_adapter->lld_state = HINIC3_NOT_PROBE;
- pci_adapter->probe_fault_level = probe_fault_level;
- lld_dev_cnt_init(pci_adapter);
+ if (pci_adapter_assign_val(&pci_adapter, pdev, id))
+ goto allco_queue_err;
- if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev))) {
+ if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev)) &&
+ (!hinic3_get_vf_nic_en_status(pdev))) {
sdk_info(&pdev->dev, "VF device disable load in host\n");
return 0;
}
- err = hinic3_probe_func(pci_adapter);
- if (err)
+ if (hinic3_probe_func(pci_adapter))
+ goto hinic3_probe_func_fail;
+
+ if (hinic3_os_hot_replace_allow(pci_adapter)) {
+ if (!hinic3_os_hot_replace_process(pci_adapter)) {
+ device_id = PCI_SLOT(pdev->devfn);
+ function_id = PCI_FUNC(pdev->devfn);
+ sdk_info(&pdev->dev,
+ "os hot replace: skip function %d:%d for partition %d",
+ device_id, function_id, get_partition_id());
+ goto os_hot_repalce_not_allow;
+ }
+ }
+
+ if (hinic3_probe_migration_dwork(pdev, pci_adapter))
goto hinic3_probe_func_fail;
sdk_info(&pdev->dev, "Pcie device probed\n");
return 0;
+os_hot_repalce_not_allow:
+ hinic3_func_deinit(pdev);
+ lld_lock_chip_node();
+ free_chip_node(pci_adapter);
+ lld_unlock_chip_node();
+ unmapping_bar(pci_adapter);
+ set_vf_func_in_use(pdev, false);
+
hinic3_probe_func_fail:
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
+allco_queue_err:
probe_fault_level = pci_adapter->probe_fault_level;
hinic3_pci_deinit(pdev);
-
pci_init_err:
hinic3_probe_pre_unprocess(pdev);
@@ -1131,6 +2157,10 @@ static int hinic3_get_pf_info(struct pci_dev *pdev, u16 service,
}
*pf_infos = kzalloc(sizeof(struct hinic3_hw_pf_infos), GFP_KERNEL);
+ if (*pf_infos == NULL) {
+ sdk_err(&pdev->dev, "pf_infos kzalloc failed\n");
+ return -EFAULT;
+ }
err = hinic3_get_hw_pf_infos(dev->hwdev, *pf_infos, HINIC3_CHANNEL_COMM);
if (err) {
kfree(*pf_infos);
@@ -1146,6 +2176,7 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
{
int err;
+ mutex_lock(&dst_dev->pdev_mutex);
/* unload invalid vf func id */
if (!en && vf_func_id != hinic3_global_func_id(dst_dev->hwdev) &&
!strcmp(des_pdev->driver->name, HINIC3_DRV_NAME)) {
@@ -1163,6 +2194,8 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
err = hinic3_probe_func(dst_dev);
if (err)
return -EFAULT;
+ } else {
+ mutex_unlock(&dst_dev->pdev_mutex);
}
return 0;
@@ -1187,7 +2220,6 @@ static int get_vf_service_state_param(struct pci_dev *pdev, struct hinic3_pcidev
return 0;
}
-#define BUS_MAX_DEV_NUM 256
static int hinic3_dst_pdev_valid(struct hinic3_pcidev *dst_dev, struct pci_dev **des_pdev_ptr,
u16 vf_devfn, bool en)
{
@@ -1245,7 +2277,7 @@ int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id, u16 servic
lld_hold();
list_for_each_entry(dst_dev, &dev->chip_node->func_list, node) {
- if (paramerter_is_unexpected(dst_dev, &func_id, &vf_start, &vf_end, vf_func_id))
+ if (paramerter_is_unexpected(dst_dev, &func_id, &vf_start, &vf_end, vf_func_id) != 0)
continue;
vf_devfn = pf_infos->infos[func_id].vf_offset + (vf_func_id - vf_start) +
@@ -1269,7 +2301,6 @@ int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id, u16 servic
if (en)
pci_dev_put(des_pdev);
- mutex_lock(&dst_dev->pdev_mutex);
find_dst_dev = true;
break;
}
@@ -1289,19 +2320,18 @@ free_pf_info:
}
EXPORT_SYMBOL(hinic3_set_vf_service_state);
-/*lint -save -e133 -e10*/
static const struct pci_device_id hinic3_pci_table[] = {
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SPU), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_STANDARD), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_1_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_SDI_5_1_ID_VF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_VF), 0},
{0, 0}
};
-/*lint -restore*/
-
MODULE_DEVICE_TABLE(pci, hinic3_pci_table);
/**
@@ -1333,14 +2363,27 @@ static pci_ers_result_t hinic3_io_error_detected(struct pci_dev *pdev,
return PCI_ERS_RESULT_CAN_RECOVER;
}
+static void hinic3_timer_disable(void *hwdev)
+{
+ if (!hwdev)
+ return;
+
+ if (hinic3_get_stateful_enable(hwdev) && hinic3_get_timer_enable(hwdev))
+ (void)hinic3_func_tmr_bitmap_set(hwdev, hinic3_global_func_id(hwdev), false);
+
+ return;
+}
+
static void hinic3_shutdown(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
sdk_info(&pdev->dev, "Shutdown device\n");
- if (pci_adapter)
+ if (pci_adapter) {
+ hinic3_timer_disable(pci_adapter->hwdev);
hinic3_shutdown_hwdev(pci_adapter->hwdev);
+ }
pci_disable_device(pdev);
@@ -1367,6 +2410,9 @@ static struct pci_driver hinic3_driver = {
.probe = hinic3_probe,
.remove = hinic3_remove,
.shutdown = hinic3_shutdown,
+#ifdef CONFIG_PARTITION_DEVICE
+ .driver.probe_concurrency = true,
+#endif
#if defined(HAVE_SRIOV_CONFIGURE)
.sriov_configure = hinic3_pci_sriov_configure,
#elif defined(HAVE_RHEL6_SRIOV_CONFIGURE)
@@ -1388,16 +2434,21 @@ int hinic3_lld_init(void)
err = hinic3_module_pre_init();
if (err) {
pr_err("Init custom failed\n");
- return err;
+ goto module_pre_init_err;
}
err = pci_register_driver(&hinic3_driver);
if (err) {
- hinic3_module_post_exit();
- return err;
+ pr_err("sdk3 pci register driver failed\n");
+ goto register_pci_driver_err;
}
return 0;
+
+register_pci_driver_err:
+ hinic3_module_post_exit();
+module_pre_init_err:
+ return err;
}
void hinic3_lld_exit(void)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
index d2a7dd7..5398a34 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
@@ -584,6 +584,7 @@ static void free_recv_mbox(struct hinic3_recv_mbox *recv_msg)
kfree(recv_msg->resp_buff);
kfree(recv_msg->msg);
kfree(recv_msg);
+ recv_msg = NULL;
}
static void recv_func_mbox_work_handler(struct work_struct *work)
@@ -1233,6 +1234,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
set_mbox_to_func_event(func_to_func, EVENT_FAIL);
goto send_err;
}
+ func_to_func->hwdev->mbox_send_cnt++;
if (wait_mbox_msg_completion(func_to_func, timeout) != 0) {
sdk_err(func_to_func->hwdev->dev_hdl,
@@ -1241,6 +1243,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
err = -ETIMEDOUT;
goto send_err;
}
+ func_to_func->hwdev->mbox_ack_cnt++;
if (mod != msg_desc->mod || cmd != msg_desc->cmd) {
sdk_err(func_to_func->hwdev->dev_hdl,
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
index 3ad9a77..0d75177 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
@@ -348,7 +348,7 @@ int hinic3_pf_to_mgmt_sync(void *hwdev, u8 mod, u16 cmd, void *buf_in,
if (!COMM_SUPPORT_API_CHAIN((struct hinic3_hwdev *)hwdev))
return -EPERM;
- if (!buf_in || in_size == 0)
+ if ((buf_in == NULL) || (in_size == 0))
return -EINVAL;
ret = msg_to_mgmt_pre(mod, buf_in, in_size);
@@ -864,6 +864,7 @@ static int alloc_recv_msg(struct hinic3_recv_msg *recv_msg)
static void free_recv_msg(struct hinic3_recv_msg *recv_msg)
{
kfree(recv_msg->msg);
+ recv_msg->msg = NULL;
}
/**
@@ -935,6 +936,9 @@ static void free_msg_buf(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt)
free_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
+ pf_to_mgmt->mgmt_ack_buf = NULL;
+ pf_to_mgmt->sync_msg_buf = NULL;
+ pf_to_mgmt->async_msg_buf = NULL;
}
/**
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
index 3548410..b619800 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
@@ -676,6 +676,11 @@ static int hinic3_register_slave_ppf(struct hinic3_hwdev *hwdev, bool registered
if (!IS_SLAVE_HOST(hwdev))
return -EINVAL;
+ /* if unsupport hot plug, return true. */
+ if (UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev)) {
+ return 0;
+ }
+
host_info = kcalloc(1, sizeof(struct register_slave_host), GFP_KERNEL);
if (!host_info)
return -ENOMEM;
@@ -1074,8 +1079,9 @@ int hinic3_get_func_nic_enable(void *hwdev, u16 glb_func_idx, bool *en)
if (!hwdev || !en)
return -EINVAL;
- /* if single host, return true. */
- if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev)) {
+ /* if single host or unsupport hot plug, return true. */
+ if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev) ||
+ UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev)) {
*en = true;
return 0;
}
@@ -1145,11 +1151,18 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
{
int err;
struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+ int is_use_vram, is_in_kexec;
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
- hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0) {
+ snprintf(hwdev->mhost_mgmt_name, VRAM_NAME_MAX_LEN, "%s", VRAM_NIC_MHOST_MGMT);
+ hwdev->mhost_mgmt = hi_vram_kalloc(hwdev->mhost_mgmt_name, sizeof(*hwdev->mhost_mgmt));
+ } else {
+ hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ }
if (!hwdev->mhost_mgmt)
return -ENOMEM;
@@ -1165,8 +1178,11 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK, hwdev, hilink_ppf_mbox_handler);
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC, hwdev, sw_func_ppf_mbox_handler);
- bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
- bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ }
/* Slave host:
* register slave host ppf functions
@@ -1179,7 +1195,13 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
return 0;
out_free_mhost_mgmt:
- kfree(hwdev->mhost_mgmt);
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)hwdev->mhost_mgmt,
+ hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ } else {
+ kfree(hwdev->mhost_mgmt);
+ }
hwdev->mhost_mgmt = NULL;
return err;
@@ -1187,6 +1209,7 @@ out_free_mhost_mgmt:
int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
{
+ int is_use_vram;
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
@@ -1203,7 +1226,14 @@ int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC);
- kfree(hwdev->mhost_mgmt);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)hwdev->mhost_mgmt,
+ hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ } else {
+ kfree(hwdev->mhost_mgmt);
+ }
hwdev->mhost_mgmt = NULL;
return 0;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
index f7d350c..ee7afef 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
@@ -14,6 +14,7 @@
#include "hinic3_crm.h"
#include "hinic3_hw.h"
#include "hinic3_hw_cfg.h"
+#include "hinic3_dev_mgmt.h"
#include "hinic3_hwdev.h"
#include "hinic3_lld.h"
#include "hinic3_hw_mt.h"
@@ -22,9 +23,7 @@
static int g_nictool_ref_cnt;
static dev_t g_dev_id = {0};
-/*lint -save -e104 -e808*/
static struct class *g_nictool_class;
-/*lint -restore*/
static struct cdev g_nictool_cdev;
#define HINIC3_MAX_BUF_SIZE (2048 * 1024)
@@ -92,6 +91,21 @@ static int get_all_chip_id_cmd(struct hinic3_lld_dev *lld_dev, const void *buf_i
return 0;
}
+static int get_os_hot_replace_info(struct hinic3_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ if (*out_size != sizeof(struct os_hot_replace_info) || !buf_out) {
+ pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
+ *out_size, sizeof(struct os_hot_replace_info));
+ return -EFAULT;
+ }
+
+ hinic3_get_os_hot_replace_info(buf_out);
+
+ return 0;
+}
+
static int get_card_usr_api_chain_mem(int card_idx)
{
unsigned char *tmp = NULL;
@@ -100,8 +114,8 @@ static int get_card_usr_api_chain_mem(int card_idx)
card_id = card_idx;
if (!g_card_vir_addr[card_idx]) {
g_card_vir_addr[card_idx] =
- (void *)__get_free_pages(GFP_KERNEL,
- DBGTOOL_PAGE_ORDER);
+ (void *)ossl_get_free_pages(GFP_KERNEL,
+ DBGTOOL_PAGE_ORDER);
if (!g_card_vir_addr[card_idx]) {
pr_err("Alloc api chain memory fail for card %d!\n", card_idx);
return -EFAULT;
@@ -166,7 +180,7 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
if (!buf_out || *out_size != sizeof(struct pf_dev_info) * PF_DEV_INFO_NUM) {
pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
- *out_size, sizeof(dev_info) * PF_DEV_INFO_NUM);
+ *out_size, sizeof(*dev_info) * PF_DEV_INFO_NUM);
return -EFAULT;
}
@@ -193,13 +207,18 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
return 0;
}
-static long dbgtool_knl_free_mem(int id)
+static void dbgtool_knl_free_mem(int id)
{
unsigned char *tmp = NULL;
int i;
+ if (id < 0 || id >= MAX_CARD_NUM) {
+ pr_err("Invalid card id\n");
+ return;
+ }
+
if (!g_card_vir_addr[id])
- return 0;
+ return;
tmp = g_card_vir_addr[id];
for (i = 0; i < (1 << DBGTOOL_PAGE_ORDER); i++) {
@@ -210,8 +229,6 @@ static long dbgtool_knl_free_mem(int id)
free_pages((unsigned long)g_card_vir_addr[id], DBGTOOL_PAGE_ORDER);
g_card_vir_addr[id] = NULL;
g_card_phy_addr[id] = 0;
-
- return 0;
}
static int free_knl_mem(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_size,
@@ -236,7 +253,8 @@ static int free_knl_mem(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32
return 0;
}
-static int card_info_param_valid(char *dev_name, const void *buf_out, u32 buf_out_size, int *id)
+static int card_info_param_valid(const char *dev_name, const void *buf_out,
+ u32 buf_out_size, int *id)
{
int err;
@@ -351,7 +369,7 @@ static int get_hw_drv_version(struct hinic3_lld_dev *lld_dev, const void *buf_in
}
err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s", HINIC3_DRV_VERSION,
- "2023-05-17_19:56:38");
+ "2025-05-01_00:00:03");
if (err < 0)
return -EINVAL;
@@ -386,22 +404,38 @@ static int get_pf_id(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_
return 0;
}
+static int get_mbox_cnt(struct hinic3_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ if (buf_out == NULL || *out_size != sizeof(struct card_mbox_cnt_info)) {
+ pr_err("buf_out is NULL, or out_size != %lu\n",
+ sizeof(struct card_info));
+ return -EINVAL;
+ }
+
+ hinic3_get_mbox_cnt(hinic3_get_sdk_hwdev_by_lld(lld_dev), buf_out);
+
+ return 0;
+}
+
struct hw_drv_module_handle hw_driv_module_cmd_handle[] = {
- {FUNC_TYPE, get_func_type},
- {GET_FUNC_IDX, get_func_id},
- {GET_HW_STATS, (hw_driv_module)get_hw_driver_stats},
- {CLEAR_HW_STATS, clear_hw_driver_stats},
- {GET_SELF_TEST_RES, get_self_test_result},
- {GET_CHIP_FAULT_STATS, (hw_driv_module)get_chip_faults_stats},
- {GET_SINGLE_CARD_INFO, (hw_driv_module)get_single_card_info},
- {IS_DRV_IN_VM, is_driver_in_vm},
- {GET_CHIP_ID, get_all_chip_id_cmd},
- {GET_PF_DEV_INFO, get_pf_dev_info},
- {CMD_FREE_MEM, free_knl_mem},
- {GET_CHIP_INFO, get_card_func_info},
- {GET_FUNC_CAP, get_pf_cap_info},
- {GET_DRV_VERSION, get_hw_drv_version},
- {GET_PF_ID, get_pf_id},
+ {FUNC_TYPE, get_func_type},
+ {GET_FUNC_IDX, get_func_id},
+ {GET_HW_STATS, (hw_driv_module)get_hw_driver_stats},
+ {CLEAR_HW_STATS, clear_hw_driver_stats},
+ {GET_SELF_TEST_RES, get_self_test_result},
+ {GET_CHIP_FAULT_STATS, (hw_driv_module)get_chip_faults_stats},
+ {GET_SINGLE_CARD_INFO, (hw_driv_module)get_single_card_info},
+ {IS_DRV_IN_VM, is_driver_in_vm},
+ {GET_CHIP_ID, get_all_chip_id_cmd},
+ {GET_PF_DEV_INFO, get_pf_dev_info},
+ {CMD_FREE_MEM, free_knl_mem},
+ {GET_CHIP_INFO, get_card_func_info},
+ {GET_FUNC_CAP, get_pf_cap_info},
+ {GET_DRV_VERSION, get_hw_drv_version},
+ {GET_PF_ID, get_pf_id},
+ {GET_OS_HOT_REPLACE_INFO, get_os_hot_replace_info},
+ {GET_MBOX_CNT, (hw_driv_module)get_mbox_cnt},
};
static int alloc_tmp_buf(void *hwdev, struct msg_module *nt_msg, u32 in_size,
@@ -439,8 +473,8 @@ static void free_tmp_buf(void *hwdev, struct msg_module *nt_msg,
static int send_to_hw_driver(struct hinic3_lld_dev *lld_dev, struct msg_module *nt_msg,
const void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(hw_driv_module_cmd_handle) /
- sizeof(hw_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(hw_driv_module_cmd_handle) /
+ sizeof(hw_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type =
(enum driver_cmd_type)(nt_msg->msg_formate);
int err = 0;
@@ -482,8 +516,8 @@ static int send_to_service_driver(struct hinic3_lld_dev *lld_dev, struct msg_mod
if (nt_msg->msg_formate == GET_DRV_VERSION)
return 0;
- pr_err("Can not get the uld dev correctly: %s, %s driver may be not register\n",
- nt_msg->device_name, service_name[type]);
+ pr_err("Can not get the uld dev correctly: %s driver may be not register\n",
+ service_name[type]);
return -EINVAL;
}
@@ -550,26 +584,29 @@ static struct hinic3_lld_dev *get_lld_dev_by_nt_msg(struct msg_module *nt_msg)
{
struct hinic3_lld_dev *lld_dev = NULL;
- if (nt_msg->module >= SEND_TO_SRV_DRV_BASE && nt_msg->module < SEND_TO_DRIVER_MAX &&
- nt_msg->module != SEND_TO_HW_DRIVER && nt_msg->msg_formate != GET_DRV_VERSION) {
+ if (nt_msg->module == SEND_TO_NIC_DRIVER &&
+ (nt_msg->msg_formate == GET_XSFP_INFO ||
+ nt_msg->msg_formate == GET_XSFP_PRESENT ||
+ nt_msg->msg_formate == GET_XSFP_INFO_COMP_CMIS)) {
+ lld_dev = hinic3_get_lld_dev_by_chip_and_port(nt_msg->device_name, nt_msg->port_id);
+ } else if (nt_msg->module == SEND_TO_CUSTOM_DRIVER &&
+ nt_msg->msg_formate == CMD_CUSTOM_BOND_GET_CHIP_NAME) {
+ lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
+ SERVICE_T_MAX);
+ } else if (nt_msg->module == SEND_TO_VBS_DRIVER ||
+ nt_msg->module == SEND_TO_BIFUR_DRIVER) {
+ lld_dev = hinic3_get_lld_dev_by_chip_name(nt_msg->device_name);
+ } else if (nt_msg->module >= SEND_TO_SRV_DRV_BASE &&
+ nt_msg->module < SEND_TO_DRIVER_MAX &&
+ nt_msg->msg_formate != GET_DRV_VERSION) {
lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
nt_msg->module - SEND_TO_SRV_DRV_BASE);
} else {
lld_dev = hinic3_get_lld_dev_by_chip_name(nt_msg->device_name);
if (!lld_dev)
- lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
- SERVICE_T_MAX);
+ lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name, SERVICE_T_MAX);
}
- if (nt_msg->module == SEND_TO_NIC_DRIVER && (nt_msg->msg_formate == GET_XSFP_INFO ||
- nt_msg->msg_formate == GET_XSFP_PRESENT))
- lld_dev = hinic3_get_lld_dev_by_chip_and_port(nt_msg->device_name,
- nt_msg->port_id);
-
- if (nt_msg->module == SEND_TO_CUSTOM_DRIVER &&
- nt_msg->msg_formate == CMD_CUSTOM_BOND_GET_CHIP_NAME)
- lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name, SERVICE_T_MAX);
-
return lld_dev;
}
@@ -591,14 +628,16 @@ static long hinicadm_k_unlocked_ioctl(struct file *pfile, unsigned long arg)
lld_dev = get_lld_dev_by_nt_msg(&nt_msg);
if (!lld_dev) {
if (nt_msg.msg_formate != DEV_NAME_TEST)
- pr_err("Can not find device %s for module %d\n",
+ pr_err("Can not find device %s for module %u\n",
nt_msg.device_name, nt_msg.module);
return -ENODEV;
}
- if (nt_msg.msg_formate == DEV_NAME_TEST)
+ if (nt_msg.msg_formate == DEV_NAME_TEST) {
+ lld_dev_put(lld_dev);
return 0;
+ }
ret = alloc_tmp_buf(hinic3_get_sdk_hwdev_by_lld(lld_dev), &nt_msg,
in_size, &buf_in, out_size_expect, &buf_out);
@@ -642,6 +681,9 @@ out_free_lock:
static long dbgtool_knl_ffm_info_rd(struct dbgtool_param *para,
struct dbgtool_k_glb_info *dbgtool_info)
{
+ if (!para->param.ffm_rd || !dbgtool_info->ffm)
+ return -EINVAL;
+
/* Copy the ffm_info to user mode */
if (copy_to_user(para->param.ffm_rd, dbgtool_info->ffm,
(unsigned int)sizeof(struct ffm_record_info))) {
@@ -674,13 +716,14 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
card_info = (struct card_node *)g_card_node_array[i];
if (!card_info)
continue;
- if (!strncmp(param.chip_name, card_info->chip_name, IFNAMSIZ))
+ if (memcmp(param.chip_name, card_info->chip_name,
+ strlen(card_info->chip_name) + 1) == 0)
break;
}
if (i == MAX_CARD_NUM || !card_info) {
lld_put();
- pr_err("Can't find this card %s\n", param.chip_name);
+ pr_err("Can't find this card.\n");
return -EFAULT;
}
@@ -701,6 +744,7 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
default:
pr_err("Dbgtool cmd(0x%x) not support now\n", real_cmd);
ret = -EFAULT;
+ break;
}
up(&dbgtool_info->dbgtool_sem);
@@ -746,9 +790,11 @@ static long nictool_k_unlocked_ioctl(struct file *pfile,
static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
{
+ pgprot_t vm_page_prot;
unsigned long vmsize = vma->vm_end - vma->vm_start;
phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
phys_addr_t phy_addr;
+ int err = 0;
if (vmsize > (PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER))) {
pr_err("Map size = %lu is bigger than alloc\n", vmsize);
@@ -757,14 +803,18 @@ static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
/* old version of tool set vma->vm_pgoff to 0 */
phy_addr = offset ? offset : g_card_phy_addr[card_id];
-
- if (!phy_addr) {
- pr_err("Card_id = %d physical address is 0\n", card_id);
- return -EAGAIN;
+ /* check phy_addr valid */
+ if (phy_addr != g_card_phy_addr[card_id]) {
+ err = hinic3_bar_mmap_param_valid(phy_addr, vmsize);
+ if (err != 0) {
+ pr_err("mmap param invalid, err: %d\n", err);
+ return err;
+ }
}
/* Disable cache and write buffer in the mapping area */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_page_prot = vm_page_prot;
if (remap_pfn_range(vma, vma->vm_start, (phy_addr >> PAGE_SHIFT),
vmsize, vma->vm_page_prot)) {
pr_err("Remap pfn range failed.\n");
@@ -787,7 +837,6 @@ static const struct file_operations fifo_operations = {
static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
{
struct dbgtool_k_glb_info *dbgtool_info = NULL;
- int err, id;
if (hinic3_func_type(hwdev) != TYPE_VF)
chip_info->func_handle_array[hinic3_global_func_id(hwdev)] = NULL;
@@ -795,23 +844,23 @@ static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
if (--chip_info->func_num)
return;
- err = sscanf(chip_info->chip_name, HINIC3_CHIP_NAME "%d", &id);
- if (err < 0)
- pr_err("Failed to get card id\n");
-
- if (id < MAX_CARD_NUM)
- g_card_node_array[id] = NULL;
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ g_card_node_array[chip_info->chip_id] = NULL;
dbgtool_info = chip_info->dbgtool_info;
/* FFM deinit */
- kfree(dbgtool_info->ffm);
- dbgtool_info->ffm = NULL;
+ if (dbgtool_info && dbgtool_info->ffm) {
+ kfree(dbgtool_info->ffm);
+ dbgtool_info->ffm = NULL;
+ }
+
+ if (dbgtool_info)
+ kfree(dbgtool_info);
- kfree(dbgtool_info);
chip_info->dbgtool_info = NULL;
- if (id < MAX_CARD_NUM)
- (void)dbgtool_knl_free_mem(id);
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ dbgtool_knl_free_mem(chip_info->chip_id);
}
static int alloc_dbgtool_info(void *hwdev, struct card_node *chip_info)
@@ -872,7 +921,6 @@ dbgtool_info_fail:
* nictool_k_init - initialize the hw interface
**/
/* temp for dbgtool_info */
-/*lint -e438*/
int nictool_k_init(void *hwdev, void *chip_node)
{
struct card_node *chip_info = (struct card_node *)chip_node;
@@ -895,9 +943,7 @@ int nictool_k_init(void *hwdev, void *chip_node)
}
/* Create equipment */
- /*lint -save -e160*/
g_nictool_class = class_create(THIS_MODULE, HIADM3_DEV_CLASS);
- /*lint -restore*/
if (IS_ERR(g_nictool_class)) {
pr_err("Create nictool_class fail\n");
err = -EFAULT;
@@ -944,7 +990,7 @@ alloc_chdev_fail:
free_dbgtool_info(hwdev, chip_info);
return err;
-} /*lint +e438*/
+}
void nictool_k_uninit(void *hwdev, void *chip_node)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
index f368133..c943dfc 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
@@ -18,6 +18,8 @@
int nictool_k_init(void *hwdev, void *chip_node);
void nictool_k_uninit(void *hwdev, void *chip_node);
+void hinic3_get_os_hot_replace_info(void *oshr_info);
+
void hinic3_get_all_chip_id(void *id_info);
void hinic3_get_card_func_info_by_card_name
@@ -29,6 +31,8 @@ bool hinic3_is_in_host(void);
int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *isvalid);
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin);
+
extern struct hinic3_uld_info g_uld_info[SERVICE_T_MAX];
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
index 2d5423e..6f145a0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
@@ -19,6 +19,20 @@
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
+#elif defined(CONFIG_NF_VID_DID)
+#define PCI_VENDOR_ID_NF 0x2036
+#define NFNIC_DEV_ID_STANDARD 0x1618
+#define NFNIC_DEV_ID_SDI_5_1_PF 0x0226
+#define NFNIC_DEV_ID_SDI_5_0_PF 0x0225
+#define NFNIC_DEV_ID_DPU_PF 0x0224
+#define NFNIC_DEV_ID_VF 0x1619
+#define NFNIC_DEV_ID_VF_HV 0x379F
+#define NFNIC_DEV_SDI_5_1_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_0_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_1_ID_VF_HV 0x379F
+#define NFNIC_DEV_ID_SPU 0xAC00
+#define NFNIC_DEV_SDI_5_1_SSDID_VF 0x1000
+#define NFNIC_DEV_SDI_V100_SSDID_MASK (3 << 12)
#else
#define PCI_VENDOR_ID_HUAWEI 0x19e5
#define HINIC3_DEV_ID_STANDARD 0x0222
@@ -28,16 +42,33 @@
#define HINIC3_DEV_ID_VF 0x375F
#define HINIC3_DEV_ID_VF_HV 0x379F
#define HINIC3_DEV_SDI_5_1_ID_VF 0x375F
+#define HINIC3_DEV_SDI_5_0_ID_VF 0x375F
#define HINIC3_DEV_SDI_5_1_ID_VF_HV 0x379F
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
#endif
+#define NFNIC_DEV_SSID_2X25G_NF 0x0860
+#define NFNIC_DEV_SSID_4X25G_NF 0x0861
+#define NFNIC_DEV_SSID_2x100G_NF 0x0862
+#define NFNIC_DEV_SSID_2x200G_NF 0x0863
+
+#define HINIC3_DEV_SSID_2X10G 0x0035
#define HINIC3_DEV_SSID_2X25G 0x0051
#define HINIC3_DEV_SSID_4X25G 0x0052
+#define HINIC3_DEV_SSID_4X25G_BD 0x0252
+#define HINIC3_DEV_SSID_4X25G_SMARTNIC 0x0152
+#define HINIC3_DEV_SSID_6X25G_VL 0x0356
#define HINIC3_DEV_SSID_2X100G 0x00A1
+#define HINIC3_DEV_SSID_2X100G_SMARTNIC 0x01A1
+#define HINIC3_DEV_SSID_2X200G 0x04B1
#define HINIC3_DEV_SSID_2X100G_VF 0x1000
+#define HINIC3_DEV_SSID_HPC_4_HOST_NIC 0x005A
+#define HINIC3_DEV_SSID_2X200G_VL 0x00B1
+#define HINIC3_DEV_SSID_1X100G 0x02A4
+
+#define BIFUR_RESOURCE_PF_SSID 0x05a1
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
index b23b69f..c8258ff 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
@@ -68,7 +68,6 @@ ssize_t hinic3_sriov_numvfs_show(struct device *dev,
return sprintf(buf, "%d\n", pci_num_vf(pdev));
}
-/*lint -save -e713*/
ssize_t hinic3_sriov_numvfs_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -116,7 +115,6 @@ ssize_t hinic3_sriov_numvfs_store(struct device *dev,
return count;
}
-/*lint -restore*/
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
int hinic3_pci_sriov_disable(struct pci_dev *dev)
@@ -174,24 +172,15 @@ int hinic3_pci_sriov_disable(struct pci_dev *dev)
return 0;
}
-int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
-{
#ifdef CONFIG_PCI_IOV
- struct hinic3_sriov_info *sriov_info = NULL;
- struct hinic3_event_info event = {0};
- void *hwdev = NULL;
- int pre_existing_vfs = 0;
- int err = 0;
-
- sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
- hwdev = hinic3_get_hwdev_by_pcidev(dev);
- if (!hwdev) {
- sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
- return -EPERM;
- }
+int hinic3_pci_sriov_check(struct hinic3_sriov_info *sriov_info, struct pci_dev *dev, int num_vfs)
+{
+ int pre_existing_vfs;
+ int err;
if (test_and_set_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state)) {
- sdk_err(&dev->dev, "SR-IOV enable in process, please wait, num_vfs %d\n",
+ sdk_err(&dev->dev,
+ "SR-IOV enable in process, please wait, num_vfs %d\n",
num_vfs);
return -EPERM;
}
@@ -202,6 +191,7 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
clear_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state);
return -ERANGE;
}
+
if (pre_existing_vfs && pre_existing_vfs != num_vfs) {
err = hinic3_pci_sriov_disable(dev);
if (err) {
@@ -213,6 +203,31 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
return num_vfs;
}
+ return 0;
+}
+#endif
+
+
+int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
+{
+#ifdef CONFIG_PCI_IOV
+ struct hinic3_sriov_info *sriov_info = NULL;
+ struct hinic3_event_info event = {0};
+ void *hwdev = NULL;
+ int err = 0;
+
+ sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
+ hwdev = hinic3_get_hwdev_by_pcidev(dev);
+ if (!hwdev) {
+ sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
+ return -EPERM;
+ }
+
+ err = hinic3_pci_sriov_check(sriov_info, dev, num_vfs);
+ if (err != 0) {
+ return err;
+ }
+
err = hinic3_init_vf_hw(hwdev, 1, (u16)num_vfs);
if (err) {
sdk_err(&dev->dev, "Failed to init vf in hardware before enable sriov, error %d\n",
@@ -262,6 +277,3 @@ int hinic3_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
else
return hinic3_pci_sriov_enable(dev, num_vfs);
}
-
-/*lint -restore*/
-
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c
index 2f5e098..4f8acd6 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c
@@ -128,7 +128,7 @@ int hinic3_wq_create(void *hwdev, struct hinic3_wq *wq, u32 q_depth,
wq_page_size = ALIGN(dev->wq_page_size, PAGE_SIZE);
- memset(wq, 0, sizeof(*wq));
+ memset(wq, 0, sizeof(struct hinic3_wq));
wq->dev_hdl = dev->dev_hdl;
wq->q_depth = q_depth;
wq->idx_mask = (u16)(q_depth - 1);
diff --git a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
index 9e8fc75..bfb4499 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
@@ -10,6 +10,10 @@
#define OVS_PORT_NUM_MAX BOND_PORT_MAX_NUM
#define DEFAULT_ROCE_BOND_FUNC 0xFFFFFFFF
+#define BOND_ID_IS_VALID(_id) \
+ (((_id) >= BOND_FIRST_ID) && ((_id) <= BOND_MAX_ID))
+#define BOND_ID_IS_INVALID(_id) (!(BOND_ID_IS_VALID(_id)))
+
enum bond_group_id {
BOND_FIRST_ID = 1,
BOND_MAX_ID = 4,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
index f56df08..f9737ea 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
@@ -21,6 +21,7 @@ enum servic_bit_define {
SERVICE_BIT_PPA = 11,
SERVICE_BIT_MIGRATE = 12,
SERVICE_BIT_VROCE = 13,
+ SERVICE_BIT_BIFUR = 14,
SERVICE_BIT_MAX
};
@@ -38,6 +39,7 @@ enum servic_bit_define {
#define CFG_SERVICE_MASK_PPA (0x1 << SERVICE_BIT_PPA)
#define CFG_SERVICE_MASK_MIGRATE (0x1 << SERVICE_BIT_MIGRATE)
#define CFG_SERVICE_MASK_VROCE (0x1 << SERVICE_BIT_VROCE)
+#define CFG_SERVICE_MASK_BIFUR (0x1 << SERVICE_BIT_BIFUR)
/* Definition of the scenario ID in the cfg_data, which is used for SML memory allocation. */
enum scenes_id_define {
@@ -50,6 +52,8 @@ enum scenes_id_define {
SCENES_ID_STORAGE_ROCE = 6,
SCENES_ID_COMPUTE_ROCE = 7,
SCENES_ID_STORAGE_TOE = 8,
+ SCENES_ID_COMPUTE_DPU = 100,
+ SCENES_ID_COMPUTE_SMART_NIC = 101,
SCENES_ID_MAX
};
@@ -120,13 +124,18 @@ struct cfg_cmd_dev_cap {
u8 srv_multi_host_mode;
u8 virtio_vq_size;
- u32 rsvd_func3[5];
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 lro_enable;
+ u8 os_hot_replace;
+
+ u32 rsvd_func3[4];
/* l2nic */
u16 nic_max_sq_id;
u16 nic_max_rq_id;
u16 nic_default_num_queues;
- u16 rsvd1_nic;
+ u16 outband_vlan_cfg_en;
u32 rsvd2_nic[2];
/* RoCE */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
index d9f67e2..6c5b995 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
@@ -37,7 +37,7 @@ static inline void hinic3_cpu_to_be32(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -59,7 +59,7 @@ static inline void hinic3_be32_to_cpu(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -86,52 +86,16 @@ static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
sge->len = (u32)len;
}
-#ifdef HW_CONVERT_ENDIAN
#define hinic3_hw_be32(val) (val)
#define hinic3_hw_cpu32(val) (val)
#define hinic3_hw_cpu16(val) (val)
-#else
-#define hinic3_hw_be32(val) cpu_to_be32(val)
-#define hinic3_hw_cpu32(val) be32_to_cpu(val)
-#define hinic3_hw_cpu16(val) be16_to_cpu(val)
-#endif
static inline void hinic3_hw_be32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_be32(*mem);
- mem++;
- }
-#endif
}
static inline void hinic3_hw_cpu32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_cpu32(*mem);
- mem++;
- }
-#endif
}
int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
@@ -149,6 +113,8 @@ int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
/* func_attr.glb_func_idx, global function index */
u16 hinic3_global_func_id(void *hwdev);
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id);
+
/* func_attr.p2p_idx, belongs to which pf */
u8 hinic3_pf_id_of_vf(void *hwdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
index 9a9bfe2..e36ba1d 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
@@ -219,5 +219,7 @@ void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
const char **hinic3_get_uld_names(void);
+int hinic3_lld_init(void);
+void hinic3_lld_exit(void);
#endif
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
index 97d34f0..199f17a 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
@@ -43,6 +43,10 @@ enum mag_cmd {
MAG_CMD_GET_XSFP_PRESENT = 62, /* get xsfp present status @see mag_cmd_get_xsfp_present */
MAG_CMD_SET_XSFP_RW = 63, /* sfp/qsfp single byte read/write, @see mag_cmd_set_xsfp_rw */
MAG_CMD_CFG_XSFP_TEMPERATURE = 64, /* get xsfp temp @see mag_cmd_sfp_temp_out_info */
+ /**< set xsfp tlv info @see struct mag_cmd_set_xsfp_tlv_req */
+ MAG_CMD_SET_XSFP_TLV_INFO = 65,
+ /**< get xsfp tlv info @see struct drv_mag_cmd_get_xsfp_tlv_rsp */
+ MAG_CMD_GET_XSFP_TLV_INFO = 66,
/* Event reported 100-149 */
MAG_CMD_WIRE_EVENT = 100,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
index caaba5d..88a9c0d 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
@@ -16,32 +16,43 @@
#define BOARD_TYPE_RSVD_RANGE_END 255
enum board_type_define_e {
- BOARD_TYPE_MPU_DEFAULT = 0, /* Default config */
- BOARD_TYPE_TEST_EVB_4X25G = 1, /* EVB Board */
- BOARD_TYPE_TEST_CEM_2X100G = 2, /* 2X100G CEM Card */
- BOARD_TYPE_STRG_SMARTIO_4X32G_FC = 30, /* 4X32G SmartIO FC Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_TIOE = 31, /* 4X25GE SmartIO TIOE Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE = 32, /* 4X25GE SmartIO ROCE Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE_AA = 33, /* 4X25GE SmartIO ROCE_AA Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV = 34, /* 4X25GE SmartIO container Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV_SW = 35, /* 4X25GE SmartIO container switch Card */
- BOARD_TYPE_STRG_4X25G_COMSTORAGE = 36, /* 4X25GE compute storage Onboard Card */
- BOARD_TYPE_STRG_2X100G_TIOE = 40, /* 2X100G SmartIO TIOE Card */
- BOARD_TYPE_STRG_2X100G_ROCE = 41, /* 2X100G SmartIO ROCE Card */
- BOARD_TYPE_STRG_2X100G_ROCE_AA = 42, /* 2X100G SmartIO ROCE_AA Card */
- BOARD_TYPE_CAL_2X25G_NIC_75MPPS = 100, /* 2X25G ETH Standard card 75MPPS */
- BOARD_TYPE_CAL_2X25G_NIC_40MPPS = 101, /* 2X25G ETH Standard card 40MPPS */
- BOARD_TYPE_CAL_2X100G_DPU = 102, /* 2x100G DPU Card */
- BOARD_TYPE_CAL_4X25G_NIC_120MPPS = 105, /* 4X25G ETH Standard card 120MPPS */
- BOARD_TYPE_CAL_4X25G_COMSTORAGE = 106, /* 4X25GE compute storage Onboard Card */
- BOARD_TYPE_CAL_2X32G_FC_HBA = 110, /* 2X32G FC HBA card */
- BOARD_TYPE_CAL_2X16G_FC_HBA = 111, /* 2X16G FC HBA card */
- BOARD_TYPE_CAL_2X100G_NIC_120MPPS = 115, /* 2X100G ETH Standard card 120MPPS */
- BOARD_TYPE_CAL_2X25G_DPU = 116, /* 2x25G DPU Card */
- BOARD_TYPE_CAL_4X25G_DPU = 118, /* 4x25G DPU Card */
- BOARD_TYPE_CLD_2X100G_SDI5_1 = 170, /* 2X100G SDI 5.1 Card */
- BOARD_TYPE_CLD_2X25G_SDI5_0_LITE = 171, /* 2x25G SDI5.0 Lite Card */
- BOARD_TYPE_CLD_2X100G_SDI5_0 = 172, /* 2x100G SDI5.0 Card */
+ BOARD_TYPE_MPU_DEFAULT = 0,
+ BOARD_TYPE_TEST_EVB_4X25G = 1,
+ BOARD_TYPE_TEST_CEM_2X100G = 2,
+ BOARD_TYPE_STRG_SMARTIO_4X32G_FC = 30,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_TIOE = 31,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE = 32,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE_AA = 33,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV = 34,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV_SW = 35,
+ BOARD_TYPE_STRG_4X25G_COMSTORAGE = 36,
+ BOARD_TYPE_STRG_2X100G_TIOE = 40,
+ BOARD_TYPE_STRG_2X100G_ROCE = 41,
+ BOARD_TYPE_STRG_2X100G_ROCE_AA = 42,
+ BOARD_TYPE_CAL_2X25G_NIC_75MPPS = 100,
+ BOARD_TYPE_CAL_2X25G_NIC_40MPPS = 101,
+ BOARD_TYPE_CAL_2X100G_DPU_VL = 102,
+ BOARD_TYPE_CAL_4X25G_NIC_120MPPS = 105,
+ BOARD_TYPE_CAL_4X25G_COMSTORAGE = 106,
+ BOARD_TYPE_CAL_2X32G_FC_HBA = 110,
+ BOARD_TYPE_CAL_2X16G_FC_HBA = 111,
+ BOARD_TYPE_CAL_2X100G_NIC_120MPPS = 115,
+ BOARD_TYPE_CAL_2X25G_DPU_BD = 116,
+ BOARD_TYPE_CAL_2X100G_TCE_BACKPLANE = 117,
+ BOARD_TYPE_CAL_4X25G_DPU_VL = 118,
+ BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS = 119,
+ BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS = 120,
+ BOARD_TYPE_CAL_6X25G_DPU_VL = 121,
+ BOARD_TYPE_CAL_4X25G_DPU_BD = 122,
+ BOARD_TYPE_CAL_2X25G_NIC_4HOST = 123,
+ BOARD_TYPE_CAL_2X10G_LOW_POWER = 125,
+ BOARD_TYPE_CAL_2X200G_NIC_INTERNET = 127,
+ BOARD_TYPE_CAL_1X100GR2_OCP = 129,
+ BOARD_TYPE_CAL_2X200G_DPU_VL = 130,
+ BOARD_TYPE_CLD_2X100G_SDI5_1 = 170,
+ BOARD_TYPE_CLD_2X25G_SDI5_0_LITE = 171,
+ BOARD_TYPE_CLD_2X100G_SDI5_0 = 172,
+ BOARD_TYPE_CLD_4X25G_SDI5_0_C = 175,
BOARD_TYPE_MAX_INDEX = 0xFF
};
@@ -49,23 +60,76 @@ static inline u32 spu_board_type_valid(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
- ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
+}
+
+static inline int board_type_is_sdi_50(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
+ ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C);
}
static inline int board_type_is_sdi(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_1) ||
((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
- ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0);
+ ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C);
+}
+
+static inline int board_type_is_dpu_spu(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
}
static inline int board_type_is_dpu(u32 board_type)
{
- return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_6X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
+}
+
+static inline int board_type_is_smartnic(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS);
+}
+
+/* 此接口判断是否是分布式存储的标卡以及计算的标卡(含ROCE特性),
+ * 仅用于LLDP TX功能冲突命令字处理的判断
+ */
+static inline int board_type_is_compute(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_75MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_40MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_NIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_COMSTORAGE) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_NIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X10G_LOW_POWER) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_NIC_INTERNET) ||
+ ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_4HOST) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS);
+}
+
+/* 此接口判断服务器输入reboot网卡是否需要复位 */
+static inline int board_type_is_multi_socket(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP);
}
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
index 89d5cc4..e65c206 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
@@ -1,11 +1,11 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ * Description : common definitions
+ */
#ifndef COMM_DEFS_H
#define COMM_DEFS_H
-#include "mgmt_msg_base.h"
-
/** MPU CMD MODULE TYPE */
enum hinic3_mod_type {
HINIC3_MOD_COMM = 0, /* HW communication module */
@@ -33,16 +33,16 @@ enum hinic3_mod_type {
HINIC3_MOD_MAX,
};
-/* Func reset flag, Specifies the resource to be cleaned.*/
-enum func_reset_flag_e {
+/* func reset的flag ,用于指示清理哪种资源 */
+enum func_reset_flag_e{
RES_TYPE_FLUSH_BIT = 0,
RES_TYPE_MQM,
RES_TYPE_SMF,
RES_TYPE_PF_BW_CFG,
RES_TYPE_COMM = 10,
- RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
RES_TYPE_NIC,
RES_TYPE_OVS,
RES_TYPE_VBS,
@@ -53,33 +53,48 @@ enum func_reset_flag_e {
RES_TYPE_MAX,
};
-#define HINIC3_COMM_RES \
- ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
- (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
- (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
+#define HINIC3_COMM_RES \
+ ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
+ (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
+ (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
-#define HINIC3_NIC_RES BIT(RES_TYPE_NIC)
-#define HINIC3_OVS_RES BIT(RES_TYPE_OVS)
-#define HINIC3_VBS_RES BIT(RES_TYPE_VBS)
-#define HINIC3_ROCE_RES BIT(RES_TYPE_ROCE)
-#define HINIC3_FC_RES BIT(RES_TYPE_FC)
-#define HINIC3_TOE_RES BIT(RES_TYPE_TOE)
-#define HINIC3_IPSEC_RES BIT(RES_TYPE_IPSEC)
+#define HINIC3_NIC_RES (1 << RES_TYPE_NIC)
+#define HINIC3_OVS_RES (1 << RES_TYPE_OVS)
+#define HINIC3_VBS_RES (1 << RES_TYPE_VBS)
+#define HINIC3_ROCE_RES (1 << RES_TYPE_ROCE)
+#define HINIC3_FC_RES (1 << RES_TYPE_FC)
+#define HINIC3_TOE_RES (1 << RES_TYPE_TOE)
+#define HINIC3_IPSEC_RES (1 << RES_TYPE_IPSEC)
/* MODE OVS、NIC、UNKNOWN */
#define HINIC3_WORK_MODE_OVS 0
#define HINIC3_WORK_MODE_UNKNOWN 1
#define HINIC3_WORK_MODE_NIC 2
-#define DEVICE_TYPE_L2NIC 0
-#define DEVICE_TYPE_NVME 1
-#define DEVICE_TYPE_VIRTIO_NET 2
-#define DEVICE_TYPE_VIRTIO_BLK 3
-#define DEVICE_TYPE_VIRTIO_VSOCK 4
-#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
-#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
-#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
-#define DEVICE_TYPE_VIRTIO_HPC 8
+#define DEVICE_TYPE_L2NIC 0
+#define DEVICE_TYPE_NVME 1
+#define DEVICE_TYPE_VIRTIO_NET 2
+#define DEVICE_TYPE_VIRTIO_BLK 3
+#define DEVICE_TYPE_VIRTIO_VSOCK 4
+#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
+#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
+#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
+#define DEVICE_TYPE_VIRTIO_HPC 8
+#define DEVICE_TYPE_VIRTIO_FS 9
+
+#define IS_STORAGE_DEVICE_TYPE(dev_type) \
+ ((dev_type) == DEVICE_TYPE_VIRTIO_BLK || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_BLK_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_SCSI_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_FS)
+
+#define MGMT_MSG_CMD_OP_SET 1
+#define MGMT_MSG_CMD_OP_GET 0
+
+#define MGMT_MSG_CMD_OP_START 1
+#define MGMT_MSG_CMD_OP_STOP 0
+
+#define HOT_REPLACE_PARTITION_NUM 2
enum hinic3_svc_type {
SVC_T_COMM = 0,
@@ -98,8 +113,17 @@ enum hinic3_svc_type {
};
/**
- * Common header control information of the COMM message interaction command word
- * between the driver and PF.
+ * Common header control information of the COMM message interaction command word between the driver and PF
+ * stuct mgmt_msg_head and struct comm_info_head are the same stucture
+ */
+struct mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+/**
+ * Common header control information of the COMM message interaction command word between the driver and PF
*/
struct comm_info_head {
/** response status code, 0: success, others: error code */
@@ -113,4 +137,29 @@ struct comm_info_head {
u8 rsvd[5];
};
+
+static inline u32 get_function_partition(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM;
+}
+
+static inline u32 is_primary_function(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0;
+}
+
+static inline u32 mpu_nic_get_primary_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ function_id : (function_id - port_num);
+}
+
+// when func_id is in partition 0/1, it will get its another func_id in partition 1/0
+static inline u32 mpu_nic_get_backup_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ (function_id + port_num) : (function_id - port_num);
+}
+
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
index b24e729..fd0401f 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
@@ -89,6 +89,10 @@ enum hinic3_mgmt_cmd {
* @see comm_read_ucode_sm_resp
*/
COMM_MGMT_CMD_CLEAR_LOG, /**< clear log @see comm_cmd_clear_log_s */
+ COMM_MGMT_CMD_UCODE_SM_COUNTER_PER,
+ /**< get ucode sm counter @see struct comm_read_ucode_sm_per_req
+ * @see struct comm_read_ucode_sm_per_resp
+ */
COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140, /* check if switch workmode reserved
* @see comm_cmd_check_if_switch_workmode
@@ -101,6 +105,7 @@ enum hinic3_mgmt_cmd {
COMM_MGMT_CMD_CPI_TCAM_DBG, /* enable or disable the scheduled cpi tcam task,
* set task interval time @see comm_cmd_cpi_tcam_dbg_s
*/
+ COMM_MGMT_CMD_LLDP_TX_FUNC_SET,
COMM_MGMT_CMD_SECTION_RSVD_0 = 160, /**< rsvd0 section */
COMM_MGMT_CMD_SECTION_RSVD_1 = 170, /**< rsvd1 section */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
index f535777..fd3a7dd 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
@@ -313,7 +313,8 @@ struct comm_cmd_get_fw_version {
struct mgmt_msg_head head;
u16 fw_type; /**< firmware type @see enum hinic3_fw_ver_type */
- u16 rsvd1;
+ u16 fw_dfx_vld : 1; /**< 0: release, 1: debug */
+ u16 rsvd1 : 15;
u8 ver[HINIC3_FW_VERSION_LEN]; /**< firmware version */
u8 time[HINIC3_FW_COMPILE_TIME_LEN]; /**< firmware compile time */
};
@@ -558,6 +559,7 @@ struct nic_log_info_request {
#define MPU_TEMP_OP_GET 0
#define MPU_TEMP_THRESHOLD_OP_CFG 1
+#define MPU_TEMP_MCTP_DFX_INFO_GET 2
struct comm_temp_in_info {
struct comm_info_head head;
u8 opt_type; /**< operation type 0:read operation 1:cfg operation */
@@ -660,6 +662,28 @@ struct comm_read_ucode_sm_resp {
u64 val2;
};
+#define PER_REQ_MAX_DATA_LEN 0x600
+
+struct comm_read_ucode_sm_per_req {
+ struct mgmt_msg_head msg_head;
+
+ u32 tbl_type;
+ u32 count_id;
+};
+
+struct comm_read_ucode_sm_per_resp {
+ struct mgmt_msg_head msg_head;
+
+ u8 data[PER_REQ_MAX_DATA_LEN];
+};
+
+struct ucode_sm_counter_get_info {
+ u32 width_type;
+ u32 tbl_type;
+ unsigned int base_count;
+ unsigned int count_num;
+};
+
enum log_type {
MPU_LOG_CLEAR = 0,
SMU_LOG_CLEAR = 1,
@@ -1057,7 +1081,9 @@ struct comm_cmd_ncsi_settings {
u8 lldp_over_ncsi_enable;
u8 lldp_over_mctp_enable;
u32 magicwd;
- u8 rsvd[8];
+ u8 lldp_tx_enable;
+ u8 rsvd[3];
+ u32 crc;
struct tag_ncsi_chan_info ncsi_chan_info;
};
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
index fde8617..767f886 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
@@ -114,6 +114,14 @@ struct tag_ncsi_client_info {
#define AEN_CTRL_CONFIG_REQ_SHIFT 1
#define AEN_CTRL_DRV_CHANGE_SHIFT 2
+/* AEN Type */
+enum aen_type_e{
+ AEN_LINK_STATUS_CHANGE_TYPE = 0x0,
+ AEN_CONFIG_REQUIRED_TYPE = 0x1,
+ OEM_AEN_CONFIG_REQUEST_TYPE = 0x80,
+ AEN_TYPE_MAX = 0x100
+} ;
+
/* get link status 0x0A */
#define GET_LINK_STATUS_REQ_LEN 0
#define GET_LINK_STATUS_RSP_LEN 16
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
index fe663e1..83b75f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
@@ -1,5 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+/*
+ * Copyright (C), 2001-2021, Huawei Tech. Co., Ltd.
+ * File Name : nic_cfg_comm.h
+ * Version : Initial Draft
+ * Description : nic config common header file
+ * Function List :
+ * History :
+ * Modification: Created file
+ */
#ifndef NIC_CFG_COMM_H
#define NIC_CFG_COMM_H
@@ -26,7 +34,7 @@ enum nic_rss_hash_type {
};
#define NIC_RSS_INDIR_SIZE 256
-#define NIC_RSS_KEY_SIZE 40
+#define NIC_RSS_KEY_SIZE 40
/* *
* Definition of the NIC receiving mode
@@ -36,6 +44,7 @@ enum nic_rss_hash_type {
#define NIC_RX_MODE_BC 0x04
#define NIC_RX_MODE_MC_ALL 0x08
#define NIC_RX_MODE_PROMISC 0x10
+#define NIC_RX_DB_COS_MAX 0x4
/* IEEE 802.1Qaz std */
#define NIC_DCB_COS_MAX 0x8
@@ -52,4 +61,7 @@ enum nic_rss_hash_type {
#define NIC_DCB_PRIO_STRICT 0x1
#define NIC_DCB_MAX_PFC_NUM 0x4
+
+#define NIC_ETS_PERCENT_WEIGHT 100
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
index 801aeed..9f93f7e 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
@@ -23,7 +23,11 @@
#define VRAM_CQM_BITMAP_BASE "B"
#define VRAM_NIC_DCB "DCB"
+#define VRAM_NIC_MHOST_MGMT "MHOST_MGMT"
#define VRAM_NIC_VRAM "NIC_VRAM"
+#define VRAM_NIC_IRQ_VRAM "NIC_IRQ"
+
+#define VRAM_NIC_MQM "NM"
#define VRAM_VBS_BASE_IOCB "BASE_IOCB"
#define VRAM_VBS_EX_IOCB "EX_IOCB"
@@ -55,11 +59,16 @@ enum KUP_HOOK_POINT {
PRE_FREEZE,
FREEZE_TO_KILL,
PRE_UPDATE_KERNEL,
- FLUSH_DURING_KUP,
POST_UPDATE_KERNEL,
UNFREEZE_TO_RUN,
POST_RUN,
KUP_HOOK_MAX,
};
+#define hi_vram_kalloc(name, size) 0
+#define hi_vram_kfree(vaddr, name, size)
+#define get_use_vram_flag(void) 0
+#define vram_get_kexec_flag(void) 0
+#define hi_vram_get_gfp_vram(void) 0
+
#endif /* VRAM_COMMON_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
similarity index 79%
rename from drivers/net/ethernet/huawei/hinic3/mag_cmd.h
rename to drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
index 9649503..e77d7d5 100644
--- a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
@@ -9,6 +9,7 @@
/* serdes cmd struct define */
#define CMD_ARRAY_BUF_SIZE 64
#define SERDES_CMD_DATA_BUF_SIZE 512
+#define RATE_MBPS_TO_GBPS 1000
struct serdes_in_info {
u32 chip_id : 16;
u32 macro_id : 16;
@@ -127,6 +128,7 @@ enum mag_cmd_cnt_type {
MAG_RX_PCS_E_BLK_CNT = 5,
MAG_RX_PCS_DEC_ERR_BLK_CNT = 6,
MAG_RX_PCS_LANE_BIP_ERR_CNT = 7,
+ MAG_RX_RSFEC_ERR_CW_CNT = 8,
MAG_CNT_NUM
};
@@ -208,7 +210,9 @@ struct mag_cmd_get_port_info {
u32 supported_mode;
u32 advertised_mode;
- u8 rsvd2[8];
+ u32 supported_fec_mode;
+ u16 bond_speed;
+ u8 rsvd2[2];
};
#define MAG_CMD_OPCODE_GET 0
@@ -330,8 +334,8 @@ struct mag_cmd_cfg_fec_mode {
u8 port_id;
u8 opcode; /* 0:get fec mode 1:set fec mode */
- u8 fec;
- u8 rsvd0;
+ u8 advertised_fec;
+ u8 supported_fec;
};
/* speed */
@@ -641,7 +645,7 @@ struct mag_cmd_event_port_info {
u32 cable_length; /* 1/3/5m */
u8 cable_temp; /* temp */
u8 max_speed; /* Maximum rate of an optical module */
- u8 sfp_type; /* sfp/qsfp */
+ u8 sfp_type; /* sfp/qsfp/dsfp */
u8 rsvd1;
u32 power[4]; /* Optical Power */
@@ -678,6 +682,10 @@ struct mag_cmd_event_port_info {
u8 rsvd3[360];
};
+struct mag_cmd_rsfec_stats {
+ u32 rx_err_lane_phy;
+};
+
struct mag_cmd_port_stats {
u64 mac_tx_fragment_pkt_num;
u64 mac_tx_undersize_pkt_num;
@@ -913,10 +921,223 @@ struct mag_cmd_sfp_temp_in_info {
};
struct mag_cmd_sfp_temp_out_info {
- struct mgmt_msg_head head; /* 8B */
- s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
- s32 max_temp; /* Chip optical module threshold */
- s32 min_temp; /* Chip optical module threshold */
+ struct mgmt_msg_head head; /* 8B */
+ s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
+ s32 max_temp; /* Chip optical module threshold */
+ s32 min_temp; /* Chip optical module threshold */
+};
+
+#define XSFP_CMIS_PARSE_PAGE_NUM 6
+#define XSFP_CMIS_INFO_MAX_SIZE 1536
+#define QSFP_CMIS_PAGE_SIZE 128
+#define QSFP_CMIS_MAX_CHANNEL_NUM 0x8
+
+/* Lower: Control and Essentials, Upper: Administrative Information */
+#define QSFP_CMIS_PAGE_00H 0x00
+/* Advertising */
+#define QSFP_CMIS_PAGE_01H 0x01
+/* Module and lane Thresholds */
+#define QSFP_CMIS_PAGE_02H 0x02
+/* User EEPROM */
+#define QSFP_CMIS_PAGE_03H 0x03
+/* Laser Capabilities Advertising (Page 04h, Optional) */
+#define QSFP_CMIS_PAGE_04H 0x04
+#define QSFP_CMIS_PAGE_05H 0x05
+/* Lane and Data Path Control */
+#define QSFP_CMIS_PAGE_10H 0x10
+/* Lane Status */
+#define QSFP_CMIS_PAGE_11H 0x11
+#define QSFP_CMIS_PAGE_12H 0x12
+
+#define MGMT_TLV_U8_SIZE 1
+#define MGMT_TLV_U16_SIZE 2
+#define MGMT_TLV_U32_SIZE 4
+
+#define MGMT_TLV_GET_U8(addr) (*((u8 *)(void *)(addr)))
+#define MGMT_TLV_SET_U8(addr, value) \
+ ((*((u8 *)(void *)(addr))) = ((u8)(value)))
+
+#define MGMT_TLV_GET_U16(addr) (*((u16 *)(void *)(addr)))
+#define MGMT_TLV_SET_U16(addr, value) \
+ ((*((u16 *)(void *)(addr))) = ((u16)(value)))
+
+#define MGMT_TLV_GET_U32(addr) (*((u32 *)(void *)(addr)))
+#define MGMT_TLV_SET_U32(addr, value) \
+ ((*((u32 *)(void *)(addr))) = ((u32)(value)))
+
+#define MGMT_TLV_TYPE_END 0xFFFF
+
+enum mag_xsfp_type {
+ MAG_XSFP_TYPE_PAGE = 0x01,
+ MAG_XSFP_TYPE_WIRE_TYPE = 0x02,
+ MAG_XSFP_TYPE_END = MGMT_TLV_TYPE_END
+};
+
+struct qsfp_cmis_lower_page_00_s {
+ u8 resv0[14];
+ u8 temperature_msb;
+ u8 temperature_lsb;
+ u8 volt_supply[2];
+ u8 resv1[67];
+ u8 media_type;
+ u8 electrical_interface_id;
+ u8 media_interface_id;
+ u8 lane_count;
+ u8 resv2[39];
+};
+
+struct qsfp_cmis_upper_page_00_s {
+ u8 identifier;
+ u8 vendor_name[16];
+ u8 vendor_oui[3];
+ u8 vendor_pn[16];
+ u8 vendor_rev[2];
+ u8 vendor_sn[16];
+ u8 date_code[8];
+ u8 clei_code[10];
+ u8 power_character[2];
+ u8 cable_len;
+ u8 connector;
+ u8 copper_cable_attenuation[6];
+ u8 near_end_implementation;
+ u8 far_end_config;
+ u8 media_technology;
+ u8 resv0[43];
+};
+
+struct qsfp_cmis_upper_page_01_s {
+ u8 firmware_rev[2];
+ u8 hardware_rev[2];
+ u8 smf_len_km;
+ u8 om5_len;
+ u8 om4_len;
+ u8 om3_len;
+ u8 om2_len;
+ u8 resv0;
+ u8 wavelength[2];
+ u8 wavelength_tolerance[2];
+ u8 pages_implement;
+ u8 resv1[16];
+ u8 monitor_implement[2];
+ u8 resv2[95];
+};
+
+struct qsfp_cmis_upper_page_02_s {
+ u8 temperature_high_alarm[2];
+ u8 temperature_low_alarm[2];
+ u8 temperature_high_warn[2];
+ u8 temperature_low_warn[2];
+ u8 volt_high_alarm[2];
+ u8 volt_low_alarm[2];
+ u8 volt_high_warn[2];
+ u8 volt_low_warn[2];
+ u8 resv0[32];
+ u8 tx_power_high_alarm[2];
+ u8 tx_power_low_alarm[2];
+ u8 tx_power_high_warn[2];
+ u8 tx_power_low_warn[2];
+ u8 tx_bias_high_alarm[2];
+ u8 tx_bias_low_alarm[2];
+ u8 tx_bias_high_warn[2];
+ u8 tx_bias_low_warn[2];
+ u8 rx_power_high_alarm[2];
+ u8 rx_power_low_alarm[2];
+ u8 rx_power_high_warn[2];
+ u8 rx_power_low_warn[2];
+ u8 resv1[56];
+};
+
+struct qsfp_cmis_upper_page_03_s {
+ u8 resv0[QSFP_CMIS_PAGE_SIZE]; /* Reg 128-255: Upper Memory: Page 03H */
+};
+
+struct qsfp_cmis_upper_page_10_s {
+ u8 resv0[2]; /* Reg 128-129: Upper Memory: Page 10H */
+ u8 tx_disable; /* Reg 130: Tx disable, 0b=enabled, 1b=disabled */
+ u8 resv1[125]; /* Reg 131-255 */
+};
+
+struct qsfp_cmis_upper_page_11_s {
+ u8 resv0[7];
+ u8 tx_fault;
+ u8 tx_los;
+ u8 resv1[10];
+ u8 rx_los;
+ u8 resv2[6];
+ u8 tx_power[16];
+ u8 tx_bias[16];
+ u8 rx_power[16];
+ u8 resv3[54];
+};
+
+struct qsfp_cmis_info_s {
+ struct qsfp_cmis_lower_page_00_s lower_page_00;
+ struct qsfp_cmis_upper_page_00_s upper_page_00;
+ struct qsfp_cmis_upper_page_01_s upper_page_01;
+ struct qsfp_cmis_upper_page_02_s upper_page_02;
+ struct qsfp_cmis_upper_page_10_s upper_page_10;
+ struct qsfp_cmis_upper_page_11_s upper_page_11;
+};
+
+struct qsfp_cmis_comm_power_s {
+ u32 chl_power[QSFP_CMIS_MAX_CHANNEL_NUM];
+};
+
+struct qsfp_cmis_wire_info_s {
+ struct qsfp_cmis_comm_power_s rx_power;
+ u8 rx_los;
+ u8 resv0[3];
+};
+
+struct mgmt_tlv_info {
+ u16 type;
+ u16 length;
+ u8 value[];
+};
+
+struct mag_cmd_set_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 tlv_buf[];
+};
+
+struct mag_cmd_set_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+};
+
+struct mag_cmd_get_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd;
+ u16 rsp_buf_len;
+};
+
+struct mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[];
+};
+
+
+struct parse_tlv_info {
+ u8 tlv_page_info[XSFP_CMIS_INFO_MAX_SIZE + 1];
+ u32 tlv_page_info_len;
+ u32 tlv_page_num[XSFP_CMIS_PARSE_PAGE_NUM];
+ u32 wire_type;
+ u8 id;
+};
+
+struct drv_mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[XSFP_CMIS_INFO_MAX_SIZE];
};
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h b/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
deleted file mode 100644
index 257bf67..0000000
--- a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : mgmt_msg_base.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef MGMT_MSG_BASE_H
-#define MGMT_MSG_BASE_H
-
-#define MGMT_MSG_CMD_OP_SET 1
-#define MGMT_MSG_CMD_OP_GET 0
-
-#define MGMT_MSG_CMD_OP_START 1
-#define MGMT_MSG_CMD_OP_STOP 0
-
-struct mgmt_msg_head {
- u8 status;
- u8 version;
- u8 rsvd0[6];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
deleted file mode 100644
index 9fb4232..0000000
--- a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2001-2021, Huawei Tech. Co., Ltd.
- * File Name : nic_cfg_comm.h
- * Version : Initial Draft
- * Description : nic config common header file
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef NIC_CFG_COMM_H
-#define NIC_CFG_COMM_H
-
-/* rss */
-#define HINIC3_RSS_TYPE_VALID_SHIFT 23
-#define HINIC3_RSS_TYPE_TCP_IPV6_EXT_SHIFT 24
-#define HINIC3_RSS_TYPE_IPV6_EXT_SHIFT 25
-#define HINIC3_RSS_TYPE_TCP_IPV6_SHIFT 26
-#define HINIC3_RSS_TYPE_IPV6_SHIFT 27
-#define HINIC3_RSS_TYPE_TCP_IPV4_SHIFT 28
-#define HINIC3_RSS_TYPE_IPV4_SHIFT 29
-#define HINIC3_RSS_TYPE_UDP_IPV6_SHIFT 30
-#define HINIC3_RSS_TYPE_UDP_IPV4_SHIFT 31
-
-#define HINIC3_RSS_TYPE_SET(val, member) (((u32)(val) & 0x1) << HINIC3_RSS_TYPE_##member##_SHIFT)
-#define HINIC3_RSS_TYPE_GET(val, member) (((u32)(val) >> HINIC3_RSS_TYPE_##member##_SHIFT) & 0x1)
-
-enum nic_rss_hash_type {
- NIC_RSS_HASH_TYPE_XOR = 0,
- NIC_RSS_HASH_TYPE_TOEP,
-
- NIC_RSS_HASH_TYPE_MAX /* MUST BE THE LAST ONE */
-};
-
-#define NIC_RSS_INDIR_SIZE 256
-#define NIC_RSS_KEY_SIZE 40
-
-/* *
- * Definition of the NIC receiving mode
- */
-#define NIC_RX_MODE_UC 0x01
-#define NIC_RX_MODE_MC 0x02
-#define NIC_RX_MODE_BC 0x04
-#define NIC_RX_MODE_MC_ALL 0x08
-#define NIC_RX_MODE_PROMISC 0x10
-
-/* IEEE 802.1Qaz std */
-#define NIC_DCB_COS_MAX 0x8
-#define NIC_DCB_UP_MAX 0x8
-#define NIC_DCB_TC_MAX 0x8
-#define NIC_DCB_PG_MAX 0x8
-#define NIC_DCB_TSA_SP 0x0
-#define NIC_DCB_TSA_CBS 0x1 /* hi1822 do NOT support */
-#define NIC_DCB_TSA_ETS 0x2
-#define NIC_DCB_DSCP_NUM 0x8
-#define NIC_DCB_IP_PRI_MAX 0x40
-
-#define NIC_DCB_PRIO_DWRR 0x0
-#define NIC_DCB_PRIO_STRICT 0x1
-
-#define NIC_DCB_MAX_PFC_NUM 0x4
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
similarity index 77%
rename from drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
rename to drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
index 31e224a..8e0fa89 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
- * File Name : hinic3_comm_cmd.h
+ * File Name : nic_mpu_cmd.h
* Version : Initial Draft
* Created : 2019/4/25
* Last Modified :
@@ -9,8 +9,8 @@
* Function List :
*/
-#ifndef HINIC3_NIC_CMD_H
-#define HINIC3_NIC_CMD_H
+#ifndef NIC_MPU_CMD_H
+#define NIC_MPU_CMD_H
/* Commands between NIC to MPU
*/
@@ -33,8 +33,9 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_CFG_LOCAL_LRO_STATE,
HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
+ HINIC3_NIC_CMD_SET_FUNC_ER_FWD_ID,
- /* MAC & VLAN CFG */
+ /** MAC & VLAN CFG & VXLAN CFG */
HINIC3_NIC_CMD_GET_MAC = 20,
HINIC3_NIC_CMD_SET_MAC,
HINIC3_NIC_CMD_DEL_MAC,
@@ -45,6 +46,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_VLAN_FILTER_EN,
HINIC3_NIC_CMD_SET_RX_VLAN_OFFLOAD,
HINIC3_NIC_CMD_SMAC_CHECK_STATE,
+ HINIC3_NIC_CMD_OUTBAND_SET_FUNC_VLAN,
+
+ HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+ HINIC3_NIC_CMD_RX_RATE_CFG,
+ HINIC3_NIC_CMD_WR_ORDERING_CFG,
/* SR-IOV */
HINIC3_NIC_CMD_CFG_VF_VLAN = 40,
@@ -61,6 +67,7 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC,
/* IP checksum error packets, enable rss quadruple hash */
HINIC3_NIC_CMD_IPCS_ERR_RSS_ENABLE_OP = 66,
+ HINIC3_NIC_CMD_GTP_INNER_PARSE_STATUS,
/* PPA/FDIR */
HINIC3_NIC_CMD_ADD_TC_FLOW = 80,
@@ -76,6 +83,10 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_CFG_PPA_FLUSH,
HINIC3_NIC_CMD_SET_FDIR_STATUS,
HINIC3_NIC_CMD_GET_PPA_COUNTER,
+ HINIC3_NIC_CMD_SET_FUNC_FLOW_BIFUR_ENABLE,
+ HINIC3_NIC_CMD_SET_BOND_MASK,
+ HINIC3_NIC_CMD_GET_BLOCK_TC_FLOWS,
+ HINIC3_NIC_CMD_GET_BOND_MASK,
/* PORT CFG */
HINIC3_NIC_CMD_SET_PORT_ENABLE = 100,
@@ -94,6 +105,8 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_QOS_PORT_CFG,
HINIC3_NIC_CMD_QOS_MAP_CFG,
HINIC3_NIC_CMD_FORCE_PKT_DROP,
+ HINIC3_NIC_CMD_CFG_TX_PROMISC_SKIP = 114,
+ HINIC3_NIC_CMD_SET_PORT_FLOW_BIFUR_ENABLE = 117,
HINIC3_NIC_CMD_TX_PAUSE_EXCP_NOTICE = 118,
HINIC3_NIC_CMD_INQUIRT_PAUSE_CFG = 119,
@@ -116,6 +129,10 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_UCAPTURE_OPT = 160, /* TODO: move to roce */
HINIC3_NIC_CMD_SET_VHD_CFG,
+ /* OUT OF BAND */
+ HINIC3_NIC_CMD_GET_OUTBAND_CFG = 170,
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+
/* TODO: move to HILINK */
HINIC3_NIC_CMD_GET_PORT_STAT = 200,
HINIC3_NIC_CMD_CLEAN_PORT_STAT,
@@ -136,24 +153,22 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_LINK_ERR_EVENT,
HINIC3_NIC_CMD_SET_LED_STATUS,
- HINIC3_NIC_CMD_MAX = 256,
-};
+ /* mig */
+ HINIC3_NIC_CMD_MIG_SET_CEQ_CTRL = 230,
+ HINIC3_NIC_CMD_MIG_CFG_MSIX_INFO,
+ HINIC3_NIC_CMD_MIG_CFG_FUNC_VAT_TBL,
+ HINIC3_NIC_CMD_MIG_GET_VF_INFO,
+ HINIC3_NIC_CMD_MIG_CHK_MBX_EMPTY,
+ HINIC3_NIC_CMD_MIG_SET_VPORT_ENABLE,
+ HINIC3_NIC_CMD_MIG_CFG_SQ_CI,
+ HINIC3_NIC_CMD_MIG_CFG_RSS_TBL,
+ HINIC3_NIC_CMD_MIG_CFG_MAC_TBL,
+ HINIC3_NIC_CMD_MIG_TMP_SET_CMDQ_CTX,
+
+ HINIC3_OSHR_CMD_ACTIVE_FUNCTION = 240,
+ HINIC3_NIC_CMD_GET_RQ_INFO = 241,
-/* NIC CMDQ MODE */
-enum hinic3_ucode_cmd {
- HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
- HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
- HINIC3_UCODE_CMD_ARM_SQ,
- HINIC3_UCODE_CMD_ARM_RQ,
- HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_SET_IQ_ENABLE,
- HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
- HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
- HINIC3_UCODE_CMD_PPA_HASH_TABLE,
- HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_NIC_CMD_MAX = 256,
};
-#endif /* HINIC3_NIC_CMD_H */
+#endif /* NIC_MPU_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
similarity index 84%
rename from drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h
rename to drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
index 522518d..ee6bf20 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
@@ -20,6 +20,10 @@
#define NIC_TCAM_BLOCK_LARGE_NUM 256
#define NIC_TCAM_BLOCK_LARGE_SIZE 16
+#define TRAFFIC_BIFUR_MODEL_TYPE 2
+
+#define NIC_TCAM_FLOW_BIFUR_FLAG (1 << 0)
+
#ifndef BIT
#define BIT(n) (1UL << (n))
#endif
@@ -103,6 +107,7 @@ struct hinic3_port_state {
#define HINIC3_SET_PORT_CAR_PROFILE 0
#define HINIC3_SET_PORT_CAR_STATE 1
+#define HINIC3_GET_PORT_CAR_LIMIT_SPEED 2
struct hinic3_port_car_info {
u32 cir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
@@ -117,7 +122,7 @@ struct hinic3_cmd_set_port_car {
u8 port_id;
u8 opcode; /* 0--set car profile, 1--set car state */
u8 state; /* 0--disable, 1--enable */
- u8 rsvd;
+ u8 level;
struct hinic3_port_car_info car;
};
@@ -350,6 +355,14 @@ struct hinic3_cmd_local_lro_state {
u8 state; /* 0: disable, 1: enable */
};
+struct hinic3_cmd_gtp_inner_parse_status {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 status; /* 0: disable, 1: enable */
+};
+
struct hinic3_cmd_vf_vlan_config {
struct hinic3_mgmt_msg_head msg_head;
@@ -373,7 +386,8 @@ struct hinic3_cmd_tx_rate_cfg {
struct hinic3_mgmt_msg_head msg_head;
u16 func_id;
- u16 rsvd1;
+ u8 rsvd1;
+ u8 direct;
u32 min_rate;
u32 max_rate;
u8 rsvd2[8];
@@ -416,8 +430,22 @@ struct hinic3_cmd_vlan_config {
u16 func_id;
u8 opcode;
- u8 rsvd1;
+ u8 outband_defvid_flag;
u16 vlan_id;
+ u8 blacklist_flag;
+ u8 rsvd2;
+};
+
+#define VLAN_BLACKLIST_ENABLE 1
+#define VLAN_BLACKLIST_DISABLE 0
+
+struct hinic3_cmd_vxlan_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 cfg_mode;
+ u16 vxlan_port;
u16 rsvd2;
};
@@ -561,11 +589,13 @@ struct hinic3_up_ets_cfg { /* delet */
u8 tc_prio[NIC_DCB_TC_MAX];
};
-#define CMD_QOS_ETS_COS_TC BIT(0)
-#define CMD_QOS_ETS_TC_BW BIT(1)
-#define CMD_QOS_ETS_COS_PRIO BIT(2)
-#define CMD_QOS_ETS_COS_BW BIT(3)
-#define CMD_QOS_ETS_TC_PRIO BIT(4)
+#define CMD_QOS_ETS_COS_TC BIT(0)
+#define CMD_QOS_ETS_TC_BW BIT(1)
+#define CMD_QOS_ETS_COS_PRIO BIT(2)
+#define CMD_QOS_ETS_COS_BW BIT(3)
+#define CMD_QOS_ETS_TC_PRIO BIT(4)
+#define CMD_QOS_ETS_TC_RATELIMIT BIT(5)
+
struct hinic3_cmd_ets_cfg {
struct hinic3_mgmt_msg_head head;
@@ -580,6 +610,7 @@ struct hinic3_cmd_ets_cfg {
u8 cos_prio[NIC_DCB_COS_MAX]; /* 0 - DWRR, 1 - STRICT */
u8 cos_bw[NIC_DCB_COS_MAX];
u8 tc_prio[NIC_DCB_TC_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 rate_limit[NIC_DCB_TC_MAX];
};
struct hinic3_cmd_set_dcb_state {
@@ -666,6 +697,8 @@ struct nic_cmd_pause_inquiry_cfg {
u32 type; /* 1: set, 2: get */
+ u32 cos_id;
+
u32 rx_inquiry_pause_drop_pkts_en;
u32 rx_inquiry_pause_period_ms;
u32 rx_inquiry_pause_times;
@@ -678,7 +711,7 @@ struct nic_cmd_pause_inquiry_cfg {
u32 tx_inquiry_pause_times; /* tx pause Default Times Period 5 */
u32 tx_inquiry_pause_frame_thd; /* tx pause Detection Threshold */
u32 tx_inquiry_rx_total_pkts;
- u32 rsvd[4];
+ u32 rsvd[3];
};
/* pfc/pause Storm TX exception reporting */
@@ -903,7 +936,9 @@ struct nic_cmd_fdir_get_block_rules {
};
struct hinic3_tcam_key_ipv4_mem {
- u32 rsvd1 : 4;
+ u32 rsvd1 : 1;
+ u32 bifur_flag : 2;
+ u32 model : 1;
u32 tunnel_type : 4;
u32 ip_proto : 8;
u32 rsvd0 : 16;
@@ -935,14 +970,16 @@ union hinic3_tag_tcam_ext_info {
u32 id : 16; /* id */
u32 type : 4; /* type: 0-func, 1-vmdq, 2-port, 3-rsvd, 4-trunk, 5-dp, 6-mc */
u32 host_id : 3;
- u32 rsv : 8;
+ u32 rss_q_num : 8; /* rss queue num */
u32 ext : 1;
} bs;
u32 value;
};
struct hinic3_tcam_key_ipv6_mem {
- u32 rsvd1 : 4;
+ u32 bifur_flag : 2;
+ u32 vlan_flag : 1;
+ u32 outer_ip_type : 1;
u32 tunnel_type : 4;
u32 ip_proto : 8;
u32 rsvd0 : 16;
@@ -1044,7 +1081,7 @@ struct hinic3_ppa_cfg_ppa_en_cmd {
u16 func_id;
u8 ppa_en;
- u8 rsvd;
+ u8 ppa_miss_drop_en;
};
struct hinic3_func_flow_bifur_en_cmd {
@@ -1058,7 +1095,8 @@ struct hinic3_port_flow_bifur_en_cmd {
struct hinic3_mgmt_msg_head msg_head;
u16 port_id;
u8 flow_bifur_en;
- u8 rsvd[5];
+ u8 flow_bifur_type; /* 0->vf bifur, 2->traffic bifur */
+ u8 rsvd[4];
};
struct hinic3_bond_mask_cmd {
@@ -1070,9 +1108,18 @@ struct hinic3_bond_mask_cmd {
u8 rsvd[3];
};
+struct hinic3_func_er_value_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 vf_id;
+ u16 er_fwd_id;
+};
+
#define HINIC3_TX_SET_PROMISC_SKIP 0
#define HINIC3_TX_GET_PROMISC_SKIP 1
+#define HINIC3_GET_TRAFFIC_BIFUR_STATE 0
+#define HINIC3_SET_TRAFFIC_BIFUR_STATE 1
+
struct hinic3_tx_promisc_cfg {
struct hinic3_mgmt_msg_head msg_head;
u8 port_id;
@@ -1116,53 +1163,88 @@ enum {
NIC_NVM_DATA_VLAN_PRI = BIT(3),
NIC_NVM_DATA_VLAN_ID = BIT(4),
NIC_NVM_DATA_WORK_MODE = BIT(5),
- NIC_NVM_DATA_PF_SPEED_LIMIT = BIT(6),
+ NIC_NVM_DATA_PF_TX_SPEED_LIMIT = BIT(6),
NIC_NVM_DATA_GE_MODE = BIT(7),
NIC_NVM_DATA_AUTO_NEG = BIT(8),
NIC_NVM_DATA_LINK_FEC = BIT(9),
NIC_NVM_DATA_PF_ADAPTIVE_LINK = BIT(10),
NIC_NVM_DATA_SRIOV_CONTROL = BIT(11),
NIC_NVM_DATA_EXTEND_MODE = BIT(12),
+ NIC_NVM_DATA_LEGACY_VLAN = BIT(13),
+ NIC_NVM_DATA_LEGACY_VLAN_PRI = BIT(14),
+ NIC_NVM_DATA_LEGACY_VLAN_ID = BIT(15),
NIC_NVM_DATA_RESET = BIT(31),
};
-#define BIOS_CFG_SIGNATURE 0x1923E518
-#define BIOS_OP_CFG_ALL(op_code_val) ((((op_code_val) >> 1) & (0xFFFFFFFF)) != 0)
-#define BIOS_OP_CFG_WRITE(op_code_val) ((((op_code_val) & NIC_NVM_DATA_SET)) != 0)
-#define BIOS_OP_CFG_PXE_EN(op_code_val) (((op_code_val) & NIC_NVM_DATA_PXE) != 0)
-#define BIOS_OP_CFG_VLAN_EN(op_code_val) (((op_code_val) & NIC_NVM_DATA_VLAN) != 0)
-#define BIOS_OP_CFG_VLAN_PRI(op_code_val) (((op_code_val) & NIC_NVM_DATA_VLAN_PRI) != 0)
-#define BIOS_OP_CFG_VLAN_ID(op_code_val) (((op_code_val) & NIC_NVM_DATA_VLAN_ID) != 0)
-#define BIOS_OP_CFG_WORK_MODE(op_code_val) (((op_code_val) & NIC_NVM_DATA_WORK_MODE) != 0)
-#define BIOS_OP_CFG_PF_BW(op_code_val) (((op_code_val) & NIC_NVM_DATA_PF_SPEED_LIMIT) != 0)
-#define BIOS_OP_CFG_GE_SPEED(op_code_val) (((op_code_val) & NIC_NVM_DATA_GE_MODE) != 0)
-#define BIOS_OP_CFG_AUTO_NEG(op_code_val) (((op_code_val) & NIC_NVM_DATA_AUTO_NEG) != 0)
-#define BIOS_OP_CFG_LINK_FEC(op_code_val) (((op_code_val) & NIC_NVM_DATA_LINK_FEC) != 0)
-#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) (((op_code_val) & NIC_NVM_DATA_PF_ADAPTIVE_LINK) != 0)
-#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val) (((op_code_val) & NIC_NVM_DATA_SRIOV_CONTROL) != 0)
-#define BIOS_OP_CFG_EXTEND_MODE(op_code_val) (((op_code_val) & NIC_NVM_DATA_EXTEND_MODE) != 0)
-#define BIOS_OP_CFG_RST_DEF_SET(op_code_val) (((op_code_val) & (u32)NIC_NVM_DATA_RESET) != 0)
+#define BIOS_CFG_SIGNATURE 0x1923E518
+#define BIOS_OP_CFG_ALL(op_code_val) \
+ ((((op_code_val) >> 1) & (0xFFFFFFFF)) != 0)
+#define BIOS_OP_CFG_WRITE(op_code_val) \
+ ((((op_code_val) & NIC_NVM_DATA_SET)) != 0)
+#define BIOS_OP_CFG_PXE_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PXE) != 0)
+#define BIOS_OP_CFG_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN) != 0)
+#define BIOS_OP_CFG_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_ID) != 0)
+#define BIOS_OP_CFG_WORK_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_WORK_MODE) != 0)
+#define BIOS_OP_CFG_PF_BW(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_TX_SPEED_LIMIT) != 0)
+#define BIOS_OP_CFG_GE_SPEED(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_GE_MODE) != 0)
+#define BIOS_OP_CFG_AUTO_NEG(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_AUTO_NEG) != 0)
+#define BIOS_OP_CFG_LINK_FEC(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LINK_FEC) != 0)
+#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_ADAPTIVE_LINK) != 0)
+#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_SRIOV_CONTROL) != 0)
+#define BIOS_OP_CFG_EXTEND_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_EXTEND_MODE) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_ID) != 0)
+#define BIOS_OP_CFG_RST_DEF_SET(op_code_val) \
+ (((op_code_val) & (u32)NIC_NVM_DATA_RESET) != 0)
+
#define NIC_BIOS_CFG_MAX_PF_BW 100
+
+struct nic_legacy_vlan_cfg {
+ /* Legacy mode PXE VLAN enable: 0 - disable 1 - enable */
+ u8 pxe_vlan_en : 1;
+ /* Legacy mode PXE VLAN priority: 0-7 */
+ u8 pxe_vlan_pri : 3;
+ /* Legacy mode PXE VLAN ID 1-4094 */
+ u16 pxe_vlan_id : 12;
+};
+
/* Note: This structure must be 4-byte aligned. */
struct nic_bios_cfg {
u32 signature;
- u8 pxe_en; /* PXE enable: 0 - disable 1 - enable */
+ u8 pxe_en;
u8 extend_mode;
- u8 rsvd0[2];
- u8 pxe_vlan_en; /* PXE VLAN enable: 0 - disable 1 - enable */
- u8 pxe_vlan_pri; /* PXE VLAN priority: 0-7 */
- u16 pxe_vlan_id; /* PXE VLAN ID 1-4094 */
- u32 service_mode; /* @See CHIPIF_SERVICE_MODE_x */
- u32 pf_bw; /* PF rate, in percentage. The value ranges from 0 to 100. */
- u8 speed; /* enum of port speed */
- u8 auto_neg; /* Auto-Negotiation Switch 0 - Invalid Field 1 - On 2 - Off */
- u8 lanes; /* lane num */
- u8 fec; /* FEC mode, @See enum mag_cmd_port_fec */
- u8 auto_adapt; /* Adaptive Mode Configuration 0 - Invalid Configuration 1 - On 2 - Off */
- u8 func_valid; /* Whether func_id is valid; 0: invalid; other: valid */
- u8 func_id; /* This member is valid only when func_valid is not set to 0. */
- u8 sriov_en; /* SRIOV-EN: 0 - Invalid configuration, 1 - On, 2 - Off */
+ struct nic_legacy_vlan_cfg nlvc;
+ u8 pxe_vlan_en;
+ u8 pxe_vlan_pri;
+ u16 pxe_vlan_id;
+ u32 service_mode;
+ u32 pf_tx_bw;
+ u8 speed;
+ u8 auto_neg;
+ u8 lanes;
+ u8 fec;
+ u8 auto_adapt;
+ u8 func_valid;
+ u8 func_id;
+ u8 sriov_en;
};
struct nic_cmd_bios_cfg {
@@ -1171,6 +1253,14 @@ struct nic_cmd_bios_cfg {
struct nic_bios_cfg bios_cfg;
};
+struct nic_rx_rate_bios_cfg {
+ struct mgmt_msg_head msg_head;
+
+ u32 op_code; /* Operation Code:[0:read 1:write] */
+ u8 rx_rate_limit;
+ u8 func_id;
+};
+
struct nic_cmd_vhd_config {
struct hinic3_mgmt_msg_head head;
@@ -1192,7 +1282,8 @@ struct hinic3_create_bond_info {
u32 active_port_max_num; /* Maximum number of active bond member interfaces */
u32 active_port_min_num; /* Minimum number of active bond member interfaces */
u32 xmit_hash_policy;
- u32 rsvd[2];
+ u32 default_param_flag;
+ u32 rsvd;
};
struct hinic3_cmd_create_bond {
@@ -1287,7 +1378,8 @@ struct hinic3_smac_check_state {
struct hinic3_mgmt_msg_head head;
u8 smac_check_en; /* 1: enable 0: disable */
u8 op_code; /* 1: set 0: get */
- u8 rsvd[2];
+ u8 flash_en; /* 1: enable 0: disable */
+ u8 rsvd;
};
struct hinic3_clear_log_state {
@@ -1295,4 +1387,34 @@ struct hinic3_clear_log_state {
u32 type;
};
+struct hinic3_outband_cfg_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 outband_default_vid;
+ u16 func_id;
+};
+
+struct hinic3_wr_ordering {
+ struct hinic3_mgmt_msg_head head;
+ u8 op_code; /* 1: set 0: get */
+ u8 wr_pkt_so_ro;
+ u8 rd_pkt_so_ro;
+ u8 rsvd;
+};
+
+struct hinic3_function_active_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_rq_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rq_depth;
+ u16 rq_num;
+ u16 pf_num;
+ u16 port_num;
+};
+
#endif /* HINIC_MGMT_INTERFACE_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
new file mode 100644
index 0000000..97eda43
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
+ * File Name : nic_npu_cmd.h
+ * Version : Initial Draft
+ * Created : 2019/4/25
+ * Last Modified :
+ * Description : NIC Commands between Driver and NPU
+ * Function List :
+ */
+
+#ifndef NIC_NPU_CMD_H
+#define NIC_NPU_CMD_H
+
+/* NIC CMDQ MODE */
+enum hinic3_ucode_cmd {
+ HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
+ HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
+ HINIC3_UCODE_CMD_ARM_SQ, /**< Unused */
+ HINIC3_UCODE_CMD_ARM_RQ, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_IQ_ENABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
+ HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
+ HINIC3_UCODE_CMD_PPA_HASH_TABLE,
+ HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_UCODE_MIG_CFG_Q_CTX = 14,
+ HINIC3_UCODE_MIG_CHK_SQ_STOP,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ HINIC3_UCODE_MIG_CFG_BAT_INFO,
+};
+
+#endif /* NIC_NPU_CMD_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
index ee005a8..5f0f790 100644
--- a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
+++ b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
@@ -4,8 +4,8 @@
#ifndef OSSL_KNL_LINUX_H_
#define OSSL_KNL_LINUX_H_
-#include <net/checksum.h>
#include <net/ipv6.h>
+#include <net/devlink.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/device.h>
@@ -19,6 +19,12 @@
#include <linux/list.h>
#include <linux/bitmap.h>
#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/filter.h>
+#include <linux/aer.h>
+#include <linux/socket.h>
#ifndef NETIF_F_SCTP_CSUM
#define NETIF_F_SCTP_CSUM 0
@@ -37,6 +43,17 @@
#define ossl_get_free_pages __get_free_pages
+#ifndef ETHTOOL_LINK_MODE_100000baseKR_Full_BIT
+#define ETHTOOL_LINK_MODE_100000baseKR_Full_BIT 75
+#define ETHTOOL_LINK_MODE_100000baseCR_Full_BIT 78
+#define ETHTOOL_LINK_MODE_100000baseSR_Full_BIT 76
+#endif
+#ifndef ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT
+#define ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT 80
+#define ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT 81
+#define ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT 84
+#endif
+
#ifndef high_16_bits
#define low_16_bits(x) ((x) & 0xFFFF)
#define high_16_bits(x) (((x) & 0xFFFF0000) >> 16)
@@ -54,13 +71,11 @@
#endif
#define HAVE_INET6_IFADDR_LIST
-
#define HAVE_NDO_GET_STATS64
#ifndef HAVE_MQPRIO
#define HAVE_MQPRIO
#endif
-
#ifndef HAVE_SETUP_TC
#define HAVE_SETUP_TC
#endif
@@ -68,25 +83,20 @@
#ifndef HAVE_NDO_SET_FEATURES
#define HAVE_NDO_SET_FEATURES
#endif
-
#define HAVE_IRQ_AFFINITY_NOTIFY
-
#define HAVE_ETHTOOL_SET_PHYS_ID
-
#define HAVE_NETDEV_WANTED_FEAUTES
#ifndef HAVE_PCI_DEV_FLAGS_ASSIGNED
#define HAVE_PCI_DEV_FLAGS_ASSIGNED
#define HAVE_VF_SPOOFCHK_CONFIGURE
#endif
-
#ifndef HAVE_SKB_L4_RXHASH
#define HAVE_SKB_L4_RXHASH
#endif
#define HAVE_ETHTOOL_GRXFHINDIR_SIZE
#define HAVE_INT_NDO_VLAN_RX_ADD_VID
-
#ifdef ETHTOOL_SRXNTUPLE
#undef ETHTOOL_SRXNTUPLE
#endif
@@ -95,9 +105,9 @@
#define _kc_kunmap_atomic(addr) kunmap_atomic(addr)
#include <linux/of_net.h>
-
#define HAVE_FDB_OPS
#define HAVE_ETHTOOL_GET_TS_INFO
+
#define HAVE_NAPI_GRO_FLUSH_OLD
#ifndef HAVE_SRIOV_CONFIGURE
@@ -107,6 +117,7 @@
#define HAVE_ENCAP_TSO_OFFLOAD
#define HAVE_SKB_INNER_NETWORK_HEADER
+
#define HAVE_NDO_SET_VF_LINK_STATE
#define HAVE_SKB_INNER_PROTOCOL
#define HAVE_MPLS_FEATURES
@@ -115,12 +126,12 @@
#define HAVE_NETIF_SET_XPS_QUEUE_CONST_MASK
#define HAVE_VXLAN_CHECKS
-#define HAVE_NDO_SELECT_QUEUE_ACCEL
#define HAVE_NET_GET_RANDOM_ONCE
#define HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS
#define HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK
+
#define HAVE_NDO_SET_VF_MIN_MAX_TX_RATE
#define HAVE_VLAN_FIND_DEV_DEEP_RCU
@@ -128,8 +139,8 @@
#define HAVE_MULTI_VLAN_OFFLOAD_EN
#define HAVE_ETH_GET_HEADLEN_FUNC
-#define HAVE_RXFH_HASHFUNC
+#define HAVE_RXFH_HASHFUNC
#define HAVE_NDO_SET_VF_TRUST
#include <net/devlink.h>
@@ -138,6 +149,7 @@
#define HAVE_NETDEVICE_MIN_MAX_MTU
+
#define HAVE_VOID_NDO_GET_STATS64
#define HAVE_VM_OPS_FAULT_NO_VMA
@@ -146,9 +158,13 @@
#define HAVE_PCI_ERROR_HANDLER_RESET_PREPARE
#define HAVE_PTP_CLOCK_DO_AUX_WORK
+
#define HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV
#define HAVE_XDP_SUPPORT
+#if (KERNEL_VERSION(5, 9, 0) > LINUX_VERSION_CODE)
+#define HAVE_XDP_QUERY_PROG
+#endif
#define HAVE_NDO_BPF_NETDEV_BPF
#define HAVE_TIMER_SETUP
@@ -158,6 +174,7 @@
#define HAVE_NDO_SELECT_QUEUE_SB_DEV
+
#define dev_open(x) dev_open(x, NULL)
#define HAVE_NEW_ETHTOOL_LINK_SETTINGS_ONLY
@@ -180,12 +197,14 @@ static inline void *_hinic3_dma_zalloc_coherent(struct device *dev,
}
#endif
+#if (KERNEL_VERSION(5, 6, 0) <= LINUX_VERSION_CODE)
#ifndef DT_KNL_EMU
struct timeval {
__kernel_old_time_t tv_sec; /* seconds */
__kernel_suseconds_t tv_usec; /* microseconds */
};
#endif
+#endif
#ifndef do_gettimeofday
#define do_gettimeofday(time) _kc_do_gettimeofday(time)
@@ -199,6 +218,8 @@ static inline void _kc_do_gettimeofday(struct timeval *tv)
}
#endif
+
+
#define HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY
#define ETH_GET_HEADLEN_NEED_DEV
#define HAVE_GENL_OPS_FIELD_VALIDATE
@@ -207,32 +228,75 @@ static inline void _kc_do_gettimeofday(struct timeval *tv)
#define FIELD_SIZEOF(t, f) (sizeof(((t *)0)->f))
#endif
+/*****************************************************************************/
+#if (KERNEL_VERSION(5, 5, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.5.0 */
#define HAVE_DEVLINK_FLASH_UPDATE_PARAMS
+#endif /* 5.5.0 */
+/*****************************************************************************/
+#if (KERNEL_VERSION(5, 6, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.6.0 */
#ifndef rtc_time_to_tm
#define rtc_time_to_tm rtc_time64_to_tm
#endif
#define HAVE_NDO_TX_TIMEOUT_TXQ
#define HAVE_PROC_OPS
+#endif /* 5.6.0 */
+/*****************************************************************************/
+#if (KERNEL_VERSION(5, 7, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.7.0 */
#define SUPPORTED_COALESCE_PARAMS
#ifndef pci_cleanup_aer_uncorrect_error_status
#define pci_cleanup_aer_uncorrect_error_status pci_aer_clear_nonfatal_status
#endif
+#endif /* 5.7.0 */
+
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 9, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.9.0 */
#define HAVE_XDP_FRAME_SZ
+#endif /* 5.9.0 */
+
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE)
+#define HAVE_DEVLINK_FW_FILE_NAME_PARAM
+#else /* >= 5.10.0 */
+#endif /* 5.10.0 */
#define HAVE_DEVLINK_FW_FILE_NAME_MEMBER
-#define HAVE_ENCAPSULATION_TSO
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.10.0 */
+#if !defined(HAVE_ETHTOOL_COALESCE_EXTACK) && \
+ !defined(NO_ETHTOOL_COALESCE_EXTACK)
+#define HAVE_ETHTOOL_COALESCE_EXTACK
+#endif
+#endif /* 5.10.0 */
+
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE)
+
+#else /* >= 5.10.0 */
+#if !defined(HAVE_ETHTOOL_RINGPARAM_EXTACK) && \
+ !defined(NO_ETHTOOL_RINGPARAM_EXTACK)
+#define HAVE_ETHTOOL_RINGPARAM_EXTACK
+#endif
+#endif /* 5.10.0 */
+/* ************************************************************************ */
+#define HAVE_NDO_UDP_TUNNEL_ADD
+#define HAVE_ENCAPSULATION_TSO
#define HAVE_ENCAPSULATION_CSUM
#ifndef eth_zero_addr
static inline void hinic3_eth_zero_addr(u8 *addr)
{
- memset(addr, 0x00, ETH_ALEN);
+ (void)memset(addr, 0x00, ETH_ALEN);
}
#define eth_zero_addr(_addr) hinic3_eth_zero_addr(_addr)
@@ -273,13 +337,10 @@ int creat_thread(struct sdk_thread_info *thread_info);
void stop_thread(struct sdk_thread_info *thread_info);
#define destroy_work(work)
-
void utctime_to_localtime(u64 utctime, u64 *localtime);
-
#ifndef HAVE_TIMER_SETUP
void initialize_timer(const void *adapter_hdl, struct timer_list *timer);
#endif
-
void add_to_timer(struct timer_list *timer, u64 period);
void stop_timer(struct timer_list *timer);
void delete_timer(struct timer_list *timer);
@@ -304,3 +365,4 @@ u64 ossl_get_real_time(void);
#define tasklet_state(tasklet) ((tasklet)->state)
#endif
+/* ************************************************************************ */
--
2.45.1.windows.1
2
1

[openeuler:openEuler-1.0-LTS] BUILD REGRESSION 73294fd6312e6e1ec05837ba0b31a889d5c711f1
by kernel test robot 08 May '25
by kernel test robot 08 May '25
08 May '25
tree/branch: https://gitee.com/openeuler/kernel.git openEuler-1.0-LTS
branch HEAD: 73294fd6312e6e1ec05837ba0b31a889d5c711f1 !16139 Bluetooth: Fix use after free in hci_send_acl
Error/Warning (recently discovered and may have been fixed):
https://lore.kernel.org/oe-kbuild-all/202504180904.aJTbSHsO-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504250657.SBZLGq3K-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504250827.FCNrED1Z-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504250942.HWyvS6HD-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504251109.LNg7C0pb-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504251357.XH0GnYXx-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290542.wZ43d7od-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290604.Y62ysEZs-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290804.SFjtS4nf-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290808.iYcj1P8f-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504291102.S4UEqzyV-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504291551.FOwjwu8e-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505070314.0zdCBK7T-lkp@intel.com
block/bio-integrity.c:41:6: warning: no previous prototype for '__bio_integrity_free' [-Wmissing-prototypes]
block/bio-integrity.c:41:6: warning: no previous prototype for function '__bio_integrity_free' [-Wmissing-prototypes]
block/blk-iolatency.c:308:14: warning: variable 'changed' set but not used [-Wunused-but-set-variable]
block/blk-iolatency.c:308:7: warning: variable 'changed' set but not used [-Wunused-but-set-variable]
block/blk-iolatency.c:800:24: warning: variable 'blkiolat' set but not used [-Wunused-but-set-variable]
block/blk-iolatency.c:800:31: warning: variable 'blkiolat' set but not used [-Wunused-but-set-variable]
block/blk-merge.c:696:16: warning: no previous prototype for 'blk_try_req_merge' [-Wmissing-prototypes]
block/blk-mq-sched.c:220:5: warning: no previous prototype for '__blk_mq_sched_dispatch_requests' [-Wmissing-prototypes]
block/blk-mq-sched.c:220:5: warning: no previous prototype for function '__blk_mq_sched_dispatch_requests' [-Wmissing-prototypes]
block/blk-wbt.c:674:6: warning: no previous prototype for 'wbt_issue' [-Wmissing-prototypes]
block/blk-wbt.c:674:6: warning: no previous prototype for function 'wbt_issue' [-Wmissing-prototypes]
block/blk-wbt.c:694:6: warning: no previous prototype for 'wbt_requeue' [-Wmissing-prototypes]
block/blk-wbt.c:694:6: warning: no previous prototype for function 'wbt_requeue' [-Wmissing-prototypes]
block/genhd.c:533: warning: Function parameter or member 'devt' not described in 'blk_invalidate_devt'
block/genhd.c:642:5: warning: no previous prototype for 'disk_scan_partitions' [-Wmissing-prototypes]
block/genhd.c:642:5: warning: no previous prototype for function 'disk_scan_partitions' [-Wmissing-prototypes]
include/linux/device.h:1509:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
include/linux/filter.h:787:10: warning: cast between incompatible function types from 'u64 (*)(u64, u64, u64, u64, u64)' {aka 'long long unsigned int (*)(long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int)'} to 'u64 (*)(u64, u64, u64, u64, u64, const struct bpf_insn *)' {aka 'long long unsigned int (*)(long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int, const struct bpf_insn *)'} [-Wcast-function-type]
include/linux/ktask.h:123:35: warning: cast between incompatible function types from 'int (*)(long unsigned int, long unsigned int, struct cgp_args *)' to 'int (*)(void *, void *, void *)' [-Wcast-function-type]
include/linux/ktask.h:123:35: warning: cast between incompatible function types from 'int (*)(long unsigned int, long unsigned int, struct deferred_args *)' to 'int (*)(void *, void *, void *)' [-Wcast-function-type]
include/linux/ktask.h:123:35: warning: cast between incompatible function types from 'int (*)(long unsigned int, long unsigned int, struct hf_args *)' to 'int (*)(void *, void *, void *)' [-Wcast-function-type]
include/linux/ktask.h:123:35: warning: cast between incompatible function types from 'int (*)(long unsigned int, long unsigned int, struct vfio_pin_args *)' to 'int (*)(void *, void *, void *)' [-Wcast-function-type]
include/linux/ktask.h:163:32: warning: cast between incompatible function types from 'void (*)(long unsigned int, long unsigned int, struct vfio_pin_args *)' to 'void (*)(void *, void *, void *)' [-Wcast-function-type]
include/linux/mempolicy.h:329:13: warning: '__do_mbind' defined but not used [-Wunused-function]
include/linux/skbuff.h:3551:24: warning: this statement may fall through [-Wimplicit-fallthrough=]
include/linux/string.h:249:16: warning: '__builtin_strncpy' accessing 80 bytes at offsets 100 and 36 may overlap up to 0 bytes at offset [9223372036854775807, -9223372036854775808] [-Wrestrict]
include/trace/trace_events.h:26:23: warning: 'str__fs__trace_system_name' defined but not used [-Wunused-const-variable=]
mm/mmu_gather.o: warning: objtool: missing symbol for section .text
Unverified Error/Warning (likely false positive, kindly check if interested):
crypto/jitterentropy.c:204: warning: Function parameter or member 'ec' not described in 'jent_fold_time'
crypto/jitterentropy.c:204: warning: Function parameter or member 'folded' not described in 'jent_fold_time'
crypto/jitterentropy.c:204: warning: Function parameter or member 'loop_cnt' not described in 'jent_fold_time'
crypto/jitterentropy.c:204: warning: Function parameter or member 'time' not described in 'jent_fold_time'
crypto/jitterentropy.c:390: warning: Function parameter or member 'entropy_collector' not described in 'jent_unbiased_bit'
crypto/jitterentropy.c:422: warning: Function parameter or member 'entropy_collector' not described in 'jent_stir_pool'
Error/Warning ids grouped by kconfigs:
recent_errors
|-- arm64-allmodconfig
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-__bio_integrity_free
| |-- block-blk-iolatency.c:warning:variable-blkiolat-set-but-not-used
| |-- block-blk-iolatency.c:warning:variable-changed-set-but-not-used
| |-- block-blk-merge.c:warning:no-previous-prototype-for-blk_try_req_merge
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-__blk_mq_sched_dispatch_requests
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-wbt_issue
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-wbt_requeue
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
| |-- include-asm-generic-bitops-non-atomic.h:warning:array-subscript-long-unsigned-int-is-partly-outside-array-bounds-of-u32-aka-unsigned-int
| |-- include-linux-device.h:warning:this-statement-may-fall-through
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-cgp_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-deferred_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-hf_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-vfio_pin_args-)-to-int-(-)(void-void-void-)
| |-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-void-(-)(long-unsigned-int-long-unsigned-int-struct-vfio_pin_args-)-to-void-(-)(void-void-void-)
| |-- include-linux-skbuff.h:warning:this-statement-may-fall-through
| |-- include-linux-string.h:warning:__builtin_strncpy-accessing-bytes-at-offsets-and-may-overlap-up-to-bytes-at-offset
| |-- include-linux-thread_info.h:warning:b-may-be-used-uninitialized
| `-- include-trace-trace_events.h:warning:str__fs__trace_system_name-defined-but-not-used
|-- arm64-allnoconfig
| `-- include-linux-mempolicy.h:warning:__do_mbind-defined-but-not-used
|-- x86_64-allnoconfig
| |-- mm-mmu_gather.o:warning:objtool:missing-symbol-for-section-.text
| `-- mm-vmscan.c:error:implicit-declaration-of-function-kernel_swap_enabled-Werror-Wimplicit-function-declaration
|-- x86_64-allyesconfig
| |-- block-bio-integrity.c:warning:no-previous-prototype-for-function-__bio_integrity_free
| |-- block-blk-iolatency.c:warning:variable-blkiolat-set-but-not-used
| |-- block-blk-iolatency.c:warning:variable-changed-set-but-not-used
| |-- block-blk-mq-sched.c:warning:no-previous-prototype-for-function-__blk_mq_sched_dispatch_requests
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-function-wbt_issue
| |-- block-blk-wbt.c:warning:no-previous-prototype-for-function-wbt_requeue
| |-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
| |-- block-genhd.c:warning:no-previous-prototype-for-function-disk_scan_partitions
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
| |-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
| `-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
`-- x86_64-defconfig
|-- block-blk-merge.c:warning:no-previous-prototype-for-blk_try_req_merge
|-- block-blk-mq-sched.c:warning:no-previous-prototype-for-__blk_mq_sched_dispatch_requests
|-- block-genhd.c:warning:Function-parameter-or-member-devt-not-described-in-blk_invalidate_devt
|-- block-genhd.c:warning:no-previous-prototype-for-disk_scan_partitions
|-- crypto-jitterentropy.c:warning:Function-parameter-or-member-ec-not-described-in-jent_fold_time
|-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_stir_pool
|-- crypto-jitterentropy.c:warning:Function-parameter-or-member-entropy_collector-not-described-in-jent_unbiased_bit
|-- crypto-jitterentropy.c:warning:Function-parameter-or-member-folded-not-described-in-jent_fold_time
|-- crypto-jitterentropy.c:warning:Function-parameter-or-member-loop_cnt-not-described-in-jent_fold_time
|-- crypto-jitterentropy.c:warning:Function-parameter-or-member-time-not-described-in-jent_fold_time
|-- include-linux-filter.h:warning:cast-between-incompatible-function-types-from-u64-(-)(u64-u64-u64-u64-u64)-aka-long-long-unsigned-int-(-)(long-long-unsigned-int-long-long-unsigned-int-long-long-unsigne
|-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-cgp_args-)-to-int-(-)(void-void-void-)
|-- include-linux-ktask.h:warning:cast-between-incompatible-function-types-from-int-(-)(long-unsigned-int-long-unsigned-int-struct-hf_args-)-to-int-(-)(void-void-void-)
|-- include-linux-skbuff.h:warning:this-statement-may-fall-through
`-- include-trace-trace_events.h:warning:str__fs__trace_system_name-defined-but-not-used
elapsed time: 1686m
configs tested: 5
configs skipped: 50
tested configs:
arm64 allmodconfig gcc-14.2.0
arm64 allnoconfig gcc-14.2.0
x86_64 allnoconfig clang-20
x86_64 allyesconfig clang-20
x86_64 defconfig gcc-11
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

08 May '25
From: z30065765 <zhuyikai1(a)h-partners.com>
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IC5K44?from=project-issue
CVE: NA
--------------------------------
Add optical module type adaptation.
Add ethtool fec function.
Add NIC XDP PASS function.
Add QoS persistence.
Add NIC out-of-band VLAN configuration function.
Fix NIC bifur bugs.
Fix performance test bugs.
Fix NIC RX bugs.
Fix NIC VF bugs.
Fix the bug of exiting when probing NIC.
Fix bond bugs.
Fix the bug of reading NIC status incorrectly.
Fix and add some statistics.
Signed-off-by: z30065765 <zhuyikai1(a)h-partners.com>
---
drivers/net/ethernet/huawei/hinic3/Makefile | 1 +
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c | 136 ++-
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h | 1 +
drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h | 212 ----
drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h | 239 ----
drivers/net/ethernet/huawei/hinic3/comm_defs.h | 105 --
drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h | 103 --
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c | 51 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h | 2 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c | 86 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c | 1 -
drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c | 28 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c | 27 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c | 37 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c | 9 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c | 12 +-
drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h | 185 ---
drivers/net/ethernet/huawei/hinic3/hinic3_common.h | 118 --
drivers/net/ethernet/huawei/hinic3/hinic3_crm.h | 30 +-
drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c | 305 +++--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c | 267 +++--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h | 7 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c | 227 +++-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c | 387 +++---
drivers/net/ethernet/huawei/hinic3/hinic3_filter.c | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_hw.h | 18 +
drivers/net/ethernet/huawei/hinic3/hinic3_irq.c | 11 +-
drivers/net/ethernet/huawei/hinic3/hinic3_lld.h | 205 ----
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c | 836 ++++++++++++-
drivers/net/ethernet/huawei/hinic3/hinic3_main.c | 476 +++++++-
drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h | 1298 ---------------------
drivers/net/ethernet/huawei/hinic3/hinic3_mt.h | 225 +++-
drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c | 372 ++++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic.h | 61 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c | 450 +++++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h | 55 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c | 167 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h | 159 ---
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c | 13 +
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h | 221 ++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c | 119 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c | 18 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c | 18 +-
drivers/net/ethernet/huawei/hinic3/hinic3_profile.h | 146 ---
drivers/net/ethernet/huawei/hinic3/hinic3_rss.c | 142 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c | 41 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rx.c | 357 ++++--
drivers/net/ethernet/huawei/hinic3/hinic3_rx.h | 39 +-
drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h | 6 +-
drivers/net/ethernet/huawei/hinic3/hinic3_tx.c | 141 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_wq.h | 4 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c | 15 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c | 13 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h | 5 -
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c | 206 +++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h | 13 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c | 5 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c | 14 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c | 42 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c | 91 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h | 13 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c | 163 ++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c | 116 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c | 87 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h | 34 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c | 40 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c | 1223 +++++++++++++++++--
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c | 3 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c | 6 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c | 44 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c | 182 +--
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h | 4 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h | 31 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c | 52 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c | 2 +-
drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h | 13 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h | 42 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h | 2 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h | 130 ++-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h | 109 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h | 5 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h | 30 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h | 8 +
drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h | 16 +-
drivers/net/ethernet/huawei/hinic3/include/vram_common.h | 11 +-
drivers/net/ethernet/huawei/hinic3/mag_cmd.h | 922 ---------------
drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h | 1143 ++++++++++++++++++
drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h | 27 -
drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h | 63 -
drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h | 174 +++
drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h | 1420 +++++++++++++++++++++++
drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h | 36 +
drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h | 94 +-
99 files changed, 9448 insertions(+), 5393 deletions(-)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_defs.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_common.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/mag_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
diff --git a/drivers/net/ethernet/huawei/hinic3/Makefile b/drivers/net/ethernet/huawei/hinic3/Makefile
index 11fe010..21d8093 100644
--- a/drivers/net/ethernet/huawei/hinic3/Makefile
+++ b/drivers/net/ethernet/huawei/hinic3/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/drivers/net/ethernet/huawei/hinic3/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/drivers/net/ethernet/huawei/hinic3/hw/
+ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/drivers/net/ethernet/huawei/hinic3/bond/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/drivers/net/ethernet/huawei/hinic3/cqm/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/drivers/net/ethernet/huawei/hinic3/include/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/drivers/net/ethernet/huawei/hinic3/include/cqm/
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
index ba3076c..a252e09 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
@@ -9,14 +9,18 @@
#include <linux/net.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
+#include <linux/version.h>
+#include "ossl_knl.h"
#include "hinic3_lld.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic_dev.h"
#include "hinic3_hw.h"
-#include "mpu_inband_cmd.h"
-#include "hinic3_hwdev.h"
#include "hinic3_bond.h"
+#include "hinic3_hwdev.h"
+
+#include "bond_common_defs.h"
+#include "vram_common.h"
#define PORT_INVALID_ID 0xFF
@@ -214,10 +218,10 @@ static void bond_dev_untrack_port(struct hinic3_bond_dev *bdev, u8 idx)
spin_lock(&bdev->lock);
if (bdev->tracker.ndev[idx]) {
- pr_info("hinic3_bond: untrack port:%u ndev:%s cnt:%d\n", idx,
- bdev->tracker.ndev[idx]->name, bdev->tracker.cnt);
bdev->tracker.ndev[idx] = NULL;
bdev->tracker.cnt--;
+ pr_info("hinic3_bond: untrack port:%u ndev:%s cnt:%d\n", idx,
+ bdev->tracker.ndev[idx]->name, bdev->tracker.cnt);
}
spin_unlock(&bdev->lock);
@@ -268,11 +272,16 @@ static void bond_master_event(struct hinic3_bond_dev *bdev,
queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
}
-static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
+static struct hinic3_bond_dev *bond_get_bdev(struct bonding *bond)
{
struct hinic3_bond_dev *bdev = NULL;
int bid;
+ if (bond == NULL) {
+ pr_err("hinic3_bond: bond is NULL\n");
+ return NULL;
+ }
+
mutex_lock(&g_bond_mutex);
for (bid = BOND_FIRST_ID; bid <= BOND_MAX_ID; bid++) {
bdev = bond_mngr.bond_dev[bid];
@@ -283,38 +292,72 @@ static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
mutex_unlock(&g_bond_mutex);
return bdev;
}
+
+ if (strncmp(bond->dev->name, bdev->name, BOND_NAME_MAX_LEN) == 0) {
+ bdev->bond = bond;
+ return bdev;
+ }
}
mutex_unlock(&g_bond_mutex);
return NULL;
}
-static void bond_handle_rtnl_event(struct net_device *ndev)
+static struct bonding *get_bonding_by_netdev(struct net_device *ndev)
{
- struct hinic3_bond_dev *bdev = NULL;
struct bonding *bond = NULL;
struct slave *slave = NULL;
if (netif_is_bond_master(ndev)) {
bond = netdev_priv(ndev);
- bdev = bond_get_bdev(bond);
} else if (netif_is_bond_slave(ndev)) {
- /*lint -e(160) */
slave = bond_slave_get_rtnl(ndev);
if (slave) {
bond = bond_get_bond_by_slave(slave);
- bdev = bond_get_bdev(bond);
}
}
- if (!bond || !bdev)
+ return bond;
+}
+/*lint -e580 -e546*/
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+
+ if (!ndev) {
+ pr_err("hinic3_bond: netdev is NULL\n");
+ return false;
+ }
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
+ return false;
+
+ return bdev->status == BOND_DEV_STATUS_ACTIVATED;
+}
+EXPORT_SYMBOL(hinic3_is_bond_dev_status_actived);
+/*lint +e580 +e546*/
+
+static void bond_handle_rtnl_event(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+ struct slave *slave = NULL;
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
return;
bond_update_attr(bdev, bond);
- if (slave)
+ if (netif_is_bond_slave(ndev)) {
+ slave = bond_slave_get_rtnl(ndev);
bond_slave_event(bdev, slave);
- else
+ } else {
bond_master_event(bdev, bond);
+ }
}
static void bond_rtnl_data_ready(struct sock *sk)
@@ -478,7 +521,11 @@ static void bond_update_slave_info(struct hinic3_bond_dev *bdev,
continue;
}
+ if (!bdev->tracker.ndev[i])
+ continue;
+
bond_pf_bitmap_set(bdev, i);
+
if (!bdev->tracker.netdev_state[i].tx_enabled)
continue;
@@ -516,6 +563,7 @@ static int bond_upcmd_config(struct hinic3_bond_dev *bdev,
attr->active_slaves,
attr->lacp_collect_slaves);
pr_info("bond_pf_bitmap: 0x%x\n", attr->bond_pf_bitmap);
+ pr_info("bond user_bitmap 0x%x\n", attr->user_bitmap);
err = bond_send_upcmd(bdev, attr, MPU_CMD_BOND_SET_ATTR);
if (!err)
@@ -560,17 +608,36 @@ static void bond_call_service_func(struct hinic3_bond_dev *bdev, struct bond_att
mutex_unlock(&g_bond_service_func_mutex);
}
+static u32 bond_get_user_bitmap(struct hinic3_bond_dev *bdev)
+{
+ u32 user_bitmap = 0;
+ u8 user;
+
+ for (user = HINIC3_BOND_USER_OVS; user < HINIC3_BOND_USER_NUM; user++) {
+ if (bdev->slot_used[user] == 1)
+ BITMAP_SET(user_bitmap, user);
+ }
+ return user_bitmap;
+}
+
static void bond_do_work(struct hinic3_bond_dev *bdev)
{
bool is_bonded = 0;
struct bond_attr attr;
+ int is_in_kexec;
int err = 0;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ pr_info("Skip changing bond status during os replace\n");
+ return;
+ }
+
spin_lock(&bdev->lock);
is_bonded = bdev->tracker.is_bonded;
attr = bdev->new_attr;
spin_unlock(&bdev->lock);
- attr.user_bitmap = 0;
+ attr.user_bitmap = bond_get_user_bitmap(bdev);
/* is_bonded indicates whether bond should be activated. */
if (is_bonded && !bond_dev_is_activated(bdev)) {
@@ -591,17 +658,21 @@ static void bond_do_work(struct hinic3_bond_dev *bdev)
pr_err("hinic3_bond: Do bond failed\n");
}
-#define MIN_BOND_SLAVE_CNT 2
static void bond_try_do_work(struct work_struct *work)
{
struct delayed_work *delayed_work = to_delayed_work(work);
struct hinic3_bond_dev *bdev =
container_of(delayed_work, struct hinic3_bond_dev, bond_work);
+ int status;
- if (g_bond_service_func[HINIC3_BOND_USER_ROCE] && bdev->tracker.cnt < MIN_BOND_SLAVE_CNT)
+ status = mutex_trylock(&g_bond_mutex);
+ if (status == 0) {
+ /* Delay 1 sec and retry */
queue_delayed_work(bdev->wq, &bdev->bond_work, HZ);
- else
+ } else {
bond_do_work(bdev);
+ mutex_unlock(&g_bond_mutex);
+ }
}
static int bond_dev_init(struct hinic3_bond_dev *bdev, const char *name)
@@ -630,6 +701,7 @@ static int bond_dev_release(struct hinic3_bond_dev *bdev)
err = bond_upcmd_deactivate(bdev);
if (err) {
pr_err("hinic3_bond: Failed to deactivate dev\n");
+ mutex_unlock(&g_bond_mutex);
return err;
}
@@ -764,20 +836,28 @@ static struct hinic3_bond_dev *bond_dev_by_name(const char *name)
static void bond_dev_user_attach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user)
{
+ u32 user_bitmap;
+
+ if (user < 0 || user >= HINIC3_BOND_USER_NUM)
+ return;
+
if (bdev->slot_used[user])
return;
bdev->slot_used[user] = 1;
if (!kref_get_unless_zero(&bdev->ref))
kref_init(&bdev->ref);
+ else {
+ user_bitmap = bond_get_user_bitmap(bdev);
+ pr_info("hinic3_bond: user %u attach bond %s, user_bitmap %#x\n",
+ user, bdev->name, user_bitmap);
+ queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
+ }
}
static void bond_dev_user_detach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user, bool *freed)
{
- if (user < 0 || user >= HINIC3_BOND_USER_NUM)
- return;
-
if (bdev->slot_used[user]) {
bdev->slot_used[user] = 0;
if (kref_read(&bdev->ref) == 1)
@@ -790,12 +870,15 @@ static struct bonding *bond_get_knl_bonding(const char *name)
{
struct net_device *ndev_tmp = NULL;
+ rcu_read_lock();
for_each_netdev(&init_net, ndev_tmp) {
if (netif_is_bond_master(ndev_tmp) &&
- !strcmp(ndev_tmp->name, name))
+ !strcmp(ndev_tmp->name, name)) {
+ rcu_read_unlock();
return netdev_priv(ndev_tmp);
+ }
}
-
+ rcu_read_unlock();
return NULL;
}
@@ -852,8 +935,9 @@ int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user)
int err = 0;
bool lock_freed = false;
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
- pr_warn("hinic3_bond: Invalid bond id:%u to delete\n", bond_id);
+ if (!BOND_ID_IS_VALID(bond_id) || user >= HINIC3_BOND_USER_NUM) {
+ pr_warn("hinic3_bond: Invalid bond id or user, bond_id: %u, user: %d\n",
+ bond_id, user);
return -EINVAL;
}
@@ -891,7 +975,7 @@ EXPORT_SYMBOL(hinic3_bond_clean_user);
int hinic3_bond_get_uplink_id(u16 bond_id, u32 *uplink_id)
{
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID || !uplink_id) {
+ if (!BOND_ID_IS_VALID(bond_id) || !uplink_id) {
pr_warn("hinic3_bond: Invalid args, id: %u, uplink: %d\n",
bond_id, !!uplink_id);
return -EINVAL;
@@ -941,7 +1025,7 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
int i;
int len;
- if (!info || bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
+ if (!info || !BOND_ID_IS_VALID(bond_id)) {
pr_warn("hinic3_bond: Invalid args, info: %d,id: %u\n",
!!info, bond_id);
return -EINVAL;
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
index 024de95..5ab36f7 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
@@ -82,6 +82,7 @@ struct hinic3_bond_cmd {
char bond_name[16];
};
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev);
void hinic3_bond_set_user_bitmap(struct bond_attr *attr, enum hinic3_bond_user user);
int hinic3_bond_attach(const char *name, enum hinic3_bond_user user, u16 *bond_id);
int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user);
diff --git a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h b/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
deleted file mode 100644
index 557f326..0000000
--- a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2016-2022. All rights reserved.
- * File name: Cfg_mgt_comm_pub.h
- * Version No.: Draft
- * Generation date: 2016 year 05 month 07 day
- * Latest modification:
- * Function description: Header file for communication between the: Host and FW
- * Function list:
- * Modification history:
- * 1. Date: 2016 May 07
- * Modify content: Create a file.
- */
-#ifndef CFG_MGT_COMM_PUB_H
-#define CFG_MGT_COMM_PUB_H
-
-#include "mgmt_msg_base.h"
-
-enum servic_bit_define {
- SERVICE_BIT_NIC = 0,
- SERVICE_BIT_ROCE = 1,
- SERVICE_BIT_VBS = 2,
- SERVICE_BIT_TOE = 3,
- SERVICE_BIT_IPSEC = 4,
- SERVICE_BIT_FC = 5,
- SERVICE_BIT_VIRTIO = 6,
- SERVICE_BIT_OVS = 7,
- SERVICE_BIT_NVME = 8,
- SERVICE_BIT_ROCEAA = 9,
- SERVICE_BIT_CURRENET = 10,
- SERVICE_BIT_PPA = 11,
- SERVICE_BIT_MIGRATE = 12,
- SERVICE_BIT_MAX
-};
-
-#define CFG_SERVICE_MASK_NIC (0x1 << SERVICE_BIT_NIC)
-#define CFG_SERVICE_MASK_ROCE (0x1 << SERVICE_BIT_ROCE)
-#define CFG_SERVICE_MASK_VBS (0x1 << SERVICE_BIT_VBS)
-#define CFG_SERVICE_MASK_TOE (0x1 << SERVICE_BIT_TOE)
-#define CFG_SERVICE_MASK_IPSEC (0x1 << SERVICE_BIT_IPSEC)
-#define CFG_SERVICE_MASK_FC (0x1 << SERVICE_BIT_FC)
-#define CFG_SERVICE_MASK_VIRTIO (0x1 << SERVICE_BIT_VIRTIO)
-#define CFG_SERVICE_MASK_OVS (0x1 << SERVICE_BIT_OVS)
-#define CFG_SERVICE_MASK_NVME (0x1 << SERVICE_BIT_NVME)
-#define CFG_SERVICE_MASK_ROCEAA (0x1 << SERVICE_BIT_ROCEAA)
-#define CFG_SERVICE_MASK_CURRENET (0x1 << SERVICE_BIT_CURRENET)
-#define CFG_SERVICE_MASK_PPA (0x1 << SERVICE_BIT_PPA)
-#define CFG_SERVICE_MASK_MIGRATE (0x1 << SERVICE_BIT_MIGRATE)
-
-/* Definition of the scenario ID in the cfg_data, which is used for SML memory allocation. */
-enum scenes_id_define {
- SCENES_ID_FPGA_ETH = 0,
- SCENES_ID_FPGA_TIOE = 1, /* Discarded */
- SCENES_ID_STORAGE_ROCEAA_2x100 = 2,
- SCENES_ID_STORAGE_ROCEAA_4x25 = 3,
- SCENES_ID_CLOUD = 4,
- SCENES_ID_FC = 5,
- SCENES_ID_STORAGE_ROCE = 6,
- SCENES_ID_COMPUTE_ROCE = 7,
- SCENES_ID_STORAGE_TOE = 8,
- SCENES_ID_MAX
-};
-
-/* struct cfg_cmd_dev_cap.sf_svc_attr */
-enum {
- SF_SVC_FT_BIT = (1 << 0),
- SF_SVC_RDMA_BIT = (1 << 1),
-};
-
-enum cfg_cmd {
- CFG_CMD_GET_DEV_CAP = 0,
- CFG_CMD_GET_HOST_TIMER = 1,
-};
-
-struct cfg_cmd_host_timer {
- struct mgmt_msg_head head;
-
- u8 host_id;
- u8 rsvd1;
-
- u8 timer_pf_num;
- u8 timer_pf_id_start;
- u16 timer_vf_num;
- u16 timer_vf_id_start;
- u32 rsvd2[8];
-};
-
-struct cfg_cmd_dev_cap {
- struct mgmt_msg_head head;
-
- u16 func_id;
- u16 rsvd1;
-
- /* Public resources */
- u8 host_id;
- u8 ep_id;
- u8 er_id;
- u8 port_id;
-
- u16 host_total_func;
- u8 host_pf_num;
- u8 pf_id_start;
- u16 host_vf_num;
- u16 vf_id_start;
- u8 host_oq_id_mask_val;
- u8 timer_en;
- u8 host_valid_bitmap;
- u8 rsvd_host;
-
- u16 svc_cap_en;
- u16 max_vf;
- u8 flexq_en;
- u8 valid_cos_bitmap;
- /* Reserved for func_valid_cos_bitmap */
- u8 port_cos_valid_bitmap;
- u8 rsvd_func1;
- u32 rsvd_func2;
-
- u8 sf_svc_attr;
- u8 func_sf_en;
- u8 lb_mode;
- u8 smf_pg;
-
- u32 max_conn_num;
- u16 max_stick2cache_num;
- u16 max_bfilter_start_addr;
- u16 bfilter_len;
- u16 hash_bucket_num;
-
- /* shared resource */
- u8 host_sf_en;
- u8 master_host_id;
- u8 srv_multi_host_mode;
- u8 virtio_vq_size;
-
- u32 rsvd_func3[5];
-
- /* l2nic */
- u16 nic_max_sq_id;
- u16 nic_max_rq_id;
- u16 nic_default_num_queues;
- u16 rsvd1_nic;
- u32 rsvd2_nic[2];
-
- /* RoCE */
- u32 roce_max_qp;
- u32 roce_max_cq;
- u32 roce_max_srq;
- u32 roce_max_mpt;
- u32 roce_max_drc_qp;
-
- u32 roce_cmtt_cl_start;
- u32 roce_cmtt_cl_end;
- u32 roce_cmtt_cl_size;
-
- u32 roce_dmtt_cl_start;
- u32 roce_dmtt_cl_end;
- u32 roce_dmtt_cl_size;
-
- u32 roce_wqe_cl_start;
- u32 roce_wqe_cl_end;
- u32 roce_wqe_cl_size;
- u8 roce_srq_container_mode;
- u8 rsvd_roce1[3];
- u32 rsvd_roce2[5];
-
- /* IPsec */
- u32 ipsec_max_sactx;
- u16 ipsec_max_cq;
- u16 rsvd_ipsec1;
- u32 rsvd_ipsec[2];
-
- /* OVS */
- u32 ovs_max_qpc;
- u32 rsvd_ovs1[3];
-
- /* ToE */
- u32 toe_max_pctx;
- u32 toe_max_cq;
- u16 toe_max_srq;
- u16 toe_srq_id_start;
- u16 toe_max_mpt;
- u16 toe_max_cctxt;
- u32 rsvd_toe[2];
-
- /* FC */
- u32 fc_max_pctx;
- u32 fc_max_scq;
- u32 fc_max_srq;
-
- u32 fc_max_cctx;
- u32 fc_cctx_id_start;
-
- u8 fc_vp_id_start;
- u8 fc_vp_id_end;
- u8 rsvd_fc1[2];
- u32 rsvd_fc2[5];
-
- /* VBS */
- u16 vbs_max_volq;
- u16 rsvd0_vbs;
- u32 rsvd1_vbs[3];
-
- u16 fake_vf_start_id;
- u16 fake_vf_num;
- u32 fake_vf_max_pctx;
- u16 fake_vf_bfilter_start_addr;
- u16 fake_vf_bfilter_len;
- u32 rsvd_glb[8];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
deleted file mode 100644
index 6f5f87b..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/******************************************************************************
- * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
- ******************************************************************************
- File Name : comm_cmdq_intf.h
- Version : Initial Draft
- Description : common command queue interface
- Function List :
- History :
- Modification: Created file
-
-******************************************************************************/
-
-#ifndef COMM_CMDQ_INTF_H
-#define COMM_CMDQ_INTF_H
-
-/* Cmdq ack type */
-enum hinic3_ack_type {
- HINIC3_ACK_TYPE_CMDQ,
- HINIC3_ACK_TYPE_SHARE_CQN,
- HINIC3_ACK_TYPE_APP_CQN,
-
- HINIC3_MOD_ACK_MAX = 15,
-};
-
-/* Defines the queue type of the set arm bit. */
-enum {
- SET_ARM_BIT_FOR_CMDQ = 0,
- SET_ARM_BIT_FOR_L2NIC_SQ,
- SET_ARM_BIT_FOR_L2NIC_RQ,
- SET_ARM_BIT_TYPE_NUM
-};
-
-/* Defines the type. Each function supports a maximum of eight CMDQ types. */
-enum {
- CMDQ_0 = 0,
- CMDQ_1 = 1, /* dedicated and non-blocking queues */
- CMDQ_NUM
-};
-
-/* *******************cmd common command data structure ************************ */
-// Func->ucode, which is used to set arm bit data,
-// The microcode needs to perform big-endian conversion.
-struct comm_info_ucode_set_arm_bit {
- u32 q_type;
- u32 q_id;
-};
-
-/* *******************WQE data structure ************************ */
-union cmdq_wqe_cs_dw0 {
- struct {
- u32 err_status : 29;
- u32 error_code : 2;
- u32 rsvd : 1;
- } bs;
- u32 val;
-};
-
-union cmdq_wqe_cs_dw1 {
- // This structure is used when the driver writes the wqe.
- struct {
- u32 token : 16; // [15:0]
- u32 cmd : 8; // [23:16]
- u32 mod : 5; // [28:24]
- u32 ack_type : 2; // [30:29]
- u32 obit : 1; // [31]
- } drv_wr;
-
- /* The uCode writes back the structure of the CS_DW1.
- * The driver reads and uses the structure. */
- struct {
- u32 mod : 5; // [4:0]
- u32 ack_type : 3; // [7:5]
- u32 cmd : 8; // [15:8]
- u32 arm : 1; // [16]
- u32 rsvd : 14; // [30:17]
- u32 obit : 1; // [31]
- } wb;
- u32 val;
-};
-
-/* CmdQ BD information or write back buffer information */
-struct cmdq_sge {
- u32 pa_h; // Upper 32 bits of the physical address
- u32 pa_l; // Upper 32 bits of the physical address
- u32 len; // Invalid bit[31].
- u32 resv;
-};
-
-/* Ctrls section definition of WQE */
-struct cmdq_wqe_ctrls {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
-};
-
-/* Complete section definition of WQE */
-struct cmdq_wqe_cs {
- union cmdq_wqe_cs_dw0 dw0;
- union cmdq_wqe_cs_dw1 dw1;
- union {
- struct cmdq_sge sge;
- u32 dw2_5[4];
- } ack;
-};
-
-/* Inline header in WQE inline, describing the length of inline data */
-union cmdq_wqe_inline_header {
- struct {
- u32 buf_len : 11; // [10:0] inline data len
- u32 rsv : 21; // [31:11]
- } bs;
- u32 val;
-};
-
-/* Definition of buffer descriptor section in WQE */
-union cmdq_wqe_bds {
- struct {
- struct cmdq_sge bds_sge;
- u32 rsvd[4]; /* Zwy is used to transfer the virtual address of the buffer. */
- } lcmd; /* Long command, non-inline, and SGE describe the buffer information. */
-};
-
-/* Definition of CMDQ WQE */
-/* (long cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(16B) |
- * | |
- * +----------------------------------------+
- * | driver section(16B) |
- * +----------------------------------------+
- *
- *
- * (middle cmd, 128B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(88B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- *
- *
- * (short cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(24B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- */
-struct cmdq_wqe {
- struct cmdq_wqe_ctrls ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds bds;
-};
-
-/* Definition of ctrls section in inline WQE */
-struct cmdq_wqe_ctrls_inline {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
- u64 db;
-};
-
-/* Buffer descriptor section definition of WQE */
-union cmdq_wqe_bds_inline {
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[80];
- } mcmd; /* Middle command, inline mode */
-
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[16];
- } scmd; /* Short command, inline mode */
-};
-
-struct cmdq_wqe_inline {
- struct cmdq_wqe_ctrls_inline ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds_inline bds;
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_defs.h b/drivers/net/ethernet/huawei/hinic3/comm_defs.h
deleted file mode 100644
index 91d298d..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_defs.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_defs.h
- * Version : Initial Draft
- * Description : common definitions
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef COMM_DEFS_H
-#define COMM_DEFS_H
-
-/* CMDQ MODULE_TYPE */
-enum hinic3_mod_type {
- HINIC3_MOD_COMM = 0, /* HW communication module */
- HINIC3_MOD_L2NIC = 1, /* L2NIC module */
- HINIC3_MOD_ROCE = 2,
- HINIC3_MOD_PLOG = 3,
- HINIC3_MOD_TOE = 4,
- HINIC3_MOD_FLR = 5,
- HINIC3_MOD_RSVD1 = 6,
- HINIC3_MOD_CFGM = 7, /* Configuration module */
- HINIC3_MOD_CQM = 8,
- HINIC3_MOD_RSVD2 = 9,
- COMM_MOD_FC = 10,
- HINIC3_MOD_OVS = 11,
- HINIC3_MOD_DSW = 12,
- HINIC3_MOD_MIGRATE = 13,
- HINIC3_MOD_HILINK = 14,
- HINIC3_MOD_CRYPT = 15, /* secure crypto module */
- HINIC3_MOD_VIO = 16,
- HINIC3_MOD_IMU = 17,
- HINIC3_MOD_DFT = 18, /* DFT */
- HINIC3_MOD_HW_MAX = 19, /* hardware max module id */
- /* Software module id, for PF/VF and multi-host */
- HINIC3_MOD_SW_FUNC = 20,
- HINIC3_MOD_MAX,
-};
-
-/* func reset的flag ,用于指示清理哪种资源 */
-enum func_reset_flag {
- RES_TYPE_FLUSH_BIT = 0,
- RES_TYPE_MQM,
- RES_TYPE_SMF,
- RES_TYPE_PF_BW_CFG,
-
- RES_TYPE_COMM = 10,
- RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_NIC,
- RES_TYPE_OVS,
- RES_TYPE_VBS,
- RES_TYPE_ROCE,
- RES_TYPE_FC,
- RES_TYPE_TOE,
- RES_TYPE_IPSEC,
- RES_TYPE_MAX,
-};
-
-#define HINIC3_COMM_RES \
- ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
- (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
- (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
-
-#define HINIC3_NIC_RES (1 << RES_TYPE_NIC)
-#define HINIC3_OVS_RES (1 << RES_TYPE_OVS)
-#define HINIC3_VBS_RES (1 << RES_TYPE_VBS)
-#define HINIC3_ROCE_RES (1 << RES_TYPE_ROCE)
-#define HINIC3_FC_RES (1 << RES_TYPE_FC)
-#define HINIC3_TOE_RES (1 << RES_TYPE_TOE)
-#define HINIC3_IPSEC_RES (1 << RES_TYPE_IPSEC)
-
-/* MODE OVS、NIC、UNKNOWN */
-#define HINIC3_WORK_MODE_OVS 0
-#define HINIC3_WORK_MODE_UNKNOWN 1
-#define HINIC3_WORK_MODE_NIC 2
-
-#define DEVICE_TYPE_L2NIC 0
-#define DEVICE_TYPE_NVME 1
-#define DEVICE_TYPE_VIRTIO_NET 2
-#define DEVICE_TYPE_VIRTIO_BLK 3
-#define DEVICE_TYPE_VIRTIO_VSOCK 4
-#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
-#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
-#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
-#define DEVICE_TYPE_VIRTIO_HPC 8
-
-#define IS_STORAGE_DEVICE_TYPE(dev_type) \
- ((dev_type) == DEVICE_TYPE_VIRTIO_BLK || \
- (dev_type) == DEVICE_TYPE_VIRTIO_BLK_TRANSITION || \
- (dev_type) == DEVICE_TYPE_VIRTIO_SCSI_TRANSITION)
-
-/* Common header control information of the COMM message
- * interaction command word between the driver and PF
- */
-struct comm_info_head {
- u8 status;
- u8 version;
- u8 rep_aeq_num;
- u8 rsvd[5];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
deleted file mode 100644
index ae998cf..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_msg_intf.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef COMM_MSG_INTF_H
-#define COMM_MSG_INTF_H
-
-#include "comm_defs.h"
-#include "mgmt_msg_base.h"
-#include "mpu_cmd_base_defs.h"
-#include "mpu_inband_cmd_defs.h"
-
-struct spu_cmd_freq_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: check */
- u8 rsvd[3];
- u32 freq;
-};
-
-struct spu_cmd_power_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: init */
- u8 slave_addr;
- u8 cmd_id;
- u8 size;
- u32 value;
-};
-
-struct spu_cmd_tsensor_operation {
- struct comm_info_head head;
-
- u8 op_code;
- u8 rsvd[3];
- s16 fabric_tsensor_temp_avg;
- s16 fabric_tsensor_temp;
- s16 sys_tsensor_temp_avg;
- s16 sys_tsensor_temp;
-};
-
-enum cfg_msix_operation {
- CFG_MSIX_OPERATION_FREE = 0,
- CFG_MSIX_OPERATION_ALLOC = 1,
-};
-
-struct comm_cmd_ffm_info {
- struct mgmt_msg_head head;
-
- u8 node_id;
- /* error level of the interrupt source */
- u8 err_level;
- /* Classification by interrupt source properties */
- u16 err_type;
- u32 err_csr_addr;
- u32 err_csr_value;
- u32 rsvd1;
-};
-
-struct hinic3_cmd_update_firmware {
- struct mgmt_msg_head msg_head;
-
- struct {
- u32 sl : 1;
- u32 sf : 1;
- u32 flag : 1;
- u32 bit_signed : 1;
- u32 reserved : 12;
- u32 fragment_len : 16;
- } ctl_info;
-
- struct {
- u32 section_crc;
- u32 section_type;
- } section_info;
-
- u32 total_len;
- u32 section_len;
- u32 section_version;
- u32 section_offset;
- u32 data[384];
-};
-
-struct hinic3_cmd_activate_firmware {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-struct hinic3_cmd_switch_config {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
index 76e128e..1562c59 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
@@ -28,6 +28,8 @@
#include "cqm_npu_cmd.h"
#include "cqm_npu_cmd_defs.h"
+#include "vram_common.h"
+
static void cqm_bat_fill_cla_common_gpa(struct tag_cqm_handle *cqm_handle,
struct tag_cqm_cla_table *cla_table,
struct tag_cqm_bat_entry_standerd *bat_entry_standerd)
@@ -367,6 +369,14 @@ static s32 cqm_bat_update_cmd(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
struct tag_cqm_cmdq_bat_update *bat_update_cmd = NULL;
s32 ret = CQM_FAIL;
+ int is_in_kexec;
+
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip updating the cqm_bat to chip during kexec!\n");
+ return CQM_SUCCESS;
+ }
+
bat_update_cmd = (struct tag_cqm_cmdq_bat_update *)(buf_in->buf);
bat_update_cmd->offset = 0;
@@ -644,6 +654,7 @@ void cqm_bat_uninit(struct tag_cqm_handle *cqm_handle)
static s32 cqm_cla_fill_buf(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *cla_base_buf,
struct tag_cqm_buf *cla_sub_buf, u8 gpa_check_enable)
{
+ struct hinic3_hwdev *handle = cqm_handle->ex_handle;
struct hinic3_func_attr *func_attr = NULL;
dma_addr_t *base = NULL;
u64 fake_en = 0;
@@ -655,13 +666,17 @@ static s32 cqm_cla_fill_buf(struct tag_cqm_handle *cqm_handle, struct tag_cqm_bu
/* Apply for space for base_buf */
if (!cla_base_buf->buf_list) {
- if (cqm_buf_alloc(cqm_handle, cla_base_buf, false) == CQM_FAIL)
+ if (cqm_buf_alloc(cqm_handle, cla_base_buf, false) ==
+ CQM_FAIL) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(cla_base_buf));
return CQM_FAIL;
+ }
}
/* Apply for space for sub_buf */
if (!cla_sub_buf->buf_list) {
if (cqm_buf_alloc(cqm_handle, cla_sub_buf, false) == CQM_FAIL) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(cla_sub_buf));
cqm_buf_free(cla_base_buf, cqm_handle);
return CQM_FAIL;
}
@@ -768,8 +783,10 @@ static s32 cqm_cla_xyz_lvl1(struct tag_cqm_handle *cqm_handle,
/* Applying for CLA_Z_BUF Space */
cla_z_buf = &cla_table->cla_z_buf;
cla_z_buf->buf_size = trunk_size;
- cla_z_buf->buf_number = (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
- cla_z_buf->page_number = cla_z_buf->buf_number << cla_table->trunk_order;
+ cla_z_buf->buf_number =
+ (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
+ cla_z_buf->page_number = cla_z_buf->buf_number <<
+ cla_table->trunk_order;
/* All buffer space must be statically allocated. */
if (cla_table->alloc_static) {
@@ -785,6 +802,7 @@ static s32 cqm_cla_xyz_lvl1(struct tag_cqm_handle *cqm_handle,
cla_z_buf->buf_list = vmalloc(cla_z_buf->buf_number *
sizeof(struct tag_cqm_buf_list));
if (!cla_z_buf->buf_list) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_1_z_buf));
cqm_buf_free(cla_y_buf, cqm_handle);
return CQM_FAIL;
}
@@ -840,6 +858,7 @@ static s32 cqm_cla_xyz_lvl2_xyz_apply(struct tag_cqm_handle *cqm_handle,
cla_x_buf->buf_size = trunk_size;
cla_x_buf->buf_number = 1;
cla_x_buf->page_number = cla_x_buf->buf_number << cla_table->trunk_order;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
ret = cqm_buf_alloc(cqm_handle, cla_x_buf, false);
if (ret != CQM_SUCCESS)
return CQM_FAIL;
@@ -869,14 +888,20 @@ static s32 cqm_cla_xyz_vram_name_init(struct tag_cqm_cla_table *cla_table,
cla_x_buf = &cla_table->cla_x_buf;
cla_z_buf = &cla_table->cla_z_buf;
cla_y_buf = &cla_table->cla_y_buf;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_x_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_X);
+ VRAM_NAME_APPLY_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_X);
+ cla_y_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_y_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Y);
+ VRAM_NAME_APPLY_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Y);
+ cla_z_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_z_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Z);
+ VRAM_NAME_APPLY_LEN, "%s%s",
+ cla_table->name, VRAM_CQM_CLA_COORD_Z);
return CQM_SUCCESS;
}
@@ -925,6 +950,7 @@ static s32 cqm_cla_xyz_lvl2(struct tag_cqm_handle *cqm_handle,
cla_z_buf->buf_list = vmalloc(cla_z_buf->buf_number *
sizeof(struct tag_cqm_buf_list));
if (!cla_z_buf->buf_list) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_2_z_buf));
cqm_buf_free(cla_x_buf, cqm_handle);
return CQM_FAIL;
}
@@ -934,6 +960,7 @@ static s32 cqm_cla_xyz_lvl2(struct tag_cqm_handle *cqm_handle,
cla_y_buf->buf_list = vmalloc(cla_y_buf->buf_number *
sizeof(struct tag_cqm_buf_list));
if (!cla_y_buf->buf_list) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_2_y_buf));
cqm_buf_free(cla_z_buf, cqm_handle);
cqm_buf_free(cla_x_buf, cqm_handle);
return CQM_FAIL;
@@ -1188,7 +1215,7 @@ static void cqm_cla_init_entry_extern(struct tag_cqm_handle *cqm_handle,
* exceed 128 x 4 KB. Otherwise, clearing the timer buffer of
* the function is complex.
*/
- cla_table->trunk_order = CQM_4K_PAGE_ORDER;
+ cla_table->trunk_order = CQM_8K_PAGE_ORDER;
cla_table->max_buffer_size = capability->timer_number *
capability->timer_basic_size;
cla_table->obj_size = capability->timer_basic_size;
@@ -1237,7 +1264,7 @@ static s32 cqm_cla_init_entry_condition(struct tag_cqm_handle *cqm_handle, u32 e
memcpy(cla_table_timer, cla_table, sizeof(struct tag_cqm_cla_table));
snprintf(cla_table_timer->name,
- VRAM_NAME_MAX_LEN - 1, "%s%s%01u", cla_table->name,
+ VRAM_NAME_APPLY_LEN, "%s%s%01u", cla_table->name,
VRAM_CQM_CLA_SMF_BASE, i);
if (cqm_cla_xyz(cqm_handle, cla_table_timer) ==
@@ -1268,7 +1295,7 @@ static s32 cqm_cla_init_entry(struct tag_cqm_handle *cqm_handle,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
cla_table->type = bat_table->bat_entry_type[i];
- snprintf(cla_table->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(cla_table->name, VRAM_NAME_APPLY_LEN,
"%s%s%s%02u", cqm_handle->name, VRAM_CQM_CLA_BASE,
VRAM_CQM_CLA_TYPE_BASE, cla_table->type);
@@ -1485,11 +1512,11 @@ static s32 cqm_cla_update(struct tag_cqm_handle *cqm_handle,
spu_en = 0;
pa = ((buf_node_parent->pa + (child_index * sizeof(dma_addr_t))) |
- (u32)spu_en);
+ spu_en);
cmd.gpa_h = CQM_ADDR_HI(pa);
cmd.gpa_l = CQM_ADDR_LW(pa);
- pa = (buf_node_child->pa | (u32)spu_en);
+ pa = (buf_node_child->pa | spu_en);
cmd.value_h = CQM_ADDR_HI(pa);
cmd.value_l = CQM_ADDR_LW(pa);
@@ -1980,7 +2007,7 @@ struct tag_cqm_cla_table *cqm_cla_table_get(struct tag_cqm_bat_table *bat_table,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
- if (cla_table && entry_type == cla_table->type)
+ if ((cla_table != NULL) && (entry_type == cla_table->type))
return cla_table;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
index dd0766e..a51c1dc 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
@@ -9,6 +9,7 @@
#include "cqm_bitmap_table.h"
#include "cqm_object.h"
+#include "vram_common.h"
/* When the connection check is enabled, the maximum number of connections
* supported by the chip is 1M - 63, which cannot reach 1M
@@ -19,6 +20,7 @@
#define CLA_TABLE_PAGE_ORDER 0
#define CQM_4K_PAGE_ORDER 0
#define CQM_4K_PAGE_SIZE 4096
+#define CQM_8K_PAGE_ORDER 1
#define CQM_BAT_ENTRY_MAX 16
#define CQM_BAT_ENTRY_SIZE 16
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
index f4844d5..86b268c 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
@@ -254,8 +254,10 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
}
pages = vmalloc(sizeof(struct page *) * buf->page_number);
- if (!pages)
+ if (!pages) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(pages));
return CQM_FAIL;
+ }
for (i = 0; i < buf->buf_number; i++) {
for (j = 0; j < ((u32)1 << order); j++)
@@ -273,6 +275,11 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
return CQM_SUCCESS;
}
+static bool check_use_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ return buf->buf_info.use_vram ? true : false;
+}
+
static bool check_use_non_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
{
return buf->buf_info.use_vram ? false : true;
@@ -294,11 +301,48 @@ static bool check_for_nouse_node_alloc(struct hinic3_hwdev *handle, struct tag_c
return false;
}
+static s32 cqm_buf_vram_kalloc(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ void *vaddr = NULL;
+ int i;
+
+ vaddr = hi_vram_kalloc(buf->buf_info.buf_vram_name, (u64)buf->buf_size * buf->buf_number);
+ if (!vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
+ return CQM_FAIL;
+ }
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = (void *)((char *)vaddr + i * (u64)buf->buf_size);
+
+ return CQM_SUCCESS;
+}
+
+static void cqm_buf_vram_free(struct tag_cqm_buf *buf)
+{
+ s32 i;
+
+ if (buf->buf_list == NULL) {
+ return;
+ }
+
+ if (buf->buf_list[0].va)
+ hi_vram_kfree(buf->buf_list[0].va, buf->buf_info.buf_vram_name,
+ (u64)buf->buf_size * buf->buf_number);
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = NULL;
+}
+
static void cqm_buf_free_page_common(struct tag_cqm_buf *buf)
{
u32 order;
s32 i;
+ if (buf->buf_list == NULL) {
+ return;
+ }
+
order = (u32)get_order(buf->buf_size);
for (i = 0; i < (s32)buf->buf_number; i++) {
@@ -320,8 +364,10 @@ static s32 cqm_buf_use_node_alloc_page(struct hinic3_hwdev *handle, struct tag_c
node = dev_to_node(handle->dev_hdl);
for (i = 0; i < (s32)buf->buf_number; i++) {
newpage = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, order);
- if (!newpage)
+ if (!newpage) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
va = (void *)page_address(newpage);
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
@@ -349,8 +395,10 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
for (i = 0; i < (s32)buf->buf_number; i++) {
va = (void *)ossl_get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
- if (!va)
+ if (!va) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
* value must be 0.
@@ -367,21 +415,21 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
return CQM_SUCCESS;
}
-#define MALLOC_FUNCS_COUNT 2
-#define FREE_FUNCS_COUNT 1
-static const struct malloc_memory g_malloc_funcs[MALLOC_FUNCS_COUNT] = {
+static const struct malloc_memory g_malloc_funcs[] = {
+ {check_use_vram, cqm_buf_vram_kalloc},
{check_for_use_node_alloc, cqm_buf_use_node_alloc_page},
{check_for_nouse_node_alloc, cqm_buf_unused_node_alloc_page}
};
-static const struct free_memory g_free_funcs[FREE_FUNCS_COUNT] = {
+static const struct free_memory g_free_funcs[] = {
+ {check_use_vram, cqm_buf_vram_free},
{check_use_non_vram, cqm_buf_free_page_common}
};
static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *buf)
{
struct hinic3_hwdev *handle = cqm_handle->ex_handle;
- u32 malloc_funcs_num = MALLOC_FUNCS_COUNT;
+ u32 malloc_funcs_num = ARRAY_SIZE(g_malloc_funcs);
u32 i;
for (i = 0; i < malloc_funcs_num; i++) {
@@ -398,7 +446,7 @@ static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
static void cqm_buf_free_page(struct tag_cqm_buf *buf)
{
- u32 free_funcs_num = FREE_FUNCS_COUNT;
+ u32 free_funcs_num = ARRAY_SIZE(g_free_funcs);
u32 i;
for (i = 0; i < free_funcs_num; i++) {
@@ -447,8 +495,11 @@ static s32 cqm_buf_get_secure_mem_pages(struct tag_cqm_handle *cqm_handle, struc
cqm_get_secure_mem_pages(handle,
(u32)get_order(buf->buf_size),
&buf->buf_list[i].pa);
- if (!buf->buf_list[i].va)
+ if (!buf->buf_list[i].va) {
+ cqm_err(handle->dev_hdl,
+ CQM_ALLOC_FAIL(cqm_get_secure_mem_pages));
break;
+ }
}
if (i != buf->buf_number) {
@@ -780,7 +831,10 @@ static s32 cqm_single_bitmap_init(struct tag_cqm_bitmap *bitmap)
*/
bit_number = (ALIGN(bitmap->max_num, CQM_NUM_BIT_BYTE) >>
CQM_BYTE_BIT_SHIFT);
- bitmap->table = vmalloc(bit_number);
+ if (bitmap->bitmap_info.use_vram != 0)
+ bitmap->table = hi_vram_kalloc(bitmap->bitmap_info.buf_vram_name, bit_number);
+ else
+ bitmap->table = vmalloc(bit_number);
if (!bitmap->table)
return CQM_FAIL;
memset(bitmap->table, 0, bit_number);
@@ -859,7 +913,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
}
bitmap = &cla_table->bitmap;
- snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_APPLY_LEN,
"%s%s%02d", cla_table->name,
VRAM_CQM_BITMAP_BASE, cla_table->type);
@@ -869,6 +923,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
bitmap->reserved_top = capability->qpc_reserved;
bitmap->reserved_back = capability->qpc_reserved_back;
bitmap->last = capability->qpc_reserved;
+ bitmap->bitmap_info.use_vram = get_use_vram_flag();
cqm_info(handle->dev_hdl,
"Bitmap init: cla_table_type=%u, max_num=0x%x\n",
cla_table->type, bitmap->max_num);
@@ -948,7 +1003,12 @@ void cqm_bitmap_uninit(struct tag_cqm_handle *cqm_handle)
if (cla_table->type != CQM_BAT_ENTRY_T_INVALID &&
bitmap->table) {
spin_lock_deinit(&bitmap->lock);
- vfree(bitmap->table);
+ if (bitmap->bitmap_info.use_vram != 0)
+ hi_vram_kfree(bitmap->table, bitmap->bitmap_info.buf_vram_name,
+ ALIGN(bitmap->max_num, CQM_NUM_BIT_BYTE) >>
+ CQM_BYTE_BIT_SHIFT);
+ else
+ vfree(bitmap->table);
bitmap->table = NULL;
}
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
index 7febf76..06b8661 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
@@ -9,6 +9,7 @@
#include <linux/spinlock.h>
#include "cqm_object.h"
+#include "vram_common.h"
struct tag_cqm_bitmap {
ulong *table;
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c
index cf7df37..3d38edc 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c
@@ -15,7 +15,6 @@
#include "cqm_bitmap_table.h"
#include "cqm_bat_cla.h"
#include "cqm_main.h"
-#include "cqm_cmd.h"
/**
* cqm_cmd_alloc - Apply for a cmd buffer. The buffer size is fixed to 2 KB,
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
index 9a13ae0..db65c8b 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
@@ -196,6 +196,12 @@ void *cqm_get_db_addr(void *ex_handle, u32 service_type)
pr_err("[CQM]%s: ex_handle is null\n", __func__);
return NULL;
}
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return NULL;
+ }
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -218,6 +224,17 @@ s32 cqm_ring_hardware_db(void *ex_handle, u32 service_type, u8 db_count, u64 db)
struct tag_cqm_service *service = NULL;
struct hinic3_hwdev *handle = NULL;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -278,6 +295,17 @@ s32 cqm_ring_direct_wqe_db(void *ex_handle, u32 service_type, u8 db_count,
u64 *tmp = (u64 *)direct_wqe;
int i;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
index 19a8b56..0e8a579 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
@@ -23,6 +23,8 @@
#include "cqm_memsec.h"
#include "cqm_main.h"
+#include "vram_common.h"
+
static unsigned char roce_qpc_rsv_mode = CQM_QPC_ROCE_NORMAL;
module_param(roce_qpc_rsv_mode, byte, 0644);
MODULE_PARM_DESC(roce_qpc_rsv_mode,
@@ -98,10 +100,17 @@ static s32 cqm_set_timer_enable(void *ex_handle)
{
struct hinic3_hwdev *handle = (struct hinic3_hwdev *)ex_handle;
struct tag_cqm_handle *cqm_handle = NULL;
+ int is_in_kexec;
if (!ex_handle)
return CQM_FAIL;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip starting cqm timer during kexec\n");
+ return CQM_SUCCESS;
+ }
+
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
if (cqm_handle->func_capability.fake_func_type == CQM_FAKE_FUNC_PARENT &&
cqm_set_fake_vf_timer(cqm_handle) != CQM_SUCCESS)
@@ -456,7 +465,7 @@ static void cqm_service_capability_init_roce(struct tag_cqm_handle *cqm_handle,
cqm_info(handle->dev_hdl, "Cap init: roce qpc 0x%x, scqc 0x%x, srqc 0x%x, drc_qp 0x%x\n",
roce_own_cap->max_qps, roce_own_cap->max_cqs,
roce_own_cap->max_srqs, roce_own_cap->max_drc_qps);
- cqm_info(handle->dev_hdl, "Cap init: type 0x%x, scenes:0x%x, qpc_rsv:0x%x, srv_bmp:0x%x\n",
+ cqm_info(handle->dev_hdl, "Cap init: board_type 0x%x, scenes_id:0x%x, qpc_rsv_mode:0x%x, srv_bmp:0x%x\n",
board_info->board_type, board_info->scenes_id,
roce_qpc_rsv_mode, board_info->service_en_bitmap);
@@ -610,7 +619,7 @@ static void cqm_service_capability_init_ipsec(struct tag_cqm_handle *cqm_handle,
func_cap->scqc_basic_size);
func_cap->scqc_alloc_static = true;
cqm_info(handle->dev_hdl, "Cap init: ipsec is valid\n");
- cqm_info(handle->dev_hdl, "Cap init: ipsec 0x%x, childc %d, scqc 0x%x, scqc_bsize %d\n",
+ cqm_info(handle->dev_hdl, "Cap init: ipsec childc_num 0x%x, childc_bsize %d, scqc_num 0x%x, scqc_bsize %d\n",
ipsec_srvcap->max_sactxs, func_cap->childc_basic_size,
ipsec_srvcap->max_cqs, func_cap->scqc_basic_size);
}
@@ -812,7 +821,7 @@ static int cqm_capability_init_bloomfilter(struct hinic3_hwdev *handle)
func_cap->bloomfilter_addr = service_capability->bfilter_start_addr;
if (func_cap->bloomfilter_length != 0 &&
!cqm_check_align(func_cap->bloomfilter_length)) {
- cqm_err(handle->dev_hdl, "Cap bloomfilter len %u is not the power of 2\n",
+ cqm_err(handle->dev_hdl, "Cap init: bloomfilter_length %u is not the power of 2\n",
func_cap->bloomfilter_length);
return CQM_FAIL;
@@ -883,7 +892,7 @@ static int cqm_capability_init_timer(struct hinic3_hwdev *handle)
func_cap->timer_vf_num = service_capability->timer_vf_num;
func_cap->timer_vf_id_start = service_capability->timer_vf_id_start;
cqm_info(handle->dev_hdl,
- "timer init: pf_num 0x%x, pf_start 0x%x, vf_num 0x%x, vf_start 0x%x\n",
+ "host timer init: timer_pf_num 0x%x, timer_pf_id_start 0x%x, timer_vf_num 0x%x, timer_vf_id_start 0x%x\n",
func_cap->timer_pf_num, func_cap->timer_pf_id_start,
func_cap->timer_vf_num, func_cap->timer_vf_id_start);
@@ -891,7 +900,7 @@ static int cqm_capability_init_timer(struct hinic3_hwdev *handle)
if (IS_SLAVE_HOST(handle)) {
total_timer_num *= CQM_TIMER_NUM_MULTI;
cqm_info(handle->dev_hdl,
- "timer init: need double tw resources, total_timer_num=0x%x\n",
+ "host timer init: need double tw resources, total_timer_num=0x%x\n",
total_timer_num);
}
}
@@ -1059,8 +1068,10 @@ static s32 cqm_fake_init(struct tag_cqm_handle *cqm_handle)
for (i = 0; i < (u32)child_func_number; i++) {
fake_cqm_handle = kmalloc(sizeof(*fake_cqm_handle), GFP_KERNEL | __GFP_ZERO);
- if (!fake_cqm_handle)
+ if (!fake_cqm_handle) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(fake_cqm_handle));
goto err;
+ }
/* Copy the attributes of the parent CQM handle to the child CQM
* handle and modify the values of function.
@@ -1129,7 +1140,7 @@ static s32 cqm_fake_mem_init(struct tag_cqm_handle *cqm_handle)
for (i = 0; i < (u32)child_func_number; i++) {
fake_cqm_handle = cqm_handle->fake_cqm_handle[i];
- snprintf(fake_cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(fake_cqm_handle->name, VRAM_NAME_APPLY_LEN,
"%s%s%02u", cqm_handle->name, VRAM_CQM_FAKE_MEM_BASE, i);
if (cqm_bat_init(fake_cqm_handle) != CQM_SUCCESS) {
@@ -1174,7 +1185,7 @@ s32 cqm_mem_init(void *ex_handle)
struct tag_cqm_handle *cqm_handle = NULL;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
- snprintf(cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(cqm_handle->name, VRAM_NAME_APPLY_LEN,
"%s%02u", VRAM_CQM_GLB_FUNC_BASE, hinic3_global_func_id(handle));
if (cqm_fake_init(cqm_handle) != CQM_SUCCESS) {
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
index 4f87bd1..8d1e481 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
@@ -362,6 +362,7 @@ s32 cqm_fake_vf_num_set(void *ex_handle, u16 fake_vf_num_cfg);
#define CQM_LOG_ID 0
#define CQM_PTR_NULL(x) "%s: " #x " is null\n", __func__
+#define CQM_ALLOC_FAIL(x) "%s: " #x " alloc fail\n", __func__
#define CQM_MAP_FAIL(x) "%s: " #x " map fail\n", __func__
#define CQM_FUNCTION_FAIL(x) "%s: " #x " return failure\n", __func__
#define CQM_WRONG_VALUE(x) "%s: " #x " %u is wrong\n", __func__, (u32)(x)
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
index 4888b0a..d3def81 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
@@ -21,6 +21,7 @@
#include "cqm_bloomfilter.h"
#include "cqm_db.h"
#include "cqm_main.h"
+#include "vram_common.h"
#include "vmsec_mpu_common.h"
#include "cqm_memsec.h"
@@ -34,6 +35,8 @@
#define STD_INPUT_ONE_PARA 1
#define STD_INPUT_TWO_PARA 2
#define MR_KEY_2_INDEX_SHIFT 8
+#define IS_ADDR_IN_MEMSEC(va, len, start, end) \
+ ((va) >= (start) && (va) + (len) < (end))
static int memsec_proc_show(struct seq_file *seq, void *offset);
static int memsec_proc_open(struct inode *inode, struct file *file);
@@ -46,15 +49,24 @@ static int hinic3_secure_mem_proc_node_add(void *hwdev);
static ssize_t memsec_proc_write(struct file *file, const char __user *data, size_t len,
loff_t *pff);
-static struct proc_dir_entry *g_hinic3_memsec_proc_ent; /* proc dir */
+static struct proc_dir_entry *g_hinic3_memsec_proc_ent = NULL; /* proc dir */
static atomic_t g_memsec_proc_refcnt = ATOMIC_INIT(0);
+#if KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE
+static const struct file_operations memsec_proc_fops = {
+ .open = memsec_proc_open,
+ .read = seq_read,
+ .write = memsec_proc_write,
+ .release = memsec_proc_release,
+};
+#else
static const struct proc_ops memsec_proc_fops = {
.proc_open = memsec_proc_open,
.proc_read = seq_read,
.proc_write = memsec_proc_write,
.proc_release = memsec_proc_release,
};
+#endif
bool cqm_need_secure_mem(void *hwdev)
{
@@ -63,6 +75,9 @@ bool cqm_need_secure_mem(void *hwdev)
struct hinic3_hwdev *handle = (struct hinic3_hwdev *)hwdev;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (cqm_handle == NULL) {
+ return false;
+ }
info = &cqm_handle->secure_mem;
return ((info->need_secure_mem) && hinic3_is_guest_vmsec_enable(hwdev));
}
@@ -275,9 +290,10 @@ static int test_query_context(struct hinic3_hwdev *handle, char *data, size_t le
case CQM_OBJECT_SERVICE_CTX:
case CQM_OBJECT_MPT:
qpc_mpt = (struct tag_cqm_qpc_mpt *)cqm_obj;
- if (qpc_mpt->vaddr >= (u8 *)info->va_base &&
- (qpc_mpt->vaddr + cqm_obj->object_size) < (u8 *)info->va_end)
- in_secmem = true;
+ in_secmem = IS_ADDR_IN_MEMSEC(qpc_mpt->vaddr,
+ cqm_obj->object_size,
+ (u8 *)info->va_base,
+ (u8 *)info->va_end);
cqm_info(handle->dev_hdl,
"[memsec_dfx]Query %s:0x%x, va=%p %sin secure mem\n",
query_type == CQM_OBJECT_MPT ? "MPT, mpt_index" : "QPC, qpn",
@@ -286,9 +302,10 @@ static int test_query_context(struct hinic3_hwdev *handle, char *data, size_t le
case CQM_OBJECT_RDMA_SRQ:
case CQM_OBJECT_RDMA_SCQ:
cqm_queue = (struct tag_cqm_queue *)cqm_obj;
- if (cqm_queue->q_ctx_vaddr >= (u8 *)info->va_base &&
- (cqm_queue->q_ctx_vaddr + cqm_obj->object_size) < (u8 *)info->va_end)
- in_secmem = true;
+ in_secmem = IS_ADDR_IN_MEMSEC(cqm_queue->q_ctx_vaddr,
+ cqm_obj->object_size,
+ (u8 *)info->va_base,
+ (u8 *)info->va_end);
cqm_info(handle->dev_hdl,
"[memsec_dfx]Query %s:0x%x, va=%p %sin secure mem\n",
query_type == CQM_OBJECT_RDMA_SRQ ? "SRQC, srqn " : "SCQC, scqn",
@@ -378,7 +395,7 @@ static int hinic3_secure_mem_proc_node_remove(void *hwdev)
atomic_dec(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
@@ -401,7 +418,7 @@ static int hinic3_secure_mem_proc_node_add(void *hwdev)
atomic_inc(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
/* 0400 Read by owner */
@@ -653,7 +670,7 @@ void cqm_free_secure_mem_pages(struct hinic3_hwdev *handle, void *va, u32 order)
return;
}
- if (va < info->va_base || va > (info->va_end - PAGE_SIZE) ||
+ if (va < info->va_base || (va > (info->va_end - PAGE_SIZE)) ||
!PAGE_ALIGNED((va - info->va_base)))
cqm_err(handle->dev_hdl, "%s va wrong value\n", __func__);
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c
index 7d1bd35..86359c0 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c
@@ -180,8 +180,10 @@ struct tag_cqm_queue *cqm_object_recv_queue_create(void *ex_handle, u32 service_
rq_qinfo->common.q_header_vaddr =
cqm_kmalloc_align(sizeof(struct tag_cqm_queue_header),
GFP_KERNEL | __GFP_ZERO, CQM_QHEAD_ALIGN_ORDER);
- if (!rq_qinfo->common.q_header_vaddr)
+ if (!rq_qinfo->common.q_header_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_header_vaddr));
goto err1;
+ }
rq_qinfo->common.q_header_paddr =
pci_map_single(cqm_handle->dev, rq_qinfo->common.q_header_vaddr,
@@ -484,7 +486,8 @@ static bool cqm_object_nonrdma_queue_param_check(struct hinic3_hwdev *handle, u3
struct tag_cqm_handle *cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
/* exception of service registrion check */
- if (!cqm_handle->service[service_type].has_register) {
+ if (service_type >= CQM_SERVICE_T_MAX ||
+ !cqm_handle->service[service_type].has_register) {
cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(service_type));
return false;
}
@@ -1487,4 +1490,4 @@ void cqm_srq_used_rq_container_delete(struct tag_cqm_object *object, u8 *contain
}
kfree((void *)addr);
}
-EXPORT_SYMBOL(cqm_srq_used_rq_container_delete);
+EXPORT_SYMBOL(cqm_srq_used_rq_container_delete);
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c
index 92c19c4..1007b44 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c
@@ -127,8 +127,10 @@ s32 cqm_container_create(struct tag_cqm_object *object, u8 **container_addr, boo
* of the Container.
*/
new_container = kmalloc(qinfo->container_size, GFP_ATOMIC | __GFP_ZERO);
- if (!new_container)
+ if (!new_container) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(new_container));
return CQM_FAIL;
+ }
/* Container PCI mapping */
new_container_pa = pci_map_single(cqm_handle->dev, new_container,
@@ -299,8 +301,10 @@ s32 cqm_share_recv_queue_create(struct tag_cqm_object *object)
/* apply for buffer for SRQC */
common->q_ctx_vaddr = kmalloc(qinfo->q_ctx_size,
GFP_KERNEL | __GFP_ZERO);
- if (!common->q_ctx_vaddr)
+ if (!common->q_ctx_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_ctx_vaddr));
goto err2;
+ }
return CQM_SUCCESS;
err2:
@@ -808,8 +812,10 @@ static s32 cqm_nonrdma_queue_ctx_create(struct tag_cqm_object *object)
common->q_ctx_vaddr = cqm_kmalloc_align(qinfo->q_ctx_size,
GFP_KERNEL | __GFP_ZERO,
(u16)shift);
- if (!common->q_ctx_vaddr)
+ if (!common->q_ctx_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_ctx_vaddr));
return CQM_FAIL;
+ }
common->q_ctx_paddr = pci_map_single(cqm_handle->dev, common->q_ctx_vaddr,
qinfo->q_ctx_size, PCI_DMA_BIDIRECTIONAL);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h b/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
deleted file mode 100644
index ad732c3..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2019-2022. All rights reserved.
- * File Name : hinic3_comm_cmd.h
- * Version : Initial Draft
- * Created : 2019/4/25
- * Last Modified :
- * Description : COMM Commands between Driver and MPU
- * Function List :
- */
-
-#ifndef HINIC3_COMMON_CMD_H
-#define HINIC3_COMMON_CMD_H
-
-/* COMM Commands between Driver to MPU */
-enum hinic3_mgmt_cmd {
- /* flr及资源清理相关命令 */
- COMM_MGMT_CMD_FUNC_RESET = 0,
- COMM_MGMT_CMD_FEATURE_NEGO,
- COMM_MGMT_CMD_FLUSH_DOORBELL,
- COMM_MGMT_CMD_START_FLUSH,
- COMM_MGMT_CMD_SET_FUNC_FLR,
- COMM_MGMT_CMD_GET_GLOBAL_ATTR,
- COMM_MGMT_CMD_SET_PPF_FLR_TYPE,
- COMM_MGMT_CMD_SET_FUNC_SVC_USED_STATE,
-
- /* 分配msi-x中断资源 */
- COMM_MGMT_CMD_CFG_MSIX_NUM = 10,
-
- /* 驱动相关配置命令 */
- COMM_MGMT_CMD_SET_CMDQ_CTXT = 20,
- COMM_MGMT_CMD_SET_VAT,
- COMM_MGMT_CMD_CFG_PAGESIZE,
- COMM_MGMT_CMD_CFG_MSIX_CTRL_REG,
- COMM_MGMT_CMD_SET_CEQ_CTRL_REG,
- COMM_MGMT_CMD_SET_DMA_ATTR,
-
- /* INFRA配置相关命令字 */
- COMM_MGMT_CMD_GET_MQM_FIX_INFO = 40,
- COMM_MGMT_CMD_SET_MQM_CFG_INFO,
- COMM_MGMT_CMD_SET_MQM_SRCH_GPA,
- COMM_MGMT_CMD_SET_PPF_TMR,
- COMM_MGMT_CMD_SET_PPF_HT_GPA,
- COMM_MGMT_CMD_SET_FUNC_TMR_BITMAT,
- COMM_MGMT_CMD_SET_MBX_CRDT,
- COMM_MGMT_CMD_CFG_TEMPLATE,
- COMM_MGMT_CMD_SET_MQM_LIMIT,
-
- /* 信息获取相关命令字 */
- COMM_MGMT_CMD_GET_FW_VERSION = 60,
- COMM_MGMT_CMD_GET_BOARD_INFO,
- COMM_MGMT_CMD_SYNC_TIME,
- COMM_MGMT_CMD_GET_HW_PF_INFOS,
- COMM_MGMT_CMD_SEND_BDF_INFO,
- COMM_MGMT_CMD_GET_VIRTIO_BDF_INFO,
- COMM_MGMT_CMD_GET_SML_TABLE_INFO,
- COMM_MGMT_CMD_GET_SDI_INFO,
-
- /* 升级相关命令字 */
- COMM_MGMT_CMD_UPDATE_FW = 80,
- COMM_MGMT_CMD_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_DONE_NOTICE,
- COMM_MGMT_CMD_SWITCH_CFG,
- COMM_MGMT_CMD_CHECK_FLASH,
- COMM_MGMT_CMD_CHECK_FLASH_RW,
- COMM_MGMT_CMD_RESOURCE_CFG,
- COMM_MGMT_CMD_UPDATE_BIOS, /* TODO: merge to COMM_MGMT_CMD_UPDATE_FW */
- COMM_MGMT_CMD_MPU_GIT_CODE,
-
- /* chip reset相关 */
- COMM_MGMT_CMD_FAULT_REPORT = 100,
- COMM_MGMT_CMD_WATCHDOG_INFO,
- COMM_MGMT_CMD_MGMT_RESET,
- COMM_MGMT_CMD_FFM_SET, /* TODO: check if needed */
-
- /* chip info/log 相关 */
- COMM_MGMT_CMD_GET_LOG = 120,
- COMM_MGMT_CMD_TEMP_OP,
- COMM_MGMT_CMD_EN_AUTO_RST_CHIP,
- COMM_MGMT_CMD_CFG_REG,
- COMM_MGMT_CMD_GET_CHIP_ID,
- COMM_MGMT_CMD_SYSINFO_DFX,
- COMM_MGMT_CMD_PCIE_DFX_NTC,
- COMM_MGMT_CMD_DICT_LOG_STATUS, /* LOG STATUS 127 */
- COMM_MGMT_CMD_MSIX_INFO,
- COMM_MGMT_CMD_CHANNEL_DETECT,
- COMM_MGMT_CMD_DICT_COUNTER_STATUS,
-
- /* switch workmode 相关 */
- COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140,
- COMM_MGMT_CMD_SWITCH_WORKMODE,
-
- /* mpu 相关 */
- COMM_MGMT_CMD_MIGRATE_DFX_HPA = 150,
- COMM_MGMT_CMD_BDF_INFO,
- COMM_MGMT_CMD_NCSI_CFG_INFO_GET_PROC,
-
- /* rsvd0 section */
- COMM_MGMT_CMD_SECTION_RSVD_0 = 160,
-
- /* rsvd1 section */
- COMM_MGMT_CMD_SECTION_RSVD_1 = 170,
-
- /* rsvd2 section */
- COMM_MGMT_CMD_SECTION_RSVD_2 = 180,
-
- /* rsvd3 section */
- COMM_MGMT_CMD_SECTION_RSVD_3 = 190,
-
- /* TODO: move to DFT mode */
- COMM_MGMT_CMD_GET_DIE_ID = 200,
- COMM_MGMT_CMD_GET_EFUSE_TEST,
- COMM_MGMT_CMD_EFUSE_INFO_CFG,
- COMM_MGMT_CMD_GPIO_CTL,
- COMM_MGMT_CMD_HI30_SERLOOP_START, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_SERLOOP_STOP, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_SET_FLAG, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_GET_RESULT, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_ECC_TEST,
- COMM_MGMT_CMD_FUNC_BIST_TEST, /* 209 */
-
- COMM_MGMT_CMD_VPD_SET = 210,
- COMM_MGMT_CMD_VPD_GET,
-
- COMM_MGMT_CMD_ERASE_FLASH,
- COMM_MGMT_CMD_QUERY_FW_INFO,
- COMM_MGMT_CMD_GET_CFG_INFO,
- COMM_MGMT_CMD_GET_UART_LOG,
- COMM_MGMT_CMD_SET_UART_CMD,
- COMM_MGMT_CMD_SPI_TEST,
-
- /* TODO: ALL reg read/write merge to COMM_MGMT_CMD_CFG_REG */
- COMM_MGMT_CMD_UP_REG_GET,
- COMM_MGMT_CMD_UP_REG_SET, /* 219 */
-
- COMM_MGMT_CMD_REG_READ = 220,
- COMM_MGMT_CMD_REG_WRITE,
- COMM_MGMT_CMD_MAG_REG_WRITE,
- COMM_MGMT_CMD_ANLT_REG_WRITE,
-
- COMM_MGMT_CMD_HEART_EVENT, /* TODO: delete */
- COMM_MGMT_CMD_NCSI_OEM_GET_DRV_INFO, /* TODO: delete */
- COMM_MGMT_CMD_LASTWORD_GET,
- COMM_MGMT_CMD_READ_BIN_DATA, /* TODO: delete */
- /* COMM_MGMT_CMD_WWPN_GET, TODO: move to FC? */
- /* COMM_MGMT_CMD_WWPN_SET, TODO: move to FC? */ /* 229 */
-
- /* TODO: check if needed */
- COMM_MGMT_CMD_SET_VIRTIO_DEV = 230,
- COMM_MGMT_CMD_SET_MAC,
- /* MPU patch cmd */
- COMM_MGMT_CMD_LOAD_PATCH,
- COMM_MGMT_CMD_REMOVE_PATCH,
- COMM_MGMT_CMD_PATCH_ACTIVE,
- COMM_MGMT_CMD_PATCH_DEACTIVE,
- COMM_MGMT_CMD_PATCH_SRAM_OPTIMIZE,
- /* container host process */
- COMM_MGMT_CMD_CONTAINER_HOST_PROC,
- /* nsci counter */
- COMM_MGMT_CMD_NCSI_COUNTER_PROC,
- COMM_MGMT_CMD_CHANNEL_STATUS_CHECK, /* 239 */
-
- /* hot patch rsvd cmd */
- COMM_MGMT_CMD_RSVD_0 = 240,
- COMM_MGMT_CMD_RSVD_1,
- COMM_MGMT_CMD_RSVD_2,
- COMM_MGMT_CMD_RSVD_3,
- COMM_MGMT_CMD_RSVD_4,
- /* 无效字段,版本收编删除,编译使用 */
- COMM_MGMT_CMD_SEND_API_ACK_BY_UP,
-
- /* 注:添加cmd,不能修改已有命令字的值,请在前方rsvd
- * section中添加;原则上所有分支cmd表完全一致
- */
- COMM_MGMT_CMD_MAX = 255,
-};
-
-/* CmdQ Common subtype */
-enum comm_cmdq_cmd {
- COMM_CMD_UCODE_ARM_BIT_SET = 2,
- COMM_CMD_SEND_NPU_DFT_CMD,
-};
-
-#endif /* HINIC3_COMMON_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
deleted file mode 100644
index 9ce908e..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_COMMON_H
-#define HINIC3_COMMON_H
-
-#include <linux/types.h>
-
-struct hinic3_dma_addr_align {
- u32 real_size;
-
- void *ori_vaddr;
- dma_addr_t ori_paddr;
-
- void *align_vaddr;
- dma_addr_t align_paddr;
-};
-
-enum hinic3_wait_return {
- WAIT_PROCESS_CPL = 0,
- WAIT_PROCESS_WAITING = 1,
- WAIT_PROCESS_ERR = 2,
-};
-
-struct hinic3_sge {
- u32 hi_addr;
- u32 lo_addr;
- u32 len;
-};
-
-#ifdef static
-#undef static
-#define LLT_STATIC_DEF_SAVED
-#endif
-
-/* *
- * hinic_cpu_to_be32 - convert data to big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert, must be Multiple of 4B
- */
-static inline void hinic3_cpu_to_be32(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = cpu_to_be32(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_cpu_to_be32 - convert data from big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert
- */
-static inline void hinic3_be32_to_cpu(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = be32_to_cpu(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_set_sge - set dma area in scatter gather entry
- * @sge: scatter gather entry
- * @addr: dma address
- * @len: length of relevant data in the dma address
- */
-static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
- int len)
-{
- sge->hi_addr = upper_32_bits(addr);
- sge->lo_addr = lower_32_bits(addr);
- sge->len = len;
-}
-
-#define hinic3_hw_be32(val) (val)
-#define hinic3_hw_cpu32(val) (val)
-#define hinic3_hw_cpu16(val) (val)
-
-static inline void hinic3_hw_be32_len(void *data, int len)
-{
-}
-
-static inline void hinic3_hw_cpu32_len(void *data, int len)
-{
-}
-
-int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
- unsigned int flag,
- struct hinic3_dma_addr_align *mem_align);
-
-void hinic3_dma_free_coherent_align(void *dev_hdl,
- struct hinic3_dma_addr_align *mem_align);
-
-typedef enum hinic3_wait_return (*wait_cpl_handler)(void *priv_data);
-
-int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
- u32 wait_total_ms, u32 wait_once_us);
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
index f269691..7979244 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
@@ -8,7 +8,7 @@
#include "mpu_cmd_base_defs.h"
-#define HINIC3_DRV_VERSION "15.17.1.1"
+#define HINIC3_DRV_VERSION "17.7.8.1"
#define HINIC3_DRV_DESC "Intelligent Network Interface Card Driver"
#define HIUDK_DRV_DESC "Intelligent Network Unified Driver"
@@ -45,6 +45,8 @@ enum hinic3_service_type {
SERVICE_T_CUSTOM,
SERVICE_T_VROCE,
SERVICE_T_CRYPT,
+ SERVICE_T_VSOCK,
+ SERVICE_T_BIFUR,
SERVICE_T_MAX,
/* Only used for interruption resource management,
@@ -63,6 +65,9 @@ struct nic_service_cap {
u16 max_sqs;
u16 max_rqs;
u16 default_num_queues;
+ u16 outband_vlan_cfg_en;
+ u8 lro_enable;
+ u8 rsvd1[3];
};
struct ppa_service_cap {
@@ -76,6 +81,10 @@ struct ppa_service_cap {
u16 rsvd1;
};
+struct bifur_service_cap {
+ u8 rsvd;
+};
+
struct vbs_service_cap {
u16 vbs_max_volq;
u8 vbs_main_pf_enable;
@@ -786,6 +795,15 @@ bool hinic3_support_toe(void *hwdev, struct toe_service_cap *cap);
bool hinic3_support_ppa(void *hwdev, struct ppa_service_cap *cap);
/* *
+ * @brief hinic3_support_bifur - function support bifur
+ * @param hwdev: device pointer to hwdev
+ * @param cap: bifur service capbility
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+bool hinic3_support_bifur(void *hwdev, struct bifur_service_cap *cap);
+
+/* *
* @brief hinic3_support_migr - function support migrate
* @param hwdev: device pointer to hwdev
* @param cap: migrate service capbility
@@ -896,6 +914,13 @@ int hinic3_get_fw_version(void *hwdev, struct hinic3_fw_version *fw_ver,
u16 channel);
/* *
+ * @brief hinic3_get_bond_create_mode - get bond create mode
+ * @param hwdev: device pointer to hwdev
+ * @retval global function id
+ */
+u8 hinic3_get_bond_create_mode(void *udkdev);
+
+/* *
* @brief hinic3_global_func_id - get global function id
* @param hwdev: device pointer to hwdev
* @retval global function id
@@ -1249,4 +1274,7 @@ int hinic3_mbox_to_host_sync(void *hwdev, enum hinic3_mod_type mod,
int hinic3_get_func_vroce_enable(void *hwdev, u16 glb_func_idx, u8 *en);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type);
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
index 5863bee..9b5f017 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
@@ -18,9 +18,8 @@
#include "hinic3_tx.h"
#include "hinic3_dcb.h"
#include "hinic3_nic.h"
-#include "hinic3_mgmt_interface.h"
-#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "hinic3_bond.h"
+#include "nic_mpu_cmd_defs.h"
typedef int (*nic_driv_module)(struct hinic3_nic_dev *nic_dev,
const void *buf_in, u32 in_size,
@@ -48,7 +47,7 @@ static int get_nic_drv_version(void *buf_out, const u32 *out_size)
}
err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
- HINIC3_NIC_DRV_VERSION, "2024-07-03_09:33:00");
+ HINIC3_NIC_DRV_VERSION, "2025-05-01_00:00:03");
if (err < 0)
return -EINVAL;
@@ -94,13 +93,13 @@ static int get_q_num(struct hinic3_nic_dev *nic_dev,
return -EFAULT;
}
- if (!buf_out) {
+ if (!buf_out || !out_size) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Get queue number para buf_out is NULL.\n");
return -EINVAL;
}
- if (!out_size || *out_size != sizeof(u16)) {
+ if (*out_size != sizeof(u16)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user: %u, expect: %lu\n",
*out_size, sizeof(u16));
@@ -126,7 +125,8 @@ static int get_tx_wqe_info(struct hinic3_nic_dev *nic_dev,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -178,7 +178,8 @@ static int get_rx_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
rq_info->delta = (u16)nic_dev->rxqs[q_id].delta;
- rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx & nic_dev->rxqs[q_id].q_mask);
+ rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx &
+ nic_dev->rxqs[q_id].q_mask);
rq_info->sw_pi = nic_dev->rxqs[q_id].next_to_update;
rq_info->msix_vector = nic_dev->rxqs[q_id].irq_id;
@@ -201,7 +202,8 @@ static int get_rx_wqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -230,7 +232,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EFAULT;
}
- if (!buf_in || !buf_out) {
+ if (!buf_in || !buf_out || !out_size) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Buf_in or buf_out is NULL.\n");
return -EINVAL;
@@ -243,7 +245,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EINVAL;
}
- if (!out_size || *out_size != sizeof(struct hinic3_rq_cqe)) {
+ if (*out_size != sizeof(struct hinic3_rq_cqe)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(struct hinic3_rq_cqe));
@@ -252,10 +254,16 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
q_id = (u16)info->q_id;
idx = (u16)info->wqe_id;
- if (q_id >= nic_dev->q_params.num_qps || idx >= nic_dev->rxqs[q_id].q_depth) {
+ if (q_id >= nic_dev->q_params.num_qps) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid q_id[%u] >= %u.\n", q_id,
+ nic_dev->q_params.num_qps);
+ return -EFAULT;
+ }
+ if (idx >= nic_dev->rxqs[q_id].q_depth) {
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Invalid q_id[%u] >= %u, or wqe idx[%u] >= %u.\n",
- q_id, nic_dev->q_params.num_qps, idx, nic_dev->rxqs[q_id].q_depth);
+ "Invalid wqe idx[%u] >= %u.\n", idx,
+ nic_dev->rxqs[q_id].q_depth);
return -EFAULT;
}
@@ -338,7 +346,8 @@ static int set_loopback_mode(struct hinic3_nic_dev *nic_dev, const void *buf_in,
err = hinic3_set_loopback_mode(nic_dev->hwdev, (u8)mode->loop_mode,
(u8)mode->loop_ctrl);
if (err == 0)
- nicif_info(nic_dev, drv, nic_dev->netdev, "Set loopback mode %u en %u succeed\n",
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Set loopback mode %u en %u succeed\n",
mode->loop_mode, mode->loop_ctrl);
return err;
@@ -417,6 +426,59 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
{
u32 pf_bw_limit;
int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
+
+ if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To set VF bandwidth rate, please use ip link cmd\n");
+ return -EINVAL;
+ }
+
+ if (!buf_in || !buf_out || in_size != sizeof(u32) ||
+ !out_size || *out_size != sizeof(u8))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_TX;
+ pf_bw_limit = *((u32 *)buf_in);
+
+ err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
+ if (err) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %u%%\n",
+ pf_bw_limit);
+ if (err < 0)
+ return err;
+ }
+
+ *((u8 *)buf_out) = (u8)err;
+
+ return 0;
+}
+
+static int set_rx_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ u32 pf_bw_limit;
+ int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
nicif_err(nic_dev, drv, nic_dev->netdev, "To set VF bandwidth rate, please use ip link cmd\n");
@@ -426,11 +488,16 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || !buf_out || in_size != sizeof(u32) || !out_size || *out_size != sizeof(u8))
return -EINVAL;
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_RX;
pf_bw_limit = *((u32 *)buf_in);
err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %d%%\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to set pf bandwidth limit to %d%%\n",
pf_bw_limit);
if (err < 0)
return err;
@@ -445,19 +512,21 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
struct hinic3_nic_io *nic_io = NULL;
+ u32 *rate_limit = (u32 *)buf_out;
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "To get VF bandwidth rate, please use ip link cmd\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To get VF bandwidth rate, please use ip link cmd\n");
return -EINVAL;
}
if (!buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(u32)) {
+ if (*out_size != sizeof(u32) * 2) { // 2:Stored in an array, TX and RX, both length are u32
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user: %d, expect: %lu\n",
- *out_size, sizeof(u32));
+ *out_size, sizeof(u32) * 2);
return -EFAULT;
}
@@ -465,8 +534,12 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!nic_io)
return -EINVAL;
- *((u32 *)buf_out) = nic_io->nic_cfg.pf_bw_limit;
+ rate_limit[HINIC3_NIC_RX] = nic_io->nic_cfg.pf_bw_rx_limit;
+ rate_limit[HINIC3_NIC_TX] = nic_io->nic_cfg.pf_bw_tx_limit;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "read rate cfg success rx rate is: %u, tx rate is : %u\n",
+ rate_limit[HINIC3_NIC_RX], rate_limit[HINIC3_NIC_TX]);
return 0;
}
@@ -477,8 +550,8 @@ static int get_sset_count(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || in_size != sizeof(u32) || !out_size ||
*out_size != sizeof(u32) || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
@@ -504,16 +577,16 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
int err;
if (!buf_in || in_size != sizeof(u32) || !out_size || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
size = sizeof(u32);
err = get_sset_count(nic_dev, buf_in, in_size, &count, &size);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Get sset count failed, ret=%d\n",
- err);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Get sset count failed, ret=%d\n", err);
return -EINVAL;
}
if (count * sizeof(*items) != *out_size) {
@@ -527,12 +600,14 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
switch (sset) {
case HINIC3_SHOW_SSET_IO_STATS:
- hinic3_get_io_stats(nic_dev, items);
+ err = hinic3_get_io_stats(nic_dev, items);
+ if (err < 0)
+ return -EINVAL;
break;
default:
- nicif_err(nic_dev, drv, nic_dev->netdev, "Unknown %u to get stats\n",
- sset);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unknown %u to get stats\n", sset);
err = -EINVAL;
break;
}
@@ -544,15 +619,18 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int i;
u8 cos_num = 0, valid_cos_bitmap = 0;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_PCP2COS) {
for (i = 0; i < NIC_DCB_UP_MAX; i++) {
- if (!(nic_dev->func_dft_cos_bitmap & BIT(qos_in->pcp2cos[i]))) {
+ if (!(dcb->func_dft_cos_bitmap &
+ BIT(qos_in->pcp2cos[i]))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- qos_in->pcp2cos[i], nic_dev->func_dft_cos_bitmap);
+ qos_in->pcp2cos[i],
+ dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -562,7 +640,8 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
}
- memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos, sizeof(qos_in->pcp2cos));
+ memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos,
+ sizeof(qos_in->pcp2cos));
wanted_dcb_cfg->pcp_user_cos_num = cos_num;
wanted_dcb_cfg->pcp_valid_cos_map = valid_cos_bitmap;
}
@@ -572,12 +651,14 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = 0;
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++) {
u8 cos = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->wanted_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ dcb->wanted_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
- if (cos >= NIC_DCB_UP_MAX || !(nic_dev->func_dft_cos_bitmap & BIT(cos))) {
+ if (cos >= NIC_DCB_UP_MAX ||
+ !(dcb->func_dft_cos_bitmap & BIT(cos))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- cos, nic_dev->func_dft_cos_bitmap);
+ cos, dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -588,8 +669,10 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- wanted_dcb_cfg->dscp2cos[i] = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->hw_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ wanted_dcb_cfg->dscp2cos[i] =
+ qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
+ dcb->hw_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
wanted_dcb_cfg->dscp_user_cos_num = cos_num;
wanted_dcb_cfg->dscp_valid_cos_map = valid_cos_bitmap;
}
@@ -601,11 +684,12 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int ret;
u8 cos_num, valid_cos_bitmap;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_TRUST) {
- if (qos_in->trust > DCB_DSCP) {
+ if (qos_in->trust > HINIC3_DCB_DSCP) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid trust=%u\n", qos_in->trust);
return -EINVAL;
@@ -615,7 +699,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
}
if (qos_in->cfg_bitmap & CMD_QOS_DEV_DFT_COS) {
- if (!(BIT(qos_in->dft_cos) & nic_dev->func_dft_cos_bitmap)) {
+ if (!(BIT(qos_in->dft_cos) & dcb->func_dft_cos_bitmap)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid dft_cos=%u\n", qos_in->dft_cos);
return -EINVAL;
@@ -628,7 +712,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
if (ret)
return ret;
- if (wanted_dcb_cfg->trust == DCB_PCP) {
+ if (wanted_dcb_cfg->trust == HINIC3_DCB_PCP) {
cos_num = wanted_dcb_cfg->pcp_user_cos_num;
valid_cos_bitmap = wanted_dcb_cfg->pcp_valid_cos_map;
} else {
@@ -636,18 +720,11 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = wanted_dcb_cfg->dscp_valid_cos_map;
}
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "DCB is on, cos num should not more than channel num:%u\n",
- nic_dev->q_params.num_qps);
- return -EOPNOTSUPP;
- }
- }
-
if (!(BIT(wanted_dcb_cfg->default_cos) & valid_cos_bitmap)) {
- nicif_info(nic_dev, drv, nic_dev->netdev, "Current default_cos=%u, change to %u\n",
- wanted_dcb_cfg->default_cos, (u8)fls(valid_cos_bitmap) - 1);
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Current default_cos=%u, change to %u\n",
+ wanted_dcb_cfg->default_cos,
+ (u8)fls(valid_cos_bitmap) - 1);
wanted_dcb_cfg->default_cos = (u8)fls(valid_cos_bitmap) - 1;
}
@@ -657,6 +734,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_dev_cfg *qos_in = buf_in;
struct hinic3_mt_qos_dev_cfg *qos_out = buf_out;
u8 i;
@@ -675,9 +753,10 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(qos_out, qos_in, sizeof(*qos_in));
qos_out->head.status = 0;
if (qos_in->op_code & MT_DCB_OPCODE_WR) {
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg,
+ memcpy(&dcb->wanted_dcb_cfg, &dcb->hw_dcb_cfg,
sizeof(struct hinic3_dcb_config));
- err = update_wanted_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg, qos_in);
+ err = update_wanted_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg,
+ qos_in);
if (err) {
qos_out->head.status = MT_EINVAL;
return 0;
@@ -687,12 +766,12 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
qos_out->head.status = MT_EIO;
} else {
- qos_out->dft_cos = nic_dev->hw_dcb_cfg.default_cos;
- qos_out->trust = nic_dev->hw_dcb_cfg.trust;
+ qos_out->dft_cos = dcb->hw_dcb_cfg.default_cos;
+ qos_out->trust = dcb->hw_dcb_cfg.trust;
for (i = 0; i < NIC_DCB_UP_MAX; i++)
- qos_out->pcp2cos[i] = nic_dev->hw_dcb_cfg.pcp2cos[i];
+ qos_out->pcp2cos[i] = dcb->hw_dcb_cfg.pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- qos_out->dscp2cos[i] = nic_dev->hw_dcb_cfg.dscp2cos[i];
+ qos_out->dscp2cos[i] = dcb->hw_dcb_cfg.dscp2cos[i];
}
return 0;
@@ -721,27 +800,17 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(dcb_out, dcb_in, sizeof(*dcb_in));
dcb_out->head.status = 0;
if (dcb_in->op_code & MT_DCB_OPCODE_WR) {
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) == dcb_in->state)
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ==
+ dcb_in->state)
return 0;
- if (dcb_in->state) {
- if (user_cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "cos num %u should not more than channel num %u\n",
- user_cos_num,
- nic_dev->q_params.num_qps);
-
- return -EOPNOTSUPP;
- }
- }
-
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? user_cos_num : 0,
+ err = hinic3_setup_cos(nic_dev->netdev,
+ dcb_in->state ? user_cos_num : 0,
netif_run);
if (err)
goto setup_cos_fail;
@@ -751,7 +820,6 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
goto vport_up_fail;
}
- rtnl_unlock();
} else {
dcb_out->state = !!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
}
@@ -759,12 +827,12 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
vport_up_fail:
- hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num,
+ netif_run);
setup_cos_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
return err;
}
@@ -772,13 +840,15 @@ setup_cos_fail:
static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_cos_cfg *cos_cfg_in = buf_in;
struct hinic3_mt_qos_cos_cfg *cos_cfg_out = buf_out;
if (!buf_in || !buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(*cos_cfg_out) || in_size != sizeof(*cos_cfg_in)) {
+ if (*out_size != sizeof(*cos_cfg_out) ||
+ in_size != sizeof(*cos_cfg_in)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
in_size, *out_size, sizeof(*cos_cfg_in));
@@ -789,9 +859,9 @@ static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
cos_cfg_out->head.status = 0;
cos_cfg_out->port_id = hinic3_physical_port_id(nic_dev->hwdev);
- cos_cfg_out->func_cos_bitmap = (u8)nic_dev->func_dft_cos_bitmap;
- cos_cfg_out->port_cos_bitmap = (u8)nic_dev->port_dft_cos_bitmap;
- cos_cfg_out->func_max_cos_num = nic_dev->cos_config_num_max;
+ cos_cfg_out->func_cos_bitmap = (u8)dcb->func_dft_cos_bitmap;
+ cos_cfg_out->port_cos_bitmap = (u8)dcb->port_dft_cos_bitmap;
+ cos_cfg_out->func_max_cos_num = dcb->cos_config_num_max;
return 0;
}
@@ -803,7 +873,13 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
intr_num = hinic3_intr_num(nic_dev->hwdev);
- if (!buf_out || !out_size || *out_size != sizeof(u16)) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != sizeof(u16)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(u16));
@@ -817,20 +893,27 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
static int get_netdev_name(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- if (!buf_out || !out_size || *out_size != IFNAMSIZ) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != IFNAMSIZ) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %u\n",
*out_size, IFNAMSIZ);
return -EFAULT;
}
- strlcpy(buf_out, nic_dev->netdev->name, IFNAMSIZ);
+ strscpy(buf_out, nic_dev->netdev->name, IFNAMSIZ);
return 0;
}
-static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
int *tx_timeout = buf_out;
@@ -839,7 +922,8 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (*out_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, out_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, out_size: %u, expect: %lu\n",
*out_size, sizeof(int));
return -EINVAL;
}
@@ -849,8 +933,9 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return 0;
}
-static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
const int *tx_timeout = buf_in;
@@ -859,13 +944,15 @@ static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (in_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, in_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, in_size: %u, expect: %lu\n",
in_size, sizeof(int));
return -EINVAL;
}
net_dev->watchdog_timeo = *tx_timeout * HZ;
- nicif_info(nic_dev, drv, net_dev, "Set tx timeout check period to %ds\n", *tx_timeout);
+ nicif_info(nic_dev, drv, net_dev,
+ "Set tx timeout check period to %ds\n", *tx_timeout);
return 0;
}
@@ -891,6 +978,34 @@ static int get_xsfp_present(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
}
+static int get_xsfp_tlv_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct drv_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info = buf_out;
+ const struct mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req = buf_in;
+ int err;
+
+ if ((buf_in == NULL) || (buf_out == NULL) || (out_size == NULL))
+ return -EINVAL;
+
+ if (*out_size != sizeof(*sfp_tlv_info) ||
+ in_size != sizeof(*sfp_tlv_info_req)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
+ in_size, *out_size, sizeof(*sfp_tlv_info));
+ return -EINVAL;
+ }
+
+ err = hinic3_get_sfp_tlv_info(nic_dev->hwdev,
+ sfp_tlv_info, sfp_tlv_info_req);
+ if (err != 0) {
+ sfp_tlv_info->head.status = MT_EIO;
+ return 0;
+ }
+
+ return 0;
+}
+
static int get_xsfp_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
@@ -928,7 +1043,7 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{GET_LOOPBACK_MODE, get_loopback_mode},
{SET_LOOPBACK_MODE, set_loopback_mode},
{SET_LINK_MODE, set_link_mode},
- {SET_PF_BW_LIMIT, set_pf_bw_limit},
+ {SET_TX_PF_BW_LIMIT, set_pf_bw_limit},
{GET_PF_BW_LIMIT, get_pf_bw_limit},
{GET_SSET_COUNT, get_sset_count},
{GET_SSET_ITEMS, get_sset_stats},
@@ -940,17 +1055,22 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{SET_TX_TIMEOUT, set_netdev_tx_timeout},
{GET_XSFP_PRESENT, get_xsfp_present},
{GET_XSFP_INFO, get_xsfp_info},
+ {GET_XSFP_INFO_COMP_CMIS, get_xsfp_tlv_info},
+ {SET_RX_PF_BW_LIMIT, set_rx_pf_bw_limit}
};
static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
u32 cmd, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(nic_driv_module_cmd_handle) /
- sizeof(nic_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(nic_driv_module_cmd_handle) /
+ sizeof(nic_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type = (enum driver_cmd_type)cmd;
int err = 0;
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_lock();
+
mutex_lock(&nic_dev->nic_mutex);
for (index = 0; index < num_cmds; index++) {
if (cmd_type ==
@@ -963,6 +1083,9 @@ static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
}
mutex_unlock(&nic_dev->nic_mutex);
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_unlock();
+
if (index == num_cmds) {
pr_err("Can't find callback for %d\n", cmd_type);
return -EINVAL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
index a1fb4af..aa53c19 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
@@ -24,82 +24,80 @@
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_user_cos_num;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_user_cos_num;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_user_cos_num;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_user_cos_num;
return 0;
}
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_valid_cos_map;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_valid_cos_map;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_valid_cos_map;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_valid_cos_map;
return 0;
}
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
- u8 i, remainder, num_sq_per_cos, cur_cos_num = 0;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ struct hinic3_dcb_config *wanted_dcb_cfg =
+ &nic_dev->dcb->wanted_dcb_cfg;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
+ u8 cos_qp_num, cos_qp_offset = 0;
+ u8 i, remainder, num_qp_per_cos;
- if (num_cos == 0)
- return;
-
- num_sq_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
- if (num_sq_per_cos == 0)
+ if (num_cos == 0 || nic_dev->q_params.num_qps == 0)
return;
- remainder = nic_dev->q_params.num_qps % num_sq_per_cos;
+ num_qp_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
+ remainder = nic_dev->q_params.num_qps % num_cos;
- memset(dcb_cfg->cos_qp_offset, 0, sizeof(dcb_cfg->cos_qp_offset));
- memset(dcb_cfg->cos_qp_num, 0, sizeof(dcb_cfg->cos_qp_num));
+ memset(hw_dcb_cfg->cos_qp_offset, 0, sizeof(hw_dcb_cfg->cos_qp_offset));
+ memset(hw_dcb_cfg->cos_qp_num, 0, sizeof(hw_dcb_cfg->cos_qp_num));
for (i = 0; i < PCP_MAX_UP; i++) {
if (BIT(i) & valid_cos_map) {
- u8 cos_qp_num = num_sq_per_cos;
- u8 cos_qp_offset = (u8)(cur_cos_num * num_sq_per_cos);
-
- if (cur_cos_num < remainder) {
- cos_qp_num++;
- cos_qp_offset += cur_cos_num;
- } else {
- cos_qp_offset += remainder;
- }
-
- cur_cos_num++;
- valid_cos_map -= (u8)BIT(i);
+ cos_qp_num = num_qp_per_cos + ((remainder > 0) ?
+ (remainder--, 1) : 0);
- dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
- dcb_cfg->cos_qp_num[i] = cos_qp_num;
+ hw_dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
+ hw_dcb_cfg->cos_qp_num[i] = cos_qp_num;
hinic3_info(nic_dev, drv, "cos %u, cos_qp_offset=%u cos_qp_num=%u\n",
i, cos_qp_offset, cos_qp_num);
+
+ cos_qp_offset += cos_qp_num;
+ valid_cos_map -= (int)BIT(i);
}
}
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_offset, dcb_cfg->cos_qp_offset,
- sizeof(dcb_cfg->cos_qp_offset));
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_num, dcb_cfg->cos_qp_num,
- sizeof(dcb_cfg->cos_qp_num));
+ memcpy(wanted_dcb_cfg->cos_qp_offset, hw_dcb_cfg->cos_qp_offset,
+ sizeof(hw_dcb_cfg->cos_qp_offset));
+ memcpy(wanted_dcb_cfg->cos_qp_num, hw_dcb_cfg->cos_qp_num,
+ sizeof(hw_dcb_cfg->cos_qp_num));
}
void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
u8 i;
u16 start_qid, q_num;
hinic3_set_txq_cos(nic_dev, 0, nic_dev->q_params.num_qps,
- nic_dev->hw_dcb_cfg.default_cos);
+ hw_dcb_cfg->default_cos);
if (!dcb_en)
return;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- q_num = (u16)nic_dev->hw_dcb_cfg.cos_qp_num[i];
+ q_num = (u16)hw_dcb_cfg->cos_qp_num[i];
if (q_num) {
- start_qid = (u16)nic_dev->hw_dcb_cfg.cos_qp_offset[i];
+ start_qid = (u16)hw_dcb_cfg->cos_qp_offset[i];
hinic3_set_txq_cos(nic_dev, start_qid, q_num, i);
hinic3_info(nic_dev, drv, "update tx db cos, start_qid %u, q_num=%u cos=%u\n",
@@ -110,30 +108,29 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ struct hinic3_dcb_config *hw_dcb_cfg = &dcb->hw_dcb_cfg;
struct hinic3_dcb_state dcb_state = {0};
u8 i;
int err;
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- /* VF does not support DCB, use the default cos */
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
-
- return 0;
- }
+ u32 pcp2cos_size = sizeof(dcb_state.pcp2cos);
+ u32 dscp2cos_size = sizeof(dcb_state.dscp2cos);
dcb_state.dcb_on = dcb_en;
- dcb_state.default_cos = dcb_cfg->default_cos;
- dcb_state.trust = dcb_cfg->trust;
+ dcb_state.default_cos = hw_dcb_cfg->default_cos;
+ dcb_state.trust = hw_dcb_cfg->trust;
if (dcb_en) {
for (i = 0; i < NIC_DCB_COS_MAX; i++)
- dcb_state.pcp2cos[i] = dcb_cfg->pcp2cos[i];
+ dcb_state.pcp2cos[i] = hw_dcb_cfg->pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- dcb_state.dscp2cos[i] = dcb_cfg->dscp2cos[i];
+ dcb_state.dscp2cos[i] = hw_dcb_cfg->dscp2cos[i];
} else {
- memset(dcb_state.pcp2cos, dcb_cfg->default_cos, sizeof(dcb_state.pcp2cos));
- memset(dcb_state.dscp2cos, dcb_cfg->default_cos, sizeof(dcb_state.dscp2cos));
+ memset(dcb_state.pcp2cos, hw_dcb_cfg->default_cos,
+ pcp2cos_size);
+ memset(dcb_state.dscp2cos, hw_dcb_cfg->default_cos,
+ dscp2cos_size);
}
err = hinic3_set_dcb_state(nic_dev->hwdev, &dcb_state);
@@ -143,7 +140,7 @@ static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
return err;
}
-static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
int err;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
@@ -169,11 +166,13 @@ static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
goto rx_configure_fail;
}
- if (dcb_en)
+ if (dcb_en) {
set_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
- else
+ set_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ } else {
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
-
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ }
return 0;
rx_configure_fail:
hinic3_set_tx_cos_state(nic_dev, dcb_en ? 0 : 1);
@@ -188,6 +187,7 @@ set_tx_cos_fail:
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err;
if (cos && test_bit(HINIC3_SAME_RXTX, &nic_dev->flags)) {
@@ -195,9 +195,10 @@ int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
return -EOPNOTSUPP;
}
- if (cos > nic_dev->cos_config_num_max) {
- nicif_err(nic_dev, drv, netdev, "Invalid num_tc: %u, max cos: %u\n",
- cos, nic_dev->cos_config_num_max);
+ if (cos > dcb->cos_config_num_max) {
+ nicif_err(nic_dev, drv, netdev,
+ "Invalid num_tc: %u, max cos: %u\n",
+ cos, dcb->cos_config_num_max);
return -EINVAL;
}
@@ -223,36 +224,48 @@ static u8 get_cos_num(u8 hw_valid_cos_bitmap)
static void hinic3_sync_dcb_cfg(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dcb_config *dcb_cfg)
{
- struct hinic3_dcb_config *hw_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
- memcpy(hw_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(hw_dcb_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
}
static int init_default_dcb_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *dcb_cfg)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 i, hw_dft_cos_map, port_cos_bitmap, dscp_ind;
int err;
+ int is_in_kexec;
- err = hinic3_cos_valid_bitmap(nic_dev->hwdev, &hw_dft_cos_map, &port_cos_bitmap);
+ err = hinic3_cos_valid_bitmap(nic_dev->hwdev,
+ &hw_dft_cos_map, &port_cos_bitmap);
if (err) {
hinic3_err(nic_dev, drv, "None cos supported\n");
return -EFAULT;
}
- nic_dev->func_dft_cos_bitmap = hw_dft_cos_map;
- nic_dev->port_dft_cos_bitmap = port_cos_bitmap;
- nic_dev->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+ is_in_kexec = vram_get_kexec_flag();
- dcb_cfg->trust = DCB_PCP;
- dcb_cfg->pcp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->dscp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
+ dcb->func_dft_cos_bitmap = hw_dft_cos_map;
+ dcb->port_dft_cos_bitmap = port_cos_bitmap;
+
+ dcb->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+
+ if (is_in_kexec == 0) {
+ dcb_cfg->trust = HINIC3_DCB_PCP;
+ dcb_cfg->default_cos = (u8)fls(dcb->func_dft_cos_bitmap) - 1;
+ } else {
+ dcb_cfg->trust = nic_dev->dcb->hw_dcb_cfg.trust;
+ dcb_cfg->default_cos = nic_dev->dcb->hw_dcb_cfg.default_cos;
+ }
+ dcb_cfg->pcp_user_cos_num = dcb->cos_config_num_max;
+ dcb_cfg->dscp_user_cos_num = dcb->cos_config_num_max;
dcb_cfg->pcp_valid_cos_map = hw_dft_cos_map;
dcb_cfg->dscp_valid_cos_map = hw_dft_cos_map;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i) ? i : dcb_cfg->default_cos;
+ dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i)
+ ? i : (u8)fls(dcb->func_dft_cos_bitmap) - 1;
for (dscp_ind = 0; dscp_ind < NIC_DCB_COS_MAX; dscp_ind++)
dcb_cfg->dscp2cos[i * NIC_DCB_DSCP_NUM + dscp_ind] = dcb_cfg->pcp2cos[i];
}
@@ -276,58 +289,121 @@ int hinic3_configure_dcb(struct net_device *netdev)
int err;
err = hinic3_sync_dcb_state(nic_dev->hwdev, 1,
- test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)
+ ? 1 : 0);
if (err) {
hinic3_err(nic_dev, drv, "Set dcb state failed\n");
return err;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ hinic3_sync_dcb_cfg(nic_dev, &nic_dev->dcb->wanted_dcb_cfg);
else
hinic3_dcb_reset_hw_config(nic_dev);
return 0;
}
+static int hinic3_dcb_alloc(struct hinic3_nic_dev *nic_dev)
+{
+ u16 func_id;
+ int is_use_vram;
+ int ret;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ ret = snprintf(nic_dev->dcb_name, VRAM_NAME_MAX_LEN,
+ "%s%u%s", VRAM_CQM_GLB_FUNC_BASE, func_id,
+ VRAM_NIC_DCB);
+ if (ret < 0) {
+ hinic3_err(nic_dev, drv, "Nic dcb snprintf failed, ret:%d.\n", ret);
+ return ret;
+ }
+
+ nic_dev->dcb = (struct hinic3_dcb *)hi_vram_kalloc(nic_dev->dcb_name,
+ sizeof(*nic_dev->dcb));
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to vram alloc dcb.\n");
+ return -EFAULT;
+ }
+ } else {
+ nic_dev->dcb = kzalloc(sizeof(*nic_dev->dcb), GFP_KERNEL);
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to create dcb.\n");
+ return -EFAULT;
+ }
+ }
+
+ return 0;
+}
+
+static void hinic3_dcb_free(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram)
+ hi_vram_kfree((void *)nic_dev->dcb, nic_dev->dcb_name, sizeof(*nic_dev->dcb));
+ else
+ kfree(nic_dev->dcb);
+ nic_dev->dcb = NULL;
+}
+
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
+ hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+
+ hinic3_dcb_free(nic_dev);
+}
+
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = NULL;
int err;
u8 dcb_en = test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0;
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- return hinic3_set_tx_cos_state(nic_dev, dcb_en);
+ err = hinic3_dcb_alloc(nic_dev);
+ if (err != 0) {
+ hinic3_err(nic_dev, drv, "Dcb alloc failed.\n");
+ return err;
+ }
- err = init_default_dcb_cfg(nic_dev, dcb_cfg);
+ hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ err = init_default_dcb_cfg(nic_dev, hw_dcb_cfg);
if (err) {
- hinic3_err(nic_dev, drv, "Initialize dcb configuration failed\n");
+ hinic3_err(nic_dev, drv,
+ "Initialize dcb configuration failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&nic_dev->dcb->wanted_dcb_cfg, hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
hinic3_info(nic_dev, drv, "Support num cos %u, default cos %u\n",
- nic_dev->cos_config_num_max, dcb_cfg->default_cos);
+ nic_dev->dcb->cos_config_num_max, hw_dcb_cfg->default_cos);
err = hinic3_set_tx_cos_state(nic_dev, dcb_en);
if (err) {
hinic3_err(nic_dev, drv, "Set tx cos state failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- sema_init(&nic_dev->dcb_sem, 1);
-
return 0;
}
-static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dcb_config *dcb_cfg)
+static int change_qos_cfg(struct hinic3_nic_dev *nic_dev,
+ const struct hinic3_dcb_config *dcb_cfg)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err = 0;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags)) {
+ if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags)) {
nicif_warn(nic_dev, drv, netdev,
"Cos_up map setting in inprocess, please try again later\n");
return -EFAULT;
@@ -337,40 +413,44 @@ static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dc
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
- clear_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags);
+ clear_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags);
return err;
}
int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err, rollback_err;
u8 netif_run = 0;
struct hinic3_dcb_config old_dcb_cfg;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- memcpy(&old_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&old_dcb_cfg, &dcb->hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
- if (!memcmp(&nic_dev->wanted_dcb_cfg, &old_dcb_cfg, sizeof(struct hinic3_dcb_config))) {
+ if (!memcmp(&dcb->wanted_dcb_cfg, &old_dcb_cfg,
+ sizeof(struct hinic3_dcb_config))) {
nicif_info(nic_dev, drv, nic_dev->netdev,
"Same valid up bitmap, don't need to change anything\n");
return 0;
}
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = change_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ err = change_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Set cos_up map to hw failed\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Set cos_up map to hw failed\n");
goto change_qos_cfg_fail;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- err = hinic3_setup_cos(nic_dev->netdev, user_cos_num, netif_run);
+ err = hinic3_setup_cos(nic_dev->netdev,
+ user_cos_num, netif_run);
if (err)
goto set_err;
}
@@ -381,13 +461,12 @@ int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
goto vport_up_fail;
}
- rtnl_unlock();
-
return 0;
vport_up_fail:
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_setup_cos(nic_dev->netdev, user_cos_num ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, user_cos_num
+ ? 0 : user_cos_num, netif_run);
set_err:
rollback_err = change_qos_cfg(nic_dev, &old_dcb_cfg);
@@ -399,7 +478,5 @@ change_qos_cfg_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
-
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
index 7987f56..e0b35cb 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
@@ -24,11 +24,6 @@ struct hinic3_tc_cfg {
u16 rsvd;
};
-enum HINIC3_DCB_TRUST {
- DCB_PCP,
- DCB_DSCP,
-};
-
#define PCP_MAX_UP 8
#define DSCP_MAC_UP 64
#define DBG_DFLT_DSCP_VAL 0xFF
@@ -50,6 +45,7 @@ struct hinic3_dcb_config {
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev);
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev);
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev);
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev);
void hinic3_dcb_reset_hw_config(struct hinic3_nic_dev *nic_dev);
int hinic3_configure_dcb(struct net_device *netdev);
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run);
@@ -75,4 +71,5 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos);
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev);
int hinic3_vport_up(struct hinic3_nic_dev *nic_dev);
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
index 2b3561e..548d67d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
@@ -44,9 +44,9 @@ static void hinic3_get_drvinfo(struct net_device *netdev,
u8 mgmt_ver[HINIC3_MGMT_VERSION_MAX_LEN] = {0};
int err;
- strlcpy(info->driver, HINIC3_NIC_DRV_NAME, sizeof(info->driver));
- strlcpy(info->version, HINIC3_NIC_DRV_VERSION, sizeof(info->version));
- strlcpy(info->bus_info, pci_name(pdev), sizeof(info->bus_info));
+ strscpy(info->driver, HINIC3_NIC_DRV_NAME, sizeof(info->driver));
+ strscpy(info->version, HINIC3_NIC_DRV_VERSION, sizeof(info->version));
+ strscpy(info->bus_info, pci_name(pdev), sizeof(info->bus_info));
err = hinic3_get_mgmt_version(nic_dev->hwdev, mgmt_ver,
HINIC3_MGMT_VERSION_MAX_LEN,
@@ -123,10 +123,15 @@ reset_err:
return err;
}
+#ifdef HAVE_ETHTOOL_RINGPARAM_EXTACK
static void hinic3_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring,
struct kernel_ethtool_ringparam *kernel_ring,
struct netlink_ext_ack *extack)
+#else
+static void hinic3_get_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+#endif
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
@@ -176,10 +181,15 @@ static int check_ringparam_valid(struct net_device *netdev,
return 0;
}
+#ifdef HAVE_ETHTOOL_RINGPARAM_EXTACK
static int hinic3_set_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring,
struct kernel_ethtool_ringparam *kernel_ring,
struct netlink_ext_ack *extack)
+#else
+static int hinic3_set_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+#endif
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic3_dyna_txrxq_params q_params = {0};
@@ -273,7 +283,7 @@ static int get_coalesce(struct net_device *netdev,
static int set_queue_coalesce(struct hinic3_nic_dev *nic_dev, u16 q_id,
struct hinic3_intr_coal_info *coal)
{
- struct hinic3_intr_coal_info *intr_coal;
+ struct hinic3_intr_coal_info *intr_coal = NULL;
struct interrupt_info info = {0};
struct net_device *netdev = nic_dev->netdev;
int err;
@@ -367,24 +377,11 @@ static int is_coalesce_exceed_limit(struct net_device *netdev,
return 0;
}
-static int is_coalesce_legal(struct net_device *netdev,
- const struct ethtool_coalesce *coal)
+static int is_coalesce_allowed_change(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct ethtool_coalesce tmp_coal = {0};
- int err;
-
- if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
- nicif_err(nic_dev, drv, netdev,
- "tx-usecs must be equal to rx-usecs\n");
- return -EINVAL;
- }
-
- if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
- nicif_err(nic_dev, drv, netdev,
- "tx-frames must be equal to rx-frames\n");
- return -EINVAL;
- }
tmp_coal.cmd = coal->cmd;
tmp_coal.rx_coalesce_usecs = coal->rx_coalesce_usecs;
@@ -409,6 +406,31 @@ static int is_coalesce_legal(struct net_device *netdev,
return -EOPNOTSUPP;
}
+ return 0;
+}
+
+static int is_coalesce_legal(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-usecs must be equal to rx-usecs\n");
+ return -EINVAL;
+ }
+
+ if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-frames must be equal to rx-frames\n");
+ return -EINVAL;
+ }
+
+ err = is_coalesce_allowed_change(netdev, coal);
+ if (err)
+ return err;
+
err = is_coalesce_exceed_limit(netdev, coal);
if (err)
return err;
@@ -491,19 +513,10 @@ static int set_hw_coal_param(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static int set_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *coal, u16 queue)
+static void check_coalesce_align(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
- struct hinic3_intr_coal_info intr_coal = {0};
- struct hinic3_intr_coal_info *ori_intr_coal = NULL;
- u32 last_adaptive_rx;
- char obj_str[32] = {0};
- int err = 0;
-
- err = is_coalesce_legal(netdev, coal);
- if (err)
- return err;
CHECK_COALESCE_ALIGN(coal, rx_coalesce_usecs, COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal, rx_max_coalesced_frames,
@@ -516,6 +529,14 @@ static int set_coalesce(struct net_device *netdev,
COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal, rx_max_coalesced_frames_low,
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int check_coalesce_change(struct net_device *netdev,
+ u16 queue, struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info *ori_intr_coal = NULL;
+ char obj_str[32] = {0};
if (queue == COALESCE_ALL_QUEUE) {
ori_intr_coal = &nic_dev->intr_coalesce[0];
@@ -524,6 +545,7 @@ static int set_coalesce(struct net_device *netdev,
ori_intr_coal = &nic_dev->intr_coalesce[queue];
snprintf(obj_str, sizeof(obj_str), "for queue %u", queue);
}
+
CHECK_COALESCE_CHANGED(coal, rx_coalesce_usecs, COALESCE_TIMER_CFG_UNIT,
ori_intr_coal->coalesce_timer_cfg, obj_str);
CHECK_COALESCE_CHANGED(coal, rx_max_coalesced_frames,
@@ -545,28 +567,52 @@ static int set_coalesce(struct net_device *netdev,
CHECK_COALESCE_CHANGED(coal, rx_max_coalesced_frames_low,
COALESCE_PENDING_LIMIT_UNIT,
ori_intr_coal->rx_pending_limt_low, obj_str);
+ return 0;
+}
- intr_coal.coalesce_timer_cfg =
+static void init_intr_coal_params(struct hinic3_intr_coal_info *intr_coal,
+ struct ethtool_coalesce *coal)
+{
+ intr_coal->coalesce_timer_cfg =
(u8)(coal->rx_coalesce_usecs / COALESCE_TIMER_CFG_UNIT);
- intr_coal.pending_limt = (u8)(coal->rx_max_coalesced_frames /
- COALESCE_PENDING_LIMIT_UNIT);
+ intr_coal->pending_limt = (u8)(coal->rx_max_coalesced_frames /
+ COALESCE_PENDING_LIMIT_UNIT);
- last_adaptive_rx = nic_dev->adaptive_rx_coal;
- nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
-
- intr_coal.pkt_rate_high = coal->pkt_rate_high;
- intr_coal.rx_usecs_high =
+ intr_coal->pkt_rate_high = coal->pkt_rate_high;
+ intr_coal->rx_usecs_high =
(u8)(coal->rx_coalesce_usecs_high / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_high =
+ intr_coal->rx_pending_limt_high =
(u8)(coal->rx_max_coalesced_frames_high /
COALESCE_PENDING_LIMIT_UNIT);
- intr_coal.pkt_rate_low = coal->pkt_rate_low;
- intr_coal.rx_usecs_low =
+ intr_coal->pkt_rate_low = coal->pkt_rate_low;
+ intr_coal->rx_usecs_low =
(u8)(coal->rx_coalesce_usecs_low / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_low =
+ intr_coal->rx_pending_limt_low =
(u8)(coal->rx_max_coalesced_frames_low /
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal, u16 queue)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info intr_coal = {0};
+ u32 last_adaptive_rx;
+ int err = 0;
+
+ err = is_coalesce_legal(netdev, coal);
+ if (err)
+ return err;
+
+ check_coalesce_align(netdev, coal);
+
+ check_coalesce_change(netdev, queue, coal);
+
+ init_intr_coal_params(&intr_coal, coal);
+
+ last_adaptive_rx = nic_dev->adaptive_rx_coal;
+ nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
/* coalesce timer or pending set to zero will disable coalesce */
if (!nic_dev->adaptive_rx_coal &&
@@ -588,18 +634,28 @@ static int set_coalesce(struct net_device *netdev,
return set_hw_coal_param(nic_dev, &intr_coal, queue);
}
+#ifdef HAVE_ETHTOOL_COALESCE_EXTACK
static int hinic3_get_coalesce(struct net_device *netdev,
struct ethtool_coalesce *coal,
struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack)
+#else
+static int hinic3_get_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
+#endif
{
return get_coalesce(netdev, coal, COALESCE_ALL_QUEUE);
}
+#ifdef HAVE_ETHTOOL_COALESCE_EXTACK
static int hinic3_set_coalesce(struct net_device *netdev,
struct ethtool_coalesce *coal,
struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack)
+#else
+static int hinic3_set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
+#endif
{
return set_coalesce(netdev, coal, COALESCE_ALL_QUEUE);
}
@@ -762,6 +818,14 @@ static int hinic3_get_module_info(struct net_device *netdev,
modinfo->type = ETH_MODULE_SFF_8636;
modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
break;
+ case MODULE_TYPE_DSFP:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
+ case MODULE_TYPE_QSFP_CMIS:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
default:
nicif_warn(nic_dev, drv, netdev,
"Optical module unknown: 0x%x\n", sfp_type);
@@ -784,6 +848,9 @@ static int hinic3_get_module_eeprom(struct net_device *netdev,
memset(data, 0, ee->len);
err = hinic3_get_sfp_eeprom(nic_dev->hwdev, (u8 *)sfp_data, ee->len);
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(nic_dev->hwdev, (u8 *)sfp_data, sizeof(sfp_data));
+
if (err)
return err;
@@ -814,7 +881,7 @@ static u32 hinic3_get_priv_flags(struct net_device *netdev)
return priv_flags;
}
-int hinic3_set_rxq_recovery_flag(struct net_device *netdev, u32 priv_flags)
+static int hinic3_set_rxq_recovery_flag(struct net_device *netdev, u32 priv_flags)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
@@ -844,12 +911,14 @@ static int hinic3_set_symm_rss_flag(struct net_device *netdev, u32 priv_flags)
if (priv_flags & HINIC3_PRIV_FLAGS_SYMM_RSS) {
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, netdev, "Failed to open Symmetric RSS while DCB is enabled\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to open Symmetric RSS while DCB is enabled\n");
return -EOPNOTSUPP;
}
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, netdev, "Failed to open Symmetric RSS while RSS is disabled\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to open Symmetric RSS while RSS is disabled\n");
return -EOPNOTSUPP;
}
@@ -1129,10 +1198,61 @@ static void hinic3_diag_test(struct net_device *netdev,
hinic3_lp_test(netdev, eth_test, data, 0);
}
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+static int hinic3_get_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u8 advertised_fec = 0;
+ u8 supported_fec = 0;
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_GFECPARAM) {
+ nicif_err(nic_dev, drv, netdev,
+ "get fecparam cmd err.exp:0x%x,real:0x%x\n",
+ ETHTOOL_GFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = get_fecparam(nic_dev->hwdev, &advertised_fec, &supported_fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Get fec param failed\n");
+ return err;
+ }
+ fecparam->active_fec = (u32)advertised_fec;
+ fecparam->fec = (u32)supported_fec;
+
+ nicif_info(nic_dev, drv, netdev, "Get fec param success\n");
+ return 0;
+}
+
+static int hinic3_set_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_SFECPARAM) {
+ nicif_err(nic_dev, drv, netdev, "Set fecparam cmd err.exp:0x%x,real:0x%x\n", ETHTOOL_SFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = set_fecparam(nic_dev->hwdev, (u8)fecparam->fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Set fec param failed\n");
+ return err;
+ }
+
+ nicif_info(nic_dev, drv, netdev, "Set fec param success\n");
+ return 0;
+}
+#endif
+
static const struct ethtool_ops hinic3_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1179,6 +1299,11 @@ static const struct ethtool_ops hinic3_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
+
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
@@ -1239,7 +1364,10 @@ static const struct ethtool_ops_ext hinic3_ethtool_ops_ext = {
static const struct ethtool_ops hinic3vf_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1266,6 +1394,11 @@ static const struct ethtool_ops hinic3vf_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
+
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
index de59b76..ec89f62 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
@@ -24,11 +24,24 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
-#define FPGA_PORT_COUNTER 0
-#define EVB_PORT_COUNTER 1
-u16 mag_support_mode = EVB_PORT_COUNTER;
-module_param(mag_support_mode, ushort, 0444);
-MODULE_PARM_DESC(mag_support_mode, "Set mag port counter support mode, 0:FPGA 1:EVB, default is 1");
+#define HINIC_SET_LINK_STR_LEN 128
+#define HINIC_ETHTOOL_FEC_INFO_LEN 6
+#define HINIC_SUPPORTED_FEC_CMD 0
+#define HINIC_ADVERTISED_FEC_CMD 1
+
+struct hinic3_ethtool_fec {
+ u8 hinic_fec_offset;
+ u8 ethtool_bit_offset;
+};
+
+static struct hinic3_ethtool_fec hinic3_ethtool_fec_info[HINIC_ETHTOOL_FEC_INFO_LEN] = {
+ {PORT_FEC_NOT_SET, 0xFF}, /* The ethtool does not have the corresponding enumeration variable */
+ {PORT_FEC_RSFEC, 0x32}, /* ETHTOOL_LINK_MODE_FEC_RS_BIT */
+ {PORT_FEC_BASEFEC, 0x33}, /* ETHTOOL_LINK_MODE_FEC_BASER_BIT */
+ {PORT_FEC_NOFEC, 0x31}, /* ETHTOOL_LINK_MODE_FEC_NONE_BIT */
+ {PORT_FEC_LLRSFEC, 0x4A}, /* ETHTOOL_LINK_MODE_FEC_LLRS_BIT: Available only in later versions */
+ {PORT_FEC_AUTO, 0XFF} /* The ethtool does not have the corresponding enumeration variable */
+};
struct hinic3_stats {
char name[ETH_GSTRING_LEN];
@@ -36,6 +49,20 @@ struct hinic3_stats {
int offset;
};
+struct hinic3_netdev_link_count_str {
+ u64 link_down_events_phy;
+};
+
+#define HINIC3_NETDEV_LINK_COUNT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic3_netdev_link_count_str, _stat_item), \
+ .offset = offsetof(struct hinic3_netdev_link_count_str, _stat_item) \
+}
+
+static struct hinic3_stats hinic3_netdev_link_count[] = {
+ HINIC3_NETDEV_LINK_COUNT(link_down_events_phy),
+};
+
#define HINIC3_NETDEV_STAT(_stat_item) { \
.name = #_stat_item, \
.size = FIELD_SIZEOF(struct rtnl_link_stats64, _stat_item), \
@@ -94,7 +121,6 @@ static struct hinic3_stats hinic3_nic_dev_stats_extern[] = {
.offset = offsetof(struct hinic3_txq_stats, _stat_item) \
}
-/*lint -save -e786*/
static struct hinic3_stats hinic3_rx_queue_stats[] = {
HINIC3_RXQ_STAT(packets),
HINIC3_RXQ_STAT(bytes),
@@ -135,8 +161,6 @@ static struct hinic3_stats hinic3_tx_queue_stats_extern[] = {
HINIC3_TXQ_STAT(rsvd2),
};
-/*lint -restore*/
-
#define HINIC3_FUNC_STAT(_stat_item) { \
.name = #_stat_item, \
.size = FIELD_SIZEOF(struct hinic3_vport_stats, _stat_item), \
@@ -260,49 +284,22 @@ static struct hinic3_stats hinic3_port_stats[] = {
HINIC3_PORT_STAT(mac_rx_unfilter_pkt_num),
};
+#define HINIC3_RSFEC_STAT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct mag_cmd_rsfec_stats, _stat_item), \
+ .offset = offsetof(struct mag_cmd_rsfec_stats, _stat_item) \
+}
+
+static struct hinic3_stats g_hinic3_rsfec_stats[] = {
+ HINIC3_RSFEC_STAT(rx_err_lane_phy),
+};
+
#define HINIC3_FGPA_PORT_STAT(_stat_item) { \
.name = #_stat_item, \
.size = FIELD_SIZEOF(struct hinic3_phy_fpga_port_stats, _stat_item), \
.offset = offsetof(struct hinic3_phy_fpga_port_stats, _stat_item) \
}
-static struct hinic3_stats g_hinic3_fpga_port_stats[] = {
- HINIC3_FGPA_PORT_STAT(mac_rx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_under_frame_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_frag_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_crc_error_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_length_err_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_pause_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_unknown_mac_frame_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_underrun_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_pause_pkts_port),
-};
-
static char g_hinic_priv_flags_strings[][ETH_GSTRING_LEN] = {
"Symmetric-RSS",
"Force-Link-up",
@@ -313,12 +310,12 @@ u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev)
{
u32 count;
- count = ARRAY_LEN(hinic3_nic_dev_stats) +
+ count = (u32)(ARRAY_LEN(hinic3_nic_dev_stats) +
ARRAY_LEN(hinic3_nic_dev_stats_extern) +
(ARRAY_LEN(hinic3_tx_queue_stats) +
ARRAY_LEN(hinic3_tx_queue_stats_extern) +
ARRAY_LEN(hinic3_rx_queue_stats) +
- ARRAY_LEN(hinic3_rx_queue_stats_extern)) * nic_dev->max_qps;
+ ARRAY_LEN(hinic3_rx_queue_stats_extern)) * nic_dev->max_qps);
return count;
}
@@ -342,46 +339,81 @@ u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev)
} \
} while (0)
-#define QUEUE_STATS_PACK(items, item_idx, array, stats_ptr, qid) do { \
- int j; \
- for (j = 0; j < ARRAY_LEN(array); j++) { \
- memcpy((items)[item_idx].name, (array)[j].name, \
- HINIC3_SHOW_ITEM_LEN); \
- snprintf((items)[item_idx].name, HINIC3_SHOW_ITEM_LEN, \
- (array)[j].name, (qid)); \
- (items)[item_idx].hexadecimal = 0; \
- (items)[item_idx].value = \
- GET_VALUE_OF_PTR((array)[j].size, \
- (char *)(stats_ptr) + (array)[j].offset); \
- (item_idx)++; \
- } \
-} while (0)
+int hinic3_rx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat, struct hinic3_rxq_stats *rxq_stats, u16 qid)
+{
+ int ret;
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
+ ret = snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
+ if (ret < 0)
+ return -EINVAL;
+
+ item->hexadecimal = 0;
+ item->value = GET_VALUE_OF_PTR(stat->size, (char *)(rxq_stats) + stat->offset);
+
+ return 0;
+}
+
+int hinic3_tx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat, struct hinic3_txq_stats *txq_stats, u16 qid)
+{
+ int ret;
+
+ ret = snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
+ if (ret < 0)
+ return -EINVAL;
+
+ item->hexadecimal = 0;
+ item->value = GET_VALUE_OF_PTR(stat->size, (char *)(txq_stats) + stat->offset);
+
+ return 0;
+}
+
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
{
struct hinic3_show_item *items = stats;
int item_idx = 0;
u16 qid;
+ int idx;
+ int ret;
DEV_STATS_PACK(items, item_idx, hinic3_nic_dev_stats, &nic_dev->stats);
- DEV_STATS_PACK(items, item_idx, hinic3_nic_dev_stats_extern,
- &nic_dev->stats);
+ DEV_STATS_PACK(items, item_idx, hinic3_nic_dev_stats_extern, &nic_dev->stats);
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- QUEUE_STATS_PACK(items, item_idx, hinic3_tx_queue_stats,
- &nic_dev->txqs[qid].txq_stats, qid);
- QUEUE_STATS_PACK(items, item_idx, hinic3_tx_queue_stats_extern,
- &nic_dev->txqs[qid].txq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++], &hinic3_tx_queue_stats[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats_extern); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++], &hinic3_tx_queue_stats_extern[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
}
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- QUEUE_STATS_PACK(items, item_idx, hinic3_rx_queue_stats,
- &nic_dev->rxqs[qid].rxq_stats, qid);
- QUEUE_STATS_PACK(items, item_idx, hinic3_rx_queue_stats_extern,
- &nic_dev->rxqs[qid].rxq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++], &hinic3_rx_queue_stats[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats_extern); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++], &hinic3_rx_queue_stats_extern[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
}
-}
+ return 0;
+}
static char g_hinic3_test_strings[][ETH_GSTRING_LEN] = {
"Internal lb test (on/offline)",
"External lb test (external_lb)",
@@ -398,16 +430,15 @@ int hinic3_get_sset_count(struct net_device *netdev, int sset)
case ETH_SS_STATS:
q_num = nic_dev->q_params.num_qps;
count = ARRAY_LEN(hinic3_netdev_stats) +
- ARRAY_LEN(hinic3_nic_dev_stats) +
+ ARRAY_LEN(hinic3_nic_dev_stats) +
+ ARRAY_LEN(hinic3_netdev_link_count) +
ARRAY_LEN(hinic3_function_stats) +
(ARRAY_LEN(hinic3_tx_queue_stats) +
ARRAY_LEN(hinic3_rx_queue_stats)) * q_num;
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER)
- count += ARRAY_LEN(g_hinic3_fpga_port_stats);
- else
- count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(g_hinic3_rsfec_stats);
}
return count;
@@ -452,9 +483,9 @@ static void get_drv_queue_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
}
}
-static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct hinic3_phy_fpga_port_stats *port_stats = NULL;
+ struct mag_cmd_port_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
@@ -464,19 +495,19 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to malloc port stats\n");
memset(&data[i], 0,
- ARRAY_LEN(g_hinic3_fpga_port_stats) * sizeof(*data));
- i += ARRAY_LEN(g_hinic3_fpga_port_stats);
+ ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
+ i += ARRAY_LEN(hinic3_port_stats);
return i;
}
- err = hinic3_get_fpga_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to get port stats from fw\n");
- for (j = 0; j < ARRAY_LEN(g_hinic3_fpga_port_stats); j++, i++) {
- p = (char *)(port_stats) + g_hinic3_fpga_port_stats[j].offset;
- data[i] = (g_hinic3_fpga_port_stats[j].size ==
+ for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
+ p = (char *)(port_stats) + hinic3_port_stats[j].offset;
+ data[i] = (hinic3_port_stats[j].size ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
@@ -485,35 +516,32 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
return i;
}
-static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_rsfec_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct mag_cmd_port_stats *port_stats = NULL;
+ struct mag_cmd_rsfec_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
- if (mag_support_mode == FPGA_PORT_COUNTER)
- return get_fpga_port_stats(nic_dev, data);
-
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
if (!port_stats) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to malloc port stats\n");
memset(&data[i], 0,
- ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
- i += ARRAY_LEN(hinic3_port_stats);
+ ARRAY_LEN(g_hinic3_rsfec_stats) * sizeof(*data));
+ i += ARRAY_LEN(g_hinic3_rsfec_stats);
return i;
- }
+ }
- err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_rsfec_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to get port stats from fw\n");
+ "Failed to get rsfec stats from fw\n");
- for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
- p = (char *)(port_stats) + hinic3_port_stats[j].offset;
- data[i] = (hinic3_port_stats[j].size ==
- sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+ for (j = 0; j < ARRAY_LEN(g_hinic3_rsfec_stats); j++, i++) {
+ p = (char *)(port_stats) + g_hinic3_rsfec_stats[j].offset;
+ data[i] = (g_hinic3_rsfec_stats[j].size ==
+ sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
kfree(port_stats);
@@ -537,6 +565,8 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
u16 i = 0, j = 0;
char *p = NULL;
int err;
+ int link_down_events_phy_tmp = 0;
+ struct hinic3_netdev_link_count_str link_count = {0};
#ifdef HAVE_NDO_GET_STATS64
net_stats = dev_get_stats(netdev, &temp);
@@ -554,6 +584,14 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = GET_VALUE_OF_PTR(hinic3_nic_dev_stats[j].size, p);
}
+ err = hinic3_get_link_event_stats(nic_dev->hwdev, &link_down_events_phy_tmp);
+
+ link_count.link_down_events_phy = (u64)link_down_events_phy_tmp;
+ for (j = 0; j < ARRAY_LEN(hinic3_netdev_link_count); j++, i++) {
+ p = (char *)(&link_count) + hinic3_netdev_link_count[j].offset;
+ data[i] = GET_VALUE_OF_PTR(hinic3_netdev_link_count[j].size, p);
+ }
+
err = hinic3_get_vport_stats(nic_dev->hwdev, hinic3_global_func_id(nic_dev->hwdev),
&vport_stats);
if (err)
@@ -565,8 +603,10 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = GET_VALUE_OF_PTR(hinic3_function_stats[j].size, p);
}
- if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
i += get_ethtool_port_stats(nic_dev, data + i);
+ i += get_ethtool_rsfec_stats(nic_dev, data + i);
+ }
get_drv_queue_stats(nic_dev, data + i);
}
@@ -588,6 +628,12 @@ static u16 get_drv_dev_strings(struct hinic3_nic_dev *nic_dev, char *p)
cnt++;
}
+ for (i = 0; i < ARRAY_LEN(hinic3_netdev_link_count); i++) {
+ memcpy(p, hinic3_netdev_link_count[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+
return cnt;
}
@@ -603,18 +649,16 @@ static u16 get_hw_stats_strings(struct hinic3_nic_dev *nic_dev, char *p)
}
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER) {
- for (i = 0; i < ARRAY_LEN(g_hinic3_fpga_port_stats); i++) {
- memcpy(p, g_hinic3_fpga_port_stats[i].name, ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
- } else {
- for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
- memcpy(p, hinic3_port_stats[i].name, ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
+ for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
+ memcpy(p, hinic3_port_stats[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+ for (i = 0; i < ARRAY_LEN(g_hinic3_rsfec_stats); i++) {
+ memcpy(p, g_hinic3_rsfec_stats[i].name,
+ ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
}
}
@@ -758,7 +802,6 @@ struct hw2ethtool_link_mode {
u32 speed;
};
-/*lint -save -e26 */
static const struct hw2ethtool_link_mode
hw2ethtool_link_mode_table[LINK_MODE_MAX_NUMBERS] = {
[LINK_MODE_GE] = {
@@ -818,8 +861,6 @@ static const struct hw2ethtool_link_mode
},
};
-/*lint -restore */
-
#define GET_SUPPORTED_MODE 0
#define GET_ADVERTISED_MODE 1
@@ -838,29 +879,33 @@ struct cmd_link_settings {
#define ETHTOOL_ADD_ADVERTISED_LINK_MODE(ecmd, mode) \
set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->advertising)
-#define ETHTOOL_ADD_SUPPORTED_SPEED_LINK_MODE(ecmd, mode) \
-do { \
- u32 i; \
- for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) { \
- if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >= \
- __ETHTOOL_LINK_MODE_MASK_NBITS) \
- continue; \
- set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i], \
- (ecmd)->supported); \
- } \
-} while (0)
+static void ethtool_add_supported_speed_link_mode(struct cmd_link_settings *link_settings,
+ u32 mode)
+{
+ u32 i;
-#define ETHTOOL_ADD_ADVERTISED_SPEED_LINK_MODE(ecmd, mode) \
-do { \
- u32 i; \
- for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) { \
- if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >= \
- __ETHTOOL_LINK_MODE_MASK_NBITS) \
- continue; \
- set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i], \
- (ecmd)->advertising); \
- } \
-} while (0)
+ for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
+ if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
+ continue;
+ set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
+ link_settings->supported);
+ }
+}
+
+static void ethtool_add_advertised_speed_link_mode(struct cmd_link_settings *link_settings,
+ u32 mode)
+{
+ u32 i;
+
+ for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
+ if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
+ continue;
+ set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
+ link_settings->advertising);
+ }
+}
/* Related to enum mag_cmd_port_speed */
static u32 hw_to_ethtool_speed[] = {
@@ -888,11 +933,11 @@ static void hinic3_add_ethtool_link_mode(struct cmd_link_settings *link_settings
for (link_mode = 0; link_mode < LINK_MODE_MAX_NUMBERS; link_mode++) {
if (hw_link_mode & BIT(link_mode)) {
if (name == GET_SUPPORTED_MODE)
- ETHTOOL_ADD_SUPPORTED_SPEED_LINK_MODE
- (link_settings, link_mode);
+ ethtool_add_supported_speed_link_mode(
+ link_settings, link_mode);
else
- ETHTOOL_ADD_ADVERTISED_SPEED_LINK_MODE
- (link_settings, link_mode);
+ ethtool_add_advertised_speed_link_mode(
+ link_settings, link_mode);
}
}
}
@@ -915,10 +960,15 @@ static int hinic3_link_speed_set(struct hinic3_nic_dev *nic_dev,
err = hinic3_get_link_state(nic_dev->hwdev, &link_state);
if (!err && link_state) {
- link_settings->speed =
- port_info->speed < ARRAY_LEN(hw_to_ethtool_speed) ?
- hw_to_ethtool_speed[port_info->speed] :
- (u32)SPEED_UNKNOWN;
+ if (hinic3_get_bond_create_mode(nic_dev->hwdev)) {
+ link_settings->speed = port_info->bond_speed;
+ } else {
+ link_settings->speed =
+ port_info->speed <
+ ARRAY_LEN(hw_to_ethtool_speed) ?
+ hw_to_ethtool_speed[port_info->speed] :
+ (u32)SPEED_UNKNOWN;
+ }
link_settings->duplex = port_info->duplex;
} else {
@@ -993,6 +1043,39 @@ static int get_link_pause_settings(struct hinic3_nic_dev *nic_dev,
return 0;
}
+static bool is_bit_offset_defined(u8 bit_offset)
+{
+ if (bit_offset < __ETHTOOL_LINK_MODE_MASK_NBITS)
+ return true;
+ return false;
+}
+
+static void
+ethtool_add_supported_advertised_fec(struct cmd_link_settings *link_settings,
+ u32 fec, u8 cmd)
+{
+ u8 i;
+ for (i = 0; i < HINIC_ETHTOOL_FEC_INFO_LEN; i++) {
+ if ((fec & BIT(hinic3_ethtool_fec_info[i].hinic_fec_offset)) == 0)
+ continue;
+ if ((is_bit_offset_defined(hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true) &&
+ (cmd == HINIC_ADVERTISED_FEC_CMD)) {
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset, link_settings->advertising);
+ return; /* There can be only one advertised fec mode. */
+ }
+ if ((is_bit_offset_defined(hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true) &&
+ (cmd == HINIC_SUPPORTED_FEC_CMD))
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset, link_settings->supported);
+ }
+}
+
+static void hinic3_link_fec_type(struct cmd_link_settings *link_settings,
+ u32 fec, u32 supported_fec)
+{
+ ethtool_add_supported_advertised_fec(link_settings, supported_fec, HINIC_SUPPORTED_FEC_CMD);
+ ethtool_add_supported_advertised_fec(link_settings, fec, HINIC_ADVERTISED_FEC_CMD);
+}
+
static int get_link_settings(struct net_device *netdev,
struct cmd_link_settings *link_settings)
{
@@ -1013,6 +1096,9 @@ static int get_link_settings(struct net_device *netdev,
hinic3_link_port_type(link_settings, port_info.port_type);
+ hinic3_link_fec_type(link_settings, BIT(port_info.fec),
+ port_info.supported_fec_mode);
+
link_settings->autoneg = port_info.autoneg_state == PORT_CFG_AN_ON ?
AUTONEG_ENABLE : AUTONEG_DISABLE;
if (port_info.autoneg_cap)
@@ -1138,10 +1224,11 @@ static int hinic3_set_settings_to_hw(struct hinic3_nic_dev *nic_dev,
struct net_device *netdev = nic_dev->netdev;
struct hinic3_link_ksettings settings = {0};
int speed_level = 0;
- char set_link_str[128] = {0};
+ char set_link_str[HINIC_SET_LINK_STR_LEN] = {0};
+ char link_info[HINIC_SET_LINK_STR_LEN] = {0};
int err = 0;
- err = snprintf(set_link_str, sizeof(set_link_str) - 1, "%s",
+ err = snprintf(link_info, sizeof(link_info), "%s",
(bool)(set_settings & HILINK_LINK_SET_AUTONEG) ?
((bool)autoneg ? "autong enable " : "autong disable ") : "");
if (err < 0)
@@ -1149,8 +1236,8 @@ static int hinic3_set_settings_to_hw(struct hinic3_nic_dev *nic_dev,
if (set_settings & HILINK_LINK_SET_SPEED) {
speed_level = hinic3_ethtool_to_hw_speed_level(speed);
- err = snprintf(set_link_str, sizeof(set_link_str) - 1,
- "%sspeed %u ", set_link_str, speed);
+ err = snprintf(set_link_str, sizeof(set_link_str),
+ "%sspeed %u ", link_info, speed);
if (err < 0)
return -EINVAL;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
index 70346d6..2daa7f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
@@ -82,7 +82,7 @@ static struct hinic3_mac_filter *hinic3_add_filter(struct hinic3_nic_dev *nic_de
struct list_head *mac_filter_list,
u8 *addr)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
@@ -117,7 +117,7 @@ static void hinic3_del_filter(struct hinic3_nic_dev *nic_dev,
static struct hinic3_mac_filter *hinic3_mac_filter_entry_clone(const struct hinic3_mac_filter *src)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
index ef8c62b..7fed1c1 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
@@ -40,6 +40,7 @@ enum hinic3_channel_id {
HINIC3_CHANNEL_DSW,
HINIC3_CHANNEL_MIG,
HINIC3_CHANNEL_CRYPT,
+ HINIC3_CHANNEL_VROCE,
HINIC3_CHANNEL_MAX = 32,
};
@@ -398,6 +399,16 @@ void hinic3_free_cmd_buf(void *hwdev, struct hinic3_cmd_buf *cmd_buf);
int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read clear
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+
+/**
* @brief hinic3_sm_ctr_rd32 - small single 32 counter read
* @param hwdev: device pointer to hwdev
* @param node: the node id
@@ -811,6 +822,13 @@ int hinic3_dbg_lt_wr_16byte_mask(void *hwdev, u8 dest, u8 instance,
void hinic3_link_event_stats(void *dev, u8 link);
/**
+ * @brief hinic3_get_link_event_stats - link event stats
+ * @param hwdev: device pointer to hwdev
+ * @param link: link status
+ */
+int hinic3_get_link_event_stats(void *dev, int *link_state);
+
+/**
* @brief hinic3_get_hw_pf_infos - get pf infos
* @param hwdev: device pointer to hwdev
* @param infos: pf infos
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
index 3c835ff..7a2644c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
@@ -12,6 +12,7 @@
#include <linux/netdevice.h>
#include <linux/debugfs.h>
+#include "ossl_knl.h"
#include "hinic3_hw.h"
#include "hinic3_crm.h"
#include "hinic3_nic_io.h"
@@ -47,12 +48,16 @@ static void qp_add_napi(struct hinic3_irq *irq_cfg)
netif_napi_add(nic_dev->netdev, &irq_cfg->napi,
hinic3_poll, nic_dev->poll_weight);
napi_enable(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_IS_REGIN;
}
-static void qp_del_napi(struct hinic3_irq *irq_cfg)
+void qp_del_napi(struct hinic3_irq *irq_cfg)
{
- napi_disable(&irq_cfg->napi);
- netif_napi_del(&irq_cfg->napi);
+ if (irq_cfg->napi_reign == NAPI_IS_REGIN) {
+ napi_disable(&irq_cfg->napi);
+ netif_napi_del(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_NOT_REGIN;
+ }
}
static irqreturn_t qp_irq(int irq, void *data)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
deleted file mode 100644
index 2482c5f..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_LLD_H
-#define HINIC3_LLD_H
-
-#include "hinic3_crm.h"
-
-struct hinic3_lld_dev {
- struct pci_dev *pdev;
- void *hwdev;
-};
-
-struct hinic3_uld_info {
- /* When the function does not need to initialize the corresponding uld,
- * @probe needs to return 0 and uld_dev is set to NULL;
- * if uld_dev is NULL, @remove will not be called when uninstalling
- */
- int (*probe)(struct hinic3_lld_dev *lld_dev, void **uld_dev, char *uld_dev_name);
- void (*remove)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- int (*suspend)(struct hinic3_lld_dev *lld_dev, void *uld_dev, pm_message_t state);
- int (*resume)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- void (*event)(struct hinic3_lld_dev *lld_dev, void *uld_dev,
- struct hinic3_event_info *event);
- int (*ioctl)(void *uld_dev, u32 cmd, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size);
-};
-
-/* hinic3_register_uld - register an upper-layer driver
- * @type: uld service type
- * @uld_info: uld callback
- *
- * Registers an upper-layer driver.
- * Traverse existing devices and call @probe to initialize the uld device.
- */
-int hinic3_register_uld(enum hinic3_service_type type, struct hinic3_uld_info *uld_info);
-
-/**
- * hinic3_unregister_uld - unregister an upper-layer driver
- * @type: uld service type
- *
- * Traverse existing devices and call @remove to uninstall the uld device.
- * Unregisters an existing upper-layer driver.
- */
-void hinic3_unregister_uld(enum hinic3_service_type type);
-
-void lld_hold(void);
-void lld_put(void);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_name - get lld device by chip name
- * @param chip_name: chip name
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_name(const char *chip_name);
-
-/**
- * @brief lld_dev_hold - get reference to lld_dev
- * @param dev: lld device
- *
- * Hold reference to device to keep it from being freed
- **/
-void lld_dev_hold(struct hinic3_lld_dev *dev);
-
-/**
- * @brief lld_dev_put - release reference to lld_dev
- * @param dev: lld device
- *
- * Release reference to device to allow it to be freed
- **/
-void lld_dev_put(struct hinic3_lld_dev *dev);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name_unsafe - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * hinic3_get_lld_dev_by_dev_name_unsafe() is completely analogous to
- * hinic3_get_lld_dev_by_dev_name(), The only difference is that the reference
- * of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that lld_dev will not be freed during the remove process
- * when using lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name_unsafe(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_and_port - get lld device by chip name and port id
- * @param chip_name: chip name
- * @param port_id: port id
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name, u8 port_id);
-
-/**
- * @brief hinic3_get_ppf_lld_dev - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief hinic3_get_ppf_lld_dev_unsafe - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * hinic3_get_ppf_lld_dev_unsafe() is completely analogous to hinic3_get_ppf_lld_dev(),
- * The only difference is that the reference of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that ppf's lld_dev will not be freed during the remove process
- * when using ppf lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev_unsafe(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief uld_dev_hold - get reference to uld_dev
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * Hold reference to uld device to keep it from being freed
- **/
-void uld_dev_hold(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief uld_dev_put - release reference to lld_dev
- * @param dev: lld device
- * @param type: uld service type
- *
- * Release reference to uld device to allow it to be freed
- **/
-void uld_dev_put(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * The value of uld_dev reference increases when uld_dev is obtained. The caller needs
- * to release the reference by calling uld_dev_put.
- **/
-void *hinic3_get_uld_dev(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev_unsafe - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * hinic3_get_uld_dev_unsafe() is completely analogous to hinic3_get_uld_dev(),
- * The only difference is that the reference of uld_dev is not increased when uld_dev is obtained.
- *
- * The caller must ensure that uld_dev will not be freed during the remove process
- * when using uld_dev.
- **/
-void *hinic3_get_uld_dev_unsafe(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_chip_name - get chip name by lld device
- * @param lld_dev: lld device
- * @param chip_name: String for storing the chip name
- * @param max_len: Maximum number of characters to be copied for chip_name
- **/
-int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len);
-
-struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev);
-
-struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev);
-
-bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service);
-
-int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
- bool vf_srv_load);
-
-int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id,
- u16 service, bool en);
-
-bool hinic3_get_vf_load_state(struct pci_dev *pdev);
-
-int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state);
-
-int hinic3_attach_nic(struct hinic3_lld_dev *lld_dev);
-
-void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
-
-int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-const char **hinic3_get_uld_names(void);
-int hinic3_lld_init(void);
-void hinic3_lld_exit(void);
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
index 2fe808b..8cd891e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
@@ -17,12 +17,22 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_hw.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_common.h"
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
+#define CAP_INFO_MAX_LEN 512
+#define DEVICE_VENDOR_MAX_LEN 17
+#define READ_RSFEC_REGISTER_DELAY_TIME_MS 500
+
+struct parse_tlv_info g_page_info = {0};
+struct drv_mag_cmd_get_xsfp_tlv_rsp g_xsfp_tlv_info = {0};
+
static int mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
static int mag_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in,
@@ -78,8 +88,10 @@ int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats)
return -ENOMEM;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
memset(&stats_info, 0, sizeof(stats_info));
stats_info.port_id = hinic3_physical_port_id(hwdev);
@@ -104,6 +116,64 @@ out:
}
EXPORT_SYMBOL(hinic3_get_phy_port_stats);
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats)
+{
+ struct mag_cmd_get_mag_cnt *port_stats = NULL;
+ struct mag_cmd_get_mag_cnt stats_info;
+ u16 out_size = sizeof(*port_stats);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !stats)
+ return -EINVAL;
+
+ port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
+ if (!port_stats)
+ return -ENOMEM;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ memset(&stats_info, 0, sizeof(stats_info));
+ stats_info.port_id = hinic3_physical_port_id(hwdev);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT,
+ &stats_info, sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+ /* 读2遍, 清除误码残留 */
+ msleep(READ_RSFEC_REGISTER_DELAY_TIME_MS);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT, &stats_info,
+ sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+
+ memcpy(stats, &port_stats->mag_csr[MAG_RX_RSFEC_ERR_CW_CNT],
+ sizeof(u32));
+
+out:
+ kfree(port_stats);
+
+ return err;
+}
+EXPORT_SYMBOL(hinic3_get_phy_rsfec_stats);
+
int hinic3_set_port_funcs_state(void *hwdev, bool enable)
{
return 0;
@@ -180,6 +250,8 @@ int hinic3_get_loopback_mode(void *hwdev, u8 *mode, u8 *enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_cfg_loopback_mode(nic_io, MGMT_MSG_CMD_OP_GET, mode,
enable);
@@ -195,6 +267,8 @@ int hinic3_set_loopback_mode(void *hwdev, u8 mode, u8 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) {
nic_err(nic_io->dev_hdl, "Invalid loopback mode %u to set\n",
@@ -218,6 +292,9 @@ int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&led_info, 0, sizeof(led_info));
led_info.function_id = hinic3_global_func_id(hwdev);
@@ -249,6 +326,8 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
memset(&port_msg, 0, sizeof(port_msg));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
port_msg.port_id = hinic3_physical_port_id(hwdev);
@@ -268,9 +347,12 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
port_info->port_type = port_msg.wire_type;
port_info->speed = port_msg.speed;
port_info->fec = port_msg.fec;
+ port_info->lanes = port_msg.lanes;
port_info->supported_mode = port_msg.supported_mode;
port_info->advertised_mode = port_msg.advertised_mode;
-
+ port_info->supported_fec_mode = port_msg.supported_fec_mode;
+ /* switch Gbps to Mbps */
+ port_info->bond_speed = (u32)port_msg.bond_speed * RATE_MBPS_TO_GBPS;
return 0;
}
@@ -306,6 +388,8 @@ int hinic3_set_link_settings(void *hwdev,
memset(&info, 0, sizeof(info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
info.port_id = hinic3_physical_port_id(hwdev);
info.config_bitmap = settings->valid_bitmap;
@@ -335,6 +419,8 @@ int hinic3_get_link_state(void *hwdev, u8 *link_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&get_link, 0, sizeof(get_link));
get_link.port_id = hinic3_physical_port_id(hwdev);
@@ -364,9 +450,10 @@ void hinic3_notify_vf_link_status(struct hinic3_nic_io *nic_io,
if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
link.status = link_status;
link.port_id = hinic3_physical_port_id(nic_io->hwdev);
- err = hinic3_mbox_to_vf(nic_io->hwdev, vf_id, HINIC3_MOD_HILINK,
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
MAG_CMD_GET_LINK_STATUS, &link,
- sizeof(link), &link, &out_size, 0,
+ sizeof(link), &link, &out_size,
HINIC3_CHANNEL_NIC);
if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
@@ -387,6 +474,9 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
u16 i;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
+
nic_io->link_status = link_status;
for (i = 1; i <= nic_io->max_vfs; i++) {
if (!nic_io->vf_infos[HW_VF_ID_TO_OS(i)].link_forced)
@@ -394,6 +484,167 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
}
}
+static char *g_hw_to_char_fec[HILINK_FEC_MAX_TYPE] = {
+ "not set", "rsfec", "basefec",
+ "nofec", "llrsfec"};
+static char *g_hw_to_speed_info[PORT_SPEED_UNKNOWN] = {
+ "not set", "10MB", "100MB", "1GB", "10GB",
+ "25GB", "40GB", "50GB", "100GB", "200GB"};
+static char *g_hw_to_an_state_info[PORT_CFG_AN_OFF + 1] = {
+ "not set", "on", "off"};
+
+struct port_type_table {
+ u32 port_type;
+ char *port_type_name;
+};
+
+static const struct port_type_table port_optical_type_table_s[] = {
+ {LINK_PORT_UNKNOWN, "UNKNOWN"},
+ {LINK_PORT_OPTICAL_MM, "optical_sr"},
+ {LINK_PORT_OPTICAL_SM, "optical_lr"},
+ {LINK_PORT_PAS_COPPER, "copper"},
+ {LINK_PORT_ACC, "ACC"},
+ {LINK_PORT_BASET, "baset"},
+ {LINK_PORT_AOC, "AOC"},
+ {LINK_PORT_ELECTRIC, "electric"},
+ {LINK_PORT_BACKBOARD_INTERFACE, "interface"},
+};
+
+static char *get_port_type_name(u32 type)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(port_optical_type_table_s); i++) {
+ if (type == port_optical_type_table_s[i].port_type)
+ return port_optical_type_table_s[i].port_type_name;
+ }
+ return "UNKNOWN TYPE";
+}
+
+static void get_port_type(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ char **port_type)
+{
+ if (info->port_type <= LINK_PORT_BACKBOARD_INTERFACE)
+ *port_type = get_port_type_name(info->port_type);
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown port type: %u\n",
+ info->port_type);
+}
+
+static int get_port_temperature_power(struct mag_cmd_event_port_info *info,
+ char *str)
+{
+ char cap_info[CAP_INFO_MAX_LEN];
+
+ memset(cap_info, 0, sizeof(cap_info));
+ snprintf(cap_info, CAP_INFO_MAX_LEN, "%s, %s, Temperature: %u", str,
+ info->sfp_type ? "QSFP" : "SFP", info->cable_temp);
+
+ if (info->sfp_type)
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuw %uuW %uuW %uuW",
+ cap_info, info->power[0x0], info->power[0x1],
+ info->power[0x2], info->power[0x3]);
+ else
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuW, tx power: %uuW",
+ cap_info, info->power[0x0], info->power[0x1]);
+
+ return 0;
+}
+
+static void print_cable_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info)
+{
+ char tmp_str[CAP_INFO_MAX_LEN] = {0};
+ char tmp_vendor[DEVICE_VENDOR_MAX_LEN] = {0};
+ char *port_type = "Unknown port type";
+ int i;
+ int err = 0;
+
+ if (info->gpio_insert) {
+ sdk_info(nic_io->dev_hdl, "Cable unpresent\n");
+ return;
+ }
+
+ get_port_type(nic_io, info, &port_type);
+
+ for (i = sizeof(info->vendor_name) - 1; i >= 0; i--) {
+ if (info->vendor_name[i] == ' ')
+ info->vendor_name[i] = '\0';
+ else
+ break;
+ }
+
+ memcpy(tmp_vendor, info->vendor_name, sizeof(info->vendor_name));
+ snprintf(tmp_str, CAP_INFO_MAX_LEN, "Vendor: %s, %s, length: %um, max_speed: %uGbps",
+ tmp_vendor, port_type, info->cable_length, info->max_speed);
+
+ if (info->port_type == LINK_PORT_OPTICAL_MM ||
+ info->port_type == LINK_PORT_AOC) {
+ err = get_port_temperature_power(info, tmp_str);
+ if (err)
+ return;
+ }
+
+ sdk_info(nic_io->dev_hdl, "Cable information: %s\n", tmp_str);
+}
+
+static void print_link_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ enum hinic3_nic_event_type type)
+{
+ char *fec = "None";
+ char *speed = "None";
+ char *an_state = "None";
+
+ if (info->fec < HILINK_FEC_MAX_TYPE)
+ fec = g_hw_to_char_fec[info->fec];
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown fec type: %u\n", info->fec);
+
+ if (info->an_state > PORT_CFG_AN_OFF) {
+ sdk_info(nic_io->dev_hdl, "an_state %u is invalid",
+ info->an_state);
+ return;
+ }
+
+ an_state = g_hw_to_an_state_info[info->an_state];
+
+ if (info->speed >= PORT_SPEED_UNKNOWN) {
+ sdk_info(nic_io->dev_hdl, "speed %u is invalid", info->speed);
+ return;
+ }
+
+ speed = g_hw_to_speed_info[info->speed];
+ sdk_info(nic_io->dev_hdl, "Link information: speed %s, %s, autoneg %s",
+ speed, fec, an_state);
+}
+
+void print_port_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *port_info,
+ enum hinic3_nic_event_type type)
+{
+ print_cable_info(nic_io, port_info);
+
+ print_link_info(nic_io, port_info, type);
+
+ if (type == EVENT_NIC_LINK_UP)
+ return;
+
+ sdk_info(nic_io->dev_hdl, "PMA ctrl: %s, tx %s, rx %s, PMA fifo reg: 0x%x, PMA signal ok reg: 0x%x, RF/LF status reg: 0x%x\n",
+ port_info->pma_ctrl == 1 ? "off" : "on",
+ port_info->tx_enable ? "enable" : "disable",
+ port_info->rx_enable ? "enable" : "disable", port_info->pma_fifo_reg,
+ port_info->pma_signal_ok_reg, port_info->rf_lf);
+ sdk_info(nic_io->dev_hdl, "alos: %u, rx_los: %u, PCS 64 66b reg: 0x%x, PCS link: 0x%x, MAC link: 0x%x PCS_err_cnt: 0x%x\n",
+ port_info->alos, port_info->rx_los, port_info->pcs_64_66b_reg,
+ port_info->pcs_link, port_info->pcs_mac_link,
+ port_info->pcs_err_cnt);
+ sdk_info(nic_io->dev_hdl, "his_link_machine_state = 0x%08x, cur_link_machine_state = 0x%08x\n",
+ port_info->his_link_machine_state,
+ port_info->cur_link_machine_state);
+}
+
static int hinic3_get_vf_link_status_msg_handler(struct hinic3_nic_io *nic_io,
u16 vf_id, void *buf_in,
u16 in_size, void *buf_out,
@@ -433,6 +684,10 @@ static void get_port_info(void *hwdev,
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (hinic3_func_type(hwdev) != TYPE_VF && link_status->status) {
err = hinic3_get_port_info(hwdev, &port_info, HINIC3_CHANNEL_NIC);
if (err) {
@@ -457,8 +712,17 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
struct hinic3_event_info event_info = {0};
struct hinic3_event_link_info *link_info = (void *)event_info.event_data;
struct hinic3_nic_io *nic_io = NULL;
+ struct pci_dev *pdev = NULL;
+
+ /* Ignore link change event */
+ if (hinic3_is_bm_slave_host(hwdev))
+ return;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
link_status = buf_in;
sdk_info(nic_io->dev_hdl, "Link status report received, func_id: %u, status: %u\n",
@@ -475,6 +739,13 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
hinic3_event_callback(hwdev, &event_info);
+ if (nic_io->pcidev_hdl != NULL) {
+ pdev = nic_io->pcidev_hdl;
+ if (pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID) {
+ return;
+ }
+ }
+
if (hinic3_func_type(hwdev) != TYPE_VF) {
hinic3_notify_all_vfs_link_changed(hwdev, link_status->status);
ret_link_status = buf_out;
@@ -483,20 +754,142 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
}
}
+static void port_info_event_printf(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_event_port_info *port_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info;
+ enum hinic3_nic_event_type type;
+
+ if (!hwdev) {
+ pr_err("hwdev is NULL\n");
+ return;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ if (in_size != sizeof(*port_info)) {
+ sdk_info(nic_io->dev_hdl, "Invalid port info message size %u, should be %lu\n",
+ in_size, sizeof(*port_info));
+ return;
+ }
+
+ ((struct mag_cmd_event_port_info *)buf_out)->head.status = 0;
+
+ type = port_info->event_type;
+ if (type < EVENT_NIC_LINK_DOWN || type > EVENT_NIC_LINK_UP) {
+ sdk_info(nic_io->dev_hdl, "Invalid hilink info report, type: %d\n",
+ type);
+ return;
+ }
+
+ print_port_info(nic_io, port_info, type);
+
+ memset(&event_info, 0, sizeof(event_info));
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = type;
+
+ *out_size = sizeof(*port_info);
+
+ hinic3_event_callback(hwdev, &event_info);
+}
+
+void hinic3_notify_vf_bond_status(struct hinic3_nic_io *nic_io,
+ u16 vf_id, u8 bond_status)
+{
+ struct mag_cmd_get_bond_status bond;
+ struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ u16 out_size = sizeof(bond);
+ int err;
+
+ memset(&bond, 0, sizeof(bond));
+ if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
+ bond.status = bond_status;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
+ MAG_CMD_GET_BOND_STATUS, &bond,
+ sizeof(bond), &bond, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF %hu not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return;
+ }
+ if (err || !out_size || bond.head.status)
+ nic_err(nic_io->dev_hdl,
+ "Send bond change event to VF %hu failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err, bond.head.status,
+ out_size);
+ }
+}
+
+void hinic3_notify_all_vfs_bond_changed(void *hwdev, u8 bond_status)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 i;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ nic_io->link_status = bond_status;
+ for (i = 1; i <= nic_io->max_vfs; i++)
+ hinic3_notify_vf_bond_status(nic_io, i, bond_status);
+}
+
+static void bond_status_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_get_bond_status *bond_status = NULL;
+ struct hinic3_event_info event_info = {};
+ struct hinic3_nic_io *nic_io = NULL;
+ struct mag_cmd_get_bond_status *ret_bond_status = NULL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+
+ bond_status = (struct mag_cmd_get_bond_status *)buf_in;
+ sdk_info(nic_io->dev_hdl, "bond status report received, func_id: %u, status: %u\n",
+ hinic3_global_func_id(hwdev), bond_status->status);
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = bond_status->status ?
+ EVENT_NIC_BOND_UP : EVENT_NIC_BOND_DOWN;
+
+ hinic3_event_callback(hwdev, &event_info);
+
+ if (hinic3_func_type(hwdev) != TYPE_VF) {
+ hinic3_notify_all_vfs_bond_changed(hwdev, bond_status->status);
+ ret_bond_status = buf_out;
+ ret_bond_status->head.status = 0;
+ *out_size = sizeof(*ret_bond_status);
+ }
+}
+
static void cable_plug_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct mag_cmd_wire_event *plug_event = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_event_info event_info;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
rt_cmd->mpu_send_sfp_abs = false;
rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
memset(&event_info, 0, sizeof(event_info));
@@ -518,20 +911,54 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
{
struct mag_cmd_get_xsfp_info *sfp_info = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_info)) {
- sdk_err(nic_io->dev_hdl, "Invalid sfp info cmd, length: %u, should be %ld\n",
+ sdk_err(nic_io->dev_hdl, "Invalid sfp info cmd, length: %u, should be %lu\n",
in_size, sizeof(*sfp_info));
return;
}
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
memcpy(&rt_cmd->std_sfp_info, sfp_info,
sizeof(struct mag_cmd_get_xsfp_info));
rt_cmd->mpu_send_sfp_info = true;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+}
+
+static void port_xsfp_tlv_info_event(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_get_xsfp_tlv_rsp *xsfp_tlv_info = buf_in;
+ struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
+ size_t cpy_len = in_size - sizeof(struct mgmt_msg_head) -
+ XSFP_TLV_PRE_INFO_LEN;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL)
+ return;
+
+ if (cpy_len > XSFP_CMIS_INFO_MAX_SIZE) {
+ sdk_err(nic_io->dev_hdl, "invalid cpy_len(%lu)\n", cpy_len);
+ return;
+ }
+ rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ rt_cmd_ext->std_xsfp_tlv_info.port_id = xsfp_tlv_info->port_id;
+ memcpy(&(rt_cmd_ext->std_xsfp_tlv_info.tlv_buf[0]),
+ &(xsfp_tlv_info->tlv_buf[0]), cpy_len);
+ rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = true;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
}
@@ -543,8 +970,10 @@ static void port_sfp_abs_event(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_abs)) {
- sdk_err(nic_io->dev_hdl, "Invalid sfp absent cmd, length: %u, should be %ld\n",
+ sdk_err(nic_io->dev_hdl, "Invalid sfp absent cmd, length: %u, should be %lu\n",
in_size, sizeof(*sfp_abs));
return;
}
@@ -564,9 +993,11 @@ bool hinic3_if_sfp_absent(void *hwdev)
u8 port_id = hinic3_physical_port_id(hwdev);
u16 out_size = sizeof(sfp_abs);
int err;
- bool sfp_abs_status;
+ bool sfp_abs_status = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return true;
memset(&sfp_abs, 0, sizeof(sfp_abs));
rt_cmd = &nic_io->nic_cfg.rt_cmd;
@@ -597,10 +1028,187 @@ bool hinic3_if_sfp_absent(void *hwdev)
return (sfp_abs.abs_status == 0 ? false : true);
}
+int hinic3_get_sfp_tlv_info(void *hwdev, struct drv_mag_cmd_get_xsfp_tlv_rsp
+ *sfp_tlv_info,
+ const struct mag_cmd_get_xsfp_tlv_req
+ *sfp_tlv_info_req)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ u16 out_size = sizeof(*sfp_tlv_info);
+ int err;
+
+ if ((hwdev == NULL) || (sfp_tlv_info == NULL))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL)
+ return -EINVAL;
+
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ if (rt_cmd_ext->mpu_send_xsfp_tlv_info == true) {
+ if (rt_cmd_ext->std_xsfp_tlv_info.head.status != 0) {
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return -EIO;
+ }
+
+ memcpy(sfp_tlv_info, &rt_cmd_ext->std_xsfp_tlv_info,
+ sizeof(*sfp_tlv_info));
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_TLV_INFO,
+ (void *)sfp_tlv_info_req,
+ sizeof(*sfp_tlv_info_req),
+ sfp_tlv_info, &out_size);
+ if ((sfp_tlv_info->head.status != 0) || (err != 0) || (out_size == 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get port%u tlv sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
+ hinic3_physical_port_id(hwdev), err,
+ sfp_tlv_info->head.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_get_page_pos(u32 page_id, u32 content_len, u32 *pos)
+{
+ if (page_id <= QSFP_CMIS_PAGE_03H) {
+ *pos = (page_id * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_11H) {
+ *pos = (QSFP_CMIS_PAGE_04H * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_12H) {
+ *pos = (QSFP_CMIS_PAGE_05H * content_len);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int hinic3_get_page_key_info(struct mgmt_tlv_info *tlv_info,
+ struct parse_tlv_info *page_info, u8 idx,
+ u32 *total_len)
+{
+ u8 *src_addr = NULL;
+ u8 *dst_addr = NULL;
+ u8 *tmp_addr = NULL;
+ u32 page_id = 0;
+ u32 content_len = 0;
+ u32 src_pos = 0;
+ int ret;
+
+ page_id = MGMT_TLV_GET_U32(tlv_info->value);
+ content_len = tlv_info->length - MGMT_TLV_U32_SIZE;
+ if (page_id == QSFP_CMIS_PAGE_00H) {
+ tmp_addr = (u8 *)(tlv_info + 1);
+ page_info->id = *(tmp_addr + MGMT_TLV_U32_SIZE);
+ }
+
+ ret = hinic3_trans_cmis_get_page_pos(page_id, content_len, &src_pos);
+ if (ret != 0)
+ return ret;
+
+ src_addr = page_info->tlv_page_info + src_pos;
+ tmp_addr = (u8 *)(tlv_info + 1);
+ dst_addr = tmp_addr + MGMT_TLV_U32_SIZE;
+ memcpy(src_addr, dst_addr, content_len);
+ if (ret != 0)
+ return ret;
+
+ if (idx < XSFP_CMIS_PARSE_PAGE_NUM)
+ page_info->tlv_page_num[idx] = page_id;
+
+ *total_len += content_len;
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_tlv_info_to_buf(u8 *sfp_tlv_info,
+ struct parse_tlv_info *page_info)
+{
+ struct mgmt_tlv_info *tlv_info = NULL;
+ u8 *tlv_buf = sfp_tlv_info;
+ u8 idx = 0;
+ u32 total_len = 0;
+ int ret = 0;
+ bool need_continue = true;
+
+ if ((sfp_tlv_info == NULL) || (page_info == NULL))
+ return -EIO;
+
+ while (need_continue) {
+ tlv_info = (struct mgmt_tlv_info *)tlv_buf;
+ switch (tlv_info->type) {
+ case MAG_XSFP_TYPE_PAGE:
+ ret = hinic3_get_page_key_info(
+ tlv_info, page_info, idx, &total_len);
+ if (ret != 0) {
+ pr_err("lib_get_page_key_info fail,ret:0x%x.\n",
+ ret);
+ break;
+ }
+ idx++;
+ break;
+
+ case MAG_XSFP_TYPE_WIRE_TYPE:
+ page_info->wire_type =
+ MGMT_TLV_GET_U32(&(tlv_info->value[0]));
+ break;
+
+ case MAG_XSFP_TYPE_END:
+ need_continue = false;
+ break;
+
+ default:
+ break;
+ }
+
+ tlv_buf += (sizeof(struct mgmt_tlv_info) + tlv_info->length);
+ }
+
+ page_info->tlv_page_info_len = total_len;
+
+ return 0;
+}
+
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len)
+{
+ int err = 0;
+ struct mag_cmd_get_xsfp_tlv_req xsfp_tlv_info_req = {0};
+
+ xsfp_tlv_info_req.rsp_buf_len = XSFP_CMIS_INFO_MAX_SIZE;
+ xsfp_tlv_info_req.port_id = hinic3_physical_port_id(hwdev);
+ err = hinic3_get_sfp_tlv_info(hwdev, &g_xsfp_tlv_info,
+ &xsfp_tlv_info_req);
+ if (err != 0)
+ return err;
+
+ err = hinic3_trans_cmis_tlv_info_to_buf(g_xsfp_tlv_info.tlv_buf,
+ &g_page_info);
+ if (err)
+ return -ENOMEM;
+
+ memcpy(data, g_page_info.tlv_page_info, len);
+
+ return (err == 0) ? 0 : -ENOMEM;
+}
+
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
{
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ u8 sfp_info_status = 0;
u16 out_size = sizeof(*sfp_info);
int err;
@@ -608,13 +1216,17 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ sfp_info_status = rt_cmd->std_sfp_info.head.status;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (sfp_info_status != 0) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return -EIO;
+ return (sfp_info_status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ ? HINIC3_MGMT_CMD_UNSUPPORTED : -EIO;
}
memcpy(sfp_info, &rt_cmd->std_sfp_info, sizeof(*sfp_info));
@@ -626,7 +1238,14 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
sfp_info->port_id = hinic3_physical_port_id(hwdev);
err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_INFO, sfp_info,
sizeof(*sfp_info), sfp_info, &out_size);
- if (sfp_info->head.status || err || !out_size) {
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED) {
+ return HINIC3_MGMT_CMD_UNSUPPORTED;
+ }
+
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED) {
+ return -EOPNOTSUPP;
+ }
+ if ((sfp_info->head.status != 0) || (err != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Failed to get port%u sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
hinic3_physical_port_id(hwdev), err,
@@ -642,7 +1261,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
struct mag_cmd_get_xsfp_info sfp_info;
int err;
- if (!hwdev || !data)
+ if (!hwdev || !data || len > PAGE_SIZE)
return -EINVAL;
if (hinic3_if_sfp_absent(hwdev))
@@ -654,7 +1273,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
if (err)
return err;
- memcpy(data, sfp_info.sfp_info, len);
+ memcpy(data, sfp_info.sfp_info, sizeof(sfp_info.sfp_info));
return 0;
}
@@ -664,7 +1283,7 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
- int err;
+ int err = 0;
if (!hwdev || !sfp_type || !sfp_type_ext)
return -EINVAL;
@@ -673,24 +1292,41 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
return -ENXIO;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (rt_cmd->std_sfp_info.head.status == 0) {
+ *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
+ *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ if (rt_cmd->std_sfp_info.head.status != HINIC3_MGMT_CMD_UNSUPPORTED) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
return -EIO;
}
- *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
- *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
- mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return 0;
+ err = HINIC3_MGMT_CMD_UNSUPPORTED; /* cmis */
}
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
- STD_SFP_INFO_MAX_SIZE);
+ if (err == 0) {
+ err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ } else {
+ /* mpu_send_sfp_info is false */
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ }
+
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+
if (err)
return err;
@@ -796,12 +1432,20 @@ int hinic3_set_pf_bw_limit(void *hwdev, u32 bw_limit)
return -EINVAL;
}
- old_bw_limit = nic_io->nic_cfg.pf_bw_limit;
- nic_io->nic_cfg.pf_bw_limit = bw_limit;
+ if (nic_io->direct == HINIC3_NIC_TX) {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_tx_limit;
+ nic_io->nic_cfg.pf_bw_tx_limit = bw_limit;
+ } else {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_rx_limit;
+ nic_io->nic_cfg.pf_bw_rx_limit = bw_limit;
+ }
err = hinic3_update_pf_bw(hwdev);
if (err) {
- nic_io->nic_cfg.pf_bw_limit = old_bw_limit;
+ if (nic_io->direct == HINIC3_NIC_TX)
+ nic_io->nic_cfg.pf_bw_tx_limit = old_bw_limit;
+ else
+ nic_io->nic_cfg.pf_bw_rx_limit = old_bw_limit;
return err;
}
@@ -828,6 +1472,8 @@ int hinic3_pf_mag_mbox_handler(void *hwdev, u16 vf_id,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (index = 0; index < cmd_size; index++) {
handler = &vf_mag_cmd_handler[index];
@@ -849,6 +1495,11 @@ static struct nic_event_handler mag_cmd_handler[] = {
},
{
+ .cmd = MAG_CMD_EVENT_PORT_INFO,
+ .handler = port_info_event_printf,
+ },
+
+ {
.cmd = MAG_CMD_WIRE_EVENT,
.handler = cable_plug_event,
},
@@ -862,6 +1513,16 @@ static struct nic_event_handler mag_cmd_handler[] = {
.cmd = MAG_CMD_GET_XSFP_PRESENT,
.handler = port_sfp_abs_event,
},
+
+ {
+ .cmd = MAG_CMD_GET_BOND_STATUS,
+ .handler = bond_status_event_handler,
+ },
+
+ {
+ .cmd = MAG_CMD_GET_XSFP_TLV_INFO,
+ .handler = port_xsfp_tlv_info_event,
+ },
};
static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
@@ -877,6 +1538,9 @@ static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
for (i = 0; i < size; i++) {
if (cmd == mag_cmd_handler[i].cmd) {
mag_cmd_handler[i].handler(hwdev, buf_in, in_size,
@@ -917,7 +1581,8 @@ static int _mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u32 i, cmd_cnt = ARRAY_LEN(vf_mag_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_mag_cmd_handler[i].cmd) {
cmd_to_pf = true;
@@ -949,3 +1614,124 @@ static int mag_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in,
return _mag_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out,
out_size, channel);
}
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+struct fecparam_value_map {
+ u8 hinic3_fec_offset;
+ u8 hinic3_fec_value;
+ u8 ethtool_fec_value;
+};
+
+static void fecparam_convert(u32 opcode, u8 in_fec_param, u8 *out_fec_param)
+{
+ u8 i;
+ u8 fec_value_table_lenth;
+ struct fecparam_value_map fec_value_table[] = {
+ {PORT_FEC_NOT_SET, BIT(PORT_FEC_NOT_SET), ETHTOOL_FEC_NONE},
+ {PORT_FEC_RSFEC, BIT(PORT_FEC_RSFEC), ETHTOOL_FEC_RS},
+ {PORT_FEC_BASEFEC, BIT(PORT_FEC_BASEFEC), ETHTOOL_FEC_BASER},
+ {PORT_FEC_NOFEC, BIT(PORT_FEC_NOFEC), ETHTOOL_FEC_OFF},
+#ifdef ETHTOOL_FEC_LLRS
+ {PORT_FEC_LLRSFEC, BIT(PORT_FEC_LLRSFEC), ETHTOOL_FEC_LLRS},
+#endif
+ {PORT_FEC_AUTO, BIT(PORT_FEC_AUTO), ETHTOOL_FEC_AUTO}
+ };
+
+ *out_fec_param = 0;
+ fec_value_table_lenth = (u8)(sizeof(fec_value_table) / sizeof(struct fecparam_value_map));
+
+ if (opcode == MAG_CMD_OPCODE_SET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].ethtool_fec_value) != 0)
+ /* The MPU uses the offset to determine the FEC mode. */
+ *out_fec_param =
+ fec_value_table[i].hinic3_fec_offset;
+ }
+ }
+
+ if (opcode == MAG_CMD_OPCODE_GET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].hinic3_fec_value) != 0)
+ *out_fec_param |=
+ fec_value_table[i].ethtool_fec_value;
+ }
+ }
+}
+
+/* When the ethtool is used to set the FEC mode */
+static bool check_fecparam_is_valid(u8 fec_param)
+{
+ if (
+#ifdef ETHTOOL_FEC_LLRS
+ (fec_param == ETHTOOL_FEC_LLRS) ||
+#endif
+ (fec_param == ETHTOOL_FEC_RS) ||
+ (fec_param == ETHTOOL_FEC_BASER) ||
+ (fec_param == ETHTOOL_FEC_OFF)) {
+ return true;
+ }
+ return false;
+}
+
+int set_fecparam(void *hwdev, u8 fecparam)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ u8 advertised_fec = 0;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (check_fecparam_is_valid(fecparam) == false) {
+ nic_err(nic_io->dev_hdl, "fec param is invalid, failed to set fec param\n");
+ return -EINVAL;
+ }
+ fecparam_convert(MAG_CMD_OPCODE_SET, fecparam, &advertised_fec);
+ fec_msg.opcode = MAG_CMD_OPCODE_SET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ fec_msg.advertised_fec = advertised_fec;
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0))
+ return -EINVAL;
+ return 0;
+}
+
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ fec_msg.opcode = MAG_CMD_OPCODE_GET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0))
+ return -EINVAL;
+
+ /* fec_msg.advertised_fec: bit offset,
+ *value is BIT(fec_msg.advertised_fec); fec_msg.supported_fec: value
+ */
+ fecparam_convert(MAG_CMD_OPCODE_GET, BIT(fec_msg.advertised_fec),
+ advertised_fec);
+ fecparam_convert(MAG_CMD_OPCODE_GET, fec_msg.supported_fec,
+ supported_fec);
+ return 0;
+}
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
index 307ad8d..7790ae2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
@@ -20,6 +20,9 @@
#include <linux/debugfs.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#include "hinic3_hw.h"
#include "hinic3_crm.h"
#include "hinic3_mt.h"
@@ -35,8 +38,8 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
#include "hinic3_profile.h"
+#include "hinic3_bond.h"
-/*lint -e806*/
#define DEFAULT_POLL_WEIGHT 64
static unsigned int poll_weight = DEFAULT_POLL_WEIGHT;
module_param(poll_weight, uint, 0444);
@@ -68,7 +71,9 @@ static unsigned char set_link_status_follow = HINIC3_LINK_FOLLOW_STATUS_MAX;
module_param(set_link_status_follow, byte, 0444);
MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=default,1=follow,2=separate,3=unset");
-/*lint +e806*/
+static bool page_pool_enabled = true;
+module_param(page_pool_enabled, bool, 0444);
+MODULE_PARM_DESC(page_pool_enabled, "enable/disable page_pool feature for rxq page management (default enable)");
#define HINIC3_NIC_DEV_WQ_NAME "hinic3_nic_dev_wq"
@@ -80,6 +85,8 @@ MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=
#define HINIC3_SQ_DEPTH 1024
#define HINIC3_RQ_DEPTH 1024
+#define LRO_ENABLE 1
+
enum hinic3_rx_buff_len {
RX_BUFF_VALID_2KB = 2,
RX_BUFF_VALID_4KB = 4,
@@ -88,6 +95,9 @@ enum hinic3_rx_buff_len {
};
#define CONVERT_UNIT 1024
+#define NIC_MAX_PF_NUM 32
+
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
static int hinic3_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr);
@@ -99,6 +109,17 @@ static struct notifier_block hinic3_netdev_notifier = {
.notifier_call = hinic3_netdev_event,
};
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+static const struct udp_tunnel_nic_info hinic3_udp_tunnels = {
+ .set_port = hinic3_udp_tunnel_set_port,
+ .unset_port = hinic3_udp_tunnel_unset_port,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static void hinic3_register_notifier(struct hinic3_nic_dev *nic_dev)
{
int err;
@@ -264,6 +285,11 @@ static void netdev_feature_init(struct net_device *netdev)
netdev->features |= dft_fts | cso_fts | tso_fts | vlan_fts;
netdev->vlan_features |= dft_fts | cso_fts | tso_fts;
+ if (nic_dev->nic_cap.lro_enable == LRO_ENABLE) {
+ netdev->features |= NETIF_F_LRO;
+ netdev->vlan_features |= NETIF_F_LRO;
+ }
+
#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT
hw_features |= get_netdev_hw_features(netdev);
#else
@@ -350,6 +376,7 @@ static int hinic3_init_intr_coalesce(struct hinic3_nic_dev *nic_dev)
static void hinic3_free_intr_coalesce(struct hinic3_nic_dev *nic_dev)
{
kfree(nic_dev->intr_coalesce);
+ nic_dev->intr_coalesce = NULL;
}
static int hinic3_alloc_txrxqs(struct hinic3_nic_dev *nic_dev)
@@ -404,8 +431,85 @@ static void hinic3_sw_deinit(struct hinic3_nic_dev *nic_dev)
HINIC3_CHANNEL_NIC);
hinic3_clear_rss_config(nic_dev);
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+ hinic3_dcb_deinit(nic_dev);
+}
+
+static void hinic3_netdev_mtu_init(struct net_device *netdev)
+{
+ /* MTU range: 384 - 9600 */
+#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
+ netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+
+#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
+ netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+}
+
+static int hinic3_set_default_mac(struct hinic3_nic_dev *nic_dev)
+{
+ struct net_device *netdev = nic_dev->netdev;
+ u8 mac_addr[ETH_ALEN];
+ int err = 0;
+
+ err = hinic3_get_default_mac(nic_dev->hwdev, mac_addr);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev, "Failed to get MAC address\n");
+ return err;
+ }
+
+ ether_addr_copy(netdev->dev_addr, mac_addr);
+
+ if (!is_valid_ether_addr(netdev->dev_addr)) {
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
+ nic_err(&nic_dev->pdev->dev,
+ "Invalid MAC address %pM\n",
+ netdev->dev_addr);
+ return -EIO;
+ }
+
+ nic_info(&nic_dev->pdev->dev,
+ "Invalid MAC address %pM, using random\n",
+ netdev->dev_addr);
+ eth_hw_addr_random(netdev);
+ }
+
+ err = hinic3_set_mac(nic_dev->hwdev, netdev->dev_addr, 0,
+ hinic3_global_func_id(nic_dev->hwdev),
+ HINIC3_CHANNEL_NIC);
+ /* When this is VF driver, we must consider that PF has already set VF
+ * MAC, and we can't consider this condition is error status during
+ * driver probe procedure.
+ */
+ if (err && err != HINIC3_PF_SET_VF_ALREADY) {
+ nic_err(&nic_dev->pdev->dev, "Failed to set default MAC\n");
+ }
+
+ if (err == HINIC3_PF_SET_VF_ALREADY)
+ return 0;
+
+ return err;
+}
+
+static void hinic3_outband_cfg_init(struct hinic3_nic_dev *nic_dev)
+{
+ u16 outband_default_vid = 0;
+ int err = 0;
+
+ if (!nic_dev->nic_cap.outband_vlan_cfg_en)
+ return;
+
+ err = hinic3_get_outband_vlan_cfg(nic_dev->hwdev, &outband_default_vid);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev, "Failed to get_outband_cfg, err: %d\n", err);
+ return;
+ }
+
+ nic_dev->outband_cfg.outband_default_vid = outband_default_vid;
+
+ return;
}
static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
@@ -421,8 +525,6 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
nic_features &= NIC_DRV_DEFAULT_FEATURE;
hinic3_update_nic_feature(nic_dev->hwdev, nic_features);
- sema_init(&nic_dev->port_state_sem, 1);
-
err = hinic3_dcb_init(nic_dev);
if (err) {
nic_err(&nic_dev->pdev->dev, "Failed to init dcb\n");
@@ -434,47 +536,12 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
hinic3_try_to_enable_rss(nic_dev);
- err = hinic3_get_default_mac(nic_dev->hwdev, netdev->dev_addr);
+ err = hinic3_set_default_mac(nic_dev);
if (err) {
- nic_err(&nic_dev->pdev->dev, "Failed to get MAC address\n");
- goto get_mac_err;
- }
-
- if (!is_valid_ether_addr(netdev->dev_addr)) {
- if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- nic_err(&nic_dev->pdev->dev, "Invalid MAC address %pM\n",
- netdev->dev_addr);
- err = -EIO;
- goto err_mac;
- }
-
- nic_info(&nic_dev->pdev->dev, "Invalid MAC address %pM, using random\n",
- netdev->dev_addr);
- eth_hw_addr_random(netdev);
- }
-
- err = hinic3_set_mac(nic_dev->hwdev, netdev->dev_addr, 0,
- hinic3_global_func_id(nic_dev->hwdev),
- HINIC3_CHANNEL_NIC);
- /* When this is VF driver, we must consider that PF has already set VF
- * MAC, and we can't consider this condition is error status during
- * driver probe procedure.
- */
- if (err && err != HINIC3_PF_SET_VF_ALREADY) {
- nic_err(&nic_dev->pdev->dev, "Failed to set default MAC\n");
goto set_mac_err;
}
- /* MTU range: 384 - 9600 */
-#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
- netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
-
-#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
- netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
+ hinic3_netdev_mtu_init(netdev);
err = hinic3_alloc_txrxqs(nic_dev);
if (err) {
@@ -482,6 +549,8 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
goto alloc_qps_err;
}
+ hinic3_outband_cfg_init(nic_dev);
+
return 0;
alloc_qps_err:
@@ -490,8 +559,6 @@ alloc_qps_err:
HINIC3_CHANNEL_NIC);
set_mac_err:
-err_mac:
-get_mac_err:
hinic3_clear_rss_config(nic_dev);
return err;
@@ -690,20 +757,51 @@ static void hinic3_periodic_work_handler(struct work_struct *work)
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
}
+static void hinic3_vport_stats_work_handler(struct work_struct *work)
+{
+ int err;
+ struct hinic3_vport_stats vport_stats = {0};
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_nic_dev *nic_dev = container_of(delay, struct hinic3_nic_dev, vport_stats_work);
+ err = hinic3_get_vport_stats(nic_dev->hwdev, hinic3_global_func_id(nic_dev->hwdev), &vport_stats);
+ if (err)
+ nic_err(&nic_dev->pdev->dev, "Failed to get dropped stats from fw\n");
+ else
+ nic_dev->vport_stats.rx_discard_vport = vport_stats.rx_discard_vport;
+ queue_delayed_work(nic_dev->workq, &nic_dev->vport_stats_work, HZ);
+}
+
+static void free_nic_dev_vram(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)nic_dev->nic_vram, nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ else
+ kfree(nic_dev->nic_vram);
+ nic_dev->nic_vram = NULL;
+}
+
static void free_nic_dev(struct hinic3_nic_dev *nic_dev)
{
hinic3_deinit_nic_prof_adapter(nic_dev);
destroy_workqueue(nic_dev->workq);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+ free_nic_dev_vram(nic_dev);
}
static int setup_nic_dev(struct net_device *netdev,
struct hinic3_lld_dev *lld_dev)
{
struct pci_dev *pdev = lld_dev->pdev;
- struct hinic3_nic_dev *nic_dev;
- char *netdev_name_fmt;
+ struct hinic3_nic_dev *nic_dev = NULL;
+ char *netdev_name_fmt = NULL;
u32 page_num;
+ u16 func_id;
+ int ret;
+ int is_in_kexec = vram_get_kexec_flag();
+ int is_use_vram = get_use_vram_flag();
nic_dev = (struct hinic3_nic_dev *)netdev_priv(netdev);
nic_dev->netdev = netdev;
@@ -718,24 +816,65 @@ static int setup_nic_dev(struct net_device *netdev,
nic_dev->dma_rx_buff_size = RX_BUFF_NUM_PER_PAGE * nic_dev->rx_buff_len;
page_num = nic_dev->dma_rx_buff_size / PAGE_SIZE;
nic_dev->page_order = page_num > 0 ? ilog2(page_num) : 0;
+ nic_dev->page_pool_enabled = page_pool_enabled;
+ nic_dev->outband_cfg.outband_default_vid = 0;
+
+ // value other than 0 indicates hot replace
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ ret = snprintf(nic_dev->nic_vram_name,
+ VRAM_NAME_MAX_LEN,
+ "%s%u", VRAM_NIC_VRAM, func_id);
+ if (ret < 0) {
+ nic_err(&pdev->dev, "NIC vram name snprintf failed, ret:%d.\n",
+ ret);
+ return -EINVAL;
+ }
+
+ nic_dev->nic_vram = (struct hinic3_vram *)hi_vram_kalloc(nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+
+ if (is_in_kexec == 0)
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ else
+ netdev->mtu = nic_dev->nic_vram->vram_mtu;
+ } else {
+ nic_dev->nic_vram = kzalloc(sizeof(struct hinic3_vram),
+ GFP_KERNEL);
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ }
mutex_init(&nic_dev->nic_mutex);
nic_dev->vlan_bitmap = kzalloc(VLAN_BITMAP_SIZE(nic_dev), GFP_KERNEL);
if (!nic_dev->vlan_bitmap) {
nic_err(&pdev->dev, "Failed to allocate vlan bitmap\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto vlan_bitmap_error;
}
nic_dev->workq = create_singlethread_workqueue(HINIC3_NIC_DEV_WQ_NAME);
if (!nic_dev->workq) {
nic_err(&pdev->dev, "Failed to initialize nic workqueue\n");
- kfree(nic_dev->vlan_bitmap);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto create_workq_error;
}
- INIT_DELAYED_WORK(&nic_dev->periodic_work, hinic3_periodic_work_handler);
- INIT_DELAYED_WORK(&nic_dev->rxq_check_work, hinic3_rxq_check_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->periodic_work,
+ hinic3_periodic_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->rxq_check_work,
+ hinic3_rxq_check_work_handler);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ INIT_DELAYED_WORK(&nic_dev->vport_stats_work,
+ hinic3_vport_stats_work_handler);
INIT_LIST_HEAD(&nic_dev->uc_filter_list);
INIT_LIST_HEAD(&nic_dev->mc_filter_list);
@@ -748,10 +887,23 @@ static int setup_nic_dev(struct net_device *netdev,
hinic3_init_nic_prof_adapter(nic_dev);
netdev_name_fmt = hinic3_get_dft_netdev_name_fmt(nic_dev);
- if (netdev_name_fmt)
- strncpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (netdev_name_fmt) {
+ ret = strscpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (ret < 0)
+ goto get_netdev_name_error;
+ }
return 0;
+
+get_netdev_name_error:
+ hinic3_deinit_nic_prof_adapter(nic_dev);
+ destroy_workqueue(nic_dev->workq);
+create_workq_error:
+ kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+vlan_bitmap_error:
+ free_nic_dev_vram(nic_dev);
+ return ret;
}
static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
@@ -790,6 +942,32 @@ static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
return 0;
}
+static void hinic3_bond_init(struct hinic3_nic_dev *nic_dev)
+{
+ u32 bond_id = HINIC3_INVALID_BOND_ID;
+ int err = hinic3_create_bond(nic_dev->hwdev, &bond_id);
+ if (err != 0) {
+ goto bond_init_failed;
+ }
+
+ /* bond id does not change, means this pf is not bond active pf, no log is generated */
+ if (bond_id == HINIC3_INVALID_BOND_ID) {
+ return;
+ }
+
+ err = hinic3_open_close_bond(nic_dev->hwdev, true);
+ if (err != 0) {
+ hinic3_delete_bond(nic_dev->hwdev);
+ goto bond_init_failed;
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Bond %d init success\n", bond_id);
+ return;
+
+bond_init_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond init failed\n");
+}
+
static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
char *uld_dev_name)
{
@@ -820,6 +998,12 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
goto err_out;
}
+ err = hinic3_get_dev_cap(lld_dev->hwdev);
+ if (err != 0) {
+ nic_err(&pdev->dev, "Failed to get dev cap\n");
+ goto err_out;
+ }
+
max_qps = hinic3_func_max_nic_qnum(lld_dev->hwdev);
netdev = alloc_etherdev_mq(sizeof(*nic_dev), max_qps);
if (!netdev) {
@@ -851,23 +1035,35 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
hinic3_assign_netdev_ops(nic_dev);
netdev_feature_init(netdev);
-
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+ netdev->udp_tunnel_nic_info = &hinic3_udp_tunnels;
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
err = hinic3_set_default_hw_feature(nic_dev);
if (err)
goto set_features_err;
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0) {
+ hinic3_bond_init(nic_dev);
+ }
+
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
hinic3_register_notifier(nic_dev);
#endif
- err = register_netdev(netdev);
- if (err) {
- nic_err(&pdev->dev, "Failed to register netdev\n");
- err = -ENOMEM;
- goto netdev_err;
+ if (pdev->subsystem_device != BIFUR_RESOURCE_PF_SSID) {
+ err = register_netdev(netdev);
+ if (err) {
+ nic_err(&pdev->dev, "Failed to register netdev\n");
+ err = -ENOMEM;
+ goto netdev_err;
+ }
}
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->vport_stats_work, HZ);
+
netif_carrier_off(netdev);
*uld_dev = nic_dev;
@@ -900,6 +1096,27 @@ err_out:
return err;
}
+static void hinic3_bond_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ int ret = 0;
+
+ ret = hinic3_open_close_bond(nic_dev->hwdev, false);
+ if (ret != 0) {
+ goto bond_deinit_failed;
+ }
+
+ ret = hinic3_delete_bond(nic_dev->hwdev);
+ if (ret != 0) {
+ goto bond_deinit_failed;
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Bond deinit success\n");
+ return;
+
+bond_deinit_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond deinit failed\n");
+}
+
static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
{
struct hinic3_nic_dev *nic_dev = adapter;
@@ -912,11 +1129,16 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
netdev = nic_dev->netdev;
- unregister_netdev(netdev);
+ if (lld_dev->pdev->subsystem_device != BIFUR_RESOURCE_PF_SSID) {
+ unregister_netdev(netdev);
+ }
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
hinic3_unregister_notifier(nic_dev);
#endif
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ cancel_delayed_work_sync(&nic_dev->vport_stats_work);
+
cancel_delayed_work_sync(&nic_dev->periodic_work);
cancel_delayed_work_sync(&nic_dev->rxq_check_work);
cancel_work_sync(&nic_dev->rx_mode_work);
@@ -924,6 +1146,10 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_flush_rx_flow_rule(nic_dev);
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0) {
+ hinic3_bond_deinit(nic_dev);
+ }
+
hinic3_update_nic_feature(nic_dev->hwdev, 0);
hinic3_set_nic_feature_to_hw(nic_dev->hwdev);
@@ -933,6 +1159,7 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_deinit_nic_prof_adapter(nic_dev);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
free_netdev(netdev);
@@ -981,6 +1208,120 @@ static void hinic3_port_module_event_handler(struct hinic3_nic_dev *nic_dev,
}
}
+bool hinic3_need_proc_link_event(struct hinic3_lld_dev *lld_dev)
+{
+ int ret = 0;
+ u16 func_id;
+ u8 roce_enable = false;
+ bool is_slave_func = false;
+ struct hinic3_hw_bond_infos hw_bond_infos = {0};
+
+ if (!lld_dev)
+ return false;
+
+ /* 非slave设备需要处理link down事件 */
+ ret = hinic3_is_slave_func(lld_dev->hwdev, &is_slave_func);
+ if (ret != 0) {
+ nic_err(&lld_dev->pdev->dev, "NIC get info, lld_dev is null\n");
+ return true;
+ }
+
+ if (!is_slave_func)
+ return true;
+
+ /* 未使能了vroce功能,需处理link down事件 */
+ func_id = hinic3_global_func_id(lld_dev->hwdev);
+ ret = hinic3_get_func_vroce_enable(lld_dev->hwdev, func_id,
+ &roce_enable);
+ if (ret != 0)
+ return true;
+
+ if (!roce_enable)
+ return true;
+
+ /* 未创建bond,需要处理link down事件 */
+ hw_bond_infos.bond_id = HINIC_OVS_BOND_DEFAULT_ID;
+
+ ret = hinic3_get_hw_bond_infos(lld_dev->hwdev, &hw_bond_infos,
+ HINIC3_CHANNEL_COMM);
+ if (ret != 0) {
+ pr_err("[ROCE, ERR] Get chipf bond info failed (%d)\n", ret);
+ return true;
+ }
+
+ if (!hw_bond_infos.valid)
+ return true;
+
+ return false;
+}
+
+bool hinic3_need_proc_bond_event(struct hinic3_lld_dev *lld_dev)
+{
+ return !hinic3_need_proc_link_event(lld_dev);
+}
+
+static void hinic_porc_bond_state_change(struct hinic3_lld_dev *lld_dev,
+ void *adapter,
+ struct hinic3_event_info *event)
+{
+ struct hinic3_nic_dev *nic_dev = adapter;
+
+ if (!nic_dev || !event || !hinic3_support_nic(lld_dev->hwdev, NULL))
+ return;
+
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond down\n");
+ hinic3_link_status_change(nic_dev, false);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond up\n");
+ hinic3_link_status_change(nic_dev, true);
+ break;
+ default:
+ break;
+ }
+}
+
+static void hinic3_outband_cfg_event_handler(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_outband_cfg_info *info)
+{
+ int err = 0;
+ if (!nic_dev || !info || !hinic3_support_nic(nic_dev->hwdev, NULL)) {
+ pr_err("Outband cfg event invalid param\n");
+ return;
+ }
+
+ if (hinic3_func_type(nic_dev->hwdev) != TYPE_VF &&
+ info->func_id >= NIC_MAX_PF_NUM) {
+ err = hinic3_notify_vf_outband_cfg(nic_dev->hwdev,
+ info->func_id,
+ info->outband_default_vid);
+ if (err)
+ nic_err(&nic_dev->pdev->dev, "Outband cfg event notify vf err: %d,"
+ "func_id: 0x%x, vid: 0x%x\n",
+ err, info->func_id, info->outband_default_vid);
+ return;
+ }
+
+ nic_info(&nic_dev->pdev->dev,
+ "Change outband default vid from %u to %u\n",
+ nic_dev->outband_cfg.outband_default_vid,
+ info->outband_default_vid);
+
+ nic_dev->outband_cfg.outband_default_vid = info->outband_default_vid;
+
+ return;
+}
+
static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
struct hinic3_event_info *event)
{
@@ -992,14 +1333,25 @@ static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_DOWN):
+ if (!hinic3_need_proc_link_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc link event\n");
+ return;
+ }
hinic3_link_status_change(nic_dev, false);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_UP):
hinic3_link_status_change(nic_dev, true);
break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ hinic_porc_bond_state_change(lld_dev, adapter, event);
+ break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_PORT_MODULE_EVENT):
hinic3_port_module_event_handler(nic_dev, event);
break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_OUTBAND_CFG):
+ hinic3_outband_cfg_event_handler(nic_dev, (void *)event->event_data);
+ break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_SRIOV_STATE_CHANGE):
sriov_state_change(nic_dev, (void *)event->event_data);
break;
@@ -1059,7 +1411,7 @@ struct hinic3_uld_info g_nic_uld_info = {
.resume = NULL,
.event = nic_event,
.ioctl = nic_ioctl,
-}; /*lint -e766*/
+};
struct hinic3_uld_info *get_nic_uld_info(void)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h b/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h
deleted file mode 100644
index 522518d..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h
+++ /dev/null
@@ -1,1298 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
-
-#ifndef NIC_MPU_CMD_DEFS_H
-#define NIC_MPU_CMD_DEFS_H
-
-#include "nic_cfg_comm.h"
-#include "mpu_cmd_base_defs.h"
-
-#ifndef ETH_ALEN
-#define ETH_ALEN 6
-#endif
-
-#define HINIC3_CMD_OP_SET 1
-#define HINIC3_CMD_OP_GET 0
-
-#define HINIC3_CMD_OP_ADD 1
-#define HINIC3_CMD_OP_DEL 0
-
-#define NIC_TCAM_BLOCK_LARGE_NUM 256
-#define NIC_TCAM_BLOCK_LARGE_SIZE 16
-
-#ifndef BIT
-#define BIT(n) (1UL << (n))
-#endif
-
-enum nic_feature_cap {
- NIC_F_CSUM = BIT(0),
- NIC_F_SCTP_CRC = BIT(1),
- NIC_F_TSO = BIT(2),
- NIC_F_LRO = BIT(3),
- NIC_F_UFO = BIT(4),
- NIC_F_RSS = BIT(5),
- NIC_F_RX_VLAN_FILTER = BIT(6),
- NIC_F_RX_VLAN_STRIP = BIT(7),
- NIC_F_TX_VLAN_INSERT = BIT(8),
- NIC_F_VXLAN_OFFLOAD = BIT(9),
- NIC_F_IPSEC_OFFLOAD = BIT(10),
- NIC_F_FDIR = BIT(11),
- NIC_F_PROMISC = BIT(12),
- NIC_F_ALLMULTI = BIT(13),
- NIC_F_XSFP_REPORT = BIT(14),
- NIC_F_VF_MAC = BIT(15),
- NIC_F_RATE_LIMIT = BIT(16),
- NIC_F_RXQ_RECOVERY = BIT(17),
-};
-
-#define NIC_F_ALL_MASK 0x3FFFF /* 使能所有属性 */
-
-struct hinic3_mgmt_msg_head {
- u8 status;
- u8 version;
- u8 rsvd0[6];
-};
-
-#define NIC_MAX_FEATURE_QWORD 4
-struct hinic3_cmd_feature_nego {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 opcode; /* 1: set, 0: get */
- u8 rsvd;
- u64 s_feature[NIC_MAX_FEATURE_QWORD];
-};
-
-struct hinic3_port_mac_set {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 vlan_id;
- u16 rsvd1;
- u8 mac[ETH_ALEN];
-};
-
-struct hinic3_port_mac_update {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 vlan_id;
- u16 rsvd1;
- u8 old_mac[ETH_ALEN];
- u16 rsvd2;
- u8 new_mac[ETH_ALEN];
-};
-
-struct hinic3_vport_state {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd1;
- u8 state; /* 0--disable, 1--enable */
- u8 rsvd2[3];
-};
-
-struct hinic3_port_state {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd1;
- u8 state; /* 0--disable, 1--enable */
- u8 rsvd2[3];
-};
-
-#define HINIC3_SET_PORT_CAR_PROFILE 0
-#define HINIC3_SET_PORT_CAR_STATE 1
-
-struct hinic3_port_car_info {
- u32 cir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
- u32 xir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
- u32 cbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
- u32 xbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
-};
-
-struct hinic3_cmd_set_port_car {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 opcode; /* 0--set car profile, 1--set car state */
- u8 state; /* 0--disable, 1--enable */
- u8 rsvd;
-
- struct hinic3_port_car_info car;
-};
-
-struct hinic3_cmd_clear_qp_resource {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd1;
-};
-
-struct hinic3_cmd_cache_out_qp_resource {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd1;
-};
-
-struct hinic3_port_stats_info {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd1;
-};
-
-struct hinic3_vport_stats {
- u64 tx_unicast_pkts_vport;
- u64 tx_unicast_bytes_vport;
- u64 tx_multicast_pkts_vport;
- u64 tx_multicast_bytes_vport;
- u64 tx_broadcast_pkts_vport;
- u64 tx_broadcast_bytes_vport;
-
- u64 rx_unicast_pkts_vport;
- u64 rx_unicast_bytes_vport;
- u64 rx_multicast_pkts_vport;
- u64 rx_multicast_bytes_vport;
- u64 rx_broadcast_pkts_vport;
- u64 rx_broadcast_bytes_vport;
-
- u64 tx_discard_vport;
- u64 rx_discard_vport;
- u64 tx_err_vport;
- u64 rx_err_vport;
-};
-
-struct hinic3_phy_fpga_port_stats {
- u64 mac_rx_total_octs_port;
- u64 mac_tx_total_octs_port;
- u64 mac_rx_under_frame_pkts_port;
- u64 mac_rx_frag_pkts_port;
- u64 mac_rx_64_oct_pkts_port;
- u64 mac_rx_127_oct_pkts_port;
- u64 mac_rx_255_oct_pkts_port;
- u64 mac_rx_511_oct_pkts_port;
- u64 mac_rx_1023_oct_pkts_port;
- u64 mac_rx_max_oct_pkts_port;
- u64 mac_rx_over_oct_pkts_port;
- u64 mac_tx_64_oct_pkts_port;
- u64 mac_tx_127_oct_pkts_port;
- u64 mac_tx_255_oct_pkts_port;
- u64 mac_tx_511_oct_pkts_port;
- u64 mac_tx_1023_oct_pkts_port;
- u64 mac_tx_max_oct_pkts_port;
- u64 mac_tx_over_oct_pkts_port;
- u64 mac_rx_good_pkts_port;
- u64 mac_rx_crc_error_pkts_port;
- u64 mac_rx_broadcast_ok_port;
- u64 mac_rx_multicast_ok_port;
- u64 mac_rx_mac_frame_ok_port;
- u64 mac_rx_length_err_pkts_port;
- u64 mac_rx_vlan_pkts_port;
- u64 mac_rx_pause_pkts_port;
- u64 mac_rx_unknown_mac_frame_port;
- u64 mac_tx_good_pkts_port;
- u64 mac_tx_broadcast_ok_port;
- u64 mac_tx_multicast_ok_port;
- u64 mac_tx_underrun_pkts_port;
- u64 mac_tx_mac_frame_ok_port;
- u64 mac_tx_vlan_pkts_port;
- u64 mac_tx_pause_pkts_port;
-};
-
-struct hinic3_port_stats {
- struct hinic3_mgmt_msg_head msg_head;
-
- struct hinic3_phy_fpga_port_stats stats;
-};
-
-struct hinic3_cmd_vport_stats {
- struct hinic3_mgmt_msg_head msg_head;
-
- u32 stats_size;
- u32 rsvd1;
- struct hinic3_vport_stats stats;
- u64 rsvd2[6];
-};
-
-struct hinic3_cmd_qpn {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 base_qpn;
-};
-
-enum hinic3_func_tbl_cfg_bitmap {
- FUNC_CFG_INIT,
- FUNC_CFG_RX_BUF_SIZE,
- FUNC_CFG_MTU,
-};
-
-struct hinic3_func_tbl_cfg {
- u16 rx_wqe_buf_size;
- u16 mtu;
- u32 rsvd[9];
-};
-
-struct hinic3_cmd_set_func_tbl {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd;
-
- u32 cfg_bitmap;
- struct hinic3_func_tbl_cfg tbl_cfg;
-};
-
-struct hinic3_cmd_cons_idx_attr {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_idx;
- u8 dma_attr_off;
- u8 pending_limit;
- u8 coalescing_time;
- u8 intr_en;
- u16 intr_idx;
- u32 l2nic_sqn;
- u32 rsvd;
- u64 ci_addr;
-};
-
-union sm_tbl_args {
- struct {
- u32 tbl_index;
- u32 cnt;
- u32 total_cnt;
- } mac_table_arg;
- struct {
- u32 er_id;
- u32 vlan_id;
- } vlan_elb_table_arg;
- struct {
- u32 func_id;
- } vlan_filter_arg;
- struct {
- u32 mc_id;
- } mc_elb_arg;
- struct {
- u32 func_id;
- } func_tbl_arg;
- struct {
- u32 port_id;
- } port_tbl_arg;
- struct {
- u32 tbl_index;
- u32 cnt;
- u32 total_cnt;
- } fdir_io_table_arg;
- struct {
- u32 tbl_index;
- u32 cnt;
- u32 total_cnt;
- } flexq_table_arg;
- u32 args[4];
-};
-
-#define DFX_SM_TBL_BUF_MAX (768)
-
-struct nic_cmd_dfx_sm_table {
- struct hinic3_mgmt_msg_head msg_head;
- u32 tbl_type;
- union sm_tbl_args args;
- u8 tbl_buf[DFX_SM_TBL_BUF_MAX];
-};
-
-struct hinic3_cmd_vlan_offload {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 vlan_offload;
- u8 rsvd1[5];
-};
-
-/* ucode capture cfg info */
-struct nic_cmd_capture_info {
- struct hinic3_mgmt_msg_head msg_head;
- u32 op_type;
- u32 func_port;
- u32 is_en_trx;
- u32 offset_cos;
- u32 data_vlan;
-};
-
-struct hinic3_cmd_lro_config {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 opcode;
- u8 rsvd1;
- u8 lro_ipv4_en;
- u8 lro_ipv6_en;
- u8 lro_max_pkt_len; /* unit is 1K */
- u8 resv2[13];
-};
-
-struct hinic3_cmd_lro_timer {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 opcode; /* 1: set timer value, 0: get timer value */
- u8 rsvd1;
- u16 rsvd2;
- u32 timer;
-};
-
-struct hinic3_cmd_local_lro_state {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 opcode; /* 0: get state, 1: set state */
- u8 state; /* 0: disable, 1: enable */
-};
-
-struct hinic3_cmd_vf_vlan_config {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 opcode;
- u8 rsvd1;
- u16 vlan_id;
- u8 qos;
- u8 rsvd2[5];
-};
-
-struct hinic3_cmd_spoofchk_set {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 state;
- u8 rsvd1;
-};
-
-struct hinic3_cmd_tx_rate_cfg {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd1;
- u32 min_rate;
- u32 max_rate;
- u8 rsvd2[8];
-};
-
-struct hinic3_cmd_port_info {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 rsvd1[3];
- u8 port_type;
- u8 autoneg_cap;
- u8 autoneg_state;
- u8 duplex;
- u8 speed;
- u8 fec;
- u16 rsvd2;
- u32 rsvd3[4];
-};
-
-struct hinic3_cmd_register_vf {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 op_register; /* 0 - unregister, 1 - register */
- u8 rsvd1[3];
- u32 support_extra_feature;
- u8 rsvd2[32];
-};
-
-struct hinic3_cmd_link_state {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 state;
- u16 rsvd1;
-};
-
-struct hinic3_cmd_vlan_config {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 opcode;
- u8 rsvd1;
- u16 vlan_id;
- u16 rsvd2;
-};
-
-/* set vlan filter */
-struct hinic3_cmd_set_vlan_filter {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 resvd[2];
- u32 vlan_filter_ctrl; /* bit0:vlan filter en; bit1:broadcast_filter_en */
-};
-
-struct hinic3_cmd_link_ksettings_info {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 rsvd1[3];
-
- u32 valid_bitmap;
- u8 speed; /* enum nic_speed_level */
- u8 autoneg; /* 0 - off, 1 - on */
- u8 fec; /* 0 - RSFEC, 1 - BASEFEC, 2 - NOFEC */
- u8 rsvd2[21]; /* reserved for duplex, port, etc. */
-};
-
-struct mpu_lt_info {
- u8 node;
- u8 inst;
- u8 entry_size;
- u8 rsvd;
- u32 lt_index;
- u32 offset;
- u32 len;
-};
-
-struct nic_mpu_lt_opera {
- struct hinic3_mgmt_msg_head msg_head;
- struct mpu_lt_info net_lt_cmd;
- u8 data[100];
-};
-
-struct hinic3_force_pkt_drop {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port;
- u8 rsvd1[3];
-};
-
-struct hinic3_rx_mode_config {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd1;
- u32 rx_mode;
-};
-
-/* rss */
-struct hinic3_rss_context_table {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd1;
- u32 context;
-};
-
-struct hinic3_cmd_rss_engine_type {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 opcode;
- u8 hash_engine;
- u8 rsvd1[4];
-};
-
-struct hinic3_cmd_rss_hash_key {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 opcode;
- u8 rsvd1;
- u8 key[NIC_RSS_KEY_SIZE];
-};
-
-struct hinic3_rss_indir_table {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd1;
- u8 indir[NIC_RSS_INDIR_SIZE];
-};
-
-#define NIC_RSS_CMD_TEMP_ALLOC 0x01
-#define NIC_RSS_CMD_TEMP_FREE 0x02
-
-struct hinic3_rss_template_mgmt {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 cmd;
- u8 template_id;
- u8 rsvd1[4];
-};
-
-struct hinic3_cmd_rss_config {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 rss_en;
- u8 rq_priority_number;
- u8 prio_tc[NIC_DCB_COS_MAX];
- u16 num_qps;
- u16 rsvd1;
-};
-
-struct hinic3_dcb_state {
- u8 dcb_on;
- u8 default_cos;
- u8 trust;
- u8 rsvd1;
- u8 pcp2cos[NIC_DCB_UP_MAX];
- u8 dscp2cos[64];
- u32 rsvd2[7];
-};
-
-struct hinic3_cmd_vf_dcb_state {
- struct hinic3_mgmt_msg_head msg_head;
-
- struct hinic3_dcb_state state;
-};
-
-struct hinic3_up_ets_cfg { /* delet */
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 rsvd1[3];
-
- u8 cos_tc[NIC_DCB_COS_MAX];
- u8 tc_bw[NIC_DCB_TC_MAX];
- u8 cos_prio[NIC_DCB_COS_MAX];
- u8 cos_bw[NIC_DCB_COS_MAX];
- u8 tc_prio[NIC_DCB_TC_MAX];
-};
-
-#define CMD_QOS_ETS_COS_TC BIT(0)
-#define CMD_QOS_ETS_TC_BW BIT(1)
-#define CMD_QOS_ETS_COS_PRIO BIT(2)
-#define CMD_QOS_ETS_COS_BW BIT(3)
-#define CMD_QOS_ETS_TC_PRIO BIT(4)
-struct hinic3_cmd_ets_cfg {
- struct hinic3_mgmt_msg_head head;
-
- u8 port_id;
- u8 op_code; /* 1 - set, 0 - get */
- /* bit0 - cos_tc, bit1 - tc_bw, bit2 - cos_prio, bit3 - cos_bw, bit4 - tc_prio */
- u8 cfg_bitmap;
- u8 rsvd;
-
- u8 cos_tc[NIC_DCB_COS_MAX];
- u8 tc_bw[NIC_DCB_TC_MAX];
- u8 cos_prio[NIC_DCB_COS_MAX]; /* 0 - DWRR, 1 - STRICT */
- u8 cos_bw[NIC_DCB_COS_MAX];
- u8 tc_prio[NIC_DCB_TC_MAX]; /* 0 - DWRR, 1 - STRICT */
-};
-
-struct hinic3_cmd_set_dcb_state {
- struct hinic3_mgmt_msg_head head;
-
- u16 func_id;
- u8 op_code; /* 0 - get dcb state, 1 - set dcb state */
- u8 state; /* 0 - disable, 1 - enable dcb */
- u8 port_state; /* 0 - disable, 1 - enable dcb */
- u8 rsvd[7];
-};
-
-#define PFC_BIT_MAP_NUM 8
-struct hinic3_cmd_set_pfc {
- struct hinic3_mgmt_msg_head head;
-
- u8 port_id;
- u8 op_code; /* 0:get 1: set pfc_en 2: set pfc_bitmap 3: set all */
- u8 pfc_en; /* pfc_en 和 pfc_bitmap 必须同时设置 */
- u8 pfc_bitmap;
- u8 rsvd[4];
-};
-
-#define CMD_QOS_PORT_TRUST BIT(0)
-#define CMD_QOS_PORT_DFT_COS BIT(1)
-struct hinic3_cmd_qos_port_cfg {
- struct hinic3_mgmt_msg_head head;
-
- u8 port_id;
- u8 op_code; /* 0 - get, 1 - set */
- u8 cfg_bitmap; /* bit0 - trust, bit1 - dft_cos */
- u8 rsvd0;
-
- u8 trust;
- u8 dft_cos;
- u8 rsvd1[18];
-};
-
-#define MAP_COS_MAX_NUM 8
-#define CMD_QOS_MAP_PCP2COS BIT(0)
-#define CMD_QOS_MAP_DSCP2COS BIT(1)
-struct hinic3_cmd_qos_map_cfg {
- struct hinic3_mgmt_msg_head head;
-
- u8 op_code;
- u8 cfg_bitmap; /* bit0 - pcp2cos, bit1 - dscp2cos */
- u16 rsvd0;
-
- u8 pcp2cos[8]; /* 8 must be configured together */
- /* If the dscp2cos parameter is set to 0xFF, the MPU ignores the DSCP priority,
- * Multiple mappings between DSCP values and CoS values can be configured at a time.
- */
- u8 dscp2cos[64];
- u32 rsvd1[4];
-};
-
-struct hinic3_cos_up_map {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 cos_valid_mask; /* every bit indicate index of map is valid 1 or not 0 */
- u16 rsvd1;
-
- /* user priority in cos(index:cos, value: up pri) */
- u8 map[NIC_DCB_UP_MAX];
-};
-
-struct hinic3_cmd_pause_config {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 opcode;
- u16 rsvd1;
- u8 auto_neg;
- u8 rx_pause;
- u8 tx_pause;
- u8 rsvd2[5];
-};
-
-struct nic_cmd_pause_inquiry_cfg {
- struct hinic3_mgmt_msg_head head;
-
- u32 valid;
-
- u32 type; /* 1: set, 2: get */
-
- u32 rx_inquiry_pause_drop_pkts_en;
- u32 rx_inquiry_pause_period_ms;
- u32 rx_inquiry_pause_times;
- /* rx pause Detection Threshold, Default PAUSE_FRAME_THD_10G/25G/40G/100 */
- u32 rx_inquiry_pause_frame_thd;
- u32 rx_inquiry_tx_total_pkts;
-
- u32 tx_inquiry_pause_en; /* tx pause detect enable */
- u32 tx_inquiry_pause_period_ms; /* tx pause Default Detection Period 200ms */
- u32 tx_inquiry_pause_times; /* tx pause Default Times Period 5 */
- u32 tx_inquiry_pause_frame_thd; /* tx pause Detection Threshold */
- u32 tx_inquiry_rx_total_pkts;
- u32 rsvd[4];
-};
-
-/* pfc/pause Storm TX exception reporting */
-struct nic_cmd_tx_pause_notice {
- struct hinic3_mgmt_msg_head head;
-
- u32 tx_pause_except; /* 1: abnormality,0: normal */
- u32 except_level;
- u32 rsvd;
-};
-
-#define HINIC3_CMD_OP_FREE 0
-#define HINIC3_CMD_OP_ALLOC 1
-
-struct hinic3_cmd_cfg_qps {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 opcode; /* 1: alloc qp, 0: free qp */
- u8 rsvd1;
- u16 num_qps;
- u16 rsvd2;
-};
-
-struct hinic3_cmd_led_config {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port;
- u8 type;
- u8 mode;
- u8 rsvd1;
-};
-
-struct hinic3_cmd_port_loopback {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 opcode;
- u8 mode;
- u8 en;
- u32 rsvd1[2];
-};
-
-struct hinic3_cmd_get_light_module_abs {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 abs_status; /* 0:present, 1:absent */
- u8 rsv[2];
-};
-
-#define STD_SFP_INFO_MAX_SIZE 640
-struct hinic3_cmd_get_std_sfp_info {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 wire_type;
- u16 eeprom_len;
- u32 rsvd;
- u8 sfp_info[STD_SFP_INFO_MAX_SIZE];
-};
-
-struct hinic3_cable_plug_event {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 plugged; /* 0: unplugged, 1: plugged */
- u8 port_id;
-};
-
-struct nic_cmd_mac_info {
- struct hinic3_mgmt_msg_head head;
-
- u32 valid_bitmap;
- u16 rsvd;
-
- u8 host_id[32];
- u8 port_id[32];
- u8 mac_addr[192];
-};
-
-struct nic_cmd_set_tcam_enable {
- struct hinic3_mgmt_msg_head head;
-
- u16 func_id;
- u8 tcam_enable;
- u8 rsvd1;
- u32 rsvd2;
-};
-
-struct nic_cmd_set_fdir_status {
- struct hinic3_mgmt_msg_head head;
-
- u16 func_id;
- u16 rsvd1;
- u8 pkt_type_en;
- u8 pkt_type;
- u8 qid;
- u8 rsvd2;
-};
-
-#define HINIC3_TCAM_BLOCK_ENABLE 1
-#define HINIC3_TCAM_BLOCK_DISABLE 0
-#define HINIC3_MAX_TCAM_RULES_NUM 4096
-
-/* tcam block type, according to tcam block size */
-enum {
- NIC_TCAM_BLOCK_TYPE_LARGE = 0, /* block_size: 16 */
- NIC_TCAM_BLOCK_TYPE_SMALL, /* block_size: 0 */
- NIC_TCAM_BLOCK_TYPE_MAX
-};
-
-/* alloc tcam block input struct */
-struct nic_cmd_ctrl_tcam_block_in {
- struct hinic3_mgmt_msg_head head;
-
- u16 func_id; /* func_id */
- u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
- /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
- u8 tcam_type;
- u16 tcam_block_index;
- /* Size of the block that the driver wants to allocate
- * Interface returned by the UP to the driver,
- * indicating the size of the allocated TCAM block supported by the UP
- */
- u16 alloc_block_num;
-};
-
-/* alloc tcam block output struct */
-struct nic_cmd_ctrl_tcam_block_out {
- struct hinic3_mgmt_msg_head head;
-
- u16 func_id; /* func_id */
- u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
- /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
- u8 tcam_type;
- u16 tcam_block_index;
- /* Size of the block that the driver wants to allocate
- * Interface returned by the UP to the driver,
- * indicating the size of the allocated TCAM block supported by the UP
- */
- u16 mpu_alloc_block_size;
-};
-
-struct nic_cmd_flush_tcam_rules {
- struct hinic3_mgmt_msg_head head;
-
- u16 func_id; /* func_id */
- u16 rsvd;
-};
-
-struct nic_cmd_dfx_fdir_tcam_block_table {
- struct hinic3_mgmt_msg_head head;
- u8 tcam_type;
- u8 valid;
- u16 tcam_block_index;
- u16 use_function_id;
- u16 rsvd;
-};
-
-struct tcam_result {
- u32 qid;
- u32 rsvd;
-};
-
-#define TCAM_FLOW_KEY_SIZE (44)
-
-struct tcam_key_x_y {
- u8 x[TCAM_FLOW_KEY_SIZE];
- u8 y[TCAM_FLOW_KEY_SIZE];
-};
-
-struct nic_tcam_cfg_rule {
- u32 index;
- struct tcam_result data;
- struct tcam_key_x_y key;
-};
-
-#define TCAM_RULE_FDIR_TYPE 0
-#define TCAM_RULE_PPA_TYPE 1
-
-struct nic_cmd_fdir_add_rule {
- struct hinic3_mgmt_msg_head head;
-
- u16 func_id;
- u8 type;
- u8 fdir_ext; /* 0x1: flow bifur en bit */
- struct nic_tcam_cfg_rule rule;
-};
-
-struct nic_cmd_fdir_del_rules {
- struct hinic3_mgmt_msg_head head;
-
- u16 func_id;
- u8 type;
- u8 rsvd;
- u32 index_start;
- u32 index_num;
-};
-
-struct nic_cmd_fdir_get_rule {
- struct hinic3_mgmt_msg_head head;
-
- u32 index;
- u8 valid;
- u8 type;
- u16 rsvd;
- struct tcam_key_x_y key;
- struct tcam_result data;
- u64 packet_count;
- u64 byte_count;
-};
-
-struct nic_cmd_fdir_get_block_rules {
- struct hinic3_mgmt_msg_head head;
- u8 tcam_block_type; // only NIC_TCAM_BLOCK_TYPE_LARGE
- u8 tcam_table_type; // TCAM_RULE_PPA_TYPE or TCAM_RULE_FDIR_TYPE
- u16 tcam_block_index;
- u8 valid[NIC_TCAM_BLOCK_LARGE_SIZE];
- struct tcam_key_x_y key[NIC_TCAM_BLOCK_LARGE_SIZE];
- struct tcam_result data[NIC_TCAM_BLOCK_LARGE_SIZE];
-};
-
-struct hinic3_tcam_key_ipv4_mem {
- u32 rsvd1 : 4;
- u32 tunnel_type : 4;
- u32 ip_proto : 8;
- u32 rsvd0 : 16;
- u32 sipv4_h : 16;
- u32 ip_type : 1;
- u32 function_id : 15;
- u32 dipv4_h : 16;
- u32 sipv4_l : 16;
- u32 vlan_id : 15;
- u32 vlan_flag : 1;
- u32 dipv4_l : 16;
- u32 rsvd3;
- u32 dport : 16;
- u32 rsvd4 : 16;
- u32 rsvd5 : 16;
- u32 sport : 16;
- u32 outer_sipv4_h : 16;
- u32 rsvd6 : 16;
- u32 outer_dipv4_h : 16;
- u32 outer_sipv4_l : 16;
- u32 vni_h : 16;
- u32 outer_dipv4_l : 16;
- u32 rsvd7 : 16;
- u32 vni_l : 16;
-};
-
-union hinic3_tag_tcam_ext_info {
- struct {
- u32 id : 16; /* id */
- u32 type : 4; /* type: 0-func, 1-vmdq, 2-port, 3-rsvd, 4-trunk, 5-dp, 6-mc */
- u32 host_id : 3;
- u32 rsv : 8;
- u32 ext : 1;
- } bs;
- u32 value;
-};
-
-struct hinic3_tcam_key_ipv6_mem {
- u32 rsvd1 : 4;
- u32 tunnel_type : 4;
- u32 ip_proto : 8;
- u32 rsvd0 : 16;
- u32 sipv6_key0 : 16;
- u32 ip_type : 1;
- u32 function_id : 15;
- u32 sipv6_key2 : 16;
- u32 sipv6_key1 : 16;
- u32 sipv6_key4 : 16;
- u32 sipv6_key3 : 16;
- u32 sipv6_key6 : 16;
- u32 sipv6_key5 : 16;
- u32 dport : 16;
- u32 sipv6_key7 : 16;
- u32 dipv6_key0 : 16;
- u32 sport : 16;
- u32 dipv6_key2 : 16;
- u32 dipv6_key1 : 16;
- u32 dipv6_key4 : 16;
- u32 dipv6_key3 : 16;
- u32 dipv6_key6 : 16;
- u32 dipv6_key5 : 16;
- u32 rsvd2 : 16;
- u32 dipv6_key7 : 16;
-};
-
-struct hinic3_tcam_key_vxlan_ipv6_mem {
- u32 rsvd1 : 4;
- u32 tunnel_type : 4;
- u32 ip_proto : 8;
- u32 rsvd0 : 16;
-
- u32 dipv6_key0 : 16;
- u32 ip_type : 1;
- u32 function_id : 15;
-
- u32 dipv6_key2 : 16;
- u32 dipv6_key1 : 16;
-
- u32 dipv6_key4 : 16;
- u32 dipv6_key3 : 16;
-
- u32 dipv6_key6 : 16;
- u32 dipv6_key5 : 16;
-
- u32 dport : 16;
- u32 dipv6_key7 : 16;
-
- u32 rsvd2 : 16;
- u32 sport : 16;
-
- u32 outer_sipv4_h : 16;
- u32 rsvd3 : 16;
-
- u32 outer_dipv4_h : 16;
- u32 outer_sipv4_l : 16;
-
- u32 vni_h : 16;
- u32 outer_dipv4_l : 16;
-
- u32 rsvd4 : 16;
- u32 vni_l : 16;
-};
-
-struct tag_tcam_key {
- union {
- struct hinic3_tcam_key_ipv4_mem key_info;
- struct hinic3_tcam_key_ipv6_mem key_info_ipv6;
- struct hinic3_tcam_key_vxlan_ipv6_mem key_info_vxlan_ipv6;
- };
-
- union {
- struct hinic3_tcam_key_ipv4_mem key_mask;
- struct hinic3_tcam_key_ipv6_mem key_mask_ipv6;
- struct hinic3_tcam_key_vxlan_ipv6_mem key_mask_vxlan_ipv6;
- };
-};
-
-enum {
- PPA_TABLE_ID_CLEAN_CMD = 0,
- PPA_TABLE_ID_ADD_CMD,
- PPA_TABLE_ID_DEL_CMD,
- FDIR_TABLE_ID_ADD_CMD,
- FDIR_TABLE_ID_DEL_CMD,
- PPA_TABEL_ID_MAX
-};
-
-struct hinic3_ppa_cfg_table_id_cmd {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 rsvd0;
- u16 cmd;
- u16 table_id;
- u16 rsvd1;
-};
-
-struct hinic3_ppa_cfg_ppa_en_cmd {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 ppa_en;
- u8 rsvd;
-};
-
-struct hinic3_func_flow_bifur_en_cmd {
- struct hinic3_mgmt_msg_head msg_head;
- u16 func_id;
- u8 flow_bifur_en;
- u8 rsvd[5];
-};
-
-struct hinic3_port_flow_bifur_en_cmd {
- struct hinic3_mgmt_msg_head msg_head;
- u16 port_id;
- u8 flow_bifur_en;
- u8 rsvd[5];
-};
-
-struct hinic3_bond_mask_cmd {
- struct hinic3_mgmt_msg_head msg_head;
- u16 func_id;
- u8 bond_mask;
- u8 bond_en;
- u8 func_valid;
- u8 rsvd[3];
-};
-
-#define HINIC3_TX_SET_PROMISC_SKIP 0
-#define HINIC3_TX_GET_PROMISC_SKIP 1
-
-struct hinic3_tx_promisc_cfg {
- struct hinic3_mgmt_msg_head msg_head;
- u8 port_id;
- u8 promisc_skip_en; /* 0: disable tx promisc replication, 1: enable */
- u8 opcode; /* 0: set, 1: get */
- u8 rsvd1;
-};
-
-struct hinic3_ppa_cfg_mode_cmd {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 rsvd0;
- u8 ppa_mode;
- u8 qpc_func_nums;
- u16 base_qpc_func_id;
- u16 rsvd1;
-};
-
-struct hinic3_ppa_flush_en_cmd {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 rsvd0;
- u8 flush_en; /* 0 flush done, 1 in flush operation */
- u8 rsvd1;
-};
-
-struct hinic3_ppa_fdir_query_cmd {
- struct hinic3_mgmt_msg_head msg_head;
-
- u32 index;
- u32 rsvd;
- u64 pkt_nums;
- u64 pkt_bytes;
-};
-
-/* BIOS CONF */
-enum {
- NIC_NVM_DATA_SET = BIT(0), /* 1-save, 0-read */
- NIC_NVM_DATA_PXE = BIT(1),
- NIC_NVM_DATA_VLAN = BIT(2),
- NIC_NVM_DATA_VLAN_PRI = BIT(3),
- NIC_NVM_DATA_VLAN_ID = BIT(4),
- NIC_NVM_DATA_WORK_MODE = BIT(5),
- NIC_NVM_DATA_PF_SPEED_LIMIT = BIT(6),
- NIC_NVM_DATA_GE_MODE = BIT(7),
- NIC_NVM_DATA_AUTO_NEG = BIT(8),
- NIC_NVM_DATA_LINK_FEC = BIT(9),
- NIC_NVM_DATA_PF_ADAPTIVE_LINK = BIT(10),
- NIC_NVM_DATA_SRIOV_CONTROL = BIT(11),
- NIC_NVM_DATA_EXTEND_MODE = BIT(12),
- NIC_NVM_DATA_RESET = BIT(31),
-};
-
-#define BIOS_CFG_SIGNATURE 0x1923E518
-#define BIOS_OP_CFG_ALL(op_code_val) ((((op_code_val) >> 1) & (0xFFFFFFFF)) != 0)
-#define BIOS_OP_CFG_WRITE(op_code_val) ((((op_code_val) & NIC_NVM_DATA_SET)) != 0)
-#define BIOS_OP_CFG_PXE_EN(op_code_val) (((op_code_val) & NIC_NVM_DATA_PXE) != 0)
-#define BIOS_OP_CFG_VLAN_EN(op_code_val) (((op_code_val) & NIC_NVM_DATA_VLAN) != 0)
-#define BIOS_OP_CFG_VLAN_PRI(op_code_val) (((op_code_val) & NIC_NVM_DATA_VLAN_PRI) != 0)
-#define BIOS_OP_CFG_VLAN_ID(op_code_val) (((op_code_val) & NIC_NVM_DATA_VLAN_ID) != 0)
-#define BIOS_OP_CFG_WORK_MODE(op_code_val) (((op_code_val) & NIC_NVM_DATA_WORK_MODE) != 0)
-#define BIOS_OP_CFG_PF_BW(op_code_val) (((op_code_val) & NIC_NVM_DATA_PF_SPEED_LIMIT) != 0)
-#define BIOS_OP_CFG_GE_SPEED(op_code_val) (((op_code_val) & NIC_NVM_DATA_GE_MODE) != 0)
-#define BIOS_OP_CFG_AUTO_NEG(op_code_val) (((op_code_val) & NIC_NVM_DATA_AUTO_NEG) != 0)
-#define BIOS_OP_CFG_LINK_FEC(op_code_val) (((op_code_val) & NIC_NVM_DATA_LINK_FEC) != 0)
-#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) (((op_code_val) & NIC_NVM_DATA_PF_ADAPTIVE_LINK) != 0)
-#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val) (((op_code_val) & NIC_NVM_DATA_SRIOV_CONTROL) != 0)
-#define BIOS_OP_CFG_EXTEND_MODE(op_code_val) (((op_code_val) & NIC_NVM_DATA_EXTEND_MODE) != 0)
-#define BIOS_OP_CFG_RST_DEF_SET(op_code_val) (((op_code_val) & (u32)NIC_NVM_DATA_RESET) != 0)
-
-#define NIC_BIOS_CFG_MAX_PF_BW 100
-/* Note: This structure must be 4-byte aligned. */
-struct nic_bios_cfg {
- u32 signature;
- u8 pxe_en; /* PXE enable: 0 - disable 1 - enable */
- u8 extend_mode;
- u8 rsvd0[2];
- u8 pxe_vlan_en; /* PXE VLAN enable: 0 - disable 1 - enable */
- u8 pxe_vlan_pri; /* PXE VLAN priority: 0-7 */
- u16 pxe_vlan_id; /* PXE VLAN ID 1-4094 */
- u32 service_mode; /* @See CHIPIF_SERVICE_MODE_x */
- u32 pf_bw; /* PF rate, in percentage. The value ranges from 0 to 100. */
- u8 speed; /* enum of port speed */
- u8 auto_neg; /* Auto-Negotiation Switch 0 - Invalid Field 1 - On 2 - Off */
- u8 lanes; /* lane num */
- u8 fec; /* FEC mode, @See enum mag_cmd_port_fec */
- u8 auto_adapt; /* Adaptive Mode Configuration 0 - Invalid Configuration 1 - On 2 - Off */
- u8 func_valid; /* Whether func_id is valid; 0: invalid; other: valid */
- u8 func_id; /* This member is valid only when func_valid is not set to 0. */
- u8 sriov_en; /* SRIOV-EN: 0 - Invalid configuration, 1 - On, 2 - Off */
-};
-
-struct nic_cmd_bios_cfg {
- struct hinic3_mgmt_msg_head head;
- u32 op_code; /* Operation Code: Bit0[0: read 1:write, BIT1-6: cfg_mask */
- struct nic_bios_cfg bios_cfg;
-};
-
-struct nic_cmd_vhd_config {
- struct hinic3_mgmt_msg_head head;
-
- u16 func_id;
- u8 vhd_type;
- u8 virtio_small_enable; /* 0: mergeable mode, 1: small mode */
-};
-
-/* BOND */
-struct hinic3_create_bond_info {
- u32 bond_id;
- u32 master_slave_port_id;
- u32 slave_bitmap; /* bond port id bitmap */
- u32 poll_timeout; /* Bond device link check time */
- u32 up_delay; /* Temporarily reserved */
- u32 down_delay; /* Temporarily reserved */
- u32 bond_mode; /* Temporarily reserved */
- u32 active_pf; /* bond use active pf id */
- u32 active_port_max_num; /* Maximum number of active bond member interfaces */
- u32 active_port_min_num; /* Minimum number of active bond member interfaces */
- u32 xmit_hash_policy;
- u32 rsvd[2];
-};
-
-struct hinic3_cmd_create_bond {
- struct hinic3_mgmt_msg_head head;
- struct hinic3_create_bond_info create_bond_info;
-};
-
-struct hinic3_cmd_delete_bond {
- struct hinic3_mgmt_msg_head head;
- u32 bond_id;
- u32 rsvd[2];
-};
-
-struct hinic3_open_close_bond_info {
- u32 bond_id;
- u32 open_close_flag; /* Bond flag. 1: open; 0: close. */
- u32 rsvd[2];
-};
-
-struct hinic3_cmd_open_close_bond {
- struct hinic3_mgmt_msg_head head;
- struct hinic3_open_close_bond_info open_close_bond_info;
-};
-
-struct lacp_port_params {
- u16 port_number;
- u16 port_priority;
- u16 key;
- u16 system_priority;
- u8 system[ETH_ALEN];
- u8 port_state;
- u8 rsvd;
-};
-
-struct lacp_port_info {
- u32 selected;
- u32 aggregator_port_id;
-
- struct lacp_port_params actor;
- struct lacp_port_params partner;
-
- u64 tx_lacp_pkts;
- u64 rx_lacp_pkts;
- u64 rx_8023ad_drop;
- u64 tx_8023ad_drop;
- u64 unknown_pkt_drop;
- u64 rx_marker_pkts;
- u64 tx_marker_pkts;
-};
-
-struct hinic3_bond_status_info {
- struct hinic3_mgmt_msg_head head;
- u32 bond_id;
- u32 bon_mmi_status;
- u32 active_bitmap;
- u32 port_count;
-
- struct lacp_port_info port_info[4];
-
- u64 success_report_cnt[4];
- u64 fail_report_cnt[4];
-
- u64 poll_timeout;
- u64 fast_periodic_timeout;
- u64 slow_periodic_timeout;
- u64 short_timeout;
- u64 long_timeout;
- u64 aggregate_wait_timeout;
- u64 tx_period_timeout;
- u64 rx_marker_timer;
-};
-
-struct hinic3_bond_active_report_info {
- struct hinic3_mgmt_msg_head head;
- u32 bond_id;
- u32 bon_mmi_status;
- u32 active_bitmap;
-
- u8 rsvd[16];
-};
-
-/* IP checksum error packets, enable rss quadruple hash. */
-struct hinic3_ipcs_err_rss_enable_operation_s {
- struct hinic3_mgmt_msg_head head;
-
- u8 en_tag;
- u8 type; /* 1: set 0: get */
- u8 rsvd[2];
-};
-
-struct hinic3_smac_check_state {
- struct hinic3_mgmt_msg_head head;
- u8 smac_check_en; /* 1: enable 0: disable */
- u8 op_code; /* 1: set 0: get */
- u8 rsvd[2];
-};
-
-struct hinic3_clear_log_state {
- struct hinic3_mgmt_msg_head head;
- u32 type;
-};
-
-#endif /* HINIC_MGMT_INTERFACE_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
index 774193a..7bc9376 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
@@ -4,11 +4,12 @@
#ifndef HINIC3_MT_H
#define HINIC3_MT_H
-#define HINIC3_DRV_NAME "hisdk3"
+#define HINIC3_DRV_NAME "hinic3"
#define HINIC3_CHIP_NAME "hinic"
/* Interrupt at most records, interrupt will be recorded in the FFM */
#define NICTOOL_CMD_TYPE (0x18)
+#define HINIC3_CARD_NAME_MAX_LEN (128)
struct api_cmd_rd {
u32 pf_id;
@@ -110,7 +111,8 @@ enum dbgtool_cmd {
DBGTOOL_CMD_NUM
};
-#define PF_MAX_SIZE (16)
+#define HINIC_PF_MAX_SIZE (16)
+#define HINIC_VF_MAX_SIZE (4096)
#define BUSINFO_LEN (32)
enum module_name {
@@ -132,7 +134,9 @@ enum module_name {
SEND_TO_MIGRATE_DRIVER,
SEND_TO_PPA_DRIVER,
SEND_TO_CUSTOM_DRIVER = SEND_TO_SRV_DRV_BASE + 11,
- SEND_TO_DRIVER_MAX = SEND_TO_SRV_DRV_BASE + 15, /* reserved */
+ SEND_TO_VSOCK_DRIVER = SEND_TO_SRV_DRV_BASE + 14,
+ SEND_TO_BIFUR_DRIVER,
+ SEND_TO_DRIVER_MAX = SEND_TO_SRV_DRV_BASE + 16, /* reserved */
};
enum driver_cmd_type {
@@ -159,7 +163,7 @@ enum driver_cmd_type {
GET_CHIP_FAULT_STATS,
NIC_RSVD1,
NIC_RSVD2,
- NIC_RSVD3,
+ GET_OS_HOT_REPLACE_INFO,
GET_CHIP_ID,
GET_SINGLE_CARD_INFO,
GET_FIRMWARE_ACTIVE_STATUS,
@@ -170,7 +174,7 @@ enum driver_cmd_type {
GET_LOOPBACK_MODE = 32,
SET_LOOPBACK_MODE,
SET_LINK_MODE,
- SET_PF_BW_LIMIT,
+ SET_TX_PF_BW_LIMIT,
GET_PF_BW_LIMIT,
ROCE_CMD,
GET_POLL_WEIGHT,
@@ -188,6 +192,7 @@ enum driver_cmd_type {
GET_NIC_STATS_STRING,
GET_NIC_STATS_INFO,
GET_PF_ID,
+ GET_MBOX_CNT,
NIC_RSVD4,
NIC_RSVD5,
DCB_QOS_INFO,
@@ -204,16 +209,54 @@ enum driver_cmd_type {
RSS_INDIR,
PORT_ID,
+ SET_RX_PF_BW_LIMIT = 0x43,
+
GET_FUNC_CAP = 0x50,
GET_XSFP_PRESENT = 0x51,
GET_XSFP_INFO = 0x52,
DEV_NAME_TEST = 0x53,
+ GET_XSFP_INFO_COMP_CMIS = 0x54,
GET_WIN_STAT = 0x60,
WIN_CSR_READ = 0x61,
WIN_CSR_WRITE = 0x62,
WIN_API_CMD_RD = 0x63,
+ GET_FUSION_Q = 0x64,
+ ROCE_CMD_SET_LDCP_PARAM = 0x70,
+
+ ROCE_CMD_GET_QPC_FROM_CACHE = 0x80,
+ ROCE_CMD_GET_QPC_FROM_HOST = 0x81,
+ ROCE_CMD_GET_CQC_FROM_CACHE = 0x82,
+ ROCE_CMD_GET_CQC_FROM_HOST = 0x83,
+ ROCE_CMD_GET_SRQC_FROM_CACHE = 0x84,
+ ROCE_CMD_GET_SRQC_FROM_HOST = 0x85,
+ ROCE_CMD_GET_MPT_FROM_CACHE = 0x86,
+ ROCE_CMD_GET_MPT_FROM_HOST = 0x87,
+ ROCE_CMD_GET_GID_FROM_CACHE = 0x88,
+ ROCE_CMD_GET_QPC_CQC_PI_CI = 0x89,
+ ROCE_CMD_GET_QP_COUNT = 0x8a,
+ ROCE_CMD_GET_DEV_ALGO = 0x8b,
+
+ ROCE_CMD_START_CAP_PACKET = 0x90,
+ ROCE_CMD_STOP_CAP_PACKET = 0x91,
+ ROCE_CMD_QUERY_CAP_INFO = 0x92,
+ ROCE_CMD_ENABLE_QP_CAP_PACKET = 0x93,
+ ROCE_CMD_DISABLE_QP_CAP_PACKET = 0x94,
+ ROCE_CMD_QUERY_QP_CAP_INFO = 0x95,
+
+ ROCE_CMD_ENABLE_BW_CTRL = 0xa0,
+ ROCE_CMD_DISABLE_BW_CTRL = 0xa1,
+ ROCE_CMD_CHANGE_BW_CTRL_PARAM = 0xa2,
+ ROCE_CMD_QUERY_BW_CTRL_PARAM = 0xa3,
+
+ ROCE_CMD_TIMEOUT_ALARM = 0xb0,
+ ROCE_CMD_PORT_TRAFFIC = 0Xb1,
+ ROCE_CMD_BOND_HASH_TYPE_SET = 0xb2,
+
+ BIFUR_SET_ENABLE = 0xc0,
+ BIFUR_GET_ENABLE = 0xc1,
+
VM_COMPAT_TEST = 0xFF
};
@@ -229,7 +272,8 @@ enum sm_cmd_type {
SM_CTR_RD64,
SM_CTR_RD32_CLEAR,
SM_CTR_RD64_PAIR_CLEAR,
- SM_CTR_RD64_CLEAR
+ SM_CTR_RD64_CLEAR,
+ SM_CTR_RD16_CLEAR,
};
struct cqm_stats {
@@ -317,10 +361,22 @@ struct pf_info {
};
struct card_info {
- struct pf_info pf[PF_MAX_SIZE];
+ struct pf_info pf[HINIC_PF_MAX_SIZE];
u32 pf_num;
};
+struct func_mbox_cnt_info {
+ char bus_info[BUSINFO_LEN];
+ u64 send_cnt;
+ u64 ack_cnt;
+};
+
+struct card_mbox_cnt_info {
+ struct func_mbox_cnt_info func_info[HINIC_PF_MAX_SIZE +
+ HINIC_VF_MAX_SIZE];
+ u32 func_num;
+};
+
struct hinic3_nic_loop_mode {
u32 loop_mode;
u32 loop_ctrl;
@@ -661,6 +717,161 @@ struct get_card_bond_msg_s {
struct bond_all_msg_s all_msg[MAX_BONDING_CNT_PER_CARD];
};
+#define MAX_FUSION_Q_STATS_STR_LEN 16
+#define MAX_FUSION_Q_NUM 256
+struct queue_status_s {
+ pid_t tgid;
+ char status[MAX_FUSION_Q_STATS_STR_LEN];
+};
+struct fusion_q_status_s {
+ u16 queue_num;
+ struct queue_status_s queue[MAX_FUSION_Q_NUM];
+};
+
+struct fusion_q_tx_hw_page {
+ u64 phy_addr;
+ u64 *map_addr;
+};
+
+struct fusion_sq_info {
+ u16 q_id;
+ u16 pi;
+ u16 ci; /* sw_ci */
+ u16 fi; /* hw_ci */
+ u32 q_depth;
+ u16 pi_reverse;
+ u16 wqebb_size;
+ u8 priority;
+ u16 *ci_addr;
+ u64 cla_addr;
+ void *slq_handle;
+ struct fusion_q_tx_hw_page direct_wqe;
+ struct fusion_q_tx_hw_page doorbell;
+ u32 page_idx;
+ u32 glb_sq_id;
+};
+
+struct fusion_q_tx_wqe {
+ u32 data[4];
+};
+
+struct fusion_rq_info {
+ u16 q_id;
+ u16 delta;
+ u16 hw_pi;
+ u16 ci; /* sw_ci */
+ u16 sw_pi;
+ u16 wqebb_size;
+ u16 q_depth;
+ u16 buf_len;
+
+ void *slq_handle;
+ u64 ci_wqe_page_addr;
+ u64 ci_cla_tbl_addr;
+
+ u8 coalesc_timer_cfg;
+ u8 pending_limt;
+ u16 msix_idx;
+ u32 msix_vector;
+};
+
+struct fusion_q_rx_wqe {
+ u32 data[8];
+};
+
+struct fusion_q_rx_cqe {
+ union {
+ struct {
+ unsigned int checksum_err : 16;
+ unsigned int lro_num : 8;
+ unsigned int rsvd1 : 7;
+ unsigned int rx_done : 1;
+ } bs;
+ unsigned int value;
+ } dw0;
+
+ union {
+ struct {
+ unsigned int vlan : 16;
+ unsigned int length : 16;
+ } bs;
+ unsigned int value;
+ } dw1;
+
+ union {
+ struct {
+ unsigned int pkt_types : 12;
+ unsigned int rsvd : 4;
+ unsigned int udp_0 : 1;
+ unsigned int ipv6_ex_add : 1;
+ unsigned int loopback : 1;
+ unsigned int umbcast : 2;
+ unsigned int vlan_offload_en : 1;
+ unsigned int tag_num : 2;
+ unsigned int rss_type : 8;
+ } bs;
+ unsigned int value;
+ } dw2;
+
+ union {
+ struct {
+ unsigned int rss_hash_value;
+ } bs;
+ unsigned int value;
+ } dw3;
+
+ union {
+ struct {
+ unsigned int tx_ts_seq : 16;
+ unsigned int message_1588_offset : 8;
+ unsigned int message_1588_type : 4;
+ unsigned int rsvd : 1;
+ unsigned int if_rx_ts : 1;
+ unsigned int if_tx_ts : 1;
+ unsigned int if_1588 : 1;
+ } bs;
+ unsigned int value;
+ } dw4;
+
+ union {
+ struct {
+ unsigned int ts;
+ } bs;
+ unsigned int value;
+ } dw5;
+
+ union {
+ struct {
+ unsigned int lro_ts;
+ } bs;
+ unsigned int value;
+ } dw6;
+
+ union {
+ struct {
+ unsigned int rsvd0;
+ } bs;
+ unsigned int value;
+ } dw7; /* 16Bytes Align */
+};
+
+struct os_hot_repalce_func_info {
+ char card_name[HINIC3_CARD_NAME_MAX_LEN];
+ int bus_num;
+ int valid;
+ int bdf;
+ int partition;
+ int backup_pf;
+ int pf_idx;
+ int port_id;
+};
+
+#define ALL_CARD_PF_NUM 2048 /* 64 card * 32 pf */
+struct os_hot_replace_info {
+ struct os_hot_repalce_func_info func_infos[ALL_CARD_PF_NUM];
+ u32 func_cnt;
+};
+
int alloc_buff_in(void *hwdev, struct msg_module *nt_msg, u32 in_size, void **buf_in);
int alloc_buff_out(void *hwdev, struct msg_module *nt_msg, u32 out_size, void **buf_out);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
index 81e4030..7cd9e4d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
@@ -15,6 +15,9 @@
#include <linux/ip.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#ifdef HAVE_XDP_SUPPORT
#include <linux/bpf.h>
#endif
@@ -28,6 +31,10 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
+#include "nic_npu_cmd.h"
+
+#include "vram_common.h"
+
#define HINIC3_DEFAULT_RX_CSUM_OFFLOAD 0xFFF
#define HINIC3_LRO_DEFAULT_COAL_PKT_SIZE 32
@@ -47,8 +54,64 @@ static void hinic3_nic_set_rx_mode(struct net_device *netdev)
queue_work(nic_dev->workq, &nic_dev->rx_mode_work);
}
+static void hinic3_free_irq_vram(struct hinic3_nic_dev *nic_dev, struct hinic3_dyna_txrxq_params *in_q_params)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ struct hinic3_dyna_txrxq_params q_params = nic_dev->q_params;
+
+ if (q_params.irq_cfg == NULL)
+ return;
+
+ size = sizeof(struct hinic3_irq) * (q_params.num_qps);
+
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)q_params.irq_cfg, q_params.irq_cfg_vram_name, size);
+ q_params.irq_cfg = NULL;
+ } else {
+ kfree(in_q_params->irq_cfg);
+ in_q_params->irq_cfg = NULL;
+ }
+}
+
+static int hinic3_alloc_irq_vram(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_dyna_txrxq_params *q_params, bool is_up_eth)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ u16 func_id;
+
+ size = sizeof(struct hinic3_irq) * q_params->num_qps;
+
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(q_params->irq_cfg_vram_name,
+ VRAM_NAME_MAX_LEN, "%s%u",
+ VRAM_NIC_IRQ_VRAM, func_id);
+ q_params->irq_cfg = (struct hinic3_irq *)hi_vram_kalloc(
+ q_params->irq_cfg_vram_name, size);
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq vram alloc failed.\n");
+ return -ENOMEM;
+ }
+ /* in order to clear napi stored in vram, irq need to init when eth up */
+ if (is_up_eth) {
+ memset(q_params->irq_cfg, 0, size);
+ }
+ } else {
+ q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq alloc failed.\n");
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_txrxq_params *q_params)
+ struct hinic3_dyna_txrxq_params *q_params,
+ bool is_up_eth)
{
u32 size;
int err;
@@ -70,12 +133,9 @@ static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
goto alloc_rxqs_res_arr_err;
}
- size = sizeof(*q_params->irq_cfg) * q_params->num_qps;
- q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
- if (!q_params->irq_cfg) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to alloc irq resource array\n");
- err = -ENOMEM;
+ err = hinic3_alloc_irq_vram(nic_dev, q_params, is_up_eth);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc irq resource array\n");
goto alloc_irq_cfg_err;
}
@@ -102,8 +162,7 @@ alloc_rxqs_res_err:
q_params->txqs_res);
alloc_txqs_res_err:
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ hinic3_free_irq_vram(nic_dev, q_params);
alloc_irq_cfg_err:
kfree(q_params->rxqs_res);
@@ -119,13 +178,14 @@ alloc_rxqs_res_arr_err:
static void hinic3_free_txrxq_resources(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_txrxq_params *q_params)
{
+ int is_in_kexec = vram_get_kexec_flag();
hinic3_free_rxqs_res(nic_dev, q_params->num_qps, q_params->rq_depth,
q_params->rxqs_res);
hinic3_free_txqs_res(nic_dev, q_params->num_qps, q_params->sq_depth,
q_params->txqs_res);
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ if (is_in_kexec == 0)
+ hinic3_free_irq_vram(nic_dev, q_params);
kfree(q_params->rxqs_res);
q_params->rxqs_res = NULL;
@@ -161,6 +221,7 @@ static int hinic3_configure_txrxqs(struct hinic3_nic_dev *nic_dev,
static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos;
if (!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
@@ -171,12 +232,13 @@ static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
num_cos = hinic3_get_dev_user_cos_num(nic_dev);
hinic3_update_qp_cos_cfg(nic_dev, num_cos);
/* For now, we don't support to change num_cos */
- if (num_cos > nic_dev->cos_config_num_max ||
+ if (num_cos > dcb->cos_config_num_max ||
nic_dev->q_params.num_qps < num_cos) {
nicif_err(nic_dev, drv, netdev, "Invalid num_cos: %u or num_qps: %u, disable DCB\n",
num_cos, nic_dev->q_params.num_qps);
nic_dev->q_params.num_cos = 0;
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
/* if we can't enable rss or get enough num_qps,
* need to sync default configure to hw
*/
@@ -190,11 +252,14 @@ static int hinic3_configure(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
- err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
- if (err) {
- nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
- return err;
+ if (is_in_kexec == 0) {
+ err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
+ return err;
+ }
}
config_dcb_qps_map(nic_dev);
@@ -256,10 +321,11 @@ static void config_dcb_num_qps(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dyna_txrxq_params *q_params,
u16 max_qps)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos = q_params->num_cos;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (!num_cos || num_cos > nic_dev->cos_config_num_max || num_cos > max_qps)
+ if (!num_cos || num_cos > dcb->cos_config_num_max || num_cos > max_qps)
return; /* will disable DCB in config_dcb_qps_map() */
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
@@ -334,57 +400,10 @@ static void hinic3_destroy_num_qps(struct hinic3_nic_dev *nic_dev)
kfree(nic_dev->qps_irq_info);
}
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev)
-{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- err = hinic3_set_port_enable(nic_dev->hwdev, false, HINIC3_CHANNEL_NIC);
- if (!err)
- nic_dev->force_port_disable = true;
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
-{
- int err = 0;
-
- down(&nic_dev->port_state_sem);
-
- nic_dev->force_port_disable = false;
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
- HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- /* Do nothing when force disable
- * Port will disable when call force port disable
- * and should not enable port when in force mode
- */
- if (nic_dev->force_port_disable) {
- up(&nic_dev->port_state_sem);
- return 0;
- }
-
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
+ return hinic3_set_port_enable(nic_dev->hwdev, enable,
HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
}
static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
@@ -401,7 +420,8 @@ static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+ struct hinic3_dyna_txrxq_params *trxq_params,
+ bool is_up_eth)
{
int err;
@@ -416,7 +436,7 @@ static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
return err;
}
- err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params);
+ err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params, is_up_eth);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc txrxq resources\n");
hinic3_free_qps(nic_dev->hwdev, qp_params);
@@ -544,9 +564,53 @@ vport_enable_err:
return err;
}
+static int hinic3_flush_rq_and_check(struct hinic3_nic_dev *nic_dev,
+ u16 glb_func_id)
+{
+ struct hinic3_flush_rq *rq_flush_msg = NULL;
+ struct hinic3_cmd_buf *cmd_buf = NULL;
+ int out_buf_len = sizeof(struct hinic3_flush_rq);
+ u16 rq_id;
+ u64 out_param = 0;
+ int ret;
+
+ cmd_buf = hinic3_alloc_cmd_buf(nic_dev->hwdev);
+ if (!cmd_buf) {
+ nic_err(&nic_dev->pdev->dev, "Failed to allocate cmd buf\n");
+ return -ENOMEM;
+ }
+
+ cmd_buf->size = sizeof(struct hinic3_flush_rq);
+ rq_flush_msg = (struct hinic3_flush_rq *)cmd_buf->buf;
+ rq_flush_msg->dw.bs.func_id = glb_func_id;
+ for (rq_id = 0; rq_id < nic_dev->q_params.num_qps; rq_id++) {
+ rq_flush_msg->dw.bs.rq_id = rq_id;
+ hinic3_cpu_to_be32(rq_flush_msg, out_buf_len);
+ ret = hinic3_cmdq_direct_resp(nic_dev->hwdev, HINIC3_MOD_L2NIC,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ cmd_buf, &out_param, 0,
+ HINIC3_CHANNEL_NIC);
+ if (ret != 0 || out_param != 0) {
+ nic_err(&nic_dev->pdev->dev, "Failed to flush rq, ret:%d, func:%u, rq:%u\n",
+ ret, glb_func_id, rq_id);
+ goto err;
+ }
+ hinic3_be32_to_cpu(rq_flush_msg, out_buf_len);
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Func:%u rq_num:%u flush rq success\n",
+ glb_func_id, nic_dev->q_params.num_qps);
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return 0;
+err:
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return -1;
+}
+
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
{
u16 glb_func_id;
+ int is_in_kexec = vram_get_kexec_flag();
netif_carrier_off(nic_dev->netdev);
netif_tx_disable(nic_dev->netdev);
@@ -559,18 +623,21 @@ void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, 0);
- hinic3_maybe_set_port_state(nic_dev, false);
+ if (is_in_kexec != 0)
+ nicif_info(nic_dev, drv, nic_dev->netdev, "Skip changing mag status!\n");
+ else
+ hinic3_maybe_set_port_state(nic_dev, false);
glb_func_id = hinic3_global_func_id(nic_dev->hwdev);
hinic3_set_vport_enable(nic_dev->hwdev, glb_func_id, false,
HINIC3_CHANNEL_NIC);
hinic3_flush_txqs(nic_dev->netdev);
- /* After set vport disable 100ms,
- * no packets will be send to host
- * FPGA set 2000ms
- */
- msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+ if (is_in_kexec == 0) {
+ msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+ } else {
+ (void)hinic3_flush_rq_and_check(nic_dev, glb_func_id);
+ }
hinic3_flush_qps_res(nic_dev->hwdev);
}
}
@@ -583,11 +650,12 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_qp_params new_qp_params = {0};
struct hinic3_dyna_qp_params cur_qp_params = {0};
int err;
+ bool is_free_resources = false;
hinic3_config_num_qps(nic_dev, trxq_params);
err = hinic3_alloc_channel_resources(nic_dev, &new_qp_params,
- trxq_params);
+ trxq_params, false);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc channel resources\n");
@@ -599,10 +667,19 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
hinic3_close_channel(nic_dev, &cur_qp_params);
hinic3_free_channel_resources(nic_dev, &cur_qp_params,
&nic_dev->q_params);
+ is_free_resources = true;
}
if (nic_dev->num_qp_irq > trxq_params->num_qps)
hinic3_qp_irq_change(nic_dev, trxq_params->num_qps);
+
+ if (is_free_resources) {
+ err = hinic3_alloc_irq_vram(nic_dev, trxq_params, false);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Change chl alloc irq failed\n");
+ goto alloc_irq_err;
+ }
+ }
nic_dev->q_params = *trxq_params;
if (reopen_handler)
@@ -623,7 +700,7 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
vport_up_err:
hinic3_close_channel(nic_dev, &new_qp_params);
-
+alloc_irq_err:
open_channel_err:
hinic3_free_channel_resources(nic_dev, &new_qp_params, trxq_params);
@@ -654,7 +731,7 @@ int hinic3_open(struct net_device *netdev)
}
err = hinic3_alloc_channel_resources(nic_dev, &qp_params,
- &nic_dev->q_params);
+ &nic_dev->q_params, true);
if (err)
goto alloc_channel_res_err;
@@ -693,12 +770,31 @@ setup_qps_err:
return err;
}
+static void hinic3_delete_napi(struct hinic3_nic_dev *nic_dev)
+{
+ u16 q_id;
+ int is_in_kexec = vram_get_kexec_flag();
+ struct hinic3_irq *irq_cfg = NULL;
+
+ if (is_in_kexec == 0 || nic_dev->q_params.irq_cfg == NULL)
+ return;
+
+ for (q_id = 0; q_id < nic_dev->q_params.num_qps; q_id++) {
+ irq_cfg = &(nic_dev->q_params.irq_cfg[q_id]);
+ qp_del_napi(irq_cfg);
+ }
+
+ hinic3_free_irq_vram(nic_dev, &nic_dev->q_params);
+}
+
int hinic3_close(struct net_device *netdev)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic3_dyna_qp_params qp_params = {0};
if (!test_and_clear_bit(HINIC3_INTF_UP, &nic_dev->flags)) {
+ /* delete napi in os hotreplace rollback */
+ hinic3_delete_napi(nic_dev);
nicif_info(nic_dev, drv, netdev, "Netdev already close, do nothing\n");
return 0;
}
@@ -835,6 +931,7 @@ static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb
#define GET_DSCP_PRI_OFFSET 2
static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev, struct sk_buff *skb)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int dscp_cp;
if (skb->protocol == htons(ETH_P_IP))
@@ -842,8 +939,8 @@ static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev, struct sk_buff *skb
else if (skb->protocol == htons(ETH_P_IPV6))
dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
else
- return nic_dev->hw_dcb_cfg.default_cos;
- return nic_dev->hw_dcb_cfg.dscp2cos[dscp_cp];
+ return dcb->hw_dcb_cfg.default_cos;
+ return dcb->hw_dcb_cfg.dscp2cos[dscp_cp];
}
#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY)
@@ -869,6 +966,7 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif /* end of HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK */
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u16 txq;
u8 cos, qp_num;
@@ -889,18 +987,19 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (nic_dev->hw_dcb_cfg.trust == DCB_PCP) {
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP) {
if (skb->vlan_tci)
- cos = nic_dev->hw_dcb_cfg.pcp2cos[skb->vlan_tci >> VLAN_PRIO_SHIFT];
+ cos = dcb->hw_dcb_cfg.pcp2cos[skb->vlan_tci >>
+ VLAN_PRIO_SHIFT];
else
- cos = nic_dev->hw_dcb_cfg.default_cos;
+ cos = dcb->hw_dcb_cfg.default_cos;
} else {
cos = hinic3_get_dscp_up(nic_dev, skb);
}
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cos] ?
- txq % nic_dev->hw_dcb_cfg.cos_qp_num[cos] : 0;
- txq = nic_dev->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
+ qp_num = dcb->hw_dcb_cfg.cos_qp_num[cos] ?
+ txq % dcb->hw_dcb_cfg.cos_qp_num[cos] : 0;
+ txq = dcb->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
}
return txq;
@@ -978,7 +1077,7 @@ static struct net_device_stats *hinic3_get_stats(struct net_device *netdev)
stats->rx_packets = packets;
stats->rx_bytes = bytes;
stats->rx_errors = errors;
- stats->rx_dropped = dropped;
+ stats->rx_dropped = dropped + nic_dev->vport_stats.rx_discard_vport;
#ifndef HAVE_VOID_NDO_GET_STATS64
return stats;
@@ -1025,10 +1124,17 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
u32 mtu = (u32)new_mtu;
int err = 0;
-
+ int is_in_kexec = vram_get_kexec_flag();
#ifdef HAVE_XDP_SUPPORT
u32 xdp_max_mtu;
+#endif
+ if (is_in_kexec != 0) {
+ nicif_info(nic_dev, drv, netdev, "Hotreplace skip change mtu\n");
+ return err;
+ }
+
+#ifdef HAVE_XDP_SUPPORT
if (hinic3_is_xdp_enable(nic_dev)) {
xdp_max_mtu = hinic3_xdp_max_mtu(nic_dev);
if (mtu > xdp_max_mtu) {
@@ -1047,6 +1153,7 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
nicif_info(nic_dev, drv, nic_dev->netdev, "Change mtu from %u to %d\n",
netdev->mtu, new_mtu);
netdev->mtu = mtu;
+ nic_dev->nic_vram->vram_mtu = mtu;
}
return err;
@@ -1080,6 +1187,71 @@ static int hinic3_set_mac_addr(struct net_device *netdev, void *addr)
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+static int hinic3_udp_tunnel_port_config(struct net_device *netdev,
+ struct udp_tunnel_info *ti,
+ u8 action)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u16 func_id = hinic3_global_func_id(nic_dev->hwdev);
+ u16 dst_port;
+ int ret = 0;
+
+ switch (ti->type) {
+ case UDP_TUNNEL_TYPE_VXLAN:
+ dst_port = ntohs(ti->port);
+ ret = hinic3_vlxan_port_config(nic_dev->hwdev, func_id,
+ dst_port, action);
+ if (ret != 0) {
+ nicif_warn(nic_dev, drv, netdev,
+ "Failed to set vxlan port %u to device(%d)\n",
+ dst_port, ret);
+ break;
+ }
+ nicif_info(nic_dev, link, netdev, "Vxlan dst port set to %u\n",
+ action == HINIC3_CMD_OP_ADD ?
+ dst_port : ntohs(VXLAN_OFFLOAD_PORT_LE));
+ break;
+ default:
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to add port, only vxlan dst port is supported\n");
+ ret = -EINVAL;
+ }
+ return ret;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+static void hinic3_udp_tunnel_add(struct net_device *netdev, struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+static void hinic3_udp_tunnel_del(struct net_device *netdev, struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD */
+
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev, __attribute__((unused)) unsigned int table,
+ __attribute__((unused))unsigned int entry, struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev, __attribute__((unused)) unsigned int table,
+ __attribute__((unused)) unsigned int entry, struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static int
hinic3_vlan_rx_add_vid(struct net_device *netdev,
__always_unused __be16 proto,
@@ -1126,7 +1298,7 @@ hinic3_vlan_rx_kill_vid(struct net_device *netdev,
int err = 0;
col = VID_COL(nic_dev, vid);
- line = VID_LINE(nic_dev, vid);
+ line = (int)VID_LINE(nic_dev, vid);
/* In the broadcast scenario, ucode finds the corresponding function
* based on VLAN 0 of vlan table. If we delete VLAN 0, the VLAN function
@@ -1165,14 +1337,12 @@ static int hinic3_vlan_restore(struct net_device *netdev)
return -EFAULT;
rcu_read_lock();
for (i = 0; i < VLAN_N_VID; i++) {
-/* lint -e778 */
#ifdef HAVE_VLAN_FIND_DEV_DEEP_RCU
vlandev =
__vlan_find_dev_deep_rcu(netdev, htons(ETH_P_8021Q), i);
#else
vlandev = __vlan_find_dev_deep(netdev, htons(ETH_P_8021Q), i);
#endif
-/* lint +e778 */
col = VID_COL(nic_dev, i);
line = VID_LINE(nic_dev, i);
if (!vlandev && (vlan_bitmap[line] & (1UL << col)) != 0) {
@@ -1330,12 +1500,17 @@ static int set_feature_vlan_filter(struct hinic3_nic_dev *nic_dev,
return 0;
#ifdef NEED_VLAN_RESTORE
- if (en)
+ if (en) {
err = hinic3_vlan_restore(nic_dev->netdev);
+ if (err) {
+ hinic3_err(nic_dev, drv, "vlan restore failed\n");
+ *failed_features |= vlan_filter_feature;
+ return err;
+ }
+ }
#endif
- if (err == 0)
- err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
+ err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
if (err) {
hinic3_err(nic_dev, drv, "%s rx vlan filter failed\n",
SET_FEATURES_OP_STR(en));
@@ -1429,8 +1604,8 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
struct hinic3_nic_dev *adapter = netdev_priv(netdev);
int err;
- if (is_multicast_ether_addr(mac) || /*lint !e574*/
- vf >= pci_num_vf(adapter->pdev)) /*lint !e574*/
+ if (is_multicast_ether_addr(mac) ||
+ vf >= pci_num_vf(adapter->pdev))
return -EINVAL;
err = hinic3_set_vf_mac(adapter->hwdev, OS_VF_ID_TO_HW(vf), mac);
@@ -1448,7 +1623,6 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
return 0;
}
-/*lint -save -e574 -e734*/
#ifdef IFLA_VF_MAX
static int set_hw_vf_vlan(void *hwdev, u16 cur_vlanprio, int vf,
u16 vlan, u8 qos)
@@ -1670,7 +1844,7 @@ static int hinic3_ndo_set_vf_bw(struct net_device *netdev, int vf,
return -EIO;
/* rate limit cannot be less than 0 and greater than link speed */
- if (max_tx_rate < 0 || max_tx_rate > speeds[port_info.speed]) {
+ if (max_tx_rate < 0 || max_tx_rate > (int)(speeds[port_info.speed])) {
nicif_err(adapter, drv, netdev, "Set vf max tx rate must be in [0 - %u]\n",
speeds[port_info.speed]);
return -EINVAL;
@@ -1719,7 +1893,7 @@ static int hinic3_xdp_setup(struct hinic3_nic_dev *nic_dev,
int max_mtu = hinic3_xdp_max_mtu(nic_dev);
int q_id;
- if (nic_dev->netdev->mtu > max_mtu) {
+ if (nic_dev->netdev->mtu > (u32)max_mtu) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to setup xdp program, the current MTU %d is larger than max allowed MTU %d\n",
nic_dev->netdev->mtu, max_mtu);
@@ -1844,6 +2018,10 @@ static const struct net_device_ops hinic3_netdev_ops = {
.ndo_xdp = hinic3_xdp,
#endif
#endif
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+ .ndo_udp_tunnel_add = hinic3_udp_tunnel_add,
+ .ndo_udp_tunnel_del = hinic3_udp_tunnel_del,
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD */
#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT
};
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
index cc00bdc..1bc6a14 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
@@ -10,6 +10,8 @@
#include "hinic3_common.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
/* ************************ array index define ********************* */
#define ARRAY_INDEX_0 0
@@ -21,6 +23,35 @@
#define ARRAY_INDEX_6 6
#define ARRAY_INDEX_7 7
+#define XSFP_TLV_PRE_INFO_LEN 4
+
+enum hinic3_link_port_type {
+ LINK_PORT_UNKNOWN,
+ LINK_PORT_OPTICAL_MM,
+ LINK_PORT_OPTICAL_SM,
+ LINK_PORT_PAS_COPPER,
+ LINK_PORT_ACC,
+ LINK_PORT_BASET,
+ LINK_PORT_AOC = 0x40,
+ LINK_PORT_ELECTRIC,
+ LINK_PORT_BACKBOARD_INTERFACE,
+};
+
+enum hilink_fibre_subtype {
+ FIBRE_SUBTYPE_SR = 1,
+ FIBRE_SUBTYPE_LR,
+ FIBRE_SUBTYPE_MAX,
+};
+
+enum hilink_fec_type {
+ HILINK_FEC_NOT_SET,
+ HILINK_FEC_RSFEC,
+ HILINK_FEC_BASEFEC,
+ HILINK_FEC_NOFEC,
+ HILINK_FEC_LLRSFE,
+ HILINK_FEC_MAX_TYPE,
+};
+
struct hinic3_sq_attr {
u8 dma_attr_off;
u8 pending_limit;
@@ -58,24 +89,32 @@ struct hinic3_port_routine_cmd {
struct mag_cmd_get_xsfp_present abs;
};
+struct hinic3_port_routine_cmd_extern {
+ bool mpu_send_xsfp_tlv_info;
+
+ struct drv_mag_cmd_get_xsfp_tlv_rsp std_xsfp_tlv_info;
+};
+
struct hinic3_nic_cfg {
- struct semaphore cfg_lock;
+ struct semaphore cfg_lock;
/* Valid when pfc is disable */
- bool pause_set;
- struct nic_pause_config nic_pause;
+ bool pause_set;
+ struct nic_pause_config nic_pause;
- u8 pfc_en;
- u8 pfc_bitmap;
+ u8 pfc_en;
+ u8 pfc_bitmap;
- struct nic_port_info port_info;
+ struct nic_port_info port_info;
/* percentage of pf link bandwidth */
- u32 pf_bw_limit;
- u32 rsvd2;
+ u32 pf_bw_tx_limit;
+ u32 pf_bw_rx_limit;
- struct hinic3_port_routine_cmd rt_cmd;
- struct mutex sfp_mutex; /* mutex used for copy sfp info */
+ struct hinic3_port_routine_cmd rt_cmd;
+ struct hinic3_port_routine_cmd_extern rt_cmd_ext;
+ /* mutex used for copy sfp info */
+ struct mutex sfp_mutex;
};
struct hinic3_nic_io {
@@ -84,7 +123,7 @@ struct hinic3_nic_io {
void *dev_hdl;
u8 link_status;
- u8 rsvd1;
+ u8 direct;
u32 rsvd2;
struct hinic3_io_queue *sq;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
index 2c1b565..525a353 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
@@ -20,10 +20,126 @@
#include "hinic3_nic_io.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_common.h"
#include "hinic3_nic_cfg.h"
+#include "vram_common.h"
+
+int hinic3_delete_bond(void *hwdev)
+{
+ struct hinic3_cmd_delete_bond cmd_delete_bond;
+ u16 out_size = sizeof(cmd_delete_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_delete_bond, 0, sizeof(cmd_delete_bond));
+ cmd_delete_bond.bond_id = HINIC3_INVALID_BOND_ID;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_DELETE,
+ &cmd_delete_bond, sizeof(cmd_delete_bond),
+ &cmd_delete_bond, &out_size);
+ if (err || !out_size || cmd_delete_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to delete bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_delete_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_delete_bond.bond_id != HINIC3_INVALID_BOND_ID) {
+ nic_info(nic_io->dev_hdl, "Delete bond success\n");
+ }
+
+ return 0;
+}
+
+int hinic3_open_close_bond(void *hwdev, u32 bond_en)
+{
+ struct hinic3_cmd_open_close_bond cmd_open_close_bond;
+ u16 out_size = sizeof(cmd_open_close_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_open_close_bond, 0, sizeof(cmd_open_close_bond));
+ cmd_open_close_bond.open_close_bond_info.bond_id = HINIC3_INVALID_BOND_ID;
+ cmd_open_close_bond.open_close_bond_info.open_close_flag = bond_en;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_OPEN_CLOSE,
+ &cmd_open_close_bond, sizeof(cmd_open_close_bond),
+ &cmd_open_close_bond, &out_size);
+ if (err || !out_size || cmd_open_close_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to %s bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ bond_en == true ? "open" : "close", err, cmd_open_close_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_open_close_bond.open_close_bond_info.bond_id != HINIC3_INVALID_BOND_ID) {
+ nic_info(nic_io->dev_hdl, "%s bond success\n", bond_en == true ? "Open" : "Close");
+ }
+
+ return 0;
+}
+
+int hinic3_create_bond(void *hwdev, u32 *bond_id)
+{
+ struct hinic3_cmd_create_bond cmd_create_bond;
+ u16 out_size = sizeof(cmd_create_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_create_bond, 0, sizeof(cmd_create_bond));
+ cmd_create_bond.create_bond_info.default_param_flag = true;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_CREATE,
+ &cmd_create_bond, sizeof(cmd_create_bond),
+ &cmd_create_bond, &out_size);
+ if (err || !out_size || cmd_create_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to create default bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_create_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_create_bond.create_bond_info.bond_id != HINIC3_INVALID_BOND_ID) {
+ *bond_id = cmd_create_bond.create_bond_info.bond_id;
+ nic_info(nic_io->dev_hdl, "Create bond success\n");
+ }
+
+ return 0;
+}
+
int hinic3_set_ci_table(void *hwdev, struct hinic3_sq_attr *attr)
{
struct hinic3_cmd_cons_idx_attr cons_idx_attr;
@@ -37,6 +153,8 @@ int hinic3_set_ci_table(void *hwdev, struct hinic3_sq_attr *attr)
memset(&cons_idx_attr, 0, sizeof(cons_idx_attr));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cons_idx_attr.func_idx = hinic3_global_func_id(hwdev);
@@ -152,6 +270,8 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -183,7 +303,7 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
}
EXPORT_SYMBOL(hinic3_del_mac);
-int hinic3_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
+int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
u16 func_id)
{
struct hinic3_port_mac_update mac_info;
@@ -197,6 +317,8 @@ int hinic3_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -247,6 +369,8 @@ int hinic3_get_default_mac(void *hwdev, u8 *mac_addr)
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
mac_info.func_id = hinic3_global_func_id(hwdev);
@@ -292,6 +416,45 @@ static int hinic3_config_vlan(struct hinic3_nic_io *nic_io, u8 opcode,
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action)
+{
+ struct hinic3_cmd_vxlan_port_info vxlan_port_info;
+ u16 out_size = sizeof(vxlan_port_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ memset(&vxlan_port_info, 0, sizeof(vxlan_port_info));
+ vxlan_port_info.opcode = action;
+ vxlan_port_info.cfg_mode = 0; // other ethtool set
+ vxlan_port_info.func_id = func_id;
+ vxlan_port_info.vxlan_port = port;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+ &vxlan_port_info, sizeof(vxlan_port_info),
+ &vxlan_port_info, &out_size);
+ if (err || !out_size || vxlan_port_info.msg_head.status) {
+ if (vxlan_port_info.msg_head.status == 0x2) {
+ nic_warn(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port because it has already been set by hinicadm\n",
+ action == HINIC3_CMD_OP_ADD ? "add" : "delete");
+ } else {
+ nic_err(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port, err: %d, status: 0x%x, out size: 0x%x\n",
+ action == HINIC3_CMD_OP_ADD ? "add" : "delete",
+ err, vxlan_port_info.msg_head.status, out_size);
+ }
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
{
struct hinic3_nic_io *nic_io = NULL;
@@ -300,6 +463,9 @@ int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan_id, func_id);
}
@@ -311,6 +477,9 @@ int hinic3_del_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_DEL, vlan_id, func_id);
}
@@ -354,6 +523,9 @@ int hinic3_set_dcb_state(void *hwdev, struct hinic3_dcb_state *dcb_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (!memcmp(&nic_io->dcb_state, dcb_state, sizeof(nic_io->dcb_state)))
return 0;
@@ -515,6 +687,8 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_cfg = &nic_io->nic_cfg;
@@ -540,7 +714,6 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
{
- struct hinic3_nic_cfg *nic_cfg = NULL;
struct hinic3_nic_io *nic_io = NULL;
int err = 0;
@@ -548,17 +721,13 @@ int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- nic_cfg = &nic_io->nic_cfg;
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_hw_pause(nic_io, HINIC3_CMD_OP_GET, nic_pause);
if (err)
return err;
- if (nic_cfg->pause_set || !nic_pause->auto_neg) {
- nic_pause->rx_pause = nic_cfg->nic_pause.rx_pause;
- nic_pause->tx_pause = nic_cfg->nic_pause.tx_pause;
- }
-
return 0;
}
@@ -573,6 +742,8 @@ int hinic3_sync_dcb_state(void *hwdev, u8 op_code, u8 state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&dcb_state, 0, sizeof(dcb_state));
@@ -659,44 +830,6 @@ int hinic3_cache_out_qps_res(void *hwdev)
return 0;
}
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats)
-{
- struct hinic3_port_stats *port_stats = NULL;
- struct hinic3_port_stats_info stats_info;
- u16 out_size = sizeof(*port_stats);
- struct hinic3_nic_io *nic_io = NULL;
- int err;
-
- port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
- if (!port_stats)
- return -ENOMEM;
-
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
-
- memset(&stats_info, 0, sizeof(stats_info));
-
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_PORT_STAT,
- &stats_info, sizeof(stats_info),
- port_stats, &out_size);
- if (err || !out_size || port_stats->msg_head.status) {
- nic_err(nic_io->dev_hdl,
- "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
- err, port_stats->msg_head.status, out_size);
- err = -EIO;
- goto out;
- }
-
- memcpy(stats, &port_stats->stats, sizeof(*stats));
-
-out:
- kfree(port_stats);
-
- return err;
-}
-EXPORT_SYMBOL(hinic3_get_fpga_phy_port_stats);
-
int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *stats)
{
struct hinic3_port_stats_info stats_info;
@@ -712,6 +845,8 @@ int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *
memset(&vport_stats, 0, sizeof(vport_stats));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
stats_info.func_id = func_id;
@@ -778,6 +913,8 @@ int hinic3_set_port_mtu(void *hwdev, u16 new_mtu)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (new_mtu < HINIC3_MIN_MTU_SIZE) {
nic_err(nic_io->dev_hdl,
@@ -808,6 +945,9 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&feature_nego, 0, sizeof(feature_nego));
feature_nego.func_id = hinic3_global_func_id(hwdev);
feature_nego.opcode = opcode;
@@ -829,29 +969,21 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return 0;
}
-static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
+static int hinic3_get_bios_pf_bw_tx_limit(void *hwdev, struct hinic3_nic_io *nic_io, u16 func_id, u32 *pf_rate)
{
- struct hinic3_nic_io *nic_io = NULL;
+ int err = 0; // default success
struct nic_cmd_bios_cfg cfg = {{0}};
u16 out_size = sizeof(cfg);
- int err;
- if (!hwdev || !pf_bw_limit)
- return -EINVAL;
-
- if (hinic3_func_type(hwdev) == TYPE_VF || !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
- return 0;
-
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- cfg.bios_cfg.func_id = (u8)hinic3_global_func_id(hwdev);
+ cfg.bios_cfg.func_id = (u8)func_id;
cfg.bios_cfg.func_valid = 1;
- cfg.op_code = 0 | NIC_NVM_DATA_PF_SPEED_LIMIT;
+ cfg.op_code = 0 | NIC_NVM_DATA_PF_TX_SPEED_LIMIT;
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BIOS_CFG, &cfg, sizeof(cfg),
&cfg, &out_size);
if (err || !out_size || cfg.head.status) {
nic_err(nic_io->dev_hdl,
- "Failed to get bios pf bandwidth limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ "Failed to get bios pf bandwidth tx limit, err: %d, status: 0x%x, out size: 0x%x\n",
err, cfg.head.status, out_size);
return -EIO;
}
@@ -861,13 +993,77 @@ static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
nic_warn(nic_io->dev_hdl, "Invalid bios configuration data, signature: 0x%x\n",
cfg.bios_cfg.signature);
- if (cfg.bios_cfg.pf_bw > MAX_LIMIT_BW) {
+ if (cfg.bios_cfg.pf_tx_bw > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
+ cfg.bios_cfg.pf_tx_bw);
+ return -EINVAL;
+ }
+
+ (*pf_rate) = cfg.bios_cfg.pf_tx_bw;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_rx_limit(void *hwdev, struct hinic3_nic_io *nic_io, u16 func_id, u32 *pf_rate)
+{
+ int err = 0; // default success
+ struct nic_rx_rate_bios_cfg rx_bios_conf = {{0}};
+ u16 out_size = sizeof(rx_bios_conf);
+
+ rx_bios_conf.func_id = (u8)func_id;
+ rx_bios_conf.op_code = 0; /* 1-save, 0-read */
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_RX_RATE_CFG, &rx_bios_conf, sizeof(rx_bios_conf),
+ &rx_bios_conf, &out_size);
+ if (rx_bios_conf.msg_head.status == HINIC3_MGMT_CMD_UNSUPPORTED && err == 0) { // Compatible older firmware
+ nic_warn(nic_io->dev_hdl, "Not support get bios pf bandwidth rx limit\n");
+ return 0;
+ } else if (err || !out_size || rx_bios_conf.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get bios pf bandwidth rx limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, rx_bios_conf.msg_head.status, out_size);
+ return -EIO;
+ }
+ if (rx_bios_conf.rx_rate_limit > MAX_LIMIT_BW) {
nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
- cfg.bios_cfg.pf_bw);
+ rx_bios_conf.rx_rate_limit);
return -EINVAL;
}
- *pf_bw_limit = cfg.bios_cfg.pf_bw;
+ (*pf_rate) = rx_bios_conf.rx_rate_limit;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit, u8 direct)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u32 pf_rate = 0;
+ int err = 0;
+ u16 func_id;
+ func_id = hinic3_global_func_id(hwdev);
+
+ if (!hwdev || !pf_bw_limit)
+ return -EINVAL;
+
+ if (hinic3_func_type(hwdev) == TYPE_VF || !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
+ return 0;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (direct == HINIC3_NIC_TX) {
+ err = hinic3_get_bios_pf_bw_tx_limit(hwdev, nic_io, func_id, &pf_rate);
+ } else if (direct == HINIC3_NIC_RX) {
+ err = hinic3_get_bios_pf_bw_rx_limit(hwdev, nic_io, func_id, &pf_rate);
+ }
+
+ if (err != 0)
+ return err;
+
+ if (pf_rate > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n", pf_rate);
+ return -EINVAL;
+ }
+ *pf_bw_limit = pf_rate;
return 0;
}
@@ -876,8 +1072,9 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
{
struct hinic3_cmd_tx_rate_cfg rate_cfg = {{0}};
struct hinic3_nic_io *nic_io = NULL;
+ u32 rate_limit;
u16 out_size = sizeof(rate_cfg);
- u32 pf_rate;
+ u32 pf_rate = 0;
int err;
u32 speed_convert[PORT_SPEED_UNKNOWN] = {
0, 10, 100, 1000, 10000, 25000, 40000, 50000, 100000, 200000
@@ -892,19 +1089,21 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
return -EINVAL;
}
- if (nic_io->nic_cfg.pf_bw_limit == MAX_LIMIT_BW) {
- pf_rate = 0;
- } else {
+ rate_limit = (nic_io->direct == HINIC3_NIC_TX) ?
+ nic_io->nic_cfg.pf_bw_tx_limit : nic_io->nic_cfg.pf_bw_rx_limit;
+
+ if (rate_limit != MAX_LIMIT_BW) {
/* divided by 100 to convert to percentage */
- pf_rate = (speed_convert[speed_level] / 100) * nic_io->nic_cfg.pf_bw_limit;
+ pf_rate = (speed_convert[speed_level] / 100) * rate_limit;
/* bandwidth limit is very small but not unlimit in this case */
- if (pf_rate == 0 && speed_level != PORT_SPEED_NOT_SET)
+ if ((pf_rate == 0) && (speed_level != PORT_SPEED_NOT_SET))
pf_rate = 1;
}
rate_cfg.func_id = hinic3_global_func_id(hwdev);
rate_cfg.min_rate = 0;
rate_cfg.max_rate = pf_rate;
+ rate_cfg.direct = nic_io->direct;
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_MAX_MIN_RATE, &rate_cfg,
sizeof(rate_cfg), &rate_cfg, &out_size);
@@ -927,6 +1126,8 @@ int hinic3_set_nic_feature_to_hw(void *hwdev)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return nic_feature_nego(hwdev, HINIC3_CMD_OP_SET, &nic_io->feature_cap, 1);
}
@@ -936,6 +1137,8 @@ u64 hinic3_get_feature_cap(void *hwdev)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
return nic_io->feature_cap;
}
@@ -945,6 +1148,9 @@ void hinic3_update_nic_feature(void *hwdev, u64 s_feature)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
+
nic_io->feature_cap = s_feature;
nic_info(nic_io->dev_hdl, "Update nic feature to 0x%llx\n", nic_io->feature_cap);
@@ -978,6 +1184,7 @@ static int hinic3_init_nic_io(void *hwdev, void *pcidev_hdl, void *dev_hdl,
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_abs = false;
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_info = false;
+ (*nic_io)->nic_cfg.rt_cmd_ext.mpu_send_xsfp_tlv_info = false;
return 0;
}
@@ -994,11 +1201,14 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
{
struct hinic3_nic_io *nic_io = NULL;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
err = hinic3_init_nic_io(hwdev, pcidev_hdl, dev_hdl, &nic_io);
if (err)
return err;
+ nic_io->rx_buff_len = rx_buff_len;
+
err = hinic3_register_service_adapter(hwdev, nic_io, SERVICE_T_NIC);
if (err) {
nic_err(nic_io->dev_hdl, "Failed to register service adapter\n");
@@ -1011,10 +1221,12 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
goto set_used_state_err;
}
- err = hinic3_init_function_table(nic_io);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to init function table\n");
- goto err_out;
+ if (is_in_kexec == 0) {
+ err = hinic3_init_function_table(nic_io);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to init function table\n");
+ goto err_out;
+ }
}
err = hinic3_get_nic_feature_from_hw(hwdev, &nic_io->feature_cap, 1);
@@ -1025,9 +1237,19 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
sdk_info(dev_hdl, "nic features: 0x%llx\n", nic_io->feature_cap);
- err = hinic3_get_bios_pf_bw_limit(hwdev, &nic_io->nic_cfg.pf_bw_limit);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to get pf bandwidth limit\n");
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_tx_limit,
+ HINIC3_NIC_TX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf tx bandwidth limit\n");
+ goto err_out;
+ }
+
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_rx_limit,
+ HINIC3_NIC_RX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf rx bandwidth limit\n");
goto err_out;
}
@@ -1037,12 +1259,13 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
goto err_out;
}
- nic_io->rx_buff_len = rx_buff_len;
-
return 0;
err_out:
- hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 0, HINIC3_CHANNEL_NIC);
+ if (hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 0,
+ HINIC3_CHANNEL_NIC) != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to set function svc used state\n");
+ }
set_used_state_err:
hinic3_unregister_service_adapter(hwdev, SERVICE_T_NIC);
@@ -1092,6 +1315,8 @@ int hinic3_force_drop_tx_pkt(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&pkt_drop, 0, sizeof(pkt_drop));
pkt_drop.port = hinic3_physical_port_id(hwdev);
@@ -1120,6 +1345,8 @@ int hinic3_set_rx_mode(void *hwdev, u32 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&rx_mode_cfg, 0, sizeof(rx_mode_cfg));
rx_mode_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1148,6 +1375,8 @@ int hinic3_set_rx_vlan_offload(void *hwdev, u8 en)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_cfg, 0, sizeof(vlan_cfg));
vlan_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1176,6 +1405,9 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
if (!nic_io->vf_infos || is_zero_ether_addr(vf_info->drv_mac_addr))
return 0;
@@ -1215,6 +1447,8 @@ static int hinic3_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en,
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_cfg, 0, sizeof(lro_cfg));
lro_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1246,6 +1480,8 @@ static int hinic3_set_rx_lro_timer(void *hwdev, u32 timer_value)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_timer, 0, sizeof(lro_timer));
lro_timer.opcode = HINIC3_CMD_OP_SET;
@@ -1278,6 +1514,8 @@ int hinic3_set_rx_lro_state(void *hwdev, u8 lro_en, u32 lro_timer,
ipv6_en = lro_en ? 1 : 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_info(nic_io->dev_hdl, "Set LRO max coalesce packet size to %uK\n",
lro_max_pkt_len);
@@ -1306,6 +1544,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_filter, 0, sizeof(vlan_filter));
vlan_filter.func_id = hinic3_global_func_id(hwdev);
@@ -1325,7 +1565,6 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
{
- // struct hinic_hwdev *dev = hwdev;
struct nic_cmd_capture_info cap_info = {{0}};
u16 out_size = sizeof(cap_info);
int err;
@@ -1334,7 +1573,6 @@ int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
return -EINVAL;
/* 2 function capture types */
- // cap_info.op_type = UP_UCAPTURE_OP_TYPE_FUNC;
cap_info.is_en_trx = cap_en;
cap_info.func_port = func_id;
@@ -1359,6 +1597,8 @@ int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (tcam_rule->index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to add is invalid\n");
return -EINVAL;
@@ -1394,6 +1634,8 @@ int hinic3_del_tcam_rule(void *hwdev, u32 index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to del is invalid\n");
return -EINVAL;
@@ -1443,6 +1685,8 @@ static int hinic3_mgmt_tcam_block(void *hwdev, u8 alloc_en, u16 *index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&tcam_block_info, 0,
sizeof(struct nic_cmd_ctrl_tcam_block_out));
@@ -1488,6 +1732,8 @@ int hinic3_set_fdir_tcam_rule_filter(void *hwdev, bool enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
port_tcam_cmd.func_id = hinic3_global_func_id(hwdev);
port_tcam_cmd.tcam_enable = (u8)enable;
@@ -1516,6 +1762,9 @@ int hinic3_flush_tcam_rule(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&tcam_flush, 0, sizeof(struct nic_cmd_flush_tcam_rules));
tcam_flush.func_id = hinic3_global_func_id(hwdev);
@@ -1546,6 +1795,9 @@ int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -1588,8 +1840,10 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return -EINVAL;
}
- if (hinic3_func_type(hwdev) == TYPE_VF)
+ if (hinic3_func_type(hwdev) == TYPE_VF) {
+ pr_err("VF are not supported to set link state.\n");
return -EINVAL;
+ }
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
if (!nic_io) {
@@ -1606,3 +1860,35 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return 0;
}
EXPORT_SYMBOL(hinic3_pf_set_vf_link_state);
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid)
+{
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ u16 out_size = sizeof(outband_cfg_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !outband_default_vid)
+ return -EINVAL;
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_OUTBAND_CFG,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size);
+ if (err || !out_size || outband_cfg_info.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get outband cfg, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, outband_cfg_info.msg_head.status, out_size);
+ return -EINVAL;
+ }
+
+ *outband_default_vid = outband_cfg_info.outband_default_vid;
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
index ee0587c..0fe7b9f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
@@ -7,9 +7,9 @@
#include <linux/types.h>
#include <linux/netdevice.h>
-#include "hinic3_mgmt_interface.h"
+#include "nic_mpu_cmd_defs.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#define OS_VF_ID_TO_HW(os_vf_id) ((os_vf_id) + 1)
#define HW_VF_ID_TO_OS(hw_vf_id) ((hw_vf_id) - 1)
@@ -54,6 +54,8 @@
#define MAX_LIMIT_BW 100
+#define HINIC3_INVALID_BOND_ID 0xffffffff
+
enum hinic3_valid_link_settings {
HILINK_LINK_SET_SPEED = 0x1,
HILINK_LINK_SET_AUTONEG = 0x2,
@@ -67,6 +69,11 @@ enum hinic3_link_follow_status {
HINIC3_LINK_FOLLOW_STATUS_MAX,
};
+enum hinic3_nic_pf_direct {
+ HINIC3_NIC_RX = 0,
+ HINIC3_NIC_TX,
+};
+
struct hinic3_link_ksettings {
u32 valid_bitmap;
u8 speed; /* enum nic_speed_level */
@@ -150,8 +157,12 @@ struct nic_port_info {
u8 duplex;
u8 speed;
u8 fec;
+ u8 lanes;
+ u8 rsvd;
u32 supported_mode;
u32 advertised_mode;
+ u32 supported_fec_mode;
+ u32 bond_speed;
};
struct nic_pause_config {
@@ -176,11 +187,17 @@ struct hinic3_rxq_hw {
#define MODULE_TYPE_QSFP28 0x11
#define MODULE_TYPE_QSFP 0x0C
#define MODULE_TYPE_QSFP_PLUS 0x0D
+#define MODULE_TYPE_DSFP 0x1B
+#define MODULE_TYPE_QSFP_CMIS 0x1E
#define TCAM_IP_TYPE_MASK 0x1
#define TCAM_TUNNEL_TYPE_MASK 0xF
#define TCAM_FUNC_ID_MASK 0x7FFF
+int hinic3_delete_bond(void *hwdev);
+int hinic3_open_close_bond(void *hwdev, u32 bond_en);
+int hinic3_create_bond(void *hwdev, u32 *bond_id);
+
int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule);
int hinic3_del_tcam_rule(void *hwdev, u32 index);
@@ -201,7 +218,7 @@ int hinic3_flush_tcam_rule(void *hwdev);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic3_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
+int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
u16 func_id);
/* *
@@ -333,7 +350,7 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr);
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr);
/* *
* @brief hinic3_vf_info_vlanprio - get vf vlan priority
@@ -508,7 +525,14 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table);
*/
int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats);
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats);
+/* *
+ * @brief hinic3_get_phy_rsfec_stats - get rsfec stats
+ * @param hwdev: device pointer to hwdev
+ * @param stats: rsfec(Reed-Solomon Forward Error Correction) stats
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats);
int hinic3_set_port_funcs_state(void *hwdev, bool enable);
@@ -544,6 +568,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl);
void hinic3_clear_vfs_info(void *hwdev);
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id);
+
int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id);
int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
@@ -563,10 +589,13 @@ int hinic3_set_autoneg(void *hwdev, bool enable);
int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext);
int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len);
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len);
bool hinic3_if_sfp_absent(void *hwdev);
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info);
-
+int hinic3_get_sfp_tlv_info(void *hwdev,
+ struct drv_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info,
+ const struct mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req);
/* *
* @brief hinic3_set_nic_feature_to_hw - sync nic feature to hardware
* @param hwdev: device pointer to hwdev
@@ -618,4 +647,18 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level);
int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type);
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+/* *
+ * @brief hinic3_vlxan_port_config - add/del vxlan dst port
+ * @param hwdev: device pointer to hwdev
+ * @param func_id: function id
+ * @param port: vxlan dst port
+ * @param action: add or del, del will set to default value (0x12B5)
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action);
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
index b46cf78..654673f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
@@ -21,7 +21,8 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
/*lint -e806*/
static unsigned char set_vf_link_state;
@@ -116,7 +117,7 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
err = hinic3_set_vlan_ctx(nic_io, glb_func_id, vlan_tag,
NIC_CONFIG_ALL_QUEUE_VLAN_CTX,
opcode == HINIC3_CMD_OP_ADD);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d vlan ctx, err: %d\n",
HW_VF_ID_TO_OS(vf_id), err);
@@ -137,22 +138,21 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
/* this function just be called by hinic3_ndo_set_vf_mac,
* others are not permitted.
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr)
{
- struct vf_data_storage *vf_info;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_info = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
-#ifndef __VMWARE__
+
/* duplicate request, so just return success */
if (ether_addr_equal(vf_info->user_mac_addr, mac_addr))
return 0;
-#else
- if (ether_addr_equal(vf_info->user_mac_addr, mac_addr))
- return 0;
-#endif
ether_addr_copy(vf_info->user_mac_addr, mac_addr);
return 0;
@@ -160,13 +160,15 @@ int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan, qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan = vlan;
@@ -180,17 +182,20 @@ int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_infos = nic_io->vf_infos;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_DEL,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_info(nic_io->dev_hdl, "Remove VLAN %u on VF %d\n",
@@ -205,11 +210,13 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
u16 hinic3_vf_info_vlanprio(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
u16 pf_vlan, vlanprio;
u8 pf_qos;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
pf_vlan = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan;
pf_qos = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos;
@@ -222,9 +229,14 @@ int hinic3_set_vf_link_state(void *hwdev, u16 vf_id, int link)
{
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ struct vf_data_storage *vf_infos = NULL;
u8 link_status = 0;
+ if (!nic_io)
+ return -EINVAL;
+
+ vf_infos = nic_io->vf_infos;
+
switch (link) {
case HINIC3_IFLA_VF_LINK_STATE_AUTO:
vf_infos[HW_VF_ID_TO_OS(vf_id)].link_forced = false;
@@ -264,6 +276,9 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_infos = nic_io->vf_infos;
memset(&spoofchk_cfg, 0, sizeof(spoofchk_cfg));
@@ -288,9 +303,11 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
bool hinic3_vf_info_spoofchk(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].spoofchk;
}
@@ -304,7 +321,7 @@ int hinic3_set_vf_trust(void *hwdev, u16 vf_id, bool trust)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
+ if (!nic_io || vf_id > nic_io->max_vfs)
return -EINVAL;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust = trust;
@@ -317,11 +334,11 @@ bool hinic3_get_vf_trust(void *hwdev, int vf_id)
struct hinic3_nic_io *nic_io = NULL;
if (!hwdev)
- return -EINVAL;
+ return false;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
- return -EINVAL;
+ if (!nic_io || vf_id > nic_io->max_vfs)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust;
}
@@ -339,6 +356,7 @@ static int hinic3_set_vf_tx_rate_max_min(struct hinic3_nic_io *nic_io,
rate_cfg.func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf_id;
rate_cfg.max_rate = max_rate;
rate_cfg.min_rate = min_rate;
+ rate_cfg.direct = HINIC3_NIC_TX;
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
&rate_cfg, sizeof(rate_cfg), &rate_cfg,
@@ -359,13 +377,16 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (!HINIC3_SUPPORT_RATE_LIMIT(hwdev)) {
nic_err(nic_io->dev_hdl, "Current function doesn't support to set vf rate limit\n");
return -EOPNOTSUPP;
}
err = hinic3_set_vf_tx_rate_max_min(nic_io, vf_id, max_rate, min_rate);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].max_rate = max_rate;
@@ -376,12 +397,16 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
void hinic3_get_vf_config(void *hwdev, u16 vf_id, struct ifla_vf_info *ivi)
{
- struct vf_data_storage *vfinfo;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vfinfo = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
vfinfo = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vfinfo)
+ return;
ivi->vf = HW_VF_ID_TO_OS(vf_id);
ether_addr_copy(ivi->mac, vfinfo->user_mac_addr);
@@ -455,12 +480,12 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
nic_io->hwdev, hinic3_vf_event_handler);
- if (err)
+ if (err != 0)
return err;
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
nic_io->hwdev, hinic3_vf_mag_event_handler);
- if (err)
+ if (err != 0)
goto reg_hilink_err;
memset(®ister_info, 0, sizeof(register_info));
@@ -472,6 +497,12 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
®ister_info, &out_size, 0,
HINIC3_CHANNEL_NIC);
if (err || !out_size || register_info.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev)) {
+ nic_warn(nic_io->dev_hdl,
+ "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, register_info.msg_head.status, out_size);
+ return 0;
+ }
nic_err(nic_io->dev_hdl, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
err, register_info.msg_head.status, out_size);
err = -EIO;
@@ -506,18 +537,18 @@ static int pf_init_vf_infos(struct hinic3_nic_io *nic_io)
for (i = 0; i < nic_io->max_vfs; i++) {
err = hinic3_init_vf_infos(nic_io, i);
- if (err)
+ if (err != 0)
goto init_vf_infos_err;
}
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
nic_io->hwdev, hinic3_pf_mbox_handler);
- if (err)
+ if (err != 0)
goto register_pf_mbox_cb_err;
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
nic_io->hwdev, hinic3_pf_mag_mbox_handler);
- if (err)
+ if (err != 0)
goto register_pf_mag_mbox_cb_err;
return 0;
@@ -540,16 +571,16 @@ int hinic3_vf_func_init(struct hinic3_nic_io *nic_io)
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
nic_io->hwdev, hinic3_pf_event_handler);
- if (err)
+ if (err != 0)
return err;
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
nic_io->hwdev, hinic3_pf_mag_event_handler);
- if (err)
+ if (err != 0)
goto register_mgmt_msg_cb_err;
err = pf_init_vf_infos(nic_io);
- if (err)
+ if (err != 0)
goto pf_init_vf_infos_err;
return 0;
@@ -576,9 +607,15 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
&unregister, sizeof(unregister),
&unregister, &out_size, 0,
HINIC3_CHANNEL_NIC);
- if (err || !out_size || unregister.msg_head.status)
- nic_err(nic_io->dev_hdl, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
- err, unregister.msg_head.status, out_size);
+ if (err || !out_size || unregister.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev))
+ nic_info(nic_io->dev_hdl,
+ "vRoCE VF notify PF unsuccessful is allowed");
+ else
+ nic_err(nic_io->dev_hdl,
+ "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, unregister.msg_head.status, out_size);
+ }
hinic3_unregister_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
} else {
@@ -587,6 +624,7 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
hinic3_unregister_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
hinic3_clear_vfs_info(nic_io->hwdev);
kfree(nic_io->vf_infos);
+ nic_io->vf_infos = NULL;
}
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
@@ -595,11 +633,15 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
static void clear_vf_infos(void *hwdev, u16 vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
u16 func_id;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
func_id = hinic3_glb_pf_vf_offset(hwdev) + vf_id;
vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
@@ -628,10 +670,57 @@ static void clear_vf_infos(void *hwdev, u16 vf_id)
void hinic3_clear_vfs_info(void *hwdev)
{
+ u16 i;
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- u16 i;
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
for (i = 0; i < nic_io->max_vfs; i++)
clear_vf_infos(hwdev, OS_VF_ID_TO_HW(i));
}
+
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id)
+{
+ int err = 0;
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ struct vf_data_storage *vf_infos = NULL;
+ u16 out_size = sizeof(outband_cfg_info);
+ u16 vf_id;
+ struct hinic3_nic_io *nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return 0;
+ }
+
+ vf_id = func_id - hinic3_glb_pf_vf_offset(nic_io->hwdev);
+ vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+ if (vf_infos->registered) {
+ outband_cfg_info.func_id = func_id;
+ outband_cfg_info.outband_default_vid = vlan_id;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_L2NIC,
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return 0;
+ }
+ if (err || !out_size || outband_cfg_info.msg_head.status)
+ nic_err(nic_io->dev_hdl,
+ "outband cfg event to VF %d failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err,
+ outband_cfg_info.msg_head.status, out_size);
+ }
+
+ return err;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
deleted file mode 100644
index 31e224a..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
- * File Name : hinic3_comm_cmd.h
- * Version : Initial Draft
- * Created : 2019/4/25
- * Last Modified :
- * Description : NIC Commands between Driver and MPU
- * Function List :
- */
-
-#ifndef HINIC3_NIC_CMD_H
-#define HINIC3_NIC_CMD_H
-
-/* Commands between NIC to MPU
- */
-enum hinic3_nic_cmd {
- HINIC3_NIC_CMD_VF_REGISTER = 0, /* only for PFD and VFD */
-
- /* FUNC CFG */
- HINIC3_NIC_CMD_SET_FUNC_TBL = 5,
- HINIC3_NIC_CMD_SET_VPORT_ENABLE,
- HINIC3_NIC_CMD_SET_RX_MODE,
- HINIC3_NIC_CMD_SQ_CI_ATTR_SET,
- HINIC3_NIC_CMD_GET_VPORT_STAT,
- HINIC3_NIC_CMD_CLEAN_VPORT_STAT,
- HINIC3_NIC_CMD_CLEAR_QP_RESOURCE,
- HINIC3_NIC_CMD_CFG_FLEX_QUEUE,
- /* LRO CFG */
- HINIC3_NIC_CMD_CFG_RX_LRO,
- HINIC3_NIC_CMD_CFG_LRO_TIMER,
- HINIC3_NIC_CMD_FEATURE_NEGO,
- HINIC3_NIC_CMD_CFG_LOCAL_LRO_STATE,
-
- HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
-
- /* MAC & VLAN CFG */
- HINIC3_NIC_CMD_GET_MAC = 20,
- HINIC3_NIC_CMD_SET_MAC,
- HINIC3_NIC_CMD_DEL_MAC,
- HINIC3_NIC_CMD_UPDATE_MAC,
- HINIC3_NIC_CMD_GET_ALL_DEFAULT_MAC,
-
- HINIC3_NIC_CMD_CFG_FUNC_VLAN,
- HINIC3_NIC_CMD_SET_VLAN_FILTER_EN,
- HINIC3_NIC_CMD_SET_RX_VLAN_OFFLOAD,
- HINIC3_NIC_CMD_SMAC_CHECK_STATE,
-
- /* SR-IOV */
- HINIC3_NIC_CMD_CFG_VF_VLAN = 40,
- HINIC3_NIC_CMD_SET_SPOOPCHK_STATE,
- /* RATE LIMIT */
- HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
-
- /* RSS CFG */
- HINIC3_NIC_CMD_RSS_CFG = 60,
- HINIC3_NIC_CMD_RSS_TEMP_MGR, /* TODO: delete after implement nego cmd */
- HINIC3_NIC_CMD_GET_RSS_CTX_TBL, /* TODO: delete: move to ucode cmd */
- HINIC3_NIC_CMD_CFG_RSS_HASH_KEY,
- HINIC3_NIC_CMD_CFG_RSS_HASH_ENGINE,
- HINIC3_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC,
- /* IP checksum error packets, enable rss quadruple hash */
- HINIC3_NIC_CMD_IPCS_ERR_RSS_ENABLE_OP = 66,
-
- /* PPA/FDIR */
- HINIC3_NIC_CMD_ADD_TC_FLOW = 80,
- HINIC3_NIC_CMD_DEL_TC_FLOW,
- HINIC3_NIC_CMD_GET_TC_FLOW,
- HINIC3_NIC_CMD_FLUSH_TCAM,
- HINIC3_NIC_CMD_CFG_TCAM_BLOCK,
- HINIC3_NIC_CMD_ENABLE_TCAM,
- HINIC3_NIC_CMD_GET_TCAM_BLOCK,
- HINIC3_NIC_CMD_CFG_PPA_TABLE_ID,
- HINIC3_NIC_CMD_SET_PPA_EN = 88,
- HINIC3_NIC_CMD_CFG_PPA_MODE,
- HINIC3_NIC_CMD_CFG_PPA_FLUSH,
- HINIC3_NIC_CMD_SET_FDIR_STATUS,
- HINIC3_NIC_CMD_GET_PPA_COUNTER,
-
- /* PORT CFG */
- HINIC3_NIC_CMD_SET_PORT_ENABLE = 100,
- HINIC3_NIC_CMD_CFG_PAUSE_INFO,
-
- HINIC3_NIC_CMD_SET_PORT_CAR,
- HINIC3_NIC_CMD_SET_ER_DROP_PKT,
-
- HINIC3_NIC_CMD_VF_COS,
- HINIC3_NIC_CMD_SETUP_COS_MAPPING,
- HINIC3_NIC_CMD_SET_ETS,
- HINIC3_NIC_CMD_SET_PFC,
- HINIC3_NIC_CMD_QOS_ETS,
- HINIC3_NIC_CMD_QOS_PFC,
- HINIC3_NIC_CMD_QOS_DCB_STATE,
- HINIC3_NIC_CMD_QOS_PORT_CFG,
- HINIC3_NIC_CMD_QOS_MAP_CFG,
- HINIC3_NIC_CMD_FORCE_PKT_DROP,
- HINIC3_NIC_CMD_TX_PAUSE_EXCP_NOTICE = 118,
- HINIC3_NIC_CMD_INQUIRT_PAUSE_CFG = 119,
-
- /* MISC */
- HINIC3_NIC_CMD_BIOS_CFG = 120,
- HINIC3_NIC_CMD_SET_FIRMWARE_CUSTOM_PACKETS_MSG,
-
- /* BOND */
- HINIC3_NIC_CMD_BOND_DEV_CREATE = 134,
- HINIC3_NIC_CMD_BOND_DEV_DELETE,
- HINIC3_NIC_CMD_BOND_DEV_OPEN_CLOSE,
- HINIC3_NIC_CMD_BOND_INFO_GET,
- HINIC3_NIC_CMD_BOND_ACTIVE_INFO_GET,
- HINIC3_NIC_CMD_BOND_ACTIVE_NOTICE,
-
- /* DFX */
- HINIC3_NIC_CMD_GET_SM_TABLE = 140,
- HINIC3_NIC_CMD_RD_LINE_TBL,
-
- HINIC3_NIC_CMD_SET_UCAPTURE_OPT = 160, /* TODO: move to roce */
- HINIC3_NIC_CMD_SET_VHD_CFG,
-
- /* TODO: move to HILINK */
- HINIC3_NIC_CMD_GET_PORT_STAT = 200,
- HINIC3_NIC_CMD_CLEAN_PORT_STAT,
- HINIC3_NIC_CMD_CFG_LOOPBACK_MODE,
- HINIC3_NIC_CMD_GET_SFP_QSFP_INFO,
- HINIC3_NIC_CMD_SET_SFP_STATUS,
- HINIC3_NIC_CMD_GET_LIGHT_MODULE_ABS,
- HINIC3_NIC_CMD_GET_LINK_INFO,
- HINIC3_NIC_CMD_CFG_AN_TYPE,
- HINIC3_NIC_CMD_GET_PORT_INFO,
- HINIC3_NIC_CMD_SET_LINK_SETTINGS,
- HINIC3_NIC_CMD_ACTIVATE_BIOS_LINK_CFG,
- HINIC3_NIC_CMD_RESTORE_LINK_CFG,
- HINIC3_NIC_CMD_SET_LINK_FOLLOW,
- HINIC3_NIC_CMD_GET_LINK_STATE,
- HINIC3_NIC_CMD_LINK_STATUS_REPORT,
- HINIC3_NIC_CMD_CABLE_PLUG_EVENT,
- HINIC3_NIC_CMD_LINK_ERR_EVENT,
- HINIC3_NIC_CMD_SET_LED_STATUS,
-
- HINIC3_NIC_CMD_MAX = 256,
-};
-
-/* NIC CMDQ MODE */
-enum hinic3_ucode_cmd {
- HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
- HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
- HINIC3_UCODE_CMD_ARM_SQ,
- HINIC3_UCODE_CMD_ARM_RQ,
- HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_SET_IQ_ENABLE,
- HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
- HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
- HINIC3_UCODE_CMD_PPA_HASH_TABLE,
- HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
-};
-
-#endif /* HINIC3_NIC_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
index 17d48c4..2878f66 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
@@ -30,6 +30,9 @@ int hinic3_dbg_get_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (q_id >= nic_io->num_qps) {
pr_err("q_id[%u] > num_qps_cfg[%u].\n", q_id, nic_io->num_qps);
return -EINVAL;
@@ -69,6 +72,9 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -82,6 +88,8 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
sq = &nic_io->sq[q_id];
+ if (!sq)
+ return -EINVAL;
sq_info->q_id = q_id;
sq_info->pi = hinic3_get_sq_local_pi(sq);
@@ -112,6 +120,9 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -125,6 +136,8 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
rq = &nic_io->rq[q_id];
+ if (!rq)
+ return -EINVAL;
rq_info->q_id = q_id;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
index 800fa73..137098b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
@@ -15,9 +15,10 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
#include "hinic3_dcb.h"
+#include "vram_common.h"
#define HINIC3_NIC_DRV_NAME "hinic3"
-#define HINIC3_NIC_DRV_VERSION "15.17.1.1"
+#define HINIC3_NIC_DRV_VERSION "17.7.8.1"
#define HINIC3_FUNC_IS_VF(hwdev) (hinic3_func_type(hwdev) == TYPE_VF)
@@ -25,6 +26,10 @@
#define HINIC3_MODERATONE_DELAY HZ
#define LP_PKT_CNT 64
+#define LP_PKT_LEN 60
+
+#define NAPI_IS_REGIN 1
+#define NAPI_NOT_REGIN 0
enum hinic3_flags {
HINIC3_INTF_UP,
@@ -91,6 +96,8 @@ struct hinic3_irq {
u16 rsvd1;
u32 irq_id; /* The IRQ number from OS */
+ u32 napi_reign;
+
char irq_name[IFNAMSIZ + 16];
struct napi_struct napi;
cpumask_t affinity_mask;
@@ -123,6 +130,41 @@ struct hinic3_dyna_txrxq_params {
struct hinic3_dyna_txq_res *txqs_res;
struct hinic3_dyna_rxq_res *rxqs_res;
struct hinic3_irq *irq_cfg;
+ char irq_cfg_vram_name[VRAM_NAME_MAX_LEN];
+};
+
+struct hinic3_flush_rq {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 lb_proc : 1;
+ u32 rsvd : 10;
+ u32 rq_id : 8;
+ u32 func_id : 13;
+#else
+ u32 func_id : 13;
+ u32 rq_id : 8;
+ u32 rsvd : 10;
+ u32 lb_proc : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd2 : 2;
+ u32 src_chnl : 12;
+ u32 pkt_len : 18;
+#else
+ u32 pkt_len : 18;
+ u32 src_chnl : 12;
+ u32 rsvd2 : 2;
+#endif
+ } bs;
+ u32 value;
+ } lb_info0; /* loop back information, used by uCode */
};
#define HINIC3_NIC_STATS_INC(nic_dev, field) \
@@ -147,6 +189,10 @@ struct hinic3_nic_stats {
#endif
};
+struct hinic3_nic_vport_stats {
+ u64 rx_discard_vport;
+};
+
#define HINIC3_TCAM_DYNAMIC_BLOCK_SIZE 16
#define HINIC3_MAX_TCAM_FILTERS 512
@@ -185,104 +231,123 @@ struct hinic3_tcam_info {
struct hinic3_tcam_dynamic_block_info tcam_dynamic_info;
};
+struct hinic3_dcb {
+ u8 cos_config_num_max;
+ u8 func_dft_cos_bitmap;
+ /* used to tool validity check */
+ u16 port_dft_cos_bitmap;
+
+ struct hinic3_dcb_config hw_dcb_cfg;
+ struct hinic3_dcb_config wanted_dcb_cfg;
+ unsigned long dcb_flags;
+};
+
+struct hinic3_vram {
+ u32 vram_mtu;
+ u16 vram_num_qps;
+ unsigned long flags;
+};
+
+struct hinic3_outband_cfg {
+ u16 outband_default_vid;
+ u16 rsvd;
+};
+
struct hinic3_nic_dev {
- struct pci_dev *pdev;
- struct net_device *netdev;
- struct hinic3_lld_dev *lld_dev;
- void *hwdev;
+ struct pci_dev *pdev;
+ struct net_device *netdev;
+ struct hinic3_lld_dev *lld_dev;
+ void *hwdev;
- int poll_weight;
- u32 rsvd1;
- unsigned long *vlan_bitmap;
+ int poll_weight;
+ u32 rsvd1;
+ unsigned long *vlan_bitmap;
- u16 max_qps;
+ u16 max_qps;
- u32 msg_enable;
- unsigned long flags;
+ u32 msg_enable;
+ unsigned long flags;
- u32 lro_replenish_thld;
- u32 dma_rx_buff_size;
- u16 rx_buff_len;
- u32 page_order;
+ u32 lro_replenish_thld;
+ u32 dma_rx_buff_size;
+ u16 rx_buff_len;
+ u32 page_order;
+ bool page_pool_enabled;
/* Rss related varibles */
- u8 rss_hash_engine;
- struct nic_rss_type rss_type;
- u8 *rss_hkey;
+ u8 rss_hash_engine;
+ struct nic_rss_type rss_type;
+ u8 *rss_hkey;
/* hkey in big endian */
- u32 *rss_hkey_be;
- u32 *rss_indir;
+ u32 *rss_hkey_be;
+ u32 *rss_indir;
- u8 cos_config_num_max;
- u8 func_dft_cos_bitmap;
- u16 port_dft_cos_bitmap; /* used to tool validity check */
+ struct hinic3_dcb *dcb;
+ char dcb_name[VRAM_NAME_MAX_LEN];
- struct hinic3_dcb_config hw_dcb_cfg;
- struct hinic3_dcb_config wanted_dcb_cfg;
- struct hinic3_dcb_config dcb_cfg;
- unsigned long dcb_flags;
- int disable_port_cnt;
- /* lock for disable or enable traffic flow */
- struct semaphore dcb_sem;
+ struct hinic3_vram *nic_vram;
+ char nic_vram_name[VRAM_NAME_MAX_LEN];
- struct hinic3_intr_coal_info *intr_coalesce;
- unsigned long last_moder_jiffies;
- u32 adaptive_rx_coal;
- u8 intr_coal_set_flag;
+ int disable_port_cnt;
+
+ struct hinic3_intr_coal_info *intr_coalesce;
+ unsigned long last_moder_jiffies;
+ u32 adaptive_rx_coal;
+ u8 intr_coal_set_flag;
#ifndef HAVE_NETDEV_STATS_IN_NETDEV
- struct net_device_stats net_stats;
+ struct net_device_stats net_stats;
#endif
- struct hinic3_nic_stats stats;
+ struct hinic3_nic_stats stats;
+ struct hinic3_nic_vport_stats vport_stats;
/* lock for nic resource */
- struct mutex nic_mutex;
- bool force_port_disable;
- struct semaphore port_state_sem;
- u8 link_status;
+ struct mutex nic_mutex;
+ u8 link_status;
- struct nic_service_cap nic_cap;
+ struct nic_service_cap nic_cap;
- struct hinic3_txq *txqs;
- struct hinic3_rxq *rxqs;
+ struct hinic3_txq *txqs;
+ struct hinic3_rxq *rxqs;
struct hinic3_dyna_txrxq_params q_params;
- u16 num_qp_irq;
- struct irq_info *qps_irq_info;
+ u16 num_qp_irq;
+ struct irq_info *qps_irq_info;
- struct workqueue_struct *workq;
+ struct workqueue_struct *workq;
- struct work_struct rx_mode_work;
- struct delayed_work moderation_task;
+ struct work_struct rx_mode_work;
+ struct delayed_work moderation_task;
- struct list_head uc_filter_list;
- struct list_head mc_filter_list;
- unsigned long rx_mod_state;
- int netdev_uc_cnt;
- int netdev_mc_cnt;
+ struct list_head uc_filter_list;
+ struct list_head mc_filter_list;
+ unsigned long rx_mod_state;
+ int netdev_uc_cnt;
+ int netdev_mc_cnt;
- int lb_test_rx_idx;
- int lb_pkt_len;
- u8 *lb_test_rx_buf;
+ int lb_test_rx_idx;
+ int lb_pkt_len;
+ u8 *lb_test_rx_buf;
- struct hinic3_tcam_info tcam;
- struct hinic3_rx_flow_rule rx_flow_rule;
+ struct hinic3_tcam_info tcam;
+ struct hinic3_rx_flow_rule rx_flow_rule;
#ifdef HAVE_XDP_SUPPORT
- struct bpf_prog *xdp_prog;
+ struct bpf_prog *xdp_prog;
#endif
- struct delayed_work periodic_work;
+ struct delayed_work periodic_work;
/* reference to enum hinic3_event_work_flags */
- unsigned long event_flag;
-
- struct hinic3_nic_prof_attr *prof_attr;
- struct hinic3_prof_adapter *prof_adap;
- u64 rsvd8[7];
- u32 rsvd9;
- u32 rxq_get_err_times;
- struct delayed_work rxq_check_work;
+ unsigned long event_flag;
+
+ struct hinic3_nic_prof_attr *prof_attr;
+ struct hinic3_prof_adapter *prof_adap;
+ u64 rsvd8[7];
+ struct hinic3_outband_cfg outband_cfg;
+ u32 rxq_get_err_times;
+ struct delayed_work rxq_check_work;
+ struct delayed_work vport_stats_work;
};
#define hinic_msg(level, nic_dev, msglvl, format, arg...) \
@@ -309,7 +374,7 @@ struct hinic3_uld_info *get_nic_uld_info(void);
u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev);
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
int hinic3_open(struct net_device *netdev);
@@ -328,6 +393,8 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev);
void hinic3_qps_irq_deinit(struct hinic3_nic_dev *nic_dev);
+void qp_del_napi(struct hinic3_irq *irq_cfg);
+
void hinic3_set_netdev_ops(struct hinic3_nic_dev *nic_dev);
bool hinic3_is_netdev_ops_match(const struct net_device *netdev);
@@ -345,10 +412,6 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
int hinic3_get_sset_count(struct net_device *netdev, int sset);
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev);
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
#ifdef ETHTOOL_GLINKSETTINGS
@@ -383,5 +446,17 @@ bool hinic3_is_xdp_enable(struct hinic3_nic_dev *nic_dev);
int hinic3_xdp_max_mtu(struct hinic3_nic_dev *nic_dev);
#endif
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+int set_fecparam(void *hwdev, u8 fecparam);
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec);
+#endif
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
index 57cf07c..6cc294e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
@@ -21,11 +21,12 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
{
- struct vf_data_storage *vf_info;
+ struct vf_data_storage *vf_info = NULL;
u16 func_id;
int err = 0;
@@ -38,7 +39,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
vf_info->pf_vlan, func_id,
HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d MAC\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -51,7 +52,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD,
vf_info->pf_vlan, vf_info->pf_qos,
vf_id);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to add VF %d VLAN_QOS\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -62,7 +63,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_vf_tx_rate(nic_io->hwdev, vf_id,
vf_info->max_rate,
vf_info->min_rate);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d max rate %u, min rate %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->max_rate,
vf_info->min_rate);
@@ -84,7 +85,7 @@ static int register_vf_msg_handler(struct hinic3_nic_io *nic_io, u16 vf_id)
}
err = hinic3_init_vf_config(nic_io, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].registered = true;
@@ -137,6 +138,9 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
int err;
+ if (!vf_info)
+ return -EINVAL;
+
if (register_vf->op_register) {
vf_info->support_extra_feature = register_vf->support_extra_feature;
err = register_vf_msg_handler(nic_io, vf_id);
@@ -145,7 +149,7 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
vf_info->support_extra_feature = 0;
}
- if (err)
+ if (err != 0)
register_info->msg_head.status = EFAULT;
*out_size = sizeof(*register_info);
@@ -157,6 +161,9 @@ void hinic3_unregister_vf(struct hinic3_nic_io *nic_io, u16 vf_id)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vf_info)
+ return;
+
unregister_vf_msg_handler(nic_io, vf_id);
vf_info->support_extra_feature = 0;
}
@@ -181,14 +188,21 @@ static int hinic3_get_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
void *buf_out, u16 *out_size)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf);
+ struct hinic3_port_mac_set *mac_in =
+ (struct hinic3_port_mac_set *)buf_in;
struct hinic3_port_mac_set *mac_info = buf_out;
int err;
- if (HINIC3_SUPPORT_VF_MAC(nic_io->hwdev)) {
+ if (!mac_info || !vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
+ if (HINIC3_SUPPORT_VF_MAC(nic_io->hwdev) != 0) {
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_GET_MAC, buf_in,
in_size, buf_out, out_size);
- if (!err) {
+ if (err == 0) {
if (is_zero_ether_addr(mac_info->mac))
ether_addr_copy(mac_info->mac, vf_info->drv_mac_addr);
}
@@ -211,6 +225,11 @@ static int hinic3_set_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -247,6 +266,11 @@ static int hinic3_del_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -283,12 +307,15 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
struct hinic3_port_mac_update *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
if (!is_valid_ether_addr(mac_in->new_mac)) {
nic_err(nic_io->dev_hdl, "Update VF MAC is invalid.\n");
return -EINVAL;
}
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
-#ifndef __VMWARE__
if (vf_info->use_specified_mac && !vf_info->trust) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
HW_VF_ID_TO_OS(vf));
@@ -296,17 +323,7 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
*out_size = sizeof(*mac_out);
return 0;
}
-#else
- err = hinic_config_vf_request(nic_io->hwdev->pcidev_hdl,
- HW_VF_ID_TO_OS(vf),
- HINIC_CFG_VF_MAC_CHANGED,
- (void *)mac_in->new_mac);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to config VF %d MAC request, err: %d\n",
- HW_VF_ID_TO_OS(vf), err);
- return err;
- }
-#endif
+
mac_in->vlan_id = vf_info->pf_vlan;
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_UPDATE_MAC,
buf_in, in_size, buf_out, out_size);
@@ -362,7 +379,8 @@ static int _l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u32 i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_cmd_handler[i].cmd)
cmd_to_pf = true;
@@ -404,6 +422,8 @@ int hinic3_pf_mbox_handler(void *hwdev,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (index = 0; index < cmd_size; index++) {
if (cmd == vf_cmd_handler[index].cmd)
@@ -460,10 +480,14 @@ void hinic3_notify_dcb_state_event(struct hinic3_nic_io *nic_io,
static void dcb_state_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- struct hinic3_cmd_vf_dcb_state *vf_dcb;
- struct hinic3_nic_io *nic_io;
+ struct hinic3_cmd_vf_dcb_state *vf_dcb = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
vf_dcb = buf_in;
if (!vf_dcb)
@@ -479,9 +503,13 @@ static void tx_pause_excp_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*excp_info)) {
- nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
+ nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %lu\n",
in_size, sizeof(*excp_info));
return;
}
@@ -501,6 +529,10 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_event_info event_info = {0};
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*active_info)) {
nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
@@ -515,6 +547,36 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
hinic3_event_callback(nic_io->hwdev, &event_info);
}
+static void outband_vlan_cfg_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out,
+ u16 *out_size)
+{
+ struct hinic3_outband_cfg_info *outband_cfg_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info = {0};
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ nic_info(nic_io->dev_hdl, "outband vlan cfg event received\n");
+
+ if (in_size != sizeof(*outband_cfg_info)) {
+ nic_err(nic_io->dev_hdl, "outband cfg info invalid in_size: %u, should be %lu\n",
+ in_size, sizeof(*outband_cfg_info));
+ return;
+ }
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = EVENT_NIC_OUTBAND_CFG;
+ memcpy((void *)event_info.event_data,
+ outband_cfg_info, sizeof(*outband_cfg_info));
+
+ hinic3_event_callback(nic_io->hwdev, &event_info);
+}
+
static const struct nic_event_handler nic_cmd_handler[] = {
{
.cmd = HINIC3_NIC_CMD_VF_COS,
@@ -529,6 +591,11 @@ static const struct nic_event_handler nic_cmd_handler[] = {
.cmd = HINIC3_NIC_CMD_BOND_ACTIVE_NOTICE,
.handler = bond_active_event_handler,
},
+
+ {
+ .cmd = HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ .handler = outband_vlan_cfg_event_handler,
+ },
};
static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
@@ -543,6 +610,8 @@ static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (i = 0; i < size; i++) {
if (cmd == nic_cmd_handler[i].cmd) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
index 22670ff..a9768b7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
@@ -16,7 +16,8 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_nic_io.h"
#define HINIC3_DEAULT_TX_CI_PENDING_LIMIT 1
@@ -34,7 +35,7 @@ MODULE_PARM_DESC(tx_coalescing_time, "TX CI coalescing parameter coalescing_time
static unsigned char rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
module_param(rq_wqe_type, byte, 0444);
-MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 0-8Bytes, 1-16Bytes, 2-32Bytes (default=2)");
+MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 1-16Bytes, 2-32Bytes (default=2)");
/*lint +e806*/
static u32 tx_drop_thd_on = HINIC3_DEAULT_DROP_THD_ON;
@@ -45,7 +46,7 @@ static u32 tx_drop_thd_off = HINIC3_DEAULT_DROP_THD_OFF;
module_param(tx_drop_thd_off, uint, 0644);
MODULE_PARM_DESC(tx_drop_thd_off, "TX parameter drop_thd_off (default=0)");
/* performance: ci addr RTE_CACHE_SIZE(64B) alignment */
-#define HINIC3_CI_Q_ADDR_SIZE (64)
+#define HINIC3_CI_Q_ADDR_SIZE (64U)
#define CI_TABLE_SIZE(num_qps, pg_sz) \
(ALIGN((num_qps) * HINIC3_CI_Q_ADDR_SIZE, pg_sz))
@@ -350,6 +351,13 @@ static int hinic3_create_rq(struct hinic3_nic_io *nic_io, struct hinic3_io_queue
{
int err;
+ /* rq_wqe_type Only support type 1-16Bytes, 2-32Bytes */
+ if (rq_wqe_type != HINIC3_NORMAL_RQ_WQE && rq_wqe_type != HINIC3_EXTEND_RQ_WQE) {
+ sdk_warn(nic_io->dev_hdl, "Module Parameter rq_wqe_type value %d is out of range: [%d, %d].",
+ rq_wqe_type, HINIC3_NORMAL_RQ_WQE, HINIC3_EXTEND_RQ_WQE);
+ rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
+ }
+
rq->wqe_type = rq_wqe_type;
rq->q_id = q_id;
rq->msix_entry_idx = rq_msix_idx;
@@ -1044,8 +1052,8 @@ static int clean_queue_offload_ctxt(struct hinic3_nic_io *nic_io,
static int clean_qp_offload_ctxt(struct hinic3_nic_io *nic_io)
{
/* clean LRO/TSO context space */
- return (clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_SQ) ||
- clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_RQ));
+ return ((clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_SQ) != 0) ||
+ (clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_RQ) != 0));
}
/* init qps ctxt and set sq ci attr and arm all sq */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
index 5c5585a..943a736 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
@@ -303,7 +303,7 @@ static inline void hinic3_write_db(struct hinic3_io_queue *queue, int cos,
wmb(); /* Write all before the doorbell */
- writeq(*((u64 *)&db), DB_ADDR(queue, pi));
+ writeq(*((u64 *)(u8 *)&db), DB_ADDR(queue, pi));
}
struct hinic3_dyna_qp_params {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
index 78d943d..9ea93a0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
@@ -32,7 +32,7 @@ struct hinic3_prof_adapter nic_prof_adap_objs[] = {
void hinic3_init_nic_prof_adapter(struct hinic3_nic_dev *nic_dev)
{
- u16 num_adap = ARRAY_SIZE(nic_prof_adap_objs);
+ int num_adap = ARRAY_LEN(nic_prof_adap_objs);
nic_dev->prof_adap = hinic3_prof_init(nic_dev, nic_prof_adap_objs, num_adap,
(void *)&nic_dev->prof_attr);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
index 283c544..6d9b0c1 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
@@ -394,7 +394,8 @@ hinic3_alloc_dynamic_block_resource(struct hinic3_nic_dev *nic_dev,
dynamic_block_ptr = kzalloc(sizeof(*dynamic_block_ptr), GFP_KERNEL);
if (!dynamic_block_ptr) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "fdir filter dynamic alloc block index %d memory failed\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "fdir filter dynamic alloc block index %u memory failed\n",
dynamic_block_id);
return NULL;
}
@@ -433,7 +434,8 @@ hinic3_dynamic_lookup_tcam_filter(struct hinic3_nic_dev *nic_dev,
list_for_each_entry(tmp,
&tcam_info->tcam_dynamic_info.tcam_dynamic_list,
block_list)
- if (tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)
+ if (!tmp ||
+ tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)
break;
if (!tmp || tmp->dynamic_index_cnt >= HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) {
@@ -515,7 +517,7 @@ static int hinic3_add_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, queue: %d, tcam_rule_nums: %d succeed\n",
+ "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, queue: %u, tcam_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev),
tcam_filter->dynamic_block_id, index, fdir_tcam_rule->index,
fdir_tcam_rule->data.qid, tcam_info->tcam_rule_nums + 1);
@@ -582,7 +584,7 @@ static int hinic3_del_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, local_rules_nums: %d, global_rule_nums: %d succeed\n",
+ "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, local_rules_nums: %u, global_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev), dynamic_block_id,
tcam_filter->index, index, tmp->dynamic_index_cnt - 1,
tcam_info->tcam_rule_nums - 1);
@@ -608,7 +610,7 @@ static inline struct hinic3_tcam_filter *
hinic3_tcam_filter_lookup(const struct list_head *filter_list,
struct tag_tcam_key *key)
{
- struct hinic3_tcam_filter *iter;
+ struct hinic3_tcam_filter *iter = NULL;
list_for_each_entry(iter, filter_list, tcam_filter_list) {
if (memcmp(key, &iter->tcam_key,
@@ -633,7 +635,7 @@ static int hinic3_remove_one_rule(struct hinic3_nic_dev *nic_dev,
struct hinic3_ethtool_rx_flow_rule *eth_rule)
{
struct hinic3_tcam_info *tcam_info = &nic_dev->tcam;
- struct hinic3_tcam_filter *tcam_filter;
+ struct hinic3_tcam_filter *tcam_filter = NULL;
struct nic_tcam_cfg_rule fdir_tcam_rule;
struct tag_tcam_key tcam_key;
int err;
@@ -754,7 +756,7 @@ static int validate_flow(struct hinic3_nic_dev *nic_dev,
{
if (fs->location >= MAX_NUM_OF_ETHTOOL_NTUPLE_RULES) {
nicif_err(nic_dev, drv, nic_dev->netdev, "loc exceed limit[0,%lu]\n",
- MAX_NUM_OF_ETHTOOL_NTUPLE_RULES);
+ MAX_NUM_OF_ETHTOOL_NTUPLE_RULES - 1);
return -EINVAL;
}
@@ -875,7 +877,7 @@ int hinic3_ethtool_get_flow(const struct hinic3_nic_dev *nic_dev,
int hinic3_ethtool_get_all_flows(const struct hinic3_nic_dev *nic_dev,
struct ethtool_rxnfc *info, u32 *rule_locs)
{
- int idx = 0;
+ u32 idx = 0;
struct hinic3_ethtool_rx_flow_rule *eth_rule = NULL;
if (!HINIC3_SUPPORT_FDIR(nic_dev->hwdev)) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h b/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
deleted file mode 100644
index a93f3b6..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_PROFILE_H
-#define HINIC3_PROFILE_H
-
-typedef bool (*hinic3_is_match_prof)(void *device);
-typedef void *(*hinic3_init_prof_attr)(void *device);
-typedef void (*hinic3_deinit_prof_attr)(void *porf_attr);
-
-enum prof_adapter_type {
- PROF_ADAP_TYPE_INVALID,
- PROF_ADAP_TYPE_PANGEA = 1,
-
- /* Add prof adapter type before default */
- PROF_ADAP_TYPE_DEFAULT,
-};
-
-/**
- * struct hinic3_prof_adapter - custom scene's profile adapter
- * @type: adapter type
- * @match: Check whether the current function is used in the custom scene.
- * Implemented in the current source file
- * @init: When @match return true, the initialization function called in probe.
- * Implemented in the source file of the custom scene
- * @deinit: When @match return true, the deinitialization function called when
- * remove. Implemented in the source file of the custom scene
- */
-struct hinic3_prof_adapter {
- enum prof_adapter_type type;
- hinic3_is_match_prof match;
- hinic3_init_prof_attr init;
- hinic3_deinit_prof_attr deinit;
-};
-
-#ifdef static
-#undef static
-#define LLT_STATIC_DEF_SAVED
-#endif
-
-/*lint -save -e661 */
-static inline struct hinic3_prof_adapter *
-hinic3_prof_init(void *device, struct hinic3_prof_adapter *adap_objs, int num_adap,
- void **prof_attr)
-{
- struct hinic3_prof_adapter *prof_obj = NULL;
- u16 i;
-
- for (i = 0; i < num_adap; i++) {
- prof_obj = &adap_objs[i];
- if (!(prof_obj->match && prof_obj->match(device)))
- continue;
-
- *prof_attr = prof_obj->init ? prof_obj->init(device) : NULL;
-
- return prof_obj;
- }
-
- return NULL;
-}
-
-static inline void hinic3_prof_deinit(struct hinic3_prof_adapter *prof_obj, void *prof_attr)
-{
- if (!prof_obj)
- return;
-
- if (prof_obj->deinit)
- prof_obj->deinit(prof_attr);
-}
-
-/*lint -restore*/
-
-/* module-level interface */
-#ifdef CONFIG_MODULE_PROF
-struct hinic3_module_ops {
- int (*module_prof_init)(void);
- void (*module_prof_exit)(void);
- void (*probe_fault_process)(void *pdev, u16 level);
- int (*probe_pre_process)(void *pdev);
- void (*probe_pre_unprocess)(void *pdev);
-};
-
-struct hinic3_module_ops *hinic3_get_module_prof_ops(void);
-
-static inline void hinic3_probe_fault_process(void *pdev, u16 level)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (ops && ops->probe_fault_process)
- ops->probe_fault_process(pdev, level);
-}
-
-static inline int hinic3_module_pre_init(void)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (!ops || !ops->module_prof_init)
- return -EINVAL;
-
- return ops->module_prof_init();
-}
-
-static inline void hinic3_module_post_exit(void)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (ops && ops->module_prof_exit)
- ops->module_prof_exit();
-}
-
-static inline int hinic3_probe_pre_process(void *pdev)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (!ops || !ops->probe_pre_process)
- return -EINVAL;
-
- return ops->probe_pre_process(pdev);
-}
-
-static inline void hinic3_probe_pre_unprocess(void *pdev)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (ops && ops->probe_pre_unprocess)
- ops->probe_pre_unprocess(pdev);
-}
-#else
-static inline void hinic3_probe_fault_process(void *pdev, u16 level) { };
-
-static inline int hinic3_module_pre_init(void)
-{
- return 0;
-}
-
-static inline void hinic3_module_post_exit(void) { };
-
-static inline int hinic3_probe_pre_process(void *pdev)
-{
- return 0;
-}
-
-static inline void hinic3_probe_pre_unprocess(void *pdev) { };
-#endif
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
index 6bf3b11..655d2b8 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/dcbnl.h>
+#include <linux/init.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -23,8 +24,9 @@
#include "hinic3_hw.h"
#include "hinic3_rss.h"
-/*lint -e806*/
-static u16 num_qps;
+#include "vram_common.h"
+
+static u16 num_qps = 0;
module_param(num_qps, ushort, 0444);
MODULE_PARM_DESC(num_qps, "Number of Queue Pairs (default=0)");
@@ -104,88 +106,84 @@ static int hinic3_get_rq2iq_map(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev, u8 num_cos, u32 *indir)
+static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev,
+ u8 group_num, u32 *indir)
{
- u16 k, group_size, start_qid = 0, qp_num = 0;
- int i = 0;
- u8 j, cur_cos = 0, default_cos;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ u16 k, group_size, start_qid = 0, cur_cos_qnum = 0;
+ u32 i = 0;
+ u8 j, cur_cos = 0, group = 0;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
- if (num_cos == 0) {
+ if (group_num == 0) {
for (i = 0; i < NIC_RSS_INDIR_SIZE; i++)
indir[i] = i % nic_dev->q_params.num_qps;
} else {
- group_size = NIC_RSS_INDIR_SIZE / num_cos;
-
- for (j = 0; j < num_cos; j++) {
- while (cur_cos < NIC_DCB_COS_MAX &&
- nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos] == 0)
- cur_cos++;
-
- if (cur_cos >= NIC_DCB_COS_MAX) {
- if (BIT(nic_dev->hw_dcb_cfg.default_cos) & valid_cos_map)
- default_cos = nic_dev->hw_dcb_cfg.default_cos;
- else
- default_cos = (u8)fls(valid_cos_map) - 1;
+ group_size = NIC_RSS_INDIR_SIZE / group_num;
+
+ for (group = 0; group < group_num; group++) {
+ cur_cos = dcb->hw_dcb_cfg.default_cos;
+ for (j = 0; j < NIC_DCB_COS_MAX; j++) {
+ if ((BIT(j) & valid_cos_map) != 0) {
+ cur_cos = j;
+ valid_cos_map -= (u8)BIT(j);
+ break;
+ }
+ }
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[default_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[default_cos];
+ cur_cos_qnum = dcb->hw_dcb_cfg.cos_qp_num[cur_cos];
+ if (cur_cos_qnum > 0) {
+ start_qid =
+ dcb->hw_dcb_cfg.cos_qp_offset[cur_cos];
} else {
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[cur_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos];
+ start_qid = cur_cos % nic_dev->q_params.num_qps;
+ /* Ensure that the offset of start_id is 0. */
+ cur_cos_qnum = 1;
}
for (k = 0; k < group_size; k++)
- indir[i++] = start_qid + k % qp_num;
-
- cur_cos++;
+ indir[i++] = start_qid + k % cur_cos_qnum;
}
}
}
-/*lint -e528*/
int hinic3_rss_init(struct hinic3_nic_dev *nic_dev, u8 *rq2iq_map, u32 map_size, u8 dcb_en)
{
struct net_device *netdev = nic_dev->netdev;
- u8 i, cos_num;
- u8 cos_map[NIC_DCB_UP_MAX] = {0};
- u8 cfg_map[NIC_DCB_UP_MAX] = {0};
+ u8 i, group_num, cos_bitmap, group = 0;
+ u8 cos_group[NIC_DCB_UP_MAX] = {0};
int err;
- if (dcb_en) {
- cos_num = hinic3_get_dev_user_cos_num(nic_dev);
-
- if (nic_dev->hw_dcb_cfg.trust == 0) {
- memcpy(cfg_map, nic_dev->hw_dcb_cfg.pcp2cos, sizeof(cfg_map));
- } else if (nic_dev->hw_dcb_cfg.trust == 1) {
- for (i = 0; i < NIC_DCB_UP_MAX; i++)
- cfg_map[i] = nic_dev->hw_dcb_cfg.dscp2cos[i * NIC_DCB_DSCP_NUM];
- }
-#define COS_CHANGE_OFFSET 4
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[COS_CHANGE_OFFSET + i] = cfg_map[i];
+ if (dcb_en != 0) {
+ group_num = (u8)roundup_pow_of_two(
+ hinic3_get_dev_user_cos_num(nic_dev));
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[i] = cfg_map[NIC_DCB_UP_MAX - (i + 1)];
+ cos_bitmap = hinic3_get_dev_valid_cos_map(nic_dev);
- while (cos_num & (cos_num - 1))
- cos_num++;
+ for (i = 0; i < NIC_DCB_UP_MAX; i++) {
+ if ((BIT(i) & cos_bitmap) != 0)
+ cos_group[NIC_DCB_UP_MAX - i - 1] = group++;
+ else
+ cos_group[NIC_DCB_UP_MAX - i - 1] =
+ group_num - 1;
+ }
} else {
- cos_num = 0;
+ group_num = 0;
}
- err = hinic3_set_hw_rss_parameters(netdev, 1, cos_num, cos_map, dcb_en);
+ err = hinic3_set_hw_rss_parameters(netdev, 1, group_num,
+ cos_group, dcb_en);
if (err)
return err;
- err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps, cos_num, cos_map,
- NIC_DCB_UP_MAX, nic_dev->rss_indir, rq2iq_map, map_size);
+ err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps,
+ group_num, cos_group, NIC_DCB_UP_MAX,
+ nic_dev->rss_indir, rq2iq_map, map_size);
if (err)
nicif_err(nic_dev, drv, netdev, "Failed to get rq map\n");
return err;
}
-/*lint -e528*/
void hinic3_rss_deinit(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -246,28 +244,59 @@ discard_user_rss_indir:
hinic3_set_default_rss_indir(netdev);
}
+#ifdef HAVE_HOT_REPLACE_FUNC
+bool partition_slave_doing_hotupgrade(void)
+{
+ return get_partition_role() && partition_doing_hotupgrade();
+}
+#endif
+
static void decide_num_qps(struct hinic3_nic_dev *nic_dev)
{
u16 tmp_num_qps = nic_dev->max_qps;
u16 num_cpus = 0;
+ u16 max_num_cpus;
int i, node;
+ int is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ nic_dev->q_params.num_qps = nic_dev->nic_vram->vram_num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Os hotreplace use vram to init num qps 1:%hu 2:%hu\n",
+ nic_dev->q_params.num_qps,
+ nic_dev->nic_vram->vram_num_qps);
+ return;
+ }
+
if (nic_dev->nic_cap.default_num_queues != 0 &&
nic_dev->nic_cap.default_num_queues < nic_dev->max_qps)
tmp_num_qps = nic_dev->nic_cap.default_num_queues;
MOD_PARA_VALIDATE_NUM_QPS(nic_dev, num_qps, tmp_num_qps);
- for (i = 0; i < (int)num_online_cpus(); i++) {
+#ifdef HAVE_HOT_REPLACE_FUNC
+ if (partition_slave_doing_hotupgrade())
+ max_num_cpus = (u16)num_present_cpus();
+ else
+ max_num_cpus = (u16)num_online_cpus();
+#else
+ max_num_cpus = (u16)num_online_cpus();
+#endif
+
+ for (i = 0; i < max_num_cpus; i++) {
node = (int)cpu_to_node(i);
if (node == dev_to_node(&nic_dev->pdev->dev))
num_cpus++;
}
if (!num_cpus)
- num_cpus = (u16)num_online_cpus();
+ num_cpus = max_num_cpus;
nic_dev->q_params.num_qps = (u16)min_t(u16, tmp_num_qps, num_cpus);
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "init num qps 1:%u 2:%u\n",
+ nic_dev->q_params.num_qps, nic_dev->nic_vram->vram_num_qps);
}
static void copy_value_to_rss_hkey(struct hinic3_nic_dev *nic_dev,
@@ -324,7 +353,6 @@ static int alloc_rss_resource(struct hinic3_nic_dev *nic_dev)
return 0;
}
-/*lint -e528*/
void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -363,6 +391,7 @@ void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
set_q_params:
clear_bit(HINIC3_RSS_ENABLE, &nic_dev->flags);
nic_dev->q_params.num_qps = nic_dev->max_qps;
+ nic_dev->nic_vram->vram_num_qps = nic_dev->max_qps;
}
static int hinic3_config_rss_hw_resource(struct hinic3_nic_dev *nic_dev,
@@ -756,6 +785,7 @@ int hinic3_set_channels(struct net_device *netdev,
nic_dev->q_params.num_qps = (u16)count;
}
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
return 0;
}
@@ -816,7 +846,7 @@ int hinic3_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
int err = 0;
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
@@ -923,7 +953,7 @@ int hinic3_get_rxfh_indir(struct net_device *netdev, u32 *indir)
indir = indir1->ring_index;
#endif
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
index 175c4d6..902d7e2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
@@ -15,13 +15,14 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_nic_cfg.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_hw.h"
#include "hinic3_nic.h"
#include "hinic3_common.h"
static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
- u8 *key)
+ u8 *key, u16 key_size)
{
struct hinic3_cmd_rss_hash_key hash_key;
u16 out_size = sizeof(hash_key);
@@ -32,7 +33,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
hash_key.opcode = opcode;
if (opcode == HINIC3_CMD_OP_SET)
- memcpy(hash_key.key, key, NIC_RSS_KEY_SIZE);
+ memcpy(hash_key.key, key, key_size);
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_CFG_RSS_HASH_KEY,
@@ -46,7 +47,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
}
if (opcode == HINIC3_CMD_OP_GET)
- memcpy(key, hash_key.key, NIC_RSS_KEY_SIZE);
+ memcpy(key, hash_key.key, key_size);
return 0;
}
@@ -60,8 +61,11 @@ int hinic3_rss_set_hash_key(void *hwdev, const u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memcpy(hash_key, key, NIC_RSS_KEY_SIZE);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET, hash_key);
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET,
+ hash_key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
@@ -72,7 +76,10 @@ int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET, key);
+ if (!nic_io)
+ return -EINVAL;
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET,
+ key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
@@ -86,6 +93,9 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -126,6 +136,8 @@ int hinic3_rss_set_indir_tbl(void *hwdev, const u32 *indir_table)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd buf\n");
@@ -170,6 +182,8 @@ static int hinic3_cmdq_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
@@ -221,6 +235,8 @@ static int hinic3_mgmt_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&ctx_tbl, 0, sizeof(ctx_tbl));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
ctx |= HINIC3_RSS_TYPE_SET(1, VALID) |
@@ -270,6 +286,8 @@ int hinic3_get_rss_type(void *hwdev, struct nic_rss_type *rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&ctx_tbl, 0, sizeof(struct hinic3_rss_context_table));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
@@ -303,6 +321,9 @@ static int hinic3_rss_cfg_hash_engine(struct hinic3_nic_io *nic_io, u8 opcode,
u16 out_size = sizeof(hash_type);
int err;
+ if (!nic_io)
+ return -EINVAL;
+
memset(&hash_type, 0, sizeof(struct hinic3_cmd_rss_engine_type));
hash_type.func_id = hinic3_global_func_id(nic_io->hwdev);
@@ -336,6 +357,9 @@ int hinic3_rss_set_hash_engine(void *hwdev, u8 type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_SET, &type);
}
@@ -347,6 +371,9 @@ int hinic3_rss_get_hash_engine(void *hwdev, u8 *type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_GET, type);
}
@@ -362,6 +389,8 @@ int hinic3_rss_cfg(void *hwdev, u8 rss_en, u8 cos_num, u8 *prio_tc, u16 num_qps)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&rss_cfg, 0, sizeof(struct hinic3_cmd_rss_config));
rss_cfg.func_id = hinic3_global_func_id(hwdev);
rss_cfg.rss_en = rss_en;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
index 5c60d01..4dbd6dd 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
@@ -10,6 +10,7 @@
#include <linux/interrupt.h>
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
+#include <net/xdp.h>
#include <linux/device.h>
#include <linux/pci.h>
#include <linux/u64_stats_sync.h>
@@ -20,6 +21,7 @@
#include <linux/ipv6.h>
#include <linux/module.h>
#include <linux/compiler.h>
+#include <linux/filter.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -31,10 +33,6 @@
#include "hinic3_rss.h"
#include "hinic3_rx.h"
-static u32 rq_pi_rd_en;
-module_param(rq_pi_rd_en, uint, 0644);
-MODULE_PARM_DESC(rq_pi_rd_en, "Enable rq read pi from host, defaut update pi by doorbell (default=0)");
-
/* performance: ci addr RTE_CACHE_SIZE(64B) alignment */
#define HINIC3_RX_HDR_SIZE 256
#define HINIC3_RX_BUFFER_WRITE 16
@@ -63,19 +61,34 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
struct pci_dev *pdev = nic_dev->pdev;
struct page *page = rx_info->page;
dma_addr_t dma = rx_info->buf_dma_addr;
+ u32 page_offset = 0;
if (likely(dma))
return true;
/* alloc new page for storage */
- page = alloc_pages_node(NUMA_NO_NODE, GFP_ATOMIC | __GFP_COLD |
- __GFP_COMP, nic_dev->page_order);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page = page_pool_alloc_frag(rx_info->page_pool, &page_offset,
+ nic_dev->rx_buff_len,
+ GFP_ATOMIC | __GFP_COLD |
+ __GFP_COMP);
+ if (unlikely(!page))
+ return false;
+ dma = page_pool_get_dma_addr(page);
+ goto set_rx_info;
+ }
+#endif
+ page = alloc_pages_node(NUMA_NO_NODE,
+ GFP_ATOMIC | __GFP_COLD | __GFP_COMP,
+ nic_dev->page_order);
+
if (unlikely(!page))
return false;
/* map page for use */
- dma = dma_map_page(&pdev->dev, page, 0, nic_dev->dma_rx_buff_size,
- DMA_FROM_DEVICE);
+ dma = dma_map_page(&pdev->dev, page, page_offset,
+ nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
/* if mapping failed free memory back to system since
* there isn't much point in holding memory we can't use
*/
@@ -83,10 +96,12 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
__free_pages(page, nic_dev->page_order);
return false;
}
+ goto set_rx_info;
+set_rx_info:
rx_info->page = page;
rx_info->buf_dma_addr = dma;
- rx_info->page_offset = 0;
+ rx_info->page_offset = page_offset;
return true;
}
@@ -108,8 +123,8 @@ static u32 hinic3_rx_fill_wqe(struct hinic3_rxq *rxq)
/* unit of cqe length is 16B */
hinic3_set_sge(&rq_wqe->extend_wqe.cqe_sect.sge,
rx_info->cqe_dma,
- (sizeof(struct hinic3_rq_cqe) >>
- HINIC3_CQE_SIZE_SHIFT));
+ (HINIC3_CQE_LEN >>
+ HINIC3_CQE_SIZE_SHIFT));
/* use fixed len */
rq_wqe->extend_wqe.buf_desc.sge.len =
nic_dev->rx_buff_len;
@@ -163,18 +178,11 @@ static u32 hinic3_rx_fill_buffers(struct hinic3_rxq *rxq)
}
if (likely(i)) {
- if (!rq_pi_rd_en) {
- hinic3_write_db(rxq->rq,
- rxq->q_id & (NIC_DCB_COS_MAX - 1),
- RQ_CFLAG_DP,
- (u16)((u32)rxq->next_to_update <<
- rxq->rq->wqe_type));
- } else {
- /* Write all the wqes before pi update */
- wmb();
-
- hinic3_update_rq_hw_pi(rxq->rq, rxq->next_to_update);
- }
+ hinic3_write_db(rxq->rq,
+ rxq->q_id & (NIC_RX_DB_COS_MAX - 1),
+ RQ_CFLAG_DP,
+ (u16)((u32)rxq->next_to_update <<
+ rxq->rq->wqe_type));
rxq->delta -= i;
rxq->next_to_alloc = rxq->next_to_update;
} else if (free_wqebbs == rxq->q_depth - 1) {
@@ -208,6 +216,18 @@ static void hinic3_rx_free_buffers(struct hinic3_nic_dev *nic_dev, u32 q_depth,
for (i = 0; i < q_depth; i++) {
rx_info = &rx_info_arr[i];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ if (rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool,
+ rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ }
+ continue;
+ }
+#endif
+
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev,
rx_info->buf_dma_addr,
@@ -226,7 +246,7 @@ static void hinic3_rx_free_buffers(struct hinic3_nic_dev *nic_dev, u32 q_depth,
static void hinic3_reuse_rx_page(struct hinic3_rxq *rxq,
struct hinic3_rx_info *old_rx_info)
{
- struct hinic3_rx_info *new_rx_info;
+ struct hinic3_rx_info *new_rx_info = NULL;
u16 nta = rxq->next_to_alloc;
new_rx_info = &rxq->rx_info[nta];
@@ -250,8 +270,8 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
struct hinic3_rx_info *rx_info,
struct sk_buff *skb, u32 size)
{
- struct page *page;
- u8 *va;
+ struct page *page = NULL;
+ u8 *va = NULL;
page = rx_info->page;
va = (u8 *)page_address(page) + rx_info->page_offset;
@@ -267,8 +287,15 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
DMA_FROM_DEVICE);
if (size <= HINIC3_RX_HDR_SIZE && !skb_is_nonlinear(skb)) {
- memcpy(__skb_put(skb, size), va,
- ALIGN(size, sizeof(long))); /*lint !e666*/
+ __skb_put_data(skb, va, size);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool,
+ page, false);
+ return false;
+ }
+#endif
/* page is not reserved, we can reuse buffer as-is */
if (likely(page_to_nid(page) == numa_node_id()))
@@ -276,25 +303,37 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
/* this page cannot be reused so discard it */
put_page(page);
- return false;
+ goto discard_page;
}
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
(int)rx_info->page_offset, (int)size, rxq->buf_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
+
/* avoid re-using remote pages */
if (unlikely(page_to_nid(page) != numa_node_id()))
- return false;
+ goto discard_page;
/* if we are only owner of page we can reuse it */
if (unlikely(page_count(page) != 1))
- return false;
+ goto discard_page;
/* flip page offset to other buffer */
rx_info->page_offset ^= rxq->buf_len;
get_page(page);
return true;
+
+discard_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
}
static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
@@ -334,13 +373,9 @@ static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
head_skb->truesize += rxq->buf_len;
}
- if (likely(hinic3_add_rx_frag(rxq, rx_info, skb, size))) {
+ if (likely(hinic3_add_rx_frag(rxq, rx_info, skb, size)))
hinic3_reuse_rx_page(rxq, rx_info);
- } else {
- /* we are not reusing the buffer so unmap it */
- dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
- rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
- }
+
/* clear contents of buffer_info */
rx_info->buf_dma_addr = 0;
rx_info->page = NULL;
@@ -481,9 +516,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
protocol = hdr.eth->h_proto;
/* L2 header */
- /*lint -save -e778*/
if (protocol == htons(ETH_P_8021_AD) ||
- protocol == htons(ETH_P_8021_Q)) { /*lint -restore*/
+ protocol == htons(ETH_P_8021_Q)) {
if (unlikely(max_len < ETH_HLEN + VLAN_HLEN))
return max_len;
@@ -495,9 +529,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
}
/* L3 header */
- /*lint -save -e778*/
switch (protocol) {
- case htons(ETH_P_IP): /*lint -restore*/
+ case htons(ETH_P_IP):
if ((int)(hdr.data - data) >
(int)(max_len - sizeof(struct iphdr)))
return max_len;
@@ -680,7 +713,7 @@ static void hinic3_copy_lp_data(struct hinic3_nic_dev *nic_dev,
nicif_warn(nic_dev, rx_err, netdev, "Loopback test warning, receive too many test pkts\n");
}
- if (skb->len != nic_dev->lb_pkt_len) {
+ if (skb->len != (u32)(nic_dev->lb_pkt_len)) {
nicif_warn(nic_dev, rx_err, netdev, "Wrong packet length\n");
nic_dev->lb_test_rx_idx++;
return;
@@ -714,7 +747,10 @@ static inline void hinic3_lro_set_gso_params(struct sk_buff *skb, u16 num_lro)
}
#ifdef HAVE_XDP_SUPPORT
-enum hinic3_xdp_pkt {
+enum hinic3_xdp_status {
+ // bpf_prog status
+ HINIC3_XDP_PROG_EMPTY,
+ // pkt action
HINIC3_XDP_PKT_PASS,
HINIC3_XDP_PKT_DROP,
};
@@ -725,9 +761,15 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
while (weqbb_num) {
rx_info = &rxq->rx_info[rxq->cons_idx & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool)
+ goto discard_direct;
+#endif
if (likely(page_to_nid(rx_info->page) == numa_node_id()))
hinic3_reuse_rx_page(rxq, rx_info);
+ goto discard_direct;
+discard_direct:
rx_info->buf_dma_addr = 0;
rx_info->page = NULL;
rxq->cons_idx++;
@@ -737,11 +779,10 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
}
}
-int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
+int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len, struct xdp_buff *xdp)
{
struct bpf_prog *xdp_prog = NULL;
struct hinic3_rx_info *rx_info = NULL;
- struct xdp_buff xdp;
int result = HINIC3_XDP_PKT_PASS;
u16 weqbb_num = 1; /* xdp can only use one rx_buff */
u8 *va = NULL;
@@ -749,13 +790,14 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
rcu_read_lock();
xdp_prog = READ_ONCE(rxq->xdp_prog);
- if (!xdp_prog)
+ if (!xdp_prog) {
+ result = HINIC3_XDP_PROG_EMPTY;
goto unlock_rcu;
+ }
if (unlikely(pkt_len > rxq->buf_len)) {
RXQ_STATS_INC(rxq, xdp_large_pkt);
- weqbb_num = (u16)(pkt_len >> rxq->rx_buff_shift) +
- ((pkt_len & (rxq->buf_len - 1)) ? 1 : 0);
+ weqbb_num = HINIC3_GET_SGE_NUM(pkt_len, rxq);
result = HINIC3_XDP_PKT_DROP;
goto xdp_out;
}
@@ -766,19 +808,20 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
dma_sync_single_range_for_cpu(rxq->dev, rx_info->buf_dma_addr,
rx_info->page_offset,
rxq->buf_len, DMA_FROM_DEVICE);
- xdp.data = va;
- xdp.data_hard_start = xdp.data;
- xdp.data_end = xdp.data + pkt_len;
+ xdp->data = va;
+ xdp->data_hard_start = xdp->data;
+ xdp->data_end = xdp->data + pkt_len;
#ifdef HAVE_XDP_FRAME_SZ
- xdp.frame_sz = rxq->buf_len;
+ xdp->frame_sz = rxq->buf_len;
#endif
#ifdef HAVE_XDP_DATA_META
- xdp_set_data_meta_invalid(&xdp);
+ xdp_set_data_meta_invalid(xdp);
#endif
- prefetchw(xdp.data_hard_start);
- act = bpf_prog_run_xdp(xdp_prog, &xdp);
+ prefetchw(xdp->data_hard_start);
+ act = bpf_prog_run_xdp(xdp_prog, xdp);
switch (act) {
case XDP_PASS:
+ result = HINIC3_XDP_PKT_PASS;
break;
case XDP_DROP:
result = HINIC3_XDP_PKT_DROP;
@@ -799,12 +842,94 @@ unlock_rcu:
return result;
}
+
+static bool hinic3_add_rx_frag_with_xdp(struct hinic3_rxq *rxq, u32 pkt_len,
+ struct hinic3_rx_info *rx_info,
+ struct sk_buff *skb,
+ struct xdp_buff *xdp)
+{
+ struct page *page = rx_info->page;
+
+ if (pkt_len <= HINIC3_RX_HDR_SIZE) {
+ __skb_put_data(skb, xdp->data, pkt_len);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool,
+ page, false);
+ return false;
+ }
+#endif
+
+ if (likely(page_to_nid(page) == numa_node_id()))
+ return true;
+
+ put_page(page);
+ goto umap_page;
+ }
+
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
+ (int)(rx_info->page_offset +
+ (xdp->data - xdp->data_hard_start)),
+ (int)pkt_len, rxq->buf_len);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
+ if (unlikely(page_to_nid(page) != numa_node_id()))
+ goto umap_page;
+ if (unlikely(page_count(page) != 1))
+ goto umap_page;
+
+ rx_info->page_offset ^= rxq->buf_len;
+ get_page(page);
+
+ return true;
+
+umap_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
+}
+
+static struct sk_buff *hinic3_fetch_rx_buffer_xdp(struct hinic3_rxq *rxq,
+ u32 pkt_len,
+ struct xdp_buff *xdp)
+{
+ struct sk_buff *skb;
+ struct hinic3_rx_info *rx_info;
+ u32 sw_ci;
+ bool reuse;
+
+ sw_ci = rxq->cons_idx & rxq->q_mask;
+ rx_info = &rxq->rx_info[sw_ci];
+
+ skb = netdev_alloc_skb_ip_align(rxq->netdev, HINIC3_RX_HDR_SIZE);
+ if (unlikely(!skb))
+ return NULL;
+
+ reuse = hinic3_add_rx_frag_with_xdp(rxq, pkt_len, rx_info, skb, xdp);
+ if (likely(reuse))
+ hinic3_reuse_rx_page(rxq, rx_info);
+
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+
+ rxq->cons_idx += 1;
+ rxq->delta += 1;
+
+ return skb;
+}
+
#endif
static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_rq_cqe *rx_cqe,
u32 pkt_len, u32 vlan_len, u32 status)
{
- struct sk_buff *skb;
+ struct sk_buff *skb = NULL;
struct net_device *netdev = rxq->netdev;
u32 offload_type;
u16 num_lro;
@@ -812,13 +937,25 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_rq_cqe *rx_cqe,
#ifdef HAVE_XDP_SUPPORT
u32 xdp_status;
+ struct xdp_buff xdp = { 0 };
- xdp_status = hinic3_run_xdp(rxq, pkt_len);
+ xdp_status = (u32)(hinic3_run_xdp(rxq, pkt_len, &xdp));
if (xdp_status == HINIC3_XDP_PKT_DROP)
return 0;
-#endif
+ // build skb
+ if (xdp_status != HINIC3_XDP_PROG_EMPTY) {
+ // xdp_prog configured, build skb with xdp
+ skb = hinic3_fetch_rx_buffer_xdp(rxq, pkt_len, &xdp);
+ } else {
+ // xdp_prog not configured, build skb
+ skb = hinic3_fetch_rx_buffer(rxq, pkt_len);
+ }
+#else
+
+ // xdp is not supported
skb = hinic3_fetch_rx_buffer(rxq, pkt_len);
+#endif
if (unlikely(!skb)) {
RXQ_STATS_INC(rxq, alloc_skb_err);
return -ENOMEM;
@@ -852,7 +989,7 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_rq_cqe *rx_cqe,
hinic3_copy_lp_data(nic_dev, skb);
num_lro = HINIC3_GET_RX_NUM_LRO(status);
- if (num_lro)
+ if (num_lro > 1)
hinic3_lro_set_gso_params(skb, num_lro);
skb_record_rx_queue(skb, rxq->q_id);
@@ -931,12 +1068,40 @@ int hinic3_rx_poll(struct hinic3_rxq *rxq, int budget)
return pkts;
}
+#ifdef HAVE_PAGE_POOL_SUPPORT
+static struct page_pool *hinic3_create_page_pool(struct hinic3_nic_dev *nic_dev,
+ u32 rq_depth,
+ struct hinic3_rx_info *rx_info_arr)
+{
+ struct page_pool_params pp_params = {
+ .flags = PP_FLAG_DMA_MAP | PP_FLAG_PAGE_FRAG |
+ PP_FLAG_DMA_SYNC_DEV,
+ .order = nic_dev->page_order,
+ .pool_size = rq_depth * nic_dev->rx_buff_len /
+ (PAGE_SIZE << nic_dev->page_order),
+ .nid = dev_to_node(&(nic_dev->pdev->dev)),
+ .dev = &(nic_dev->pdev->dev),
+ .dma_dir = DMA_FROM_DEVICE,
+ .offset = 0,
+ .max_len = PAGE_SIZE << nic_dev->page_order,
+ };
+ struct page_pool *page_pool;
+ int i;
+
+ page_pool = nic_dev->page_pool_enabled ?
+ page_pool_create(&pp_params) : NULL;
+ for (i = 0; i < rq_depth; i++)
+ rx_info_arr[i].page_pool = page_pool;
+ return page_pool;
+}
+#endif
+
int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
u32 rq_depth, struct hinic3_dyna_rxq_res *rxqs_res)
{
struct hinic3_dyna_rxq_res *rqres = NULL;
u64 cqe_mem_size = sizeof(struct hinic3_rq_cqe) * rq_depth;
- int idx, i;
+ int idx;
u32 pkts;
u64 size;
@@ -947,46 +1112,49 @@ int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
if (!rqres->rx_info) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx info\n", idx);
- goto err_out;
+ goto err_alloc_rx_info;
}
-
rqres->cqe_start_vaddr =
dma_zalloc_coherent(&nic_dev->pdev->dev, cqe_mem_size,
&rqres->cqe_start_paddr,
GFP_KERNEL);
if (!rqres->cqe_start_vaddr) {
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d cqe\n", idx);
- goto err_out;
+ goto err_alloc_cqe;
}
-
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ rqres->page_pool = hinic3_create_page_pool(nic_dev, rq_depth,
+ rqres->rx_info);
+ if (nic_dev->page_pool_enabled && !rqres->page_pool) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to create rxq%d page pool\n", idx);
+ goto err_create_page_pool;
+ }
+#endif
pkts = hinic3_rx_alloc_buffers(nic_dev, rq_depth,
rqres->rx_info);
if (!pkts) {
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx buffers\n", idx);
- goto err_out;
+ goto err_alloc_buffers;
}
rqres->next_to_alloc = (u16)pkts;
}
return 0;
-err_out:
- for (i = 0; i < idx; i++) {
- rqres = &rxqs_res[i];
-
- hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- kfree(rqres->rx_info);
- }
-
+err_alloc_buffers:
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ page_pool_destroy(rqres->page_pool);
+err_create_page_pool:
+#endif
+ dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
+ rqres->cqe_start_vaddr,
+ rqres->cqe_start_paddr);
+err_alloc_cqe:
+ kfree(rqres->rx_info);
+err_alloc_rx_info:
+ hinic3_free_rxqs_res(nic_dev, idx, rq_depth, rxqs_res);
return -ENOMEM;
}
@@ -1001,6 +1169,10 @@ void hinic3_free_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
rqres = &rxqs_res[idx];
hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rqres->page_pool)
+ page_pool_destroy(rqres->page_pool);
+#endif
dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
rqres->cqe_start_vaddr,
rqres->cqe_start_paddr);
@@ -1084,6 +1256,7 @@ void hinic3_free_rxqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->rxqs);
+ nic_dev->rxqs = NULL;
}
int hinic3_alloc_rxqs(struct net_device *netdev)
@@ -1207,6 +1380,15 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
nic_info(&nic_dev->pdev->dev, "rxq %u restore_buf_num:%u\n", q_id, rxq->restore_buf_num);
rx_info = &rxq->rx_info[(hw_ci + rxq->q_depth - 1) & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool && rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool,
+ rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ goto reset_rxq;
+ }
+#endif
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev, rx_info->buf_dma_addr,
nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
@@ -1217,7 +1399,9 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
__free_pages(rx_info->page, nic_dev->page_order);
rx_info->page = NULL;
}
+ goto reset_rxq;
+reset_rxq:
rxq->delta = 1;
rxq->next_to_update = (u16)((hw_ci + rxq->q_depth - 1) & rxq->q_mask);
rxq->cons_idx = (u16)((rxq->next_to_update + 1) & rxq->q_mask);
@@ -1238,15 +1422,10 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
return err;
}
- if (!rq_pi_rd_en) {
- hinic3_write_db(rxq->rq, rxq->q_id & (NIC_DCB_COS_MAX - 1),
- RQ_CFLAG_DP, (u16)((u32)rxq->next_to_update << rxq->rq->wqe_type));
- } else {
- /* Write all the wqes before pi update */
- wmb();
+ hinic3_write_db(rxq->rq, rxq->q_id & (NIC_DCB_COS_MAX - 1),
+ RQ_CFLAG_DP,
+ (u16)((u32)rxq->next_to_update << rxq->rq->wqe_type));
- hinic3_update_rq_hw_pi(rxq->rq, rxq->next_to_update);
- }
return 0;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
index f4d6f4f..7dd4618 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
@@ -4,6 +4,9 @@
#ifndef HINIC3_RX_H
#define HINIC3_RX_H
+#ifdef HAVE_PAGE_POOL_SUPPORT
+#include <net/page_pool.h>
+#endif
#include <linux/types.h>
#include <linux/device.h>
#include <linux/mm_types.h>
@@ -27,22 +30,22 @@
#define HINIC3_RX_CSUM_IPSU_OTHER_ERR BIT(8)
#define HINIC3_HEADER_DATA_UNIT 2
+#define HINIC3_CQE_LEN 32
struct hinic3_rxq_stats {
- u64 packets;
- u64 bytes;
- u64 errors;
- u64 csum_errors;
- u64 other_errors;
- u64 dropped;
- u64 xdp_dropped;
- u64 rx_buf_empty;
-
- u64 alloc_skb_err;
- u64 alloc_rx_buf_err;
- u64 xdp_large_pkt;
- u64 restore_drop_sge;
- u64 rsvd2;
+ u64 packets;
+ u64 bytes;
+ u64 errors;
+ u64 csum_errors;
+ u64 other_errors;
+ u64 dropped;
+ u64 xdp_dropped;
+ u64 rx_buf_empty;
+ u64 alloc_skb_err;
+ u64 alloc_rx_buf_err;
+ u64 xdp_large_pkt;
+ u64 restore_drop_sge;
+ u64 rsvd2;
#ifdef HAVE_NDO_GET_STATS64
struct u64_stats_sync syncp;
#else
@@ -56,6 +59,9 @@ struct hinic3_rx_info {
struct hinic3_rq_cqe *cqe;
dma_addr_t cqe_dma;
struct page *page;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
u32 page_offset;
u32 rsvd1;
struct hinic3_rq_wqe *rq_wqe;
@@ -96,7 +102,7 @@ struct hinic3_rxq {
u16 next_to_update;
struct device *dev; /* device for DMA mapping */
- unsigned long status;
+ u64 status;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
@@ -124,6 +130,9 @@ struct hinic3_dyna_rxq_res {
struct hinic3_rx_info *rx_info;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
};
int hinic3_alloc_rxqs(struct net_device *netdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
index bdd5a8e..051f05d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
@@ -11,9 +11,10 @@
#ifndef HINIC3_SRV_NIC_H
#define HINIC3_SRV_NIC_H
-#include "hinic3_mgmt_interface.h"
+#include <linux/netdevice.h>
+#include "nic_mpu_cmd_defs.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_lld.h"
enum hinic3_queue_type {
@@ -64,6 +65,7 @@ enum hinic3_nic_event_type {
EVENT_NIC_DCB_STATE_CHANGE,
EVENT_NIC_BOND_DOWN,
EVENT_NIC_BOND_UP,
+ EVENT_NIC_OUTBAND_CFG,
};
/* *
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
index e958782..d3f8696 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
@@ -218,6 +218,77 @@ static void get_inner_l4_info(struct sk_buff *skb, union hinic3_l4 *l4,
}
}
+static void get_inner_l3_l4_type(struct sk_buff *skb, union hinic3_ip *ip,
+ union hinic3_l4 *l4,
+ enum sq_l3_type *l3_type, u8 *l4_proto)
+{
+ unsigned char *exthdr = NULL;
+
+ if (ip->v4->version == IP4_VERSION) {
+ *l3_type = IPV4_PKT_WITH_CHKSUM_OFFLOAD;
+ *l4_proto = ip->v4->protocol;
+
+#ifdef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
+ /* inner_transport_header is wrong in centos7.0 and suse12.1 */
+ l4->hdr = ip->hdr + ((u8)ip->v4->ihl << IP_HDR_IHL_UNIT_SHIFT);
+#endif
+ } else if (ip->v4->version == IP6_VERSION) {
+ *l3_type = IPV6_PKT;
+ exthdr = ip->hdr + sizeof(*ip->v6);
+ *l4_proto = ip->v6->nexthdr;
+ if (exthdr != l4->hdr) {
+ __be16 frag_off = 0;
+#ifndef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
+ ipv6_skip_exthdr(skb, (int)(exthdr - skb->data),
+ l4_proto, &frag_off);
+#else
+ int pld_off = 0;
+
+ pld_off = ipv6_skip_exthdr(skb,
+ (int)(exthdr - skb->data),
+ l4_proto, &frag_off);
+ l4->hdr = skb->data + pld_off;
+#endif
+ }
+ } else {
+ *l3_type = UNKNOWN_L3TYPE;
+ *l4_proto = 0;
+ }
+}
+
+static u8 hinic3_get_inner_l4_type(struct sk_buff *skb)
+{
+ enum sq_l3_type l3_type;
+ u8 l4_proto;
+ union hinic3_ip ip;
+ union hinic3_l4 l4;
+
+ ip.hdr = skb_inner_network_header(skb);
+ l4.hdr = skb_inner_transport_header(skb);
+
+ get_inner_l3_l4_type(skb, &ip, &l4, &l3_type, &l4_proto);
+ return l4_proto;
+}
+
+static void hinic3_set_unknown_tunnel_csum(struct sk_buff *skb)
+{
+ int csum_offset;
+ __sum16 skb_csum;
+ u8 l4_proto;
+
+ l4_proto = hinic3_get_inner_l4_type(skb);
+ /* Unsupport tunnel packet, disable csum offload */
+ skb_checksum_help(skb);
+ /* The value of csum is changed from 0xffff to 0 according to RFC1624 */
+ if (skb->ip_summed == CHECKSUM_NONE && l4_proto != IPPROTO_UDP) {
+ csum_offset = skb_checksum_start_offset(skb) + skb->csum_offset;
+ skb_csum = *(__sum16 *)(skb->data + csum_offset);
+ if (skb_csum == 0xffff) {
+ *(__sum16 *)(skb->data + csum_offset) = 0;
+ }
+ }
+}
+
static int hinic3_tx_csum(struct hinic3_txq *txq, struct hinic3_sq_task *task,
struct sk_buff *skb)
{
@@ -251,11 +322,9 @@ static int hinic3_tx_csum(struct hinic3_txq *txq, struct hinic3_sq_task *task,
l4_proto = IPPROTO_RAW;
}
- if (l4_proto != IPPROTO_UDP ||
- ((struct udphdr *)skb_transport_header(skb))->dest != VXLAN_OFFLOAD_PORT_LE) {
+ if (l4_proto != IPPROTO_UDP) {
TXQ_STATS_INC(txq, unknown_tunnel_pkt);
- /* Unsupport tunnel packet, disable csum offload */
- skb_checksum_help(skb);
+ hinic3_set_unknown_tunnel_csum(skb);
return 0;
}
}
@@ -265,44 +334,6 @@ static int hinic3_tx_csum(struct hinic3_txq *txq, struct hinic3_sq_task *task,
return 1;
}
-static void get_inner_l3_l4_type(struct sk_buff *skb, union hinic3_ip *ip,
- union hinic3_l4 *l4,
- enum sq_l3_type *l3_type, u8 *l4_proto)
-{
- unsigned char *exthdr = NULL;
-
- if (ip->v4->version == IP4_VERSION) {
- *l3_type = IPV4_PKT_WITH_CHKSUM_OFFLOAD;
- *l4_proto = ip->v4->protocol;
-
-#ifdef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
- /* inner_transport_header is wrong in centos7.0 and suse12.1 */
- l4->hdr = ip->hdr + ((u8)ip->v4->ihl << IP_HDR_IHL_UNIT_SHIFT);
-#endif
- } else if (ip->v4->version == IP6_VERSION) {
- *l3_type = IPV6_PKT;
- exthdr = ip->hdr + sizeof(*ip->v6);
- *l4_proto = ip->v6->nexthdr;
- if (exthdr != l4->hdr) {
- __be16 frag_off = 0;
-#ifndef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
- ipv6_skip_exthdr(skb, (int)(exthdr - skb->data),
- l4_proto, &frag_off);
-#else
- int pld_off = 0;
-
- pld_off = ipv6_skip_exthdr(skb,
- (int)(exthdr - skb->data),
- l4_proto, &frag_off);
- l4->hdr = skb->data + pld_off;
-#endif
- }
- } else {
- *l3_type = UNKNOWN_L3TYPE;
- *l4_proto = 0;
- }
-}
-
static void hinic3_set_tso_info(struct hinic3_sq_task *task, u32 *queue_info,
enum sq_l4offload_type l4_offload,
u32 offset, u32 mss)
@@ -463,7 +494,8 @@ static void get_pkt_stats(struct hinic3_tx_info *tx_info, struct sk_buff *skb)
#endif
} else {
#endif
- ihs = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ ihs = (u32)(skb_transport_offset(skb)) +
+ tcp_hdrlen(skb);
#if (defined(HAVE_SKB_INNER_TRANSPORT_HEADER) && \
defined(HAVE_SK_BUFF_ENCAPSULATION))
}
@@ -471,7 +503,8 @@ static void get_pkt_stats(struct hinic3_tx_info *tx_info, struct sk_buff *skb)
hdr_len = (skb_shinfo(skb)->gso_segs - 1) * ihs;
tx_info->num_bytes = skb->len + (u64)hdr_len;
} else {
- tx_info->num_bytes = skb->len > ETH_ZLEN ? skb->len : ETH_ZLEN;
+ tx_info->num_bytes = (skb->len > ETH_ZLEN) ?
+ skb->len : ETH_ZLEN;
}
tx_info->num_pkts = 1;
@@ -626,6 +659,14 @@ static netdev_tx_t hinic3_send_one_skb(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
+ /* l2nic outband vlan cfg enable */
+ if ((!skb_vlan_tag_present(skb)) &&
+ (nic_dev->nic_cap.outband_vlan_cfg_en == 1) &&
+ nic_dev->outband_cfg.outband_default_vid != 0) {
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+ (u16)nic_dev->outband_cfg.outband_default_vid);
+ }
+
offload = hinic3_tx_offload(skb, &task, &queue_info, txq);
if (unlikely(offload == TX_OFFLOAD_INVALID)) {
TXQ_STATS_INC(txq, offload_cow_skb_err);
@@ -834,6 +875,7 @@ int hinic3_alloc_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
tqres->bds = kzalloc(size, GFP_KERNEL);
if (!tqres->bds) {
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc txq%d bds info\n", idx);
goto err_out;
@@ -847,7 +889,9 @@ err_out:
tqres = &txqs_res[i];
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
return -ENOMEM;
@@ -864,7 +908,9 @@ void hinic3_free_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
free_all_tx_skbs(nic_dev, sq_depth, tqres->tx_info);
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
}
@@ -938,6 +984,7 @@ void hinic3_free_txqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->txqs);
+ nic_dev->txqs = NULL;
}
static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
@@ -954,7 +1001,7 @@ static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
static int hinic3_stop_sq(struct hinic3_txq *txq)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(txq->netdev);
- unsigned long timeout;
+ u64 timeout;
int err;
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -963,7 +1010,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
return 0;
usleep_range(900, 1000); /* sleep 900 us ~ 1000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* force hardware to drop packets */
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -976,7 +1023,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
break;
usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* Avoid msleep takes too long and get a fake result */
if (is_hw_complete_sq_process(txq->sq))
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
index 1b9e509..7ae029b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
@@ -29,7 +29,7 @@ struct hinic3_wq {
#define WQ_MASK_IDX(wq, idx) ((idx) & (wq)->idx_mask)
#define WQ_MASK_PAGE(wq, pg_idx) \
- ((pg_idx) < (wq)->num_wq_pages ? (pg_idx) : 0)
+ (((pg_idx) < ((wq)->num_wq_pages)) ? (pg_idx) : 0)
#define WQ_PAGE_IDX(wq, idx) ((idx) >> (wq)->wqebbs_per_page_shift)
#define WQ_OFFSET_IN_PAGE(wq, idx) ((idx) & (wq)->wqebbs_per_page_mask)
#define WQ_GET_WQEBB_ADDR(wq, pg_idx, idx_in_pg) \
@@ -75,7 +75,7 @@ static inline void *hinic3_wq_get_multi_wqebbs(struct hinic3_wq *wq,
pg_idx = WQ_PAGE_IDX(wq, *prod_idx);
off_in_page = WQ_OFFSET_IN_PAGE(wq, *prod_idx);
- if (off_in_page + num_wqebbs > wq->wqebbs_per_page) {
+ if ((off_in_page + num_wqebbs) > wq->wqebbs_per_page) {
/* wqe across wq page boundary */
*second_part_wqebbs_addr =
WQ_GET_WQEBB_ADDR(wq, WQ_MASK_PAGE(wq, pg_idx + 1), 0);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
index b742f8a..0419fc2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
@@ -400,12 +400,16 @@ static int wait_for_status_poll(struct hinic3_api_cmd_chain *chain)
API_CMD_STATUS_TIMEOUT, 100); /* wait 100 us once */
}
-static void copy_resp_data(struct hinic3_api_cmd_cell_ctxt *ctxt, void *ack,
- u16 ack_size)
+static void copy_resp_data(struct hinic3_api_cmd_chain *chain,
+ struct hinic3_api_cmd_cell_ctxt *ctxt,
+ void *ack, u16 ack_size)
{
struct hinic3_api_cmd_resp_fmt *resp = ctxt->resp;
+ int rsp_size_align = chain->rsp_size_align - 0x8;
+ int rsp_size = (ack_size > rsp_size_align) ? rsp_size_align : ack_size;
+
+ memcpy(ack, &resp->resp_data, rsp_size);
- memcpy(ack, &resp->resp_data, ack_size);
ctxt->status = 0;
}
@@ -464,7 +468,7 @@ static int wait_for_api_cmd_completion(struct hinic3_api_cmd_chain *chain,
case HINIC3_API_CMD_POLL_READ:
err = wait_for_resp_polling(ctxt);
if (err == 0)
- copy_resp_data(ctxt, ack, ack_size);
+ copy_resp_data(chain, ctxt, ack, ack_size);
else
sdk_err(dev, "API CMD poll response timeout\n");
break;
@@ -1055,13 +1059,11 @@ alloc_cells_buf_err:
alloc_wb_status_err:
kfree(chain->cell_ctxt);
-/*lint -save -e548*/
alloc_cell_ctxt_err:
if (chain->chain_type == HINIC3_API_CMD_WRITE_ASYNC_TO_MGMT_CPU)
spin_lock_deinit(&chain->async_lock);
else
sema_deinit(&chain->sem);
-/*lint -restore*/
return err;
}
@@ -1078,6 +1080,7 @@ static void api_chain_free(struct hinic3_api_cmd_chain *chain)
dma_free_coherent(dev, sizeof(*chain->wb_status),
chain->wb_status, chain->wb_status_paddr);
kfree(chain->cell_ctxt);
+ chain->cell_ctxt = NULL;
if (chain->chain_type == HINIC3_API_CMD_WRITE_ASYNC_TO_MGMT_CPU)
spin_lock_deinit(&chain->async_lock);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
index 0878186..ceb7636 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
@@ -657,7 +657,7 @@ static int cmdq_sync_cmd_direct_resp(struct hinic3_cmdq *cmdq, u8 mod,
cmd_info->channel = channel;
cmdq_set_cmd_buf(cmd_info, cmdq->hwdev, buf_in, NULL);
- memcpy(&saved_cmd_info, cmd_info, sizeof(*cmd_info));
+ memcpy(&saved_cmd_info, cmd_info, sizeof(struct hinic3_cmdq_cmd_info));
cmdq_set_lcmd_wqe(&wqe, SYNC_CMD_DIRECT_RESP, buf_in, NULL,
wrapped, mod, cmd, curr_prod_idx);
@@ -745,7 +745,7 @@ static int cmdq_sync_cmd_detail_resp(struct hinic3_cmdq *cmdq, u8 mod, u8 cmd,
cmd_info->channel = channel;
cmdq_set_cmd_buf(cmd_info, cmdq->hwdev, buf_in, buf_out);
- memcpy(&saved_cmd_info, cmd_info, sizeof(*cmd_info));
+ memcpy(&saved_cmd_info, cmd_info, sizeof(struct hinic3_cmdq_cmd_info));
cmdq_set_lcmd_wqe(&wqe, SYNC_CMD_SGE_RESP, buf_in, buf_out,
wrapped, mod, cmd, curr_prod_idx);
@@ -994,9 +994,11 @@ int hinic3_cmdq_async(void *hwdev, u8 mod, u8 cmd, struct hinic3_cmd_buf *buf_in
return cmdq_async_cmd(&cmdqs->cmdq[HINIC3_CMDQ_SYNC], mod,
cmd, buf_in, channel);
}
+EXPORT_SYMBOL(hinic3_cmdq_async);
int hinic3_cmdq_async_cos(void *hwdev, u8 mod, u8 cmd,
- u8 cos_id, struct hinic3_cmd_buf *buf_in, u16 channel)
+ u8 cos_id, struct hinic3_cmd_buf *buf_in,
+ u16 channel)
{
struct hinic3_cmdqs *cmdqs = NULL;
int err;
@@ -1136,7 +1138,7 @@ void hinic3_cmdq_ceq_handler(void *handle, u32 ceqe_data)
break;
case HINIC3_CMD_TYPE_SET_ARM:
/* arm_bit was set until here */
- if (cmdq_arm_ceq_handler(cmdq, wqe, ci))
+ if (cmdq_arm_ceq_handler(cmdq, wqe, ci) != 0)
return;
break;
default:
@@ -1221,6 +1223,7 @@ cmd_infos_err:
static void free_cmdq(struct hinic3_cmdq *cmdq)
{
kfree(cmdq->cmd_infos);
+ cmdq->cmd_infos = NULL;
spin_lock_deinit(&cmdq->cmdq_lock);
}
@@ -1425,7 +1428,7 @@ static int create_cmdq_wq(struct hinic3_cmdqs *cmdqs)
type = HINIC3_CMDQ_SYNC;
for (; type < cmdqs->cmdq_num; type++)
memcpy((u8 *)cmdqs->wq_block_vaddr +
- CMDQ_WQ_CLA_SIZE * type,
+ ((u64)type * CMDQ_WQ_CLA_SIZE),
cmdqs->cmdq[type].wq.wq_block_vaddr,
cmdqs->cmdq[type].wq.num_wq_pages * sizeof(u64));
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
index b0344ea..b174ad2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
@@ -14,11 +14,6 @@
#include "hinic3_common.h"
#include "hinic3_hwdev.h"
-struct dma_pool {
- unsigned int size;
- void *dev_hdl;
-};
-
#define HINIC3_SCMD_DATA_LEN 16
#define HINIC3_CMDQ_DEPTH 4096
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
index 4c13a2e..af336f2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
@@ -22,11 +22,15 @@
#include "hinic3_sriov.h"
#include "hinic3_nictool.h"
#include "hinic3_pci_id_tbl.h"
+#include "hinic3_hwdev.h"
+#include "cfg_mgmt_mpu_cmd_defs.h"
+#include "mpu_cmd_base_defs.h"
#include "hinic3_dev_mgmt.h"
#define HINIC3_WAIT_TOOL_CNT_TIMEOUT 10000
#define HINIC3_WAIT_TOOL_MIN_USLEEP_TIME 9900
#define HINIC3_WAIT_TOOL_MAX_USLEEP_TIME 10000
+#define HIGHT_BDF 8
static unsigned long card_bit_map;
@@ -60,15 +64,23 @@ void lld_dev_cnt_init(struct hinic3_pcidev *pci_adapter)
void lld_dev_hold(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_inc(&pci_adapter->ref_cnt);
}
void lld_dev_put(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_dec(&pci_adapter->ref_cnt);
}
@@ -236,6 +248,40 @@ void hinic3_get_all_chip_id(void *id_info)
card_id->num = (u32)i;
}
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+ u64 bar1_phy_addr = 0;
+ u64 bar3_phy_addr = 0;
+ u64 bar1_size = 0;
+ u64 bar3_size = 0;
+
+ lld_hold();
+
+ /* get PF bar1 or bar3 physical address to verify */
+ list_for_each_entry(chip_node, &g_hinic3_chip_list, node) {
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (hinic3_func_type(dev->hwdev) == TYPE_VF)
+ continue;
+
+ bar1_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+ bar1_size = pci_resource_len(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+
+ bar3_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ bar3_size = pci_resource_len(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ if ((phy_addr == bar1_phy_addr && vmsize <= bar1_size) ||
+ (phy_addr == bar3_phy_addr && vmsize <= bar3_size)) {
+ lld_put();
+ return 0;
+ }
+ }
+ }
+
+ lld_put();
+ return -EINVAL;
+}
+
void hinic3_get_card_func_info_by_card_name(const char *chip_name,
struct hinic3_card_func_info *card_func)
{
@@ -328,7 +374,6 @@ out:
if (dev)
lld_dev_hold(dev);
lld_put();
-
return dev;
}
@@ -422,6 +467,28 @@ struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name
return NULL;
}
+void *hinic3_get_ppf_dev(void)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct list_head *chip_list = NULL;
+
+ lld_hold();
+ chip_list = get_hinic3_chip_list();
+
+ list_for_each_entry(chip_node, chip_list, node)
+ list_for_each_entry(pci_adapter, &chip_node->func_list, node)
+ if (hinic3_func_type(pci_adapter->hwdev) == TYPE_PPF) {
+ pr_info("Get ppf_func_id:%u", hinic3_global_func_id(pci_adapter->hwdev));
+ lld_put();
+ return pci_adapter->lld_dev.hwdev;
+ }
+
+ lld_put();
+ return NULL;
+}
+EXPORT_SYMBOL(hinic3_get_ppf_dev);
+
struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
enum hinic3_service_type type)
{
@@ -518,6 +585,7 @@ EXPORT_SYMBOL(hinic3_get_ppf_lld_dev_unsafe);
int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len)
{
struct hinic3_pcidev *pci_adapter = NULL;
+ int ret = 0;
if (!lld_dev || !chip_name || !max_len)
return -EINVAL;
@@ -527,12 +595,18 @@ int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 ma
return -EFAULT;
lld_hold();
- strncpy(chip_name, pci_adapter->chip_node->chip_name, max_len);
+ if (strscpy(chip_name, pci_adapter->chip_node->chip_name, max_len) < 0)
+ goto RELEASE;
chip_name[max_len - 1] = '\0';
lld_put();
return 0;
+
+RELEASE:
+ lld_put();
+
+ return ret;
}
EXPORT_SYMBOL(hinic3_get_chip_name);
@@ -541,6 +615,81 @@ struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev)
return lld_dev->hwdev;
}
+void hinic3_write_oshr_info(struct os_hot_replace_info *out_oshr_info,
+ struct hw_pf_info *info,
+ struct hinic3_board_info *board_info,
+ struct card_node *chip_node, u32 serivce_enable,
+ u32 func_info_idx)
+{
+ out_oshr_info->func_infos[func_info_idx].pf_idx = info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].backup_pf =
+ (((info->glb_func_idx) / (board_info->port_num)) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ ((info->glb_func_idx) + (board_info->port_num)) :
+ ((info->glb_func_idx) - (board_info->port_num));
+ out_oshr_info->func_infos[func_info_idx].partition =
+ ((info->glb_func_idx) / (board_info->port_num)) % HOT_REPLACE_PARTITION_NUM;
+ out_oshr_info->func_infos[func_info_idx].port_id = info->port_id;
+ out_oshr_info->func_infos[func_info_idx].bdf = (info->bus_num << HIGHT_BDF) + info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].bus_num = chip_node->bus_num;
+ out_oshr_info->func_infos[func_info_idx].valid = serivce_enable;
+ memcpy(out_oshr_info->func_infos[func_info_idx].card_name,
+ chip_node->chip_name, IFNAMSIZ);
+}
+
+void hinic3_get_os_hot_replace_info(void *oshr_info)
+{
+ struct os_hot_replace_info *out_oshr_info = (struct os_hot_replace_info *)oshr_info;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dst_dev = NULL;
+ struct hinic3_board_info *board_info = NULL;
+ struct hw_pf_info *infos = NULL;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ u32 func_info_idx = 0, func_id = 0, func_num, serivce_enable = 0;
+ struct list_head *hinic3_chip_list = get_hinic3_chip_list();
+ int err;
+
+ lld_hold();
+ pf_infos = kzalloc(sizeof(struct hinic3_hw_pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ pr_err("kzalloc pf_infos fail\n");
+ lld_put();
+ return;
+ }
+ list_for_each_entry(chip_node, hinic3_chip_list, node) {
+ list_for_each_entry(dst_dev, &chip_node->func_list, node) { // get all pf infos in one time by one pf_id
+ err = hinic3_get_hw_pf_infos(dst_dev->hwdev, pf_infos, HINIC3_CHANNEL_COMM);
+ if (err != 0) {
+ pr_err("get pf info failed\n");
+ break;
+ }
+
+ serivce_enable = 0;
+ infos = pf_infos->infos;
+ board_info = &((struct hinic3_hwdev *)(dst_dev->hwdev))->board_info;
+ if (((struct hinic3_hwdev *)(dst_dev->hwdev))->hot_replace_mode == HOT_REPLACE_ENABLE) {
+ serivce_enable = 1;
+ }
+ break;
+ }
+
+ func_num = pf_infos->num_pfs;
+ if (func_num <= 0) {
+ pr_err("get pf num failed\n");
+ break;
+ }
+
+ for (func_id = 0; func_id < func_num; func_id++) {
+ hinic3_write_oshr_info(out_oshr_info, &infos[func_id],
+ board_info, chip_node,
+ serivce_enable, func_info_idx);
+ func_info_idx++;
+ }
+ }
+ out_oshr_info->func_cnt = func_info_idx;
+ kfree(pf_infos);
+ lld_put();
+}
+
struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(lld_dev->pdev);
@@ -620,9 +769,13 @@ void hinic3_get_card_info(const void *hwdev, void *bufin)
}
if (hinic3_func_for_mgmt(fun_hwdev))
- strlcpy(info->pf[i].name, "FOR_MGMT", IFNAMSIZ);
+ strscpy(info->pf[i].name, "FOR_MGMT", IFNAMSIZ);
+
+ if (dev->lld_dev.pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID) {
+ strscpy(info->pf[i].name, "bifur", IFNAMSIZ);
+ }
- strlcpy(info->pf[i].bus_info, pci_name(dev->pcidev),
+ strscpy(info->pf[i].bus_info, pci_name(dev->pcidev),
sizeof(info->pf[i].bus_info));
info->pf_num++;
i = info->pf_num;
@@ -719,6 +872,7 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
struct card_node *chip_node = NULL;
unsigned char i;
unsigned char bus_number = 0;
+ int err;
if (chip_node_is_exist(pci_adapter, &bus_number))
return 0;
@@ -750,6 +904,13 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
return -EINVAL;
}
+ err = sscanf(chip_node->chip_name, HINIC3_CHIP_NAME "%d", &(chip_node->chip_id));
+ if (err <= 0) {
+ clear_bit(i, &card_bit_map);
+ kfree(chip_node);
+ return -EINVAL;
+ }
+
sdk_info(&pci_adapter->pcidev->dev,
"Add new chip %s to global list succeed\n",
chip_node->chip_name);
@@ -801,3 +962,36 @@ int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *
return 0;
}
+
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin)
+{
+ struct card_node *chip_node = NULL;
+ struct card_mbox_cnt_info *info = (struct card_mbox_cnt_info *)bufin;
+ struct hinic3_pcidev *dev = NULL;
+ struct hinic3_hwdev *func_hwdev = NULL;
+ u32 i = 0;
+
+ info->func_num = 0;
+ chip_node = hinic3_get_chip_node_by_hwdev(hwdev);
+ if (chip_node == NULL)
+ return;
+
+ lld_hold();
+
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ func_hwdev = (struct hinic3_hwdev *)dev->hwdev;
+ strscpy(info->func_info[i].bus_info, pci_name(dev->pcidev),
+ sizeof(info->func_info[i].bus_info));
+
+ info->func_info[i].send_cnt = func_hwdev->mbox_send_cnt;
+ info->func_info[i].ack_cnt = func_hwdev->mbox_ack_cnt;
+ info->func_num++;
+ i = info->func_num;
+ if (i >= ARRAY_SIZE(info->func_info)) {
+ sdk_err(&dev->pcidev->dev, "chip_node->func_list bigger than pf_max + vf_max\n");
+ break;
+ }
+ }
+
+ lld_put();
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
index a327c4a..bfa8f3e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
@@ -19,8 +19,10 @@
#define PRINT_ULD_DETACH_TIMEOUT_INTERVAL 1000 /* 1 second */
#define ULD_LOCK_MIN_USLEEP_TIME 900
#define ULD_LOCK_MAX_USLEEP_TIME 1000
+#define BIFUR_RESOURCE_PF_SSID 0x05a1
-#define HINIC3_IS_VF_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_VF)
+#define HINIC3_IS_VF_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_VF || \
+ (pdev)->device == HINIC3_DEV_SDI_5_1_ID_VF)
#define HINIC3_IS_SPU_DEV(pdev) \
(((pdev)->device == HINIC3_DEV_ID_SPU) || ((pdev)->device == HINIC3_DEV_ID_SDI_5_0_PF) || \
(((pdev)->device == HINIC3_DEV_ID_DPU_PF)))
@@ -79,6 +81,13 @@ struct hinic3_pcidev {
u16 probe_fault_level;
u16 rsvd2;
u64 rsvd4;
+
+ struct workqueue_struct *multi_host_mgmt_workq;
+ struct work_struct slave_nic_work;
+ struct work_struct slave_vroce_work;
+
+ struct workqueue_struct *migration_probe_workq;
+ struct delayed_work migration_probe_dwork;
};
struct hinic_chip_info {
@@ -104,4 +113,6 @@ void wait_lld_dev_unused(struct hinic3_pcidev *pci_adapter);
void *hinic3_get_hwdev_by_pcidev(struct pci_dev *pdev);
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
index 1949ab8..8f9d00a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
@@ -101,7 +101,8 @@ static bool check_image_device_type(struct hinic3_hwdev *hwdev, u32 device_type)
static void encapsulate_update_cmd(struct hinic3_cmd_update_firmware *msg,
struct firmware_section *section_info,
- int *remain_len, u32 *send_len, u32 *send_pos)
+ const int *remain_len, u32 *send_len,
+ u32 *send_pos)
{
memset(msg->data, 0, sizeof(msg->data));
msg->ctl_info.sf = (*remain_len == section_info->section_len) ? true : false;
@@ -380,6 +381,7 @@ int hinic3_init_devlink(struct hinic3_hwdev *hwdev)
struct pci_dev *pdev = NULL;
int err;
+ pdev = hwdev->hwif->pdev;
devlink = devlink_alloc(&hinic3_devlink_ops, sizeof(struct hinic3_devlink));
if (!devlink) {
sdk_err(hwdev->dev_hdl, "Failed to alloc devlink\n");
@@ -391,7 +393,6 @@ int hinic3_init_devlink(struct hinic3_hwdev *hwdev)
hwdev->devlink_dev->activate_fw = FW_CFG_DEFAULT_INDEX;
hwdev->devlink_dev->switch_cfg = FW_CFG_DEFAULT_INDEX;
- pdev = hwdev->hwif->pdev;
err = devlink_register(devlink, &pdev->dev);
if (err) {
sdk_err(hwdev->dev_hdl, "Failed to register devlink\n");
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
index 4b08aa0..caa99e3 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
@@ -26,6 +26,8 @@
#include "hinic3_prof_adap.h"
#include "hinic3_eqs.h"
+#include "vram_common.h"
+
#define HINIC3_EQS_WQ_NAME "hinic3_eqs"
#define AEQ_CTRL_0_INTR_IDX_SHIFT 0
@@ -66,7 +68,6 @@
#define HINIC3_TASK_PROCESS_EQE_LIMIT 1024
#define HINIC3_EQ_UPDATE_CI_STEP 64
-/*lint -e806*/
static uint g_aeq_len = HINIC3_DEFAULT_AEQ_LEN;
module_param(g_aeq_len, uint, 0444);
MODULE_PARM_DESC(g_aeq_len,
@@ -83,7 +84,6 @@ static uint g_num_ceqe_in_tasklet = HINIC3_TASK_PROCESS_EQE_LIMIT;
module_param(g_num_ceqe_in_tasklet, uint, 0444);
MODULE_PARM_DESC(g_num_ceqe_in_tasklet,
"The max number of ceqe can be processed in tasklet, default = 1024");
-/*lint +e806*/
#define CEQ_CTRL_0_INTR_IDX_SHIFT 0
#define CEQ_CTRL_0_DMA_ATTR_SHIFT 12
@@ -801,6 +801,7 @@ static int alloc_eq_pages(struct hinic3_eq *eq)
u32 reg, init_val;
u16 pg_idx, i;
int err;
+ gfp_t gfp_vram;
eq->eq_pages = kcalloc(eq->num_pages, sizeof(*eq->eq_pages),
GFP_KERNEL);
@@ -809,12 +810,15 @@ static int alloc_eq_pages(struct hinic3_eq *eq)
return -ENOMEM;
}
+ gfp_vram = hi_vram_get_gfp_vram();
+
for (pg_idx = 0; pg_idx < eq->num_pages; pg_idx++) {
eq_page = &eq->eq_pages[pg_idx];
err = hinic3_dma_zalloc_coherent_align(eq->hwdev->dev_hdl,
eq->page_size,
HINIC3_MIN_EQ_PAGE_SIZE,
- GFP_KERNEL, eq_page);
+ GFP_KERNEL | gfp_vram,
+ eq_page);
if (err) {
sdk_err(eq->hwdev->dev_hdl, "Failed to alloc eq page, page index: %hu\n",
pg_idx);
@@ -865,6 +869,7 @@ static void free_eq_pages(struct hinic3_eq *eq)
&eq->eq_pages[pg_idx]);
kfree(eq->eq_pages);
+ eq->eq_pages = NULL;
}
static inline u32 get_page_size(const struct hinic3_eq *eq)
@@ -1104,7 +1109,8 @@ int hinic3_aeqs_init(struct hinic3_hwdev *hwdev, u16 num_aeqs,
hwdev->aeqs = aeqs;
aeqs->hwdev = hwdev;
aeqs->num_aeqs = num_aeqs;
- aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME, WQ_MEM_RECLAIM,
+ aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME,
+ WQ_MEM_RECLAIM | WQ_HIGHPRI,
HINIC3_MAX_AEQS);
if (!aeqs->workq) {
sdk_err(hwdev->dev_hdl, "Failed to initialize aeq workqueue\n");
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
index a4cbac8..6b96b87 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
@@ -83,6 +83,48 @@ int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id,
}
/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read and clear to zero
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
+ u16 *value)
+{
+ struct chipif_sml_ctr_rd_req req;
+ union ctr_rd_rsp rsp;
+ int ret;
+
+ if (!hwdev || !value)
+ return -EFAULT;
+
+ if (!COMM_SUPPORT_API_CHAIN((struct hinic3_hwdev *)hwdev))
+ return -EPERM;
+
+ memset(&req, 0, sizeof(req));
+
+ hinic3_sml_ctr_read_build_req(&req, instance,
+ CHIPIF_SM_CTR_OP_READ_CLEAR,
+ CHIPIF_ACK, ctr_id, 0);
+
+ ret = hinic3_api_cmd_read_ack(hwdev, node, (u8 *)&req,
+ (unsigned short)sizeof(req),
+ (void *)&rsp,
+ (unsigned short)sizeof(rsp));
+ if (ret) {
+ sdk_err(((struct hinic3_hwdev *)hwdev)->dev_hdl,
+ "Sm 16bit counter clear fail, err(%d)\n", ret);
+ return ret;
+ }
+ sml_ctr_htonl_n((u32 *)&rsp, sizeof(rsp) / sizeof(u32));
+ *value = rsp.bs_ss16_rsp.value1;
+
+ return 0;
+}
+
+/**
* hinic3_sm_ctr_rd32 - small single 32 counter read
* @hwdev: the hardware device
* @node: the node id
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
index cea7581..2d4a9f6 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
@@ -34,13 +34,16 @@ static void parse_pub_res_cap_dfx(struct hinic3_hwdev *hwdev,
cap->max_vf);
sdk_info(hwdev->dev_hdl, "Host_pf_num: 0x%x, pf_id_start: 0x%x, host_vf_num: 0x%x, vf_id_start: 0x%x\n",
cap->pf_num, cap->pf_id_start, cap->vf_num, cap->vf_id_start);
- sdk_info(hwdev->dev_hdl, "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x\n",
- cap->host_valid_bitmap, cap->master_host_id, cap->srv_multi_host_mode);
sdk_info(hwdev->dev_hdl,
- "fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
- cap->fake_vf_start_id, cap->fake_vf_num, cap->fake_vf_max_pctx);
- sdk_info(hwdev->dev_hdl, "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x\n",
- cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len);
+ "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x, hot_plug_disable: 0x%x\n",
+ cap->host_valid_bitmap, cap->master_host_id, cap->srv_multi_host_mode,
+ cap->hot_plug_disable);
+ sdk_info(hwdev->dev_hdl,
+ "os_hot_replace: 0x%x, fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
+ cap->os_hot_replace, cap->fake_vf_start_id, cap->fake_vf_num, cap->fake_vf_max_pctx);
+ sdk_info(hwdev->dev_hdl,
+ "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x, bond_create_mode: 0x%x\n",
+ cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len, cap->bond_create_mode);
}
static void parse_cqm_res_cap(struct hinic3_hwdev *hwdev, struct service_cap *cap,
@@ -109,6 +112,9 @@ static void parse_pub_res_cap(struct hinic3_hwdev *hwdev,
cap->host_valid_bitmap = dev_cap->host_valid_bitmap;
cap->master_host_id = dev_cap->master_host_id;
cap->srv_multi_host_mode = dev_cap->srv_multi_host_mode;
+ cap->hot_plug_disable = dev_cap->hot_plug_disable;
+ cap->bond_create_mode = dev_cap->bond_create_mode;
+ cap->os_hot_replace = dev_cap->os_hot_replace;
cap->fake_vf_en = dev_cap->fake_vf_en;
cap->fake_vf_start_bit = dev_cap->fake_vf_start_bit;
cap->fake_vf_end_bit = dev_cap->fake_vf_end_bit;
@@ -148,18 +154,27 @@ static void parse_l2nic_res_cap(struct hinic3_hwdev *hwdev,
nic_cap->max_sqs = dev_cap->nic_max_sq_id + 1;
nic_cap->max_rqs = dev_cap->nic_max_rq_id + 1;
nic_cap->default_num_queues = dev_cap->nic_default_num_queues;
+ nic_cap->outband_vlan_cfg_en = dev_cap->outband_vlan_cfg_en;
+ nic_cap->lro_enable = dev_cap->lro_enable;
sdk_info(hwdev->dev_hdl, "L2nic resource capbility, max_sqs: 0x%x, max_rqs: 0x%x\n",
nic_cap->max_sqs, nic_cap->max_rqs);
/* Check parameters from firmware */
- if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP ||
- nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
- sdk_info(hwdev->dev_hdl, "Number of qp exceed limit[1-%d]: sq: %u, rq: %u\n",
- HINIC3_CFG_MAX_QP, nic_cap->max_sqs, nic_cap->max_rqs);
+ if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of sq exceed limit[1-%d]: sq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_sqs);
nic_cap->max_sqs = HINIC3_CFG_MAX_QP;
+ }
+
+ if (nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of rq exceed limit[1-%d]: rq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_rqs);
nic_cap->max_rqs = HINIC3_CFG_MAX_QP;
}
+
+ if (nic_cap->outband_vlan_cfg_en)
+ sdk_info(hwdev->dev_hdl, "L2nic outband vlan cfg enabled\n");
}
static void parse_fc_res_cap(struct hinic3_hwdev *hwdev,
@@ -333,6 +348,28 @@ static void parse_ipsec_res_cap(struct hinic3_hwdev *hwdev,
dev_cap->ipsec_max_sactx, dev_cap->ipsec_max_cq);
}
+static void parse_vbs_res_cap(struct hinic3_hwdev *hwdev,
+ struct service_cap *cap,
+ struct cfg_cmd_dev_cap *dev_cap,
+ enum func_type type)
+{
+ struct vbs_service_cap *vbs_cap = &cap->vbs_cap;
+
+ vbs_cap->vbs_max_volq = dev_cap->vbs_max_volq;
+ vbs_cap->vbs_main_pf_enable = dev_cap->vbs_main_pf_enable;
+ vbs_cap->vbs_vsock_pf_enable = dev_cap->vbs_vsock_pf_enable;
+ vbs_cap->vbs_fushion_queue_pf_enable = dev_cap->vbs_fushion_queue_pf_enable;
+
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS resource capbility, vbs_max_volq: 0x%x\n",
+ dev_cap->vbs_max_volq);
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS pf info, vbs_main_pf_enable: 0x%x, vbs_vsock_pf_enable: 0x%x, vbs_fushion_queue_pf_enable: 0x%x\n",
+ dev_cap->vbs_main_pf_enable,
+ dev_cap->vbs_vsock_pf_enable,
+ dev_cap->vbs_fushion_queue_pf_enable);
+}
+
static void parse_dev_cap(struct hinic3_hwdev *dev,
struct cfg_cmd_dev_cap *dev_cap, enum func_type type)
{
@@ -375,6 +412,9 @@ static void parse_dev_cap(struct hinic3_hwdev *dev,
if (IS_PPA_TYPE(dev))
parse_ppa_res_cap(dev, cap, dev_cap, type);
+
+ if (IS_VBS_TYPE(dev))
+ parse_vbs_res_cap(dev, cap, dev_cap, type);
}
static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
@@ -404,6 +444,23 @@ static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
return 0;
}
+u8 hinic3_get_bond_create_mode(void *dev)
+{
+ struct hinic3_hwdev *hwdev = NULL;
+ struct service_cap *cap = NULL;
+
+ if (!dev) {
+ pr_err("pointer dev is NULL\n");
+ return -EINVAL;
+ }
+
+ hwdev = (struct hinic3_hwdev *)dev;
+ cap = &hwdev->cfg_mgmt->svc_cap;
+
+ return cap->bond_create_mode;
+}
+EXPORT_SYMBOL(hinic3_get_bond_create_mode);
+
int hinic3_get_dev_cap(void *dev)
{
enum func_type type;
@@ -1173,6 +1230,20 @@ bool hinic3_support_ppa(void *hwdev, struct ppa_service_cap *cap)
}
EXPORT_SYMBOL(hinic3_support_ppa);
+bool hinic3_support_bifur(void *hwdev, struct bifur_service_cap *cap)
+{
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)hwdev;
+
+ if (!hwdev)
+ return false;
+
+ if (!IS_BIFUR_TYPE(dev))
+ return false;
+
+ return true;
+}
+EXPORT_SYMBOL(hinic3_support_bifur);
+
bool hinic3_support_migr(void *hwdev, struct migr_service_cap *cap)
{
struct hinic3_hwdev *dev = hwdev;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
index db6e3ca..7157e97 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
@@ -166,6 +166,11 @@ struct service_cap {
u8 srv_multi_host_mode;
u16 virtio_vq_size;
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 os_hot_replace;
+ u8 rsvd1;
+
u8 timer_pf_num;
u8 timer_pf_id_start;
u16 timer_vf_num;
@@ -319,9 +324,11 @@ struct cfg_mgmt_info {
#define IS_RDMA_ENABLE(dev) \
((dev)->cfg_mgmt->svc_cap.sf_svc_attr.rdma_en)
#define IS_PPA_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_PPA)
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_PPA)
#define IS_MIGR_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_MIGRATE)
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_MIGRATE)
+#define IS_BIFUR_TYPE(dev) \
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_BIFUR)
int init_cfg_mgmt(struct hinic3_hwdev *dev);
@@ -333,5 +340,7 @@ void free_capability(struct hinic3_hwdev *dev);
int hinic3_init_vf_dev_cap(void *hwdev);
+u8 hinic3_get_bond_create_mode(void *dev);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
index d8a1a28..47264f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
@@ -21,7 +21,9 @@
#include "hinic3_hw_cfg.h"
#include "hinic3_cmdq.h"
#include "mpu_inband_cmd_defs.h"
+#include "mpu_board_defs.h"
#include "hinic3_hw_comm.h"
+#include "vram_common.h"
#define HINIC3_MSIX_CNT_LLI_TIMER_SHIFT 0
#define HINIC3_MSIX_CNT_LLI_CREDIT_SHIFT 8
@@ -242,12 +244,19 @@ int hinic3_func_reset(void *dev, u16 func_id, u64 reset_flag, u16 channel)
struct hinic3_hwdev *hwdev = dev;
u16 out_size = sizeof(func_reset);
int err = 0;
+ int is_in_kexec;
if (!dev) {
pr_err("Invalid para: dev is null.\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ sdk_info(hwdev->dev_hdl, "Skip function reset!\n");
+ return 0;
+ }
+
sdk_info(hwdev->dev_hdl, "Function is reset, flag: 0x%llx, channel:0x%x\n",
reset_flag, channel);
@@ -523,7 +532,7 @@ EXPORT_SYMBOL(hinic3_set_ppf_flr_type);
int hinic3_set_ppf_tbl_hotreplace_flag(void *hwdev, u8 flag)
{
- struct comm_cmd_ppf_tbl_htrp_config htr_info = {0};
+ struct comm_cmd_ppf_tbl_htrp_config htr_info = {};
u16 out_size = sizeof(struct comm_cmd_ppf_tbl_htrp_config);
struct hinic3_hwdev *dev = hwdev;
int ret;
@@ -868,11 +877,19 @@ static int set_ppf_tmr_status(struct hinic3_hwdev *hwdev,
int hinic3_ppf_tmr_start(void *hwdev)
{
+ int is_in_kexec;
+
if (!hwdev) {
pr_err("Hwdev pointer is NULL for starting ppf timer\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ pr_info("Skip starting ppt timer during kexec");
+ return 0;
+ }
+
return set_ppf_tmr_status(hwdev, HINIC_PPF_TMR_FLAG_START);
}
EXPORT_SYMBOL(hinic3_ppf_tmr_start);
@@ -888,18 +905,110 @@ int hinic3_ppf_tmr_stop(void *hwdev)
}
EXPORT_SYMBOL(hinic3_ppf_tmr_stop);
+static int hi_vram_kalloc_align(struct hinic3_hwdev *hwdev, char *name,
+ u32 page_size, u32 page_num,
+ struct hinic3_dma_addr_align *mem_align)
+{
+ void *vaddr = NULL, *align_vaddr = NULL;
+ dma_addr_t paddr, align_paddr;
+ u64 real_size = page_size;
+ u64 align = page_size;
+
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ /* align */
+ if (align_paddr == paddr) {
+ align_vaddr = vaddr;
+ goto out;
+ }
+
+ hi_vram_kfree((void *)vaddr, name, real_size);
+
+ /* realloc memory for align */
+ real_size = page_size + align;
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc align failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ align_vaddr = (void *)((u64)vaddr + (align_paddr - paddr));
+
+out:
+ mem_align->real_size = (u32)real_size;
+ mem_align->ori_vaddr = vaddr;
+ mem_align->ori_paddr = paddr;
+ mem_align->align_vaddr = align_vaddr;
+ mem_align->align_paddr = align_paddr;
+
+ return 0;
+}
+
+static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
+{
+ u32 i;
+ struct hinic3_dma_addr_align *page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = hwdev->mqm_eqm_vram_name;
+
+ page_addr = hwdev->mqm_att.brm_srch_page_addr;
+
+ for (i = 0; i < hwdev->mqm_att.page_num; i++) {
+ if (is_use_vram != 0) {
+ hi_vram_kfree(page_addr->ori_vaddr, mqm_eqm_vram_name[i].vram_name,
+ page_addr->real_size);
+ } else {
+ hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
+ }
+ page_addr->ori_vaddr = NULL;
+ page_addr++;
+ }
+
+ kfree(mqm_eqm_vram_name);
+ hwdev->mqm_eqm_vram_name = NULL;
+}
+
static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
u32 page_num)
{
struct hinic3_dma_addr_align *page_addr = hwdev->mqm_att.brm_srch_page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = NULL;
u32 valid_num = 0;
u32 flag = 1;
u32 i = 0;
int err;
+ u16 func_id;
+
+ mqm_eqm_vram_name = kzalloc(sizeof(struct mqm_eqm_vram_name_s) * page_num, GFP_KERNEL);
+ if (mqm_eqm_vram_name == NULL) {
+ sdk_err(hwdev->dev_hdl, "mqm eqm alloc vram name failed.\n");
+ return -ENOMEM;
+ }
+
+ hwdev->mqm_eqm_vram_name = mqm_eqm_vram_name;
+ func_id = hinic3_global_func_id(hwdev);
for (i = 0; i < page_num; i++) {
- err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl, page_size,
- page_size, GFP_KERNEL, page_addr);
+ if (is_use_vram != 0) {
+ snprintf(mqm_eqm_vram_name[i].vram_name,
+ VRAM_NAME_MAX_LEN, "%s%u%s%u",
+ VRAM_CQM_GLB_FUNC_BASE, func_id, VRAM_NIC_MQM, i);
+ err = hi_vram_kalloc_align(
+ hwdev, mqm_eqm_vram_name[i].vram_name,
+ page_size, page_num, page_addr);
+ } else {
+ err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl, page_size,
+ page_size, GFP_KERNEL, page_addr);
+ }
if (err) {
flag = 0;
break;
@@ -908,15 +1017,12 @@ static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
page_addr++;
}
+ hwdev->mqm_att.page_num = valid_num;
+
if (flag == 1) {
hwdev->mqm_att.page_size = page_size;
- hwdev->mqm_att.page_num = page_num;
} else {
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
- for (i = 0; i < valid_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
+ mqm_eqm_free_page_mem(hwdev);
return -EFAULT;
}
@@ -955,19 +1061,6 @@ static int mqm_eqm_alloc_page_mem(struct hinic3_hwdev *hwdev)
return ret;
}
-static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
-{
- u32 i;
- struct hinic3_dma_addr_align *page_addr;
-
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
-
- for (i = 0; i < hwdev->mqm_att.page_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
-}
-
static int mqm_eqm_set_cfg_2_hw(struct hinic3_hwdev *hwdev, u8 valid)
{
struct comm_cmd_eqm_cfg info_eqm_cfg;
@@ -1098,6 +1191,7 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
{
struct comm_cmd_get_eqm_num info_eqm_fix;
int ret;
+ int is_in_kexec;
if (hwdev->hwif->attr.func_type != TYPE_PPF)
return 0;
@@ -1127,10 +1221,15 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
goto err_page;
}
- ret = mqm_eqm_set_page_2_hw(hwdev);
- if (ret) {
- sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
- goto err_ecmd;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ ret = mqm_eqm_set_page_2_hw(hwdev);
+ if (ret) {
+ sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
+ goto err_ecmd;
+ }
+ } else {
+ sdk_info(hwdev->dev_hdl, "Mqm db don't set to chip when os hot replace.\r\n");
}
ret = mqm_eqm_set_cfg_2_hw(hwdev, 1);
@@ -1568,3 +1667,15 @@ int hinic3_switch_config(void *hwdev, u8 cfg_index)
return 0;
}
+
+bool hinic3_is_optical_module_mode(void *hwdev)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (dev->board_info.board_type == BOARD_TYPE_STRG_4X25G_COMSTORAGE ||
+ dev->board_info.board_type == BOARD_TYPE_CAL_4X25G_COMSTORAGE ||
+ dev->board_info.board_type == BOARD_TYPE_CAL_2X100G_TCE_BACKPLANE)
+ return false;
+
+ return true;
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
index baa1ce0..722fecd 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
@@ -252,98 +252,6 @@ static u32 get_up_timeout_val(enum hinic3_mod_type mod, u16 cmd)
return 0; /* use default mbox/apichain timeout time */
}
-static int api_csr_read(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
-{
- struct up_log_msg_st *up_log_msg = (struct up_log_msg_st *)buf_in;
- u8 *buf_out_tmp = (u8 *)buf_out;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
-
- if (!buf_in || !buf_out || in_size != sizeof(*up_log_msg) ||
- *out_size != up_log_msg->rd_len || up_log_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = up_log_msg->rd_len;
- rd_addr = up_log_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_rd32(hwdev, node_id,
- rd_addr + offset,
- (u32 *)(buf_out_tmp + offset));
- if (ret) {
- pr_err("Csr rd fail, err: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, node_id, rd_addr + offset);
- return ret;
- }
- offset += DW_WIDTH;
- }
- *out_size = rd_len;
-
- return ret;
-}
-
-static int api_csr_write(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out,
- u32 *out_size)
-{
- struct csr_write_st *csr_write_msg = (struct csr_write_st *)buf_in;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
- u8 *data = NULL;
-
- if (!buf_in || in_size != sizeof(*csr_write_msg) || csr_write_msg->rd_len == 0 ||
- csr_write_msg->rd_len > API_CSR_MAX_RD_LEN || csr_write_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = csr_write_msg->rd_len;
- rd_addr = csr_write_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- data = kzalloc(rd_len, GFP_KERNEL);
- if (!data) {
- pr_err("No more memory\n");
- return -EFAULT;
- }
- if (copy_from_user(data, (void *)csr_write_msg->data, rd_len)) {
- pr_err("Copy information from user failed\n");
- kfree(data);
- return -EFAULT;
- }
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_wr32(hwdev, node_id,
- rd_addr + offset,
- *((u32 *)(data + offset)));
- if (ret) {
- pr_err("Csr wr fail, ret: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, rd_addr + offset, node_id);
- kfree(data);
- return ret;
- }
- offset += DW_WIDTH;
- }
-
- *out_size = 0;
- kfree(data);
- return ret;
-}
-
int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
@@ -370,10 +278,8 @@ int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
return ret;
}
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_BYPASS) {
- if (nt_msg->mpu_cmd.cmd == API_CSR_WRITE)
- return api_csr_write(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
-
- ret = api_csr_read(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
+ pr_err("Unsupported api_type %u\n", nt_msg->mpu_cmd.api_type);
+ return -EINVAL;
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_TO_MPU) {
timeout = get_up_timeout_val(mod, cmd);
if (hinic3_pcie_itf_id(hwdev) != SPU_HOST_ID)
@@ -440,6 +346,23 @@ static int sm_rd16(void *hwdev, u32 id, u8 instance,
return ret;
}
+static int sm_rd16_clear(void *hwdev, u32 id, u8 instance,
+ u8 node, struct sm_out_st *buf_out)
+{
+ u16 val1;
+ int ret;
+
+ ret = hinic3_sm_ctr_rd16_clear(hwdev, node, instance, id, &val1);
+ if (ret != 0) {
+ pr_err("Get sm ctr clear information (16 bits)failed!\n");
+ val1 = 0xffff;
+ }
+
+ buf_out->val1 = val1;
+
+ return ret;
+}
+
static int sm_rd32(void *hwdev, u32 id, u8 instance,
u8 node, struct sm_out_st *buf_out)
{
@@ -559,6 +482,7 @@ const struct sm_module_handle sm_module_cmd_handle[] = {
{SM_CTR_RD32, sm_rd32},
{SM_CTR_RD64_PAIR, sm_rd64_pair},
{SM_CTR_RD64, sm_rd64},
+ {SM_CTR_RD16_CLEAR, sm_rd16_clear},
{SM_CTR_RD32_CLEAR, sm_rd32_clear},
{SM_CTR_RD64_PAIR_CLEAR, sm_rd64_pair_clear},
{SM_CTR_RD64_CLEAR, sm_rd64_clear}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
index 620136a..ac80b63 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
@@ -101,6 +101,12 @@ enum hinic3_pcie_tph {
#define SLAVE_HOST_STATUS_SET(host_id, enable) (((u8)(enable) & 1U) << (host_id))
#define SLAVE_HOST_STATUS_GET(host_id, val) (!!((val) & (1U << (host_id))))
+#ifdef HAVE_HOT_REPLACE_FUNC
+ extern int get_partition_id(void);
+#else
+ static int get_partition_id(void) { return 0; }
+#endif
+
void set_slave_host_enable(void *hwdev, u8 host_id, bool enable)
{
u32 reg_val;
@@ -207,6 +213,28 @@ static void hinic3_init_host_mode_pre(struct hinic3_hwdev *hwdev)
}
}
+static void hinic3_init_hot_plug_status(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->hot_plug_disable) {
+ hwdev->hot_plug_mode = HOT_PLUG_DISABLE;
+ } else {
+ hwdev->hot_plug_mode = HOT_PLUG_ENABLE;
+ }
+}
+
+static void hinic3_init_os_hot_replace(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->os_hot_replace) {
+ hwdev->hot_replace_mode = HOT_REPLACE_ENABLE;
+ } else {
+ hwdev->hot_replace_mode = HOT_REPLACE_DISABLE;
+ }
+}
+
static u8 hinic3_nic_sw_aeqe_handler(void *hwdev, u8 event, u8 *data)
{
struct hinic3_hwdev *dev = hwdev;
@@ -270,14 +298,20 @@ static void chip_fault_show(struct hinic3_hwdev *hwdev,
"fatal", "reset", "host", "flr", "general", "suggestion"};
char level_str[FAULT_SHOW_STR_LEN + 1];
u8 level;
+ int ret;
memset(level_str, 0, FAULT_SHOW_STR_LEN + 1);
level = event->event.chip.err_level;
- if (level < FAULT_LEVEL_MAX)
- strncpy(level_str, fault_level[level],
- FAULT_SHOW_STR_LEN);
- else
- strncpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (level < FAULT_LEVEL_MAX) {
+ ret = strscpy(level_str, fault_level[level],
+ FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ } else {
+ ret = strscpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ }
if (level == FAULT_LEVEL_SERIOUS_FLR)
dev_err(hwdev->dev_hdl, "err_level: %u [%s], flr func_id: %u\n",
@@ -299,6 +333,7 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
"reg rd timeout", "reg wr timeout", "phy fault", "tsensor fault"};
char type_str[FAULT_SHOW_STR_LEN + 1] = {0};
struct fault_event_stats *fault = NULL;
+ int ret;
sdk_err(hwdev->dev_hdl, "Fault event report received, func_id: %u\n",
hinic3_global_func_id(hwdev));
@@ -306,10 +341,14 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
fault = &hwdev->hw_stats.fault_event_stats;
if (event->type < FAULT_TYPE_MAX) {
- strncpy(type_str, fault_type[event->type], sizeof(type_str));
+ ret = strscpy(type_str, fault_type[event->type], sizeof(type_str));
+ if (ret < 0)
+ return;
atomic_inc(&fault->fault_type_stat[event->type]);
} else {
- strncpy(type_str, "Unknown", sizeof(type_str));
+ ret = strscpy(type_str, "Unknown", sizeof(type_str));
+ if (ret < 0)
+ return;
}
sdk_err(hwdev->dev_hdl, "Fault type: %u [%s]\n", event->type, type_str);
@@ -1536,15 +1575,30 @@ int hinic3_init_hwdev(struct hinic3_init_para *para)
hinic3_init_host_mode_pre(hwdev);
+ hinic3_init_hot_plug_status(hwdev);
+
+ hinic3_init_os_hot_replace(hwdev);
+
err = hinic3_multi_host_mgmt_init(hwdev);
if (err != 0) {
sdk_err(hwdev->dev_hdl, "Failed to init function mode\n");
goto init_multi_host_fail;
}
- err = hinic3_init_ppf_work(hwdev);
- if (err != 0)
- goto init_ppf_work_fail;
+ // hot_replace_mode is enable, run ppf function only when partition_id is 0
+ // or run ppf function directly
+ if (hwdev->hot_replace_mode == HOT_REPLACE_ENABLE) {
+ if (get_partition_id() == 0) {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0) {
+ goto init_ppf_work_fail;
+ }
+ }
+ } else {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0)
+ goto init_ppf_work_fail;
+ }
err = hinic3_set_comm_features(hwdev, hwdev->features, COMM_MAX_FEATURE_QWORD);
if (err != 0) {
@@ -1948,6 +2002,19 @@ void hinic3_link_event_stats(void *dev, u8 link)
}
EXPORT_SYMBOL(hinic3_link_event_stats);
+int hinic3_get_link_event_stats(void *dev, int *link_state)
+{
+ struct hinic3_hwdev *hwdev = dev;
+
+ if (!hwdev || !link_state)
+ return -EINVAL;
+
+ *link_state = hwdev->hw_stats.link_event_stats.link_down_stats.counter;
+
+ return 0;
+}
+EXPORT_SYMBOL(hinic3_get_link_event_stats);
+
u8 hinic3_max_pf_num(void *hwdev)
{
if (!hwdev)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
index e739767..7c2cfc2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
@@ -10,6 +10,7 @@
#include "hinic3_hw.h"
#include "mpu_inband_cmd_defs.h"
#include "hinic3_profile.h"
+#include "vram_common.h"
struct cfg_mgmt_info;
@@ -82,6 +83,22 @@ enum hinic3_host_mode_e {
HINIC3_SDI_MODE_MAX,
};
+enum hinic3_hot_plug_mode {
+ HOT_PLUG_ENABLE,
+ HOT_PLUG_DISABLE,
+};
+
+enum hinic3_os_hot_replace_mode {
+ HOT_REPLACE_DISABLE,
+ HOT_REPLACE_ENABLE,
+};
+
+#define UNSUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_DISABLE)
+
+#define SUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_ENABLE)
+
#define MULTI_HOST_CHIP_MODE_SHIFT 0
#define MULTI_HOST_MASTER_MBX_STS_SHIFT 17
#define MULTI_HOST_PRIV_DATA_SHIFT 0x8
@@ -100,6 +117,10 @@ enum hinic3_host_mode_e {
((val) & (~(MULTI_HOST_##member##_MASK \
<< MULTI_HOST_##member##_SHIFT)))
+struct mqm_eqm_vram_name_s {
+ char vram_name[VRAM_NAME_MAX_LEN];
+};
+
struct hinic3_hwdev {
void *adapter_hdl; /* pointer to hinic3_pcidev or NDIS_Adapter */
void *pcidev_hdl; /* pointer to pcidev or Handler */
@@ -138,6 +159,9 @@ struct hinic3_hwdev {
u32 rsvd2;
struct hinic3_multi_host_mgmt *mhost_mgmt;
+ char mhost_mgmt_name[VRAM_NAME_MAX_LEN];
+
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name;
struct mutex stateful_mutex; /* protect cqm init and deinit */
@@ -170,7 +194,10 @@ struct hinic3_hwdev {
struct hinic3_devlink *devlink_dev;
enum hinic3_func_mode func_mode;
- u32 rsvd3;
+ enum hinic3_hot_plug_mode hot_plug_mode;
+
+ enum hinic3_os_hot_replace_mode hot_replace_mode;
+ u32 rsvd5;
DECLARE_BITMAP(func_probe_in_host, MAX_FUNCTION_NUM);
DECLARE_BITMAP(netdev_setup_state, MAX_FUNCTION_NUM);
@@ -179,7 +206,10 @@ struct hinic3_hwdev {
u64 last_recv_aeq_cnt;
u16 aeq_busy_cnt;
- u64 rsvd4[8];
+ u64 mbox_send_cnt;
+ u64 mbox_ack_cnt;
+
+ u64 rsvd4[5];
};
#define HINIC3_DRV_FEATURE_QW0 \
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
index 33f1210..8590f70 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
@@ -544,6 +544,7 @@ static void free_db_area(struct hinic3_free_db_area *free_db_area)
{
spin_lock_deinit(&free_db_area->idx_lock);
kfree(free_db_area->db_bitmap_array);
+ free_db_area->db_bitmap_array = NULL;
}
static int get_db_idx(struct hinic3_hwif *hwif, u32 *idx)
@@ -841,6 +842,7 @@ void hinic3_free_hwif(struct hinic3_hwdev *hwdev)
free_db_area(&hwdev->hwif->free_db_area);
enable_all_msix(hwdev);
kfree(hwdev->hwif);
+ hwdev->hwif = NULL;
}
u16 hinic3_global_func_id(void *hwdev)
@@ -856,6 +858,44 @@ u16 hinic3_global_func_id(void *hwdev)
}
EXPORT_SYMBOL(hinic3_global_func_id);
+/**
+ * get function id from register,used by sriov hot migration process
+ * @hwdev: the pointer to hw device
+ */
+u16 hinic3_global_func_id_hw(void *hwdev)
+{
+ u32 addr, attr0;
+ struct hinic3_hwdev *dev;
+
+ dev = (struct hinic3_hwdev *)hwdev;
+ addr = HINIC3_CSR_FUNC_ATTR0_ADDR;
+ attr0 = hinic3_hwif_read_reg(dev->hwif, addr);
+
+ return HINIC3_AF0_GET(attr0, FUNC_GLOBAL_IDX);
+}
+
+/**
+ * get function id, used by sriov hot migratition process.
+ * @hwdev: the pointer to hw device
+ * @func_id: function id
+ */
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id)
+{
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)hwdev;
+
+ if (!hwdev || !func_id)
+ return -EINVAL;
+
+ /* only vf get func_id from chip reg for sriov migrate */
+ if (!HINIC3_IS_VF(dev)) {
+ *func_id = hinic3_global_func_id(hwdev);
+ return 0;
+ }
+
+ *func_id = hinic3_global_func_id_hw(dev);
+ return 0;
+}
+
u16 hinic3_intr_num(void *hwdev)
{
struct hinic3_hwif *hwif = NULL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
index 321a3b7..4e2e8b0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
@@ -16,6 +16,7 @@
#include <linux/rtc.h>
#include <linux/aer.h>
#include <linux/debugfs.h>
+#include <linux/notifier.h>
#include "ossl_knl.h"
#include "hinic3_mt.h"
@@ -29,26 +30,41 @@
#include "hinic3_lld.h"
#include "hinic3_profile.h"
+#include "hinic3_hw_cfg.h"
+#include "hinic3_multi_host_mgmt.h"
#include "hinic3_hwdev.h"
#include "hinic3_prof_adap.h"
-#include "comm_msg_intf.h"
+#include "hinic3_devlink.h"
-static bool disable_vf_load;
+#include "vram_common.h"
+
+enum partition_dev_type {
+ PARTITION_DEV_NONE = 0,
+ PARTITION_DEV_SHARED,
+ PARTITION_DEV_EXCLUSIVE,
+ PARTITION_DEV_BACKUP,
+};
+
+#ifdef HAVE_HOT_REPLACE_FUNC
+extern int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type, unsigned int partition_id);
+extern int get_partition_id(void);
+#else
+static int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type, unsigned int partition_id) { return 0; }
+static int get_partition_id(void) { return 0; }
+#endif
+
+static bool disable_vf_load = false;
module_param(disable_vf_load, bool, 0444);
MODULE_PARM_DESC(disable_vf_load,
"Disable virtual functions probe or not - default is false");
+static bool g_is_pf_migrated = false;
static bool disable_attach;
module_param(disable_attach, bool, 0444);
MODULE_PARM_DESC(disable_attach, "disable_attach or not - default is false");
#define HINIC3_WAIT_SRIOV_CFG_TIMEOUT 15000
-MODULE_AUTHOR("Huawei Technologies CO., Ltd");
-MODULE_DESCRIPTION(HINIC3_DRV_DESC);
-MODULE_VERSION(HINIC3_DRV_VERSION);
-MODULE_LICENSE("GPL");
-
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
static DEVICE_ATTR(sriov_numvfs, 0664,
hinic3_sriov_numvfs_show, hinic3_sriov_numvfs_store);
@@ -71,7 +87,18 @@ static const struct attribute_group hinic3_attr_group = {
struct hinic3_uld_info g_uld_info[SERVICE_T_MAX] = { {0} };
#define HINIC3_EVENT_PROCESS_TIMEOUT 10000
+#define HINIC3_WAIT_EVENT_PROCESS_TIMEOUT 100
struct mutex g_uld_mutex;
+#define BUS_MAX_DEV_NUM 256
+#define HINIC3_SLAVE_WORK_MAX_NUM 20
+
+typedef struct vf_offset_info {
+ u8 valid;
+ u16 vf_offset_from_pf[CMD_MAX_MAX_PF_NUM];
+} VF_OFFSET_INFO_S;
+
+static VF_OFFSET_INFO_S g_vf_offset;
+DEFINE_MUTEX(g_vf_offset_lock);
void hinic3_uld_lock_init(void)
{
@@ -80,13 +107,23 @@ void hinic3_uld_lock_init(void)
static const char *s_uld_name[SERVICE_T_MAX] = {
"nic", "ovs", "roce", "toe", "ioe",
- "fc", "vbs", "ipsec", "virtio", "migrate", "ppa", "custom"};
+ "fc", "vbs", "ipsec", "virtio", "migrate",
+ "ppa", "custom", "vroce", "crypt", "vsock", "bifur"};
const char **hinic3_get_uld_names(void)
{
return s_uld_name;
}
+#ifdef CONFIG_PCI_IOV
+static int hinic3_get_pf_device_id(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_dev = pci_physfn(pdev);
+
+ return pf_dev->device;
+}
+#endif
+
static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
const struct hinic3_uld_info *uld_info)
{
@@ -105,6 +142,10 @@ static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
atomic_set(&dev->uld_ref_cnt[type], 0);
+ if (!uld_info->probe) {
+ err = 0;
+ goto out_unlock;
+ }
err = uld_info->probe(&dev->lld_dev, &uld_dev, dev->uld_dev_name[type]);
if (err) {
sdk_err(&dev->pcidev->dev,
@@ -173,6 +214,10 @@ static void detach_uld(struct hinic3_pcidev *dev,
wait_uld_unused(dev, type);
+ if (!uld_info->remove) {
+ mutex_unlock(&dev->pdev_mutex);
+ return;
+ }
uld_info->remove(&dev->lld_dev, dev->uld_dev[type]);
dev->uld_dev[type] = NULL;
@@ -190,10 +235,15 @@ static void attach_ulds(struct hinic3_pcidev *dev)
enum hinic3_service_type type;
struct pci_dev *pdev = dev->pcidev;
- lld_hold();
+ int is_in_kexec = vram_get_kexec_flag();
+ /* don't need hold when driver parallel load during spu hot replace */
+ if (is_in_kexec == 0) {
+ lld_hold();
+ }
+
mutex_lock(&g_uld_mutex);
- for (type = SERVICE_T_NIC; type < SERVICE_T_MAX; type++) {
+ for (type = SERVICE_T_OVS; type < SERVICE_T_MAX; type++) {
if (g_uld_info[type].probe) {
if (pdev->is_virtfn &&
(!hinic3_get_vf_service_load(pdev, (u16)type))) {
@@ -205,7 +255,10 @@ static void attach_ulds(struct hinic3_pcidev *dev)
}
}
mutex_unlock(&g_uld_mutex);
- lld_put();
+
+ if (is_in_kexec == 0) {
+ lld_put();
+ }
}
static void detach_ulds(struct hinic3_pcidev *dev)
@@ -255,10 +308,10 @@ int hinic3_register_uld(enum hinic3_service_type type,
}
chip_list = get_hinic3_chip_list();
- memcpy(&g_uld_info[type], uld_info, sizeof(*uld_info));
+ memcpy(&g_uld_info[type], uld_info, sizeof(struct hinic3_uld_info));
list_for_each_entry(chip_node, chip_list, node) {
list_for_each_entry(dev, &chip_node->func_list, node) {
- if (attach_uld(dev, type, uld_info)) {
+ if (attach_uld(dev, type, uld_info) != 0) {
sdk_err(&dev->pcidev->dev,
"Attach %s driver to pcie device failed\n",
s_uld_name[type]);
@@ -312,7 +365,7 @@ void hinic3_unregister_uld(enum hinic3_service_type type)
}
uld_info = &g_uld_info[type];
- memset(uld_info, 0, sizeof(*uld_info));
+ memset(uld_info, 0, sizeof(struct hinic3_uld_info));
mutex_unlock(&g_uld_mutex);
lld_put();
}
@@ -366,6 +419,26 @@ void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_ser
}
EXPORT_SYMBOL(hinic3_detach_service);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ __module_get(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_get);
+
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ module_put(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_put);
+
static void hinic3_sync_time_to_fmw(struct hinic3_pcidev *pdev_pri)
{
struct timeval tv = {0};
@@ -382,7 +455,8 @@ static void hinic3_sync_time_to_fmw(struct hinic3_pcidev *pdev_pri)
err);
} else {
rtc_time_to_tm((unsigned long)(tv.tv_sec), &rt_time);
- sdk_info(&pdev_pri->pcidev->dev, "Synchronize UTC time to firmware succeed. UTC time %d-%02d-%02d %02d:%02d:%02d.\n",
+ sdk_info(&pdev_pri->pcidev->dev,
+ "Synchronize UTC time to firmware succeed. UTC time %d-%02d-%02d %02d:%02d:%02d.\n",
rt_time.tm_year + HINIC3_SYNC_YEAR_OFFSET,
rt_time.tm_mon + HINIC3_SYNC_MONTH_OFFSET,
rt_time.tm_mday, rt_time.tm_hour,
@@ -448,23 +522,434 @@ static void send_event_to_all_pf(struct hinic3_pcidev *dev,
lld_put();
}
+u32 hinic3_pdev_is_virtfn(struct pci_dev *pdev)
+{
+#ifdef CONFIG_PCI_IOV
+ return pdev->is_virtfn;
+#else
+ return 0;
+#endif
+}
+
+static int hinic3_get_function_enable(struct pci_dev *pdev, bool *en)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+ int err;
+
+ /* PF in host os or function in guest os, probe sdk in default */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev) {
+ *en = true;
+ return 0;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev) {
+ /* vf in host and pf sdk not probed */
+ return -EFAULT;
+ }
+ pf_hwdev = pci_adapter->hwdev;
+
+ err = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (err) {
+ sdk_err(&pci_adapter->pcidev->dev, "Func hinic3_get_vfid_by_vfpci fail %d \n", err);
+ return err;
+ }
+
+ err = hinic3_get_func_nic_enable(pf_hwdev, global_func_id, en);
+ if (!!err) {
+ sdk_info(&pdev->dev, "Failed to get function nic status, err %d.\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+int hinic3_set_func_probe_in_host(void *hwdev, u16 func_id, bool probe)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (hinic3_func_type(hwdev) != TYPE_PPF)
+ return -EINVAL;
+
+ if (probe)
+ set_bit(func_id, dev->func_probe_in_host);
+ else
+ clear_bit(func_id, dev->func_probe_in_host);
+
+ return 0;
+}
+
+bool hinic3_get_func_probe_in_host(void *hwdev, u16 func_id)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+ bool probed = false;
+
+ if (!hwdev)
+ return false;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return false;
+ }
+
+ probed = !!test_bit(func_id, ppf_dev->func_probe_in_host);
+ up(&dev->ppf_sem);
+
+ return probed;
+}
+
+void *hinic3_get_ppf_hwdev_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ chip_node = pci_adapter->chip_node;
+ lld_dev_hold(&pci_adapter->lld_dev);
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (dev->lld_state == HINIC3_IN_REMOVE)
+ continue;
+
+ if (dev->hwdev && hinic3_func_type(dev->hwdev) == TYPE_PPF) {
+ lld_dev_put(&pci_adapter->lld_dev);
+ return dev->hwdev;
+ }
+ }
+ lld_dev_put(&pci_adapter->lld_dev);
+
+ return NULL;
+}
+
+static int hinic3_set_vf_nic_used_state(void *hwdev, u16 func_id, bool opened)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+
+ if (!dev || func_id >= MAX_FUNCTION_NUM)
+ return -EINVAL;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return -EINVAL;
+ }
+
+ if (opened)
+ set_bit(func_id, ppf_dev->netdev_setup_state);
+ else
+ clear_bit(func_id, ppf_dev->netdev_setup_state);
+
+ up(&dev->ppf_sem);
+
+ return 0;
+}
+
+static void set_vf_func_in_use(struct pci_dev *pdev, bool in_use)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+
+ /* only need to be set when VF is on the host */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev)
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev)
+ return;
+
+ pf_hwdev = pci_adapter->hwdev;
+
+ global_func_id = (u16)pdev->devfn + hinic3_glb_pf_vf_offset(pf_hwdev);
+ (void)hinic3_set_vf_nic_used_state(pf_hwdev, global_func_id, in_use);
+}
+
+static int hinic3_pf_get_vf_offset_info(struct hinic3_pcidev *des_dev, u16 *vf_offset)
+{
+ int err, i;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ u16 pf_func_id;
+ struct hinic3_pcidev *pf_pci_adapter = NULL;
+
+ pf_pci_adapter = (hinic3_pdev_is_virtfn(des_dev->pcidev)) ? pci_get_drvdata(des_dev->pcidev->physfn) : des_dev;
+ pf_func_id = hinic3_global_func_id(pf_pci_adapter->hwdev);
+ if (pf_func_id >= CMD_MAX_MAX_PF_NUM || !vf_offset)
+ return -EINVAL;
+
+ mutex_lock(&g_vf_offset_lock);
+ if (g_vf_offset.valid == 0) {
+ pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ sdk_err(&pf_pci_adapter->pcidev->dev, "Malloc pf_infos fail\n");
+ err = -ENOMEM;
+ goto err_malloc;
+ }
+
+ err = hinic3_get_hw_pf_infos(pf_pci_adapter->hwdev, pf_infos, HINIC3_CHANNEL_COMM);
+ if (err) {
+ sdk_warn(&pf_pci_adapter->pcidev->dev, "Hinic3_get_hw_pf_infos fail err %d\n", err);
+ err = -EFAULT;
+ goto err_out;
+ }
+
+ g_vf_offset.valid = 1;
+ for (i = 0; i < CMD_MAX_MAX_PF_NUM; i++) {
+ g_vf_offset.vf_offset_from_pf[i] = pf_infos->infos[i].vf_offset;
+ }
+
+ kfree(pf_infos);
+ }
+
+ *vf_offset = g_vf_offset.vf_offset_from_pf[pf_func_id];
+
+ mutex_unlock(&g_vf_offset_lock);
+
+ return 0;
+
+err_out:
+ kfree(pf_infos);
+err_malloc:
+ mutex_unlock(&g_vf_offset_lock);
+ return err;
+}
+
+static struct pci_dev *get_vf_pdev_by_pf(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ int err;
+ u16 bus_num;
+ u16 vf_start, vf_end;
+ u16 des_fn, pf_func_id, vf_offset;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ pf_func_id = hinic3_global_func_id(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end || pf_func_id >= CMD_MAX_MAX_PF_NUM)
+ return NULL;
+
+ err = hinic3_pf_get_vf_offset_info(des_dev, &vf_offset);
+ if (err) {
+ sdk_warn(&des_dev->pcidev->dev, "Hinic3_pf_get_vf_offset_info fail\n");
+ return NULL;
+ }
+
+ des_fn = ((func_id - vf_start) - 1) + pf_func_id + vf_offset;
+ bus_num = des_dev->pcidev->bus->number + des_fn / BUS_MAX_DEV_NUM;
+
+ return pci_get_domain_bus_and_slot(0, bus_num, (des_fn % BUS_MAX_DEV_NUM));
+}
+
+static struct hinic3_pcidev *get_des_pci_adapter(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ struct pci_dev *des_pdev = NULL;
+ u16 vf_start, vf_end;
+ bool probe_in_host = false;
+
+ if (hinic3_global_func_id(des_dev->hwdev) == func_id)
+ return des_dev;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end)
+ return NULL;
+
+ des_pdev = get_vf_pdev_by_pf(des_dev, func_id);
+ if (!des_pdev)
+ return NULL;
+
+ pci_dev_put(des_pdev);
+
+ probe_in_host = hinic3_get_func_probe_in_host(des_dev->hwdev, func_id);
+ if (!probe_in_host)
+ return NULL;
+
+ return pci_get_drvdata(des_pdev);
+}
+
+int __set_vroce_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ u8 enable_vroce = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_vroce_enable(pci_adapter->hwdev, func_id, &enable_vroce);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Failed to get vroce state.\n");
+ return err;
+ }
+
+ mutex_lock(&g_uld_mutex);
+
+ if (!!enable_vroce) {
+ if (!g_uld_info[SERVICE_T_ROCE].probe) {
+ sdk_info(&pdev->dev, "Uld(roce_info) has not been registered!\n");
+ mutex_unlock(&g_uld_mutex);
+ return 0;
+ }
+
+ err = attach_uld(pci_adapter, SERVICE_T_ROCE, &g_uld_info[SERVICE_T_ROCE]);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Failed to initialize VROCE.\n");
+ mutex_unlock(&g_uld_mutex);
+ return err;
+ }
+ } else {
+ sdk_info(&pdev->dev, "Func %hu vroce state: disable.\n", func_id);
+ if (g_uld_info[SERVICE_T_ROCE].remove)
+ detach_uld(pci_adapter, SERVICE_T_ROCE);
+ }
+
+ mutex_unlock(&g_uld_mutex);
+
+ return 0;
+}
+
+void slave_host_mgmt_vroce_work(struct work_struct *work)
+{
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_vroce_work);
+
+ __set_vroce_func_state(pci_adapter);
+}
+
+void *hinic3_get_roce_uld_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ return pci_adapter->uld_dev[SERVICE_T_ROCE];
+}
+
+static int __func_service_state_process(struct hinic3_pcidev *event_dev,
+ struct hinic3_pcidev *des_dev,
+ struct hinic3_mhost_nic_func_state *state, u16 cmd)
+{
+ int err = 0;
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)event_dev->hwdev;
+
+ switch (cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ state->enable = hinic3_get_roce_uld_by_pdev(des_dev->pcidev) ? 1 : 0;
+ break;
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive nic[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ if (event_dev->multi_host_mgmt_workq) {
+ queue_work(event_dev->multi_host_mgmt_workq, &des_dev->slave_nic_work);
+ } else {
+ sdk_err(&des_dev->pcidev->dev, "Can not schedule slave nic work\n");
+ err = -EFAULT;
+ }
+ break;
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive vroce[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ queue_work_on(hisdk3_get_work_cpu_affinity(dev, WORK_TYPE_MBOX),
+ event_dev->multi_host_mgmt_workq,
+ &des_dev->slave_vroce_work);
+ break;
+ default:
+ sdk_warn(&des_dev->pcidev->dev, "Service state process with unknown cmd: %u\n", cmd);
+ err = -EFAULT;
+ break;
+ }
+
+ return err;
+}
+
+static void __multi_host_mgmt(struct hinic3_pcidev *dev,
+ struct hinic3_multi_host_mgmt_event *mhost_mgmt)
+{
+ struct hinic3_pcidev *cur_dev = NULL;
+ struct hinic3_pcidev *des_dev = NULL;
+ struct hinic3_mhost_nic_func_state *nic_state = NULL;
+ u16 sub_cmd = mhost_mgmt->sub_cmd;
+
+ switch (sub_cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ nic_state = mhost_mgmt->data;
+ nic_state->status = 0;
+ if (!dev->hwdev)
+ return;
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)dev->hwdev))
+ return;
+
+ /* find func_idx pci_adapter and disable or enable nic */
+ lld_dev_hold(&dev->lld_dev);
+ list_for_each_entry(cur_dev, &dev->chip_node->func_list, node) {
+ if (cur_dev->lld_state == HINIC3_IN_REMOVE || hinic3_pdev_is_virtfn(cur_dev->pcidev))
+ continue;
+
+ des_dev = get_des_pci_adapter(cur_dev, nic_state->func_idx);
+ if (!des_dev)
+ continue;
+
+ if (__func_service_state_process(dev, des_dev, nic_state, sub_cmd))
+ nic_state->status = 1;
+ break;
+ }
+ lld_dev_put(&dev->lld_dev);
+ break;
+ default:
+ sdk_warn(&dev->pcidev->dev, "Received unknown multi-host mgmt event: %u\n",
+ mhost_mgmt->sub_cmd);
+ break;
+ }
+}
+
static void hinic3_event_process(void *adapter, struct hinic3_event_info *event)
{
struct hinic3_pcidev *dev = adapter;
struct hinic3_fault_event *fault = (void *)event->event_data;
+ struct hinic3_multi_host_mgmt_event *mhost_event = (void *)event->event_data;
u16 func_id;
- if ((event->service == EVENT_SRV_COMM && event->type == EVENT_COMM_FAULT) &&
- fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
- fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
- func_id = fault->event.chip.func_id;
- return send_event_to_dst_pf(adapter, func_id, event);
- }
-
- if (event->type == EVENT_COMM_MGMT_WATCHDOG)
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MULTI_HOST_MGMT):
+ __multi_host_mgmt(dev, mhost_event);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_FAULT):
+ if (fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
+ fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
+ func_id = fault->event.chip.func_id;
+ return send_event_to_dst_pf(adapter, func_id, event);
+ }
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MGMT_WATCHDOG):
send_event_to_all_pf(adapter, event);
- else
+ break;
+ default:
send_uld_dev_event(adapter, event);
+ break;
+ }
}
static void uld_def_init(struct hinic3_pcidev *pci_adapter)
@@ -631,36 +1116,75 @@ static void hinic3_pci_deinit(struct pci_dev *pdev)
kfree(pci_adapter);
}
-#ifdef CONFIG_X86
-/**
- * cfg_order_reg - when cpu model is haswell or broadwell, should configure dma
- * order register to zero
- * @pci_adapter: pci_adapter
- **/
-/*lint -save -e40 */
-static void cfg_order_reg(struct hinic3_pcidev *pci_adapter)
+static void set_vf_load_state(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
{
- u8 cpu_model[] = {0x3c, 0x3f, 0x45, 0x46, 0x3d, 0x47, 0x4f, 0x56};
- struct cpuinfo_x86 *cpuinfo = NULL;
- u32 i;
-
- if (hinic3_func_type(pci_adapter->hwdev) == TYPE_VF)
- return;
+ /* In bm mode, slave host will load vfs in default */
+ if (IS_BMGW_SLAVE_HOST(((struct hinic3_hwdev *)pci_adapter->hwdev)) &&
+ hinic3_func_type(pci_adapter->hwdev) != TYPE_VF)
+ hinic3_set_vf_load_state(pdev, false);
- cpuinfo = &cpu_data(0);
- for (i = 0; i < sizeof(cpu_model); i++) {
- if (cpu_model[i] == cpuinfo->x86_model)
- hinic3_set_pcie_order_cfg(pci_adapter->hwdev);
+ if (!disable_attach) {
+ if ((hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) &&
+ hinic3_is_bm_slave_host(pci_adapter->hwdev)) {
+ if (hinic3_func_max_vf(pci_adapter->hwdev) == 0) {
+ sdk_warn(&pdev->dev, "The sriov enabling process is skipped, vfs_num: 0.\n");
+ return;
+ }
+ hinic3_pci_sriov_enable(pdev, hinic3_func_max_vf(pci_adapter->hwdev));
+ }
}
}
-/*lint -restore*/
-#endif
-
-static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+static void hinic3_init_ppf_hwdev(struct hinic3_hwdev *hwdev)
{
- struct hinic3_init_para init_para = {0};
- bool cqm_init_en = false;
+ if (!hwdev) {
+ pr_err("[%s:%d] null hwdev pointer\n", __FILE__, __LINE__);
+ return;
+ }
+
+ hwdev->ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(hwdev->pcidev_hdl);
+ return;
+}
+
+static int set_nic_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ bool enable_nic = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_nic_enable(pci_adapter->hwdev, func_id, &enable_nic);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Failed to get nic state.\n");
+ return err;
+ }
+
+ if (!enable_nic) {
+ sdk_info(&pdev->dev, "Func %hu nic state: disable.\n", func_id);
+ detach_uld(pci_adapter, SERVICE_T_NIC);
+ return 0;
+ }
+
+ if (IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ (void)hinic3_init_vf_dev_cap(pci_adapter->hwdev);
+
+ if (g_uld_info[SERVICE_T_NIC].probe) {
+ err = attach_uld(pci_adapter, SERVICE_T_NIC, &g_uld_info[SERVICE_T_NIC]);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Initialize NIC failed\n");
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_init_para init_para = {0};
+ bool cqm_init_en = false;
int err;
init_para.adapter_hdl = pci_adapter;
@@ -715,7 +1239,16 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
list_add_tail(&pci_adapter->node, &pci_adapter->chip_node->func_list);
lld_unlock_chip_node();
+ hinic3_init_ppf_hwdev((struct hinic3_hwdev *)pci_adapter->hwdev);
+
+ set_vf_load_state(pdev, pci_adapter);
+
if (!disable_attach) {
+ /* NIC is base driver, probe firstly */
+ err = set_nic_func_state(pci_adapter);
+ if (err)
+ goto set_nic_func_state_err;
+
attach_ulds(pci_adapter);
if (hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) {
@@ -726,10 +1259,6 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
goto create_sysfs_err;
}
}
-
-#ifdef CONFIG_X86
- cfg_order_reg(pci_adapter);
-#endif
}
return 0;
@@ -737,6 +1266,7 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
create_sysfs_err:
detach_ulds(pci_adapter);
+set_nic_func_state_err:
lld_lock_chip_node();
list_del(&pci_adapter->node);
lld_unlock_chip_node();
@@ -785,6 +1315,7 @@ static void hinic3_func_deinit(struct pci_dev *pdev)
hinic3_free_stateful(pci_adapter->hwdev);
hinic3_free_hwdev(pci_adapter->hwdev);
+ pci_adapter->hwdev = NULL;
}
static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
@@ -806,6 +1337,49 @@ static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
} while (time_before(jiffies, end));
}
+static bool hinic3_get_vf_nic_en_status(struct pci_dev *pdev)
+{
+ bool nic_en = false;
+ u16 global_func_id;
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev) {
+ pr_err("pdev is null.\n");
+ return false;
+ }
+
+ if (pdev->is_virtfn)
+ pf_pdev = pdev->physfn;
+ else
+ return false;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return false;
+ }
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ return false;
+
+ if (hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id)) {
+ sdk_err(&pdev->dev, "Get vf id by vfpci failed\n");
+ return false;
+ }
+
+ if (hinic3_get_mhost_func_nic_enable(pci_adapter->hwdev,
+ global_func_id, &nic_en)) {
+ sdk_err(&pdev->dev, "Get function nic status failed\n");
+ return false;
+ }
+
+ sdk_info(&pdev->dev, "Func %hu %s default probe in host\n",
+ global_func_id, (nic_en) ? "enable" : "disable");
+
+ return nic_en;
+}
+
bool hinic3_get_vf_load_state(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = NULL;
@@ -860,6 +1434,8 @@ int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state)
}
EXPORT_SYMBOL(hinic3_set_vf_load_state);
+
+
bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service)
{
struct hinic3_pcidev *pci_adapter = NULL;
@@ -923,6 +1499,33 @@ int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
}
EXPORT_SYMBOL(hinic3_set_vf_service_load);
+static bool hinic3_is_host_vmsec_enable(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct pci_dev *pf_pdev = NULL;
+
+ if (pdev->is_virtfn) {
+ pf_pdev = pdev->physfn;
+ } else {
+ pf_pdev = pdev;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ pr_err("Pci_adapter is null.\n");
+ return false;
+ }
+
+ /* pf/vf used in host */
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ (hinic3_func_type(pci_adapter->hwdev) == TYPE_PF) &&
+ IS_RDMA_TYPE((struct hinic3_hwdev *)pci_adapter->hwdev)) {
+ return true;
+ }
+
+ return false;
+}
+
static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
@@ -936,6 +1539,13 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
pci_adapter->lld_state = HINIC3_IN_REMOVE;
mutex_unlock(&pci_adapter->pdev_mutex);
+ if (!(pdev->is_virtfn) && (hinic3_is_host_vmsec_enable(pdev) == true) &&
+ (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF)) {
+ cancel_delayed_work_sync(&pci_adapter->migration_probe_dwork);
+ flush_workqueue(pci_adapter->migration_probe_workq);
+ destroy_workqueue(pci_adapter->migration_probe_workq);
+ }
+
hinic3_detect_hw_present(pci_adapter->hwdev);
hisdk3_remove_pre_process(pci_adapter->hwdev);
@@ -960,23 +1570,129 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
sdk_info(&pdev->dev, "Pcie device removed function\n");
+ set_vf_func_in_use(pdev, false);
+
+ return 0;
+}
+
+int hinic3_get_vfid_by_vfpci(void *hwdev, struct pci_dev *pdev, u16 *global_func_id)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ u16 pf_bus, vf_bus, vf_offset;
+ int err;
+
+ if (!pdev || !global_func_id || !hinic3_pdev_is_virtfn(pdev))
+ return -EINVAL;
+ (void)hwdev;
+ pf_pdev = pdev->physfn;
+
+ vf_bus = pdev->bus->number;
+ pf_bus = pf_pdev->bus->number;
+
+ if (pdev->vendor == HINIC3_VIRTIO_VNEDER_ID) {
+ return -EPERM;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return -EINVAL;
+ }
+
+ err = hinic3_pf_get_vf_offset_info(pci_adapter, &vf_offset);
+ if (err) {
+ sdk_err(&pdev->dev, "Func hinic3_pf_get_vf_offset_info fail\n");
+ return -EFAULT;
+ }
+
+ *global_func_id = (u16)((vf_bus - pf_bus) * BUS_MAX_DEV_NUM) + (u16)pdev->devfn +
+ (u16)(CMD_MAX_MAX_PF_NUM - g_vf_offset.vf_offset_from_pf[0]);
+
return 0;
}
+EXPORT_SYMBOL(hinic3_get_vfid_by_vfpci);
+
+static void hinic3_set_vf_status_in_host(struct pci_dev *pdev, bool status)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ void *ppf_hwdev = NULL;
+ u16 global_func_id;
+ int ret;
+
+ if (!pf_pdev)
+ return;
+
+ if (!hinic3_pdev_is_virtfn(pdev))
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ pf_hwdev = pci_adapter->hwdev;
+ ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(pf_pdev);
+ if (!pf_hwdev || !ppf_hwdev)
+ return;
+
+ ret = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (ret) {
+ sdk_err(&pci_adapter->pcidev->dev, "Func hinic3_get_vfid_by_vfpci fail %d \n", ret);
+ return;
+ }
+
+ ret = hinic3_set_func_probe_in_host(ppf_hwdev, global_func_id, status);
+ if (ret)
+ sdk_err(&pci_adapter->pcidev->dev, "Set the function probe status in host failed\n");
+}
+#ifdef CONFIG_PCI_IOV
+static bool check_pdev_type_and_state(struct pci_dev *pdev)
+{
+ if (!(pdev->is_virtfn)) {
+ return false;
+ }
+
+ if ((hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_1_PF) &&
+ (hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_0_PF)) {
+ return false;
+ }
+
+ if (!hinic3_get_vf_load_state(pdev)) {
+ return false;
+ }
+
+ return true;
+}
+#endif
static void hinic3_remove(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
+ sdk_info(&pdev->dev, "Pcie device remove begin\n");
+
if (!pci_adapter)
- return;
+ goto out;
+#ifdef CONFIG_PCI_IOV
+ if (check_pdev_type_and_state(pdev)) {
+ goto out;
+ }
+#endif
- sdk_info(&pdev->dev, "Pcie device remove begin\n");
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
hinic3_remove_func(pci_adapter);
+ if (!pci_adapter->pcidev->is_virtfn &&
+ pci_adapter->multi_host_mgmt_workq)
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
+
hinic3_pci_deinit(pdev);
hinic3_probe_pre_unprocess(pdev);
+out:
+ hinic3_set_vf_status_in_host(pdev, false);
+
sdk_info(&pdev->dev, "Pcie device removed\n");
}
@@ -995,7 +1711,7 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
if (pci_adapter->lld_state >= HINIC3_PROBE_START) {
sdk_warn(&pdev->dev, "Don not probe repeat\n");
mutex_unlock(&pci_adapter->pdev_mutex);
- return 0;
+ return -EEXIST;
}
pci_adapter->lld_state = HINIC3_PROBE_START;
mutex_unlock(&pci_adapter->pdev_mutex);
@@ -1003,15 +1719,28 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
return 0;
}
+static void hinic3_probe_success_process(struct hinic3_pcidev *pci_adapter)
+{
+ hinic3_probe_success(pci_adapter->hwdev);
+
+ mutex_lock(&pci_adapter->pdev_mutex);
+ pci_adapter->lld_state = HINIC3_PROBE_OK;
+ mutex_unlock(&pci_adapter->pdev_mutex);
+}
+
static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
int err;
err = probe_func_param_init(pci_adapter);
- if (err)
+ if (err == -EEXIST)
+ return 0;
+ else if (err)
return err;
+ set_vf_func_in_use(pdev, true);
+
err = mapping_bar(pdev, pci_adapter);
if (err) {
sdk_err(&pdev->dev, "Failed to map bar\n");
@@ -1043,11 +1772,7 @@ static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
}
}
- hinic3_probe_success(pci_adapter->hwdev);
-
- mutex_lock(&pci_adapter->pdev_mutex);
- pci_adapter->lld_state = HINIC3_PROBE_OK;
- mutex_unlock(&pci_adapter->pdev_mutex);
+ hinic3_probe_success_process(pci_adapter);
return 0;
@@ -1063,18 +1788,299 @@ alloc_chip_node_fail:
unmapping_bar(pci_adapter);
map_bar_failed:
+ set_vf_func_in_use(pdev, false);
sdk_err(&pdev->dev, "Pcie device probe function failed\n");
return err;
}
+void hinic3_set_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int err;
+ bool enable_func = false;
+
+ err = hinic3_get_function_enable(pdev, &enable_func);
+ if (err) {
+ sdk_info(&pdev->dev, "Get function enable failed\n");
+ return;
+ }
+
+ sdk_info(&pdev->dev, "%s function resource start\n",
+ enable_func ? "Initialize" : "Free");
+ if (enable_func) {
+ err = hinic3_probe_func(pci_adapter);
+ if (err)
+ sdk_info(&pdev->dev, "Function probe failed\n");
+ } else {
+ hinic3_remove_func(pci_adapter);
+ }
+ if (err == 0)
+ sdk_info(&pdev->dev, "%s function resource end\n",
+ enable_func ? "Initialize" : "Free");
+}
+
+void slave_host_mgmt_work(struct work_struct *work)
+{
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_nic_work);
+
+ if (hinic3_pdev_is_virtfn(pci_adapter->pcidev))
+ hinic3_set_func_state(pci_adapter);
+ else
+ set_nic_func_state(pci_adapter);
+}
+
+static int pci_adapter_assign_val(struct hinic3_pcidev **ppci_adapter,
+ struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ *ppci_adapter = pci_get_drvdata(pdev);
+ (*ppci_adapter)->disable_vf_load = disable_vf_load;
+ (*ppci_adapter)->id = *id;
+ (*ppci_adapter)->lld_state = HINIC3_NOT_PROBE;
+ (*ppci_adapter)->probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ lld_dev_cnt_init(*ppci_adapter);
+
+ (*ppci_adapter)->multi_host_mgmt_workq =
+ alloc_workqueue("hinic_mhost_mgmt", WQ_UNBOUND,
+ HINIC3_SLAVE_WORK_MAX_NUM);
+ if (!(*ppci_adapter)->multi_host_mgmt_workq) {
+ hinic3_pci_deinit(pdev);
+ sdk_err(&pdev->dev, "Alloc multi host mgmt workqueue failed\n");
+ return -ENOMEM;
+ }
+
+ INIT_WORK(&(*ppci_adapter)->slave_nic_work, slave_host_mgmt_work);
+ INIT_WORK(&(*ppci_adapter)->slave_vroce_work,
+ slave_host_mgmt_vroce_work);
+
+ return 0;
+}
+
+static void slave_host_vfio_probe_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_pcidev *pci_adapter = container_of(delay, struct hinic3_pcidev, migration_probe_dwork);
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int (*dev_migration_probe)(struct pci_dev *);
+ int rc;
+
+ if (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) != TYPE_PF) {
+ return;
+ }
+
+ dev_migration_probe = __symbol_get("migration_dev_migration_probe");
+ if (!(dev_migration_probe)) {
+ sdk_err(&pdev->dev,
+ "Failed to find: migration_dev_migration_probe");
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork, WAIT_TIME * HZ);
+ } else {
+ rc = dev_migration_probe(pdev);
+ __symbol_put("migration_dev_migration_probe");
+ if (rc) {
+ sdk_err(&pdev->dev,
+ "Failed to __dev_migration_probe, rc:0x%x, pf migrated(%d).\n",
+ rc, g_is_pf_migrated);
+ } else {
+ g_is_pf_migrated = true;
+ sdk_info(&pdev->dev,
+ "Successed in __dev_migration_probe, pf migrated(%d).\n",
+ g_is_pf_migrated);
+ }
+ }
+
+ return;
+}
+
+struct vf_add_delaywork {
+ struct pci_dev *vf_pdev;
+ struct delayed_work migration_vf_add_dwork;
+};
+
+static void slave_host_migration_vf_add_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct vf_add_delaywork *vf_add = container_of(delay, struct vf_add_delaywork, migration_vf_add_dwork);
+ struct pci_dev *vf_pdev = vf_add->vf_pdev;
+ struct pci_dev *pf_pdev = NULL;
+ int (*migration_dev_add_vf)(struct pci_dev *);
+ int ret;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!vf_pdev) {
+ pr_err("vf pdev is null.\n");
+ goto err1;
+ }
+ if (!vf_pdev->is_virtfn) {
+ sdk_err(&vf_pdev->dev, "Pdev is not virtfn.\n");
+ goto err1;
+ }
+
+ pf_pdev = vf_pdev->physfn;
+ if (!pf_pdev) {
+ sdk_err(&vf_pdev->dev, "pf_pdev is null.\n");
+ goto err1;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&vf_pdev->dev, "Pci_adapter is null.\n");
+ goto err1;
+ }
+
+ if (!g_is_pf_migrated) {
+ sdk_info(&vf_pdev->dev, "pf is not migrated yet, so vf continues to try again.\n");
+ goto delay_work;
+ }
+
+ migration_dev_add_vf = __symbol_get("migration_dev_add_vf");
+ if (migration_dev_add_vf) {
+ ret = migration_dev_add_vf(vf_pdev);
+ __symbol_put("migration_dev_add_vf");
+ if (ret) {
+ sdk_err(&vf_pdev->dev,
+ "vf get migration symbol successed, but dev add vf failed, ret:%d.\n",
+ ret);
+ } else {
+ sdk_info(&vf_pdev->dev,
+ "vf get migration symbol successed, and dev add vf success.\n");
+ }
+ goto err1;
+ }
+ sdk_info(&vf_pdev->dev, "pf is migrated, but vf get migration symbol failed.\n");
+
+delay_work:
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork, WAIT_TIME * HZ);
+ return;
+
+err1:
+ kfree(vf_add);
+ return;
+}
+
+static void hinic3_probe_vf_add_dwork(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!hinic3_is_host_vmsec_enable(pdev)) {
+ return;
+ }
+
+#if defined(CONFIG_SP_VID_DID)
+ if ((pdev->vendor == PCI_VENDOR_ID_SPNIC) && (pdev->device == HINIC3_DEV_SDI_5_1_ID_VF)) {
+#elif defined(CONFIG_NF_VID_DID)
+ if ((pdev->vendor == PCI_VENDOR_ID_NF) && (pdev->device == NFNIC_DEV_ID_VF)) {
+#else
+ if ((pdev->vendor == PCI_VENDOR_ID_HUAWEI) && (pdev->device == HINIC3_DEV_SDI_5_0_ID_VF)) {
+#endif
+ struct vf_add_delaywork *vf_add = kmalloc(sizeof(struct vf_add_delaywork), GFP_ATOMIC);
+ if (!vf_add) {
+ sdk_info(&pdev->dev, "vf_add is null.\n");
+ return;
+ }
+ vf_add->vf_pdev = pdev;
+
+ pf_pdev = pdev->physfn;
+
+ if (!pf_pdev) {
+ sdk_info(&pdev->dev, "Vf-pf_pdev is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_info(&pdev->dev, "Pci_adapter is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ INIT_DELAYED_WORK(&vf_add->migration_vf_add_dwork,
+ slave_host_migration_vf_add_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork,
+ WAIT_TIME * HZ);
+ }
+
+ return;
+}
+
+static int hinic3_probe_migration_dwork(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+{
+ if (!hinic3_is_host_vmsec_enable(pdev)) {
+ sdk_info(&pdev->dev, "Probe_migration : hinic3_is_host_vmsec_enable is (0).\n");
+ return 0;
+ }
+
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF) {
+ pci_adapter->migration_probe_workq =
+ create_singlethread_workqueue("hinic3_migration_probe_delay");
+ if (!pci_adapter->migration_probe_workq) {
+ sdk_err(&pdev->dev, "Failed to create work queue:%s\n",
+ "hinic3_migration_probe_delay");
+ return -EINVAL;
+ }
+
+ INIT_DELAYED_WORK(&pci_adapter->migration_probe_dwork,
+ slave_host_vfio_probe_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork, WAIT_TIME * HZ);
+ }
+
+ return 0;
+}
+
+static bool hinic3_os_hot_replace_allow(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_hwdev *hwdev = (struct hinic3_hwdev *)pci_adapter->hwdev;
+ // check service enable and dev is not VF
+ if (hinic3_func_type(hwdev) == TYPE_VF || hwdev->hot_replace_mode == HOT_REPLACE_DISABLE)
+ return false;
+
+ return true;
+}
+
+static bool hinic3_os_hot_replace_process(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_board_info *board_info;
+ u16 cur_pf_id = hinic3_global_func_id(pci_adapter->hwdev);
+ u8 cur_partion_id;
+ board_info = &((struct hinic3_hwdev *)(pci_adapter->hwdev))->board_info;
+ // probe to os
+ vpci_set_partition_attrs(pci_adapter->pcidev, PARTITION_DEV_EXCLUSIVE,
+ get_function_partition(cur_pf_id, board_info->port_num));
+
+ // check pf_id is in the right partition_id
+ cur_partion_id = get_partition_id();
+ if (get_function_partition(cur_pf_id, board_info->port_num) == cur_partion_id) {
+ return true;
+ }
+
+ pci_adapter->probe_fault_level = FAULT_LEVEL_SUGGESTION;
+ return false;
+}
+
static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct hinic3_pcidev *pci_adapter = NULL;
u16 probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ u32 device_id, function_id;
int err;
sdk_info(&pdev->dev, "Pcie device probe begin\n");
-
+#ifdef CONFIG_PCI_IOV
+ hinic3_set_vf_status_in_host(pdev, true);
+ if (check_pdev_type_and_state(pdev)) {
+ sdk_info(&pdev->dev, "VFs are not binded to hinic\n");
+ hinic3_probe_vf_add_dwork(pdev);
+ return -EINVAL;
+ }
+#endif
err = hinic3_probe_pre_process(pdev);
if (err != 0 && err != HINIC3_NOT_PROBE)
goto out;
@@ -1082,33 +2088,53 @@ static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (err == HINIC3_NOT_PROBE)
return 0;
- err = hinic3_pci_init(pdev);
- if (err)
+ if (hinic3_pci_init(pdev))
goto pci_init_err;
- pci_adapter = pci_get_drvdata(pdev);
- pci_adapter->disable_vf_load = disable_vf_load;
- pci_adapter->id = *id;
- pci_adapter->lld_state = HINIC3_NOT_PROBE;
- pci_adapter->probe_fault_level = probe_fault_level;
- lld_dev_cnt_init(pci_adapter);
+ if (pci_adapter_assign_val(&pci_adapter, pdev, id))
+ goto allco_queue_err;
- if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev))) {
+ if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev)) &&
+ (!hinic3_get_vf_nic_en_status(pdev))) {
sdk_info(&pdev->dev, "VF device disable load in host\n");
return 0;
}
- err = hinic3_probe_func(pci_adapter);
- if (err)
+ if (hinic3_probe_func(pci_adapter))
+ goto hinic3_probe_func_fail;
+
+ if (hinic3_os_hot_replace_allow(pci_adapter)) {
+ if (!hinic3_os_hot_replace_process(pci_adapter)) {
+ device_id = PCI_SLOT(pdev->devfn);
+ function_id = PCI_FUNC(pdev->devfn);
+ sdk_info(&pdev->dev,
+ "os hot replace: skip function %d:%d for partition %d",
+ device_id, function_id, get_partition_id());
+ goto os_hot_repalce_not_allow;
+ }
+ }
+
+ if (hinic3_probe_migration_dwork(pdev, pci_adapter))
goto hinic3_probe_func_fail;
sdk_info(&pdev->dev, "Pcie device probed\n");
return 0;
+os_hot_repalce_not_allow:
+ hinic3_func_deinit(pdev);
+ lld_lock_chip_node();
+ free_chip_node(pci_adapter);
+ lld_unlock_chip_node();
+ unmapping_bar(pci_adapter);
+ set_vf_func_in_use(pdev, false);
+
hinic3_probe_func_fail:
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
+allco_queue_err:
probe_fault_level = pci_adapter->probe_fault_level;
hinic3_pci_deinit(pdev);
-
pci_init_err:
hinic3_probe_pre_unprocess(pdev);
@@ -1131,6 +2157,10 @@ static int hinic3_get_pf_info(struct pci_dev *pdev, u16 service,
}
*pf_infos = kzalloc(sizeof(struct hinic3_hw_pf_infos), GFP_KERNEL);
+ if (*pf_infos == NULL) {
+ sdk_err(&pdev->dev, "pf_infos kzalloc failed\n");
+ return -EFAULT;
+ }
err = hinic3_get_hw_pf_infos(dev->hwdev, *pf_infos, HINIC3_CHANNEL_COMM);
if (err) {
kfree(*pf_infos);
@@ -1146,6 +2176,7 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
{
int err;
+ mutex_lock(&dst_dev->pdev_mutex);
/* unload invalid vf func id */
if (!en && vf_func_id != hinic3_global_func_id(dst_dev->hwdev) &&
!strcmp(des_pdev->driver->name, HINIC3_DRV_NAME)) {
@@ -1163,6 +2194,8 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
err = hinic3_probe_func(dst_dev);
if (err)
return -EFAULT;
+ } else {
+ mutex_unlock(&dst_dev->pdev_mutex);
}
return 0;
@@ -1187,7 +2220,6 @@ static int get_vf_service_state_param(struct pci_dev *pdev, struct hinic3_pcidev
return 0;
}
-#define BUS_MAX_DEV_NUM 256
static int hinic3_dst_pdev_valid(struct hinic3_pcidev *dst_dev, struct pci_dev **des_pdev_ptr,
u16 vf_devfn, bool en)
{
@@ -1245,7 +2277,7 @@ int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id, u16 servic
lld_hold();
list_for_each_entry(dst_dev, &dev->chip_node->func_list, node) {
- if (paramerter_is_unexpected(dst_dev, &func_id, &vf_start, &vf_end, vf_func_id))
+ if (paramerter_is_unexpected(dst_dev, &func_id, &vf_start, &vf_end, vf_func_id) != 0)
continue;
vf_devfn = pf_infos->infos[func_id].vf_offset + (vf_func_id - vf_start) +
@@ -1269,7 +2301,6 @@ int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id, u16 servic
if (en)
pci_dev_put(des_pdev);
- mutex_lock(&dst_dev->pdev_mutex);
find_dst_dev = true;
break;
}
@@ -1289,19 +2320,18 @@ free_pf_info:
}
EXPORT_SYMBOL(hinic3_set_vf_service_state);
-/*lint -save -e133 -e10*/
static const struct pci_device_id hinic3_pci_table[] = {
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SPU), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_STANDARD), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_1_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_SDI_5_1_ID_VF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_VF), 0},
{0, 0}
};
-/*lint -restore*/
-
MODULE_DEVICE_TABLE(pci, hinic3_pci_table);
/**
@@ -1333,14 +2363,27 @@ static pci_ers_result_t hinic3_io_error_detected(struct pci_dev *pdev,
return PCI_ERS_RESULT_CAN_RECOVER;
}
+static void hinic3_timer_disable(void *hwdev)
+{
+ if (!hwdev)
+ return;
+
+ if (hinic3_get_stateful_enable(hwdev) && hinic3_get_timer_enable(hwdev))
+ (void)hinic3_func_tmr_bitmap_set(hwdev, hinic3_global_func_id(hwdev), false);
+
+ return;
+}
+
static void hinic3_shutdown(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
sdk_info(&pdev->dev, "Shutdown device\n");
- if (pci_adapter)
+ if (pci_adapter) {
+ hinic3_timer_disable(pci_adapter->hwdev);
hinic3_shutdown_hwdev(pci_adapter->hwdev);
+ }
pci_disable_device(pdev);
@@ -1367,6 +2410,9 @@ static struct pci_driver hinic3_driver = {
.probe = hinic3_probe,
.remove = hinic3_remove,
.shutdown = hinic3_shutdown,
+#ifdef CONFIG_PARTITION_DEVICE
+ .driver.probe_concurrency = true,
+#endif
#if defined(HAVE_SRIOV_CONFIGURE)
.sriov_configure = hinic3_pci_sriov_configure,
#elif defined(HAVE_RHEL6_SRIOV_CONFIGURE)
@@ -1388,16 +2434,21 @@ int hinic3_lld_init(void)
err = hinic3_module_pre_init();
if (err) {
pr_err("Init custom failed\n");
- return err;
+ goto module_pre_init_err;
}
err = pci_register_driver(&hinic3_driver);
if (err) {
- hinic3_module_post_exit();
- return err;
+ pr_err("sdk3 pci register driver failed\n");
+ goto register_pci_driver_err;
}
return 0;
+
+register_pci_driver_err:
+ hinic3_module_post_exit();
+module_pre_init_err:
+ return err;
}
void hinic3_lld_exit(void)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
index d2a7dd7..5398a34 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
@@ -584,6 +584,7 @@ static void free_recv_mbox(struct hinic3_recv_mbox *recv_msg)
kfree(recv_msg->resp_buff);
kfree(recv_msg->msg);
kfree(recv_msg);
+ recv_msg = NULL;
}
static void recv_func_mbox_work_handler(struct work_struct *work)
@@ -1233,6 +1234,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
set_mbox_to_func_event(func_to_func, EVENT_FAIL);
goto send_err;
}
+ func_to_func->hwdev->mbox_send_cnt++;
if (wait_mbox_msg_completion(func_to_func, timeout) != 0) {
sdk_err(func_to_func->hwdev->dev_hdl,
@@ -1241,6 +1243,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
err = -ETIMEDOUT;
goto send_err;
}
+ func_to_func->hwdev->mbox_ack_cnt++;
if (mod != msg_desc->mod || cmd != msg_desc->cmd) {
sdk_err(func_to_func->hwdev->dev_hdl,
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
index 3ad9a77..0d75177 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
@@ -348,7 +348,7 @@ int hinic3_pf_to_mgmt_sync(void *hwdev, u8 mod, u16 cmd, void *buf_in,
if (!COMM_SUPPORT_API_CHAIN((struct hinic3_hwdev *)hwdev))
return -EPERM;
- if (!buf_in || in_size == 0)
+ if ((buf_in == NULL) || (in_size == 0))
return -EINVAL;
ret = msg_to_mgmt_pre(mod, buf_in, in_size);
@@ -864,6 +864,7 @@ static int alloc_recv_msg(struct hinic3_recv_msg *recv_msg)
static void free_recv_msg(struct hinic3_recv_msg *recv_msg)
{
kfree(recv_msg->msg);
+ recv_msg->msg = NULL;
}
/**
@@ -935,6 +936,9 @@ static void free_msg_buf(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt)
free_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
+ pf_to_mgmt->mgmt_ack_buf = NULL;
+ pf_to_mgmt->sync_msg_buf = NULL;
+ pf_to_mgmt->async_msg_buf = NULL;
}
/**
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
index 3548410..b619800 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
@@ -676,6 +676,11 @@ static int hinic3_register_slave_ppf(struct hinic3_hwdev *hwdev, bool registered
if (!IS_SLAVE_HOST(hwdev))
return -EINVAL;
+ /* if unsupport hot plug, return true. */
+ if (UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev)) {
+ return 0;
+ }
+
host_info = kcalloc(1, sizeof(struct register_slave_host), GFP_KERNEL);
if (!host_info)
return -ENOMEM;
@@ -1074,8 +1079,9 @@ int hinic3_get_func_nic_enable(void *hwdev, u16 glb_func_idx, bool *en)
if (!hwdev || !en)
return -EINVAL;
- /* if single host, return true. */
- if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev)) {
+ /* if single host or unsupport hot plug, return true. */
+ if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev) ||
+ UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev)) {
*en = true;
return 0;
}
@@ -1145,11 +1151,18 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
{
int err;
struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+ int is_use_vram, is_in_kexec;
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
- hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0) {
+ snprintf(hwdev->mhost_mgmt_name, VRAM_NAME_MAX_LEN, "%s", VRAM_NIC_MHOST_MGMT);
+ hwdev->mhost_mgmt = hi_vram_kalloc(hwdev->mhost_mgmt_name, sizeof(*hwdev->mhost_mgmt));
+ } else {
+ hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ }
if (!hwdev->mhost_mgmt)
return -ENOMEM;
@@ -1165,8 +1178,11 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK, hwdev, hilink_ppf_mbox_handler);
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC, hwdev, sw_func_ppf_mbox_handler);
- bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
- bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ }
/* Slave host:
* register slave host ppf functions
@@ -1179,7 +1195,13 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
return 0;
out_free_mhost_mgmt:
- kfree(hwdev->mhost_mgmt);
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)hwdev->mhost_mgmt,
+ hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ } else {
+ kfree(hwdev->mhost_mgmt);
+ }
hwdev->mhost_mgmt = NULL;
return err;
@@ -1187,6 +1209,7 @@ out_free_mhost_mgmt:
int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
{
+ int is_use_vram;
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
@@ -1203,7 +1226,14 @@ int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC);
- kfree(hwdev->mhost_mgmt);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)hwdev->mhost_mgmt,
+ hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ } else {
+ kfree(hwdev->mhost_mgmt);
+ }
hwdev->mhost_mgmt = NULL;
return 0;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
index f7d350c..ee7afef 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
@@ -14,6 +14,7 @@
#include "hinic3_crm.h"
#include "hinic3_hw.h"
#include "hinic3_hw_cfg.h"
+#include "hinic3_dev_mgmt.h"
#include "hinic3_hwdev.h"
#include "hinic3_lld.h"
#include "hinic3_hw_mt.h"
@@ -22,9 +23,7 @@
static int g_nictool_ref_cnt;
static dev_t g_dev_id = {0};
-/*lint -save -e104 -e808*/
static struct class *g_nictool_class;
-/*lint -restore*/
static struct cdev g_nictool_cdev;
#define HINIC3_MAX_BUF_SIZE (2048 * 1024)
@@ -92,6 +91,21 @@ static int get_all_chip_id_cmd(struct hinic3_lld_dev *lld_dev, const void *buf_i
return 0;
}
+static int get_os_hot_replace_info(struct hinic3_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ if (*out_size != sizeof(struct os_hot_replace_info) || !buf_out) {
+ pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
+ *out_size, sizeof(struct os_hot_replace_info));
+ return -EFAULT;
+ }
+
+ hinic3_get_os_hot_replace_info(buf_out);
+
+ return 0;
+}
+
static int get_card_usr_api_chain_mem(int card_idx)
{
unsigned char *tmp = NULL;
@@ -100,8 +114,8 @@ static int get_card_usr_api_chain_mem(int card_idx)
card_id = card_idx;
if (!g_card_vir_addr[card_idx]) {
g_card_vir_addr[card_idx] =
- (void *)__get_free_pages(GFP_KERNEL,
- DBGTOOL_PAGE_ORDER);
+ (void *)ossl_get_free_pages(GFP_KERNEL,
+ DBGTOOL_PAGE_ORDER);
if (!g_card_vir_addr[card_idx]) {
pr_err("Alloc api chain memory fail for card %d!\n", card_idx);
return -EFAULT;
@@ -166,7 +180,7 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
if (!buf_out || *out_size != sizeof(struct pf_dev_info) * PF_DEV_INFO_NUM) {
pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
- *out_size, sizeof(dev_info) * PF_DEV_INFO_NUM);
+ *out_size, sizeof(*dev_info) * PF_DEV_INFO_NUM);
return -EFAULT;
}
@@ -193,13 +207,18 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
return 0;
}
-static long dbgtool_knl_free_mem(int id)
+static void dbgtool_knl_free_mem(int id)
{
unsigned char *tmp = NULL;
int i;
+ if (id < 0 || id >= MAX_CARD_NUM) {
+ pr_err("Invalid card id\n");
+ return;
+ }
+
if (!g_card_vir_addr[id])
- return 0;
+ return;
tmp = g_card_vir_addr[id];
for (i = 0; i < (1 << DBGTOOL_PAGE_ORDER); i++) {
@@ -210,8 +229,6 @@ static long dbgtool_knl_free_mem(int id)
free_pages((unsigned long)g_card_vir_addr[id], DBGTOOL_PAGE_ORDER);
g_card_vir_addr[id] = NULL;
g_card_phy_addr[id] = 0;
-
- return 0;
}
static int free_knl_mem(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_size,
@@ -236,7 +253,8 @@ static int free_knl_mem(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32
return 0;
}
-static int card_info_param_valid(char *dev_name, const void *buf_out, u32 buf_out_size, int *id)
+static int card_info_param_valid(const char *dev_name, const void *buf_out,
+ u32 buf_out_size, int *id)
{
int err;
@@ -351,7 +369,7 @@ static int get_hw_drv_version(struct hinic3_lld_dev *lld_dev, const void *buf_in
}
err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s", HINIC3_DRV_VERSION,
- "2023-05-17_19:56:38");
+ "2025-05-01_00:00:03");
if (err < 0)
return -EINVAL;
@@ -386,22 +404,38 @@ static int get_pf_id(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_
return 0;
}
+static int get_mbox_cnt(struct hinic3_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ if (buf_out == NULL || *out_size != sizeof(struct card_mbox_cnt_info)) {
+ pr_err("buf_out is NULL, or out_size != %lu\n",
+ sizeof(struct card_info));
+ return -EINVAL;
+ }
+
+ hinic3_get_mbox_cnt(hinic3_get_sdk_hwdev_by_lld(lld_dev), buf_out);
+
+ return 0;
+}
+
struct hw_drv_module_handle hw_driv_module_cmd_handle[] = {
- {FUNC_TYPE, get_func_type},
- {GET_FUNC_IDX, get_func_id},
- {GET_HW_STATS, (hw_driv_module)get_hw_driver_stats},
- {CLEAR_HW_STATS, clear_hw_driver_stats},
- {GET_SELF_TEST_RES, get_self_test_result},
- {GET_CHIP_FAULT_STATS, (hw_driv_module)get_chip_faults_stats},
- {GET_SINGLE_CARD_INFO, (hw_driv_module)get_single_card_info},
- {IS_DRV_IN_VM, is_driver_in_vm},
- {GET_CHIP_ID, get_all_chip_id_cmd},
- {GET_PF_DEV_INFO, get_pf_dev_info},
- {CMD_FREE_MEM, free_knl_mem},
- {GET_CHIP_INFO, get_card_func_info},
- {GET_FUNC_CAP, get_pf_cap_info},
- {GET_DRV_VERSION, get_hw_drv_version},
- {GET_PF_ID, get_pf_id},
+ {FUNC_TYPE, get_func_type},
+ {GET_FUNC_IDX, get_func_id},
+ {GET_HW_STATS, (hw_driv_module)get_hw_driver_stats},
+ {CLEAR_HW_STATS, clear_hw_driver_stats},
+ {GET_SELF_TEST_RES, get_self_test_result},
+ {GET_CHIP_FAULT_STATS, (hw_driv_module)get_chip_faults_stats},
+ {GET_SINGLE_CARD_INFO, (hw_driv_module)get_single_card_info},
+ {IS_DRV_IN_VM, is_driver_in_vm},
+ {GET_CHIP_ID, get_all_chip_id_cmd},
+ {GET_PF_DEV_INFO, get_pf_dev_info},
+ {CMD_FREE_MEM, free_knl_mem},
+ {GET_CHIP_INFO, get_card_func_info},
+ {GET_FUNC_CAP, get_pf_cap_info},
+ {GET_DRV_VERSION, get_hw_drv_version},
+ {GET_PF_ID, get_pf_id},
+ {GET_OS_HOT_REPLACE_INFO, get_os_hot_replace_info},
+ {GET_MBOX_CNT, (hw_driv_module)get_mbox_cnt},
};
static int alloc_tmp_buf(void *hwdev, struct msg_module *nt_msg, u32 in_size,
@@ -439,8 +473,8 @@ static void free_tmp_buf(void *hwdev, struct msg_module *nt_msg,
static int send_to_hw_driver(struct hinic3_lld_dev *lld_dev, struct msg_module *nt_msg,
const void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(hw_driv_module_cmd_handle) /
- sizeof(hw_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(hw_driv_module_cmd_handle) /
+ sizeof(hw_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type =
(enum driver_cmd_type)(nt_msg->msg_formate);
int err = 0;
@@ -482,8 +516,8 @@ static int send_to_service_driver(struct hinic3_lld_dev *lld_dev, struct msg_mod
if (nt_msg->msg_formate == GET_DRV_VERSION)
return 0;
- pr_err("Can not get the uld dev correctly: %s, %s driver may be not register\n",
- nt_msg->device_name, service_name[type]);
+ pr_err("Can not get the uld dev correctly: %s driver may be not register\n",
+ service_name[type]);
return -EINVAL;
}
@@ -550,26 +584,29 @@ static struct hinic3_lld_dev *get_lld_dev_by_nt_msg(struct msg_module *nt_msg)
{
struct hinic3_lld_dev *lld_dev = NULL;
- if (nt_msg->module >= SEND_TO_SRV_DRV_BASE && nt_msg->module < SEND_TO_DRIVER_MAX &&
- nt_msg->module != SEND_TO_HW_DRIVER && nt_msg->msg_formate != GET_DRV_VERSION) {
+ if (nt_msg->module == SEND_TO_NIC_DRIVER &&
+ (nt_msg->msg_formate == GET_XSFP_INFO ||
+ nt_msg->msg_formate == GET_XSFP_PRESENT ||
+ nt_msg->msg_formate == GET_XSFP_INFO_COMP_CMIS)) {
+ lld_dev = hinic3_get_lld_dev_by_chip_and_port(nt_msg->device_name, nt_msg->port_id);
+ } else if (nt_msg->module == SEND_TO_CUSTOM_DRIVER &&
+ nt_msg->msg_formate == CMD_CUSTOM_BOND_GET_CHIP_NAME) {
+ lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
+ SERVICE_T_MAX);
+ } else if (nt_msg->module == SEND_TO_VBS_DRIVER ||
+ nt_msg->module == SEND_TO_BIFUR_DRIVER) {
+ lld_dev = hinic3_get_lld_dev_by_chip_name(nt_msg->device_name);
+ } else if (nt_msg->module >= SEND_TO_SRV_DRV_BASE &&
+ nt_msg->module < SEND_TO_DRIVER_MAX &&
+ nt_msg->msg_formate != GET_DRV_VERSION) {
lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
nt_msg->module - SEND_TO_SRV_DRV_BASE);
} else {
lld_dev = hinic3_get_lld_dev_by_chip_name(nt_msg->device_name);
if (!lld_dev)
- lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
- SERVICE_T_MAX);
+ lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name, SERVICE_T_MAX);
}
- if (nt_msg->module == SEND_TO_NIC_DRIVER && (nt_msg->msg_formate == GET_XSFP_INFO ||
- nt_msg->msg_formate == GET_XSFP_PRESENT))
- lld_dev = hinic3_get_lld_dev_by_chip_and_port(nt_msg->device_name,
- nt_msg->port_id);
-
- if (nt_msg->module == SEND_TO_CUSTOM_DRIVER &&
- nt_msg->msg_formate == CMD_CUSTOM_BOND_GET_CHIP_NAME)
- lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name, SERVICE_T_MAX);
-
return lld_dev;
}
@@ -591,14 +628,16 @@ static long hinicadm_k_unlocked_ioctl(struct file *pfile, unsigned long arg)
lld_dev = get_lld_dev_by_nt_msg(&nt_msg);
if (!lld_dev) {
if (nt_msg.msg_formate != DEV_NAME_TEST)
- pr_err("Can not find device %s for module %d\n",
+ pr_err("Can not find device %s for module %u\n",
nt_msg.device_name, nt_msg.module);
return -ENODEV;
}
- if (nt_msg.msg_formate == DEV_NAME_TEST)
+ if (nt_msg.msg_formate == DEV_NAME_TEST) {
+ lld_dev_put(lld_dev);
return 0;
+ }
ret = alloc_tmp_buf(hinic3_get_sdk_hwdev_by_lld(lld_dev), &nt_msg,
in_size, &buf_in, out_size_expect, &buf_out);
@@ -642,6 +681,9 @@ out_free_lock:
static long dbgtool_knl_ffm_info_rd(struct dbgtool_param *para,
struct dbgtool_k_glb_info *dbgtool_info)
{
+ if (!para->param.ffm_rd || !dbgtool_info->ffm)
+ return -EINVAL;
+
/* Copy the ffm_info to user mode */
if (copy_to_user(para->param.ffm_rd, dbgtool_info->ffm,
(unsigned int)sizeof(struct ffm_record_info))) {
@@ -674,13 +716,14 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
card_info = (struct card_node *)g_card_node_array[i];
if (!card_info)
continue;
- if (!strncmp(param.chip_name, card_info->chip_name, IFNAMSIZ))
+ if (memcmp(param.chip_name, card_info->chip_name,
+ strlen(card_info->chip_name) + 1) == 0)
break;
}
if (i == MAX_CARD_NUM || !card_info) {
lld_put();
- pr_err("Can't find this card %s\n", param.chip_name);
+ pr_err("Can't find this card.\n");
return -EFAULT;
}
@@ -701,6 +744,7 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
default:
pr_err("Dbgtool cmd(0x%x) not support now\n", real_cmd);
ret = -EFAULT;
+ break;
}
up(&dbgtool_info->dbgtool_sem);
@@ -746,9 +790,11 @@ static long nictool_k_unlocked_ioctl(struct file *pfile,
static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
{
+ pgprot_t vm_page_prot;
unsigned long vmsize = vma->vm_end - vma->vm_start;
phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
phys_addr_t phy_addr;
+ int err = 0;
if (vmsize > (PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER))) {
pr_err("Map size = %lu is bigger than alloc\n", vmsize);
@@ -757,14 +803,18 @@ static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
/* old version of tool set vma->vm_pgoff to 0 */
phy_addr = offset ? offset : g_card_phy_addr[card_id];
-
- if (!phy_addr) {
- pr_err("Card_id = %d physical address is 0\n", card_id);
- return -EAGAIN;
+ /* check phy_addr valid */
+ if (phy_addr != g_card_phy_addr[card_id]) {
+ err = hinic3_bar_mmap_param_valid(phy_addr, vmsize);
+ if (err != 0) {
+ pr_err("mmap param invalid, err: %d\n", err);
+ return err;
+ }
}
/* Disable cache and write buffer in the mapping area */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_page_prot = vm_page_prot;
if (remap_pfn_range(vma, vma->vm_start, (phy_addr >> PAGE_SHIFT),
vmsize, vma->vm_page_prot)) {
pr_err("Remap pfn range failed.\n");
@@ -787,7 +837,6 @@ static const struct file_operations fifo_operations = {
static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
{
struct dbgtool_k_glb_info *dbgtool_info = NULL;
- int err, id;
if (hinic3_func_type(hwdev) != TYPE_VF)
chip_info->func_handle_array[hinic3_global_func_id(hwdev)] = NULL;
@@ -795,23 +844,23 @@ static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
if (--chip_info->func_num)
return;
- err = sscanf(chip_info->chip_name, HINIC3_CHIP_NAME "%d", &id);
- if (err < 0)
- pr_err("Failed to get card id\n");
-
- if (id < MAX_CARD_NUM)
- g_card_node_array[id] = NULL;
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ g_card_node_array[chip_info->chip_id] = NULL;
dbgtool_info = chip_info->dbgtool_info;
/* FFM deinit */
- kfree(dbgtool_info->ffm);
- dbgtool_info->ffm = NULL;
+ if (dbgtool_info && dbgtool_info->ffm) {
+ kfree(dbgtool_info->ffm);
+ dbgtool_info->ffm = NULL;
+ }
+
+ if (dbgtool_info)
+ kfree(dbgtool_info);
- kfree(dbgtool_info);
chip_info->dbgtool_info = NULL;
- if (id < MAX_CARD_NUM)
- (void)dbgtool_knl_free_mem(id);
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ dbgtool_knl_free_mem(chip_info->chip_id);
}
static int alloc_dbgtool_info(void *hwdev, struct card_node *chip_info)
@@ -872,7 +921,6 @@ dbgtool_info_fail:
* nictool_k_init - initialize the hw interface
**/
/* temp for dbgtool_info */
-/*lint -e438*/
int nictool_k_init(void *hwdev, void *chip_node)
{
struct card_node *chip_info = (struct card_node *)chip_node;
@@ -895,9 +943,7 @@ int nictool_k_init(void *hwdev, void *chip_node)
}
/* Create equipment */
- /*lint -save -e160*/
g_nictool_class = class_create(THIS_MODULE, HIADM3_DEV_CLASS);
- /*lint -restore*/
if (IS_ERR(g_nictool_class)) {
pr_err("Create nictool_class fail\n");
err = -EFAULT;
@@ -944,7 +990,7 @@ alloc_chdev_fail:
free_dbgtool_info(hwdev, chip_info);
return err;
-} /*lint +e438*/
+}
void nictool_k_uninit(void *hwdev, void *chip_node)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
index f368133..c943dfc 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
@@ -18,6 +18,8 @@
int nictool_k_init(void *hwdev, void *chip_node);
void nictool_k_uninit(void *hwdev, void *chip_node);
+void hinic3_get_os_hot_replace_info(void *oshr_info);
+
void hinic3_get_all_chip_id(void *id_info);
void hinic3_get_card_func_info_by_card_name
@@ -29,6 +31,8 @@ bool hinic3_is_in_host(void);
int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *isvalid);
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin);
+
extern struct hinic3_uld_info g_uld_info[SERVICE_T_MAX];
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
index 2d5423e..6f145a0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
@@ -19,6 +19,20 @@
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
+#elif defined(CONFIG_NF_VID_DID)
+#define PCI_VENDOR_ID_NF 0x2036
+#define NFNIC_DEV_ID_STANDARD 0x1618
+#define NFNIC_DEV_ID_SDI_5_1_PF 0x0226
+#define NFNIC_DEV_ID_SDI_5_0_PF 0x0225
+#define NFNIC_DEV_ID_DPU_PF 0x0224
+#define NFNIC_DEV_ID_VF 0x1619
+#define NFNIC_DEV_ID_VF_HV 0x379F
+#define NFNIC_DEV_SDI_5_1_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_0_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_1_ID_VF_HV 0x379F
+#define NFNIC_DEV_ID_SPU 0xAC00
+#define NFNIC_DEV_SDI_5_1_SSDID_VF 0x1000
+#define NFNIC_DEV_SDI_V100_SSDID_MASK (3 << 12)
#else
#define PCI_VENDOR_ID_HUAWEI 0x19e5
#define HINIC3_DEV_ID_STANDARD 0x0222
@@ -28,16 +42,33 @@
#define HINIC3_DEV_ID_VF 0x375F
#define HINIC3_DEV_ID_VF_HV 0x379F
#define HINIC3_DEV_SDI_5_1_ID_VF 0x375F
+#define HINIC3_DEV_SDI_5_0_ID_VF 0x375F
#define HINIC3_DEV_SDI_5_1_ID_VF_HV 0x379F
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
#endif
+#define NFNIC_DEV_SSID_2X25G_NF 0x0860
+#define NFNIC_DEV_SSID_4X25G_NF 0x0861
+#define NFNIC_DEV_SSID_2x100G_NF 0x0862
+#define NFNIC_DEV_SSID_2x200G_NF 0x0863
+
+#define HINIC3_DEV_SSID_2X10G 0x0035
#define HINIC3_DEV_SSID_2X25G 0x0051
#define HINIC3_DEV_SSID_4X25G 0x0052
+#define HINIC3_DEV_SSID_4X25G_BD 0x0252
+#define HINIC3_DEV_SSID_4X25G_SMARTNIC 0x0152
+#define HINIC3_DEV_SSID_6X25G_VL 0x0356
#define HINIC3_DEV_SSID_2X100G 0x00A1
+#define HINIC3_DEV_SSID_2X100G_SMARTNIC 0x01A1
+#define HINIC3_DEV_SSID_2X200G 0x04B1
#define HINIC3_DEV_SSID_2X100G_VF 0x1000
+#define HINIC3_DEV_SSID_HPC_4_HOST_NIC 0x005A
+#define HINIC3_DEV_SSID_2X200G_VL 0x00B1
+#define HINIC3_DEV_SSID_1X100G 0x02A4
+
+#define BIFUR_RESOURCE_PF_SSID 0x05a1
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
index b23b69f..c8258ff 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
@@ -68,7 +68,6 @@ ssize_t hinic3_sriov_numvfs_show(struct device *dev,
return sprintf(buf, "%d\n", pci_num_vf(pdev));
}
-/*lint -save -e713*/
ssize_t hinic3_sriov_numvfs_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -116,7 +115,6 @@ ssize_t hinic3_sriov_numvfs_store(struct device *dev,
return count;
}
-/*lint -restore*/
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
int hinic3_pci_sriov_disable(struct pci_dev *dev)
@@ -174,24 +172,15 @@ int hinic3_pci_sriov_disable(struct pci_dev *dev)
return 0;
}
-int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
-{
#ifdef CONFIG_PCI_IOV
- struct hinic3_sriov_info *sriov_info = NULL;
- struct hinic3_event_info event = {0};
- void *hwdev = NULL;
- int pre_existing_vfs = 0;
- int err = 0;
-
- sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
- hwdev = hinic3_get_hwdev_by_pcidev(dev);
- if (!hwdev) {
- sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
- return -EPERM;
- }
+int hinic3_pci_sriov_check(struct hinic3_sriov_info *sriov_info, struct pci_dev *dev, int num_vfs)
+{
+ int pre_existing_vfs;
+ int err;
if (test_and_set_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state)) {
- sdk_err(&dev->dev, "SR-IOV enable in process, please wait, num_vfs %d\n",
+ sdk_err(&dev->dev,
+ "SR-IOV enable in process, please wait, num_vfs %d\n",
num_vfs);
return -EPERM;
}
@@ -202,6 +191,7 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
clear_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state);
return -ERANGE;
}
+
if (pre_existing_vfs && pre_existing_vfs != num_vfs) {
err = hinic3_pci_sriov_disable(dev);
if (err) {
@@ -213,6 +203,31 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
return num_vfs;
}
+ return 0;
+}
+#endif
+
+
+int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
+{
+#ifdef CONFIG_PCI_IOV
+ struct hinic3_sriov_info *sriov_info = NULL;
+ struct hinic3_event_info event = {0};
+ void *hwdev = NULL;
+ int err = 0;
+
+ sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
+ hwdev = hinic3_get_hwdev_by_pcidev(dev);
+ if (!hwdev) {
+ sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
+ return -EPERM;
+ }
+
+ err = hinic3_pci_sriov_check(sriov_info, dev, num_vfs);
+ if (err != 0) {
+ return err;
+ }
+
err = hinic3_init_vf_hw(hwdev, 1, (u16)num_vfs);
if (err) {
sdk_err(&dev->dev, "Failed to init vf in hardware before enable sriov, error %d\n",
@@ -262,6 +277,3 @@ int hinic3_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
else
return hinic3_pci_sriov_enable(dev, num_vfs);
}
-
-/*lint -restore*/
-
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c
index 2f5e098..4f8acd6 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c
@@ -128,7 +128,7 @@ int hinic3_wq_create(void *hwdev, struct hinic3_wq *wq, u32 q_depth,
wq_page_size = ALIGN(dev->wq_page_size, PAGE_SIZE);
- memset(wq, 0, sizeof(*wq));
+ memset(wq, 0, sizeof(struct hinic3_wq));
wq->dev_hdl = dev->dev_hdl;
wq->q_depth = q_depth;
wq->idx_mask = (u16)(q_depth - 1);
diff --git a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
index 9e8fc75..bfb4499 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
@@ -10,6 +10,10 @@
#define OVS_PORT_NUM_MAX BOND_PORT_MAX_NUM
#define DEFAULT_ROCE_BOND_FUNC 0xFFFFFFFF
+#define BOND_ID_IS_VALID(_id) \
+ (((_id) >= BOND_FIRST_ID) && ((_id) <= BOND_MAX_ID))
+#define BOND_ID_IS_INVALID(_id) (!(BOND_ID_IS_VALID(_id)))
+
enum bond_group_id {
BOND_FIRST_ID = 1,
BOND_MAX_ID = 4,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
index f56df08..f9737ea 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
@@ -21,6 +21,7 @@ enum servic_bit_define {
SERVICE_BIT_PPA = 11,
SERVICE_BIT_MIGRATE = 12,
SERVICE_BIT_VROCE = 13,
+ SERVICE_BIT_BIFUR = 14,
SERVICE_BIT_MAX
};
@@ -38,6 +39,7 @@ enum servic_bit_define {
#define CFG_SERVICE_MASK_PPA (0x1 << SERVICE_BIT_PPA)
#define CFG_SERVICE_MASK_MIGRATE (0x1 << SERVICE_BIT_MIGRATE)
#define CFG_SERVICE_MASK_VROCE (0x1 << SERVICE_BIT_VROCE)
+#define CFG_SERVICE_MASK_BIFUR (0x1 << SERVICE_BIT_BIFUR)
/* Definition of the scenario ID in the cfg_data, which is used for SML memory allocation. */
enum scenes_id_define {
@@ -50,6 +52,8 @@ enum scenes_id_define {
SCENES_ID_STORAGE_ROCE = 6,
SCENES_ID_COMPUTE_ROCE = 7,
SCENES_ID_STORAGE_TOE = 8,
+ SCENES_ID_COMPUTE_DPU = 100,
+ SCENES_ID_COMPUTE_SMART_NIC = 101,
SCENES_ID_MAX
};
@@ -120,13 +124,18 @@ struct cfg_cmd_dev_cap {
u8 srv_multi_host_mode;
u8 virtio_vq_size;
- u32 rsvd_func3[5];
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 lro_enable;
+ u8 os_hot_replace;
+
+ u32 rsvd_func3[4];
/* l2nic */
u16 nic_max_sq_id;
u16 nic_max_rq_id;
u16 nic_default_num_queues;
- u16 rsvd1_nic;
+ u16 outband_vlan_cfg_en;
u32 rsvd2_nic[2];
/* RoCE */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
index d9f67e2..6c5b995 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
@@ -37,7 +37,7 @@ static inline void hinic3_cpu_to_be32(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -59,7 +59,7 @@ static inline void hinic3_be32_to_cpu(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -86,52 +86,16 @@ static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
sge->len = (u32)len;
}
-#ifdef HW_CONVERT_ENDIAN
#define hinic3_hw_be32(val) (val)
#define hinic3_hw_cpu32(val) (val)
#define hinic3_hw_cpu16(val) (val)
-#else
-#define hinic3_hw_be32(val) cpu_to_be32(val)
-#define hinic3_hw_cpu32(val) be32_to_cpu(val)
-#define hinic3_hw_cpu16(val) be16_to_cpu(val)
-#endif
static inline void hinic3_hw_be32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_be32(*mem);
- mem++;
- }
-#endif
}
static inline void hinic3_hw_cpu32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_cpu32(*mem);
- mem++;
- }
-#endif
}
int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
@@ -149,6 +113,8 @@ int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
/* func_attr.glb_func_idx, global function index */
u16 hinic3_global_func_id(void *hwdev);
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id);
+
/* func_attr.p2p_idx, belongs to which pf */
u8 hinic3_pf_id_of_vf(void *hwdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
index 9a9bfe2..e36ba1d 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
@@ -219,5 +219,7 @@ void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
const char **hinic3_get_uld_names(void);
+int hinic3_lld_init(void);
+void hinic3_lld_exit(void);
#endif
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
index 97d34f0..199f17a 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
@@ -43,6 +43,10 @@ enum mag_cmd {
MAG_CMD_GET_XSFP_PRESENT = 62, /* get xsfp present status @see mag_cmd_get_xsfp_present */
MAG_CMD_SET_XSFP_RW = 63, /* sfp/qsfp single byte read/write, @see mag_cmd_set_xsfp_rw */
MAG_CMD_CFG_XSFP_TEMPERATURE = 64, /* get xsfp temp @see mag_cmd_sfp_temp_out_info */
+ /**< set xsfp tlv info @see struct mag_cmd_set_xsfp_tlv_req */
+ MAG_CMD_SET_XSFP_TLV_INFO = 65,
+ /**< get xsfp tlv info @see struct drv_mag_cmd_get_xsfp_tlv_rsp */
+ MAG_CMD_GET_XSFP_TLV_INFO = 66,
/* Event reported 100-149 */
MAG_CMD_WIRE_EVENT = 100,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
index caaba5d..88a9c0d 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
@@ -16,32 +16,43 @@
#define BOARD_TYPE_RSVD_RANGE_END 255
enum board_type_define_e {
- BOARD_TYPE_MPU_DEFAULT = 0, /* Default config */
- BOARD_TYPE_TEST_EVB_4X25G = 1, /* EVB Board */
- BOARD_TYPE_TEST_CEM_2X100G = 2, /* 2X100G CEM Card */
- BOARD_TYPE_STRG_SMARTIO_4X32G_FC = 30, /* 4X32G SmartIO FC Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_TIOE = 31, /* 4X25GE SmartIO TIOE Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE = 32, /* 4X25GE SmartIO ROCE Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE_AA = 33, /* 4X25GE SmartIO ROCE_AA Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV = 34, /* 4X25GE SmartIO container Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV_SW = 35, /* 4X25GE SmartIO container switch Card */
- BOARD_TYPE_STRG_4X25G_COMSTORAGE = 36, /* 4X25GE compute storage Onboard Card */
- BOARD_TYPE_STRG_2X100G_TIOE = 40, /* 2X100G SmartIO TIOE Card */
- BOARD_TYPE_STRG_2X100G_ROCE = 41, /* 2X100G SmartIO ROCE Card */
- BOARD_TYPE_STRG_2X100G_ROCE_AA = 42, /* 2X100G SmartIO ROCE_AA Card */
- BOARD_TYPE_CAL_2X25G_NIC_75MPPS = 100, /* 2X25G ETH Standard card 75MPPS */
- BOARD_TYPE_CAL_2X25G_NIC_40MPPS = 101, /* 2X25G ETH Standard card 40MPPS */
- BOARD_TYPE_CAL_2X100G_DPU = 102, /* 2x100G DPU Card */
- BOARD_TYPE_CAL_4X25G_NIC_120MPPS = 105, /* 4X25G ETH Standard card 120MPPS */
- BOARD_TYPE_CAL_4X25G_COMSTORAGE = 106, /* 4X25GE compute storage Onboard Card */
- BOARD_TYPE_CAL_2X32G_FC_HBA = 110, /* 2X32G FC HBA card */
- BOARD_TYPE_CAL_2X16G_FC_HBA = 111, /* 2X16G FC HBA card */
- BOARD_TYPE_CAL_2X100G_NIC_120MPPS = 115, /* 2X100G ETH Standard card 120MPPS */
- BOARD_TYPE_CAL_2X25G_DPU = 116, /* 2x25G DPU Card */
- BOARD_TYPE_CAL_4X25G_DPU = 118, /* 4x25G DPU Card */
- BOARD_TYPE_CLD_2X100G_SDI5_1 = 170, /* 2X100G SDI 5.1 Card */
- BOARD_TYPE_CLD_2X25G_SDI5_0_LITE = 171, /* 2x25G SDI5.0 Lite Card */
- BOARD_TYPE_CLD_2X100G_SDI5_0 = 172, /* 2x100G SDI5.0 Card */
+ BOARD_TYPE_MPU_DEFAULT = 0,
+ BOARD_TYPE_TEST_EVB_4X25G = 1,
+ BOARD_TYPE_TEST_CEM_2X100G = 2,
+ BOARD_TYPE_STRG_SMARTIO_4X32G_FC = 30,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_TIOE = 31,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE = 32,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE_AA = 33,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV = 34,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV_SW = 35,
+ BOARD_TYPE_STRG_4X25G_COMSTORAGE = 36,
+ BOARD_TYPE_STRG_2X100G_TIOE = 40,
+ BOARD_TYPE_STRG_2X100G_ROCE = 41,
+ BOARD_TYPE_STRG_2X100G_ROCE_AA = 42,
+ BOARD_TYPE_CAL_2X25G_NIC_75MPPS = 100,
+ BOARD_TYPE_CAL_2X25G_NIC_40MPPS = 101,
+ BOARD_TYPE_CAL_2X100G_DPU_VL = 102,
+ BOARD_TYPE_CAL_4X25G_NIC_120MPPS = 105,
+ BOARD_TYPE_CAL_4X25G_COMSTORAGE = 106,
+ BOARD_TYPE_CAL_2X32G_FC_HBA = 110,
+ BOARD_TYPE_CAL_2X16G_FC_HBA = 111,
+ BOARD_TYPE_CAL_2X100G_NIC_120MPPS = 115,
+ BOARD_TYPE_CAL_2X25G_DPU_BD = 116,
+ BOARD_TYPE_CAL_2X100G_TCE_BACKPLANE = 117,
+ BOARD_TYPE_CAL_4X25G_DPU_VL = 118,
+ BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS = 119,
+ BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS = 120,
+ BOARD_TYPE_CAL_6X25G_DPU_VL = 121,
+ BOARD_TYPE_CAL_4X25G_DPU_BD = 122,
+ BOARD_TYPE_CAL_2X25G_NIC_4HOST = 123,
+ BOARD_TYPE_CAL_2X10G_LOW_POWER = 125,
+ BOARD_TYPE_CAL_2X200G_NIC_INTERNET = 127,
+ BOARD_TYPE_CAL_1X100GR2_OCP = 129,
+ BOARD_TYPE_CAL_2X200G_DPU_VL = 130,
+ BOARD_TYPE_CLD_2X100G_SDI5_1 = 170,
+ BOARD_TYPE_CLD_2X25G_SDI5_0_LITE = 171,
+ BOARD_TYPE_CLD_2X100G_SDI5_0 = 172,
+ BOARD_TYPE_CLD_4X25G_SDI5_0_C = 175,
BOARD_TYPE_MAX_INDEX = 0xFF
};
@@ -49,23 +60,76 @@ static inline u32 spu_board_type_valid(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
- ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
+}
+
+static inline int board_type_is_sdi_50(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
+ ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C);
}
static inline int board_type_is_sdi(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_1) ||
((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
- ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0);
+ ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C);
+}
+
+static inline int board_type_is_dpu_spu(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
}
static inline int board_type_is_dpu(u32 board_type)
{
- return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_6X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
+}
+
+static inline int board_type_is_smartnic(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS);
+}
+
+/* 此接口判断是否是分布式存储的标卡以及计算的标卡(含ROCE特性),
+ * 仅用于LLDP TX功能冲突命令字处理的判断
+ */
+static inline int board_type_is_compute(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_75MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_40MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_NIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_COMSTORAGE) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_NIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X10G_LOW_POWER) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_NIC_INTERNET) ||
+ ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_4HOST) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS);
+}
+
+/* 此接口判断服务器输入reboot网卡是否需要复位 */
+static inline int board_type_is_multi_socket(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP);
}
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
index 89d5cc4..e65c206 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
@@ -1,11 +1,11 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ * Description : common definitions
+ */
#ifndef COMM_DEFS_H
#define COMM_DEFS_H
-#include "mgmt_msg_base.h"
-
/** MPU CMD MODULE TYPE */
enum hinic3_mod_type {
HINIC3_MOD_COMM = 0, /* HW communication module */
@@ -33,16 +33,16 @@ enum hinic3_mod_type {
HINIC3_MOD_MAX,
};
-/* Func reset flag, Specifies the resource to be cleaned.*/
-enum func_reset_flag_e {
+/* func reset的flag ,用于指示清理哪种资源 */
+enum func_reset_flag_e{
RES_TYPE_FLUSH_BIT = 0,
RES_TYPE_MQM,
RES_TYPE_SMF,
RES_TYPE_PF_BW_CFG,
RES_TYPE_COMM = 10,
- RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
RES_TYPE_NIC,
RES_TYPE_OVS,
RES_TYPE_VBS,
@@ -53,33 +53,48 @@ enum func_reset_flag_e {
RES_TYPE_MAX,
};
-#define HINIC3_COMM_RES \
- ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
- (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
- (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
+#define HINIC3_COMM_RES \
+ ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
+ (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
+ (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
-#define HINIC3_NIC_RES BIT(RES_TYPE_NIC)
-#define HINIC3_OVS_RES BIT(RES_TYPE_OVS)
-#define HINIC3_VBS_RES BIT(RES_TYPE_VBS)
-#define HINIC3_ROCE_RES BIT(RES_TYPE_ROCE)
-#define HINIC3_FC_RES BIT(RES_TYPE_FC)
-#define HINIC3_TOE_RES BIT(RES_TYPE_TOE)
-#define HINIC3_IPSEC_RES BIT(RES_TYPE_IPSEC)
+#define HINIC3_NIC_RES (1 << RES_TYPE_NIC)
+#define HINIC3_OVS_RES (1 << RES_TYPE_OVS)
+#define HINIC3_VBS_RES (1 << RES_TYPE_VBS)
+#define HINIC3_ROCE_RES (1 << RES_TYPE_ROCE)
+#define HINIC3_FC_RES (1 << RES_TYPE_FC)
+#define HINIC3_TOE_RES (1 << RES_TYPE_TOE)
+#define HINIC3_IPSEC_RES (1 << RES_TYPE_IPSEC)
/* MODE OVS、NIC、UNKNOWN */
#define HINIC3_WORK_MODE_OVS 0
#define HINIC3_WORK_MODE_UNKNOWN 1
#define HINIC3_WORK_MODE_NIC 2
-#define DEVICE_TYPE_L2NIC 0
-#define DEVICE_TYPE_NVME 1
-#define DEVICE_TYPE_VIRTIO_NET 2
-#define DEVICE_TYPE_VIRTIO_BLK 3
-#define DEVICE_TYPE_VIRTIO_VSOCK 4
-#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
-#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
-#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
-#define DEVICE_TYPE_VIRTIO_HPC 8
+#define DEVICE_TYPE_L2NIC 0
+#define DEVICE_TYPE_NVME 1
+#define DEVICE_TYPE_VIRTIO_NET 2
+#define DEVICE_TYPE_VIRTIO_BLK 3
+#define DEVICE_TYPE_VIRTIO_VSOCK 4
+#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
+#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
+#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
+#define DEVICE_TYPE_VIRTIO_HPC 8
+#define DEVICE_TYPE_VIRTIO_FS 9
+
+#define IS_STORAGE_DEVICE_TYPE(dev_type) \
+ ((dev_type) == DEVICE_TYPE_VIRTIO_BLK || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_BLK_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_SCSI_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_FS)
+
+#define MGMT_MSG_CMD_OP_SET 1
+#define MGMT_MSG_CMD_OP_GET 0
+
+#define MGMT_MSG_CMD_OP_START 1
+#define MGMT_MSG_CMD_OP_STOP 0
+
+#define HOT_REPLACE_PARTITION_NUM 2
enum hinic3_svc_type {
SVC_T_COMM = 0,
@@ -98,8 +113,17 @@ enum hinic3_svc_type {
};
/**
- * Common header control information of the COMM message interaction command word
- * between the driver and PF.
+ * Common header control information of the COMM message interaction command word between the driver and PF
+ * stuct mgmt_msg_head and struct comm_info_head are the same stucture
+ */
+struct mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+/**
+ * Common header control information of the COMM message interaction command word between the driver and PF
*/
struct comm_info_head {
/** response status code, 0: success, others: error code */
@@ -113,4 +137,29 @@ struct comm_info_head {
u8 rsvd[5];
};
+
+static inline u32 get_function_partition(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM;
+}
+
+static inline u32 is_primary_function(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0;
+}
+
+static inline u32 mpu_nic_get_primary_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ function_id : (function_id - port_num);
+}
+
+// when func_id is in partition 0/1, it will get its another func_id in partition 1/0
+static inline u32 mpu_nic_get_backup_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ (function_id + port_num) : (function_id - port_num);
+}
+
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
index b24e729..fd0401f 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
@@ -89,6 +89,10 @@ enum hinic3_mgmt_cmd {
* @see comm_read_ucode_sm_resp
*/
COMM_MGMT_CMD_CLEAR_LOG, /**< clear log @see comm_cmd_clear_log_s */
+ COMM_MGMT_CMD_UCODE_SM_COUNTER_PER,
+ /**< get ucode sm counter @see struct comm_read_ucode_sm_per_req
+ * @see struct comm_read_ucode_sm_per_resp
+ */
COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140, /* check if switch workmode reserved
* @see comm_cmd_check_if_switch_workmode
@@ -101,6 +105,7 @@ enum hinic3_mgmt_cmd {
COMM_MGMT_CMD_CPI_TCAM_DBG, /* enable or disable the scheduled cpi tcam task,
* set task interval time @see comm_cmd_cpi_tcam_dbg_s
*/
+ COMM_MGMT_CMD_LLDP_TX_FUNC_SET,
COMM_MGMT_CMD_SECTION_RSVD_0 = 160, /**< rsvd0 section */
COMM_MGMT_CMD_SECTION_RSVD_1 = 170, /**< rsvd1 section */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
index f535777..fd3a7dd 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
@@ -313,7 +313,8 @@ struct comm_cmd_get_fw_version {
struct mgmt_msg_head head;
u16 fw_type; /**< firmware type @see enum hinic3_fw_ver_type */
- u16 rsvd1;
+ u16 fw_dfx_vld : 1; /**< 0: release, 1: debug */
+ u16 rsvd1 : 15;
u8 ver[HINIC3_FW_VERSION_LEN]; /**< firmware version */
u8 time[HINIC3_FW_COMPILE_TIME_LEN]; /**< firmware compile time */
};
@@ -558,6 +559,7 @@ struct nic_log_info_request {
#define MPU_TEMP_OP_GET 0
#define MPU_TEMP_THRESHOLD_OP_CFG 1
+#define MPU_TEMP_MCTP_DFX_INFO_GET 2
struct comm_temp_in_info {
struct comm_info_head head;
u8 opt_type; /**< operation type 0:read operation 1:cfg operation */
@@ -660,6 +662,28 @@ struct comm_read_ucode_sm_resp {
u64 val2;
};
+#define PER_REQ_MAX_DATA_LEN 0x600
+
+struct comm_read_ucode_sm_per_req {
+ struct mgmt_msg_head msg_head;
+
+ u32 tbl_type;
+ u32 count_id;
+};
+
+struct comm_read_ucode_sm_per_resp {
+ struct mgmt_msg_head msg_head;
+
+ u8 data[PER_REQ_MAX_DATA_LEN];
+};
+
+struct ucode_sm_counter_get_info {
+ u32 width_type;
+ u32 tbl_type;
+ unsigned int base_count;
+ unsigned int count_num;
+};
+
enum log_type {
MPU_LOG_CLEAR = 0,
SMU_LOG_CLEAR = 1,
@@ -1057,7 +1081,9 @@ struct comm_cmd_ncsi_settings {
u8 lldp_over_ncsi_enable;
u8 lldp_over_mctp_enable;
u32 magicwd;
- u8 rsvd[8];
+ u8 lldp_tx_enable;
+ u8 rsvd[3];
+ u32 crc;
struct tag_ncsi_chan_info ncsi_chan_info;
};
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
index fde8617..767f886 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
@@ -114,6 +114,14 @@ struct tag_ncsi_client_info {
#define AEN_CTRL_CONFIG_REQ_SHIFT 1
#define AEN_CTRL_DRV_CHANGE_SHIFT 2
+/* AEN Type */
+enum aen_type_e{
+ AEN_LINK_STATUS_CHANGE_TYPE = 0x0,
+ AEN_CONFIG_REQUIRED_TYPE = 0x1,
+ OEM_AEN_CONFIG_REQUEST_TYPE = 0x80,
+ AEN_TYPE_MAX = 0x100
+} ;
+
/* get link status 0x0A */
#define GET_LINK_STATUS_REQ_LEN 0
#define GET_LINK_STATUS_RSP_LEN 16
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
index fe663e1..83b75f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
@@ -1,5 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+/*
+ * Copyright (C), 2001-2021, Huawei Tech. Co., Ltd.
+ * File Name : nic_cfg_comm.h
+ * Version : Initial Draft
+ * Description : nic config common header file
+ * Function List :
+ * History :
+ * Modification: Created file
+ */
#ifndef NIC_CFG_COMM_H
#define NIC_CFG_COMM_H
@@ -26,7 +34,7 @@ enum nic_rss_hash_type {
};
#define NIC_RSS_INDIR_SIZE 256
-#define NIC_RSS_KEY_SIZE 40
+#define NIC_RSS_KEY_SIZE 40
/* *
* Definition of the NIC receiving mode
@@ -36,6 +44,7 @@ enum nic_rss_hash_type {
#define NIC_RX_MODE_BC 0x04
#define NIC_RX_MODE_MC_ALL 0x08
#define NIC_RX_MODE_PROMISC 0x10
+#define NIC_RX_DB_COS_MAX 0x4
/* IEEE 802.1Qaz std */
#define NIC_DCB_COS_MAX 0x8
@@ -52,4 +61,7 @@ enum nic_rss_hash_type {
#define NIC_DCB_PRIO_STRICT 0x1
#define NIC_DCB_MAX_PFC_NUM 0x4
+
+#define NIC_ETS_PERCENT_WEIGHT 100
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
index 801aeed..9f93f7e 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
@@ -23,7 +23,11 @@
#define VRAM_CQM_BITMAP_BASE "B"
#define VRAM_NIC_DCB "DCB"
+#define VRAM_NIC_MHOST_MGMT "MHOST_MGMT"
#define VRAM_NIC_VRAM "NIC_VRAM"
+#define VRAM_NIC_IRQ_VRAM "NIC_IRQ"
+
+#define VRAM_NIC_MQM "NM"
#define VRAM_VBS_BASE_IOCB "BASE_IOCB"
#define VRAM_VBS_EX_IOCB "EX_IOCB"
@@ -55,11 +59,16 @@ enum KUP_HOOK_POINT {
PRE_FREEZE,
FREEZE_TO_KILL,
PRE_UPDATE_KERNEL,
- FLUSH_DURING_KUP,
POST_UPDATE_KERNEL,
UNFREEZE_TO_RUN,
POST_RUN,
KUP_HOOK_MAX,
};
+#define hi_vram_kalloc(name, size) 0
+#define hi_vram_kfree(vaddr, name, size)
+#define get_use_vram_flag(void) 0
+#define vram_get_kexec_flag(void) 0
+#define hi_vram_get_gfp_vram(void) 0
+
#endif /* VRAM_COMMON_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h b/drivers/net/ethernet/huawei/hinic3/mag_cmd.h
deleted file mode 100644
index 9649503..0000000
--- a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h
+++ /dev/null
@@ -1,922 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
-
-#ifndef MAG_MPU_CMD_DEFS_H
-#define MAG_MPU_CMD_DEFS_H
-
-#include "mpu_cmd_base_defs.h"
-
-/* serdes cmd struct define */
-#define CMD_ARRAY_BUF_SIZE 64
-#define SERDES_CMD_DATA_BUF_SIZE 512
-struct serdes_in_info {
- u32 chip_id : 16;
- u32 macro_id : 16;
- u32 start_sds_id : 16;
- u32 sds_num : 16;
-
- u32 cmd_type : 8; /* reserved for iotype */
- u32 sub_cmd : 8;
- u32 rw : 1; /* 0: read, 1: write */
- u32 rsvd : 15;
-
- u32 val;
- union {
- char field[CMD_ARRAY_BUF_SIZE];
- u32 addr;
- u8 *ex_param;
- };
-};
-
-struct serdes_out_info {
- u32 str_len; /* out_str length */
- u32 result_offset;
- u32 type; /* 0:data; 1:string */
- char out_str[SERDES_CMD_DATA_BUF_SIZE];
-};
-
-struct serdes_cmd_in {
- struct mgmt_msg_head head;
-
- struct serdes_in_info serdes_in;
-};
-
-struct serdes_cmd_out {
- struct mgmt_msg_head head;
-
- struct serdes_out_info serdes_out;
-};
-
-enum mag_cmd_port_speed {
- PORT_SPEED_NOT_SET = 0,
- PORT_SPEED_10MB = 1,
- PORT_SPEED_100MB = 2,
- PORT_SPEED_1GB = 3,
- PORT_SPEED_10GB = 4,
- PORT_SPEED_25GB = 5,
- PORT_SPEED_40GB = 6,
- PORT_SPEED_50GB = 7,
- PORT_SPEED_100GB = 8,
- PORT_SPEED_200GB = 9,
- PORT_SPEED_UNKNOWN
-};
-
-enum mag_cmd_port_an {
- PORT_AN_NOT_SET = 0,
- PORT_CFG_AN_ON = 1,
- PORT_CFG_AN_OFF = 2
-};
-
-enum mag_cmd_port_adapt {
- PORT_ADAPT_NOT_SET = 0,
- PORT_CFG_ADAPT_ON = 1,
- PORT_CFG_ADAPT_OFF = 2
-};
-
-enum mag_cmd_port_sriov {
- PORT_SRIOV_NOT_SET = 0,
- PORT_CFG_SRIOV_ON = 1,
- PORT_CFG_SRIOV_OFF = 2
-};
-
-enum mag_cmd_port_fec {
- PORT_FEC_NOT_SET = 0,
- PORT_FEC_RSFEC = 1,
- PORT_FEC_BASEFEC = 2,
- PORT_FEC_NOFEC = 3,
- PORT_FEC_LLRSFEC = 4,
- PORT_FEC_AUTO = 5
-};
-
-enum mag_cmd_port_lanes {
- PORT_LANES_NOT_SET = 0,
- PORT_LANES_X1 = 1,
- PORT_LANES_X2 = 2,
- PORT_LANES_X4 = 4,
- PORT_LANES_X8 = 8 /* reserved for future use */
-};
-
-enum mag_cmd_port_duplex {
- PORT_DUPLEX_HALF = 0,
- PORT_DUPLEX_FULL = 1
-};
-
-enum mag_cmd_wire_node {
- WIRE_NODE_UNDEF = 0,
- CABLE_10G = 1,
- FIBER_10G = 2,
- CABLE_25G = 3,
- FIBER_25G = 4,
- CABLE_40G = 5,
- FIBER_40G = 6,
- CABLE_50G = 7,
- FIBER_50G = 8,
- CABLE_100G = 9,
- FIBER_100G = 10,
- CABLE_200G = 11,
- FIBER_200G = 12,
- WIRE_NODE_NUM
-};
-
-enum mag_cmd_cnt_type {
- MAG_RX_RSFEC_DEC_CW_CNT = 0,
- MAG_RX_RSFEC_CORR_CW_CNT = 1,
- MAG_RX_RSFEC_UNCORR_CW_CNT = 2,
- MAG_RX_PCS_BER_CNT = 3,
- MAG_RX_PCS_ERR_BLOCK_CNT = 4,
- MAG_RX_PCS_E_BLK_CNT = 5,
- MAG_RX_PCS_DEC_ERR_BLK_CNT = 6,
- MAG_RX_PCS_LANE_BIP_ERR_CNT = 7,
- MAG_CNT_NUM
-};
-
-/* mag_cmd_set_port_cfg config bitmap */
-#define MAG_CMD_SET_SPEED 0x1
-#define MAG_CMD_SET_AUTONEG 0x2
-#define MAG_CMD_SET_FEC 0x4
-#define MAG_CMD_SET_LANES 0x8
-struct mag_cmd_set_port_cfg {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 rsvd0[3];
-
- u32 config_bitmap;
- u8 speed;
- u8 autoneg;
- u8 fec;
- u8 lanes;
- u8 rsvd1[20];
-};
-
-/* mag supported/advertised link mode bitmap */
-enum mag_cmd_link_mode {
- LINK_MODE_GE = 0,
- LINK_MODE_10GE_BASE_R = 1,
- LINK_MODE_25GE_BASE_R = 2,
- LINK_MODE_40GE_BASE_R4 = 3,
- LINK_MODE_50GE_BASE_R = 4,
- LINK_MODE_50GE_BASE_R2 = 5,
- LINK_MODE_100GE_BASE_R = 6,
- LINK_MODE_100GE_BASE_R2 = 7,
- LINK_MODE_100GE_BASE_R4 = 8,
- LINK_MODE_200GE_BASE_R2 = 9,
- LINK_MODE_200GE_BASE_R4 = 10,
- LINK_MODE_MAX_NUMBERS,
-
- LINK_MODE_UNKNOWN = 0xFFFF
-};
-
-#define LINK_MODE_GE_BIT 0x1u
-#define LINK_MODE_10GE_BASE_R_BIT 0x2u
-#define LINK_MODE_25GE_BASE_R_BIT 0x4u
-#define LINK_MODE_40GE_BASE_R4_BIT 0x8u
-#define LINK_MODE_50GE_BASE_R_BIT 0x10u
-#define LINK_MODE_50GE_BASE_R2_BIT 0x20u
-#define LINK_MODE_100GE_BASE_R_BIT 0x40u
-#define LINK_MODE_100GE_BASE_R2_BIT 0x80u
-#define LINK_MODE_100GE_BASE_R4_BIT 0x100u
-#define LINK_MODE_200GE_BASE_R2_BIT 0x200u
-#define LINK_MODE_200GE_BASE_R4_BIT 0x400u
-
-#define CABLE_10GE_BASE_R_BIT LINK_MODE_10GE_BASE_R_BIT
-#define CABLE_25GE_BASE_R_BIT (LINK_MODE_25GE_BASE_R_BIT | LINK_MODE_10GE_BASE_R_BIT)
-#define CABLE_40GE_BASE_R4_BIT LINK_MODE_40GE_BASE_R4_BIT
-#define CABLE_50GE_BASE_R_BIT (LINK_MODE_50GE_BASE_R_BIT | LINK_MODE_25GE_BASE_R_BIT | \
- LINK_MODE_10GE_BASE_R_BIT)
-#define CABLE_50GE_BASE_R2_BIT LINK_MODE_50GE_BASE_R2_BIT
-#define CABLE_100GE_BASE_R2_BIT (LINK_MODE_100GE_BASE_R2_BIT | LINK_MODE_50GE_BASE_R2_BIT)
-#define CABLE_100GE_BASE_R4_BIT (LINK_MODE_100GE_BASE_R4_BIT | LINK_MODE_40GE_BASE_R4_BIT)
-#define CABLE_200GE_BASE_R4_BIT (LINK_MODE_200GE_BASE_R4_BIT | LINK_MODE_100GE_BASE_R4_BIT | \
- LINK_MODE_40GE_BASE_R4_BIT)
-
-struct mag_cmd_get_port_info {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 rsvd0[3];
-
- u8 wire_type;
- u8 an_support;
- u8 an_en;
- u8 duplex;
-
- u8 speed;
- u8 fec;
- u8 lanes;
- u8 rsvd1;
-
- u32 supported_mode;
- u32 advertised_mode;
- u8 rsvd2[8];
-};
-
-#define MAG_CMD_OPCODE_GET 0
-#define MAG_CMD_OPCODE_SET 1
-struct mag_cmd_set_port_adapt {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 opcode; /* 0:get adapt info 1:set adapt */
- u8 enable;
- u8 rsvd0;
- u32 speed_mode;
- u32 rsvd1[3];
-};
-
-#define MAG_CMD_LP_MODE_SDS_S_TX2RX 1
-#define MAG_CMD_LP_MODE_SDS_P_RX2TX 2
-#define MAG_CMD_LP_MODE_SDS_P_TX2RX 3
-#define MAG_CMD_LP_MODE_MAC_RX2TX 4
-#define MAG_CMD_LP_MODE_MAC_TX2RX 5
-#define MAG_CMD_LP_MODE_TXDP2RXDP 6
-struct mag_cmd_cfg_loopback_mode {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 opcode; /* 0:get loopback mode 1:set loopback mode */
- u8 lp_mode;
- u8 lp_en; /* 0:disable 1:enable */
-
- u32 rsvd0[2];
-};
-
-#define MAG_CMD_PORT_DISABLE 0x0
-#define MAG_CMD_TX_ENABLE 0x1
-#define MAG_CMD_RX_ENABLE 0x2
-/* the physical port is disable only when all pf of the port are set to down,
- * if any pf is enable, the port is enable
- */
-struct mag_cmd_set_port_enable {
- struct mgmt_msg_head head;
-
- u16 function_id; /* function_id should not more than the max support pf_id(32) */
- u16 rsvd0;
-
- u8 state; /* bitmap bit0:tx_en bit1:rx_en */
- u8 rsvd1[3];
-};
-
-struct mag_cmd_get_port_enable {
- struct mgmt_msg_head head;
-
- u8 port;
- u8 state; /* bitmap bit0:tx_en bit1:rx_en */
- u8 rsvd0[2];
-};
-
-#define PMA_FOLLOW_DEFAULT 0x0
-#define PMA_FOLLOW_ENABLE 0x1
-#define PMA_FOLLOW_DISABLE 0x2
-#define PMA_FOLLOW_GET 0x4
-/* the physical port disable link follow only when all pf of the port are set to follow disable */
-struct mag_cmd_set_link_follow {
- struct mgmt_msg_head head;
-
- u16 function_id; /* function_id should not more than the max support pf_id(32) */
- u16 rsvd0;
-
- u8 follow;
- u8 rsvd1[3];
-};
-
-/* firmware also use this cmd report link event to driver */
-struct mag_cmd_get_link_status {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 status; /* 0:link down 1:link up */
- u8 rsvd0[2];
-};
-
-/* firmware also use this cmd report bond event to driver */
-struct mag_cmd_get_bond_status {
- struct mgmt_msg_head head;
-
- u8 status; /* 0:bond down 1:bond up */
- u8 rsvd0[3];
-};
-
-struct mag_cmd_set_pma_enable {
- struct mgmt_msg_head head;
-
- u16 function_id; /* function_id should not more than the max support pf_id(32) */
- u16 enable;
-};
-
-struct mag_cmd_cfg_an_type {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 opcode; /* 0:get an type 1:set an type */
- u8 rsvd0[2];
-
- u32 an_type; /* 0:ieee 1:25G/50 eth consortium */
-};
-
-struct mag_cmd_get_link_time {
- struct mgmt_msg_head head;
- u8 port_id;
- u8 rsvd0[3];
-
- u32 link_up_begin;
- u32 link_up_end;
- u32 link_down_begin;
- u32 link_down_end;
-};
-
-struct mag_cmd_cfg_fec_mode {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 opcode; /* 0:get fec mode 1:set fec mode */
- u8 fec;
- u8 rsvd0;
-};
-
-/* speed */
-#define PANGEA_ADAPT_10G_BITMAP 0xd
-#define PANGEA_ADAPT_25G_BITMAP 0x72
-#define PANGEA_ADAPT_40G_BITMAP 0x680
-#define PANGEA_ADAPT_100G_BITMAP 0x1900
-
-/* speed and fec */
-#define PANGEA_10G_NO_BITMAP 0x8
-#define PANGEA_10G_BASE_BITMAP 0x4
-#define PANGEA_25G_NO_BITMAP 0x10
-#define PANGEA_25G_BASE_BITMAP 0x20
-#define PANGEA_25G_RS_BITMAP 0x40
-#define PANGEA_40G_NO_BITMAP 0x400
-#define PANGEA_40G_BASE_BITMAP 0x200
-#define PANGEA_100G_NO_BITMAP 0x800
-#define PANGEA_100G_RS_BITMAP 0x1000
-
-/* adapt or fec */
-#define PANGEA_ADAPT_ADAPT_BITMAP 0x183
-#define PANGEA_ADAPT_NO_BITMAP 0xc18
-#define PANGEA_ADAPT_BASE_BITMAP 0x224
-#define PANGEA_ADAPT_RS_BITMAP 0x1040
-
-/* default cfg */
-#define PANGEA_ADAPT_CFG_10G_CR 0x200d
-#define PANGEA_ADAPT_CFG_10G_SRLR 0xd
-#define PANGEA_ADAPT_CFG_25G_CR 0x207f
-#define PANGEA_ADAPT_CFG_25G_SRLR 0x72
-#define PANGEA_ADAPT_CFG_40G_CR4 0x2680
-#define PANGEA_ADAPT_CFG_40G_SRLR4 0x680
-#define PANGEA_ADAPT_CFG_100G_CR4 0x3f80
-#define PANGEA_ADAPT_CFG_100G_SRLR4 0x1900
-
-union pangea_adapt_bitmap_u {
- struct {
- u32 adapt_10g : 1; /* [0] adapt_10g */
- u32 adapt_25g : 1; /* [1] adapt_25g */
- u32 base_10g : 1; /* [2] base_10g */
- u32 no_10g : 1; /* [3] no_10g */
- u32 no_25g : 1; /* [4] no_25g */
- u32 base_25g : 1; /* [5] base_25g */
- u32 rs_25g : 1; /* [6] rs_25g */
- u32 adapt_40g : 1; /* [7] adapt_40g */
- u32 adapt_100g : 1; /* [8] adapt_100g */
- u32 base_40g : 1; /* [9] base_40g */
- u32 no_40g : 1; /* [10] no_40g */
- u32 no_100g : 1; /* [11] no_100g */
- u32 rs_100g : 1; /* [12] rs_100g */
- u32 auto_neg : 1; /* [13] auto_neg */
- u32 rsvd0 : 18; /* [31:14] reserved */
- } bits;
-
- u32 value;
-};
-
-#define PANGEA_ADAPT_GET 0x0
-#define PANGEA_ADAPT_SET 0x1
-struct mag_cmd_set_pangea_adapt {
- struct mgmt_msg_head head;
-
- u16 port_id;
- u8 opcode; /* 0:get adapt info 1:cfg adapt info */
- u8 wire_type;
-
- union pangea_adapt_bitmap_u cfg_bitmap;
- union pangea_adapt_bitmap_u cur_bitmap;
- u32 rsvd1[3];
-};
-
-struct mag_cmd_cfg_bios_link_cfg {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 opcode; /* 0:get bios link info 1:set bios link cfg */
- u8 clear;
- u8 rsvd0;
-
- u32 wire_type;
- u8 an_en;
- u8 speed;
- u8 fec;
- u8 rsvd1;
- u32 speed_mode;
- u32 rsvd2[3];
-};
-
-struct mag_cmd_restore_link_cfg {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 rsvd[7];
-};
-
-struct mag_cmd_activate_bios_link_cfg {
- struct mgmt_msg_head head;
-
- u32 rsvd[8];
-};
-
-/* led type */
-enum mag_led_type {
- MAG_CMD_LED_TYPE_ALARM = 0x0,
- MAG_CMD_LED_TYPE_LOW_SPEED = 0x1,
- MAG_CMD_LED_TYPE_HIGH_SPEED = 0x2
-};
-
-/* led mode */
-enum mag_led_mode {
- MAG_CMD_LED_MODE_DEFAULT = 0x0,
- MAG_CMD_LED_MODE_FORCE_ON = 0x1,
- MAG_CMD_LED_MODE_FORCE_OFF = 0x2,
- MAG_CMD_LED_MODE_FORCE_BLINK_1HZ = 0x3,
- MAG_CMD_LED_MODE_FORCE_BLINK_2HZ = 0x4,
- MAG_CMD_LED_MODE_FORCE_BLINK_4HZ = 0x5,
- MAG_CMD_LED_MODE_1HZ = 0x6,
- MAG_CMD_LED_MODE_2HZ = 0x7,
- MAG_CMD_LED_MODE_4HZ = 0x8
-};
-
-/* the led is report alarm when any pf of the port is alram */
-struct mag_cmd_set_led_cfg {
- struct mgmt_msg_head head;
-
- u16 function_id;
- u8 type;
- u8 mode;
-};
-
-#define XSFP_INFO_MAX_SIZE 640
-/* xsfp wire type, refer to cmis protocol definition */
-enum mag_wire_type {
- MAG_CMD_WIRE_TYPE_UNKNOWN = 0x0,
- MAG_CMD_WIRE_TYPE_MM = 0x1,
- MAG_CMD_WIRE_TYPE_SM = 0x2,
- MAG_CMD_WIRE_TYPE_COPPER = 0x3,
- MAG_CMD_WIRE_TYPE_ACC = 0x4,
- MAG_CMD_WIRE_TYPE_BASET = 0x5,
- MAG_CMD_WIRE_TYPE_AOC = 0x40,
- MAG_CMD_WIRE_TYPE_ELECTRIC = 0x41,
- MAG_CMD_WIRE_TYPE_BACKPLANE = 0x42
-};
-
-struct mag_cmd_get_xsfp_info {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 wire_type;
- u16 out_len;
- u32 rsvd;
- u8 sfp_info[XSFP_INFO_MAX_SIZE];
-};
-
-#define MAG_CMD_XSFP_DISABLE 0x0
-#define MAG_CMD_XSFP_ENABLE 0x1
-/* the sfp is disable only when all pf of the port are set sfp down,
- * if any pf is enable, the sfp is enable
- */
-struct mag_cmd_set_xsfp_enable {
- struct mgmt_msg_head head;
-
- u32 port_id;
- u32 status; /* 0:on 1:off */
-};
-
-#define MAG_CMD_XSFP_PRESENT 0x0
-#define MAG_CMD_XSFP_ABSENT 0x1
-struct mag_cmd_get_xsfp_present {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 abs_status; /* 0:present, 1:absent */
- u8 rsvd[2];
-};
-
-#define MAG_CMD_XSFP_READ 0x0
-#define MAG_CMD_XSFP_WRITE 0x1
-struct mag_cmd_set_xsfp_rw {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 operation; /* 0: read; 1: write */
- u8 value;
- u8 rsvd0;
- u32 devaddr;
- u32 offset;
- u32 rsvd1;
-};
-
-struct mag_cmd_cfg_xsfp_temperature {
- struct mgmt_msg_head head;
-
- u8 opcode; /* 0:read 1:write */
- u8 rsvd0[3];
- s32 max_temp;
- s32 min_temp;
-};
-
-struct mag_cmd_get_xsfp_temperature {
- struct mgmt_msg_head head;
-
- s16 sfp_temp[8];
- u8 rsvd[32];
- s32 max_temp;
- s32 min_temp;
-};
-
-/* xsfp plug event */
-struct mag_cmd_wire_event {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 status; /* 0:present, 1:absent */
- u8 rsvd[2];
-};
-
-/* link err type definition */
-#define MAG_CMD_ERR_XSFP_UNKNOWN 0x0
-struct mag_cmd_link_err_event {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 link_err_type;
- u8 rsvd[2];
-};
-
-#define MAG_PARAM_TYPE_DEFAULT_CFG 0x0
-#define MAG_PARAM_TYPE_BIOS_CFG 0x1
-#define MAG_PARAM_TYPE_TOOL_CFG 0x2
-#define MAG_PARAM_TYPE_FINAL_CFG 0x3
-#define MAG_PARAM_TYPE_WIRE_INFO 0x4
-#define MAG_PARAM_TYPE_ADAPT_INFO 0x5
-#define MAG_PARAM_TYPE_MAX_CNT 0x6
-struct param_head {
- u8 valid_len;
- u8 info_type;
- u8 rsvd[2];
-};
-
-struct mag_port_link_param {
- struct param_head head;
-
- u8 an;
- u8 fec;
- u8 speed;
- u8 rsvd0;
-
- u32 used;
- u32 an_fec_ability;
- u32 an_speed_ability;
- u32 an_pause_ability;
-};
-
-struct mag_port_wire_info {
- struct param_head head;
-
- u8 status;
- u8 rsvd0[3];
-
- u8 wire_type;
- u8 default_fec;
- u8 speed;
- u8 rsvd1;
- u32 speed_ability;
-};
-
-struct mag_port_adapt_info {
- struct param_head head;
-
- u32 adapt_en;
- u32 flash_adapt;
- u32 rsvd0[2];
-
- u32 wire_node;
- u32 an_en;
- u32 speed;
- u32 fec;
-};
-
-struct mag_port_param_info {
- u8 parameter_cnt;
- u8 lane_id;
- u8 lane_num;
- u8 rsvd0;
-
- struct mag_port_link_param default_cfg;
- struct mag_port_link_param bios_cfg;
- struct mag_port_link_param tool_cfg;
- struct mag_port_link_param final_cfg;
-
- struct mag_port_wire_info wire_info;
- struct mag_port_adapt_info adapt_info;
-};
-
-#define XSFP_VENDOR_NAME_LEN 16
-struct mag_cmd_event_port_info {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 event_type;
- u8 rsvd0[2];
-
- u8 vendor_name[XSFP_VENDOR_NAME_LEN];
- u32 port_type; /* fiber / copper */
- u32 port_sub_type; /* sr / lr */
- u32 cable_length; /* 1/3/5m */
- u8 cable_temp; /* temp */
- u8 max_speed; /* Maximum rate of an optical module */
- u8 sfp_type; /* sfp/qsfp */
- u8 rsvd1;
- u32 power[4]; /* Optical Power */
-
- u8 an_state;
- u8 fec;
- u16 speed;
-
- u8 gpio_insert; /* 0:present 1:absent */
- u8 alos;
- u8 rx_los;
- u8 pma_ctrl;
-
- u32 pma_fifo_reg;
- u32 pma_signal_ok_reg;
- u32 pcs_64_66b_reg;
- u32 rf_lf;
- u8 pcs_link;
- u8 pcs_mac_link;
- u8 tx_enable;
- u8 rx_enable;
- u32 pcs_err_cnt;
-
- u8 eq_data[38];
- u8 rsvd2[2];
-
- u32 his_link_machine_state;
- u32 cur_link_machine_state;
- u8 his_machine_state_data[128];
- u8 cur_machine_state_data[128];
- u8 his_machine_state_length;
- u8 cur_machine_state_length;
-
- struct mag_port_param_info param_info;
- u8 rsvd3[360];
-};
-
-struct mag_cmd_port_stats {
- u64 mac_tx_fragment_pkt_num;
- u64 mac_tx_undersize_pkt_num;
- u64 mac_tx_undermin_pkt_num;
- u64 mac_tx_64_oct_pkt_num;
- u64 mac_tx_65_127_oct_pkt_num;
- u64 mac_tx_128_255_oct_pkt_num;
- u64 mac_tx_256_511_oct_pkt_num;
- u64 mac_tx_512_1023_oct_pkt_num;
- u64 mac_tx_1024_1518_oct_pkt_num;
- u64 mac_tx_1519_2047_oct_pkt_num;
- u64 mac_tx_2048_4095_oct_pkt_num;
- u64 mac_tx_4096_8191_oct_pkt_num;
- u64 mac_tx_8192_9216_oct_pkt_num;
- u64 mac_tx_9217_12287_oct_pkt_num;
- u64 mac_tx_12288_16383_oct_pkt_num;
- u64 mac_tx_1519_max_bad_pkt_num;
- u64 mac_tx_1519_max_good_pkt_num;
- u64 mac_tx_oversize_pkt_num;
- u64 mac_tx_jabber_pkt_num;
- u64 mac_tx_bad_pkt_num;
- u64 mac_tx_bad_oct_num;
- u64 mac_tx_good_pkt_num;
- u64 mac_tx_good_oct_num;
- u64 mac_tx_total_pkt_num;
- u64 mac_tx_total_oct_num;
- u64 mac_tx_uni_pkt_num;
- u64 mac_tx_multi_pkt_num;
- u64 mac_tx_broad_pkt_num;
- u64 mac_tx_pause_num;
- u64 mac_tx_pfc_pkt_num;
- u64 mac_tx_pfc_pri0_pkt_num;
- u64 mac_tx_pfc_pri1_pkt_num;
- u64 mac_tx_pfc_pri2_pkt_num;
- u64 mac_tx_pfc_pri3_pkt_num;
- u64 mac_tx_pfc_pri4_pkt_num;
- u64 mac_tx_pfc_pri5_pkt_num;
- u64 mac_tx_pfc_pri6_pkt_num;
- u64 mac_tx_pfc_pri7_pkt_num;
- u64 mac_tx_control_pkt_num;
- u64 mac_tx_err_all_pkt_num;
- u64 mac_tx_from_app_good_pkt_num;
- u64 mac_tx_from_app_bad_pkt_num;
-
- u64 mac_rx_fragment_pkt_num;
- u64 mac_rx_undersize_pkt_num;
- u64 mac_rx_undermin_pkt_num;
- u64 mac_rx_64_oct_pkt_num;
- u64 mac_rx_65_127_oct_pkt_num;
- u64 mac_rx_128_255_oct_pkt_num;
- u64 mac_rx_256_511_oct_pkt_num;
- u64 mac_rx_512_1023_oct_pkt_num;
- u64 mac_rx_1024_1518_oct_pkt_num;
- u64 mac_rx_1519_2047_oct_pkt_num;
- u64 mac_rx_2048_4095_oct_pkt_num;
- u64 mac_rx_4096_8191_oct_pkt_num;
- u64 mac_rx_8192_9216_oct_pkt_num;
- u64 mac_rx_9217_12287_oct_pkt_num;
- u64 mac_rx_12288_16383_oct_pkt_num;
- u64 mac_rx_1519_max_bad_pkt_num;
- u64 mac_rx_1519_max_good_pkt_num;
- u64 mac_rx_oversize_pkt_num;
- u64 mac_rx_jabber_pkt_num;
- u64 mac_rx_bad_pkt_num;
- u64 mac_rx_bad_oct_num;
- u64 mac_rx_good_pkt_num;
- u64 mac_rx_good_oct_num;
- u64 mac_rx_total_pkt_num;
- u64 mac_rx_total_oct_num;
- u64 mac_rx_uni_pkt_num;
- u64 mac_rx_multi_pkt_num;
- u64 mac_rx_broad_pkt_num;
- u64 mac_rx_pause_num;
- u64 mac_rx_pfc_pkt_num;
- u64 mac_rx_pfc_pri0_pkt_num;
- u64 mac_rx_pfc_pri1_pkt_num;
- u64 mac_rx_pfc_pri2_pkt_num;
- u64 mac_rx_pfc_pri3_pkt_num;
- u64 mac_rx_pfc_pri4_pkt_num;
- u64 mac_rx_pfc_pri5_pkt_num;
- u64 mac_rx_pfc_pri6_pkt_num;
- u64 mac_rx_pfc_pri7_pkt_num;
- u64 mac_rx_control_pkt_num;
- u64 mac_rx_sym_err_pkt_num;
- u64 mac_rx_fcs_err_pkt_num;
- u64 mac_rx_send_app_good_pkt_num;
- u64 mac_rx_send_app_bad_pkt_num;
- u64 mac_rx_unfilter_pkt_num;
-};
-
-struct mag_port_stats {
- u64 tx_frag_pkts_port;
- u64 tx_under_frame_pkts_port;
- u64 tx_under_min_pkts_port;
- u64 tx_64_oct_pkts_port;
- u64 tx_127_oct_pkts_port;
- u64 tx_255_oct_pkts_port;
- u64 tx_511_oct_pkts_port;
- u64 tx_1023_oct_pkts_port;
- u64 tx_1518_oct_pkts_port;
- u64 tx_2047_oct_pkts_port;
- u64 tx_4095_oct_pkts_port;
- u64 tx_8191_oct_pkts_port;
- u64 tx_9216_oct_pkts_port;
- u64 tx_12287_oct_pkts_port;
- u64 tx_16383_oct_pkts_port;
- u64 tx_1519_to_max_bad_pkts_port;
- u64 tx_1519_to_max_good_pkts_port;
- u64 tx_oversize_pkts_port;
- u64 tx_jabber_pkts_port;
- u64 tx_bad_pkts_port;
- u64 tx_bad_octs_port;
- u64 tx_good_pkts_port;
- u64 tx_good_octs_port;
- u64 tx_total_pkts_port;
- u64 tx_total_octs_port;
- u64 tx_unicast_pkts_port;
- u64 tx_multicast_pkts_port;
- u64 tx_broadcast_pkts_port;
- u64 tx_pause_pkts_port;
- u64 tx_pfc_pkts_port;
- u64 tx_pri_0_pkts_port;
- u64 tx_pri_1_pkts_port;
- u64 tx_pri_2_pkts_port;
- u64 tx_pri_3_pkts_port;
- u64 tx_pri_4_pkts_port;
- u64 tx_pri_5_pkts_port;
- u64 tx_pri_6_pkts_port;
- u64 tx_pri_7_pkts_port;
- u64 tx_mac_control_pkts_port;
- u64 tx_y1731_pkts_port;
- u64 tx_1588_pkts_port;
- u64 tx_error_pkts_port;
- u64 tx_app_good_pkts_port;
- u64 tx_app_bad_pkts_port;
- u64 rx_frag_pkts_port;
- u64 rx_under_frame_pkts_port;
- u64 rx_under_min_pkts_port;
- u64 rx_64_oct_pkts_port;
- u64 rx_127_oct_pkts_port;
- u64 rx_255_oct_pkts_port;
- u64 rx_511_oct_pkts_port;
- u64 rx_1023_oct_pkts_port;
- u64 rx_1518_oct_pkts_port;
- u64 rx_2047_oct_pkts_port;
- u64 rx_4095_oct_pkts_port;
- u64 rx_8191_oct_pkts_port;
- u64 rx_9216_oct_pkts_port;
- u64 rx_12287_oct_pkts_port;
- u64 rx_16383_oct_pkts_port;
- u64 rx_1519_to_max_bad_pkts_port;
- u64 rx_1519_to_max_good_pkts_port;
- u64 rx_oversize_pkts_port;
- u64 rx_jabber_pkts_port;
- u64 rx_bad_pkts_port;
- u64 rx_bad_octs_port;
- u64 rx_good_pkts_port;
- u64 rx_good_octs_port;
- u64 rx_total_pkts_port;
- u64 rx_total_octs_port;
- u64 rx_unicast_pkts_port;
- u64 rx_multicast_pkts_port;
- u64 rx_broadcast_pkts_port;
- u64 rx_pause_pkts_port;
- u64 rx_pfc_pkts_port;
- u64 rx_pri_0_pkts_port;
- u64 rx_pri_1_pkts_port;
- u64 rx_pri_2_pkts_port;
- u64 rx_pri_3_pkts_port;
- u64 rx_pri_4_pkts_port;
- u64 rx_pri_5_pkts_port;
- u64 rx_pri_6_pkts_port;
- u64 rx_pri_7_pkts_port;
- u64 rx_mac_control_pkts_port;
- u64 rx_y1731_pkts_port;
- u64 rx_sym_err_pkts_port;
- u64 rx_fcs_err_pkts_port;
- u64 rx_app_good_pkts_port;
- u64 rx_app_bad_pkts_port;
- u64 rx_unfilter_pkts_port;
-};
-
-struct mag_cmd_port_stats_info {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 rsvd0[3];
-};
-
-struct mag_cmd_get_port_stat {
- struct mgmt_msg_head head;
-
- struct mag_cmd_port_stats counter;
- u64 rsvd1[15];
-};
-
-struct mag_cmd_get_pcs_err_cnt {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 rsvd0[3];
-
- u32 pcs_err_cnt;
-};
-
-struct mag_cmd_get_mag_cnt {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 len;
- u8 rsvd0[2];
-
- u32 mag_csr[128];
-};
-
-struct mag_cmd_dump_antrain_info {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 len;
- u8 rsvd0[2];
-
- u32 antrain_csr[256];
-};
-
-#define MAG_SFP_PORT_NUM 24
-struct mag_cmd_sfp_temp_in_info {
- struct mgmt_msg_head head; /* 8B */
- u8 opt_type; /* 0:read operation 1:cfg operation */
- u8 rsv[3];
- s32 max_temp; /* Chip optical module threshold */
- s32 min_temp; /* Chip optical module threshold */
-};
-
-struct mag_cmd_sfp_temp_out_info {
- struct mgmt_msg_head head; /* 8B */
- s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
- s32 max_temp; /* Chip optical module threshold */
- s32 min_temp; /* Chip optical module threshold */
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
new file mode 100644
index 0000000..e77d7d5
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
@@ -0,0 +1,1143 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+
+#ifndef MAG_MPU_CMD_DEFS_H
+#define MAG_MPU_CMD_DEFS_H
+
+#include "mpu_cmd_base_defs.h"
+
+/* serdes cmd struct define */
+#define CMD_ARRAY_BUF_SIZE 64
+#define SERDES_CMD_DATA_BUF_SIZE 512
+#define RATE_MBPS_TO_GBPS 1000
+struct serdes_in_info {
+ u32 chip_id : 16;
+ u32 macro_id : 16;
+ u32 start_sds_id : 16;
+ u32 sds_num : 16;
+
+ u32 cmd_type : 8; /* reserved for iotype */
+ u32 sub_cmd : 8;
+ u32 rw : 1; /* 0: read, 1: write */
+ u32 rsvd : 15;
+
+ u32 val;
+ union {
+ char field[CMD_ARRAY_BUF_SIZE];
+ u32 addr;
+ u8 *ex_param;
+ };
+};
+
+struct serdes_out_info {
+ u32 str_len; /* out_str length */
+ u32 result_offset;
+ u32 type; /* 0:data; 1:string */
+ char out_str[SERDES_CMD_DATA_BUF_SIZE];
+};
+
+struct serdes_cmd_in {
+ struct mgmt_msg_head head;
+
+ struct serdes_in_info serdes_in;
+};
+
+struct serdes_cmd_out {
+ struct mgmt_msg_head head;
+
+ struct serdes_out_info serdes_out;
+};
+
+enum mag_cmd_port_speed {
+ PORT_SPEED_NOT_SET = 0,
+ PORT_SPEED_10MB = 1,
+ PORT_SPEED_100MB = 2,
+ PORT_SPEED_1GB = 3,
+ PORT_SPEED_10GB = 4,
+ PORT_SPEED_25GB = 5,
+ PORT_SPEED_40GB = 6,
+ PORT_SPEED_50GB = 7,
+ PORT_SPEED_100GB = 8,
+ PORT_SPEED_200GB = 9,
+ PORT_SPEED_UNKNOWN
+};
+
+enum mag_cmd_port_an {
+ PORT_AN_NOT_SET = 0,
+ PORT_CFG_AN_ON = 1,
+ PORT_CFG_AN_OFF = 2
+};
+
+enum mag_cmd_port_adapt {
+ PORT_ADAPT_NOT_SET = 0,
+ PORT_CFG_ADAPT_ON = 1,
+ PORT_CFG_ADAPT_OFF = 2
+};
+
+enum mag_cmd_port_sriov {
+ PORT_SRIOV_NOT_SET = 0,
+ PORT_CFG_SRIOV_ON = 1,
+ PORT_CFG_SRIOV_OFF = 2
+};
+
+enum mag_cmd_port_fec {
+ PORT_FEC_NOT_SET = 0,
+ PORT_FEC_RSFEC = 1,
+ PORT_FEC_BASEFEC = 2,
+ PORT_FEC_NOFEC = 3,
+ PORT_FEC_LLRSFEC = 4,
+ PORT_FEC_AUTO = 5
+};
+
+enum mag_cmd_port_lanes {
+ PORT_LANES_NOT_SET = 0,
+ PORT_LANES_X1 = 1,
+ PORT_LANES_X2 = 2,
+ PORT_LANES_X4 = 4,
+ PORT_LANES_X8 = 8 /* reserved for future use */
+};
+
+enum mag_cmd_port_duplex {
+ PORT_DUPLEX_HALF = 0,
+ PORT_DUPLEX_FULL = 1
+};
+
+enum mag_cmd_wire_node {
+ WIRE_NODE_UNDEF = 0,
+ CABLE_10G = 1,
+ FIBER_10G = 2,
+ CABLE_25G = 3,
+ FIBER_25G = 4,
+ CABLE_40G = 5,
+ FIBER_40G = 6,
+ CABLE_50G = 7,
+ FIBER_50G = 8,
+ CABLE_100G = 9,
+ FIBER_100G = 10,
+ CABLE_200G = 11,
+ FIBER_200G = 12,
+ WIRE_NODE_NUM
+};
+
+enum mag_cmd_cnt_type {
+ MAG_RX_RSFEC_DEC_CW_CNT = 0,
+ MAG_RX_RSFEC_CORR_CW_CNT = 1,
+ MAG_RX_RSFEC_UNCORR_CW_CNT = 2,
+ MAG_RX_PCS_BER_CNT = 3,
+ MAG_RX_PCS_ERR_BLOCK_CNT = 4,
+ MAG_RX_PCS_E_BLK_CNT = 5,
+ MAG_RX_PCS_DEC_ERR_BLK_CNT = 6,
+ MAG_RX_PCS_LANE_BIP_ERR_CNT = 7,
+ MAG_RX_RSFEC_ERR_CW_CNT = 8,
+ MAG_CNT_NUM
+};
+
+/* mag_cmd_set_port_cfg config bitmap */
+#define MAG_CMD_SET_SPEED 0x1
+#define MAG_CMD_SET_AUTONEG 0x2
+#define MAG_CMD_SET_FEC 0x4
+#define MAG_CMD_SET_LANES 0x8
+struct mag_cmd_set_port_cfg {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd0[3];
+
+ u32 config_bitmap;
+ u8 speed;
+ u8 autoneg;
+ u8 fec;
+ u8 lanes;
+ u8 rsvd1[20];
+};
+
+/* mag supported/advertised link mode bitmap */
+enum mag_cmd_link_mode {
+ LINK_MODE_GE = 0,
+ LINK_MODE_10GE_BASE_R = 1,
+ LINK_MODE_25GE_BASE_R = 2,
+ LINK_MODE_40GE_BASE_R4 = 3,
+ LINK_MODE_50GE_BASE_R = 4,
+ LINK_MODE_50GE_BASE_R2 = 5,
+ LINK_MODE_100GE_BASE_R = 6,
+ LINK_MODE_100GE_BASE_R2 = 7,
+ LINK_MODE_100GE_BASE_R4 = 8,
+ LINK_MODE_200GE_BASE_R2 = 9,
+ LINK_MODE_200GE_BASE_R4 = 10,
+ LINK_MODE_MAX_NUMBERS,
+
+ LINK_MODE_UNKNOWN = 0xFFFF
+};
+
+#define LINK_MODE_GE_BIT 0x1u
+#define LINK_MODE_10GE_BASE_R_BIT 0x2u
+#define LINK_MODE_25GE_BASE_R_BIT 0x4u
+#define LINK_MODE_40GE_BASE_R4_BIT 0x8u
+#define LINK_MODE_50GE_BASE_R_BIT 0x10u
+#define LINK_MODE_50GE_BASE_R2_BIT 0x20u
+#define LINK_MODE_100GE_BASE_R_BIT 0x40u
+#define LINK_MODE_100GE_BASE_R2_BIT 0x80u
+#define LINK_MODE_100GE_BASE_R4_BIT 0x100u
+#define LINK_MODE_200GE_BASE_R2_BIT 0x200u
+#define LINK_MODE_200GE_BASE_R4_BIT 0x400u
+
+#define CABLE_10GE_BASE_R_BIT LINK_MODE_10GE_BASE_R_BIT
+#define CABLE_25GE_BASE_R_BIT (LINK_MODE_25GE_BASE_R_BIT | LINK_MODE_10GE_BASE_R_BIT)
+#define CABLE_40GE_BASE_R4_BIT LINK_MODE_40GE_BASE_R4_BIT
+#define CABLE_50GE_BASE_R_BIT (LINK_MODE_50GE_BASE_R_BIT | LINK_MODE_25GE_BASE_R_BIT | \
+ LINK_MODE_10GE_BASE_R_BIT)
+#define CABLE_50GE_BASE_R2_BIT LINK_MODE_50GE_BASE_R2_BIT
+#define CABLE_100GE_BASE_R2_BIT (LINK_MODE_100GE_BASE_R2_BIT | LINK_MODE_50GE_BASE_R2_BIT)
+#define CABLE_100GE_BASE_R4_BIT (LINK_MODE_100GE_BASE_R4_BIT | LINK_MODE_40GE_BASE_R4_BIT)
+#define CABLE_200GE_BASE_R4_BIT (LINK_MODE_200GE_BASE_R4_BIT | LINK_MODE_100GE_BASE_R4_BIT | \
+ LINK_MODE_40GE_BASE_R4_BIT)
+
+struct mag_cmd_get_port_info {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd0[3];
+
+ u8 wire_type;
+ u8 an_support;
+ u8 an_en;
+ u8 duplex;
+
+ u8 speed;
+ u8 fec;
+ u8 lanes;
+ u8 rsvd1;
+
+ u32 supported_mode;
+ u32 advertised_mode;
+ u32 supported_fec_mode;
+ u16 bond_speed;
+ u8 rsvd2[2];
+};
+
+#define MAG_CMD_OPCODE_GET 0
+#define MAG_CMD_OPCODE_SET 1
+struct mag_cmd_set_port_adapt {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 opcode; /* 0:get adapt info 1:set adapt */
+ u8 enable;
+ u8 rsvd0;
+ u32 speed_mode;
+ u32 rsvd1[3];
+};
+
+#define MAG_CMD_LP_MODE_SDS_S_TX2RX 1
+#define MAG_CMD_LP_MODE_SDS_P_RX2TX 2
+#define MAG_CMD_LP_MODE_SDS_P_TX2RX 3
+#define MAG_CMD_LP_MODE_MAC_RX2TX 4
+#define MAG_CMD_LP_MODE_MAC_TX2RX 5
+#define MAG_CMD_LP_MODE_TXDP2RXDP 6
+struct mag_cmd_cfg_loopback_mode {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 opcode; /* 0:get loopback mode 1:set loopback mode */
+ u8 lp_mode;
+ u8 lp_en; /* 0:disable 1:enable */
+
+ u32 rsvd0[2];
+};
+
+#define MAG_CMD_PORT_DISABLE 0x0
+#define MAG_CMD_TX_ENABLE 0x1
+#define MAG_CMD_RX_ENABLE 0x2
+/* the physical port is disable only when all pf of the port are set to down,
+ * if any pf is enable, the port is enable
+ */
+struct mag_cmd_set_port_enable {
+ struct mgmt_msg_head head;
+
+ u16 function_id; /* function_id should not more than the max support pf_id(32) */
+ u16 rsvd0;
+
+ u8 state; /* bitmap bit0:tx_en bit1:rx_en */
+ u8 rsvd1[3];
+};
+
+struct mag_cmd_get_port_enable {
+ struct mgmt_msg_head head;
+
+ u8 port;
+ u8 state; /* bitmap bit0:tx_en bit1:rx_en */
+ u8 rsvd0[2];
+};
+
+#define PMA_FOLLOW_DEFAULT 0x0
+#define PMA_FOLLOW_ENABLE 0x1
+#define PMA_FOLLOW_DISABLE 0x2
+#define PMA_FOLLOW_GET 0x4
+/* the physical port disable link follow only when all pf of the port are set to follow disable */
+struct mag_cmd_set_link_follow {
+ struct mgmt_msg_head head;
+
+ u16 function_id; /* function_id should not more than the max support pf_id(32) */
+ u16 rsvd0;
+
+ u8 follow;
+ u8 rsvd1[3];
+};
+
+/* firmware also use this cmd report link event to driver */
+struct mag_cmd_get_link_status {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 status; /* 0:link down 1:link up */
+ u8 rsvd0[2];
+};
+
+/* firmware also use this cmd report bond event to driver */
+struct mag_cmd_get_bond_status {
+ struct mgmt_msg_head head;
+
+ u8 status; /* 0:bond down 1:bond up */
+ u8 rsvd0[3];
+};
+
+struct mag_cmd_set_pma_enable {
+ struct mgmt_msg_head head;
+
+ u16 function_id; /* function_id should not more than the max support pf_id(32) */
+ u16 enable;
+};
+
+struct mag_cmd_cfg_an_type {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 opcode; /* 0:get an type 1:set an type */
+ u8 rsvd0[2];
+
+ u32 an_type; /* 0:ieee 1:25G/50 eth consortium */
+};
+
+struct mag_cmd_get_link_time {
+ struct mgmt_msg_head head;
+ u8 port_id;
+ u8 rsvd0[3];
+
+ u32 link_up_begin;
+ u32 link_up_end;
+ u32 link_down_begin;
+ u32 link_down_end;
+};
+
+struct mag_cmd_cfg_fec_mode {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 opcode; /* 0:get fec mode 1:set fec mode */
+ u8 advertised_fec;
+ u8 supported_fec;
+};
+
+/* speed */
+#define PANGEA_ADAPT_10G_BITMAP 0xd
+#define PANGEA_ADAPT_25G_BITMAP 0x72
+#define PANGEA_ADAPT_40G_BITMAP 0x680
+#define PANGEA_ADAPT_100G_BITMAP 0x1900
+
+/* speed and fec */
+#define PANGEA_10G_NO_BITMAP 0x8
+#define PANGEA_10G_BASE_BITMAP 0x4
+#define PANGEA_25G_NO_BITMAP 0x10
+#define PANGEA_25G_BASE_BITMAP 0x20
+#define PANGEA_25G_RS_BITMAP 0x40
+#define PANGEA_40G_NO_BITMAP 0x400
+#define PANGEA_40G_BASE_BITMAP 0x200
+#define PANGEA_100G_NO_BITMAP 0x800
+#define PANGEA_100G_RS_BITMAP 0x1000
+
+/* adapt or fec */
+#define PANGEA_ADAPT_ADAPT_BITMAP 0x183
+#define PANGEA_ADAPT_NO_BITMAP 0xc18
+#define PANGEA_ADAPT_BASE_BITMAP 0x224
+#define PANGEA_ADAPT_RS_BITMAP 0x1040
+
+/* default cfg */
+#define PANGEA_ADAPT_CFG_10G_CR 0x200d
+#define PANGEA_ADAPT_CFG_10G_SRLR 0xd
+#define PANGEA_ADAPT_CFG_25G_CR 0x207f
+#define PANGEA_ADAPT_CFG_25G_SRLR 0x72
+#define PANGEA_ADAPT_CFG_40G_CR4 0x2680
+#define PANGEA_ADAPT_CFG_40G_SRLR4 0x680
+#define PANGEA_ADAPT_CFG_100G_CR4 0x3f80
+#define PANGEA_ADAPT_CFG_100G_SRLR4 0x1900
+
+union pangea_adapt_bitmap_u {
+ struct {
+ u32 adapt_10g : 1; /* [0] adapt_10g */
+ u32 adapt_25g : 1; /* [1] adapt_25g */
+ u32 base_10g : 1; /* [2] base_10g */
+ u32 no_10g : 1; /* [3] no_10g */
+ u32 no_25g : 1; /* [4] no_25g */
+ u32 base_25g : 1; /* [5] base_25g */
+ u32 rs_25g : 1; /* [6] rs_25g */
+ u32 adapt_40g : 1; /* [7] adapt_40g */
+ u32 adapt_100g : 1; /* [8] adapt_100g */
+ u32 base_40g : 1; /* [9] base_40g */
+ u32 no_40g : 1; /* [10] no_40g */
+ u32 no_100g : 1; /* [11] no_100g */
+ u32 rs_100g : 1; /* [12] rs_100g */
+ u32 auto_neg : 1; /* [13] auto_neg */
+ u32 rsvd0 : 18; /* [31:14] reserved */
+ } bits;
+
+ u32 value;
+};
+
+#define PANGEA_ADAPT_GET 0x0
+#define PANGEA_ADAPT_SET 0x1
+struct mag_cmd_set_pangea_adapt {
+ struct mgmt_msg_head head;
+
+ u16 port_id;
+ u8 opcode; /* 0:get adapt info 1:cfg adapt info */
+ u8 wire_type;
+
+ union pangea_adapt_bitmap_u cfg_bitmap;
+ union pangea_adapt_bitmap_u cur_bitmap;
+ u32 rsvd1[3];
+};
+
+struct mag_cmd_cfg_bios_link_cfg {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 opcode; /* 0:get bios link info 1:set bios link cfg */
+ u8 clear;
+ u8 rsvd0;
+
+ u32 wire_type;
+ u8 an_en;
+ u8 speed;
+ u8 fec;
+ u8 rsvd1;
+ u32 speed_mode;
+ u32 rsvd2[3];
+};
+
+struct mag_cmd_restore_link_cfg {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[7];
+};
+
+struct mag_cmd_activate_bios_link_cfg {
+ struct mgmt_msg_head head;
+
+ u32 rsvd[8];
+};
+
+/* led type */
+enum mag_led_type {
+ MAG_CMD_LED_TYPE_ALARM = 0x0,
+ MAG_CMD_LED_TYPE_LOW_SPEED = 0x1,
+ MAG_CMD_LED_TYPE_HIGH_SPEED = 0x2
+};
+
+/* led mode */
+enum mag_led_mode {
+ MAG_CMD_LED_MODE_DEFAULT = 0x0,
+ MAG_CMD_LED_MODE_FORCE_ON = 0x1,
+ MAG_CMD_LED_MODE_FORCE_OFF = 0x2,
+ MAG_CMD_LED_MODE_FORCE_BLINK_1HZ = 0x3,
+ MAG_CMD_LED_MODE_FORCE_BLINK_2HZ = 0x4,
+ MAG_CMD_LED_MODE_FORCE_BLINK_4HZ = 0x5,
+ MAG_CMD_LED_MODE_1HZ = 0x6,
+ MAG_CMD_LED_MODE_2HZ = 0x7,
+ MAG_CMD_LED_MODE_4HZ = 0x8
+};
+
+/* the led is report alarm when any pf of the port is alram */
+struct mag_cmd_set_led_cfg {
+ struct mgmt_msg_head head;
+
+ u16 function_id;
+ u8 type;
+ u8 mode;
+};
+
+#define XSFP_INFO_MAX_SIZE 640
+/* xsfp wire type, refer to cmis protocol definition */
+enum mag_wire_type {
+ MAG_CMD_WIRE_TYPE_UNKNOWN = 0x0,
+ MAG_CMD_WIRE_TYPE_MM = 0x1,
+ MAG_CMD_WIRE_TYPE_SM = 0x2,
+ MAG_CMD_WIRE_TYPE_COPPER = 0x3,
+ MAG_CMD_WIRE_TYPE_ACC = 0x4,
+ MAG_CMD_WIRE_TYPE_BASET = 0x5,
+ MAG_CMD_WIRE_TYPE_AOC = 0x40,
+ MAG_CMD_WIRE_TYPE_ELECTRIC = 0x41,
+ MAG_CMD_WIRE_TYPE_BACKPLANE = 0x42
+};
+
+struct mag_cmd_get_xsfp_info {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 wire_type;
+ u16 out_len;
+ u32 rsvd;
+ u8 sfp_info[XSFP_INFO_MAX_SIZE];
+};
+
+#define MAG_CMD_XSFP_DISABLE 0x0
+#define MAG_CMD_XSFP_ENABLE 0x1
+/* the sfp is disable only when all pf of the port are set sfp down,
+ * if any pf is enable, the sfp is enable
+ */
+struct mag_cmd_set_xsfp_enable {
+ struct mgmt_msg_head head;
+
+ u32 port_id;
+ u32 status; /* 0:on 1:off */
+};
+
+#define MAG_CMD_XSFP_PRESENT 0x0
+#define MAG_CMD_XSFP_ABSENT 0x1
+struct mag_cmd_get_xsfp_present {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 abs_status; /* 0:present, 1:absent */
+ u8 rsvd[2];
+};
+
+#define MAG_CMD_XSFP_READ 0x0
+#define MAG_CMD_XSFP_WRITE 0x1
+struct mag_cmd_set_xsfp_rw {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 operation; /* 0: read; 1: write */
+ u8 value;
+ u8 rsvd0;
+ u32 devaddr;
+ u32 offset;
+ u32 rsvd1;
+};
+
+struct mag_cmd_cfg_xsfp_temperature {
+ struct mgmt_msg_head head;
+
+ u8 opcode; /* 0:read 1:write */
+ u8 rsvd0[3];
+ s32 max_temp;
+ s32 min_temp;
+};
+
+struct mag_cmd_get_xsfp_temperature {
+ struct mgmt_msg_head head;
+
+ s16 sfp_temp[8];
+ u8 rsvd[32];
+ s32 max_temp;
+ s32 min_temp;
+};
+
+/* xsfp plug event */
+struct mag_cmd_wire_event {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 status; /* 0:present, 1:absent */
+ u8 rsvd[2];
+};
+
+/* link err type definition */
+#define MAG_CMD_ERR_XSFP_UNKNOWN 0x0
+struct mag_cmd_link_err_event {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 link_err_type;
+ u8 rsvd[2];
+};
+
+#define MAG_PARAM_TYPE_DEFAULT_CFG 0x0
+#define MAG_PARAM_TYPE_BIOS_CFG 0x1
+#define MAG_PARAM_TYPE_TOOL_CFG 0x2
+#define MAG_PARAM_TYPE_FINAL_CFG 0x3
+#define MAG_PARAM_TYPE_WIRE_INFO 0x4
+#define MAG_PARAM_TYPE_ADAPT_INFO 0x5
+#define MAG_PARAM_TYPE_MAX_CNT 0x6
+struct param_head {
+ u8 valid_len;
+ u8 info_type;
+ u8 rsvd[2];
+};
+
+struct mag_port_link_param {
+ struct param_head head;
+
+ u8 an;
+ u8 fec;
+ u8 speed;
+ u8 rsvd0;
+
+ u32 used;
+ u32 an_fec_ability;
+ u32 an_speed_ability;
+ u32 an_pause_ability;
+};
+
+struct mag_port_wire_info {
+ struct param_head head;
+
+ u8 status;
+ u8 rsvd0[3];
+
+ u8 wire_type;
+ u8 default_fec;
+ u8 speed;
+ u8 rsvd1;
+ u32 speed_ability;
+};
+
+struct mag_port_adapt_info {
+ struct param_head head;
+
+ u32 adapt_en;
+ u32 flash_adapt;
+ u32 rsvd0[2];
+
+ u32 wire_node;
+ u32 an_en;
+ u32 speed;
+ u32 fec;
+};
+
+struct mag_port_param_info {
+ u8 parameter_cnt;
+ u8 lane_id;
+ u8 lane_num;
+ u8 rsvd0;
+
+ struct mag_port_link_param default_cfg;
+ struct mag_port_link_param bios_cfg;
+ struct mag_port_link_param tool_cfg;
+ struct mag_port_link_param final_cfg;
+
+ struct mag_port_wire_info wire_info;
+ struct mag_port_adapt_info adapt_info;
+};
+
+#define XSFP_VENDOR_NAME_LEN 16
+struct mag_cmd_event_port_info {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 event_type;
+ u8 rsvd0[2];
+
+ u8 vendor_name[XSFP_VENDOR_NAME_LEN];
+ u32 port_type; /* fiber / copper */
+ u32 port_sub_type; /* sr / lr */
+ u32 cable_length; /* 1/3/5m */
+ u8 cable_temp; /* temp */
+ u8 max_speed; /* Maximum rate of an optical module */
+ u8 sfp_type; /* sfp/qsfp/dsfp */
+ u8 rsvd1;
+ u32 power[4]; /* Optical Power */
+
+ u8 an_state;
+ u8 fec;
+ u16 speed;
+
+ u8 gpio_insert; /* 0:present 1:absent */
+ u8 alos;
+ u8 rx_los;
+ u8 pma_ctrl;
+
+ u32 pma_fifo_reg;
+ u32 pma_signal_ok_reg;
+ u32 pcs_64_66b_reg;
+ u32 rf_lf;
+ u8 pcs_link;
+ u8 pcs_mac_link;
+ u8 tx_enable;
+ u8 rx_enable;
+ u32 pcs_err_cnt;
+
+ u8 eq_data[38];
+ u8 rsvd2[2];
+
+ u32 his_link_machine_state;
+ u32 cur_link_machine_state;
+ u8 his_machine_state_data[128];
+ u8 cur_machine_state_data[128];
+ u8 his_machine_state_length;
+ u8 cur_machine_state_length;
+
+ struct mag_port_param_info param_info;
+ u8 rsvd3[360];
+};
+
+struct mag_cmd_rsfec_stats {
+ u32 rx_err_lane_phy;
+};
+
+struct mag_cmd_port_stats {
+ u64 mac_tx_fragment_pkt_num;
+ u64 mac_tx_undersize_pkt_num;
+ u64 mac_tx_undermin_pkt_num;
+ u64 mac_tx_64_oct_pkt_num;
+ u64 mac_tx_65_127_oct_pkt_num;
+ u64 mac_tx_128_255_oct_pkt_num;
+ u64 mac_tx_256_511_oct_pkt_num;
+ u64 mac_tx_512_1023_oct_pkt_num;
+ u64 mac_tx_1024_1518_oct_pkt_num;
+ u64 mac_tx_1519_2047_oct_pkt_num;
+ u64 mac_tx_2048_4095_oct_pkt_num;
+ u64 mac_tx_4096_8191_oct_pkt_num;
+ u64 mac_tx_8192_9216_oct_pkt_num;
+ u64 mac_tx_9217_12287_oct_pkt_num;
+ u64 mac_tx_12288_16383_oct_pkt_num;
+ u64 mac_tx_1519_max_bad_pkt_num;
+ u64 mac_tx_1519_max_good_pkt_num;
+ u64 mac_tx_oversize_pkt_num;
+ u64 mac_tx_jabber_pkt_num;
+ u64 mac_tx_bad_pkt_num;
+ u64 mac_tx_bad_oct_num;
+ u64 mac_tx_good_pkt_num;
+ u64 mac_tx_good_oct_num;
+ u64 mac_tx_total_pkt_num;
+ u64 mac_tx_total_oct_num;
+ u64 mac_tx_uni_pkt_num;
+ u64 mac_tx_multi_pkt_num;
+ u64 mac_tx_broad_pkt_num;
+ u64 mac_tx_pause_num;
+ u64 mac_tx_pfc_pkt_num;
+ u64 mac_tx_pfc_pri0_pkt_num;
+ u64 mac_tx_pfc_pri1_pkt_num;
+ u64 mac_tx_pfc_pri2_pkt_num;
+ u64 mac_tx_pfc_pri3_pkt_num;
+ u64 mac_tx_pfc_pri4_pkt_num;
+ u64 mac_tx_pfc_pri5_pkt_num;
+ u64 mac_tx_pfc_pri6_pkt_num;
+ u64 mac_tx_pfc_pri7_pkt_num;
+ u64 mac_tx_control_pkt_num;
+ u64 mac_tx_err_all_pkt_num;
+ u64 mac_tx_from_app_good_pkt_num;
+ u64 mac_tx_from_app_bad_pkt_num;
+
+ u64 mac_rx_fragment_pkt_num;
+ u64 mac_rx_undersize_pkt_num;
+ u64 mac_rx_undermin_pkt_num;
+ u64 mac_rx_64_oct_pkt_num;
+ u64 mac_rx_65_127_oct_pkt_num;
+ u64 mac_rx_128_255_oct_pkt_num;
+ u64 mac_rx_256_511_oct_pkt_num;
+ u64 mac_rx_512_1023_oct_pkt_num;
+ u64 mac_rx_1024_1518_oct_pkt_num;
+ u64 mac_rx_1519_2047_oct_pkt_num;
+ u64 mac_rx_2048_4095_oct_pkt_num;
+ u64 mac_rx_4096_8191_oct_pkt_num;
+ u64 mac_rx_8192_9216_oct_pkt_num;
+ u64 mac_rx_9217_12287_oct_pkt_num;
+ u64 mac_rx_12288_16383_oct_pkt_num;
+ u64 mac_rx_1519_max_bad_pkt_num;
+ u64 mac_rx_1519_max_good_pkt_num;
+ u64 mac_rx_oversize_pkt_num;
+ u64 mac_rx_jabber_pkt_num;
+ u64 mac_rx_bad_pkt_num;
+ u64 mac_rx_bad_oct_num;
+ u64 mac_rx_good_pkt_num;
+ u64 mac_rx_good_oct_num;
+ u64 mac_rx_total_pkt_num;
+ u64 mac_rx_total_oct_num;
+ u64 mac_rx_uni_pkt_num;
+ u64 mac_rx_multi_pkt_num;
+ u64 mac_rx_broad_pkt_num;
+ u64 mac_rx_pause_num;
+ u64 mac_rx_pfc_pkt_num;
+ u64 mac_rx_pfc_pri0_pkt_num;
+ u64 mac_rx_pfc_pri1_pkt_num;
+ u64 mac_rx_pfc_pri2_pkt_num;
+ u64 mac_rx_pfc_pri3_pkt_num;
+ u64 mac_rx_pfc_pri4_pkt_num;
+ u64 mac_rx_pfc_pri5_pkt_num;
+ u64 mac_rx_pfc_pri6_pkt_num;
+ u64 mac_rx_pfc_pri7_pkt_num;
+ u64 mac_rx_control_pkt_num;
+ u64 mac_rx_sym_err_pkt_num;
+ u64 mac_rx_fcs_err_pkt_num;
+ u64 mac_rx_send_app_good_pkt_num;
+ u64 mac_rx_send_app_bad_pkt_num;
+ u64 mac_rx_unfilter_pkt_num;
+};
+
+struct mag_port_stats {
+ u64 tx_frag_pkts_port;
+ u64 tx_under_frame_pkts_port;
+ u64 tx_under_min_pkts_port;
+ u64 tx_64_oct_pkts_port;
+ u64 tx_127_oct_pkts_port;
+ u64 tx_255_oct_pkts_port;
+ u64 tx_511_oct_pkts_port;
+ u64 tx_1023_oct_pkts_port;
+ u64 tx_1518_oct_pkts_port;
+ u64 tx_2047_oct_pkts_port;
+ u64 tx_4095_oct_pkts_port;
+ u64 tx_8191_oct_pkts_port;
+ u64 tx_9216_oct_pkts_port;
+ u64 tx_12287_oct_pkts_port;
+ u64 tx_16383_oct_pkts_port;
+ u64 tx_1519_to_max_bad_pkts_port;
+ u64 tx_1519_to_max_good_pkts_port;
+ u64 tx_oversize_pkts_port;
+ u64 tx_jabber_pkts_port;
+ u64 tx_bad_pkts_port;
+ u64 tx_bad_octs_port;
+ u64 tx_good_pkts_port;
+ u64 tx_good_octs_port;
+ u64 tx_total_pkts_port;
+ u64 tx_total_octs_port;
+ u64 tx_unicast_pkts_port;
+ u64 tx_multicast_pkts_port;
+ u64 tx_broadcast_pkts_port;
+ u64 tx_pause_pkts_port;
+ u64 tx_pfc_pkts_port;
+ u64 tx_pri_0_pkts_port;
+ u64 tx_pri_1_pkts_port;
+ u64 tx_pri_2_pkts_port;
+ u64 tx_pri_3_pkts_port;
+ u64 tx_pri_4_pkts_port;
+ u64 tx_pri_5_pkts_port;
+ u64 tx_pri_6_pkts_port;
+ u64 tx_pri_7_pkts_port;
+ u64 tx_mac_control_pkts_port;
+ u64 tx_y1731_pkts_port;
+ u64 tx_1588_pkts_port;
+ u64 tx_error_pkts_port;
+ u64 tx_app_good_pkts_port;
+ u64 tx_app_bad_pkts_port;
+ u64 rx_frag_pkts_port;
+ u64 rx_under_frame_pkts_port;
+ u64 rx_under_min_pkts_port;
+ u64 rx_64_oct_pkts_port;
+ u64 rx_127_oct_pkts_port;
+ u64 rx_255_oct_pkts_port;
+ u64 rx_511_oct_pkts_port;
+ u64 rx_1023_oct_pkts_port;
+ u64 rx_1518_oct_pkts_port;
+ u64 rx_2047_oct_pkts_port;
+ u64 rx_4095_oct_pkts_port;
+ u64 rx_8191_oct_pkts_port;
+ u64 rx_9216_oct_pkts_port;
+ u64 rx_12287_oct_pkts_port;
+ u64 rx_16383_oct_pkts_port;
+ u64 rx_1519_to_max_bad_pkts_port;
+ u64 rx_1519_to_max_good_pkts_port;
+ u64 rx_oversize_pkts_port;
+ u64 rx_jabber_pkts_port;
+ u64 rx_bad_pkts_port;
+ u64 rx_bad_octs_port;
+ u64 rx_good_pkts_port;
+ u64 rx_good_octs_port;
+ u64 rx_total_pkts_port;
+ u64 rx_total_octs_port;
+ u64 rx_unicast_pkts_port;
+ u64 rx_multicast_pkts_port;
+ u64 rx_broadcast_pkts_port;
+ u64 rx_pause_pkts_port;
+ u64 rx_pfc_pkts_port;
+ u64 rx_pri_0_pkts_port;
+ u64 rx_pri_1_pkts_port;
+ u64 rx_pri_2_pkts_port;
+ u64 rx_pri_3_pkts_port;
+ u64 rx_pri_4_pkts_port;
+ u64 rx_pri_5_pkts_port;
+ u64 rx_pri_6_pkts_port;
+ u64 rx_pri_7_pkts_port;
+ u64 rx_mac_control_pkts_port;
+ u64 rx_y1731_pkts_port;
+ u64 rx_sym_err_pkts_port;
+ u64 rx_fcs_err_pkts_port;
+ u64 rx_app_good_pkts_port;
+ u64 rx_app_bad_pkts_port;
+ u64 rx_unfilter_pkts_port;
+};
+
+struct mag_cmd_port_stats_info {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd0[3];
+};
+
+struct mag_cmd_get_port_stat {
+ struct mgmt_msg_head head;
+
+ struct mag_cmd_port_stats counter;
+ u64 rsvd1[15];
+};
+
+struct mag_cmd_get_pcs_err_cnt {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd0[3];
+
+ u32 pcs_err_cnt;
+};
+
+struct mag_cmd_get_mag_cnt {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 len;
+ u8 rsvd0[2];
+
+ u32 mag_csr[128];
+};
+
+struct mag_cmd_dump_antrain_info {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 len;
+ u8 rsvd0[2];
+
+ u32 antrain_csr[256];
+};
+
+#define MAG_SFP_PORT_NUM 24
+struct mag_cmd_sfp_temp_in_info {
+ struct mgmt_msg_head head; /* 8B */
+ u8 opt_type; /* 0:read operation 1:cfg operation */
+ u8 rsv[3];
+ s32 max_temp; /* Chip optical module threshold */
+ s32 min_temp; /* Chip optical module threshold */
+};
+
+struct mag_cmd_sfp_temp_out_info {
+ struct mgmt_msg_head head; /* 8B */
+ s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
+ s32 max_temp; /* Chip optical module threshold */
+ s32 min_temp; /* Chip optical module threshold */
+};
+
+#define XSFP_CMIS_PARSE_PAGE_NUM 6
+#define XSFP_CMIS_INFO_MAX_SIZE 1536
+#define QSFP_CMIS_PAGE_SIZE 128
+#define QSFP_CMIS_MAX_CHANNEL_NUM 0x8
+
+/* Lower: Control and Essentials, Upper: Administrative Information */
+#define QSFP_CMIS_PAGE_00H 0x00
+/* Advertising */
+#define QSFP_CMIS_PAGE_01H 0x01
+/* Module and lane Thresholds */
+#define QSFP_CMIS_PAGE_02H 0x02
+/* User EEPROM */
+#define QSFP_CMIS_PAGE_03H 0x03
+/* Laser Capabilities Advertising (Page 04h, Optional) */
+#define QSFP_CMIS_PAGE_04H 0x04
+#define QSFP_CMIS_PAGE_05H 0x05
+/* Lane and Data Path Control */
+#define QSFP_CMIS_PAGE_10H 0x10
+/* Lane Status */
+#define QSFP_CMIS_PAGE_11H 0x11
+#define QSFP_CMIS_PAGE_12H 0x12
+
+#define MGMT_TLV_U8_SIZE 1
+#define MGMT_TLV_U16_SIZE 2
+#define MGMT_TLV_U32_SIZE 4
+
+#define MGMT_TLV_GET_U8(addr) (*((u8 *)(void *)(addr)))
+#define MGMT_TLV_SET_U8(addr, value) \
+ ((*((u8 *)(void *)(addr))) = ((u8)(value)))
+
+#define MGMT_TLV_GET_U16(addr) (*((u16 *)(void *)(addr)))
+#define MGMT_TLV_SET_U16(addr, value) \
+ ((*((u16 *)(void *)(addr))) = ((u16)(value)))
+
+#define MGMT_TLV_GET_U32(addr) (*((u32 *)(void *)(addr)))
+#define MGMT_TLV_SET_U32(addr, value) \
+ ((*((u32 *)(void *)(addr))) = ((u32)(value)))
+
+#define MGMT_TLV_TYPE_END 0xFFFF
+
+enum mag_xsfp_type {
+ MAG_XSFP_TYPE_PAGE = 0x01,
+ MAG_XSFP_TYPE_WIRE_TYPE = 0x02,
+ MAG_XSFP_TYPE_END = MGMT_TLV_TYPE_END
+};
+
+struct qsfp_cmis_lower_page_00_s {
+ u8 resv0[14];
+ u8 temperature_msb;
+ u8 temperature_lsb;
+ u8 volt_supply[2];
+ u8 resv1[67];
+ u8 media_type;
+ u8 electrical_interface_id;
+ u8 media_interface_id;
+ u8 lane_count;
+ u8 resv2[39];
+};
+
+struct qsfp_cmis_upper_page_00_s {
+ u8 identifier;
+ u8 vendor_name[16];
+ u8 vendor_oui[3];
+ u8 vendor_pn[16];
+ u8 vendor_rev[2];
+ u8 vendor_sn[16];
+ u8 date_code[8];
+ u8 clei_code[10];
+ u8 power_character[2];
+ u8 cable_len;
+ u8 connector;
+ u8 copper_cable_attenuation[6];
+ u8 near_end_implementation;
+ u8 far_end_config;
+ u8 media_technology;
+ u8 resv0[43];
+};
+
+struct qsfp_cmis_upper_page_01_s {
+ u8 firmware_rev[2];
+ u8 hardware_rev[2];
+ u8 smf_len_km;
+ u8 om5_len;
+ u8 om4_len;
+ u8 om3_len;
+ u8 om2_len;
+ u8 resv0;
+ u8 wavelength[2];
+ u8 wavelength_tolerance[2];
+ u8 pages_implement;
+ u8 resv1[16];
+ u8 monitor_implement[2];
+ u8 resv2[95];
+};
+
+struct qsfp_cmis_upper_page_02_s {
+ u8 temperature_high_alarm[2];
+ u8 temperature_low_alarm[2];
+ u8 temperature_high_warn[2];
+ u8 temperature_low_warn[2];
+ u8 volt_high_alarm[2];
+ u8 volt_low_alarm[2];
+ u8 volt_high_warn[2];
+ u8 volt_low_warn[2];
+ u8 resv0[32];
+ u8 tx_power_high_alarm[2];
+ u8 tx_power_low_alarm[2];
+ u8 tx_power_high_warn[2];
+ u8 tx_power_low_warn[2];
+ u8 tx_bias_high_alarm[2];
+ u8 tx_bias_low_alarm[2];
+ u8 tx_bias_high_warn[2];
+ u8 tx_bias_low_warn[2];
+ u8 rx_power_high_alarm[2];
+ u8 rx_power_low_alarm[2];
+ u8 rx_power_high_warn[2];
+ u8 rx_power_low_warn[2];
+ u8 resv1[56];
+};
+
+struct qsfp_cmis_upper_page_03_s {
+ u8 resv0[QSFP_CMIS_PAGE_SIZE]; /* Reg 128-255: Upper Memory: Page 03H */
+};
+
+struct qsfp_cmis_upper_page_10_s {
+ u8 resv0[2]; /* Reg 128-129: Upper Memory: Page 10H */
+ u8 tx_disable; /* Reg 130: Tx disable, 0b=enabled, 1b=disabled */
+ u8 resv1[125]; /* Reg 131-255 */
+};
+
+struct qsfp_cmis_upper_page_11_s {
+ u8 resv0[7];
+ u8 tx_fault;
+ u8 tx_los;
+ u8 resv1[10];
+ u8 rx_los;
+ u8 resv2[6];
+ u8 tx_power[16];
+ u8 tx_bias[16];
+ u8 rx_power[16];
+ u8 resv3[54];
+};
+
+struct qsfp_cmis_info_s {
+ struct qsfp_cmis_lower_page_00_s lower_page_00;
+ struct qsfp_cmis_upper_page_00_s upper_page_00;
+ struct qsfp_cmis_upper_page_01_s upper_page_01;
+ struct qsfp_cmis_upper_page_02_s upper_page_02;
+ struct qsfp_cmis_upper_page_10_s upper_page_10;
+ struct qsfp_cmis_upper_page_11_s upper_page_11;
+};
+
+struct qsfp_cmis_comm_power_s {
+ u32 chl_power[QSFP_CMIS_MAX_CHANNEL_NUM];
+};
+
+struct qsfp_cmis_wire_info_s {
+ struct qsfp_cmis_comm_power_s rx_power;
+ u8 rx_los;
+ u8 resv0[3];
+};
+
+struct mgmt_tlv_info {
+ u16 type;
+ u16 length;
+ u8 value[];
+};
+
+struct mag_cmd_set_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 tlv_buf[];
+};
+
+struct mag_cmd_set_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+};
+
+struct mag_cmd_get_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd;
+ u16 rsp_buf_len;
+};
+
+struct mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[];
+};
+
+
+struct parse_tlv_info {
+ u8 tlv_page_info[XSFP_CMIS_INFO_MAX_SIZE + 1];
+ u32 tlv_page_info_len;
+ u32 tlv_page_num[XSFP_CMIS_PARSE_PAGE_NUM];
+ u32 wire_type;
+ u8 id;
+};
+
+struct drv_mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[XSFP_CMIS_INFO_MAX_SIZE];
+};
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h b/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
deleted file mode 100644
index 257bf67..0000000
--- a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : mgmt_msg_base.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef MGMT_MSG_BASE_H
-#define MGMT_MSG_BASE_H
-
-#define MGMT_MSG_CMD_OP_SET 1
-#define MGMT_MSG_CMD_OP_GET 0
-
-#define MGMT_MSG_CMD_OP_START 1
-#define MGMT_MSG_CMD_OP_STOP 0
-
-struct mgmt_msg_head {
- u8 status;
- u8 version;
- u8 rsvd0[6];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
deleted file mode 100644
index 9fb4232..0000000
--- a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2001-2021, Huawei Tech. Co., Ltd.
- * File Name : nic_cfg_comm.h
- * Version : Initial Draft
- * Description : nic config common header file
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef NIC_CFG_COMM_H
-#define NIC_CFG_COMM_H
-
-/* rss */
-#define HINIC3_RSS_TYPE_VALID_SHIFT 23
-#define HINIC3_RSS_TYPE_TCP_IPV6_EXT_SHIFT 24
-#define HINIC3_RSS_TYPE_IPV6_EXT_SHIFT 25
-#define HINIC3_RSS_TYPE_TCP_IPV6_SHIFT 26
-#define HINIC3_RSS_TYPE_IPV6_SHIFT 27
-#define HINIC3_RSS_TYPE_TCP_IPV4_SHIFT 28
-#define HINIC3_RSS_TYPE_IPV4_SHIFT 29
-#define HINIC3_RSS_TYPE_UDP_IPV6_SHIFT 30
-#define HINIC3_RSS_TYPE_UDP_IPV4_SHIFT 31
-
-#define HINIC3_RSS_TYPE_SET(val, member) (((u32)(val) & 0x1) << HINIC3_RSS_TYPE_##member##_SHIFT)
-#define HINIC3_RSS_TYPE_GET(val, member) (((u32)(val) >> HINIC3_RSS_TYPE_##member##_SHIFT) & 0x1)
-
-enum nic_rss_hash_type {
- NIC_RSS_HASH_TYPE_XOR = 0,
- NIC_RSS_HASH_TYPE_TOEP,
-
- NIC_RSS_HASH_TYPE_MAX /* MUST BE THE LAST ONE */
-};
-
-#define NIC_RSS_INDIR_SIZE 256
-#define NIC_RSS_KEY_SIZE 40
-
-/* *
- * Definition of the NIC receiving mode
- */
-#define NIC_RX_MODE_UC 0x01
-#define NIC_RX_MODE_MC 0x02
-#define NIC_RX_MODE_BC 0x04
-#define NIC_RX_MODE_MC_ALL 0x08
-#define NIC_RX_MODE_PROMISC 0x10
-
-/* IEEE 802.1Qaz std */
-#define NIC_DCB_COS_MAX 0x8
-#define NIC_DCB_UP_MAX 0x8
-#define NIC_DCB_TC_MAX 0x8
-#define NIC_DCB_PG_MAX 0x8
-#define NIC_DCB_TSA_SP 0x0
-#define NIC_DCB_TSA_CBS 0x1 /* hi1822 do NOT support */
-#define NIC_DCB_TSA_ETS 0x2
-#define NIC_DCB_DSCP_NUM 0x8
-#define NIC_DCB_IP_PRI_MAX 0x40
-
-#define NIC_DCB_PRIO_DWRR 0x0
-#define NIC_DCB_PRIO_STRICT 0x1
-
-#define NIC_DCB_MAX_PFC_NUM 0x4
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
new file mode 100644
index 0000000..8e0fa89
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
@@ -0,0 +1,174 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
+ * File Name : nic_mpu_cmd.h
+ * Version : Initial Draft
+ * Created : 2019/4/25
+ * Last Modified :
+ * Description : NIC Commands between Driver and MPU
+ * Function List :
+ */
+
+#ifndef NIC_MPU_CMD_H
+#define NIC_MPU_CMD_H
+
+/* Commands between NIC to MPU
+ */
+enum hinic3_nic_cmd {
+ HINIC3_NIC_CMD_VF_REGISTER = 0, /* only for PFD and VFD */
+
+ /* FUNC CFG */
+ HINIC3_NIC_CMD_SET_FUNC_TBL = 5,
+ HINIC3_NIC_CMD_SET_VPORT_ENABLE,
+ HINIC3_NIC_CMD_SET_RX_MODE,
+ HINIC3_NIC_CMD_SQ_CI_ATTR_SET,
+ HINIC3_NIC_CMD_GET_VPORT_STAT,
+ HINIC3_NIC_CMD_CLEAN_VPORT_STAT,
+ HINIC3_NIC_CMD_CLEAR_QP_RESOURCE,
+ HINIC3_NIC_CMD_CFG_FLEX_QUEUE,
+ /* LRO CFG */
+ HINIC3_NIC_CMD_CFG_RX_LRO,
+ HINIC3_NIC_CMD_CFG_LRO_TIMER,
+ HINIC3_NIC_CMD_FEATURE_NEGO,
+ HINIC3_NIC_CMD_CFG_LOCAL_LRO_STATE,
+
+ HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
+ HINIC3_NIC_CMD_SET_FUNC_ER_FWD_ID,
+
+ /** MAC & VLAN CFG & VXLAN CFG */
+ HINIC3_NIC_CMD_GET_MAC = 20,
+ HINIC3_NIC_CMD_SET_MAC,
+ HINIC3_NIC_CMD_DEL_MAC,
+ HINIC3_NIC_CMD_UPDATE_MAC,
+ HINIC3_NIC_CMD_GET_ALL_DEFAULT_MAC,
+
+ HINIC3_NIC_CMD_CFG_FUNC_VLAN,
+ HINIC3_NIC_CMD_SET_VLAN_FILTER_EN,
+ HINIC3_NIC_CMD_SET_RX_VLAN_OFFLOAD,
+ HINIC3_NIC_CMD_SMAC_CHECK_STATE,
+ HINIC3_NIC_CMD_OUTBAND_SET_FUNC_VLAN,
+
+ HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+ HINIC3_NIC_CMD_RX_RATE_CFG,
+ HINIC3_NIC_CMD_WR_ORDERING_CFG,
+
+ /* SR-IOV */
+ HINIC3_NIC_CMD_CFG_VF_VLAN = 40,
+ HINIC3_NIC_CMD_SET_SPOOPCHK_STATE,
+ /* RATE LIMIT */
+ HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
+
+ /* RSS CFG */
+ HINIC3_NIC_CMD_RSS_CFG = 60,
+ HINIC3_NIC_CMD_RSS_TEMP_MGR, /* TODO: delete after implement nego cmd */
+ HINIC3_NIC_CMD_GET_RSS_CTX_TBL, /* TODO: delete: move to ucode cmd */
+ HINIC3_NIC_CMD_CFG_RSS_HASH_KEY,
+ HINIC3_NIC_CMD_CFG_RSS_HASH_ENGINE,
+ HINIC3_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC,
+ /* IP checksum error packets, enable rss quadruple hash */
+ HINIC3_NIC_CMD_IPCS_ERR_RSS_ENABLE_OP = 66,
+ HINIC3_NIC_CMD_GTP_INNER_PARSE_STATUS,
+
+ /* PPA/FDIR */
+ HINIC3_NIC_CMD_ADD_TC_FLOW = 80,
+ HINIC3_NIC_CMD_DEL_TC_FLOW,
+ HINIC3_NIC_CMD_GET_TC_FLOW,
+ HINIC3_NIC_CMD_FLUSH_TCAM,
+ HINIC3_NIC_CMD_CFG_TCAM_BLOCK,
+ HINIC3_NIC_CMD_ENABLE_TCAM,
+ HINIC3_NIC_CMD_GET_TCAM_BLOCK,
+ HINIC3_NIC_CMD_CFG_PPA_TABLE_ID,
+ HINIC3_NIC_CMD_SET_PPA_EN = 88,
+ HINIC3_NIC_CMD_CFG_PPA_MODE,
+ HINIC3_NIC_CMD_CFG_PPA_FLUSH,
+ HINIC3_NIC_CMD_SET_FDIR_STATUS,
+ HINIC3_NIC_CMD_GET_PPA_COUNTER,
+ HINIC3_NIC_CMD_SET_FUNC_FLOW_BIFUR_ENABLE,
+ HINIC3_NIC_CMD_SET_BOND_MASK,
+ HINIC3_NIC_CMD_GET_BLOCK_TC_FLOWS,
+ HINIC3_NIC_CMD_GET_BOND_MASK,
+
+ /* PORT CFG */
+ HINIC3_NIC_CMD_SET_PORT_ENABLE = 100,
+ HINIC3_NIC_CMD_CFG_PAUSE_INFO,
+
+ HINIC3_NIC_CMD_SET_PORT_CAR,
+ HINIC3_NIC_CMD_SET_ER_DROP_PKT,
+
+ HINIC3_NIC_CMD_VF_COS,
+ HINIC3_NIC_CMD_SETUP_COS_MAPPING,
+ HINIC3_NIC_CMD_SET_ETS,
+ HINIC3_NIC_CMD_SET_PFC,
+ HINIC3_NIC_CMD_QOS_ETS,
+ HINIC3_NIC_CMD_QOS_PFC,
+ HINIC3_NIC_CMD_QOS_DCB_STATE,
+ HINIC3_NIC_CMD_QOS_PORT_CFG,
+ HINIC3_NIC_CMD_QOS_MAP_CFG,
+ HINIC3_NIC_CMD_FORCE_PKT_DROP,
+ HINIC3_NIC_CMD_CFG_TX_PROMISC_SKIP = 114,
+ HINIC3_NIC_CMD_SET_PORT_FLOW_BIFUR_ENABLE = 117,
+ HINIC3_NIC_CMD_TX_PAUSE_EXCP_NOTICE = 118,
+ HINIC3_NIC_CMD_INQUIRT_PAUSE_CFG = 119,
+
+ /* MISC */
+ HINIC3_NIC_CMD_BIOS_CFG = 120,
+ HINIC3_NIC_CMD_SET_FIRMWARE_CUSTOM_PACKETS_MSG,
+
+ /* BOND */
+ HINIC3_NIC_CMD_BOND_DEV_CREATE = 134,
+ HINIC3_NIC_CMD_BOND_DEV_DELETE,
+ HINIC3_NIC_CMD_BOND_DEV_OPEN_CLOSE,
+ HINIC3_NIC_CMD_BOND_INFO_GET,
+ HINIC3_NIC_CMD_BOND_ACTIVE_INFO_GET,
+ HINIC3_NIC_CMD_BOND_ACTIVE_NOTICE,
+
+ /* DFX */
+ HINIC3_NIC_CMD_GET_SM_TABLE = 140,
+ HINIC3_NIC_CMD_RD_LINE_TBL,
+
+ HINIC3_NIC_CMD_SET_UCAPTURE_OPT = 160, /* TODO: move to roce */
+ HINIC3_NIC_CMD_SET_VHD_CFG,
+
+ /* OUT OF BAND */
+ HINIC3_NIC_CMD_GET_OUTBAND_CFG = 170,
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+
+ /* TODO: move to HILINK */
+ HINIC3_NIC_CMD_GET_PORT_STAT = 200,
+ HINIC3_NIC_CMD_CLEAN_PORT_STAT,
+ HINIC3_NIC_CMD_CFG_LOOPBACK_MODE,
+ HINIC3_NIC_CMD_GET_SFP_QSFP_INFO,
+ HINIC3_NIC_CMD_SET_SFP_STATUS,
+ HINIC3_NIC_CMD_GET_LIGHT_MODULE_ABS,
+ HINIC3_NIC_CMD_GET_LINK_INFO,
+ HINIC3_NIC_CMD_CFG_AN_TYPE,
+ HINIC3_NIC_CMD_GET_PORT_INFO,
+ HINIC3_NIC_CMD_SET_LINK_SETTINGS,
+ HINIC3_NIC_CMD_ACTIVATE_BIOS_LINK_CFG,
+ HINIC3_NIC_CMD_RESTORE_LINK_CFG,
+ HINIC3_NIC_CMD_SET_LINK_FOLLOW,
+ HINIC3_NIC_CMD_GET_LINK_STATE,
+ HINIC3_NIC_CMD_LINK_STATUS_REPORT,
+ HINIC3_NIC_CMD_CABLE_PLUG_EVENT,
+ HINIC3_NIC_CMD_LINK_ERR_EVENT,
+ HINIC3_NIC_CMD_SET_LED_STATUS,
+
+ /* mig */
+ HINIC3_NIC_CMD_MIG_SET_CEQ_CTRL = 230,
+ HINIC3_NIC_CMD_MIG_CFG_MSIX_INFO,
+ HINIC3_NIC_CMD_MIG_CFG_FUNC_VAT_TBL,
+ HINIC3_NIC_CMD_MIG_GET_VF_INFO,
+ HINIC3_NIC_CMD_MIG_CHK_MBX_EMPTY,
+ HINIC3_NIC_CMD_MIG_SET_VPORT_ENABLE,
+ HINIC3_NIC_CMD_MIG_CFG_SQ_CI,
+ HINIC3_NIC_CMD_MIG_CFG_RSS_TBL,
+ HINIC3_NIC_CMD_MIG_CFG_MAC_TBL,
+ HINIC3_NIC_CMD_MIG_TMP_SET_CMDQ_CTX,
+
+ HINIC3_OSHR_CMD_ACTIVE_FUNCTION = 240,
+ HINIC3_NIC_CMD_GET_RQ_INFO = 241,
+
+ HINIC3_NIC_CMD_MAX = 256,
+};
+
+#endif /* NIC_MPU_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
new file mode 100644
index 0000000..ee6bf20
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
@@ -0,0 +1,1420 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+
+#ifndef NIC_MPU_CMD_DEFS_H
+#define NIC_MPU_CMD_DEFS_H
+
+#include "nic_cfg_comm.h"
+#include "mpu_cmd_base_defs.h"
+
+#ifndef ETH_ALEN
+#define ETH_ALEN 6
+#endif
+
+#define HINIC3_CMD_OP_SET 1
+#define HINIC3_CMD_OP_GET 0
+
+#define HINIC3_CMD_OP_ADD 1
+#define HINIC3_CMD_OP_DEL 0
+
+#define NIC_TCAM_BLOCK_LARGE_NUM 256
+#define NIC_TCAM_BLOCK_LARGE_SIZE 16
+
+#define TRAFFIC_BIFUR_MODEL_TYPE 2
+
+#define NIC_TCAM_FLOW_BIFUR_FLAG (1 << 0)
+
+#ifndef BIT
+#define BIT(n) (1UL << (n))
+#endif
+
+enum nic_feature_cap {
+ NIC_F_CSUM = BIT(0),
+ NIC_F_SCTP_CRC = BIT(1),
+ NIC_F_TSO = BIT(2),
+ NIC_F_LRO = BIT(3),
+ NIC_F_UFO = BIT(4),
+ NIC_F_RSS = BIT(5),
+ NIC_F_RX_VLAN_FILTER = BIT(6),
+ NIC_F_RX_VLAN_STRIP = BIT(7),
+ NIC_F_TX_VLAN_INSERT = BIT(8),
+ NIC_F_VXLAN_OFFLOAD = BIT(9),
+ NIC_F_IPSEC_OFFLOAD = BIT(10),
+ NIC_F_FDIR = BIT(11),
+ NIC_F_PROMISC = BIT(12),
+ NIC_F_ALLMULTI = BIT(13),
+ NIC_F_XSFP_REPORT = BIT(14),
+ NIC_F_VF_MAC = BIT(15),
+ NIC_F_RATE_LIMIT = BIT(16),
+ NIC_F_RXQ_RECOVERY = BIT(17),
+};
+
+#define NIC_F_ALL_MASK 0x3FFFF /* 使能所有属性 */
+
+struct hinic3_mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+#define NIC_MAX_FEATURE_QWORD 4
+struct hinic3_cmd_feature_nego {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 1: set, 0: get */
+ u8 rsvd;
+ u64 s_feature[NIC_MAX_FEATURE_QWORD];
+};
+
+struct hinic3_port_mac_set {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 rsvd1;
+ u8 mac[ETH_ALEN];
+};
+
+struct hinic3_port_mac_update {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 rsvd1;
+ u8 old_mac[ETH_ALEN];
+ u16 rsvd2;
+ u8 new_mac[ETH_ALEN];
+};
+
+struct hinic3_vport_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 state; /* 0--disable, 1--enable */
+ u8 rsvd2[3];
+};
+
+struct hinic3_port_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 state; /* 0--disable, 1--enable */
+ u8 rsvd2[3];
+};
+
+#define HINIC3_SET_PORT_CAR_PROFILE 0
+#define HINIC3_SET_PORT_CAR_STATE 1
+#define HINIC3_GET_PORT_CAR_LIMIT_SPEED 2
+
+struct hinic3_port_car_info {
+ u32 cir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
+ u32 xir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
+ u32 cbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
+ u32 xbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
+};
+
+struct hinic3_cmd_set_port_car {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode; /* 0--set car profile, 1--set car state */
+ u8 state; /* 0--disable, 1--enable */
+ u8 level;
+
+ struct hinic3_port_car_info car;
+};
+
+struct hinic3_cmd_clear_qp_resource {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_cmd_cache_out_qp_resource {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_port_stats_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_vport_stats {
+ u64 tx_unicast_pkts_vport;
+ u64 tx_unicast_bytes_vport;
+ u64 tx_multicast_pkts_vport;
+ u64 tx_multicast_bytes_vport;
+ u64 tx_broadcast_pkts_vport;
+ u64 tx_broadcast_bytes_vport;
+
+ u64 rx_unicast_pkts_vport;
+ u64 rx_unicast_bytes_vport;
+ u64 rx_multicast_pkts_vport;
+ u64 rx_multicast_bytes_vport;
+ u64 rx_broadcast_pkts_vport;
+ u64 rx_broadcast_bytes_vport;
+
+ u64 tx_discard_vport;
+ u64 rx_discard_vport;
+ u64 tx_err_vport;
+ u64 rx_err_vport;
+};
+
+struct hinic3_phy_fpga_port_stats {
+ u64 mac_rx_total_octs_port;
+ u64 mac_tx_total_octs_port;
+ u64 mac_rx_under_frame_pkts_port;
+ u64 mac_rx_frag_pkts_port;
+ u64 mac_rx_64_oct_pkts_port;
+ u64 mac_rx_127_oct_pkts_port;
+ u64 mac_rx_255_oct_pkts_port;
+ u64 mac_rx_511_oct_pkts_port;
+ u64 mac_rx_1023_oct_pkts_port;
+ u64 mac_rx_max_oct_pkts_port;
+ u64 mac_rx_over_oct_pkts_port;
+ u64 mac_tx_64_oct_pkts_port;
+ u64 mac_tx_127_oct_pkts_port;
+ u64 mac_tx_255_oct_pkts_port;
+ u64 mac_tx_511_oct_pkts_port;
+ u64 mac_tx_1023_oct_pkts_port;
+ u64 mac_tx_max_oct_pkts_port;
+ u64 mac_tx_over_oct_pkts_port;
+ u64 mac_rx_good_pkts_port;
+ u64 mac_rx_crc_error_pkts_port;
+ u64 mac_rx_broadcast_ok_port;
+ u64 mac_rx_multicast_ok_port;
+ u64 mac_rx_mac_frame_ok_port;
+ u64 mac_rx_length_err_pkts_port;
+ u64 mac_rx_vlan_pkts_port;
+ u64 mac_rx_pause_pkts_port;
+ u64 mac_rx_unknown_mac_frame_port;
+ u64 mac_tx_good_pkts_port;
+ u64 mac_tx_broadcast_ok_port;
+ u64 mac_tx_multicast_ok_port;
+ u64 mac_tx_underrun_pkts_port;
+ u64 mac_tx_mac_frame_ok_port;
+ u64 mac_tx_vlan_pkts_port;
+ u64 mac_tx_pause_pkts_port;
+};
+
+struct hinic3_port_stats {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ struct hinic3_phy_fpga_port_stats stats;
+};
+
+struct hinic3_cmd_vport_stats {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u32 stats_size;
+ u32 rsvd1;
+ struct hinic3_vport_stats stats;
+ u64 rsvd2[6];
+};
+
+struct hinic3_cmd_qpn {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 base_qpn;
+};
+
+enum hinic3_func_tbl_cfg_bitmap {
+ FUNC_CFG_INIT,
+ FUNC_CFG_RX_BUF_SIZE,
+ FUNC_CFG_MTU,
+};
+
+struct hinic3_func_tbl_cfg {
+ u16 rx_wqe_buf_size;
+ u16 mtu;
+ u32 rsvd[9];
+};
+
+struct hinic3_cmd_set_func_tbl {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd;
+
+ u32 cfg_bitmap;
+ struct hinic3_func_tbl_cfg tbl_cfg;
+};
+
+struct hinic3_cmd_cons_idx_attr {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_idx;
+ u8 dma_attr_off;
+ u8 pending_limit;
+ u8 coalescing_time;
+ u8 intr_en;
+ u16 intr_idx;
+ u32 l2nic_sqn;
+ u32 rsvd;
+ u64 ci_addr;
+};
+
+union sm_tbl_args {
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } mac_table_arg;
+ struct {
+ u32 er_id;
+ u32 vlan_id;
+ } vlan_elb_table_arg;
+ struct {
+ u32 func_id;
+ } vlan_filter_arg;
+ struct {
+ u32 mc_id;
+ } mc_elb_arg;
+ struct {
+ u32 func_id;
+ } func_tbl_arg;
+ struct {
+ u32 port_id;
+ } port_tbl_arg;
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } fdir_io_table_arg;
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } flexq_table_arg;
+ u32 args[4];
+};
+
+#define DFX_SM_TBL_BUF_MAX (768)
+
+struct nic_cmd_dfx_sm_table {
+ struct hinic3_mgmt_msg_head msg_head;
+ u32 tbl_type;
+ union sm_tbl_args args;
+ u8 tbl_buf[DFX_SM_TBL_BUF_MAX];
+};
+
+struct hinic3_cmd_vlan_offload {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 vlan_offload;
+ u8 rsvd1[5];
+};
+
+/* ucode capture cfg info */
+struct nic_cmd_capture_info {
+ struct hinic3_mgmt_msg_head msg_head;
+ u32 op_type;
+ u32 func_port;
+ u32 is_en_trx;
+ u32 offset_cos;
+ u32 data_vlan;
+};
+
+struct hinic3_cmd_lro_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u8 lro_ipv4_en;
+ u8 lro_ipv6_en;
+ u8 lro_max_pkt_len; /* unit is 1K */
+ u8 resv2[13];
+};
+
+struct hinic3_cmd_lro_timer {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 opcode; /* 1: set timer value, 0: get timer value */
+ u8 rsvd1;
+ u16 rsvd2;
+ u32 timer;
+};
+
+struct hinic3_cmd_local_lro_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 state; /* 0: disable, 1: enable */
+};
+
+struct hinic3_cmd_gtp_inner_parse_status {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 status; /* 0: disable, 1: enable */
+};
+
+struct hinic3_cmd_vf_vlan_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u16 vlan_id;
+ u8 qos;
+ u8 rsvd2[5];
+};
+
+struct hinic3_cmd_spoofchk_set {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 state;
+ u8 rsvd1;
+};
+
+struct hinic3_cmd_tx_rate_cfg {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 rsvd1;
+ u8 direct;
+ u32 min_rate;
+ u32 max_rate;
+ u8 rsvd2[8];
+};
+
+struct hinic3_cmd_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+ u8 port_type;
+ u8 autoneg_cap;
+ u8 autoneg_state;
+ u8 duplex;
+ u8 speed;
+ u8 fec;
+ u16 rsvd2;
+ u32 rsvd3[4];
+};
+
+struct hinic3_cmd_register_vf {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 op_register; /* 0 - unregister, 1 - register */
+ u8 rsvd1[3];
+ u32 support_extra_feature;
+ u8 rsvd2[32];
+};
+
+struct hinic3_cmd_link_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 state;
+ u16 rsvd1;
+};
+
+struct hinic3_cmd_vlan_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 outband_defvid_flag;
+ u16 vlan_id;
+ u8 blacklist_flag;
+ u8 rsvd2;
+};
+
+#define VLAN_BLACKLIST_ENABLE 1
+#define VLAN_BLACKLIST_DISABLE 0
+
+struct hinic3_cmd_vxlan_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 cfg_mode;
+ u16 vxlan_port;
+ u16 rsvd2;
+};
+
+/* set vlan filter */
+struct hinic3_cmd_set_vlan_filter {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 resvd[2];
+ u32 vlan_filter_ctrl; /* bit0:vlan filter en; bit1:broadcast_filter_en */
+};
+
+struct hinic3_cmd_link_ksettings_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+
+ u32 valid_bitmap;
+ u8 speed; /* enum nic_speed_level */
+ u8 autoneg; /* 0 - off, 1 - on */
+ u8 fec; /* 0 - RSFEC, 1 - BASEFEC, 2 - NOFEC */
+ u8 rsvd2[21]; /* reserved for duplex, port, etc. */
+};
+
+struct mpu_lt_info {
+ u8 node;
+ u8 inst;
+ u8 entry_size;
+ u8 rsvd;
+ u32 lt_index;
+ u32 offset;
+ u32 len;
+};
+
+struct nic_mpu_lt_opera {
+ struct hinic3_mgmt_msg_head msg_head;
+ struct mpu_lt_info net_lt_cmd;
+ u8 data[100];
+};
+
+struct hinic3_force_pkt_drop {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port;
+ u8 rsvd1[3];
+};
+
+struct hinic3_rx_mode_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u32 rx_mode;
+};
+
+/* rss */
+struct hinic3_rss_context_table {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u32 context;
+};
+
+struct hinic3_cmd_rss_engine_type {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 hash_engine;
+ u8 rsvd1[4];
+};
+
+struct hinic3_cmd_rss_hash_key {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u8 key[NIC_RSS_KEY_SIZE];
+};
+
+struct hinic3_rss_indir_table {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 indir[NIC_RSS_INDIR_SIZE];
+};
+
+#define NIC_RSS_CMD_TEMP_ALLOC 0x01
+#define NIC_RSS_CMD_TEMP_FREE 0x02
+
+struct hinic3_rss_template_mgmt {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 cmd;
+ u8 template_id;
+ u8 rsvd1[4];
+};
+
+struct hinic3_cmd_rss_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 rss_en;
+ u8 rq_priority_number;
+ u8 prio_tc[NIC_DCB_COS_MAX];
+ u16 num_qps;
+ u16 rsvd1;
+};
+
+struct hinic3_dcb_state {
+ u8 dcb_on;
+ u8 default_cos;
+ u8 trust;
+ u8 rsvd1;
+ u8 pcp2cos[NIC_DCB_UP_MAX];
+ u8 dscp2cos[64];
+ u32 rsvd2[7];
+};
+
+struct hinic3_cmd_vf_dcb_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ struct hinic3_dcb_state state;
+};
+
+struct hinic3_up_ets_cfg { /* delet */
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+
+ u8 cos_tc[NIC_DCB_COS_MAX];
+ u8 tc_bw[NIC_DCB_TC_MAX];
+ u8 cos_prio[NIC_DCB_COS_MAX];
+ u8 cos_bw[NIC_DCB_COS_MAX];
+ u8 tc_prio[NIC_DCB_TC_MAX];
+};
+
+#define CMD_QOS_ETS_COS_TC BIT(0)
+#define CMD_QOS_ETS_TC_BW BIT(1)
+#define CMD_QOS_ETS_COS_PRIO BIT(2)
+#define CMD_QOS_ETS_COS_BW BIT(3)
+#define CMD_QOS_ETS_TC_PRIO BIT(4)
+#define CMD_QOS_ETS_TC_RATELIMIT BIT(5)
+
+struct hinic3_cmd_ets_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 1 - set, 0 - get */
+ /* bit0 - cos_tc, bit1 - tc_bw, bit2 - cos_prio, bit3 - cos_bw, bit4 - tc_prio */
+ u8 cfg_bitmap;
+ u8 rsvd;
+
+ u8 cos_tc[NIC_DCB_COS_MAX];
+ u8 tc_bw[NIC_DCB_TC_MAX];
+ u8 cos_prio[NIC_DCB_COS_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 cos_bw[NIC_DCB_COS_MAX];
+ u8 tc_prio[NIC_DCB_TC_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 rate_limit[NIC_DCB_TC_MAX];
+};
+
+struct hinic3_cmd_set_dcb_state {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 op_code; /* 0 - get dcb state, 1 - set dcb state */
+ u8 state; /* 0 - disable, 1 - enable dcb */
+ u8 port_state; /* 0 - disable, 1 - enable dcb */
+ u8 rsvd[7];
+};
+
+#define PFC_BIT_MAP_NUM 8
+struct hinic3_cmd_set_pfc {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 0:get 1: set pfc_en 2: set pfc_bitmap 3: set all */
+ u8 pfc_en; /* pfc_en 和 pfc_bitmap 必须同时设置 */
+ u8 pfc_bitmap;
+ u8 rsvd[4];
+};
+
+#define CMD_QOS_PORT_TRUST BIT(0)
+#define CMD_QOS_PORT_DFT_COS BIT(1)
+struct hinic3_cmd_qos_port_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 0 - get, 1 - set */
+ u8 cfg_bitmap; /* bit0 - trust, bit1 - dft_cos */
+ u8 rsvd0;
+
+ u8 trust;
+ u8 dft_cos;
+ u8 rsvd1[18];
+};
+
+#define MAP_COS_MAX_NUM 8
+#define CMD_QOS_MAP_PCP2COS BIT(0)
+#define CMD_QOS_MAP_DSCP2COS BIT(1)
+struct hinic3_cmd_qos_map_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 op_code;
+ u8 cfg_bitmap; /* bit0 - pcp2cos, bit1 - dscp2cos */
+ u16 rsvd0;
+
+ u8 pcp2cos[8]; /* 8 must be configured together */
+ /* If the dscp2cos parameter is set to 0xFF, the MPU ignores the DSCP priority,
+ * Multiple mappings between DSCP values and CoS values can be configured at a time.
+ */
+ u8 dscp2cos[64];
+ u32 rsvd1[4];
+};
+
+struct hinic3_cos_up_map {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 cos_valid_mask; /* every bit indicate index of map is valid 1 or not 0 */
+ u16 rsvd1;
+
+ /* user priority in cos(index:cos, value: up pri) */
+ u8 map[NIC_DCB_UP_MAX];
+};
+
+struct hinic3_cmd_pause_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode;
+ u16 rsvd1;
+ u8 auto_neg;
+ u8 rx_pause;
+ u8 tx_pause;
+ u8 rsvd2[5];
+};
+
+struct nic_cmd_pause_inquiry_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 valid;
+
+ u32 type; /* 1: set, 2: get */
+
+ u32 cos_id;
+
+ u32 rx_inquiry_pause_drop_pkts_en;
+ u32 rx_inquiry_pause_period_ms;
+ u32 rx_inquiry_pause_times;
+ /* rx pause Detection Threshold, Default PAUSE_FRAME_THD_10G/25G/40G/100 */
+ u32 rx_inquiry_pause_frame_thd;
+ u32 rx_inquiry_tx_total_pkts;
+
+ u32 tx_inquiry_pause_en; /* tx pause detect enable */
+ u32 tx_inquiry_pause_period_ms; /* tx pause Default Detection Period 200ms */
+ u32 tx_inquiry_pause_times; /* tx pause Default Times Period 5 */
+ u32 tx_inquiry_pause_frame_thd; /* tx pause Detection Threshold */
+ u32 tx_inquiry_rx_total_pkts;
+ u32 rsvd[3];
+};
+
+/* pfc/pause Storm TX exception reporting */
+struct nic_cmd_tx_pause_notice {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 tx_pause_except; /* 1: abnormality,0: normal */
+ u32 except_level;
+ u32 rsvd;
+};
+
+#define HINIC3_CMD_OP_FREE 0
+#define HINIC3_CMD_OP_ALLOC 1
+
+struct hinic3_cmd_cfg_qps {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 1: alloc qp, 0: free qp */
+ u8 rsvd1;
+ u16 num_qps;
+ u16 rsvd2;
+};
+
+struct hinic3_cmd_led_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port;
+ u8 type;
+ u8 mode;
+ u8 rsvd1;
+};
+
+struct hinic3_cmd_port_loopback {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode;
+ u8 mode;
+ u8 en;
+ u32 rsvd1[2];
+};
+
+struct hinic3_cmd_get_light_module_abs {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 abs_status; /* 0:present, 1:absent */
+ u8 rsv[2];
+};
+
+#define STD_SFP_INFO_MAX_SIZE 640
+struct hinic3_cmd_get_std_sfp_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 wire_type;
+ u16 eeprom_len;
+ u32 rsvd;
+ u8 sfp_info[STD_SFP_INFO_MAX_SIZE];
+};
+
+struct hinic3_cable_plug_event {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 plugged; /* 0: unplugged, 1: plugged */
+ u8 port_id;
+};
+
+struct nic_cmd_mac_info {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 valid_bitmap;
+ u16 rsvd;
+
+ u8 host_id[32];
+ u8 port_id[32];
+ u8 mac_addr[192];
+};
+
+struct nic_cmd_set_tcam_enable {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 tcam_enable;
+ u8 rsvd1;
+ u32 rsvd2;
+};
+
+struct nic_cmd_set_fdir_status {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 pkt_type_en;
+ u8 pkt_type;
+ u8 qid;
+ u8 rsvd2;
+};
+
+#define HINIC3_TCAM_BLOCK_ENABLE 1
+#define HINIC3_TCAM_BLOCK_DISABLE 0
+#define HINIC3_MAX_TCAM_RULES_NUM 4096
+
+/* tcam block type, according to tcam block size */
+enum {
+ NIC_TCAM_BLOCK_TYPE_LARGE = 0, /* block_size: 16 */
+ NIC_TCAM_BLOCK_TYPE_SMALL, /* block_size: 0 */
+ NIC_TCAM_BLOCK_TYPE_MAX
+};
+
+/* alloc tcam block input struct */
+struct nic_cmd_ctrl_tcam_block_in {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
+ /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
+ u8 tcam_type;
+ u16 tcam_block_index;
+ /* Size of the block that the driver wants to allocate
+ * Interface returned by the UP to the driver,
+ * indicating the size of the allocated TCAM block supported by the UP
+ */
+ u16 alloc_block_num;
+};
+
+/* alloc tcam block output struct */
+struct nic_cmd_ctrl_tcam_block_out {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
+ /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
+ u8 tcam_type;
+ u16 tcam_block_index;
+ /* Size of the block that the driver wants to allocate
+ * Interface returned by the UP to the driver,
+ * indicating the size of the allocated TCAM block supported by the UP
+ */
+ u16 mpu_alloc_block_size;
+};
+
+struct nic_cmd_flush_tcam_rules {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u16 rsvd;
+};
+
+struct nic_cmd_dfx_fdir_tcam_block_table {
+ struct hinic3_mgmt_msg_head head;
+ u8 tcam_type;
+ u8 valid;
+ u16 tcam_block_index;
+ u16 use_function_id;
+ u16 rsvd;
+};
+
+struct tcam_result {
+ u32 qid;
+ u32 rsvd;
+};
+
+#define TCAM_FLOW_KEY_SIZE (44)
+
+struct tcam_key_x_y {
+ u8 x[TCAM_FLOW_KEY_SIZE];
+ u8 y[TCAM_FLOW_KEY_SIZE];
+};
+
+struct nic_tcam_cfg_rule {
+ u32 index;
+ struct tcam_result data;
+ struct tcam_key_x_y key;
+};
+
+#define TCAM_RULE_FDIR_TYPE 0
+#define TCAM_RULE_PPA_TYPE 1
+
+struct nic_cmd_fdir_add_rule {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 type;
+ u8 fdir_ext; /* 0x1: flow bifur en bit */
+ struct nic_tcam_cfg_rule rule;
+};
+
+struct nic_cmd_fdir_del_rules {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 type;
+ u8 rsvd;
+ u32 index_start;
+ u32 index_num;
+};
+
+struct nic_cmd_fdir_get_rule {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 index;
+ u8 valid;
+ u8 type;
+ u16 rsvd;
+ struct tcam_key_x_y key;
+ struct tcam_result data;
+ u64 packet_count;
+ u64 byte_count;
+};
+
+struct nic_cmd_fdir_get_block_rules {
+ struct hinic3_mgmt_msg_head head;
+ u8 tcam_block_type; // only NIC_TCAM_BLOCK_TYPE_LARGE
+ u8 tcam_table_type; // TCAM_RULE_PPA_TYPE or TCAM_RULE_FDIR_TYPE
+ u16 tcam_block_index;
+ u8 valid[NIC_TCAM_BLOCK_LARGE_SIZE];
+ struct tcam_key_x_y key[NIC_TCAM_BLOCK_LARGE_SIZE];
+ struct tcam_result data[NIC_TCAM_BLOCK_LARGE_SIZE];
+};
+
+struct hinic3_tcam_key_ipv4_mem {
+ u32 rsvd1 : 1;
+ u32 bifur_flag : 2;
+ u32 model : 1;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+ u32 sipv4_h : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+ u32 dipv4_h : 16;
+ u32 sipv4_l : 16;
+ u32 vlan_id : 15;
+ u32 vlan_flag : 1;
+ u32 dipv4_l : 16;
+ u32 rsvd3;
+ u32 dport : 16;
+ u32 rsvd4 : 16;
+ u32 rsvd5 : 16;
+ u32 sport : 16;
+ u32 outer_sipv4_h : 16;
+ u32 rsvd6 : 16;
+ u32 outer_dipv4_h : 16;
+ u32 outer_sipv4_l : 16;
+ u32 vni_h : 16;
+ u32 outer_dipv4_l : 16;
+ u32 rsvd7 : 16;
+ u32 vni_l : 16;
+};
+
+union hinic3_tag_tcam_ext_info {
+ struct {
+ u32 id : 16; /* id */
+ u32 type : 4; /* type: 0-func, 1-vmdq, 2-port, 3-rsvd, 4-trunk, 5-dp, 6-mc */
+ u32 host_id : 3;
+ u32 rss_q_num : 8; /* rss queue num */
+ u32 ext : 1;
+ } bs;
+ u32 value;
+};
+
+struct hinic3_tcam_key_ipv6_mem {
+ u32 bifur_flag : 2;
+ u32 vlan_flag : 1;
+ u32 outer_ip_type : 1;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+ u32 sipv6_key0 : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+ u32 sipv6_key2 : 16;
+ u32 sipv6_key1 : 16;
+ u32 sipv6_key4 : 16;
+ u32 sipv6_key3 : 16;
+ u32 sipv6_key6 : 16;
+ u32 sipv6_key5 : 16;
+ u32 dport : 16;
+ u32 sipv6_key7 : 16;
+ u32 dipv6_key0 : 16;
+ u32 sport : 16;
+ u32 dipv6_key2 : 16;
+ u32 dipv6_key1 : 16;
+ u32 dipv6_key4 : 16;
+ u32 dipv6_key3 : 16;
+ u32 dipv6_key6 : 16;
+ u32 dipv6_key5 : 16;
+ u32 rsvd2 : 16;
+ u32 dipv6_key7 : 16;
+};
+
+struct hinic3_tcam_key_vxlan_ipv6_mem {
+ u32 rsvd1 : 4;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+
+ u32 dipv6_key0 : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+
+ u32 dipv6_key2 : 16;
+ u32 dipv6_key1 : 16;
+
+ u32 dipv6_key4 : 16;
+ u32 dipv6_key3 : 16;
+
+ u32 dipv6_key6 : 16;
+ u32 dipv6_key5 : 16;
+
+ u32 dport : 16;
+ u32 dipv6_key7 : 16;
+
+ u32 rsvd2 : 16;
+ u32 sport : 16;
+
+ u32 outer_sipv4_h : 16;
+ u32 rsvd3 : 16;
+
+ u32 outer_dipv4_h : 16;
+ u32 outer_sipv4_l : 16;
+
+ u32 vni_h : 16;
+ u32 outer_dipv4_l : 16;
+
+ u32 rsvd4 : 16;
+ u32 vni_l : 16;
+};
+
+struct tag_tcam_key {
+ union {
+ struct hinic3_tcam_key_ipv4_mem key_info;
+ struct hinic3_tcam_key_ipv6_mem key_info_ipv6;
+ struct hinic3_tcam_key_vxlan_ipv6_mem key_info_vxlan_ipv6;
+ };
+
+ union {
+ struct hinic3_tcam_key_ipv4_mem key_mask;
+ struct hinic3_tcam_key_ipv6_mem key_mask_ipv6;
+ struct hinic3_tcam_key_vxlan_ipv6_mem key_mask_vxlan_ipv6;
+ };
+};
+
+enum {
+ PPA_TABLE_ID_CLEAN_CMD = 0,
+ PPA_TABLE_ID_ADD_CMD,
+ PPA_TABLE_ID_DEL_CMD,
+ FDIR_TABLE_ID_ADD_CMD,
+ FDIR_TABLE_ID_DEL_CMD,
+ PPA_TABEL_ID_MAX
+};
+
+struct hinic3_ppa_cfg_table_id_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u16 cmd;
+ u16 table_id;
+ u16 rsvd1;
+};
+
+struct hinic3_ppa_cfg_ppa_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 ppa_en;
+ u8 ppa_miss_drop_en;
+};
+
+struct hinic3_func_flow_bifur_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 func_id;
+ u8 flow_bifur_en;
+ u8 rsvd[5];
+};
+
+struct hinic3_port_flow_bifur_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 port_id;
+ u8 flow_bifur_en;
+ u8 flow_bifur_type; /* 0->vf bifur, 2->traffic bifur */
+ u8 rsvd[4];
+};
+
+struct hinic3_bond_mask_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 func_id;
+ u8 bond_mask;
+ u8 bond_en;
+ u8 func_valid;
+ u8 rsvd[3];
+};
+
+struct hinic3_func_er_value_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 vf_id;
+ u16 er_fwd_id;
+};
+
+#define HINIC3_TX_SET_PROMISC_SKIP 0
+#define HINIC3_TX_GET_PROMISC_SKIP 1
+
+#define HINIC3_GET_TRAFFIC_BIFUR_STATE 0
+#define HINIC3_SET_TRAFFIC_BIFUR_STATE 1
+
+struct hinic3_tx_promisc_cfg {
+ struct hinic3_mgmt_msg_head msg_head;
+ u8 port_id;
+ u8 promisc_skip_en; /* 0: disable tx promisc replication, 1: enable */
+ u8 opcode; /* 0: set, 1: get */
+ u8 rsvd1;
+};
+
+struct hinic3_ppa_cfg_mode_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u8 ppa_mode;
+ u8 qpc_func_nums;
+ u16 base_qpc_func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_ppa_flush_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u8 flush_en; /* 0 flush done, 1 in flush operation */
+ u8 rsvd1;
+};
+
+struct hinic3_ppa_fdir_query_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u32 index;
+ u32 rsvd;
+ u64 pkt_nums;
+ u64 pkt_bytes;
+};
+
+/* BIOS CONF */
+enum {
+ NIC_NVM_DATA_SET = BIT(0), /* 1-save, 0-read */
+ NIC_NVM_DATA_PXE = BIT(1),
+ NIC_NVM_DATA_VLAN = BIT(2),
+ NIC_NVM_DATA_VLAN_PRI = BIT(3),
+ NIC_NVM_DATA_VLAN_ID = BIT(4),
+ NIC_NVM_DATA_WORK_MODE = BIT(5),
+ NIC_NVM_DATA_PF_TX_SPEED_LIMIT = BIT(6),
+ NIC_NVM_DATA_GE_MODE = BIT(7),
+ NIC_NVM_DATA_AUTO_NEG = BIT(8),
+ NIC_NVM_DATA_LINK_FEC = BIT(9),
+ NIC_NVM_DATA_PF_ADAPTIVE_LINK = BIT(10),
+ NIC_NVM_DATA_SRIOV_CONTROL = BIT(11),
+ NIC_NVM_DATA_EXTEND_MODE = BIT(12),
+ NIC_NVM_DATA_LEGACY_VLAN = BIT(13),
+ NIC_NVM_DATA_LEGACY_VLAN_PRI = BIT(14),
+ NIC_NVM_DATA_LEGACY_VLAN_ID = BIT(15),
+ NIC_NVM_DATA_RESET = BIT(31),
+};
+
+#define BIOS_CFG_SIGNATURE 0x1923E518
+#define BIOS_OP_CFG_ALL(op_code_val) \
+ ((((op_code_val) >> 1) & (0xFFFFFFFF)) != 0)
+#define BIOS_OP_CFG_WRITE(op_code_val) \
+ ((((op_code_val) & NIC_NVM_DATA_SET)) != 0)
+#define BIOS_OP_CFG_PXE_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PXE) != 0)
+#define BIOS_OP_CFG_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN) != 0)
+#define BIOS_OP_CFG_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_ID) != 0)
+#define BIOS_OP_CFG_WORK_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_WORK_MODE) != 0)
+#define BIOS_OP_CFG_PF_BW(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_TX_SPEED_LIMIT) != 0)
+#define BIOS_OP_CFG_GE_SPEED(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_GE_MODE) != 0)
+#define BIOS_OP_CFG_AUTO_NEG(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_AUTO_NEG) != 0)
+#define BIOS_OP_CFG_LINK_FEC(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LINK_FEC) != 0)
+#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_ADAPTIVE_LINK) != 0)
+#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_SRIOV_CONTROL) != 0)
+#define BIOS_OP_CFG_EXTEND_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_EXTEND_MODE) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_ID) != 0)
+#define BIOS_OP_CFG_RST_DEF_SET(op_code_val) \
+ (((op_code_val) & (u32)NIC_NVM_DATA_RESET) != 0)
+
+
+#define NIC_BIOS_CFG_MAX_PF_BW 100
+
+struct nic_legacy_vlan_cfg {
+ /* Legacy mode PXE VLAN enable: 0 - disable 1 - enable */
+ u8 pxe_vlan_en : 1;
+ /* Legacy mode PXE VLAN priority: 0-7 */
+ u8 pxe_vlan_pri : 3;
+ /* Legacy mode PXE VLAN ID 1-4094 */
+ u16 pxe_vlan_id : 12;
+};
+
+/* Note: This structure must be 4-byte aligned. */
+struct nic_bios_cfg {
+ u32 signature;
+ u8 pxe_en;
+ u8 extend_mode;
+ struct nic_legacy_vlan_cfg nlvc;
+ u8 pxe_vlan_en;
+ u8 pxe_vlan_pri;
+ u16 pxe_vlan_id;
+ u32 service_mode;
+ u32 pf_tx_bw;
+ u8 speed;
+ u8 auto_neg;
+ u8 lanes;
+ u8 fec;
+ u8 auto_adapt;
+ u8 func_valid;
+ u8 func_id;
+ u8 sriov_en;
+};
+
+struct nic_cmd_bios_cfg {
+ struct hinic3_mgmt_msg_head head;
+ u32 op_code; /* Operation Code: Bit0[0: read 1:write, BIT1-6: cfg_mask */
+ struct nic_bios_cfg bios_cfg;
+};
+
+struct nic_rx_rate_bios_cfg {
+ struct mgmt_msg_head msg_head;
+
+ u32 op_code; /* Operation Code:[0:read 1:write] */
+ u8 rx_rate_limit;
+ u8 func_id;
+};
+
+struct nic_cmd_vhd_config {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 vhd_type;
+ u8 virtio_small_enable; /* 0: mergeable mode, 1: small mode */
+};
+
+/* BOND */
+struct hinic3_create_bond_info {
+ u32 bond_id;
+ u32 master_slave_port_id;
+ u32 slave_bitmap; /* bond port id bitmap */
+ u32 poll_timeout; /* Bond device link check time */
+ u32 up_delay; /* Temporarily reserved */
+ u32 down_delay; /* Temporarily reserved */
+ u32 bond_mode; /* Temporarily reserved */
+ u32 active_pf; /* bond use active pf id */
+ u32 active_port_max_num; /* Maximum number of active bond member interfaces */
+ u32 active_port_min_num; /* Minimum number of active bond member interfaces */
+ u32 xmit_hash_policy;
+ u32 default_param_flag;
+ u32 rsvd;
+};
+
+struct hinic3_cmd_create_bond {
+ struct hinic3_mgmt_msg_head head;
+ struct hinic3_create_bond_info create_bond_info;
+};
+
+struct hinic3_cmd_delete_bond {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 rsvd[2];
+};
+
+struct hinic3_open_close_bond_info {
+ u32 bond_id;
+ u32 open_close_flag; /* Bond flag. 1: open; 0: close. */
+ u32 rsvd[2];
+};
+
+struct hinic3_cmd_open_close_bond {
+ struct hinic3_mgmt_msg_head head;
+ struct hinic3_open_close_bond_info open_close_bond_info;
+};
+
+struct lacp_port_params {
+ u16 port_number;
+ u16 port_priority;
+ u16 key;
+ u16 system_priority;
+ u8 system[ETH_ALEN];
+ u8 port_state;
+ u8 rsvd;
+};
+
+struct lacp_port_info {
+ u32 selected;
+ u32 aggregator_port_id;
+
+ struct lacp_port_params actor;
+ struct lacp_port_params partner;
+
+ u64 tx_lacp_pkts;
+ u64 rx_lacp_pkts;
+ u64 rx_8023ad_drop;
+ u64 tx_8023ad_drop;
+ u64 unknown_pkt_drop;
+ u64 rx_marker_pkts;
+ u64 tx_marker_pkts;
+};
+
+struct hinic3_bond_status_info {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 bon_mmi_status;
+ u32 active_bitmap;
+ u32 port_count;
+
+ struct lacp_port_info port_info[4];
+
+ u64 success_report_cnt[4];
+ u64 fail_report_cnt[4];
+
+ u64 poll_timeout;
+ u64 fast_periodic_timeout;
+ u64 slow_periodic_timeout;
+ u64 short_timeout;
+ u64 long_timeout;
+ u64 aggregate_wait_timeout;
+ u64 tx_period_timeout;
+ u64 rx_marker_timer;
+};
+
+struct hinic3_bond_active_report_info {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 bon_mmi_status;
+ u32 active_bitmap;
+
+ u8 rsvd[16];
+};
+
+/* IP checksum error packets, enable rss quadruple hash. */
+struct hinic3_ipcs_err_rss_enable_operation_s {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 en_tag;
+ u8 type; /* 1: set 0: get */
+ u8 rsvd[2];
+};
+
+struct hinic3_smac_check_state {
+ struct hinic3_mgmt_msg_head head;
+ u8 smac_check_en; /* 1: enable 0: disable */
+ u8 op_code; /* 1: set 0: get */
+ u8 flash_en; /* 1: enable 0: disable */
+ u8 rsvd;
+};
+
+struct hinic3_clear_log_state {
+ struct hinic3_mgmt_msg_head head;
+ u32 type;
+};
+
+struct hinic3_outband_cfg_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 outband_default_vid;
+ u16 func_id;
+};
+
+struct hinic3_wr_ordering {
+ struct hinic3_mgmt_msg_head head;
+ u8 op_code; /* 1: set 0: get */
+ u8 wr_pkt_so_ro;
+ u8 rd_pkt_so_ro;
+ u8 rsvd;
+};
+
+struct hinic3_function_active_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_rq_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rq_depth;
+ u16 rq_num;
+ u16 pf_num;
+ u16 port_num;
+};
+
+#endif /* HINIC_MGMT_INTERFACE_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
new file mode 100644
index 0000000..97eda43
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
+ * File Name : nic_npu_cmd.h
+ * Version : Initial Draft
+ * Created : 2019/4/25
+ * Last Modified :
+ * Description : NIC Commands between Driver and NPU
+ * Function List :
+ */
+
+#ifndef NIC_NPU_CMD_H
+#define NIC_NPU_CMD_H
+
+/* NIC CMDQ MODE */
+enum hinic3_ucode_cmd {
+ HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
+ HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
+ HINIC3_UCODE_CMD_ARM_SQ, /**< Unused */
+ HINIC3_UCODE_CMD_ARM_RQ, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_IQ_ENABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
+ HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
+ HINIC3_UCODE_CMD_PPA_HASH_TABLE,
+ HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_UCODE_MIG_CFG_Q_CTX = 14,
+ HINIC3_UCODE_MIG_CHK_SQ_STOP,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ HINIC3_UCODE_MIG_CFG_BAT_INFO,
+};
+
+#endif /* NIC_NPU_CMD_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
index ee005a8..5f0f790 100644
--- a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
+++ b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
@@ -4,8 +4,8 @@
#ifndef OSSL_KNL_LINUX_H_
#define OSSL_KNL_LINUX_H_
-#include <net/checksum.h>
#include <net/ipv6.h>
+#include <net/devlink.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/device.h>
@@ -19,6 +19,12 @@
#include <linux/list.h>
#include <linux/bitmap.h>
#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/filter.h>
+#include <linux/aer.h>
+#include <linux/socket.h>
#ifndef NETIF_F_SCTP_CSUM
#define NETIF_F_SCTP_CSUM 0
@@ -37,6 +43,17 @@
#define ossl_get_free_pages __get_free_pages
+#ifndef ETHTOOL_LINK_MODE_100000baseKR_Full_BIT
+#define ETHTOOL_LINK_MODE_100000baseKR_Full_BIT 75
+#define ETHTOOL_LINK_MODE_100000baseCR_Full_BIT 78
+#define ETHTOOL_LINK_MODE_100000baseSR_Full_BIT 76
+#endif
+#ifndef ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT
+#define ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT 80
+#define ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT 81
+#define ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT 84
+#endif
+
#ifndef high_16_bits
#define low_16_bits(x) ((x) & 0xFFFF)
#define high_16_bits(x) (((x) & 0xFFFF0000) >> 16)
@@ -54,13 +71,11 @@
#endif
#define HAVE_INET6_IFADDR_LIST
-
#define HAVE_NDO_GET_STATS64
#ifndef HAVE_MQPRIO
#define HAVE_MQPRIO
#endif
-
#ifndef HAVE_SETUP_TC
#define HAVE_SETUP_TC
#endif
@@ -68,25 +83,20 @@
#ifndef HAVE_NDO_SET_FEATURES
#define HAVE_NDO_SET_FEATURES
#endif
-
#define HAVE_IRQ_AFFINITY_NOTIFY
-
#define HAVE_ETHTOOL_SET_PHYS_ID
-
#define HAVE_NETDEV_WANTED_FEAUTES
#ifndef HAVE_PCI_DEV_FLAGS_ASSIGNED
#define HAVE_PCI_DEV_FLAGS_ASSIGNED
#define HAVE_VF_SPOOFCHK_CONFIGURE
#endif
-
#ifndef HAVE_SKB_L4_RXHASH
#define HAVE_SKB_L4_RXHASH
#endif
#define HAVE_ETHTOOL_GRXFHINDIR_SIZE
#define HAVE_INT_NDO_VLAN_RX_ADD_VID
-
#ifdef ETHTOOL_SRXNTUPLE
#undef ETHTOOL_SRXNTUPLE
#endif
@@ -95,9 +105,9 @@
#define _kc_kunmap_atomic(addr) kunmap_atomic(addr)
#include <linux/of_net.h>
-
#define HAVE_FDB_OPS
#define HAVE_ETHTOOL_GET_TS_INFO
+
#define HAVE_NAPI_GRO_FLUSH_OLD
#ifndef HAVE_SRIOV_CONFIGURE
@@ -107,6 +117,7 @@
#define HAVE_ENCAP_TSO_OFFLOAD
#define HAVE_SKB_INNER_NETWORK_HEADER
+
#define HAVE_NDO_SET_VF_LINK_STATE
#define HAVE_SKB_INNER_PROTOCOL
#define HAVE_MPLS_FEATURES
@@ -115,12 +126,12 @@
#define HAVE_NETIF_SET_XPS_QUEUE_CONST_MASK
#define HAVE_VXLAN_CHECKS
-#define HAVE_NDO_SELECT_QUEUE_ACCEL
#define HAVE_NET_GET_RANDOM_ONCE
#define HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS
#define HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK
+
#define HAVE_NDO_SET_VF_MIN_MAX_TX_RATE
#define HAVE_VLAN_FIND_DEV_DEEP_RCU
@@ -128,8 +139,8 @@
#define HAVE_MULTI_VLAN_OFFLOAD_EN
#define HAVE_ETH_GET_HEADLEN_FUNC
-#define HAVE_RXFH_HASHFUNC
+#define HAVE_RXFH_HASHFUNC
#define HAVE_NDO_SET_VF_TRUST
#include <net/devlink.h>
@@ -138,6 +149,7 @@
#define HAVE_NETDEVICE_MIN_MAX_MTU
+
#define HAVE_VOID_NDO_GET_STATS64
#define HAVE_VM_OPS_FAULT_NO_VMA
@@ -146,9 +158,13 @@
#define HAVE_PCI_ERROR_HANDLER_RESET_PREPARE
#define HAVE_PTP_CLOCK_DO_AUX_WORK
+
#define HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV
#define HAVE_XDP_SUPPORT
+#if (KERNEL_VERSION(5, 9, 0) > LINUX_VERSION_CODE)
+#define HAVE_XDP_QUERY_PROG
+#endif
#define HAVE_NDO_BPF_NETDEV_BPF
#define HAVE_TIMER_SETUP
@@ -158,6 +174,7 @@
#define HAVE_NDO_SELECT_QUEUE_SB_DEV
+
#define dev_open(x) dev_open(x, NULL)
#define HAVE_NEW_ETHTOOL_LINK_SETTINGS_ONLY
@@ -180,12 +197,14 @@ static inline void *_hinic3_dma_zalloc_coherent(struct device *dev,
}
#endif
+#if (KERNEL_VERSION(5, 6, 0) <= LINUX_VERSION_CODE)
#ifndef DT_KNL_EMU
struct timeval {
__kernel_old_time_t tv_sec; /* seconds */
__kernel_suseconds_t tv_usec; /* microseconds */
};
#endif
+#endif
#ifndef do_gettimeofday
#define do_gettimeofday(time) _kc_do_gettimeofday(time)
@@ -199,6 +218,8 @@ static inline void _kc_do_gettimeofday(struct timeval *tv)
}
#endif
+
+
#define HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY
#define ETH_GET_HEADLEN_NEED_DEV
#define HAVE_GENL_OPS_FIELD_VALIDATE
@@ -207,32 +228,75 @@ static inline void _kc_do_gettimeofday(struct timeval *tv)
#define FIELD_SIZEOF(t, f) (sizeof(((t *)0)->f))
#endif
+/*****************************************************************************/
+#if (KERNEL_VERSION(5, 5, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.5.0 */
#define HAVE_DEVLINK_FLASH_UPDATE_PARAMS
+#endif /* 5.5.0 */
+/*****************************************************************************/
+#if (KERNEL_VERSION(5, 6, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.6.0 */
#ifndef rtc_time_to_tm
#define rtc_time_to_tm rtc_time64_to_tm
#endif
#define HAVE_NDO_TX_TIMEOUT_TXQ
#define HAVE_PROC_OPS
+#endif /* 5.6.0 */
+/*****************************************************************************/
+#if (KERNEL_VERSION(5, 7, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.7.0 */
#define SUPPORTED_COALESCE_PARAMS
#ifndef pci_cleanup_aer_uncorrect_error_status
#define pci_cleanup_aer_uncorrect_error_status pci_aer_clear_nonfatal_status
#endif
+#endif /* 5.7.0 */
+
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 9, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.9.0 */
#define HAVE_XDP_FRAME_SZ
+#endif /* 5.9.0 */
+
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE)
+#define HAVE_DEVLINK_FW_FILE_NAME_PARAM
+#else /* >= 5.10.0 */
+#endif /* 5.10.0 */
#define HAVE_DEVLINK_FW_FILE_NAME_MEMBER
-#define HAVE_ENCAPSULATION_TSO
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.10.0 */
+#if !defined(HAVE_ETHTOOL_COALESCE_EXTACK) && \
+ !defined(NO_ETHTOOL_COALESCE_EXTACK)
+#define HAVE_ETHTOOL_COALESCE_EXTACK
+#endif
+#endif /* 5.10.0 */
+
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE)
+
+#else /* >= 5.10.0 */
+#if !defined(HAVE_ETHTOOL_RINGPARAM_EXTACK) && \
+ !defined(NO_ETHTOOL_RINGPARAM_EXTACK)
+#define HAVE_ETHTOOL_RINGPARAM_EXTACK
+#endif
+#endif /* 5.10.0 */
+/* ************************************************************************ */
+#define HAVE_NDO_UDP_TUNNEL_ADD
+#define HAVE_ENCAPSULATION_TSO
#define HAVE_ENCAPSULATION_CSUM
#ifndef eth_zero_addr
static inline void hinic3_eth_zero_addr(u8 *addr)
{
- memset(addr, 0x00, ETH_ALEN);
+ (void)memset(addr, 0x00, ETH_ALEN);
}
#define eth_zero_addr(_addr) hinic3_eth_zero_addr(_addr)
@@ -273,13 +337,10 @@ int creat_thread(struct sdk_thread_info *thread_info);
void stop_thread(struct sdk_thread_info *thread_info);
#define destroy_work(work)
-
void utctime_to_localtime(u64 utctime, u64 *localtime);
-
#ifndef HAVE_TIMER_SETUP
void initialize_timer(const void *adapter_hdl, struct timer_list *timer);
#endif
-
void add_to_timer(struct timer_list *timer, u64 period);
void stop_timer(struct timer_list *timer);
void delete_timer(struct timer_list *timer);
@@ -304,3 +365,4 @@ u64 ossl_get_real_time(void);
#define tasklet_state(tasklet) ((tasklet)->state)
#endif
+/* ************************************************************************ */
--
1.8.3.1
2
1

08 May '25
From: f30059697 <fuguiming(a)huawei.com>
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IC5K0L?from=project-issue
CVE: NA
--------------------------------
Add optical module type adaptation.
Add ethtool fec function.
Add NIC XDP PASS function.
Add QoS persistence.
Add NIC out-of-band VLAN configuration function.
Fix NIC bifur bugs.
Fix performance test bugs.
Fix NIC RX bugs.
Fix NIC VF bugs.
Fix the bug of exiting when probing NIC.
Fix bond bugs.
Fix the bug of MAC address configuration failure in OS 6.6.
Fix the bug of reading NIC status incorrectly.
Fix and add some statistics.
Signed-off-by: f30059697 <fuguiming(a)huawei.com>
---
drivers/net/ethernet/huawei/hinic3/Makefile | 1 +
drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c | 3 +-
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c | 181 ++-
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h | 1 +
drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h | 212 ---
drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h | 239 ----
drivers/net/ethernet/huawei/hinic3/comm_defs.h | 100 --
drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h | 103 --
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c | 40 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h | 2 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c | 88 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c | 29 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c | 22 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h | 185 ---
drivers/net/ethernet/huawei/hinic3/hinic3_common.h | 118 --
drivers/net/ethernet/huawei/hinic3/hinic3_crm.h | 16 +-
drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c | 298 ++--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c | 264 ++--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h | 7 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c | 252 +++-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c | 456 +++---
drivers/net/ethernet/huawei/hinic3/hinic3_filter.c | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_hw.h | 19 +
drivers/net/ethernet/huawei/hinic3/hinic3_irq.c | 39 +-
drivers/net/ethernet/huawei/hinic3/hinic3_lld.h | 205 ---
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c | 831 ++++++++++-
drivers/net/ethernet/huawei/hinic3/hinic3_main.c | 492 ++++++-
drivers/net/ethernet/huawei/hinic3/hinic3_mt.h | 218 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c | 402 ++++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic.h | 50 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c | 557 ++++++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h | 54 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c | 186 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c | 10 +
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h | 114 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c | 105 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c | 50 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c | 15 +-
drivers/net/ethernet/huawei/hinic3/hinic3_profile.h | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rss.c | 141 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c | 41 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rx.c | 311 +++-
drivers/net/ethernet/huawei/hinic3/hinic3_rx.h | 41 +-
drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h | 7 +-
drivers/net/ethernet/huawei/hinic3/hinic3_tx.c | 79 +-
drivers/net/ethernet/huawei/hinic3/hinic3_wq.h | 4 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c | 11 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c | 6 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h | 5 -
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c | 1 -
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c | 213 ++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h | 18 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c | 3 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c | 14 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c | 42 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c | 79 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h | 7 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c | 155 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c | 115 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c | 85 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h | 31 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c | 40 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c | 1247 +++++++++++++++--
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c | 3 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c | 4 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c | 41 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c | 126 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h | 4 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h | 31 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c | 56 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h | 6 +-
drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c | 1 +
drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h | 4 +
.../include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h | 11 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h | 42 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h | 2 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h | 70 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h | 141 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h | 5 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h | 88 +-
.../include/mpu/mpu_outband_ncsi_cmd_defs.h | 8 +
drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/vram_common.h | 25 +-
drivers/net/ethernet/huawei/hinic3/{mag_cmd.h => mag_mpu_cmd_defs.h} | 237 +++-
drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h | 27 -
drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h | 65 -
drivers/net/ethernet/huawei/hinic3/{hinic3_nic_cmd.h => nic_mpu_cmd.h} | 55 +-
...c3_mgmt_interface.h => nic_mpu_cmd_defs.h} | 198 ++-
drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h | 36 +
drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h | 29 +-
96 files changed, 7173 insertions(+), 2828 deletions(-)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_defs.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_common.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
rename drivers/net/ethernet/huawei/hinic3/{mag_cmd.h => mag_mpu_cmd_defs.h} (79%)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
rename drivers/net/ethernet/huawei/hinic3/{hinic3_nic_cmd.h => nic_mpu_cmd.h} (77%)
rename drivers/net/ethernet/huawei/hinic3/{hinic3_mgmt_interface.h => nic_mpu_cmd_defs.h} (86%)
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
diff --git a/drivers/net/ethernet/huawei/hinic3/Makefile b/drivers/net/ethernet/huawei/hinic3/Makefile
index 6f9ed3f..457c920 100644
--- a/drivers/net/ethernet/huawei/hinic3/Makefile
+++ b/drivers/net/ethernet/huawei/hinic3/Makefile
@@ -11,6 +11,7 @@ ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/drivers/net/ethernet/huawei/hinic3/include/mpu/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/drivers/net/ethernet/huawei/hinic3/include/bond/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/drivers/net/ethernet/huawei/hinic3/include/vmsec/
+ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/drivers/net/ethernet/huawei/hinic3/bond/
obj-$(CONFIG_HINIC3) += hinic3.o
hinic3-objs := hw/hinic3_hwdev.o \
diff --git a/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c b/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c
index cc2e4b3..440fea6 100644
--- a/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/adapter/sw_cmdq/sw_cmdq_ops.c
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_nic_cmdq.h"
#include "sw_cmdq_ops.h"
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
index e8c703b..cd6ea8e 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
@@ -9,6 +9,7 @@
#include <linux/net.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
+#include <linux/version.h>
#include "hinic3_lld.h"
#include "hinic3_srv_nic.h"
@@ -81,7 +82,7 @@ static u32 bond_gen_uplink_id(struct hinic3_bond_dev *bdev)
spin_lock(&bdev->lock);
for (i = 0; i < BOND_PORT_MAX_NUM; i++) {
if (BITMAP_JUDGE(bdev->bond_attr.slaves, i)) {
- if (!bdev->tracker.ndev[i])
+ if (bdev->tracker.ndev[i] == NULL)
continue;
nic_dev = netdev_priv(bdev->tracker.ndev[i]);
pdev = nic_dev->pdev;
@@ -109,7 +110,8 @@ static struct hinic3_nic_dev *get_nic_dev_safe(struct net_device *ndev)
return netdev_priv(ndev);
}
-static u8 bond_get_slaves_bitmap(struct hinic3_bond_dev *bdev, struct bonding *bond)
+static u8 bond_get_slaves_bitmap(struct hinic3_bond_dev *bdev,
+ struct bonding *bond)
{
struct slave *slave = NULL;
struct list_head *iter = NULL;
@@ -203,7 +205,8 @@ static u8 bond_dev_track_port(struct hinic3_bond_dev *bdev,
bdev->tracker.netdev_state[port_id].tx_enabled = 0;
if (!bdev->ppf_hwdev)
bdev->ppf_hwdev = ppf_hwdev;
- pr_info("TRACK cnt: %d, slave_name(%s)\n", bdev->tracker.cnt, ndev->name);
+ pr_info("TRACK cnt: %d, slave_name(%s)\n",
+ bdev->tracker.cnt, ndev->name);
spin_unlock(&bdev->lock);
return port_id;
@@ -268,11 +271,16 @@ static void bond_master_event(struct hinic3_bond_dev *bdev,
queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
}
-static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
+static struct hinic3_bond_dev *bond_get_bdev(struct bonding *bond)
{
struct hinic3_bond_dev *bdev = NULL;
int bid;
+ if (bond == NULL) {
+ pr_err("hinic3_bond: bond is NULL\n");
+ return NULL;
+ }
+
mutex_lock(&g_bond_mutex);
for (bid = BOND_FIRST_ID; bid <= BOND_MAX_ID; bid++) {
bdev = bond_mngr.bond_dev[bid];
@@ -283,38 +291,73 @@ static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
mutex_unlock(&g_bond_mutex);
return bdev;
}
+
+ if (strncmp(bond->dev->name,
+ bdev->name, BOND_NAME_MAX_LEN) == 0) {
+ bdev->bond = bond;
+ return bdev;
+ }
}
mutex_unlock(&g_bond_mutex);
return NULL;
}
-static void bond_handle_rtnl_event(struct net_device *ndev)
+static struct bonding *get_bonding_by_netdev(struct net_device *ndev)
{
- struct hinic3_bond_dev *bdev = NULL;
struct bonding *bond = NULL;
struct slave *slave = NULL;
if (netif_is_bond_master(ndev)) {
bond = netdev_priv(ndev);
- bdev = bond_get_bdev(bond);
} else if (netif_is_bond_slave(ndev)) {
- /*lint -e(160) */
slave = bond_slave_get_rtnl(ndev);
if (slave) {
bond = bond_get_bond_by_slave(slave);
- bdev = bond_get_bdev(bond);
}
}
- if (!bond || !bdev)
+ return bond;
+}
+/*lint -e580 -e546*/
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+
+ if (!ndev) {
+ pr_err("hinic3_bond: netdev is NULL\n");
+ return false;
+ }
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
+ return false;
+
+ return bdev->status == BOND_DEV_STATUS_ACTIVATED;
+}
+EXPORT_SYMBOL(hinic3_is_bond_dev_status_actived);
+/*lint +e580 +e546*/
+
+static void bond_handle_rtnl_event(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+ struct slave *slave = NULL;
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
return;
bond_update_attr(bdev, bond);
- if (slave)
+ if (netif_is_bond_slave(ndev)) {
+ slave = bond_slave_get_rtnl(ndev);
bond_slave_event(bdev, slave);
- else
+ } else {
bond_master_event(bdev, bond);
+ }
}
static void bond_rtnl_data_ready(struct sock *sk)
@@ -368,7 +411,8 @@ static int bond_enable_netdev_event(void)
(*rtnl_sock)->sk->sk_data_ready = bond_rtnl_data_ready;
(*rtnl_sock)->sk->sk_allocation = GFP_KERNEL;
- err = kernel_bind(*rtnl_sock, (struct sockaddr *)(u8 *)&addr, sizeof(addr));
+ err = kernel_bind(*rtnl_sock, (struct sockaddr *)(u8 *)&addr,
+ sizeof(addr));
if (err) {
pr_err("hinic3_bond: Couldn't bind rtnl socket.\n");
sock_release(*rtnl_sock);
@@ -387,7 +431,7 @@ static void bond_disable_netdev_event(void)
static int bond_send_upcmd(struct hinic3_bond_dev *bdev, struct bond_attr *attr,
u8 cmd_type)
{
- int err, len;
+ int err, ret, len;
struct hinic3_bond_cmd cmd = {0};
u16 out_size = sizeof(cmd);
@@ -403,7 +447,9 @@ static int bond_send_upcmd(struct hinic3_bond_dev *bdev, struct bond_attr *attr,
len = sizeof(cmd.bond_name);
if (cmd_type == MPU_CMD_BOND_CREATE) {
- strscpy(cmd.bond_name, bdev->name, len);
+ ret = strscpy(cmd.bond_name, bdev->name, len);
+ if (ret < 0)
+ pr_err("strscpy bond name failed\n");
cmd.bond_name[sizeof(cmd.bond_name) - 1] = '\0';
}
@@ -478,7 +524,11 @@ static void bond_update_slave_info(struct hinic3_bond_dev *bdev,
continue;
}
+ if (!bdev->tracker.ndev[i])
+ continue;
+
bond_pf_bitmap_set(bdev, i);
+
if (!bdev->tracker.netdev_state[i].tx_enabled)
continue;
@@ -516,6 +566,7 @@ static int bond_upcmd_config(struct hinic3_bond_dev *bdev,
attr->active_slaves,
attr->lacp_collect_slaves);
pr_info("bond_pf_bitmap: 0x%x\n", attr->bond_pf_bitmap);
+ pr_info("bond user_bitmap 0x%x\n", attr->user_bitmap);
err = bond_send_upcmd(bdev, attr, MPU_CMD_BOND_SET_ATTR);
if (!err)
@@ -544,8 +595,10 @@ static int bond_upcmd_activate(struct hinic3_bond_dev *bdev,
return err;
}
-static void bond_call_service_func(struct hinic3_bond_dev *bdev, struct bond_attr *attr,
- enum bond_service_proc_pos pos, int bond_status)
+static void bond_call_service_func(struct hinic3_bond_dev *bdev,
+ struct bond_attr *attr,
+ enum bond_service_proc_pos pos,
+ int bond_status)
{
int i;
@@ -560,6 +613,18 @@ static void bond_call_service_func(struct hinic3_bond_dev *bdev, struct bond_att
mutex_unlock(&g_bond_service_func_mutex);
}
+static u32 bond_get_user_bitmap(struct hinic3_bond_dev *bdev)
+{
+ u32 user_bitmap = 0;
+ u8 user;
+
+ for (user = HINIC3_BOND_USER_OVS; user < HINIC3_BOND_USER_NUM; user++) {
+ if (bdev->slot_used[user] == 1)
+ BITMAP_SET(user_bitmap, user);
+ }
+ return user_bitmap;
+}
+
static void bond_do_work(struct hinic3_bond_dev *bdev)
{
bool is_bonded = 0;
@@ -570,7 +635,7 @@ static void bond_do_work(struct hinic3_bond_dev *bdev)
is_bonded = bdev->tracker.is_bonded;
attr = bdev->new_attr;
spin_unlock(&bdev->lock);
- attr.user_bitmap = 0;
+ attr.user_bitmap = bond_get_user_bitmap(bdev);
/* is_bonded indicates whether bond should be activated. */
if (is_bonded && !bond_dev_is_activated(bdev)) {
@@ -597,15 +662,22 @@ static void bond_try_do_work(struct work_struct *work)
struct delayed_work *delayed_work = to_delayed_work(work);
struct hinic3_bond_dev *bdev =
container_of(delayed_work, struct hinic3_bond_dev, bond_work);
+ int status;
- if (g_bond_service_func[HINIC3_BOND_USER_ROCE] && bdev->tracker.cnt < MIN_BOND_SLAVE_CNT)
+ status = mutex_trylock(&g_bond_mutex);
+ if (status == 0) {
+ /* Delay 1 sec and retry */
queue_delayed_work(bdev->wq, &bdev->bond_work, HZ);
- else
+ } else {
bond_do_work(bdev);
+ mutex_unlock(&g_bond_mutex);
+ }
}
static int bond_dev_init(struct hinic3_bond_dev *bdev, const char *name)
{
+ int err = 0;
+
bdev->wq = create_singlethread_workqueue("hinic3_bond_wq");
if (!bdev->wq) {
pr_err("hinic3_bond: Failed to create workqueue\n");
@@ -614,7 +686,13 @@ static int bond_dev_init(struct hinic3_bond_dev *bdev, const char *name)
INIT_DELAYED_WORK(&bdev->bond_work, bond_try_do_work);
bdev->status = BOND_DEV_STATUS_IDLE;
- strscpy(bdev->name, name, sizeof(bdev->name));
+ err = strscpy(bdev->name, name, strlen(name));
+ if (err < 0) {
+ pr_err("hinic3_bond: Failed to init bond dev\n");
+ cancel_delayed_work_sync(&bdev->bond_work);
+ destroy_workqueue(bdev->wq);
+ return err;
+ }
spin_lock_init(&bdev->lock);
@@ -630,6 +708,7 @@ static int bond_dev_release(struct hinic3_bond_dev *bdev)
err = bond_upcmd_deactivate(bdev);
if (err) {
pr_err("hinic3_bond: Failed to deactivate dev\n");
+ mutex_unlock(&g_bond_mutex);
return err;
}
@@ -637,7 +716,8 @@ static int bond_dev_release(struct hinic3_bond_dev *bdev)
if (bond_mngr.bond_dev[i] == bdev) {
bond_mngr.bond_dev[i] = NULL;
bond_mngr.cnt--;
- pr_info("hinic3_bond: Free bond, id: %u mngr_cnt:%u\n", i, bond_mngr.cnt);
+ pr_info("hinic3_bond: Free bond, id: %u mngr_cnt:%u\n",
+ i, bond_mngr.cnt);
break;
}
}
@@ -694,7 +774,8 @@ static struct hinic3_bond_dev *bond_dev_alloc(const char *name)
bdev->bond_attr.bond_id = i;
bond_mngr.bond_dev[i] = bdev;
bond_mngr.cnt++;
- pr_info("hinic3_bond: Create bond dev, id:%u cnt:%u\n", i, bond_mngr.cnt);
+ pr_info("hinic3_bond: Create bond dev, id:%u cnt:%u\n",
+ i, bond_mngr.cnt);
break;
}
}
@@ -764,20 +845,28 @@ static struct hinic3_bond_dev *bond_dev_by_name(const char *name)
static void bond_dev_user_attach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user)
{
+ u32 user_bitmap;
+
+ if (user < 0 || user >= HINIC3_BOND_USER_NUM)
+ return;
+
if (bdev->slot_used[user])
return;
bdev->slot_used[user] = 1;
if (!kref_get_unless_zero(&bdev->ref))
kref_init(&bdev->ref);
+ else {
+ user_bitmap = bond_get_user_bitmap(bdev);
+ pr_info("hinic3_bond: user %u attach bond %s, user_bitmap %#x\n",
+ user, bdev->name, user_bitmap);
+ queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
+ }
}
static void bond_dev_user_detach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user, bool *freed)
{
- if (user < 0 || user >= HINIC3_BOND_USER_NUM)
- return;
-
if (bdev->slot_used[user]) {
bdev->slot_used[user] = 0;
if (kref_read(&bdev->ref) == 1)
@@ -790,16 +879,20 @@ static struct bonding *bond_get_knl_bonding(const char *name)
{
struct net_device *ndev_tmp = NULL;
+ rcu_read_lock();
for_each_netdev(&init_net, ndev_tmp) {
if (netif_is_bond_master(ndev_tmp) &&
- !strcmp(ndev_tmp->name, name))
+ !strcmp(ndev_tmp->name, name)) {
+ rcu_read_unlock();
return netdev_priv(ndev_tmp);
+ }
}
-
+ rcu_read_unlock();
return NULL;
}
-void hinic3_bond_set_user_bitmap(struct bond_attr *attr, enum hinic3_bond_user user)
+void hinic3_bond_set_user_bitmap(struct bond_attr *attr,
+ enum hinic3_bond_user user)
{
if (!BITMAP_JUDGE(attr->user_bitmap, user))
BITMAP_SET(attr->user_bitmap, user);
@@ -852,8 +945,9 @@ int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user)
int err = 0;
bool lock_freed = false;
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
- pr_warn("hinic3_bond: Invalid bond id:%u to delete\n", bond_id);
+ if (!BOND_ID_IS_VALID(bond_id) || user >= HINIC3_BOND_USER_NUM) {
+ pr_warn("hinic3_bond: Invalid bond id or user, bond_id: %u, user: %d\n",
+ bond_id, user);
return -EINVAL;
}
@@ -861,7 +955,8 @@ int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user)
if (!bond_mngr.bond_dev[bond_id])
err = -ENODEV;
else
- bond_dev_user_detach(bond_mngr.bond_dev[bond_id], user, &lock_freed);
+ bond_dev_user_detach(bond_mngr.bond_dev[bond_id],
+ user, &lock_freed);
if (!lock_freed)
mutex_unlock(&g_bond_mutex);
@@ -877,7 +972,8 @@ void hinic3_bond_clean_user(enum hinic3_bond_user user)
mutex_lock(&g_bond_mutex);
for (i = BOND_FIRST_ID; i <= BOND_MAX_ID; i++) {
if (bond_mngr.bond_dev[i]) {
- bond_dev_user_detach(bond_mngr.bond_dev[i], user, &lock_freed);
+ bond_dev_user_detach(bond_mngr.bond_dev[i],
+ user, &lock_freed);
if (lock_freed) {
mutex_lock(&g_bond_mutex);
lock_freed = false;
@@ -891,7 +987,7 @@ EXPORT_SYMBOL(hinic3_bond_clean_user);
int hinic3_bond_get_uplink_id(u16 bond_id, u32 *uplink_id)
{
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID || !uplink_id) {
+ if (!BOND_ID_IS_VALID(bond_id) || !uplink_id) {
pr_warn("hinic3_bond: Invalid args, id: %u, uplink: %d\n",
bond_id, !!uplink_id);
return -EINVAL;
@@ -941,7 +1037,7 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
int i;
int len;
- if (!info || bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
+ if (!info || !BOND_ID_IS_VALID(bond_id)) {
pr_warn("hinic3_bond: Invalid args, info: %d,id: %u\n",
!!info, bond_id);
return -EINVAL;
@@ -962,7 +1058,8 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
for (i = 0; i < BOND_PORT_MAX_NUM; i++) {
if (BITMAP_JUDGE(info->slaves, i) && tracker->ndev[i]) {
len = sizeof(info->slaves_name[0]);
- strscpy(info->slaves_name[info->cnt], tracker->ndev[i]->name, len);
+ strscpy(info->slaves_name[info->cnt],
+ tracker->ndev[i]->name, len);
info->cnt++;
}
}
@@ -972,7 +1069,8 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
}
EXPORT_SYMBOL(hinic3_bond_get_slaves);
-struct net_device *hinic3_bond_get_netdev_by_portid(const char *bond_name, u8 port_id)
+struct net_device *hinic3_bond_get_netdev_by_portid(const char *bond_name,
+ u8 port_id)
{
struct hinic3_bond_dev *bdev = NULL;
@@ -989,7 +1087,8 @@ struct net_device *hinic3_bond_get_netdev_by_portid(const char *bond_name, u8 po
}
EXPORT_SYMBOL(hinic3_bond_get_netdev_by_portid);
-int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos, u16 channel)
+int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos,
+ u16 channel)
{
struct comm_cmd_hw_bond_infos bond_infos;
u16 out_size = sizeof(bond_infos);
@@ -1002,7 +1101,8 @@ int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos, u1
bond_infos.infos.bond_id = infos->bond_id;
- err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_COMM, COMM_MGMT_CMD_GET_HW_BOND,
+ err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_COMM,
+ COMM_MGMT_CMD_GET_HW_BOND,
&bond_infos, sizeof(bond_infos),
&bond_infos, &out_size, 0, channel);
if (bond_infos.head.status || err || !out_size) {
@@ -1018,7 +1118,8 @@ int hinic3_get_hw_bond_infos(void *hwdev, struct hinic3_hw_bond_infos *infos, u1
}
EXPORT_SYMBOL(hinic3_get_hw_bond_infos);
-int hinic3_get_bond_tracker_by_name(const char *name, struct bond_tracker *tracker)
+int hinic3_get_bond_tracker_by_name(const char *name,
+ struct bond_tracker *tracker)
{
struct hinic3_bond_dev *bdev = NULL;
int i;
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
index 024de95..5ab36f7 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
@@ -82,6 +82,7 @@ struct hinic3_bond_cmd {
char bond_name[16];
};
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev);
void hinic3_bond_set_user_bitmap(struct bond_attr *attr, enum hinic3_bond_user user);
int hinic3_bond_attach(const char *name, enum hinic3_bond_user user, u16 *bond_id);
int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user);
diff --git a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h b/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
deleted file mode 100644
index 557f326..0000000
--- a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2016-2022. All rights reserved.
- * File name: Cfg_mgt_comm_pub.h
- * Version No.: Draft
- * Generation date: 2016 year 05 month 07 day
- * Latest modification:
- * Function description: Header file for communication between the: Host and FW
- * Function list:
- * Modification history:
- * 1. Date: 2016 May 07
- * Modify content: Create a file.
- */
-#ifndef CFG_MGT_COMM_PUB_H
-#define CFG_MGT_COMM_PUB_H
-
-#include "mgmt_msg_base.h"
-
-enum servic_bit_define {
- SERVICE_BIT_NIC = 0,
- SERVICE_BIT_ROCE = 1,
- SERVICE_BIT_VBS = 2,
- SERVICE_BIT_TOE = 3,
- SERVICE_BIT_IPSEC = 4,
- SERVICE_BIT_FC = 5,
- SERVICE_BIT_VIRTIO = 6,
- SERVICE_BIT_OVS = 7,
- SERVICE_BIT_NVME = 8,
- SERVICE_BIT_ROCEAA = 9,
- SERVICE_BIT_CURRENET = 10,
- SERVICE_BIT_PPA = 11,
- SERVICE_BIT_MIGRATE = 12,
- SERVICE_BIT_MAX
-};
-
-#define CFG_SERVICE_MASK_NIC (0x1 << SERVICE_BIT_NIC)
-#define CFG_SERVICE_MASK_ROCE (0x1 << SERVICE_BIT_ROCE)
-#define CFG_SERVICE_MASK_VBS (0x1 << SERVICE_BIT_VBS)
-#define CFG_SERVICE_MASK_TOE (0x1 << SERVICE_BIT_TOE)
-#define CFG_SERVICE_MASK_IPSEC (0x1 << SERVICE_BIT_IPSEC)
-#define CFG_SERVICE_MASK_FC (0x1 << SERVICE_BIT_FC)
-#define CFG_SERVICE_MASK_VIRTIO (0x1 << SERVICE_BIT_VIRTIO)
-#define CFG_SERVICE_MASK_OVS (0x1 << SERVICE_BIT_OVS)
-#define CFG_SERVICE_MASK_NVME (0x1 << SERVICE_BIT_NVME)
-#define CFG_SERVICE_MASK_ROCEAA (0x1 << SERVICE_BIT_ROCEAA)
-#define CFG_SERVICE_MASK_CURRENET (0x1 << SERVICE_BIT_CURRENET)
-#define CFG_SERVICE_MASK_PPA (0x1 << SERVICE_BIT_PPA)
-#define CFG_SERVICE_MASK_MIGRATE (0x1 << SERVICE_BIT_MIGRATE)
-
-/* Definition of the scenario ID in the cfg_data, which is used for SML memory allocation. */
-enum scenes_id_define {
- SCENES_ID_FPGA_ETH = 0,
- SCENES_ID_FPGA_TIOE = 1, /* Discarded */
- SCENES_ID_STORAGE_ROCEAA_2x100 = 2,
- SCENES_ID_STORAGE_ROCEAA_4x25 = 3,
- SCENES_ID_CLOUD = 4,
- SCENES_ID_FC = 5,
- SCENES_ID_STORAGE_ROCE = 6,
- SCENES_ID_COMPUTE_ROCE = 7,
- SCENES_ID_STORAGE_TOE = 8,
- SCENES_ID_MAX
-};
-
-/* struct cfg_cmd_dev_cap.sf_svc_attr */
-enum {
- SF_SVC_FT_BIT = (1 << 0),
- SF_SVC_RDMA_BIT = (1 << 1),
-};
-
-enum cfg_cmd {
- CFG_CMD_GET_DEV_CAP = 0,
- CFG_CMD_GET_HOST_TIMER = 1,
-};
-
-struct cfg_cmd_host_timer {
- struct mgmt_msg_head head;
-
- u8 host_id;
- u8 rsvd1;
-
- u8 timer_pf_num;
- u8 timer_pf_id_start;
- u16 timer_vf_num;
- u16 timer_vf_id_start;
- u32 rsvd2[8];
-};
-
-struct cfg_cmd_dev_cap {
- struct mgmt_msg_head head;
-
- u16 func_id;
- u16 rsvd1;
-
- /* Public resources */
- u8 host_id;
- u8 ep_id;
- u8 er_id;
- u8 port_id;
-
- u16 host_total_func;
- u8 host_pf_num;
- u8 pf_id_start;
- u16 host_vf_num;
- u16 vf_id_start;
- u8 host_oq_id_mask_val;
- u8 timer_en;
- u8 host_valid_bitmap;
- u8 rsvd_host;
-
- u16 svc_cap_en;
- u16 max_vf;
- u8 flexq_en;
- u8 valid_cos_bitmap;
- /* Reserved for func_valid_cos_bitmap */
- u8 port_cos_valid_bitmap;
- u8 rsvd_func1;
- u32 rsvd_func2;
-
- u8 sf_svc_attr;
- u8 func_sf_en;
- u8 lb_mode;
- u8 smf_pg;
-
- u32 max_conn_num;
- u16 max_stick2cache_num;
- u16 max_bfilter_start_addr;
- u16 bfilter_len;
- u16 hash_bucket_num;
-
- /* shared resource */
- u8 host_sf_en;
- u8 master_host_id;
- u8 srv_multi_host_mode;
- u8 virtio_vq_size;
-
- u32 rsvd_func3[5];
-
- /* l2nic */
- u16 nic_max_sq_id;
- u16 nic_max_rq_id;
- u16 nic_default_num_queues;
- u16 rsvd1_nic;
- u32 rsvd2_nic[2];
-
- /* RoCE */
- u32 roce_max_qp;
- u32 roce_max_cq;
- u32 roce_max_srq;
- u32 roce_max_mpt;
- u32 roce_max_drc_qp;
-
- u32 roce_cmtt_cl_start;
- u32 roce_cmtt_cl_end;
- u32 roce_cmtt_cl_size;
-
- u32 roce_dmtt_cl_start;
- u32 roce_dmtt_cl_end;
- u32 roce_dmtt_cl_size;
-
- u32 roce_wqe_cl_start;
- u32 roce_wqe_cl_end;
- u32 roce_wqe_cl_size;
- u8 roce_srq_container_mode;
- u8 rsvd_roce1[3];
- u32 rsvd_roce2[5];
-
- /* IPsec */
- u32 ipsec_max_sactx;
- u16 ipsec_max_cq;
- u16 rsvd_ipsec1;
- u32 rsvd_ipsec[2];
-
- /* OVS */
- u32 ovs_max_qpc;
- u32 rsvd_ovs1[3];
-
- /* ToE */
- u32 toe_max_pctx;
- u32 toe_max_cq;
- u16 toe_max_srq;
- u16 toe_srq_id_start;
- u16 toe_max_mpt;
- u16 toe_max_cctxt;
- u32 rsvd_toe[2];
-
- /* FC */
- u32 fc_max_pctx;
- u32 fc_max_scq;
- u32 fc_max_srq;
-
- u32 fc_max_cctx;
- u32 fc_cctx_id_start;
-
- u8 fc_vp_id_start;
- u8 fc_vp_id_end;
- u8 rsvd_fc1[2];
- u32 rsvd_fc2[5];
-
- /* VBS */
- u16 vbs_max_volq;
- u16 rsvd0_vbs;
- u32 rsvd1_vbs[3];
-
- u16 fake_vf_start_id;
- u16 fake_vf_num;
- u32 fake_vf_max_pctx;
- u16 fake_vf_bfilter_start_addr;
- u16 fake_vf_bfilter_len;
- u32 rsvd_glb[8];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
deleted file mode 100644
index 59e20a1..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/******************************************************************************
- * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
- ******************************************************************************
- File Name : comm_cmdq_intf.h
- Version : Initial Draft
- Description : common command queue interface
- Function List :
- History :
- Modification: Created file
-
-******************************************************************************/
-
-#ifndef COMM_CMDQ_INTF_H
-#define COMM_CMDQ_INTF_H
-
-/* Cmdq ack type */
-enum hinic3_ack_type {
- HINIC3_ACK_TYPE_CMDQ,
- HINIC3_ACK_TYPE_SHARE_CQN,
- HINIC3_ACK_TYPE_APP_CQN,
-
- HINIC3_MOD_ACK_MAX = 15,
-};
-
-/* Defines the queue type of the set arm bit. */
-enum {
- SET_ARM_BIT_FOR_CMDQ = 0,
- SET_ARM_BIT_FOR_L2NIC_SQ,
- SET_ARM_BIT_FOR_L2NIC_RQ,
- SET_ARM_BIT_TYPE_NUM
-};
-
-/* Defines the type. Each function supports a maximum of eight CMDQ types. */
-enum {
- CMDQ_0 = 0,
- CMDQ_1 = 1, /* dedicated and non-blocking queues */
- CMDQ_NUM
-};
-
-/* *******************cmd common command data structure ************************ */
-// Func->ucode, which is used to set arm bit data,
-// The microcode needs to perform big-endian conversion.
-struct comm_info_ucode_set_arm_bit {
- u32 q_type;
- u32 q_id;
-};
-
-/* *******************WQE data structure ************************ */
-union cmdq_wqe_cs_dw0 {
- struct {
- u32 err_status : 29;
- u32 error_code : 2;
- u32 rsvd : 1;
- } bs;
- u32 val;
-};
-
-union cmdq_wqe_cs_dw1 {
- // This structure is used when the driver writes the wqe.
- struct {
- u32 token : 16; // [15:0]
- u32 cmd : 8; // [23:16]
- u32 mod : 5; // [28:24]
- u32 ack_type : 2; // [30:29]
- u32 obit : 1; // [31]
- } drv_wr;
-
- /* The uCode writes back the structure of the CS_DW1. */
- /* The driver reads and uses the structure. */
- struct {
- u32 mod : 5; // [4:0]
- u32 ack_type : 3; // [7:5]
- u32 cmd : 8; // [15:8]
- u32 arm : 1; // [16]
- u32 rsvd : 14; // [30:17]
- u32 obit : 1; // [31]
- } wb;
- u32 val;
-};
-
-/* CmdQ BD information or write back buffer information */
-struct cmdq_sge {
- u32 pa_h; // Upper 32 bits of the physical address
- u32 pa_l; // Upper 32 bits of the physical address
- u32 len; // Invalid bit[31].
- u32 resv;
-};
-
-/* Ctrls section definition of WQE */
-struct cmdq_wqe_ctrls {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
-};
-
-/* Complete section definition of WQE */
-struct cmdq_wqe_cs {
- union cmdq_wqe_cs_dw0 dw0;
- union cmdq_wqe_cs_dw1 dw1;
- union {
- struct cmdq_sge sge;
- u32 dw2_5[4];
- } ack;
-};
-
-/* Inline header in WQE inline, describing the length of inline data */
-union cmdq_wqe_inline_header {
- struct {
- u32 buf_len : 11; // [10:0] inline data len
- u32 rsv : 21; // [31:11]
- } bs;
- u32 val;
-};
-
-/* Definition of buffer descriptor section in WQE */
-union cmdq_wqe_bds {
- struct {
- struct cmdq_sge bds_sge;
- u32 rsvd[4]; /* Zwy is used to transfer the virtual address of the buffer. */
- } lcmd; /* Long command, non-inline, and SGE describe the buffer information. */
-};
-
-/* Definition of CMDQ WQE */
-/* (long cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(16B) |
- * | |
- * +----------------------------------------+
- * | driver section(16B) |
- * +----------------------------------------+
- *
- *
- * (middle cmd, 128B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(88B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- *
- *
- * (short cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(24B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- */
-struct cmdq_wqe {
- struct cmdq_wqe_ctrls ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds bds;
-};
-
-/* Definition of ctrls section in inline WQE */
-struct cmdq_wqe_ctrls_inline {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
- u64 db;
-};
-
-/* Buffer descriptor section definition of WQE */
-union cmdq_wqe_bds_inline {
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[80];
- } mcmd; /* Middle command, inline mode */
-
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[16];
- } scmd; /* Short command, inline mode */
-};
-
-struct cmdq_wqe_inline {
- struct cmdq_wqe_ctrls_inline ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds_inline bds;
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_defs.h b/drivers/net/ethernet/huawei/hinic3/comm_defs.h
deleted file mode 100644
index c5b1913..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_defs.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_defs.h
- * Version : Initial Draft
- * Description : common definitions
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef COMM_DEFS_H
-#define COMM_DEFS_H
-
-/* CMDQ MODULE_TYPE */
-enum hinic3_mod_type {
- HINIC3_MOD_COMM = 0, /* HW communication module */
- HINIC3_MOD_L2NIC = 1, /* L2NIC module */
- HINIC3_MOD_ROCE = 2,
- HINIC3_MOD_PLOG = 3,
- HINIC3_MOD_TOE = 4,
- HINIC3_MOD_FLR = 5,
- HINIC3_MOD_RSVD1 = 6,
- HINIC3_MOD_CFGM = 7, /* Configuration module */
- HINIC3_MOD_CQM = 8,
- HINIC3_MOD_VMSEC = 9,
- COMM_MOD_FC = 10,
- HINIC3_MOD_OVS = 11,
- HINIC3_MOD_DSW = 12,
- HINIC3_MOD_MIGRATE = 13,
- HINIC3_MOD_HILINK = 14,
- HINIC3_MOD_CRYPT = 15, /* secure crypto module */
- HINIC3_MOD_VIO = 16,
- HINIC3_MOD_IMU = 17,
- HINIC3_MOD_DFT = 18, /* DFT */
- HINIC3_MOD_HW_MAX = 19, /* hardware max module id */
- /* Software module id, for PF/VF and multi-host */
- HINIC3_MOD_SW_FUNC = 20,
- HINIC3_MOD_MAX,
-};
-
-/* func reset的flag ,用于指示清理哪种资源 */
-enum func_reset_flag {
- RES_TYPE_FLUSH_BIT = 0,
- RES_TYPE_MQM,
- RES_TYPE_SMF,
- RES_TYPE_PF_BW_CFG,
-
- RES_TYPE_COMM = 10,
- RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_NIC,
- RES_TYPE_OVS,
- RES_TYPE_VBS,
- RES_TYPE_ROCE,
- RES_TYPE_FC,
- RES_TYPE_TOE,
- RES_TYPE_IPSEC,
- RES_TYPE_MAX,
-};
-
-#define HINIC3_COMM_RES \
- ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
- (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
- (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
-
-#define HINIC3_NIC_RES BIT(RES_TYPE_NIC)
-#define HINIC3_OVS_RES BIT(RES_TYPE_OVS)
-#define HINIC3_VBS_RES BIT(RES_TYPE_VBS)
-#define HINIC3_ROCE_RES BIT(RES_TYPE_ROCE)
-#define HINIC3_FC_RES BIT(RES_TYPE_FC)
-#define HINIC3_TOE_RES BIT(RES_TYPE_TOE)
-#define HINIC3_IPSEC_RES BIT(RES_TYPE_IPSEC)
-
-/* MODE OVS、NIC、UNKNOWN */
-#define HINIC3_WORK_MODE_OVS 0
-#define HINIC3_WORK_MODE_UNKNOWN 1
-#define HINIC3_WORK_MODE_NIC 2
-
-#define DEVICE_TYPE_L2NIC 0
-#define DEVICE_TYPE_NVME 1
-#define DEVICE_TYPE_VIRTIO_NET 2
-#define DEVICE_TYPE_VIRTIO_BLK 3
-#define DEVICE_TYPE_VIRTIO_VSOCK 4
-#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
-#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
-#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
-#define DEVICE_TYPE_VIRTIO_HPC 8
-
-/* Common header control information of the COMM message
- * interaction command word between the driver and PF
- */
-struct comm_info_head {
- u8 status;
- u8 version;
- u8 rep_aeq_num;
- u8 rsvd[5];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
deleted file mode 100644
index ae998cf..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_msg_intf.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef COMM_MSG_INTF_H
-#define COMM_MSG_INTF_H
-
-#include "comm_defs.h"
-#include "mgmt_msg_base.h"
-#include "mpu_cmd_base_defs.h"
-#include "mpu_inband_cmd_defs.h"
-
-struct spu_cmd_freq_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: check */
- u8 rsvd[3];
- u32 freq;
-};
-
-struct spu_cmd_power_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: init */
- u8 slave_addr;
- u8 cmd_id;
- u8 size;
- u32 value;
-};
-
-struct spu_cmd_tsensor_operation {
- struct comm_info_head head;
-
- u8 op_code;
- u8 rsvd[3];
- s16 fabric_tsensor_temp_avg;
- s16 fabric_tsensor_temp;
- s16 sys_tsensor_temp_avg;
- s16 sys_tsensor_temp;
-};
-
-enum cfg_msix_operation {
- CFG_MSIX_OPERATION_FREE = 0,
- CFG_MSIX_OPERATION_ALLOC = 1,
-};
-
-struct comm_cmd_ffm_info {
- struct mgmt_msg_head head;
-
- u8 node_id;
- /* error level of the interrupt source */
- u8 err_level;
- /* Classification by interrupt source properties */
- u16 err_type;
- u32 err_csr_addr;
- u32 err_csr_value;
- u32 rsvd1;
-};
-
-struct hinic3_cmd_update_firmware {
- struct mgmt_msg_head msg_head;
-
- struct {
- u32 sl : 1;
- u32 sf : 1;
- u32 flag : 1;
- u32 bit_signed : 1;
- u32 reserved : 12;
- u32 fragment_len : 16;
- } ctl_info;
-
- struct {
- u32 section_crc;
- u32 section_type;
- } section_info;
-
- u32 total_len;
- u32 section_len;
- u32 section_version;
- u32 section_offset;
- u32 data[384];
-};
-
-struct hinic3_cmd_activate_firmware {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-struct hinic3_cmd_switch_config {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
index 8c95032..8c9f849 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
@@ -28,6 +28,8 @@
#include "cqm_npu_cmd.h"
#include "cqm_npu_cmd_defs.h"
+#include "vram_common.h"
+
static void cqm_bat_fill_cla_common_gpa(struct tag_cqm_handle *cqm_handle,
struct tag_cqm_cla_table *cla_table,
struct tag_cqm_bat_entry_standerd *bat_entry_standerd)
@@ -366,6 +368,13 @@ static s32 cqm_bat_update_cmd(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
struct hinic3_hwdev *handle = cqm_handle->ex_handle;
struct tag_cqm_cmdq_bat_update *bat_update_cmd = NULL;
s32 ret = CQM_FAIL;
+ int is_in_kexec;
+
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip updating the cqm_bat to chip during kexec!\n");
+ return CQM_SUCCESS;
+ }
bat_update_cmd = (struct tag_cqm_cmdq_bat_update *)(buf_in->buf);
bat_update_cmd->offset = 0;
@@ -768,8 +777,10 @@ static s32 cqm_cla_xyz_lvl1(struct tag_cqm_handle *cqm_handle,
/* Applying for CLA_Z_BUF Space */
cla_z_buf = &cla_table->cla_z_buf;
cla_z_buf->buf_size = trunk_size;
- cla_z_buf->buf_number = (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
- cla_z_buf->page_number = cla_z_buf->buf_number << cla_table->trunk_order;
+ cla_z_buf->buf_number =
+ (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
+ cla_z_buf->page_number = cla_z_buf->buf_number <<
+ cla_table->trunk_order;
/* All buffer space must be statically allocated. */
if (cla_table->alloc_static) {
@@ -840,6 +851,7 @@ static s32 cqm_cla_xyz_lvl2_xyz_apply(struct tag_cqm_handle *cqm_handle,
cla_x_buf->buf_size = trunk_size;
cla_x_buf->buf_number = 1;
cla_x_buf->page_number = cla_x_buf->buf_number << cla_table->trunk_order;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
ret = cqm_buf_alloc(cqm_handle, cla_x_buf, false);
if (ret != CQM_SUCCESS)
return CQM_FAIL;
@@ -869,14 +881,20 @@ static s32 cqm_cla_xyz_vram_name_init(struct tag_cqm_cla_table *cla_table,
cla_x_buf = &cla_table->cla_x_buf;
cla_z_buf = &cla_table->cla_z_buf;
cla_y_buf = &cla_table->cla_y_buf;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_x_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_X);
+ VRAM_NAME_MAX_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_X);
+ cla_y_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_y_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Y);
+ VRAM_NAME_MAX_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Y);
+ cla_z_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_z_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Z);
+ VRAM_NAME_MAX_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Z);
return CQM_SUCCESS;
}
@@ -1188,7 +1206,7 @@ static void cqm_cla_init_entry_extern(struct tag_cqm_handle *cqm_handle,
* exceed 128 x 4 KB. Otherwise, clearing the timer buffer of
* the function is complex.
*/
- cla_table->trunk_order = CQM_4K_PAGE_ORDER;
+ cla_table->trunk_order = CQM_8K_PAGE_ORDER;
cla_table->max_buffer_size = capability->timer_number *
capability->timer_basic_size;
cla_table->obj_size = capability->timer_basic_size;
@@ -1237,7 +1255,7 @@ static s32 cqm_cla_init_entry_condition(struct tag_cqm_handle *cqm_handle, u32 e
memcpy(cla_table_timer, cla_table, sizeof(struct tag_cqm_cla_table));
snprintf(cla_table_timer->name,
- VRAM_NAME_MAX_LEN - 1, "%s%s%01u", cla_table->name,
+ VRAM_NAME_MAX_LEN, "%s%s%01u", cla_table->name,
VRAM_CQM_CLA_SMF_BASE, i);
if (cqm_cla_xyz(cqm_handle, cla_table_timer) ==
@@ -1268,7 +1286,7 @@ static s32 cqm_cla_init_entry(struct tag_cqm_handle *cqm_handle,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
cla_table->type = bat_table->bat_entry_type[i];
- snprintf(cla_table->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(cla_table->name, VRAM_NAME_MAX_LEN,
"%s%s%s%02u", cqm_handle->name, VRAM_CQM_CLA_BASE,
VRAM_CQM_CLA_TYPE_BASE, cla_table->type);
@@ -1485,11 +1503,11 @@ static s32 cqm_cla_update(struct tag_cqm_handle *cqm_handle,
spu_en = 0;
pa = ((buf_node_parent->pa + (child_index * sizeof(dma_addr_t))) |
- (u32)spu_en);
+ spu_en);
cmd.gpa_h = CQM_ADDR_HI(pa);
cmd.gpa_l = CQM_ADDR_LW(pa);
- pa = (buf_node_child->pa | (u32)spu_en);
+ pa = (buf_node_child->pa | spu_en);
cmd.value_h = CQM_ADDR_HI(pa);
cmd.value_l = CQM_ADDR_LW(pa);
@@ -1979,7 +1997,7 @@ struct tag_cqm_cla_table *cqm_cla_table_get(struct tag_cqm_bat_table *bat_table,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
- if (cla_table && entry_type == cla_table->type)
+ if ((cla_table != NULL) && (entry_type == cla_table->type))
return cla_table;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
index dd0766e..a51c1dc 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
@@ -9,6 +9,7 @@
#include "cqm_bitmap_table.h"
#include "cqm_object.h"
+#include "vram_common.h"
/* When the connection check is enabled, the maximum number of connections
* supported by the chip is 1M - 63, which cannot reach 1M
@@ -19,6 +20,7 @@
#define CLA_TABLE_PAGE_ORDER 0
#define CQM_4K_PAGE_ORDER 0
#define CQM_4K_PAGE_SIZE 4096
+#define CQM_8K_PAGE_ORDER 1
#define CQM_BAT_ENTRY_MAX 16
#define CQM_BAT_ENTRY_SIZE 16
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
index d5fac94..5f095c8 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
@@ -254,8 +254,10 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
}
pages = vmalloc(sizeof(struct page *) * buf->page_number);
- if (!pages)
+ if (!pages) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(pages));
return CQM_FAIL;
+ }
for (i = 0; i < buf->buf_number; i++) {
for (j = 0; j < ((u32)1 << order); j++)
@@ -273,6 +275,11 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
return CQM_SUCCESS;
}
+static bool check_use_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ return buf->buf_info.use_vram ? true : false;
+}
+
static bool check_use_non_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
{
return buf->buf_info.use_vram ? false : true;
@@ -294,11 +301,46 @@ static bool check_for_nouse_node_alloc(struct hinic3_hwdev *handle, struct tag_c
return false;
}
+static s32 cqm_buf_vram_kalloc(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ void *vaddr = NULL;
+ int i;
+
+ vaddr = hi_vram_kalloc(buf->buf_info.buf_vram_name, (u64)buf->buf_size * buf->buf_number);
+ if (!vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
+ return CQM_FAIL;
+ }
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = (void *)((char *)vaddr + i * (u64)buf->buf_size);
+
+ return CQM_SUCCESS;
+}
+
+static void cqm_buf_vram_free(struct tag_cqm_buf *buf)
+{
+ s32 i;
+
+ if (buf->buf_list == NULL)
+ return;
+
+ if (buf->buf_list[0].va)
+ hi_vram_kfree(buf->buf_list[0].va, buf->buf_info.buf_vram_name,
+ (u64)buf->buf_size * buf->buf_number);
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = NULL;
+}
+
static void cqm_buf_free_page_common(struct tag_cqm_buf *buf)
{
u32 order;
s32 i;
+ if (buf->buf_list == NULL)
+ return;
+
order = (u32)get_order(buf->buf_size);
for (i = 0; i < (s32)buf->buf_number; i++) {
@@ -320,8 +362,10 @@ static s32 cqm_buf_use_node_alloc_page(struct hinic3_hwdev *handle, struct tag_c
node = dev_to_node(handle->dev_hdl);
for (i = 0; i < (s32)buf->buf_number; i++) {
newpage = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, order);
- if (!newpage)
+ if (!newpage) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
va = (void *)page_address(newpage);
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
@@ -349,8 +393,10 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
for (i = 0; i < (s32)buf->buf_number; i++) {
va = (void *)ossl_get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
- if (!va)
+ if (!va) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
* value must be 0.
@@ -367,21 +413,21 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
return CQM_SUCCESS;
}
-#define MALLOC_FUNCS_COUNT 2
-#define FREE_FUNCS_COUNT 1
-static const struct malloc_memory g_malloc_funcs[MALLOC_FUNCS_COUNT] = {
+static const struct malloc_memory g_malloc_funcs[] = {
+ {check_use_vram, cqm_buf_vram_kalloc},
{check_for_use_node_alloc, cqm_buf_use_node_alloc_page},
{check_for_nouse_node_alloc, cqm_buf_unused_node_alloc_page}
};
-static const struct free_memory g_free_funcs[FREE_FUNCS_COUNT] = {
+static const struct free_memory g_free_funcs[] = {
+ {check_use_vram, cqm_buf_vram_free},
{check_use_non_vram, cqm_buf_free_page_common}
};
static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *buf)
{
struct hinic3_hwdev *handle = cqm_handle->ex_handle;
- u32 malloc_funcs_num = MALLOC_FUNCS_COUNT;
+ u32 malloc_funcs_num = ARRAY_SIZE(g_malloc_funcs);
u32 i;
for (i = 0; i < malloc_funcs_num; i++) {
@@ -398,7 +444,7 @@ static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
static void cqm_buf_free_page(struct tag_cqm_buf *buf)
{
- u32 free_funcs_num = FREE_FUNCS_COUNT;
+ u32 free_funcs_num = ARRAY_SIZE(g_free_funcs);
u32 i;
for (i = 0; i < free_funcs_num; i++) {
@@ -447,8 +493,11 @@ static s32 cqm_buf_get_secure_mem_pages(struct tag_cqm_handle *cqm_handle, struc
cqm_get_secure_mem_pages(handle,
(u32)get_order(buf->buf_size),
&buf->buf_list[i].pa);
- if (!buf->buf_list[i].va)
+ if (!buf->buf_list[i].va) {
+ cqm_err(handle->dev_hdl,
+ CQM_ALLOC_FAIL(cqm_get_secure_mem_pages));
break;
+ }
}
if (i != buf->buf_number) {
@@ -777,7 +826,12 @@ static s32 cqm_single_bitmap_init(struct tag_cqm_bitmap *bitmap)
*/
bit_number = (ALIGN(bitmap->max_num, CQM_NUM_BIT_BYTE) >>
CQM_BYTE_BIT_SHIFT);
- bitmap->table = vmalloc(bit_number);
+ if (bitmap->bitmap_info.use_vram != 0)
+ bitmap->table = hi_vram_kalloc(
+ bitmap->bitmap_info.buf_vram_name,
+ bit_number);
+ else
+ bitmap->table = vmalloc(bit_number);
if (!bitmap->table)
return CQM_FAIL;
memset(bitmap->table, 0, bit_number);
@@ -856,7 +910,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
}
bitmap = &cla_table->bitmap;
- snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_MAX_LEN,
"%s%s%02d", cla_table->name,
VRAM_CQM_BITMAP_BASE, cla_table->type);
@@ -866,6 +920,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
bitmap->reserved_top = capability->qpc_reserved;
bitmap->reserved_back = capability->qpc_reserved_back;
bitmap->last = capability->qpc_reserved;
+ bitmap->bitmap_info.use_vram = get_use_vram_flag();
cqm_info(handle->dev_hdl,
"Bitmap init: cla_table_type=%u, max_num=0x%x\n",
cla_table->type, bitmap->max_num);
@@ -945,7 +1000,14 @@ void cqm_bitmap_uninit(struct tag_cqm_handle *cqm_handle)
if (cla_table->type != CQM_BAT_ENTRY_T_INVALID &&
bitmap->table) {
spin_lock_deinit(&bitmap->lock);
- vfree(bitmap->table);
+ if (bitmap->bitmap_info.use_vram != 0)
+ hi_vram_kfree(bitmap->table,
+ bitmap->bitmap_info.buf_vram_name,
+ ALIGN(bitmap->max_num,
+ CQM_NUM_BIT_BYTE) >>
+ CQM_BYTE_BIT_SHIFT);
+ else
+ vfree(bitmap->table);
bitmap->table = NULL;
}
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
index 7febf76..06b8661 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
@@ -9,6 +9,7 @@
#include <linux/spinlock.h>
#include "cqm_object.h"
+#include "vram_common.h"
struct tag_cqm_bitmap {
ulong *table;
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
index 9a13ae0..2a24e4a 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
@@ -196,6 +196,13 @@ void *cqm_get_db_addr(void *ex_handle, u32 service_type)
pr_err("[CQM]%s: ex_handle is null\n", __func__);
return NULL;
}
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return NULL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -218,6 +225,17 @@ s32 cqm_ring_hardware_db(void *ex_handle, u32 service_type, u8 db_count, u64 db)
struct tag_cqm_service *service = NULL;
struct hinic3_hwdev *handle = NULL;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -278,6 +296,17 @@ s32 cqm_ring_direct_wqe_db(void *ex_handle, u32 service_type, u8 db_count,
u64 *tmp = (u64 *)direct_wqe;
int i;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
index 19a8b56..1f1235c 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
@@ -23,6 +23,8 @@
#include "cqm_memsec.h"
#include "cqm_main.h"
+#include "vram_common.h"
+
static unsigned char roce_qpc_rsv_mode = CQM_QPC_ROCE_NORMAL;
module_param(roce_qpc_rsv_mode, byte, 0644);
MODULE_PARM_DESC(roce_qpc_rsv_mode,
@@ -98,10 +100,17 @@ static s32 cqm_set_timer_enable(void *ex_handle)
{
struct hinic3_hwdev *handle = (struct hinic3_hwdev *)ex_handle;
struct tag_cqm_handle *cqm_handle = NULL;
+ int is_in_kexec;
if (!ex_handle)
return CQM_FAIL;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip starting cqm timer during kexec\n");
+ return CQM_SUCCESS;
+ }
+
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
if (cqm_handle->func_capability.fake_func_type == CQM_FAKE_FUNC_PARENT &&
cqm_set_fake_vf_timer(cqm_handle) != CQM_SUCCESS)
@@ -473,7 +482,8 @@ static void cqm_service_capability_init_roce(struct tag_cqm_handle *cqm_handle,
func_cap->qpc_number += roce_own_cap->max_qps;
func_cap->qpc_basic_size = GET_MAX(roce_own_cap->qpc_entry_sz,
func_cap->qpc_basic_size);
- if (cqm_handle->func_attribute.func_type == CQM_PF && (IS_MASTER_HOST(handle))) {
+ if (cqm_handle->func_attribute.func_type == CQM_PF &&
+ (IS_MASTER_HOST(handle))) {
func_cap->hash_number = roce_own_cap->max_qps;
func_cap->hash_basic_size = CQM_HASH_BUCKET_SIZE_64;
}
@@ -1129,8 +1139,9 @@ static s32 cqm_fake_mem_init(struct tag_cqm_handle *cqm_handle)
for (i = 0; i < (u32)child_func_number; i++) {
fake_cqm_handle = cqm_handle->fake_cqm_handle[i];
- snprintf(fake_cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
- "%s%s%02u", cqm_handle->name, VRAM_CQM_FAKE_MEM_BASE, i);
+ snprintf(fake_cqm_handle->name, VRAM_NAME_MAX_LEN,
+ "%s%s%02u", cqm_handle->name,
+ VRAM_CQM_FAKE_MEM_BASE, i);
if (cqm_bat_init(fake_cqm_handle) != CQM_SUCCESS) {
cqm_err(handle->dev_hdl,
@@ -1174,8 +1185,9 @@ s32 cqm_mem_init(void *ex_handle)
struct tag_cqm_handle *cqm_handle = NULL;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
- snprintf(cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
- "%s%02u", VRAM_CQM_GLB_FUNC_BASE, hinic3_global_func_id(handle));
+ snprintf(cqm_handle->name, VRAM_NAME_MAX_LEN,
+ "%s%02u", VRAM_CQM_GLB_FUNC_BASE,
+ hinic3_global_func_id(handle));
if (cqm_fake_init(cqm_handle) != CQM_SUCCESS) {
cqm_err(handle->dev_hdl, CQM_FUNCTION_FAIL(cqm_fake_init));
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
index 4f87bd1..8d1e481 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
@@ -362,6 +362,7 @@ s32 cqm_fake_vf_num_set(void *ex_handle, u16 fake_vf_num_cfg);
#define CQM_LOG_ID 0
#define CQM_PTR_NULL(x) "%s: " #x " is null\n", __func__
+#define CQM_ALLOC_FAIL(x) "%s: " #x " alloc fail\n", __func__
#define CQM_MAP_FAIL(x) "%s: " #x " map fail\n", __func__
#define CQM_FUNCTION_FAIL(x) "%s: " #x " return failure\n", __func__
#define CQM_WRONG_VALUE(x) "%s: " #x " %u is wrong\n", __func__, (u32)(x)
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
index 213803f..f5fce8f 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
@@ -378,7 +378,7 @@ static int hinic3_secure_mem_proc_node_remove(void *hwdev)
atomic_dec(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
@@ -401,7 +401,7 @@ static int hinic3_secure_mem_proc_node_add(void *hwdev)
atomic_inc(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
/* 0400 Read by owner */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h b/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
deleted file mode 100644
index ad732c3..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2019-2022. All rights reserved.
- * File Name : hinic3_comm_cmd.h
- * Version : Initial Draft
- * Created : 2019/4/25
- * Last Modified :
- * Description : COMM Commands between Driver and MPU
- * Function List :
- */
-
-#ifndef HINIC3_COMMON_CMD_H
-#define HINIC3_COMMON_CMD_H
-
-/* COMM Commands between Driver to MPU */
-enum hinic3_mgmt_cmd {
- /* flr及资源清理相关命令 */
- COMM_MGMT_CMD_FUNC_RESET = 0,
- COMM_MGMT_CMD_FEATURE_NEGO,
- COMM_MGMT_CMD_FLUSH_DOORBELL,
- COMM_MGMT_CMD_START_FLUSH,
- COMM_MGMT_CMD_SET_FUNC_FLR,
- COMM_MGMT_CMD_GET_GLOBAL_ATTR,
- COMM_MGMT_CMD_SET_PPF_FLR_TYPE,
- COMM_MGMT_CMD_SET_FUNC_SVC_USED_STATE,
-
- /* 分配msi-x中断资源 */
- COMM_MGMT_CMD_CFG_MSIX_NUM = 10,
-
- /* 驱动相关配置命令 */
- COMM_MGMT_CMD_SET_CMDQ_CTXT = 20,
- COMM_MGMT_CMD_SET_VAT,
- COMM_MGMT_CMD_CFG_PAGESIZE,
- COMM_MGMT_CMD_CFG_MSIX_CTRL_REG,
- COMM_MGMT_CMD_SET_CEQ_CTRL_REG,
- COMM_MGMT_CMD_SET_DMA_ATTR,
-
- /* INFRA配置相关命令字 */
- COMM_MGMT_CMD_GET_MQM_FIX_INFO = 40,
- COMM_MGMT_CMD_SET_MQM_CFG_INFO,
- COMM_MGMT_CMD_SET_MQM_SRCH_GPA,
- COMM_MGMT_CMD_SET_PPF_TMR,
- COMM_MGMT_CMD_SET_PPF_HT_GPA,
- COMM_MGMT_CMD_SET_FUNC_TMR_BITMAT,
- COMM_MGMT_CMD_SET_MBX_CRDT,
- COMM_MGMT_CMD_CFG_TEMPLATE,
- COMM_MGMT_CMD_SET_MQM_LIMIT,
-
- /* 信息获取相关命令字 */
- COMM_MGMT_CMD_GET_FW_VERSION = 60,
- COMM_MGMT_CMD_GET_BOARD_INFO,
- COMM_MGMT_CMD_SYNC_TIME,
- COMM_MGMT_CMD_GET_HW_PF_INFOS,
- COMM_MGMT_CMD_SEND_BDF_INFO,
- COMM_MGMT_CMD_GET_VIRTIO_BDF_INFO,
- COMM_MGMT_CMD_GET_SML_TABLE_INFO,
- COMM_MGMT_CMD_GET_SDI_INFO,
-
- /* 升级相关命令字 */
- COMM_MGMT_CMD_UPDATE_FW = 80,
- COMM_MGMT_CMD_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_DONE_NOTICE,
- COMM_MGMT_CMD_SWITCH_CFG,
- COMM_MGMT_CMD_CHECK_FLASH,
- COMM_MGMT_CMD_CHECK_FLASH_RW,
- COMM_MGMT_CMD_RESOURCE_CFG,
- COMM_MGMT_CMD_UPDATE_BIOS, /* TODO: merge to COMM_MGMT_CMD_UPDATE_FW */
- COMM_MGMT_CMD_MPU_GIT_CODE,
-
- /* chip reset相关 */
- COMM_MGMT_CMD_FAULT_REPORT = 100,
- COMM_MGMT_CMD_WATCHDOG_INFO,
- COMM_MGMT_CMD_MGMT_RESET,
- COMM_MGMT_CMD_FFM_SET, /* TODO: check if needed */
-
- /* chip info/log 相关 */
- COMM_MGMT_CMD_GET_LOG = 120,
- COMM_MGMT_CMD_TEMP_OP,
- COMM_MGMT_CMD_EN_AUTO_RST_CHIP,
- COMM_MGMT_CMD_CFG_REG,
- COMM_MGMT_CMD_GET_CHIP_ID,
- COMM_MGMT_CMD_SYSINFO_DFX,
- COMM_MGMT_CMD_PCIE_DFX_NTC,
- COMM_MGMT_CMD_DICT_LOG_STATUS, /* LOG STATUS 127 */
- COMM_MGMT_CMD_MSIX_INFO,
- COMM_MGMT_CMD_CHANNEL_DETECT,
- COMM_MGMT_CMD_DICT_COUNTER_STATUS,
-
- /* switch workmode 相关 */
- COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140,
- COMM_MGMT_CMD_SWITCH_WORKMODE,
-
- /* mpu 相关 */
- COMM_MGMT_CMD_MIGRATE_DFX_HPA = 150,
- COMM_MGMT_CMD_BDF_INFO,
- COMM_MGMT_CMD_NCSI_CFG_INFO_GET_PROC,
-
- /* rsvd0 section */
- COMM_MGMT_CMD_SECTION_RSVD_0 = 160,
-
- /* rsvd1 section */
- COMM_MGMT_CMD_SECTION_RSVD_1 = 170,
-
- /* rsvd2 section */
- COMM_MGMT_CMD_SECTION_RSVD_2 = 180,
-
- /* rsvd3 section */
- COMM_MGMT_CMD_SECTION_RSVD_3 = 190,
-
- /* TODO: move to DFT mode */
- COMM_MGMT_CMD_GET_DIE_ID = 200,
- COMM_MGMT_CMD_GET_EFUSE_TEST,
- COMM_MGMT_CMD_EFUSE_INFO_CFG,
- COMM_MGMT_CMD_GPIO_CTL,
- COMM_MGMT_CMD_HI30_SERLOOP_START, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_SERLOOP_STOP, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_SET_FLAG, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_GET_RESULT, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_ECC_TEST,
- COMM_MGMT_CMD_FUNC_BIST_TEST, /* 209 */
-
- COMM_MGMT_CMD_VPD_SET = 210,
- COMM_MGMT_CMD_VPD_GET,
-
- COMM_MGMT_CMD_ERASE_FLASH,
- COMM_MGMT_CMD_QUERY_FW_INFO,
- COMM_MGMT_CMD_GET_CFG_INFO,
- COMM_MGMT_CMD_GET_UART_LOG,
- COMM_MGMT_CMD_SET_UART_CMD,
- COMM_MGMT_CMD_SPI_TEST,
-
- /* TODO: ALL reg read/write merge to COMM_MGMT_CMD_CFG_REG */
- COMM_MGMT_CMD_UP_REG_GET,
- COMM_MGMT_CMD_UP_REG_SET, /* 219 */
-
- COMM_MGMT_CMD_REG_READ = 220,
- COMM_MGMT_CMD_REG_WRITE,
- COMM_MGMT_CMD_MAG_REG_WRITE,
- COMM_MGMT_CMD_ANLT_REG_WRITE,
-
- COMM_MGMT_CMD_HEART_EVENT, /* TODO: delete */
- COMM_MGMT_CMD_NCSI_OEM_GET_DRV_INFO, /* TODO: delete */
- COMM_MGMT_CMD_LASTWORD_GET,
- COMM_MGMT_CMD_READ_BIN_DATA, /* TODO: delete */
- /* COMM_MGMT_CMD_WWPN_GET, TODO: move to FC? */
- /* COMM_MGMT_CMD_WWPN_SET, TODO: move to FC? */ /* 229 */
-
- /* TODO: check if needed */
- COMM_MGMT_CMD_SET_VIRTIO_DEV = 230,
- COMM_MGMT_CMD_SET_MAC,
- /* MPU patch cmd */
- COMM_MGMT_CMD_LOAD_PATCH,
- COMM_MGMT_CMD_REMOVE_PATCH,
- COMM_MGMT_CMD_PATCH_ACTIVE,
- COMM_MGMT_CMD_PATCH_DEACTIVE,
- COMM_MGMT_CMD_PATCH_SRAM_OPTIMIZE,
- /* container host process */
- COMM_MGMT_CMD_CONTAINER_HOST_PROC,
- /* nsci counter */
- COMM_MGMT_CMD_NCSI_COUNTER_PROC,
- COMM_MGMT_CMD_CHANNEL_STATUS_CHECK, /* 239 */
-
- /* hot patch rsvd cmd */
- COMM_MGMT_CMD_RSVD_0 = 240,
- COMM_MGMT_CMD_RSVD_1,
- COMM_MGMT_CMD_RSVD_2,
- COMM_MGMT_CMD_RSVD_3,
- COMM_MGMT_CMD_RSVD_4,
- /* 无效字段,版本收编删除,编译使用 */
- COMM_MGMT_CMD_SEND_API_ACK_BY_UP,
-
- /* 注:添加cmd,不能修改已有命令字的值,请在前方rsvd
- * section中添加;原则上所有分支cmd表完全一致
- */
- COMM_MGMT_CMD_MAX = 255,
-};
-
-/* CmdQ Common subtype */
-enum comm_cmdq_cmd {
- COMM_CMD_UCODE_ARM_BIT_SET = 2,
- COMM_CMD_SEND_NPU_DFT_CMD,
-};
-
-#endif /* HINIC3_COMMON_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
deleted file mode 100644
index 9ce908e..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_COMMON_H
-#define HINIC3_COMMON_H
-
-#include <linux/types.h>
-
-struct hinic3_dma_addr_align {
- u32 real_size;
-
- void *ori_vaddr;
- dma_addr_t ori_paddr;
-
- void *align_vaddr;
- dma_addr_t align_paddr;
-};
-
-enum hinic3_wait_return {
- WAIT_PROCESS_CPL = 0,
- WAIT_PROCESS_WAITING = 1,
- WAIT_PROCESS_ERR = 2,
-};
-
-struct hinic3_sge {
- u32 hi_addr;
- u32 lo_addr;
- u32 len;
-};
-
-#ifdef static
-#undef static
-#define LLT_STATIC_DEF_SAVED
-#endif
-
-/* *
- * hinic_cpu_to_be32 - convert data to big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert, must be Multiple of 4B
- */
-static inline void hinic3_cpu_to_be32(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = cpu_to_be32(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_cpu_to_be32 - convert data from big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert
- */
-static inline void hinic3_be32_to_cpu(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = be32_to_cpu(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_set_sge - set dma area in scatter gather entry
- * @sge: scatter gather entry
- * @addr: dma address
- * @len: length of relevant data in the dma address
- */
-static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
- int len)
-{
- sge->hi_addr = upper_32_bits(addr);
- sge->lo_addr = lower_32_bits(addr);
- sge->len = len;
-}
-
-#define hinic3_hw_be32(val) (val)
-#define hinic3_hw_cpu32(val) (val)
-#define hinic3_hw_cpu16(val) (val)
-
-static inline void hinic3_hw_be32_len(void *data, int len)
-{
-}
-
-static inline void hinic3_hw_cpu32_len(void *data, int len)
-{
-}
-
-int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
- unsigned int flag,
- struct hinic3_dma_addr_align *mem_align);
-
-void hinic3_dma_free_coherent_align(void *dev_hdl,
- struct hinic3_dma_addr_align *mem_align);
-
-typedef enum hinic3_wait_return (*wait_cpl_handler)(void *priv_data);
-
-int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
- u32 wait_total_ms, u32 wait_once_us);
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
index 64139c4..4f5792f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
@@ -8,7 +8,7 @@
#include "mpu_cmd_base_defs.h"
-#define HINIC3_DRV_VERSION "15.17.1.2"
+#define HINIC3_DRV_VERSION "17.7.8.1"
#define HINIC3_DRV_DESC "Intelligent Network Interface Card Driver"
#define HIUDK_DRV_DESC "Intelligent Network Unified Driver"
@@ -45,6 +45,7 @@ enum hinic3_service_type {
SERVICE_T_CUSTOM,
SERVICE_T_VROCE,
SERVICE_T_CRYPT,
+ SERVICE_T_VSOCK,
SERVICE_T_BIFUR,
SERVICE_T_MAX,
@@ -64,6 +65,9 @@ struct nic_service_cap {
u16 max_sqs;
u16 max_rqs;
u16 default_num_queues;
+ u16 outband_vlan_cfg_en;
+ u8 lro_enable;
+ u8 rsvd1[3];
};
struct ppa_service_cap {
@@ -909,6 +913,13 @@ int hinic3_get_mgmt_version(void *hwdev, u8 *mgmt_ver, u8 version_size,
int hinic3_get_fw_version(void *hwdev, struct hinic3_fw_version *fw_ver,
u16 channel);
+/* *
+ * @brief hinic3_get_bond_create_mode - get bond create mode
+ * @param hwdev: device pointer to hwdev
+ * @retval global function id
+ */
+u8 hinic3_get_bond_create_mode(void *udkdev);
+
/* *
* @brief hinic3_global_func_id - get global function id
* @param hwdev: device pointer to hwdev
@@ -1263,4 +1274,7 @@ int hinic3_mbox_to_host_sync(void *hwdev, enum hinic3_mod_type mod,
int hinic3_get_func_vroce_enable(void *hwdev, u16 glb_func_idx, u8 *en);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type);
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
index 40ff473..8f5bb32 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
@@ -18,9 +18,10 @@
#include "hinic3_tx.h"
#include "hinic3_dcb.h"
#include "hinic3_nic.h"
-#include "hinic3_mgmt_interface.h"
+#include "hinic3_bond.h"
+#include "nic_mpu_cmd_defs.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
typedef int (*nic_driv_module)(struct hinic3_nic_dev *nic_dev,
const void *buf_in, u32 in_size,
@@ -34,7 +35,6 @@ struct nic_drv_module_handle {
static int get_nic_drv_version(void *buf_out, const u32 *out_size)
{
struct drv_version_info *ver_info = buf_out;
- int err;
if (!buf_out) {
pr_err("Buf_out is NULL.\n");
@@ -47,10 +47,8 @@ static int get_nic_drv_version(void *buf_out, const u32 *out_size)
return -EINVAL;
}
- err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
- HINIC3_NIC_DRV_VERSION, "2023-05-17_19:56:38");
- if (err < 0)
- return -EINVAL;
+ snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
+ HINIC3_NIC_DRV_VERSION, "2025-05-08_00:00:08");
return 0;
}
@@ -126,7 +124,8 @@ static int get_tx_wqe_info(struct hinic3_nic_dev *nic_dev,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -178,7 +177,8 @@ static int get_rx_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
rq_info->delta = (u16)nic_dev->rxqs[q_id].delta;
- rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx & nic_dev->rxqs[q_id].q_mask);
+ rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx &
+ nic_dev->rxqs[q_id].q_mask);
rq_info->sw_pi = nic_dev->rxqs[q_id].next_to_update;
rq_info->msix_vector = nic_dev->rxqs[q_id].irq_id;
@@ -201,7 +201,8 @@ static int get_rx_wqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -230,7 +231,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EFAULT;
}
- if (!buf_in || !buf_out) {
+ if (!buf_in || !buf_out || !out_size) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Buf_in or buf_out is NULL.\n");
return -EINVAL;
@@ -243,7 +244,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EINVAL;
}
- if (!out_size || *out_size != sizeof(struct hinic3_rq_cqe)) {
+ if (*out_size != sizeof(struct hinic3_rq_cqe)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(struct hinic3_rq_cqe));
@@ -252,10 +253,12 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
q_id = (u16)info->q_id;
idx = (u16)info->wqe_id;
- if (q_id >= nic_dev->q_params.num_qps || idx >= nic_dev->rxqs[q_id].q_depth) {
+ if (q_id >= nic_dev->q_params.num_qps ||
+ idx >= nic_dev->rxqs[q_id].q_depth) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid q_id[%u] >= %u, or wqe idx[%u] >= %u.\n",
- q_id, nic_dev->q_params.num_qps, idx, nic_dev->rxqs[q_id].q_depth);
+ q_id, nic_dev->q_params.num_qps, idx,
+ nic_dev->rxqs[q_id].q_depth);
return -EFAULT;
}
@@ -338,7 +341,8 @@ static int set_loopback_mode(struct hinic3_nic_dev *nic_dev, const void *buf_in,
err = hinic3_set_loopback_mode(nic_dev->hwdev, (u8)mode->loop_mode,
(u8)mode->loop_ctrl);
if (err == 0)
- nicif_info(nic_dev, drv, nic_dev->netdev, "Set loopback mode %u en %u succeed\n",
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Set loopback mode %u en %u succeed\n",
mode->loop_mode, mode->loop_ctrl);
return err;
@@ -417,6 +421,59 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
{
u32 pf_bw_limit;
int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
+
+ if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To set VF bandwidth rate, please use ip link cmd\n");
+ return -EINVAL;
+ }
+
+ if (!buf_in || !buf_out || in_size != sizeof(u32) ||
+ !out_size || *out_size != sizeof(u8))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_TX;
+ pf_bw_limit = *((u32 *)buf_in);
+
+ err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
+ if (err) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %u%%\n",
+ pf_bw_limit);
+ if (err < 0)
+ return err;
+ }
+
+ *((u8 *)buf_out) = (u8)err;
+
+ return 0;
+}
+
+static int set_rx_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ u32 pf_bw_limit;
+ int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
nicif_err(nic_dev, drv, nic_dev->netdev, "To set VF bandwidth rate, please use ip link cmd\n");
@@ -426,11 +483,16 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || !buf_out || in_size != sizeof(u32) || !out_size || *out_size != sizeof(u8))
return -EINVAL;
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_RX;
pf_bw_limit = *((u32 *)buf_in);
err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %d%%\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to set pf bandwidth limit to %d%%\n",
pf_bw_limit);
if (err < 0)
return err;
@@ -445,19 +507,21 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
struct hinic3_nic_io *nic_io = NULL;
+ u32 *rate_limit = (u32 *)buf_out;
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "To get VF bandwidth rate, please use ip link cmd\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To get VF bandwidth rate, please use ip link cmd\n");
return -EINVAL;
}
if (!buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(u32)) {
+ if (*out_size != sizeof(u32) * 2) { // 2:Stored in an array, TX and RX, both length are u32
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user: %d, expect: %lu\n",
- *out_size, sizeof(u32));
+ *out_size, sizeof(u32) * 2);
return -EFAULT;
}
@@ -465,8 +529,12 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!nic_io)
return -EINVAL;
- *((u32 *)buf_out) = nic_io->nic_cfg.pf_bw_limit;
+ rate_limit[HINIC3_NIC_RX] = nic_io->nic_cfg.pf_bw_rx_limit;
+ rate_limit[HINIC3_NIC_TX] = nic_io->nic_cfg.pf_bw_tx_limit;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "read rate cfg success rx rate is: %u, tx rate is : %u\n",
+ rate_limit[HINIC3_NIC_RX], rate_limit[HINIC3_NIC_TX]);
return 0;
}
@@ -477,8 +545,8 @@ static int get_sset_count(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || in_size != sizeof(u32) || !out_size ||
*out_size != sizeof(u32) || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
@@ -504,16 +572,16 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
int err;
if (!buf_in || in_size != sizeof(u32) || !out_size || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
size = sizeof(u32);
err = get_sset_count(nic_dev, buf_in, in_size, &count, &size);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Get sset count failed, ret=%d\n",
- err);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Get sset count failed, ret=%d\n", err);
return -EINVAL;
}
if (count * sizeof(*items) != *out_size) {
@@ -527,12 +595,14 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
switch (sset) {
case HINIC3_SHOW_SSET_IO_STATS:
- hinic3_get_io_stats(nic_dev, items);
+ err = hinic3_get_io_stats(nic_dev, items);
+ if (err < 0)
+ return -EINVAL;
break;
default:
- nicif_err(nic_dev, drv, nic_dev->netdev, "Unknown %u to get stats\n",
- sset);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unknown %u to get stats\n", sset);
err = -EINVAL;
break;
}
@@ -544,15 +614,18 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int i;
u8 cos_num = 0, valid_cos_bitmap = 0;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_PCP2COS) {
for (i = 0; i < NIC_DCB_UP_MAX; i++) {
- if (!(nic_dev->func_dft_cos_bitmap & BIT(qos_in->pcp2cos[i]))) {
+ if (!(dcb->func_dft_cos_bitmap &
+ BIT(qos_in->pcp2cos[i]))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- qos_in->pcp2cos[i], nic_dev->func_dft_cos_bitmap);
+ qos_in->pcp2cos[i],
+ dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -562,7 +635,8 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
}
- memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos, sizeof(qos_in->pcp2cos));
+ memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos,
+ sizeof(qos_in->pcp2cos));
wanted_dcb_cfg->pcp_user_cos_num = cos_num;
wanted_dcb_cfg->pcp_valid_cos_map = valid_cos_bitmap;
}
@@ -572,12 +646,14 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = 0;
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++) {
u8 cos = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->wanted_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ dcb->wanted_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
- if (cos >= NIC_DCB_UP_MAX || !(nic_dev->func_dft_cos_bitmap & BIT(cos))) {
+ if (cos >= NIC_DCB_UP_MAX ||
+ !(dcb->func_dft_cos_bitmap & BIT(cos))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- cos, nic_dev->func_dft_cos_bitmap);
+ cos, dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -588,8 +664,10 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- wanted_dcb_cfg->dscp2cos[i] = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->hw_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ wanted_dcb_cfg->dscp2cos[i] =
+ qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
+ dcb->hw_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
wanted_dcb_cfg->dscp_user_cos_num = cos_num;
wanted_dcb_cfg->dscp_valid_cos_map = valid_cos_bitmap;
}
@@ -601,11 +679,12 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int ret;
u8 cos_num, valid_cos_bitmap;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_TRUST) {
- if (qos_in->trust > DCB_DSCP) {
+ if (qos_in->trust > HINIC3_DCB_DSCP) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid trust=%u\n", qos_in->trust);
return -EINVAL;
@@ -615,7 +694,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
}
if (qos_in->cfg_bitmap & CMD_QOS_DEV_DFT_COS) {
- if (!(BIT(qos_in->dft_cos) & nic_dev->func_dft_cos_bitmap)) {
+ if (!(BIT(qos_in->dft_cos) & dcb->func_dft_cos_bitmap)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid dft_cos=%u\n", qos_in->dft_cos);
return -EINVAL;
@@ -628,7 +707,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
if (ret)
return ret;
- if (wanted_dcb_cfg->trust == DCB_PCP) {
+ if (wanted_dcb_cfg->trust == HINIC3_DCB_PCP) {
cos_num = wanted_dcb_cfg->pcp_user_cos_num;
valid_cos_bitmap = wanted_dcb_cfg->pcp_valid_cos_map;
} else {
@@ -636,18 +715,11 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = wanted_dcb_cfg->dscp_valid_cos_map;
}
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "DCB is on, cos num should not more than channel num:%u\n",
- nic_dev->q_params.num_qps);
- return -EOPNOTSUPP;
- }
- }
-
if (!(BIT(wanted_dcb_cfg->default_cos) & valid_cos_bitmap)) {
- nicif_info(nic_dev, drv, nic_dev->netdev, "Current default_cos=%u, change to %u\n",
- wanted_dcb_cfg->default_cos, (u8)fls(valid_cos_bitmap) - 1);
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Current default_cos=%u, change to %u\n",
+ wanted_dcb_cfg->default_cos,
+ (u8)fls(valid_cos_bitmap) - 1);
wanted_dcb_cfg->default_cos = (u8)fls(valid_cos_bitmap) - 1;
}
@@ -657,6 +729,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_dev_cfg *qos_in = buf_in;
struct hinic3_mt_qos_dev_cfg *qos_out = buf_out;
u8 i;
@@ -675,9 +748,10 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(qos_out, qos_in, sizeof(*qos_in));
qos_out->head.status = 0;
if (qos_in->op_code & MT_DCB_OPCODE_WR) {
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg,
+ memcpy(&dcb->wanted_dcb_cfg, &dcb->hw_dcb_cfg,
sizeof(struct hinic3_dcb_config));
- err = update_wanted_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg, qos_in);
+ err = update_wanted_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg,
+ qos_in);
if (err) {
qos_out->head.status = MT_EINVAL;
return 0;
@@ -687,12 +761,12 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
qos_out->head.status = MT_EIO;
} else {
- qos_out->dft_cos = nic_dev->hw_dcb_cfg.default_cos;
- qos_out->trust = nic_dev->hw_dcb_cfg.trust;
+ qos_out->dft_cos = dcb->hw_dcb_cfg.default_cos;
+ qos_out->trust = dcb->hw_dcb_cfg.trust;
for (i = 0; i < NIC_DCB_UP_MAX; i++)
- qos_out->pcp2cos[i] = nic_dev->hw_dcb_cfg.pcp2cos[i];
+ qos_out->pcp2cos[i] = dcb->hw_dcb_cfg.pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- qos_out->dscp2cos[i] = nic_dev->hw_dcb_cfg.dscp2cos[i];
+ qos_out->dscp2cos[i] = dcb->hw_dcb_cfg.dscp2cos[i];
}
return 0;
@@ -721,27 +795,17 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(dcb_out, dcb_in, sizeof(*dcb_in));
dcb_out->head.status = 0;
if (dcb_in->op_code & MT_DCB_OPCODE_WR) {
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) == dcb_in->state)
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ==
+ dcb_in->state)
return 0;
- if (dcb_in->state) {
- if (user_cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "cos num %u should not more than channel num %u\n",
- user_cos_num,
- nic_dev->q_params.num_qps);
-
- return -EOPNOTSUPP;
- }
- }
-
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? user_cos_num : 0,
+ err = hinic3_setup_cos(nic_dev->netdev,
+ dcb_in->state ? user_cos_num : 0,
netif_run);
if (err)
goto setup_cos_fail;
@@ -751,7 +815,6 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
goto vport_up_fail;
}
- rtnl_unlock();
} else {
dcb_out->state = !!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
}
@@ -759,12 +822,12 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
vport_up_fail:
- hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num,
+ netif_run);
setup_cos_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
return err;
}
@@ -772,13 +835,15 @@ setup_cos_fail:
static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_cos_cfg *cos_cfg_in = buf_in;
struct hinic3_mt_qos_cos_cfg *cos_cfg_out = buf_out;
if (!buf_in || !buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(*cos_cfg_out) || in_size != sizeof(*cos_cfg_in)) {
+ if (*out_size != sizeof(*cos_cfg_out) ||
+ in_size != sizeof(*cos_cfg_in)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
in_size, *out_size, sizeof(*cos_cfg_in));
@@ -789,9 +854,9 @@ static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
cos_cfg_out->head.status = 0;
cos_cfg_out->port_id = hinic3_physical_port_id(nic_dev->hwdev);
- cos_cfg_out->func_cos_bitmap = (u8)nic_dev->func_dft_cos_bitmap;
- cos_cfg_out->port_cos_bitmap = (u8)nic_dev->port_dft_cos_bitmap;
- cos_cfg_out->func_max_cos_num = nic_dev->cos_config_num_max;
+ cos_cfg_out->func_cos_bitmap = (u8)dcb->func_dft_cos_bitmap;
+ cos_cfg_out->port_cos_bitmap = (u8)dcb->port_dft_cos_bitmap;
+ cos_cfg_out->func_max_cos_num = dcb->cos_config_num_max;
return 0;
}
@@ -803,7 +868,13 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
intr_num = hinic3_intr_num(nic_dev->hwdev);
- if (!buf_out || !out_size || *out_size != sizeof(u16)) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != sizeof(u16)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(u16));
@@ -817,7 +888,13 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
static int get_netdev_name(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- if (!buf_out || !out_size || *out_size != IFNAMSIZ) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != IFNAMSIZ) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %u\n",
*out_size, IFNAMSIZ);
@@ -829,8 +906,9 @@ static int get_netdev_name(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
}
-static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
int *tx_timeout = buf_out;
@@ -839,7 +917,8 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (*out_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, out_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, out_size: %u, expect: %lu\n",
*out_size, sizeof(int));
return -EINVAL;
}
@@ -849,8 +928,9 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return 0;
}
-static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
const int *tx_timeout = buf_in;
@@ -859,13 +939,15 @@ static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (in_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, in_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, in_size: %u, expect: %lu\n",
in_size, sizeof(int));
return -EINVAL;
}
net_dev->watchdog_timeo = *tx_timeout * HZ;
- nicif_info(nic_dev, drv, net_dev, "Set tx timeout check period to %ds\n", *tx_timeout);
+ nicif_info(nic_dev, drv, net_dev,
+ "Set tx timeout check period to %ds\n", *tx_timeout);
return 0;
}
@@ -891,6 +973,34 @@ static int get_xsfp_present(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
}
+static int get_xsfp_tlv_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info = buf_out;
+ const struct tag_mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req = buf_in;
+ int err;
+
+ if ((buf_in == NULL) || (buf_out == NULL) || (out_size == NULL))
+ return -EINVAL;
+
+ if (*out_size != sizeof(*sfp_tlv_info) ||
+ in_size != sizeof(*sfp_tlv_info_req)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
+ in_size, *out_size, sizeof(*sfp_tlv_info));
+ return -EINVAL;
+ }
+
+ err = hinic3_get_sfp_tlv_info(nic_dev->hwdev,
+ sfp_tlv_info, sfp_tlv_info_req);
+ if (err != 0) {
+ sfp_tlv_info->head.status = MT_EIO;
+ return 0;
+ }
+
+ return 0;
+}
+
static int get_xsfp_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
@@ -928,7 +1038,7 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{GET_LOOPBACK_MODE, get_loopback_mode},
{SET_LOOPBACK_MODE, set_loopback_mode},
{SET_LINK_MODE, set_link_mode},
- {SET_PF_BW_LIMIT, set_pf_bw_limit},
+ {SET_TX_PF_BW_LIMIT, set_pf_bw_limit},
{GET_PF_BW_LIMIT, get_pf_bw_limit},
{GET_SSET_COUNT, get_sset_count},
{GET_SSET_ITEMS, get_sset_stats},
@@ -940,17 +1050,22 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{SET_TX_TIMEOUT, set_netdev_tx_timeout},
{GET_XSFP_PRESENT, get_xsfp_present},
{GET_XSFP_INFO, get_xsfp_info},
+ {GET_XSFP_INFO_COMP_CMIS, get_xsfp_tlv_info},
+ {SET_RX_PF_BW_LIMIT, set_rx_pf_bw_limit}
};
static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
u32 cmd, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(nic_driv_module_cmd_handle) /
- sizeof(nic_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(nic_driv_module_cmd_handle) /
+ sizeof(nic_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type = (enum driver_cmd_type)cmd;
int err = 0;
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_lock();
+
mutex_lock(&nic_dev->nic_mutex);
for (index = 0; index < num_cmds; index++) {
if (cmd_type ==
@@ -963,6 +1078,9 @@ static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
}
mutex_unlock(&nic_dev->nic_mutex);
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_unlock();
+
if (index == num_cmds) {
pr_err("Can't find callback for %d\n", cmd_type);
return -EINVAL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
index a1fb4af..ba4ec4d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
@@ -24,82 +24,80 @@
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_user_cos_num;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_user_cos_num;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_user_cos_num;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_user_cos_num;
return 0;
}
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_valid_cos_map;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_valid_cos_map;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_valid_cos_map;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_valid_cos_map;
return 0;
}
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
- u8 i, remainder, num_sq_per_cos, cur_cos_num = 0;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ struct hinic3_dcb_config *wanted_dcb_cfg =
+ &nic_dev->dcb->wanted_dcb_cfg;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
+ u8 cos_qp_num, cos_qp_offset = 0;
+ u8 i, remainder, num_qp_per_cos;
- if (num_cos == 0)
- return;
-
- num_sq_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
- if (num_sq_per_cos == 0)
+ if (num_cos == 0 || nic_dev->q_params.num_qps == 0)
return;
- remainder = nic_dev->q_params.num_qps % num_sq_per_cos;
+ num_qp_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
+ remainder = nic_dev->q_params.num_qps % num_cos;
- memset(dcb_cfg->cos_qp_offset, 0, sizeof(dcb_cfg->cos_qp_offset));
- memset(dcb_cfg->cos_qp_num, 0, sizeof(dcb_cfg->cos_qp_num));
+ memset(hw_dcb_cfg->cos_qp_offset, 0, sizeof(hw_dcb_cfg->cos_qp_offset));
+ memset(hw_dcb_cfg->cos_qp_num, 0, sizeof(hw_dcb_cfg->cos_qp_num));
for (i = 0; i < PCP_MAX_UP; i++) {
if (BIT(i) & valid_cos_map) {
- u8 cos_qp_num = num_sq_per_cos;
- u8 cos_qp_offset = (u8)(cur_cos_num * num_sq_per_cos);
-
- if (cur_cos_num < remainder) {
- cos_qp_num++;
- cos_qp_offset += cur_cos_num;
- } else {
- cos_qp_offset += remainder;
- }
-
- cur_cos_num++;
- valid_cos_map -= (u8)BIT(i);
+ cos_qp_num = num_qp_per_cos + ((remainder > 0) ?
+ (remainder--, 1) : 0);
- dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
- dcb_cfg->cos_qp_num[i] = cos_qp_num;
+ hw_dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
+ hw_dcb_cfg->cos_qp_num[i] = cos_qp_num;
hinic3_info(nic_dev, drv, "cos %u, cos_qp_offset=%u cos_qp_num=%u\n",
i, cos_qp_offset, cos_qp_num);
+
+ cos_qp_offset += cos_qp_num;
+ valid_cos_map -= (u8)BIT(i);
}
}
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_offset, dcb_cfg->cos_qp_offset,
- sizeof(dcb_cfg->cos_qp_offset));
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_num, dcb_cfg->cos_qp_num,
- sizeof(dcb_cfg->cos_qp_num));
+ memcpy(wanted_dcb_cfg->cos_qp_offset, hw_dcb_cfg->cos_qp_offset,
+ sizeof(hw_dcb_cfg->cos_qp_offset));
+ memcpy(wanted_dcb_cfg->cos_qp_num, hw_dcb_cfg->cos_qp_num,
+ sizeof(hw_dcb_cfg->cos_qp_num));
}
void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
u8 i;
u16 start_qid, q_num;
hinic3_set_txq_cos(nic_dev, 0, nic_dev->q_params.num_qps,
- nic_dev->hw_dcb_cfg.default_cos);
+ hw_dcb_cfg->default_cos);
if (!dcb_en)
return;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- q_num = (u16)nic_dev->hw_dcb_cfg.cos_qp_num[i];
+ q_num = (u16)hw_dcb_cfg->cos_qp_num[i];
if (q_num) {
- start_qid = (u16)nic_dev->hw_dcb_cfg.cos_qp_offset[i];
+ start_qid = (u16)hw_dcb_cfg->cos_qp_offset[i];
hinic3_set_txq_cos(nic_dev, start_qid, q_num, i);
hinic3_info(nic_dev, drv, "update tx db cos, start_qid %u, q_num=%u cos=%u\n",
@@ -110,30 +108,28 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ struct hinic3_dcb_config *hw_dcb_cfg = &dcb->hw_dcb_cfg;
struct hinic3_dcb_state dcb_state = {0};
u8 i;
int err;
-
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- /* VF does not support DCB, use the default cos */
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
-
- return 0;
- }
+ u32 pcp2cos_size = sizeof(dcb_state.pcp2cos);
+ u32 dscp2cos_size = sizeof(dcb_state.dscp2cos);
dcb_state.dcb_on = dcb_en;
- dcb_state.default_cos = dcb_cfg->default_cos;
- dcb_state.trust = dcb_cfg->trust;
+ dcb_state.default_cos = hw_dcb_cfg->default_cos;
+ dcb_state.trust = hw_dcb_cfg->trust;
if (dcb_en) {
for (i = 0; i < NIC_DCB_COS_MAX; i++)
- dcb_state.pcp2cos[i] = dcb_cfg->pcp2cos[i];
+ dcb_state.pcp2cos[i] = hw_dcb_cfg->pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- dcb_state.dscp2cos[i] = dcb_cfg->dscp2cos[i];
+ dcb_state.dscp2cos[i] = hw_dcb_cfg->dscp2cos[i];
} else {
- memset(dcb_state.pcp2cos, dcb_cfg->default_cos, sizeof(dcb_state.pcp2cos));
- memset(dcb_state.dscp2cos, dcb_cfg->default_cos, sizeof(dcb_state.dscp2cos));
+ memset(dcb_state.pcp2cos, hw_dcb_cfg->default_cos,
+ pcp2cos_size);
+ memset(dcb_state.dscp2cos, hw_dcb_cfg->default_cos,
+ dscp2cos_size);
}
err = hinic3_set_dcb_state(nic_dev->hwdev, &dcb_state);
@@ -143,7 +139,7 @@ static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
return err;
}
-static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
int err;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
@@ -169,11 +165,13 @@ static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
goto rx_configure_fail;
}
- if (dcb_en)
+ if (dcb_en) {
set_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
- else
+ set_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ } else {
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
-
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ }
return 0;
rx_configure_fail:
hinic3_set_tx_cos_state(nic_dev, dcb_en ? 0 : 1);
@@ -188,6 +186,7 @@ set_tx_cos_fail:
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err;
if (cos && test_bit(HINIC3_SAME_RXTX, &nic_dev->flags)) {
@@ -195,9 +194,10 @@ int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
return -EOPNOTSUPP;
}
- if (cos > nic_dev->cos_config_num_max) {
- nicif_err(nic_dev, drv, netdev, "Invalid num_tc: %u, max cos: %u\n",
- cos, nic_dev->cos_config_num_max);
+ if (cos > dcb->cos_config_num_max) {
+ nicif_err(nic_dev, drv, netdev,
+ "Invalid num_tc: %u, max cos: %u\n",
+ cos, dcb->cos_config_num_max);
return -EINVAL;
}
@@ -223,36 +223,48 @@ static u8 get_cos_num(u8 hw_valid_cos_bitmap)
static void hinic3_sync_dcb_cfg(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dcb_config *dcb_cfg)
{
- struct hinic3_dcb_config *hw_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
- memcpy(hw_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(hw_dcb_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
}
static int init_default_dcb_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *dcb_cfg)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 i, hw_dft_cos_map, port_cos_bitmap, dscp_ind;
int err;
+ int is_in_kexec;
- err = hinic3_cos_valid_bitmap(nic_dev->hwdev, &hw_dft_cos_map, &port_cos_bitmap);
+ err = hinic3_cos_valid_bitmap(nic_dev->hwdev,
+ &hw_dft_cos_map, &port_cos_bitmap);
if (err) {
hinic3_err(nic_dev, drv, "None cos supported\n");
return -EFAULT;
}
- nic_dev->func_dft_cos_bitmap = hw_dft_cos_map;
- nic_dev->port_dft_cos_bitmap = port_cos_bitmap;
- nic_dev->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+ is_in_kexec = vram_get_kexec_flag();
- dcb_cfg->trust = DCB_PCP;
- dcb_cfg->pcp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->dscp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
+ dcb->func_dft_cos_bitmap = hw_dft_cos_map;
+ dcb->port_dft_cos_bitmap = port_cos_bitmap;
+
+ dcb->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+
+ if (is_in_kexec == 0) {
+ dcb_cfg->trust = HINIC3_DCB_PCP;
+ dcb_cfg->default_cos = (u8)fls(dcb->func_dft_cos_bitmap) - 1;
+ } else {
+ dcb_cfg->trust = nic_dev->dcb->hw_dcb_cfg.trust;
+ dcb_cfg->default_cos = nic_dev->dcb->hw_dcb_cfg.default_cos;
+ }
+ dcb_cfg->pcp_user_cos_num = dcb->cos_config_num_max;
+ dcb_cfg->dscp_user_cos_num = dcb->cos_config_num_max;
dcb_cfg->pcp_valid_cos_map = hw_dft_cos_map;
dcb_cfg->dscp_valid_cos_map = hw_dft_cos_map;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i) ? i : dcb_cfg->default_cos;
+ dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i) ?
+ i : (u8)fls(dcb->func_dft_cos_bitmap) - 1;
for (dscp_ind = 0; dscp_ind < NIC_DCB_COS_MAX; dscp_ind++)
dcb_cfg->dscp2cos[i * NIC_DCB_DSCP_NUM + dscp_ind] = dcb_cfg->pcp2cos[i];
}
@@ -276,58 +288,117 @@ int hinic3_configure_dcb(struct net_device *netdev)
int err;
err = hinic3_sync_dcb_state(nic_dev->hwdev, 1,
- test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)
+ ? 1 : 0);
if (err) {
hinic3_err(nic_dev, drv, "Set dcb state failed\n");
return err;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ hinic3_sync_dcb_cfg(nic_dev, &nic_dev->dcb->wanted_dcb_cfg);
else
hinic3_dcb_reset_hw_config(nic_dev);
return 0;
}
+static int hinic3_dcb_alloc(struct hinic3_nic_dev *nic_dev)
+{
+ u16 func_id;
+ int is_use_vram;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(nic_dev->dcb_name, VRAM_NAME_MAX_LEN,
+ "%s%hu%s", VRAM_CQM_GLB_FUNC_BASE, func_id,
+ VRAM_NIC_DCB);
+
+ nic_dev->dcb = (struct hinic3_dcb *)hi_vram_kalloc(nic_dev->dcb_name,
+ sizeof(*nic_dev->dcb));
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to vram alloc dcb.\n");
+ return -EFAULT;
+ }
+ } else {
+ nic_dev->dcb = kzalloc(sizeof(*nic_dev->dcb), GFP_KERNEL);
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to create dcb.\n");
+ return -EFAULT;
+ }
+ }
+
+ return 0;
+}
+
+static void hinic3_dcb_free(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram)
+ hi_vram_kfree((void *)nic_dev->dcb, nic_dev->dcb_name,
+ sizeof(*nic_dev->dcb));
+ else
+ kfree(nic_dev->dcb);
+ nic_dev->dcb = NULL;
+}
+
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
+ hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+
+ hinic3_dcb_free(nic_dev);
+}
+
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = NULL;
int err;
u8 dcb_en = test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0;
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- return hinic3_set_tx_cos_state(nic_dev, dcb_en);
+ err = hinic3_dcb_alloc(nic_dev);
+ if (err != 0) {
+ hinic3_err(nic_dev, drv, "Dcb alloc failed.\n");
+ return err;
+ }
- err = init_default_dcb_cfg(nic_dev, dcb_cfg);
+ hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ err = init_default_dcb_cfg(nic_dev, hw_dcb_cfg);
if (err) {
- hinic3_err(nic_dev, drv, "Initialize dcb configuration failed\n");
+ hinic3_err(nic_dev, drv,
+ "Initialize dcb configuration failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&nic_dev->dcb->wanted_dcb_cfg, hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
hinic3_info(nic_dev, drv, "Support num cos %u, default cos %u\n",
- nic_dev->cos_config_num_max, dcb_cfg->default_cos);
+ nic_dev->dcb->cos_config_num_max, hw_dcb_cfg->default_cos);
err = hinic3_set_tx_cos_state(nic_dev, dcb_en);
if (err) {
hinic3_err(nic_dev, drv, "Set tx cos state failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- sema_init(&nic_dev->dcb_sem, 1);
-
return 0;
}
-static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dcb_config *dcb_cfg)
+static int change_qos_cfg(struct hinic3_nic_dev *nic_dev,
+ const struct hinic3_dcb_config *dcb_cfg)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err = 0;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags)) {
+ if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags)) {
nicif_warn(nic_dev, drv, netdev,
"Cos_up map setting in inprocess, please try again later\n");
return -EFAULT;
@@ -337,40 +408,44 @@ static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dc
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
- clear_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags);
+ clear_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags);
return err;
}
int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err, rollback_err;
u8 netif_run = 0;
struct hinic3_dcb_config old_dcb_cfg;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- memcpy(&old_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&old_dcb_cfg, &dcb->hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
- if (!memcmp(&nic_dev->wanted_dcb_cfg, &old_dcb_cfg, sizeof(struct hinic3_dcb_config))) {
+ if (!memcmp(&dcb->wanted_dcb_cfg, &old_dcb_cfg,
+ sizeof(struct hinic3_dcb_config))) {
nicif_info(nic_dev, drv, nic_dev->netdev,
"Same valid up bitmap, don't need to change anything\n");
return 0;
}
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = change_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ err = change_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Set cos_up map to hw failed\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Set cos_up map to hw failed\n");
goto change_qos_cfg_fail;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- err = hinic3_setup_cos(nic_dev->netdev, user_cos_num, netif_run);
+ err = hinic3_setup_cos(nic_dev->netdev,
+ user_cos_num, netif_run);
if (err)
goto set_err;
}
@@ -381,13 +456,12 @@ int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
goto vport_up_fail;
}
- rtnl_unlock();
-
return 0;
vport_up_fail:
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_setup_cos(nic_dev->netdev, user_cos_num ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, user_cos_num
+ ? 0 : user_cos_num, netif_run);
set_err:
rollback_err = change_qos_cfg(nic_dev, &old_dcb_cfg);
@@ -399,7 +473,5 @@ change_qos_cfg_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
-
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
index 7987f56..e0b35cb 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
@@ -24,11 +24,6 @@ struct hinic3_tc_cfg {
u16 rsvd;
};
-enum HINIC3_DCB_TRUST {
- DCB_PCP,
- DCB_DSCP,
-};
-
#define PCP_MAX_UP 8
#define DSCP_MAC_UP 64
#define DBG_DFLT_DSCP_VAL 0xFF
@@ -50,6 +45,7 @@ struct hinic3_dcb_config {
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev);
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev);
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev);
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev);
void hinic3_dcb_reset_hw_config(struct hinic3_nic_dev *nic_dev);
int hinic3_configure_dcb(struct net_device *netdev);
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run);
@@ -75,4 +71,5 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos);
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev);
int hinic3_vport_up(struct hinic3_nic_dev *nic_dev);
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
index 5a19959..ae41819 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
@@ -56,9 +56,8 @@ static void hinic3_get_drvinfo(struct net_device *netdev,
return;
}
- err = snprintf(info->fw_version, sizeof(info->fw_version), "%s", mgmt_ver);
- if (err < 0)
- nicif_err(nic_dev, drv, netdev, "Failed to snprintf fw version\n");
+ snprintf(info->fw_version, sizeof(info->fw_version),
+ "%s", mgmt_ver);
}
static u32 hinic3_get_msglevel(struct net_device *netdev)
@@ -86,7 +85,8 @@ static int hinic3_nway_reset(struct net_device *netdev)
while (test_and_set_bit(HINIC3_AUTONEG_RESET, &nic_dev->flags))
msleep(100); /* sleep 100 ms, waiting for another autoneg restart progress done */
- err = hinic3_get_port_info(nic_dev->hwdev, &port_info, HINIC3_CHANNEL_NIC);
+ err = hinic3_get_port_info(nic_dev->hwdev, &port_info,
+ HINIC3_CHANNEL_NIC);
if (err) {
nicif_err(nic_dev, drv, netdev, "Get port info failed\n");
err = -EFAULT;
@@ -273,7 +273,7 @@ static int get_coalesce(struct net_device *netdev,
static int set_queue_coalesce(struct hinic3_nic_dev *nic_dev, u16 q_id,
struct hinic3_intr_coal_info *coal)
{
- struct hinic3_intr_coal_info *intr_coal;
+ struct hinic3_intr_coal_info *intr_coal = NULL;
struct interrupt_info info = {0};
struct net_device *netdev = nic_dev->netdev;
int err;
@@ -367,24 +367,11 @@ static int is_coalesce_exceed_limit(struct net_device *netdev,
return 0;
}
-static int is_coalesce_legal(struct net_device *netdev,
- const struct ethtool_coalesce *coal)
+static int is_coalesce_allowed_change(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct ethtool_coalesce tmp_coal = {0};
- int err;
-
- if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
- nicif_err(nic_dev, drv, netdev,
- "tx-usecs must be equal to rx-usecs\n");
- return -EINVAL;
- }
-
- if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
- nicif_err(nic_dev, drv, netdev,
- "tx-frames must be equal to rx-frames\n");
- return -EINVAL;
- }
tmp_coal.cmd = coal->cmd;
tmp_coal.rx_coalesce_usecs = coal->rx_coalesce_usecs;
@@ -409,6 +396,31 @@ static int is_coalesce_legal(struct net_device *netdev,
return -EOPNOTSUPP;
}
+ return 0;
+}
+
+static int is_coalesce_legal(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-usecs must be equal to rx-usecs\n");
+ return -EINVAL;
+ }
+
+ if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-frames must be equal to rx-frames\n");
+ return -EINVAL;
+ }
+
+ err = is_coalesce_allowed_change(netdev, coal);
+ if (err)
+ return err;
+
err = is_coalesce_exceed_limit(netdev, coal);
if (err)
return err;
@@ -444,7 +456,8 @@ static int is_coalesce_legal(struct net_device *netdev,
return 0;
}
-static inline void check_coalesce_align(struct hinic3_nic_dev *nic_dev, struct net_device *netdev,
+static inline void check_coalesce_aligned(struct hinic3_nic_dev *nic_dev,
+ struct net_device *netdev,
u32 item, u32 unit, char *str)
{
if (item % unit)
@@ -453,10 +466,12 @@ static inline void check_coalesce_align(struct hinic3_nic_dev *nic_dev, struct n
}
#define CHECK_COALESCE_ALIGN(member, unit) \
- check_coalesce_align(nic_dev, netdev, member, unit, #member)
+ check_coalesce_aligned(nic_dev, netdev, member, unit, #member)
-static inline void check_coalesce_changed(struct hinic3_nic_dev *nic_dev, struct net_device *netdev,
- u32 item, u32 unit, u32 ori_val, char *obj_str, char *str)
+static inline void check_coalesce_changed(struct hinic3_nic_dev *nic_dev,
+ struct net_device *netdev,
+ u32 item, u32 unit, u32 ori_val,
+ char *obj_str, char *str)
{
if ((item / unit) != ori_val)
nicif_info(nic_dev, drv, netdev, "Change %s from %d to %u %s\n",
@@ -466,8 +481,10 @@ static inline void check_coalesce_changed(struct hinic3_nic_dev *nic_dev, struct
#define CHECK_COALESCE_CHANGED(member, unit, ori_val, obj_str) \
check_coalesce_changed(nic_dev, netdev, member, unit, ori_val, obj_str, #member)
-static inline void check_pkt_rate_changed(struct hinic3_nic_dev *nic_dev, struct net_device *netdev,
- u32 item, u32 ori_val, char *obj_str, char *str)
+static inline void check_pkt_rate_changed(struct hinic3_nic_dev *nic_dev,
+ struct net_device *netdev,
+ u32 item, u32 ori_val, char *obj_str,
+ char *str)
{
if (item != ori_val)
nicif_info(nic_dev, drv, netdev, "Change %s from %d to %u %s\n",
@@ -497,19 +514,10 @@ static int set_hw_coal_param(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static int set_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *coal, u16 queue)
+static void check_coalesce_align(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
- struct hinic3_intr_coal_info intr_coal = {0};
- struct hinic3_intr_coal_info *ori_intr_coal = NULL;
- u32 last_adaptive_rx;
- char obj_str[32] = {0};
- int err = 0;
-
- err = is_coalesce_legal(netdev, coal);
- if (err)
- return err;
CHECK_COALESCE_ALIGN(coal->rx_coalesce_usecs, COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal->rx_max_coalesced_frames,
@@ -522,6 +530,14 @@ static int set_coalesce(struct net_device *netdev,
COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal->rx_max_coalesced_frames_low,
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int check_coalesce_change(struct net_device *netdev,
+ u16 queue, struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info *ori_intr_coal = NULL;
+ char obj_str[32] = {0};
if (queue == COALESCE_ALL_QUEUE) {
ori_intr_coal = &nic_dev->intr_coalesce[0];
@@ -552,27 +568,54 @@ static int set_coalesce(struct net_device *netdev,
COALESCE_PENDING_LIMIT_UNIT,
ori_intr_coal->rx_pending_limt_low, obj_str);
- intr_coal.coalesce_timer_cfg =
+ return 0;
+}
+
+static void init_intr_coal_params(struct hinic3_intr_coal_info *intr_coal,
+ struct ethtool_coalesce *coal)
+{
+ intr_coal->coalesce_timer_cfg =
(u8)(coal->rx_coalesce_usecs / COALESCE_TIMER_CFG_UNIT);
- intr_coal.pending_limt = (u8)(coal->rx_max_coalesced_frames /
+ intr_coal->pending_limt = (u8)(coal->rx_max_coalesced_frames /
COALESCE_PENDING_LIMIT_UNIT);
- last_adaptive_rx = nic_dev->adaptive_rx_coal;
- nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
-
- intr_coal.pkt_rate_high = coal->pkt_rate_high;
- intr_coal.rx_usecs_high =
+ intr_coal->pkt_rate_high = coal->pkt_rate_high;
+ intr_coal->rx_usecs_high =
(u8)(coal->rx_coalesce_usecs_high / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_high =
+ intr_coal->rx_pending_limt_high =
(u8)(coal->rx_max_coalesced_frames_high /
COALESCE_PENDING_LIMIT_UNIT);
- intr_coal.pkt_rate_low = coal->pkt_rate_low;
- intr_coal.rx_usecs_low =
+ intr_coal->pkt_rate_low = coal->pkt_rate_low;
+ intr_coal->rx_usecs_low =
(u8)(coal->rx_coalesce_usecs_low / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_low =
+ intr_coal->rx_pending_limt_low =
(u8)(coal->rx_max_coalesced_frames_low /
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal, u16 queue)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info intr_coal = {0};
+ u32 last_adaptive_rx;
+ int err = 0;
+
+ err = is_coalesce_legal(netdev, coal);
+ if (err)
+ return err;
+
+ check_coalesce_align(netdev, coal);
+
+ err = check_coalesce_change(netdev, queue, coal);
+ if (err)
+ return err;
+
+ init_intr_coal_params(&intr_coal, coal);
+
+ last_adaptive_rx = nic_dev->adaptive_rx_coal;
+ nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
/* coalesce timer or pending set to zero will disable coalesce */
if (!nic_dev->adaptive_rx_coal &&
@@ -709,14 +752,16 @@ static int hinic3_set_pauseparam(struct net_device *netdev,
return -EFAULT;
}
- auto_neg = port_info.autoneg_state == PORT_CFG_AN_ON ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+ auto_neg = port_info.autoneg_state == PORT_CFG_AN_ON ?
+ AUTONEG_ENABLE : AUTONEG_DISABLE;
if (pause->autoneg != auto_neg) {
nicif_err(nic_dev, drv, netdev,
"To change autoneg please use: ethtool -s <dev> autoneg <on|off>\n");
return -EOPNOTSUPP;
}
- nic_pause.auto_neg = pause->autoneg == AUTONEG_ENABLE ? PORT_CFG_AN_ON : PORT_CFG_AN_OFF;
+ nic_pause.auto_neg = pause->autoneg == AUTONEG_ENABLE ?
+ PORT_CFG_AN_ON : PORT_CFG_AN_OFF;
nic_pause.rx_pause = (u8)pause->rx_pause;
nic_pause.tx_pause = (u8)pause->tx_pause;
@@ -768,6 +813,14 @@ static int hinic3_get_module_info(struct net_device *netdev,
modinfo->type = ETH_MODULE_SFF_8636;
modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
break;
+ case MODULE_TYPE_DSFP:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
+ case MODULE_TYPE_QSFP_CMIS:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
default:
nicif_warn(nic_dev, drv, netdev,
"Optical module unknown: 0x%x\n", sfp_type);
@@ -790,6 +843,11 @@ static int hinic3_get_module_eeprom(struct net_device *netdev,
memset(data, 0, ee->len);
err = hinic3_get_sfp_eeprom(nic_dev->hwdev, (u8 *)sfp_data, ee->len);
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(nic_dev->hwdev,
+ (u8 *)sfp_data,
+ sizeof(sfp_data));
+
if (err)
return err;
@@ -832,7 +890,8 @@ int hinic3_set_rxq_recovery_flag(struct net_device *netdev, u32 priv_flags)
if (test_and_set_bit(HINIC3_RXQ_RECOVERY, &nic_dev->flags))
return 0;
- queue_delayed_work(nic_dev->workq, &nic_dev->rxq_check_work, HZ);
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->rxq_check_work, HZ);
nicif_info(nic_dev, drv, netdev, "open rxq recovery\n");
} else {
if (!test_and_clear_bit(HINIC3_RXQ_RECOVERY, &nic_dev->flags))
@@ -888,7 +947,8 @@ static int hinic3_set_force_link_flag(struct net_device *netdev, u32 priv_flags)
nicif_info(nic_dev, link, netdev, "Set link up\n");
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, nic_dev->link_status);
+ hinic3_notify_all_vfs_link_changed(
+ nic_dev->hwdev, nic_dev->link_status);
} else {
if (!test_and_clear_bit(HINIC3_FORCE_LINK_UP, &nic_dev->flags))
return 0;
@@ -919,7 +979,8 @@ static int hinic3_set_force_link_flag(struct net_device *netdev, u32 priv_flags)
}
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, nic_dev->link_status);
+ hinic3_notify_all_vfs_link_changed(
+ nic_dev->hwdev, nic_dev->link_status);
}
return 0;
@@ -942,7 +1003,6 @@ static int hinic3_set_priv_flags(struct net_device *netdev, u32 priv_flags)
#define PORT_DOWN_ERR_IDX 0
#define LP_DEFAULT_TIME 5 /* seconds */
-#define LP_PKT_LEN 60
#define TEST_TIME_MULTIPLE 5
static int hinic3_run_lp_test(struct hinic3_nic_dev *nic_dev, u32 test_time)
@@ -958,8 +1018,11 @@ static int hinic3_run_lp_test(struct hinic3_nic_dev *nic_dev, u32 test_time)
u8 j;
skb_tmp = alloc_skb(LP_PKT_LEN, GFP_ATOMIC);
- if (!skb_tmp)
+ if (!skb_tmp) {
+ nicif_err(nic_dev, drv, netdev,
+ "Alloc xmit skb template failed for loopback test\n");
return -ENOMEM;
+ }
eth_hdr = __skb_put(skb_tmp, ETH_HLEN);
eth_hdr->h_proto = htons(ETH_P_ARP);
@@ -1057,6 +1120,8 @@ static int do_lp_test(struct hinic3_nic_dev *nic_dev, u32 *flags, u32 test_time,
lb_test_rx_buf = vmalloc(LP_PKT_CNT * LP_PKT_LEN);
if (!lb_test_rx_buf) {
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to alloc RX buffer for loopback test\n");
err = -ENOMEM;
} else {
nic_dev->lb_test_rx_buf = lb_test_rx_buf;
@@ -1086,7 +1151,8 @@ static int do_lp_test(struct hinic3_nic_dev *nic_dev, u32 *flags, u32 test_time,
return err;
}
-static void hinic3_lp_test(struct net_device *netdev, struct ethtool_test *eth_test,
+static void hinic3_lp_test(struct net_device *netdev,
+ struct ethtool_test *eth_test,
u64 *data, u32 test_time)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
@@ -1109,7 +1175,8 @@ static void hinic3_lp_test(struct net_device *netdev, struct ethtool_test *eth_t
netif_carrier_off(netdev);
netif_tx_disable(netdev);
- err = do_lp_test(nic_dev, ð_test->flags, test_time_real, &test_index);
+ err = do_lp_test(nic_dev, ð_test->flags,
+ test_time_real, &test_index);
if (err) {
eth_test->flags |= ETH_TEST_FL_FAILED;
data[test_index] = 1;
@@ -1130,10 +1197,65 @@ static void hinic3_diag_test(struct net_device *netdev,
hinic3_lp_test(netdev, eth_test, data, 0);
}
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+static int hinic3_get_fecparam(struct net_device *netdev,
+ struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u8 advertised_fec = 0;
+ u8 supported_fec = 0;
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_GFECPARAM) {
+ nicif_err(nic_dev, drv, netdev,
+ "get fecparam cmd err.exp:0x%x,real:0x%x\n",
+ ETHTOOL_GFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = get_fecparam(nic_dev->hwdev, &advertised_fec, &supported_fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Get fec param failed\n");
+ return err;
+ }
+ fecparam->active_fec = (u32)advertised_fec;
+ fecparam->fec = (u32)supported_fec;
+
+ nicif_info(nic_dev, drv, netdev, "Get fec param success\n");
+ return 0;
+}
+
+static int hinic3_set_fecparam(struct net_device *netdev,
+ struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_SFECPARAM) {
+ nicif_err(nic_dev, drv, netdev,
+ "Set fecparam cmd err.exp:0x%x,real:0x%x\n",
+ ETHTOOL_SFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = set_fecparam(nic_dev->hwdev, (u8)fecparam->fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Set fec param failed\n");
+ return err;
+ }
+
+ nicif_info(nic_dev, drv, netdev, "Set fec param success\n");
+ return 0;
+}
+#endif
+
static const struct ethtool_ops hinic3_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1180,6 +1302,10 @@ static const struct ethtool_ops hinic3_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
@@ -1240,7 +1366,10 @@ static const struct ethtool_ops_ext hinic3_ethtool_ops_ext = {
static const struct ethtool_ops hinic3vf_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1267,6 +1396,11 @@ static const struct ethtool_ops hinic3vf_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
+
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
index b0e6aad..938cf2c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
@@ -24,11 +24,29 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
-#define FPGA_PORT_COUNTER 0
-#define EVB_PORT_COUNTER 1
-u16 mag_support_mode = EVB_PORT_COUNTER;
-module_param(mag_support_mode, ushort, 0444);
-MODULE_PARM_DESC(mag_support_mode, "Set mag port counter support mode, 0:FPGA 1:EVB, default is 1");
+#define HINIC_SET_LINK_STR_LEN 128
+#define HINIC_ETHTOOL_FEC_INFO_LEN 6
+#define HINIC_SUPPORTED_FEC_CMD 0
+#define HINIC_ADVERTISED_FEC_CMD 1
+
+struct hinic3_ethtool_fec {
+ u8 hinic_fec_offset;
+ u8 ethtool_bit_offset;
+};
+
+static struct hinic3_ethtool_fec
+ hinic3_ethtool_fec_info[HINIC_ETHTOOL_FEC_INFO_LEN] = {
+ /* The ethtool does not have the corresponding enumeration variable */
+ {PORT_FEC_NOT_SET, 0xFF},
+ {PORT_FEC_RSFEC, 0x32}, /* ETHTOOL_LINK_MODE_FEC_RS_BIT */
+ /* ETHTOOL_LINK_MODE_FEC_BASER_BIT */
+ {PORT_FEC_BASEFEC, 0x33},
+ {PORT_FEC_NOFEC, 0x31}, /* ETHTOOL_LINK_MODE_FEC_NONE_BIT */
+ /* ETHTOOL_LINK_MODE_FEC_LLRS_BIT: Available only in later versions */
+ {PORT_FEC_LLRSFEC, 0x4A},
+ /* The ethtool does not have the corresponding enumeration variable */
+ {PORT_FEC_AUTO, 0XFF}
+};
struct hinic3_stats {
char name[ETH_GSTRING_LEN];
@@ -36,9 +54,23 @@ struct hinic3_stats {
int offset;
};
+struct hinic3_netdev_link_count_str {
+ u64 link_down_events_phy;
+};
+
+#define HINIC3_NETDEV_LINK_COUNT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic3_netdev_link_count_str, _stat_item), \
+ .offset = offsetof(struct hinic3_netdev_link_count_str, _stat_item) \
+}
+
+static struct hinic3_stats hinic3_netdev_link_count[] = {
+ HINIC3_NETDEV_LINK_COUNT(link_down_events_phy),
+};
+
#define HINIC3_NETDEV_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct rtnl_link_stats64, _stat_item), \
+ .size = FIELD_SIZEOF(struct rtnl_link_stats64, _stat_item), \
.offset = offsetof(struct rtnl_link_stats64, _stat_item) \
}
@@ -67,7 +99,7 @@ static struct hinic3_stats hinic3_netdev_stats[] = {
#define HINIC3_NIC_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct hinic3_nic_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_nic_stats, _stat_item), \
.offset = offsetof(struct hinic3_nic_stats, _stat_item) \
}
@@ -84,17 +116,16 @@ static struct hinic3_stats hinic3_nic_dev_stats_extern[] = {
#define HINIC3_RXQ_STAT(_stat_item) { \
.name = "rxq%d_"#_stat_item, \
- .size = sizeof_field(struct hinic3_rxq_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_rxq_stats, _stat_item), \
.offset = offsetof(struct hinic3_rxq_stats, _stat_item) \
}
#define HINIC3_TXQ_STAT(_stat_item) { \
.name = "txq%d_"#_stat_item, \
- .size = sizeof_field(struct hinic3_txq_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_txq_stats, _stat_item), \
.offset = offsetof(struct hinic3_txq_stats, _stat_item) \
}
-/*lint -save -e786*/
static struct hinic3_stats hinic3_rx_queue_stats[] = {
HINIC3_RXQ_STAT(packets),
HINIC3_RXQ_STAT(bytes),
@@ -135,11 +166,9 @@ static struct hinic3_stats hinic3_tx_queue_stats_extern[] = {
HINIC3_TXQ_STAT(rsvd2),
};
-/*lint -restore*/
-
#define HINIC3_FUNC_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct hinic3_vport_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct hinic3_vport_stats, _stat_item), \
.offset = offsetof(struct hinic3_vport_stats, _stat_item) \
}
@@ -166,7 +195,7 @@ static struct hinic3_stats hinic3_function_stats[] = {
#define HINIC3_PORT_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct mag_cmd_port_stats, _stat_item), \
+ .size = FIELD_SIZEOF(struct mag_cmd_port_stats, _stat_item), \
.offset = offsetof(struct mag_cmd_port_stats, _stat_item) \
}
@@ -260,49 +289,22 @@ static struct hinic3_stats hinic3_port_stats[] = {
HINIC3_PORT_STAT(mac_rx_unfilter_pkt_num),
};
-#define HINIC3_FGPA_PORT_STAT(_stat_item) { \
+#define HINIC3_RSFEC_STAT(_stat_item) { \
.name = #_stat_item, \
- .size = sizeof_field(struct hinic3_phy_fpga_port_stats, _stat_item), \
- .offset = offsetof(struct hinic3_phy_fpga_port_stats, _stat_item) \
+ .size = FIELD_SIZEOF(struct mag_cmd_rsfec_stats, _stat_item), \
+ .offset = offsetof(struct mag_cmd_rsfec_stats, _stat_item) \
}
-static struct hinic3_stats g_hinic3_fpga_port_stats[] = {
- HINIC3_FGPA_PORT_STAT(mac_rx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_under_frame_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_frag_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_crc_error_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_length_err_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_pause_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_unknown_mac_frame_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_underrun_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_pause_pkts_port),
+static struct hinic3_stats g_hinic3_rsfec_stats[] = {
+ HINIC3_RSFEC_STAT(rx_err_lane_phy),
};
+#define HINIC3_FGPA_PORT_STAT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic3_phy_fpga_port_stats, _stat_item), \
+ .offset = offsetof(struct hinic3_phy_fpga_port_stats, _stat_item) \
+}
+
static char g_hinic_priv_flags_strings[][ETH_GSTRING_LEN] = {
"Symmetric-RSS",
"Force-Link-up",
@@ -318,8 +320,7 @@ u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev)
(ARRAY_LEN(hinic3_tx_queue_stats) +
ARRAY_LEN(hinic3_tx_queue_stats_extern) +
ARRAY_LEN(hinic3_rx_queue_stats) +
- ARRAY_LEN(hinic3_rx_queue_stats_extern)) *
- nic_dev->max_qps;
+ ARRAY_LEN(hinic3_rx_queue_stats_extern)) * nic_dev->max_qps;
return count;
}
@@ -343,72 +344,87 @@ static int dev_stats_pack(struct hinic3_show_item *items, int len,
memcpy(items[item_idx].name, array[j].name,
HINIC3_SHOW_ITEM_LEN);
items[item_idx].hexadecimal = 0;
- items[item_idx].value = get_value_of_ptr(array[j].size,
- stats_ptr + array[j].offset);
+ items[item_idx].value =
+ get_value_of_ptr(array[j].size,
+ stats_ptr + array[j].offset);
item_idx++;
}
return item_idx;
}
-static int queue_stats_pack(struct hinic3_show_item *items, int len,
- struct hinic3_stats *array, void *stats_ptr,
- u16 qid)
+int hinic3_rx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat, struct hinic3_rxq_stats *rxq_stats, u16 qid)
{
- int j;
- int item_idx = 0;
+ snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
- for (j = 0; j < len; j++) {
- memcpy(items[item_idx].name, array[j].name,
- HINIC3_SHOW_ITEM_LEN);
- snprintf(items[item_idx].name, HINIC3_SHOW_ITEM_LEN,
- array[j].name, qid);
- items[item_idx].hexadecimal = 0;
- items[item_idx].value = get_value_of_ptr(array[j].size,
- stats_ptr + array[j].offset);
- item_idx++;
- }
+ item->hexadecimal = 0;
+ item->value = get_value_of_ptr(stat->size, (char *)(rxq_stats) +
+ stat->offset);
- return item_idx;
+ return 0;
+}
+
+int hinic3_tx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat, struct hinic3_txq_stats *txq_stats, u16 qid)
+{
+ snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
+
+ item->hexadecimal = 0;
+ item->value = get_value_of_ptr(stat->size, (char *)(txq_stats) +
+ stat->offset);
+
+ return 0;
}
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
{
struct hinic3_show_item *items = stats;
int item_idx = 0;
u16 qid;
+ int idx;
+ int ret;
- item_idx += dev_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_nic_dev_stats),
- hinic3_nic_dev_stats, &nic_dev->stats);
- item_idx += dev_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_nic_dev_stats_extern),
- hinic3_nic_dev_stats_extern,
- &nic_dev->stats);
+ dev_stats_pack(items, item_idx, hinic3_nic_dev_stats, &nic_dev->stats);
+ dev_stats_pack(items, item_idx, hinic3_nic_dev_stats_extern, &nic_dev->stats);
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_tx_queue_stats),
- hinic3_tx_queue_stats,
- &nic_dev->txqs[qid].txq_stats,
- qid);
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_tx_queue_stats_extern),
- hinic3_tx_queue_stats_extern,
- &nic_dev->txqs[qid].txq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++],
+ &hinic3_tx_queue_stats[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats_extern); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++],
+ &hinic3_tx_queue_stats_extern[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
}
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_rx_queue_stats),
- hinic3_rx_queue_stats,
- &nic_dev->rxqs[qid].rxq_stats,
- qid);
- item_idx += queue_stats_pack(&items[item_idx],
- ARRAY_LEN(hinic3_rx_queue_stats_extern),
- hinic3_rx_queue_stats_extern,
- &nic_dev->rxqs[qid].rxq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++],
+ &hinic3_rx_queue_stats[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats_extern); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++],
+ &hinic3_rx_queue_stats_extern[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
}
+
+ return 0;
}
static char g_hinic3_test_strings[][ETH_GSTRING_LEN] = {
@@ -428,16 +444,14 @@ int hinic3_get_sset_count(struct net_device *netdev, int sset)
q_num = nic_dev->q_params.num_qps;
count = ARRAY_LEN(hinic3_netdev_stats) +
ARRAY_LEN(hinic3_nic_dev_stats) +
+ ARRAY_LEN(hinic3_netdev_link_count) +
ARRAY_LEN(hinic3_function_stats) +
(ARRAY_LEN(hinic3_tx_queue_stats) +
- ARRAY_LEN(hinic3_rx_queue_stats)) *
- q_num;
+ ARRAY_LEN(hinic3_rx_queue_stats)) * q_num;
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER)
- count += ARRAY_LEN(g_hinic3_fpga_port_stats);
- else
- count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(g_hinic3_rsfec_stats);
}
return count;
@@ -486,9 +500,9 @@ static void get_drv_queue_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
}
}
-static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct hinic3_phy_fpga_port_stats *port_stats = NULL;
+ struct mag_cmd_port_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
@@ -496,19 +510,19 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
if (!port_stats) {
memset(&data[i], 0,
- ARRAY_LEN(g_hinic3_fpga_port_stats) * sizeof(*data));
- i += ARRAY_LEN(g_hinic3_fpga_port_stats);
+ ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
+ i += ARRAY_LEN(hinic3_port_stats);
return i;
}
- err = hinic3_get_fpga_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to get port stats from fw\n");
- for (j = 0; j < ARRAY_LEN(g_hinic3_fpga_port_stats); j++, i++) {
- p = (char *)(port_stats) + g_hinic3_fpga_port_stats[j].offset;
- data[i] = (g_hinic3_fpga_port_stats[j].size == sizeof(u64)) ?
+ for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
+ p = (char *)(port_stats) + hinic3_port_stats[j].offset;
+ data[i] = (hinic3_port_stats[j].size == sizeof(u64)) ?
*(u64 *)p :
*(u32 *)p;
}
@@ -518,34 +532,32 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
return i;
}
-static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_rsfec_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct mag_cmd_port_stats *port_stats = NULL;
+ struct mag_cmd_rsfec_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
- if (mag_support_mode == FPGA_PORT_COUNTER)
- return get_fpga_port_stats(nic_dev, data);
-
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
if (!port_stats) {
- memset(&data[i], 0,
- ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
- i += ARRAY_LEN(hinic3_port_stats);
- return i;
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to malloc port stats\n");
+ memset(&data[i], 0,
+ ARRAY_LEN(g_hinic3_rsfec_stats) * sizeof(*data));
+ i += ARRAY_LEN(g_hinic3_rsfec_stats);
+ return i;
}
- err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_rsfec_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to get port stats from fw\n");
+ "Failed to get rsfec stats from fw\n");
- for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
- p = (char *)(port_stats) + hinic3_port_stats[j].offset;
- data[i] = (hinic3_port_stats[j].size == sizeof(u64)) ?
- *(u64 *)p :
- *(u32 *)p;
+ for (j = 0; j < ARRAY_LEN(g_hinic3_rsfec_stats); j++, i++) {
+ p = (char *)(port_stats) + g_hinic3_rsfec_stats[j].offset;
+ data[i] = (g_hinic3_rsfec_stats[j].size ==
+ sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
kfree(port_stats);
@@ -569,6 +581,8 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
u16 i = 0, j = 0;
char *p = NULL;
int err;
+ int link_down_events_phy_tmp = 0;
+ struct hinic3_netdev_link_count_str link_count = {0};
#ifdef HAVE_NDO_GET_STATS64
net_stats = dev_get_stats(netdev, &temp);
@@ -586,6 +600,15 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = get_value_of_ptr(hinic3_nic_dev_stats[j].size, p);
}
+ err = hinic3_get_link_event_stats(nic_dev->hwdev,
+ &link_down_events_phy_tmp);
+
+ link_count.link_down_events_phy = (u64)link_down_events_phy_tmp;
+ for (j = 0; j < ARRAY_LEN(hinic3_netdev_link_count); j++, i++) {
+ p = (char *)(&link_count) + hinic3_netdev_link_count[j].offset;
+ data[i] = get_value_of_ptr(hinic3_netdev_link_count[j].size, p);
+ }
+
err = hinic3_get_vport_stats(nic_dev->hwdev,
hinic3_global_func_id(nic_dev->hwdev),
&vport_stats);
@@ -598,8 +621,10 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = get_value_of_ptr(hinic3_function_stats[j].size, p);
}
- if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
i += get_ethtool_port_stats(nic_dev, data + i);
+ i += get_ethtool_rsfec_stats(nic_dev, data + i);
+ }
get_drv_queue_stats(nic_dev, data + i);
}
@@ -620,6 +645,12 @@ static u16 get_drv_dev_strings(struct hinic3_nic_dev *nic_dev, char *p)
cnt++;
}
+ for (i = 0; i < ARRAY_LEN(hinic3_netdev_link_count); i++) {
+ memcpy(p, hinic3_netdev_link_count[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+
return cnt;
}
@@ -634,21 +665,16 @@ static u16 get_hw_stats_strings(struct hinic3_nic_dev *nic_dev, char *p)
}
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER) {
- for (i = 0; i < ARRAY_LEN(g_hinic3_fpga_port_stats);
- i++) {
- memcpy(p, g_hinic3_fpga_port_stats[i].name,
- ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
- } else {
- for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
- memcpy(p, hinic3_port_stats[i].name,
+ for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
+ memcpy(p, hinic3_port_stats[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+ for (i = 0; i < ARRAY_LEN(g_hinic3_rsfec_stats); i++) {
+ memcpy(p, g_hinic3_rsfec_stats[i].name,
ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
+ p += ETH_GSTRING_LEN;
+ cnt++;
}
}
@@ -664,7 +690,8 @@ static u16 get_qp_stats_strings(const struct hinic3_nic_dev *nic_dev, char *p)
for (j = 0; j < ARRAY_LEN(hinic3_tx_queue_stats); j++) {
err = sprintf(p, hinic3_tx_queue_stats[j].name, i);
if (err < 0)
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to sprintf tx queue stats name, idx_qps: %u, idx_stats: %u\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to sprintf tx queue stats name, idx_qps: %u, idx_stats: %u\n",
i, j);
p += ETH_GSTRING_LEN;
cnt++;
@@ -675,7 +702,8 @@ static u16 get_qp_stats_strings(const struct hinic3_nic_dev *nic_dev, char *p)
for (j = 0; j < ARRAY_LEN(hinic3_rx_queue_stats); j++) {
err = sprintf(p, hinic3_rx_queue_stats[j].name, i);
if (err < 0)
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to sprintf rx queue stats name, idx_qps: %u, idx_stats: %u\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to sprintf rx queue stats name, idx_qps: %u, idx_stats: %u\n",
i, j);
p += ETH_GSTRING_LEN;
cnt++;
@@ -791,7 +819,6 @@ struct hw2ethtool_link_mode {
u32 speed;
};
-/*lint -save -e26 */
static const struct hw2ethtool_link_mode
hw2ethtool_link_mode_table[LINK_MODE_MAX_NUMBERS] = {
[LINK_MODE_GE] = {
@@ -851,8 +878,6 @@ static const struct hw2ethtool_link_mode
},
};
-/*lint -restore */
-
#define GET_SUPPORTED_MODE 0
#define GET_ADVERTISED_MODE 1
@@ -867,21 +892,37 @@ struct cmd_link_settings {
};
#define ETHTOOL_ADD_SUPPORTED_LINK_MODE(ecmd, mode) \
- set_bit(ETHTOOL_LINK_##mode##_BIT, (ecmd)->supported)
+ set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->supported)
#define ETHTOOL_ADD_ADVERTISED_LINK_MODE(ecmd, mode) \
- set_bit(ETHTOOL_LINK_##mode##_BIT, (ecmd)->advertising)
+ set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->advertising)
-static void ethtool_add_speed_link_mode(__ETHTOOL_DECLARE_LINK_MODE_MASK(bitmap), u32 mode)
+static void ethtool_add_supported_speed_link_mode(
+ struct cmd_link_settings *link_settings,
+ u32 mode)
{
u32 i;
for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
- __ETHTOOL_LINK_MODE_MASK_NBITS)
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
continue;
+ set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
+ link_settings->supported);
+ }
+}
+static void ethtool_add_advertised_speed_link_mode(
+ struct cmd_link_settings *link_settings,
+ u32 mode)
+{
+ u32 i;
+
+ for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
+ if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
+ continue;
set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
- bitmap);
+ link_settings->advertising);
}
}
@@ -912,9 +953,11 @@ hinic3_add_ethtool_link_mode(struct cmd_link_settings *link_settings,
for (link_mode = 0; link_mode < LINK_MODE_MAX_NUMBERS; link_mode++) {
if (hw_link_mode & BIT(link_mode)) {
if (name == GET_SUPPORTED_MODE)
- ethtool_add_speed_link_mode(link_settings->supported, link_mode);
+ ethtool_add_supported_speed_link_mode(
+ link_settings, link_mode);
else
- ethtool_add_speed_link_mode(link_settings->advertising, link_mode);
+ ethtool_add_advertised_speed_link_mode(
+ link_settings, link_mode);
}
}
}
@@ -937,10 +980,15 @@ static int hinic3_link_speed_set(struct hinic3_nic_dev *nic_dev,
err = hinic3_get_link_state(nic_dev->hwdev, &link_state);
if (!err && link_state) {
- link_settings->speed =
- port_info->speed < ARRAY_LEN(hw_to_ethtool_speed) ?
+ if (hinic3_get_bond_create_mode(nic_dev->hwdev)) {
+ link_settings->speed = port_info->bond_speed;
+ } else {
+ link_settings->speed =
+ port_info->speed <
+ ARRAY_LEN(hw_to_ethtool_speed) ?
hw_to_ethtool_speed[port_info->speed] :
(u32)SPEED_UNKNOWN;
+ }
link_settings->duplex = port_info->duplex;
} else {
@@ -956,28 +1004,28 @@ static void hinic3_link_port_type(struct cmd_link_settings *link_settings,
{
switch (port_type) {
case MAG_CMD_WIRE_TYPE_ELECTRIC:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_TP);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_TP);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, TP);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, TP);
link_settings->port = PORT_TP;
break;
case MAG_CMD_WIRE_TYPE_AOC:
case MAG_CMD_WIRE_TYPE_MM:
case MAG_CMD_WIRE_TYPE_SM:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_FIBRE);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_FIBRE);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, FIBRE);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, FIBRE);
link_settings->port = PORT_FIBRE;
break;
case MAG_CMD_WIRE_TYPE_COPPER:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_FIBRE);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_FIBRE);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, FIBRE);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, FIBRE);
link_settings->port = PORT_DA;
break;
case MAG_CMD_WIRE_TYPE_BACKPLANE:
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_Backplane);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Backplane);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Backplane);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Backplane);
link_settings->port = PORT_NONE;
break;
@@ -1000,19 +1048,58 @@ static int get_link_pause_settings(struct hinic3_nic_dev *nic_dev,
return err;
}
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_Pause);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Pause);
if (nic_pause.rx_pause && nic_pause.tx_pause) {
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Pause);
} else if (nic_pause.tx_pause) {
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Asym_Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Asym_Pause);
} else if (nic_pause.rx_pause) {
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Pause);
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Asym_Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Pause);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Asym_Pause);
}
return 0;
}
+static bool is_bit_offset_defined(u8 bit_offset)
+{
+ if (bit_offset < __ETHTOOL_LINK_MODE_MASK_NBITS)
+ return true;
+ return false;
+}
+
+static void ethtool_add_supported_advertised_fec(
+ struct cmd_link_settings *link_settings, u32 fec, u8 cmd)
+{
+ u8 i;
+
+ for (i = 0; i < HINIC_ETHTOOL_FEC_INFO_LEN; i++) {
+ if ((fec & BIT(hinic3_ethtool_fec_info[i].hinic_fec_offset)) == 0)
+ continue;
+ if ((is_bit_offset_defined(
+ hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true) &&
+ (cmd == HINIC_ADVERTISED_FEC_CMD)) {
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset,
+ link_settings->advertising);
+ return; /* There can be only one advertised fec mode. */
+ }
+ if ((is_bit_offset_defined(
+ hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true) &&
+ (cmd == HINIC_SUPPORTED_FEC_CMD))
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset,
+ link_settings->supported);
+ }
+}
+
+static void hinic3_link_fec_type(struct cmd_link_settings *link_settings,
+ u32 fec, u32 supported_fec)
+{
+ ethtool_add_supported_advertised_fec(link_settings, supported_fec,
+ HINIC_SUPPORTED_FEC_CMD);
+ ethtool_add_supported_advertised_fec(link_settings, fec,
+ HINIC_ADVERTISED_FEC_CMD);
+}
+
static int get_link_settings(struct net_device *netdev,
struct cmd_link_settings *link_settings)
{
@@ -1033,13 +1120,19 @@ static int get_link_settings(struct net_device *netdev,
hinic3_link_port_type(link_settings, port_info.port_type);
+ /* port_info.fec is bit offset, value is BIT(port_info.fec);
+ * but port_info.supported_fec_mode is bit value
+ */
+ hinic3_link_fec_type(link_settings, BIT(port_info.fec),
+ port_info.supported_fec_mode);
+
link_settings->autoneg = port_info.autoneg_state == PORT_CFG_AN_ON ?
AUTONEG_ENABLE :
AUTONEG_DISABLE;
if (port_info.autoneg_cap)
- ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, MODE_Autoneg);
+ ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Autoneg);
if (port_info.autoneg_state == PORT_CFG_AN_ON)
- ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, MODE_Autoneg);
+ ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Autoneg);
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
err = get_link_pause_settings(nic_dev, link_settings);
@@ -1163,23 +1256,19 @@ static int hinic3_set_settings_to_hw(struct hinic3_nic_dev *nic_dev,
struct net_device *netdev = nic_dev->netdev;
struct hinic3_link_ksettings settings = { 0 };
int speed_level = 0;
- char set_link_str[128] = { 0 };
+ char set_link_str[HINIC_SET_LINK_STR_LEN] = {0};
+ char link_info[HINIC_SET_LINK_STR_LEN] = {0};
int err = 0;
- err = snprintf(set_link_str, sizeof(set_link_str) - 1, "%s",
+ snprintf(link_info, sizeof(link_info), "%s",
(bool)(set_settings & HILINK_LINK_SET_AUTONEG) ?
((bool)autoneg ? "autong enable " :
- "autong disable ") :
- "");
- if (err < 0)
- return -EINVAL;
+ "autong disable ") : "");
if (set_settings & HILINK_LINK_SET_SPEED) {
speed_level = hinic3_ethtool_to_hw_speed_level(speed);
- err = snprintf(set_link_str, sizeof(set_link_str) - 1,
- "%sspeed %u ", set_link_str, speed);
- if (err < 0)
- return -EINVAL;
+ snprintf(set_link_str, sizeof(set_link_str),
+ "%sspeed %u ", link_info, speed);
}
settings.valid_bitmap = set_settings;
@@ -1218,7 +1307,8 @@ static int set_link_settings(struct net_device *netdev, u8 autoneg, u32 speed)
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
int hinic3_set_link_ksettings(struct net_device *netdev,
- const struct ethtool_link_ksettings *link_settings)
+ const
+ struct ethtool_link_ksettings *link_settings)
{
/* Only support to set autoneg and speed */
return set_link_settings(netdev, link_settings->base.autoneg,
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
index 70346d6..2daa7f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
@@ -82,7 +82,7 @@ static struct hinic3_mac_filter *hinic3_add_filter(struct hinic3_nic_dev *nic_de
struct list_head *mac_filter_list,
u8 *addr)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
@@ -117,7 +117,7 @@ static void hinic3_del_filter(struct hinic3_nic_dev *nic_dev,
static struct hinic3_mac_filter *hinic3_mac_filter_entry_clone(const struct hinic3_mac_filter *src)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
index ef8c62b..a3136ce 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
@@ -40,6 +40,7 @@ enum hinic3_channel_id {
HINIC3_CHANNEL_DSW,
HINIC3_CHANNEL_MIG,
HINIC3_CHANNEL_CRYPT,
+ HINIC3_CHANNEL_VROCE,
HINIC3_CHANNEL_MAX = 32,
};
@@ -397,6 +398,16 @@ void hinic3_free_cmd_buf(void *hwdev, struct hinic3_cmd_buf *cmd_buf);
**/
int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read clear
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+
/**
* @brief hinic3_sm_ctr_rd32 - small single 32 counter read
* @param hwdev: device pointer to hwdev
@@ -810,6 +821,13 @@ int hinic3_dbg_lt_wr_16byte_mask(void *hwdev, u8 dest, u8 instance,
*/
void hinic3_link_event_stats(void *dev, u8 link);
+/**
+ * @brief hinic3_get_link_event_stats - link event stats
+ * @param hwdev: device pointer to hwdev
+ * @param link: link status
+ */
+int hinic3_get_link_event_stats(void *dev, int *link_state);
+
/**
* @brief hinic3_get_hw_pf_infos - get pf infos
* @param hwdev: device pointer to hwdev
@@ -856,4 +874,5 @@ void hinic3_set_api_stop(void *hwdev);
int hinic3_activate_firmware(void *hwdev, u8 cfg_index);
int hinic3_switch_config(void *hwdev, u8 cfg_index);
+bool hinic3_is_optical_module_mode(void *hwdev);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
index 7e59c81..6525b76 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
@@ -47,12 +47,16 @@ static void qp_add_napi(struct hinic3_irq *irq_cfg)
netif_napi_add_weight(nic_dev->netdev, &irq_cfg->napi,
hinic3_poll, nic_dev->poll_weight);
napi_enable(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_IS_REGIN;
}
-static void qp_del_napi(struct hinic3_irq *irq_cfg)
+void qp_del_napi(struct hinic3_irq *irq_cfg)
{
- napi_disable(&irq_cfg->napi);
- netif_napi_del(&irq_cfg->napi);
+ if (irq_cfg->napi_reign == NAPI_IS_REGIN) {
+ napi_disable(&irq_cfg->napi);
+ netif_napi_del(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_NOT_REGIN;
+ }
}
static irqreturn_t qp_irq(int irq, void *data)
@@ -60,7 +64,8 @@ static irqreturn_t qp_irq(int irq, void *data)
struct hinic3_irq *irq_cfg = (struct hinic3_irq *)data;
struct hinic3_nic_dev *nic_dev = netdev_priv(irq_cfg->netdev);
- hinic3_misx_intr_clear_resend_bit(nic_dev->hwdev, irq_cfg->msix_entry_idx, 1);
+ hinic3_misx_intr_clear_resend_bit(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx, 1);
napi_schedule(&irq_cfg->napi);
@@ -95,7 +100,8 @@ static int hinic3_request_irq(struct hinic3_irq *irq_cfg, u16 q_id)
return err;
}
- err = request_irq(irq_cfg->irq_id, &qp_irq, 0, irq_cfg->irq_name, irq_cfg);
+ err = request_irq(irq_cfg->irq_id, &qp_irq, 0,
+ irq_cfg->irq_name, irq_cfg);
if (err) {
nicif_err(nic_dev, drv, irq_cfg->netdev, "Failed to request Rx irq\n");
qp_del_napi(irq_cfg);
@@ -138,12 +144,8 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev)
local_cpu = cpumask_local_spread(q_id, dev_to_node(&pdev->dev));
cpumask_set_cpu(local_cpu, &irq_cfg->affinity_mask);
- err = snprintf(irq_cfg->irq_name, sizeof(irq_cfg->irq_name),
- "%s_qp%u", nic_dev->netdev->name, q_id);
- if (err < 0) {
- err = -EINVAL;
- goto req_tx_irq_err;
- }
+ snprintf(irq_cfg->irq_name, sizeof(irq_cfg->irq_name),
+ "%s_qp%u", nic_dev->netdev->name, q_id);
err = hinic3_request_irq(irq_cfg, q_id);
if (err) {
@@ -151,20 +153,25 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev)
goto req_tx_irq_err;
}
- hinic3_set_msix_auto_mask_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ hinic3_set_msix_auto_mask_state(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx,
HINIC3_SET_MSIX_AUTO_MASK);
- hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx, HINIC3_MSIX_ENABLE);
+ hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ HINIC3_MSIX_ENABLE);
}
- INIT_DELAYED_WORK(&nic_dev->moderation_task, hinic3_auto_moderation_work);
+ INIT_DELAYED_WORK(&nic_dev->moderation_task,
+ hinic3_auto_moderation_work);
return 0;
req_tx_irq_err:
for (i = 0; i < q_id; i++) {
irq_cfg = &nic_dev->q_params.irq_cfg[i];
- hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx, HINIC3_MSIX_DISABLE);
- hinic3_set_msix_auto_mask_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx,
+ HINIC3_MSIX_DISABLE);
+ hinic3_set_msix_auto_mask_state(nic_dev->hwdev,
+ irq_cfg->msix_entry_idx,
HINIC3_CLR_MSIX_AUTO_MASK);
hinic3_release_irq(irq_cfg);
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
deleted file mode 100644
index 2482c5f..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_LLD_H
-#define HINIC3_LLD_H
-
-#include "hinic3_crm.h"
-
-struct hinic3_lld_dev {
- struct pci_dev *pdev;
- void *hwdev;
-};
-
-struct hinic3_uld_info {
- /* When the function does not need to initialize the corresponding uld,
- * @probe needs to return 0 and uld_dev is set to NULL;
- * if uld_dev is NULL, @remove will not be called when uninstalling
- */
- int (*probe)(struct hinic3_lld_dev *lld_dev, void **uld_dev, char *uld_dev_name);
- void (*remove)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- int (*suspend)(struct hinic3_lld_dev *lld_dev, void *uld_dev, pm_message_t state);
- int (*resume)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- void (*event)(struct hinic3_lld_dev *lld_dev, void *uld_dev,
- struct hinic3_event_info *event);
- int (*ioctl)(void *uld_dev, u32 cmd, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size);
-};
-
-/* hinic3_register_uld - register an upper-layer driver
- * @type: uld service type
- * @uld_info: uld callback
- *
- * Registers an upper-layer driver.
- * Traverse existing devices and call @probe to initialize the uld device.
- */
-int hinic3_register_uld(enum hinic3_service_type type, struct hinic3_uld_info *uld_info);
-
-/**
- * hinic3_unregister_uld - unregister an upper-layer driver
- * @type: uld service type
- *
- * Traverse existing devices and call @remove to uninstall the uld device.
- * Unregisters an existing upper-layer driver.
- */
-void hinic3_unregister_uld(enum hinic3_service_type type);
-
-void lld_hold(void);
-void lld_put(void);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_name - get lld device by chip name
- * @param chip_name: chip name
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_name(const char *chip_name);
-
-/**
- * @brief lld_dev_hold - get reference to lld_dev
- * @param dev: lld device
- *
- * Hold reference to device to keep it from being freed
- **/
-void lld_dev_hold(struct hinic3_lld_dev *dev);
-
-/**
- * @brief lld_dev_put - release reference to lld_dev
- * @param dev: lld device
- *
- * Release reference to device to allow it to be freed
- **/
-void lld_dev_put(struct hinic3_lld_dev *dev);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name_unsafe - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * hinic3_get_lld_dev_by_dev_name_unsafe() is completely analogous to
- * hinic3_get_lld_dev_by_dev_name(), The only difference is that the reference
- * of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that lld_dev will not be freed during the remove process
- * when using lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name_unsafe(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_and_port - get lld device by chip name and port id
- * @param chip_name: chip name
- * @param port_id: port id
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name, u8 port_id);
-
-/**
- * @brief hinic3_get_ppf_lld_dev - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief hinic3_get_ppf_lld_dev_unsafe - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * hinic3_get_ppf_lld_dev_unsafe() is completely analogous to hinic3_get_ppf_lld_dev(),
- * The only difference is that the reference of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that ppf's lld_dev will not be freed during the remove process
- * when using ppf lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev_unsafe(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief uld_dev_hold - get reference to uld_dev
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * Hold reference to uld device to keep it from being freed
- **/
-void uld_dev_hold(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief uld_dev_put - release reference to lld_dev
- * @param dev: lld device
- * @param type: uld service type
- *
- * Release reference to uld device to allow it to be freed
- **/
-void uld_dev_put(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * The value of uld_dev reference increases when uld_dev is obtained. The caller needs
- * to release the reference by calling uld_dev_put.
- **/
-void *hinic3_get_uld_dev(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev_unsafe - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * hinic3_get_uld_dev_unsafe() is completely analogous to hinic3_get_uld_dev(),
- * The only difference is that the reference of uld_dev is not increased when uld_dev is obtained.
- *
- * The caller must ensure that uld_dev will not be freed during the remove process
- * when using uld_dev.
- **/
-void *hinic3_get_uld_dev_unsafe(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_chip_name - get chip name by lld device
- * @param lld_dev: lld device
- * @param chip_name: String for storing the chip name
- * @param max_len: Maximum number of characters to be copied for chip_name
- **/
-int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len);
-
-struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev);
-
-struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev);
-
-bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service);
-
-int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
- bool vf_srv_load);
-
-int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id,
- u16 service, bool en);
-
-bool hinic3_get_vf_load_state(struct pci_dev *pdev);
-
-int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state);
-
-int hinic3_attach_nic(struct hinic3_lld_dev *lld_dev);
-
-void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
-
-int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-const char **hinic3_get_uld_names(void);
-int hinic3_lld_init(void);
-void hinic3_lld_exit(void);
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
index 2fe808b..5e4e184 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
@@ -17,11 +17,22 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_hw.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_common.h"
+#include "mag_mpu_cmd_defs.h"
+
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
+#define CAP_INFO_MAX_LEN 512
+#define DEVICE_VENDOR_MAX_LEN 17
+#define READ_RSFEC_REGISTER_DELAY_TIME_MS 500
+
+struct parse_tlv_info g_page_info = {0};
+struct drv_tag_mag_cmd_get_xsfp_tlv_rsp g_xsfp_tlv_info = {0};
static int mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
@@ -78,8 +89,10 @@ int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats)
return -ENOMEM;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
memset(&stats_info, 0, sizeof(stats_info));
stats_info.port_id = hinic3_physical_port_id(hwdev);
@@ -104,6 +117,64 @@ out:
}
EXPORT_SYMBOL(hinic3_get_phy_port_stats);
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats)
+{
+ struct mag_cmd_get_mag_cnt *port_stats = NULL;
+ struct mag_cmd_get_mag_cnt stats_info;
+ u16 out_size = sizeof(*port_stats);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !stats)
+ return -EINVAL;
+
+ port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
+ if (!port_stats)
+ return -ENOMEM;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ memset(&stats_info, 0, sizeof(stats_info));
+ stats_info.port_id = hinic3_physical_port_id(hwdev);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT,
+ &stats_info, sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+ /* 读2遍, 清除误码残留 */
+ msleep(READ_RSFEC_REGISTER_DELAY_TIME_MS);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT, &stats_info,
+ sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+
+ memcpy(stats, &port_stats->mag_csr[MAG_RX_RSFEC_ERR_CW_CNT],
+ sizeof(u32));
+
+out:
+ kfree(port_stats);
+
+ return err;
+}
+EXPORT_SYMBOL(hinic3_get_phy_rsfec_stats);
+
int hinic3_set_port_funcs_state(void *hwdev, bool enable)
{
return 0;
@@ -180,6 +251,8 @@ int hinic3_get_loopback_mode(void *hwdev, u8 *mode, u8 *enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_cfg_loopback_mode(nic_io, MGMT_MSG_CMD_OP_GET, mode,
enable);
@@ -195,6 +268,8 @@ int hinic3_set_loopback_mode(void *hwdev, u8 mode, u8 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) {
nic_err(nic_io->dev_hdl, "Invalid loopback mode %u to set\n",
@@ -218,6 +293,9 @@ int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&led_info, 0, sizeof(led_info));
led_info.function_id = hinic3_global_func_id(hwdev);
@@ -249,6 +327,8 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
memset(&port_msg, 0, sizeof(port_msg));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
port_msg.port_id = hinic3_physical_port_id(hwdev);
@@ -268,9 +348,12 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
port_info->port_type = port_msg.wire_type;
port_info->speed = port_msg.speed;
port_info->fec = port_msg.fec;
+ port_info->lanes = port_msg.lanes;
port_info->supported_mode = port_msg.supported_mode;
port_info->advertised_mode = port_msg.advertised_mode;
-
+ port_info->supported_fec_mode = port_msg.supported_fec_mode;
+ /* switch Gbps to Mbps */
+ port_info->bond_speed = (u32)port_msg.bond_speed * RATE_MBPS_TO_GBPS;
return 0;
}
@@ -306,6 +389,8 @@ int hinic3_set_link_settings(void *hwdev,
memset(&info, 0, sizeof(info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
info.port_id = hinic3_physical_port_id(hwdev);
info.config_bitmap = settings->valid_bitmap;
@@ -335,6 +420,8 @@ int hinic3_get_link_state(void *hwdev, u8 *link_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&get_link, 0, sizeof(get_link));
get_link.port_id = hinic3_physical_port_id(hwdev);
@@ -364,9 +451,10 @@ void hinic3_notify_vf_link_status(struct hinic3_nic_io *nic_io,
if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
link.status = link_status;
link.port_id = hinic3_physical_port_id(nic_io->hwdev);
- err = hinic3_mbox_to_vf(nic_io->hwdev, vf_id, HINIC3_MOD_HILINK,
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
MAG_CMD_GET_LINK_STATUS, &link,
- sizeof(link), &link, &out_size, 0,
+ sizeof(link), &link, &out_size,
HINIC3_CHANNEL_NIC);
if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
@@ -387,6 +475,8 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
u16 i;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
nic_io->link_status = link_status;
for (i = 1; i <= nic_io->max_vfs; i++) {
if (!nic_io->vf_infos[HW_VF_ID_TO_OS(i)].link_forced)
@@ -394,6 +484,165 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
}
}
+static char *g_hw_to_char_fec[HILINK_FEC_MAX_TYPE] = {
+ "not set", "rsfec", "basefec",
+ "nofec", "llrsfec"};
+static char *g_hw_to_speed_info[PORT_SPEED_UNKNOWN] = {
+ "not set", "10MB", "100MB", "1GB", "10GB",
+ "25GB", "40GB", "50GB", "100GB", "200GB"};
+static char *g_hw_to_an_state_info[PORT_CFG_AN_OFF + 1] = {
+ "not set", "on", "off"};
+
+struct port_type_table {
+ u32 port_type;
+ char *port_type_name;
+};
+
+static const struct port_type_table port_optical_type_table_s[] = {
+ {LINK_PORT_UNKNOWN, "UNKNOWN"},
+ {LINK_PORT_OPTICAL_MM, "optical_sr"},
+ {LINK_PORT_OPTICAL_SM, "optical_lr"},
+ {LINK_PORT_PAS_COPPER, "copper"},
+ {LINK_PORT_ACC, "ACC"},
+ {LINK_PORT_BASET, "baset"},
+ {LINK_PORT_AOC, "AOC"},
+ {LINK_PORT_ELECTRIC, "electric"},
+ {LINK_PORT_BACKBOARD_INTERFACE, "interface"},
+};
+
+static char *get_port_type_name(u32 type)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(port_optical_type_table_s); i++) {
+ if (type == port_optical_type_table_s[i].port_type)
+ return port_optical_type_table_s[i].port_type_name;
+ }
+ return "UNKNOWN TYPE";
+}
+
+static void get_port_type(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ char **port_type)
+{
+ if (info->port_type <= LINK_PORT_BACKBOARD_INTERFACE)
+ *port_type = get_port_type_name(info->port_type);
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown port type: %u\n", info->port_type);
+}
+
+static int get_port_temperature_power(struct mag_cmd_event_port_info *info,
+ char *str)
+{
+ char cap_info[CAP_INFO_MAX_LEN];
+
+ memset(cap_info, 0, sizeof(cap_info));
+ snprintf(cap_info, CAP_INFO_MAX_LEN, "%s, %s, Temperature: %u", str,
+ info->sfp_type ? "QSFP" : "SFP", info->cable_temp);
+
+ if (info->sfp_type)
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuw %uuW %uuW %uuW",
+ cap_info, info->power[0x0], info->power[0x1],
+ info->power[0x2], info->power[0x3]);
+ else
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuW, tx power: %uuW",
+ cap_info, info->power[0x0], info->power[0x1]);
+
+ return 0;
+}
+
+static void print_cable_info(struct hinic3_nic_io *nic_io, struct mag_cmd_event_port_info *info)
+{
+ char tmp_str[CAP_INFO_MAX_LEN] = {0};
+ char tmp_vendor[DEVICE_VENDOR_MAX_LEN] = {0};
+ char *port_type = "Unknown port type";
+ int i;
+ int err = 0;
+
+ if (info->gpio_insert) {
+ sdk_info(nic_io->dev_hdl, "Cable unpresent\n");
+ return;
+ }
+
+ get_port_type(nic_io, info, &port_type);
+
+ for (i = sizeof(info->vendor_name) - 1; i >= 0; i--) {
+ if (info->vendor_name[i] == ' ')
+ info->vendor_name[i] = '\0';
+ else
+ break;
+ }
+
+ memcpy(tmp_vendor, info->vendor_name, sizeof(info->vendor_name));
+ snprintf(tmp_str, CAP_INFO_MAX_LEN, "Vendor: %s, %s, length: %um, max_speed: %uGbps",
+ tmp_vendor, port_type, info->cable_length, info->max_speed);
+
+ if (info->port_type == LINK_PORT_OPTICAL_MM ||
+ info->port_type == LINK_PORT_AOC) {
+ err = get_port_temperature_power(info, tmp_str);
+ if (err)
+ return;
+ }
+
+ sdk_info(nic_io->dev_hdl, "Cable information: %s\n", tmp_str);
+}
+
+static void print_link_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ enum hinic3_nic_event_type type)
+{
+ char *fec = "None";
+ char *speed = "None";
+ char *an_state = "None";
+
+ if (info->fec < HILINK_FEC_MAX_TYPE)
+ fec = g_hw_to_char_fec[info->fec];
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown fec type: %u\n", info->fec);
+
+ if (info->an_state > PORT_CFG_AN_OFF) {
+ sdk_info(nic_io->dev_hdl, "an_state %d is invalid",
+ info->an_state);
+ return;
+ }
+
+ an_state = g_hw_to_an_state_info[info->an_state];
+
+ if (info->speed >= PORT_SPEED_UNKNOWN) {
+ sdk_info(nic_io->dev_hdl, "speed %u is invalid", info->speed);
+ return;
+ }
+
+ speed = g_hw_to_speed_info[info->speed];
+ sdk_info(nic_io->dev_hdl, "Link information: speed %s, %s, autoneg %s",
+ speed, fec, an_state);
+}
+
+void print_port_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *port_info,
+ enum hinic3_nic_event_type type)
+{
+ print_cable_info(nic_io, port_info);
+
+ print_link_info(nic_io, port_info, type);
+
+ if (type == EVENT_NIC_LINK_UP)
+ return;
+
+ sdk_info(nic_io->dev_hdl, "PMA ctrl: %s, tx %s, rx %s, PMA fifo reg: 0x%x, PMA signal ok reg: 0x%x, RF/LF status reg: 0x%x\n",
+ port_info->pma_ctrl == 1 ? "off" : "on",
+ port_info->tx_enable ? "enable" : "disable",
+ port_info->rx_enable ? "enable" : "disable", port_info->pma_fifo_reg,
+ port_info->pma_signal_ok_reg, port_info->rf_lf);
+ sdk_info(nic_io->dev_hdl, "alos: %u, rx_los: %u, PCS 64 66b reg: 0x%x, PCS link: 0x%x, MAC link: 0x%x PCS_err_cnt: 0x%x\n",
+ port_info->alos, port_info->rx_los, port_info->pcs_64_66b_reg,
+ port_info->pcs_link, port_info->pcs_mac_link,
+ port_info->pcs_err_cnt);
+ sdk_info(nic_io->dev_hdl, "his_link_machine_state = 0x%08x, cur_link_machine_state = 0x%08x\n",
+ port_info->his_link_machine_state,
+ port_info->cur_link_machine_state);
+}
+
static int hinic3_get_vf_link_status_msg_handler(struct hinic3_nic_io *nic_io,
u16 vf_id, void *buf_in,
u16 in_size, void *buf_out,
@@ -433,6 +682,10 @@ static void get_port_info(void *hwdev,
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (hinic3_func_type(hwdev) != TYPE_VF && link_status->status) {
err = hinic3_get_port_info(hwdev, &port_info, HINIC3_CHANNEL_NIC);
if (err) {
@@ -457,8 +710,18 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
struct hinic3_event_info event_info = {0};
struct hinic3_event_link_info *link_info = (void *)event_info.event_data;
struct hinic3_nic_io *nic_io = NULL;
+#ifndef __UEFI__
+ struct pci_dev *pdev = NULL;
+#endif
+ /* Ignore link change event */
+ if (hinic3_is_bm_slave_host(hwdev))
+ return;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
link_status = buf_in;
sdk_info(nic_io->dev_hdl, "Link status report received, func_id: %u, status: %u\n",
@@ -475,6 +738,15 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
hinic3_event_callback(hwdev, &event_info);
+#ifndef __UEFI__
+ if (nic_io->pcidev_hdl != NULL) {
+ pdev = nic_io->pcidev_hdl;
+ if (pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID) {
+ return;
+ }
+ }
+#endif
+
if (hinic3_func_type(hwdev) != TYPE_VF) {
hinic3_notify_all_vfs_link_changed(hwdev, link_status->status);
ret_link_status = buf_out;
@@ -483,20 +755,142 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
}
}
+static void port_info_event_printf(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_event_port_info *port_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info;
+ enum hinic3_nic_event_type type;
+
+ if (!hwdev) {
+ pr_err("hwdev is NULL\n");
+ return;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ if (in_size != sizeof(*port_info)) {
+ sdk_info(nic_io->dev_hdl, "Invalid port info message size %d, should be %ld\n",
+ in_size, sizeof(*port_info));
+ return;
+ }
+
+ ((struct mag_cmd_event_port_info *)buf_out)->head.status = 0;
+
+ type = port_info->event_type;
+ if (type < EVENT_NIC_LINK_DOWN || type > EVENT_NIC_LINK_UP) {
+ sdk_info(nic_io->dev_hdl, "Invalid hilink info report, type: %d\n",
+ type);
+ return;
+ }
+
+ print_port_info(nic_io, port_info, type);
+
+ memset(&event_info, 0, sizeof(event_info));
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = type;
+
+ *out_size = sizeof(*port_info);
+
+ hinic3_event_callback(hwdev, &event_info);
+}
+
+void hinic3_notify_vf_bond_status(struct hinic3_nic_io *nic_io,
+ u16 vf_id, u8 bond_status)
+{
+ struct mag_cmd_get_bond_status bond;
+ struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ u16 out_size = sizeof(bond);
+ int err;
+
+ memset(&bond, 0, sizeof(bond));
+ if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
+ bond.status = bond_status;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
+ MAG_CMD_GET_BOND_STATUS, &bond,
+ sizeof(bond), &bond, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF %u not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return;
+ }
+ if (err || !out_size || bond.head.status)
+ nic_err(nic_io->dev_hdl,
+ "Send bond change event to VF %hu failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err, bond.head.status,
+ out_size);
+ }
+}
+
+void hinic3_notify_all_vfs_bond_changed(void *hwdev, u8 bond_status)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 i;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ nic_io->link_status = bond_status;
+ for (i = 1; i <= nic_io->max_vfs; i++)
+ hinic3_notify_vf_bond_status(nic_io, i, bond_status);
+}
+
+static void bond_status_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_get_bond_status *bond_status = NULL;
+ struct hinic3_event_info event_info = {};
+ struct hinic3_nic_io *nic_io = NULL;
+ struct mag_cmd_get_bond_status *ret_bond_status = NULL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+
+ bond_status = (struct mag_cmd_get_bond_status *)buf_in;
+ sdk_info(nic_io->dev_hdl, "bond status report received, func_id: %u, status: %u\n",
+ hinic3_global_func_id(hwdev), bond_status->status);
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = bond_status->status ?
+ EVENT_NIC_BOND_UP : EVENT_NIC_BOND_DOWN;
+
+ hinic3_event_callback(hwdev, &event_info);
+
+ if (hinic3_func_type(hwdev) != TYPE_VF) {
+ hinic3_notify_all_vfs_bond_changed(hwdev, bond_status->status);
+ ret_bond_status = buf_out;
+ ret_bond_status->head.status = 0;
+ *out_size = sizeof(*ret_bond_status);
+ }
+}
+
static void cable_plug_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct mag_cmd_wire_event *plug_event = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_event_info event_info;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
rt_cmd->mpu_send_sfp_abs = false;
rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
memset(&event_info, 0, sizeof(event_info));
@@ -518,9 +912,12 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
{
struct mag_cmd_get_xsfp_info *sfp_info = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_info)) {
sdk_err(nic_io->dev_hdl, "Invalid sfp info cmd, length: %u, should be %ld\n",
in_size, sizeof(*sfp_info));
@@ -528,10 +925,41 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
}
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
memcpy(&rt_cmd->std_sfp_info, sfp_info,
sizeof(struct mag_cmd_get_xsfp_info));
rt_cmd->mpu_send_sfp_info = true;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+}
+
+static void port_xsfp_tlv_info_event(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *xsfp_tlv_info = buf_in;
+ struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
+ size_t cpy_len = in_size - sizeof(struct mgmt_msg_head) -
+ XSFP_TLV_PRE_INFO_LEN;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL)
+ return;
+
+ if (cpy_len > XSFP_CMIS_INFO_MAX_SIZE) {
+ sdk_err(nic_io->dev_hdl, "invalid cpy_len(%lu)\n", cpy_len);
+ return;
+ }
+ rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ rt_cmd_ext->std_xsfp_tlv_info.port_id = xsfp_tlv_info->port_id;
+ memcpy(&(rt_cmd_ext->std_xsfp_tlv_info.tlv_buf[0]),
+ &(xsfp_tlv_info->tlv_buf[0]), cpy_len);
+ rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = true;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
}
@@ -543,6 +971,8 @@ static void port_sfp_abs_event(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_abs)) {
sdk_err(nic_io->dev_hdl, "Invalid sfp absent cmd, length: %u, should be %ld\n",
in_size, sizeof(*sfp_abs));
@@ -564,9 +994,11 @@ bool hinic3_if_sfp_absent(void *hwdev)
u8 port_id = hinic3_physical_port_id(hwdev);
u16 out_size = sizeof(sfp_abs);
int err;
- bool sfp_abs_status;
+ bool sfp_abs_status = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return true;
memset(&sfp_abs, 0, sizeof(sfp_abs));
rt_cmd = &nic_io->nic_cfg.rt_cmd;
@@ -597,10 +1029,185 @@ bool hinic3_if_sfp_absent(void *hwdev)
return (sfp_abs.abs_status == 0 ? false : true);
}
+int hinic3_get_sfp_tlv_info(void *hwdev, struct drv_tag_mag_cmd_get_xsfp_tlv_rsp
+ *sfp_tlv_info,
+ const struct tag_mag_cmd_get_xsfp_tlv_req
+ *sfp_tlv_info_req)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ u16 out_size = sizeof(*sfp_tlv_info);
+ int err;
+
+ if ((hwdev == NULL) || (sfp_tlv_info == NULL))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL)
+ return -EINVAL;
+
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ if (rt_cmd_ext->mpu_send_xsfp_tlv_info == true) {
+ if (rt_cmd_ext->std_xsfp_tlv_info.head.status != 0) {
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return -EIO;
+ }
+
+ memcpy(sfp_tlv_info, &rt_cmd_ext->std_xsfp_tlv_info,
+ sizeof(*sfp_tlv_info));
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_TLV_INFO,
+ (void *)sfp_tlv_info_req,
+ sizeof(*sfp_tlv_info_req),
+ sfp_tlv_info, &out_size);
+ if ((sfp_tlv_info->head.status != 0) || (err != 0) || (out_size == 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get port%u tlv sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
+ hinic3_physical_port_id(hwdev), err,
+ sfp_tlv_info->head.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_get_page_pos(u32 page_id, u32 content_len, u32 *pos)
+{
+ if (page_id <= QSFP_CMIS_PAGE_03H) {
+ *pos = (page_id * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_11H) {
+ *pos = (QSFP_CMIS_PAGE_04H * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_12H) {
+ *pos = (QSFP_CMIS_PAGE_05H * content_len);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int hinic3_get_page_key_info(struct mgmt_tlv_info *tlv_info,
+ struct parse_tlv_info *page_info, u8 idx,
+ u32 *total_len)
+{
+ u8 *src_addr = NULL;
+ u8 *dst_addr = NULL;
+ u8 *tmp_addr = NULL;
+ u32 page_id = 0;
+ u32 content_len = 0;
+ u32 src_pos = 0;
+ int ret;
+
+ page_id = MGMT_TLV_GET_U32(tlv_info->value);
+ content_len = tlv_info->length - MGMT_TLV_U32_SIZE;
+ if (page_id == QSFP_CMIS_PAGE_00H) {
+ tmp_addr = (u8 *)(tlv_info + 1);
+ page_info->id = *(tmp_addr + MGMT_TLV_U32_SIZE);
+ }
+
+ ret = hinic3_trans_cmis_get_page_pos(page_id, content_len, &src_pos);
+ if (ret != 0)
+ return ret;
+
+ src_addr = page_info->tlv_page_info + src_pos;
+ tmp_addr = (u8 *)(tlv_info + 1);
+ dst_addr = tmp_addr + MGMT_TLV_U32_SIZE;
+ memcpy(src_addr, dst_addr, content_len);
+
+ if (idx < XSFP_CMIS_PARSE_PAGE_NUM)
+ page_info->tlv_page_num[idx] = page_id;
+
+ *total_len += content_len;
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_tlv_info_to_buf(u8 *sfp_tlv_info,
+ struct parse_tlv_info *page_info)
+{
+ struct mgmt_tlv_info *tlv_info = NULL;
+ u8 *tlv_buf = sfp_tlv_info;
+ u8 idx = 0;
+ u32 total_len = 0;
+ int ret = 0;
+ bool need_continue = true;
+
+ if ((sfp_tlv_info == NULL) || (page_info == NULL))
+ return -EIO;
+
+ while (need_continue) {
+ tlv_info = (struct mgmt_tlv_info *)tlv_buf;
+ switch (tlv_info->type) {
+ case MAG_XSFP_TYPE_PAGE:
+ ret = hinic3_get_page_key_info(
+ tlv_info, page_info, idx, &total_len);
+ if (ret != 0) {
+ pr_err("lib_get_page_key_info fail,ret:0x%x.\n",
+ ret);
+ break;
+ }
+ idx++;
+ break;
+
+ case MAG_XSFP_TYPE_WIRE_TYPE:
+ page_info->wire_type =
+ MGMT_TLV_GET_U32(&(tlv_info->value));
+ break;
+
+ case MAG_XSFP_TYPE_END:
+ need_continue = false;
+ break;
+
+ default:
+ break;
+ }
+
+ tlv_buf += (sizeof(struct mgmt_tlv_info) + tlv_info->length);
+ }
+
+ page_info->tlv_page_info_len = total_len;
+
+ return 0;
+}
+
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len)
+{
+ int err = 0;
+ struct tag_mag_cmd_get_xsfp_tlv_req xsfp_tlv_info_req = {0};
+
+ xsfp_tlv_info_req.rsp_buf_len = XSFP_CMIS_INFO_MAX_SIZE;
+ xsfp_tlv_info_req.port_id = hinic3_physical_port_id(hwdev);
+ err = hinic3_get_sfp_tlv_info(hwdev, &g_xsfp_tlv_info,
+ &xsfp_tlv_info_req);
+ if (err != 0)
+ return err;
+
+ err = hinic3_trans_cmis_tlv_info_to_buf(g_xsfp_tlv_info.tlv_buf,
+ &g_page_info);
+ if (err)
+ return -ENOMEM;
+
+ memcpy(data, g_page_info.tlv_page_info, len);
+
+ return (err == 0) ? 0 : -ENOMEM;
+}
+
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
{
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ u8 sfp_info_status = 0;
u16 out_size = sizeof(*sfp_info);
int err;
@@ -608,13 +1215,17 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ sfp_info_status = rt_cmd->std_sfp_info.head.status;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (sfp_info_status != 0) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return -EIO;
+ return (sfp_info_status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ ? HINIC3_MGMT_CMD_UNSUPPORTED : -EIO;
}
memcpy(sfp_info, &rt_cmd->std_sfp_info, sizeof(*sfp_info));
@@ -626,7 +1237,12 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
sfp_info->port_id = hinic3_physical_port_id(hwdev);
err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_INFO, sfp_info,
sizeof(*sfp_info), sfp_info, &out_size);
- if (sfp_info->head.status || err || !out_size) {
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ return HINIC3_MGMT_CMD_UNSUPPORTED;
+
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ return -EOPNOTSUPP;
+ if ((sfp_info->head.status != 0) || (err != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Failed to get port%u sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
hinic3_physical_port_id(hwdev), err,
@@ -642,7 +1258,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
struct mag_cmd_get_xsfp_info sfp_info;
int err;
- if (!hwdev || !data)
+ if (!hwdev || !data || len > PAGE_SIZE)
return -EINVAL;
if (hinic3_if_sfp_absent(hwdev))
@@ -654,7 +1270,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
if (err)
return err;
- memcpy(data, sfp_info.sfp_info, len);
+ memcpy(data, sfp_info.sfp_info, sizeof(sfp_info.sfp_info));
return 0;
}
@@ -664,7 +1280,7 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
- int err;
+ int err = 0;
if (!hwdev || !sfp_type || !sfp_type_ext)
return -EINVAL;
@@ -677,20 +1293,35 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (rt_cmd->std_sfp_info.head.status == 0) {
+ *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
+ *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ if (rt_cmd->std_sfp_info.head.status != HINIC3_MGMT_CMD_UNSUPPORTED) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
return -EIO;
}
- *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
- *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
- mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return 0;
+ err = HINIC3_MGMT_CMD_UNSUPPORTED; /* cmis */
}
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
- STD_SFP_INFO_MAX_SIZE);
+ if (err == 0) {
+ err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ } else {
+ /* mpu_send_sfp_info is false */
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ }
+
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+
if (err)
return err;
@@ -796,16 +1427,23 @@ int hinic3_set_pf_bw_limit(void *hwdev, u32 bw_limit)
return -EINVAL;
}
- old_bw_limit = nic_io->nic_cfg.pf_bw_limit;
- nic_io->nic_cfg.pf_bw_limit = bw_limit;
+ if (nic_io->direct == HINIC3_NIC_TX) {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_tx_limit;
+ nic_io->nic_cfg.pf_bw_tx_limit = bw_limit;
+ } else {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_rx_limit;
+ nic_io->nic_cfg.pf_bw_rx_limit = bw_limit;
+ }
err = hinic3_update_pf_bw(hwdev);
if (err) {
- nic_io->nic_cfg.pf_bw_limit = old_bw_limit;
- return err;
+ if (nic_io->direct == HINIC3_NIC_TX)
+ nic_io->nic_cfg.pf_bw_tx_limit = old_bw_limit;
+ else
+ nic_io->nic_cfg.pf_bw_rx_limit = old_bw_limit;
}
- return 0;
+ return err;
}
static const struct vf_msg_handler vf_mag_cmd_handler[] = {
@@ -828,6 +1466,9 @@ int hinic3_pf_mag_mbox_handler(void *hwdev, u16 vf_id,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
for (index = 0; index < cmd_size; index++) {
handler = &vf_mag_cmd_handler[index];
@@ -848,6 +1489,11 @@ static struct nic_event_handler mag_cmd_handler[] = {
.handler = link_status_event_handler,
},
+ {
+ .cmd = MAG_CMD_EVENT_PORT_INFO,
+ .handler = port_info_event_printf,
+ },
+
{
.cmd = MAG_CMD_WIRE_EVENT,
.handler = cable_plug_event,
@@ -862,6 +1508,16 @@ static struct nic_event_handler mag_cmd_handler[] = {
.cmd = MAG_CMD_GET_XSFP_PRESENT,
.handler = port_sfp_abs_event,
},
+
+ {
+ .cmd = MAG_CMD_GET_BOND_STATUS,
+ .handler = bond_status_event_handler,
+ },
+
+ {
+ .cmd = MAG_CMD_GET_XSFP_TLV_INFO,
+ .handler = port_xsfp_tlv_info_event,
+ },
};
static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
@@ -877,6 +1533,9 @@ static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
for (i = 0; i < size; i++) {
if (cmd == mag_cmd_handler[i].cmd) {
mag_cmd_handler[i].handler(hwdev, buf_in, in_size,
@@ -917,7 +1576,8 @@ static int _mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u32 i, cmd_cnt = ARRAY_LEN(vf_mag_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_mag_cmd_handler[i].cmd) {
cmd_to_pf = true;
@@ -949,3 +1609,124 @@ static int mag_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in,
return _mag_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out,
out_size, channel);
}
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+struct fecparam_value_map {
+ u8 hinic3_fec_offset;
+ u8 hinic3_fec_value;
+ u8 ethtool_fec_value;
+};
+
+static void fecparam_convert(u32 opcode, u8 in_fec_param, u8 *out_fec_param)
+{
+ u8 i;
+ u8 fec_value_table_lenth;
+ struct fecparam_value_map fec_value_table[] = {
+ {PORT_FEC_NOT_SET, BIT(PORT_FEC_NOT_SET), ETHTOOL_FEC_NONE},
+ {PORT_FEC_RSFEC, BIT(PORT_FEC_RSFEC), ETHTOOL_FEC_RS},
+ {PORT_FEC_BASEFEC, BIT(PORT_FEC_BASEFEC), ETHTOOL_FEC_BASER},
+ {PORT_FEC_NOFEC, BIT(PORT_FEC_NOFEC), ETHTOOL_FEC_OFF},
+#ifdef ETHTOOL_FEC_LLRS
+ {PORT_FEC_LLRSFEC, BIT(PORT_FEC_LLRSFEC), ETHTOOL_FEC_LLRS},
+#endif
+ {PORT_FEC_AUTO, BIT(PORT_FEC_AUTO), ETHTOOL_FEC_AUTO}
+ };
+
+ *out_fec_param = 0;
+ fec_value_table_lenth = (u8)(sizeof(fec_value_table) / sizeof(struct fecparam_value_map));
+
+ if (opcode == MAG_CMD_OPCODE_SET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].ethtool_fec_value) != 0)
+ /* The MPU uses the offset to determine the FEC mode. */
+ *out_fec_param =
+ fec_value_table[i].hinic3_fec_offset;
+ }
+ }
+
+ if (opcode == MAG_CMD_OPCODE_GET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].hinic3_fec_value) != 0)
+ *out_fec_param |=
+ fec_value_table[i].ethtool_fec_value;
+ }
+ }
+}
+
+/* When the ethtool is used to set the FEC mode */
+static bool check_fecparam_is_valid(u8 fec_param)
+{
+ if (
+#ifdef ETHTOOL_FEC_LLRS
+ (fec_param == ETHTOOL_FEC_LLRS) ||
+#endif
+ (fec_param == ETHTOOL_FEC_RS) ||
+ (fec_param == ETHTOOL_FEC_BASER) ||
+ (fec_param == ETHTOOL_FEC_OFF)) {
+ return true;
+ }
+ return false;
+}
+
+int set_fecparam(void *hwdev, u8 fecparam)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ u8 advertised_fec = 0;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (check_fecparam_is_valid(fecparam) == false) {
+ nic_err(nic_io->dev_hdl, "fec param is invalid, failed to set fec param\n");
+ return -EINVAL;
+ }
+ fecparam_convert(MAG_CMD_OPCODE_SET, fecparam, &advertised_fec);
+ fec_msg.opcode = MAG_CMD_OPCODE_SET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ fec_msg.advertised_fec = advertised_fec;
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0))
+ return -EINVAL;
+ return 0;
+}
+
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ fec_msg.opcode = MAG_CMD_OPCODE_GET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0))
+ return -EINVAL;
+
+ /* fec_msg.advertised_fec: bit offset,
+ *value is BIT(fec_msg.advertised_fec); fec_msg.supported_fec: value
+ */
+ fecparam_convert(MAG_CMD_OPCODE_GET, BIT(fec_msg.advertised_fec),
+ advertised_fec);
+ fecparam_convert(MAG_CMD_OPCODE_GET, fec_msg.supported_fec,
+ supported_fec);
+ return 0;
+}
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
index 6f90c86..9d14e0f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
@@ -20,6 +20,9 @@
#include <linux/debugfs.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#include "hinic3_hw.h"
#include "hinic3_crm.h"
#include "hinic3_mt.h"
@@ -35,8 +38,8 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
#include "hinic3_profile.h"
+#include "hinic3_bond.h"
-/*lint -e806*/
#define DEFAULT_POLL_WEIGHT 64
static unsigned int poll_weight = DEFAULT_POLL_WEIGHT;
module_param(poll_weight, uint, 0444);
@@ -68,7 +71,9 @@ static unsigned char set_link_status_follow = HINIC3_LINK_FOLLOW_STATUS_MAX;
module_param(set_link_status_follow, byte, 0444);
MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=default,1=follow,2=separate,3=unset");
-/*lint +e806*/
+static bool page_pool_enabled = true;
+module_param(page_pool_enabled, bool, 0444);
+MODULE_PARM_DESC(page_pool_enabled, "enable/disable page_pool feature for rxq page management (default enable)");
#define HINIC3_NIC_DEV_WQ_NAME "hinic3_nic_dev_wq"
@@ -80,6 +85,8 @@ MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=
#define HINIC3_SQ_DEPTH 1024
#define HINIC3_RQ_DEPTH 1024
+#define LRO_ENABLE 1
+
enum hinic3_rx_buff_len {
RX_BUFF_VALID_2KB = 2,
RX_BUFF_VALID_4KB = 4,
@@ -87,12 +94,15 @@ enum hinic3_rx_buff_len {
RX_BUFF_VALID_16KB = 16,
};
+#define NIC_MAX_PF_NUM 32
+
#define CONVERT_UNIT 1024
-#define BIFUR_RESOURCE_PF_SSID 0x5a1
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
-static int hinic3_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr);
+static int hinic3_netdev_event(struct notifier_block *notifier,
+ unsigned long event, void *ptr);
/* used for netdev notifier register/unregister */
static DEFINE_MUTEX(hinic3_netdev_notifiers_mutex);
@@ -101,6 +111,17 @@ static struct notifier_block hinic3_netdev_notifier = {
.notifier_call = hinic3_netdev_event,
};
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+static const struct udp_tunnel_nic_info hinic3_udp_tunnels = {
+ .set_port = hinic3_udp_tunnel_set_port,
+ .unset_port = hinic3_udp_tunnel_unset_port,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static void hinic3_register_notifier(struct hinic3_nic_dev *nic_dev)
{
int err;
@@ -134,7 +155,8 @@ static void hinic3_unregister_notifier(struct hinic3_nic_dev *nic_dev)
NETIF_F_SCTP_CRC | NETIF_F_RXCSUM | \
NETIF_F_ALL_TSO)
-static int hinic3_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr)
+static int hinic3_netdev_event(struct notifier_block *notifier,
+ unsigned long event, void *ptr)
{
struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
struct net_device *real_dev = NULL;
@@ -266,6 +288,11 @@ static void netdev_feature_init(struct net_device *netdev)
netdev->features |= dft_fts | cso_fts | tso_fts | vlan_fts;
netdev->vlan_features |= dft_fts | cso_fts | tso_fts;
+ if (nic_dev->nic_cap.lro_enable == LRO_ENABLE) {
+ netdev->features |= NETIF_F_LRO;
+ netdev->vlan_features |= NETIF_F_LRO;
+ }
+
#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT
hw_features |= get_netdev_hw_features(netdev);
#else
@@ -306,7 +333,8 @@ static void init_intr_coal_param(struct hinic3_nic_dev *nic_dev)
info->pending_limt = qp_pending_limit;
info->coalesce_timer_cfg = qp_coalesc_timer_cfg;
- info->resend_timer_cfg = HINIC3_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG;
+ info->resend_timer_cfg =
+ HINIC3_DEAULT_TXRX_MSIX_RESEND_TIMER_CFG;
info->pkt_rate_high = HINIC3_RX_RATE_HIGH;
info->rx_usecs_high = HINIC3_RX_COAL_TIME_HIGH;
@@ -350,6 +378,7 @@ static int hinic3_init_intr_coalesce(struct hinic3_nic_dev *nic_dev)
static void hinic3_free_intr_coalesce(struct hinic3_nic_dev *nic_dev)
{
kfree(nic_dev->intr_coalesce);
+ nic_dev->intr_coalesce = NULL;
}
static int hinic3_alloc_txrxqs(struct hinic3_nic_dev *nic_dev)
@@ -396,15 +425,18 @@ static void hinic3_free_txrxqs(struct hinic3_nic_dev *nic_dev)
static void hinic3_tx_rx_ops_init(struct hinic3_nic_dev *nic_dev)
{
if (HINIC3_SUPPORT_TX_COMPACT_WQE_OL(nic_dev->hwdev)) {
- nic_dev->tx_rx_ops.tx_set_wqebb_cnt = hinic3_tx_set_compact_offload_wqebb_cnt;
- nic_dev->tx_rx_ops.tx_set_wqe_task = hinic3_tx_set_compact_offload_wqe_task;
+ nic_dev->tx_rx_ops.tx_set_wqebb_cnt =
+ hinic3_tx_set_compact_offload_wqebb_cnt;
+ nic_dev->tx_rx_ops.tx_set_wqe_task =
+ hinic3_tx_set_compact_offload_wqe_task;
} else {
nic_dev->tx_rx_ops.tx_set_wqebb_cnt = hinic3_tx_set_wqebb_cnt;
nic_dev->tx_rx_ops.tx_set_wqe_task = hinic3_tx_set_wqe_task;
}
if (HINIC3_SUPPORT_RX_COMPACT_CQE(nic_dev->hwdev))
- nic_dev->tx_rx_ops.rx_get_cqe_info = hinic3_rx_get_compact_cqe_info;
+ nic_dev->tx_rx_ops.rx_get_cqe_info =
+ hinic3_rx_get_compact_cqe_info;
else
nic_dev->tx_rx_ops.rx_get_cqe_info = hinic3_rx_get_cqe_info;
}
@@ -420,53 +452,47 @@ static void hinic3_sw_deinit(struct hinic3_nic_dev *nic_dev)
HINIC3_CHANNEL_NIC);
hinic3_clear_rss_config(nic_dev);
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+
+ hinic3_dcb_deinit(nic_dev);
}
-static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
+static void hinic3_netdev_mtu_init(struct net_device *netdev)
+{
+ /* MTU range: 384 - 9600 */
+#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
+ netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+
+#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
+ netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+}
+
+static int hinic3_set_default_mac(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
u8 mac_addr[ETH_ALEN];
- u64 nic_features;
int err = 0;
- nic_features = hinic3_get_feature_cap(nic_dev->hwdev);
- /* You can update the features supported by the driver according to the
- * scenario here
- */
- nic_features &= NIC_DRV_DEFAULT_FEATURE;
- hinic3_update_nic_feature(nic_dev->hwdev, nic_features);
-
- sema_init(&nic_dev->port_state_sem, 1);
-
- err = hinic3_dcb_init(nic_dev);
- if (err) {
- nic_err(&nic_dev->pdev->dev, "Failed to init dcb\n");
- return -EFAULT;
- }
-
- nic_dev->q_params.sq_depth = HINIC3_SQ_DEPTH;
- nic_dev->q_params.rq_depth = HINIC3_RQ_DEPTH;
-
- hinic3_try_to_enable_rss(nic_dev);
-
err = hinic3_get_default_mac(nic_dev->hwdev, mac_addr);
if (err) {
nic_err(&nic_dev->pdev->dev, "Failed to get MAC address\n");
- goto get_mac_err;
+ return err;
}
+
eth_hw_addr_set(netdev, mac_addr);
if (!is_valid_ether_addr(netdev->dev_addr)) {
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
nic_err(&nic_dev->pdev->dev, "Invalid MAC address %pM\n",
- netdev->dev_addr);
- err = -EIO;
- goto err_mac;
- }
+ netdev->dev_addr);
+ return -EIO;
+ }
- nic_info(&nic_dev->pdev->dev, "Invalid MAC address %pM, using random\n",
+ nic_info(&nic_dev->pdev->dev,
+ "Invalid MAC address %pM, using random\n",
netdev->dev_addr);
eth_hw_addr_random(netdev);
}
@@ -478,21 +504,62 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
* MAC, and we can't consider this condition is error status during
* driver probe procedure.
*/
- if (err && err != HINIC3_PF_SET_VF_ALREADY) {
+ if (err && err != HINIC3_PF_SET_VF_ALREADY)
nic_err(&nic_dev->pdev->dev, "Failed to set default MAC\n");
- goto set_mac_err;
+
+ if (err == HINIC3_PF_SET_VF_ALREADY)
+ return 0;
+
+ return err;
+}
+
+static void hinic3_outband_cfg_init(struct hinic3_nic_dev *nic_dev)
+{
+ u16 outband_default_vid = 0;
+ int err = 0;
+
+ if (!nic_dev->nic_cap.outband_vlan_cfg_en)
+ return;
+
+ err = hinic3_get_outband_vlan_cfg(nic_dev->hwdev, &outband_default_vid);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev,
+ "Failed to get_outband_cfg, err: %d\n", err);
+ return;
}
- /* MTU range: 384 - 9600 */
-#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
- netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
+ nic_dev->outband_cfg.outband_default_vid = outband_default_vid;
+}
-#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
- netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
+static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
+{
+ struct net_device *netdev = nic_dev->netdev;
+ u64 nic_features;
+ int err = 0;
+
+ nic_features = hinic3_get_feature_cap(nic_dev->hwdev);
+ /* You can update the features supported by the driver according to the
+ * scenario here
+ */
+ nic_features &= NIC_DRV_DEFAULT_FEATURE;
+ hinic3_update_nic_feature(nic_dev->hwdev, nic_features);
+
+ err = hinic3_dcb_init(nic_dev);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev, "Failed to init dcb\n");
+ return -EFAULT;
+ }
+
+ nic_dev->q_params.sq_depth = HINIC3_SQ_DEPTH;
+ nic_dev->q_params.rq_depth = HINIC3_RQ_DEPTH;
+
+ hinic3_try_to_enable_rss(nic_dev);
+
+ err = hinic3_set_default_mac(nic_dev);
+ if (err)
+ goto set_mac_err;
+
+ hinic3_netdev_mtu_init(netdev);
err = hinic3_alloc_txrxqs(nic_dev);
if (err) {
@@ -500,6 +567,8 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
goto alloc_qps_err;
}
+ hinic3_outband_cfg_init(nic_dev);
+
hinic3_tx_rx_ops_init(nic_dev);
return 0;
@@ -510,8 +579,6 @@ alloc_qps_err:
HINIC3_CHANNEL_NIC);
set_mac_err:
-err_mac:
-get_mac_err:
hinic3_clear_rss_config(nic_dev);
return err;
@@ -623,7 +690,8 @@ static void calc_coal_para(struct hinic3_nic_dev *nic_dev,
*pending_limt =
(u8)((rx_rate - q_coal->pkt_rate_low) *
- (q_coal->rx_pending_limt_high - q_coal->rx_pending_limt_low) /
+ (q_coal->rx_pending_limt_high -
+ q_coal->rx_pending_limt_low) /
(q_coal->pkt_rate_high - q_coal->pkt_rate_low) +
q_coal->rx_pending_limt_low);
}
@@ -637,8 +705,10 @@ static void update_queue_coal(struct hinic3_nic_dev *nic_dev, u16 qid,
q_coal = &nic_dev->intr_coalesce[qid];
- if (rx_rate > HINIC3_RX_RATE_THRESH && avg_pkt_size > HINIC3_AVG_PKT_SMALL) {
- calc_coal_para(nic_dev, q_coal, rx_rate, &coalesc_timer_cfg, &pending_limt);
+ if (rx_rate > HINIC3_RX_RATE_THRESH &&
+ avg_pkt_size > HINIC3_AVG_PKT_SMALL) {
+ calc_coal_para(nic_dev, q_coal, rx_rate,
+ &coalesc_timer_cfg, &pending_limt);
} else {
coalesc_timer_cfg = HINIC3_LOWEST_LATENCY;
pending_limt = q_coal->rx_pending_limt_low;
@@ -701,20 +771,55 @@ void hinic3_auto_moderation_work(struct work_struct *work)
static void hinic3_periodic_work_handler(struct work_struct *work)
{
struct delayed_work *delay = to_delayed_work(work);
- struct hinic3_nic_dev *nic_dev = container_of(delay, struct hinic3_nic_dev, periodic_work);
+ struct hinic3_nic_dev *nic_dev =
+ container_of(delay, struct hinic3_nic_dev, periodic_work);
if (test_and_clear_bit(EVENT_WORK_TX_TIMEOUT, &nic_dev->event_flag))
- hinic3_fault_event_report(nic_dev->hwdev, HINIC3_FAULT_SRC_TX_TIMEOUT,
+ hinic3_fault_event_report(nic_dev->hwdev,
+ HINIC3_FAULT_SRC_TX_TIMEOUT,
FAULT_LEVEL_SERIOUS_FLR);
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
}
+static void hinic3_vport_stats_work_handler(struct work_struct *work)
+{
+ int err;
+ struct hinic3_vport_stats vport_stats = {0};
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_nic_dev *nic_dev = container_of(delay,
+ struct hinic3_nic_dev,
+ vport_stats_work);
+ err = hinic3_get_vport_stats(nic_dev->hwdev,
+ hinic3_global_func_id(nic_dev->hwdev),
+ &vport_stats);
+ if (err)
+ nic_err(&nic_dev->pdev->dev, "Failed to get dropped stats from fw\n");
+ else
+ nic_dev->vport_stats.rx_discard_vport =
+ vport_stats.rx_discard_vport;
+ queue_delayed_work(nic_dev->workq, &nic_dev->vport_stats_work, HZ);
+}
+
+static void free_nic_dev_vram(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram = get_use_vram_flag();
+
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)nic_dev->nic_vram, nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ else
+ kfree(nic_dev->nic_vram);
+ nic_dev->nic_vram = NULL;
+}
+
static void free_nic_dev(struct hinic3_nic_dev *nic_dev)
{
hinic3_deinit_nic_prof_adapter(nic_dev);
destroy_workqueue(nic_dev->workq);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+ free_nic_dev_vram(nic_dev);
}
static int setup_nic_dev(struct net_device *netdev,
@@ -724,6 +829,10 @@ static int setup_nic_dev(struct net_device *netdev,
struct hinic3_nic_dev *nic_dev;
char *netdev_name_fmt;
u32 page_num;
+ u16 func_id;
+ int ret;
+ int is_in_kexec = vram_get_kexec_flag();
+ int is_use_vram = get_use_vram_flag();
nic_dev = (struct hinic3_nic_dev *)netdev_priv(netdev);
nic_dev->netdev = netdev;
@@ -738,22 +847,60 @@ static int setup_nic_dev(struct net_device *netdev,
nic_dev->dma_rx_buff_size = RX_BUFF_NUM_PER_PAGE * nic_dev->rx_buff_len;
page_num = nic_dev->dma_rx_buff_size / PAGE_SIZE;
nic_dev->page_order = page_num > 0 ? ilog2(page_num) : 0;
+ nic_dev->page_pool_enabled = page_pool_enabled;
+ nic_dev->outband_cfg.outband_default_vid = 0;
+
+ // value other than 0 indicates hot replace
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(nic_dev->nic_vram_name, VRAM_NAME_MAX_LEN,
+ "%s%hu", VRAM_NIC_VRAM, func_id);
+
+ nic_dev->nic_vram = (struct hinic3_vram *)hi_vram_kalloc(
+ nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+
+ if (is_in_kexec == 0)
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ else
+ netdev->mtu = nic_dev->nic_vram->vram_mtu;
+ } else {
+ nic_dev->nic_vram = kzalloc(sizeof(struct hinic3_vram),
+ GFP_KERNEL);
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ }
mutex_init(&nic_dev->nic_mutex);
nic_dev->vlan_bitmap = kzalloc(VLAN_BITMAP_SIZE(nic_dev), GFP_KERNEL);
- if (!nic_dev->vlan_bitmap)
- return -ENOMEM;
+ if (!nic_dev->vlan_bitmap) {
+ nic_err(&pdev->dev, "Failed to allocate vlan bitmap\n");
+ ret = -ENOMEM;
+ goto vlan_bitmap_error;
+ }
nic_dev->workq = create_singlethread_workqueue(HINIC3_NIC_DEV_WQ_NAME);
if (!nic_dev->workq) {
nic_err(&pdev->dev, "Failed to initialize nic workqueue\n");
- kfree(nic_dev->vlan_bitmap);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto create_workq_error;
}
- INIT_DELAYED_WORK(&nic_dev->periodic_work, hinic3_periodic_work_handler);
- INIT_DELAYED_WORK(&nic_dev->rxq_check_work, hinic3_rxq_check_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->periodic_work,
+ hinic3_periodic_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->rxq_check_work,
+ hinic3_rxq_check_work_handler);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ INIT_DELAYED_WORK(&nic_dev->vport_stats_work,
+ hinic3_vport_stats_work_handler);
INIT_LIST_HEAD(&nic_dev->uc_filter_list);
INIT_LIST_HEAD(&nic_dev->mc_filter_list);
@@ -766,10 +913,23 @@ static int setup_nic_dev(struct net_device *netdev,
hinic3_init_nic_prof_adapter(nic_dev);
netdev_name_fmt = hinic3_get_dft_netdev_name_fmt(nic_dev);
- if (netdev_name_fmt)
- strscpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (netdev_name_fmt) {
+ ret = strscpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (ret < 0)
+ goto get_netdev_name_error;
+ }
return 0;
+
+get_netdev_name_error:
+ hinic3_deinit_nic_prof_adapter(nic_dev);
+ destroy_workqueue(nic_dev->workq);
+create_workq_error:
+ kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+vlan_bitmap_error:
+ free_nic_dev_vram(nic_dev);
+ return ret;
}
static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
@@ -808,6 +968,31 @@ static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
return 0;
}
+static void hinic3_bond_init(struct hinic3_nic_dev *nic_dev)
+{
+ u32 bond_id = HINIC3_INVALID_BOND_ID;
+ int err = hinic3_create_bond(nic_dev->hwdev, &bond_id);
+
+ if (err != 0)
+ goto bond_init_failed;
+
+ /* bond id does not change, means this pf is not bond active pf, no log is generated */
+ if (bond_id == HINIC3_INVALID_BOND_ID)
+ return;
+
+ err = hinic3_open_close_bond(nic_dev->hwdev, true);
+ if (err != 0) {
+ hinic3_delete_bond(nic_dev->hwdev);
+ goto bond_init_failed;
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Bond %d init success\n", bond_id);
+ return;
+
+bond_init_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond init failed\n");
+}
+
static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
char *uld_dev_name)
{
@@ -838,6 +1023,12 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
goto err_out;
}
+ err = hinic3_get_dev_cap(lld_dev->hwdev);
+ if (err != 0) {
+ nic_err(&pdev->dev, "Failed to get dev cap\n");
+ goto err_out;
+ }
+
max_qps = hinic3_func_max_nic_qnum(lld_dev->hwdev);
netdev = alloc_etherdev_mq(sizeof(*nic_dev), max_qps);
if (!netdev) {
@@ -870,10 +1061,17 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
hinic3_assign_netdev_ops(nic_dev);
netdev_feature_init(netdev);
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+ netdev->udp_tunnel_nic_info = &hinic3_udp_tunnels;
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
err = hinic3_set_default_hw_feature(nic_dev);
if (err)
goto set_features_err;
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0)
+ hinic3_bond_init(nic_dev);
+
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
hinic3_register_notifier(nic_dev);
#endif
@@ -888,6 +1086,9 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
}
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->vport_stats_work, HZ);
netif_carrier_off(netdev);
*uld_dev = nic_dev;
@@ -920,6 +1121,25 @@ err_out:
return err;
}
+static void hinic3_bond_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ int ret = 0;
+
+ ret = hinic3_open_close_bond(nic_dev->hwdev, false);
+ if (ret != 0)
+ goto bond_deinit_failed;
+
+ ret = hinic3_delete_bond(nic_dev->hwdev);
+ if (ret != 0)
+ goto bond_deinit_failed;
+
+ nic_info(&nic_dev->pdev->dev, "Bond deinit success\n");
+ return;
+
+bond_deinit_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond deinit failed\n");
+}
+
static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
{
struct hinic3_nic_dev *nic_dev = adapter;
@@ -939,6 +1159,8 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_unregister_notifier(nic_dev);
#endif
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ cancel_delayed_work_sync(&nic_dev->vport_stats_work);
cancel_delayed_work_sync(&nic_dev->periodic_work);
cancel_delayed_work_sync(&nic_dev->rxq_check_work);
cancel_work_sync(&nic_dev->rx_mode_work);
@@ -946,6 +1168,9 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_flush_rx_flow_rule(nic_dev);
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0)
+ hinic3_bond_deinit(nic_dev);
+
hinic3_update_nic_feature(nic_dev->hwdev, 0);
hinic3_set_nic_feature_to_hw(nic_dev->hwdev);
@@ -955,6 +1180,7 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_deinit_nic_prof_adapter(nic_dev);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
free_netdev(netdev);
@@ -971,8 +1197,10 @@ static void sriov_state_change(struct hinic3_nic_dev *nic_dev,
static void hinic3_port_module_event_handler(struct hinic3_nic_dev *nic_dev,
struct hinic3_event_info *event)
{
- const char *g_hinic3_module_link_err[LINK_ERR_NUM] = { "Unrecognized module" };
- struct hinic3_port_module_event *module_event = (void *)event->event_data;
+ const char *g_hinic3_module_link_err[LINK_ERR_NUM] = {
+ "Unrecognized module" };
+ struct hinic3_port_module_event *module_event =
+ (void *)event->event_data;
enum port_module_event_type type = module_event->type;
enum link_err_type err_type = module_event->err_type;
@@ -1003,6 +1231,116 @@ static void hinic3_port_module_event_handler(struct hinic3_nic_dev *nic_dev,
}
}
+bool hinic3_need_proc_link_event(struct hinic3_lld_dev *lld_dev)
+{
+ int ret = 0;
+ u16 func_id;
+ u8 roce_enable = false;
+ bool is_slave_func = false;
+ struct hinic3_hw_bond_infos hw_bond_infos = {0};
+
+ if (!lld_dev)
+ return false;
+
+ /* 非slave设备需要处理link down事件 */
+ ret = hinic3_is_slave_func(lld_dev->hwdev, &is_slave_func);
+ if (ret != 0) {
+ nic_err(&lld_dev->pdev->dev, "NIC get info, lld_dev is null\n");
+ return true;
+ }
+
+ if (!is_slave_func)
+ return true;
+
+ /* 未使能了vroce功能,需处理link down事件 */
+ func_id = hinic3_global_func_id(lld_dev->hwdev);
+ ret = hinic3_get_func_vroce_enable(lld_dev->hwdev, func_id, &roce_enable);
+ if (ret != 0)
+ return true;
+
+ if (!roce_enable)
+ return true;
+
+ /* 未创建bond,需要处理link down事件 */
+ hw_bond_infos.bond_id = HINIC_OVS_BOND_DEFAULT_ID;
+
+ ret = hinic3_get_hw_bond_infos(lld_dev->hwdev, &hw_bond_infos, HINIC3_CHANNEL_COMM);
+ if (ret != 0) {
+ pr_err("[ROCE, ERR] Get chipf bond info failed (%d)\n", ret);
+ return true;
+ }
+
+ if (!hw_bond_infos.valid)
+ return true;
+
+ return false;
+}
+
+bool hinic3_need_proc_bond_event(struct hinic3_lld_dev *lld_dev)
+{
+ return !hinic3_need_proc_link_event(lld_dev);
+}
+
+static void hinic_porc_bond_state_change(struct hinic3_lld_dev *lld_dev, void *adapter,
+ struct hinic3_event_info *event)
+{
+ struct hinic3_nic_dev *nic_dev = adapter;
+
+ if (!nic_dev || !event || !hinic3_support_nic(lld_dev->hwdev, NULL))
+ return;
+
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond down\n");
+ hinic3_link_status_change(nic_dev, false);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond up\n");
+ hinic3_link_status_change(nic_dev, true);
+ break;
+ default:
+ break;
+ }
+}
+
+static void hinic3_outband_cfg_event_handler(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_outband_cfg_info *info)
+{
+ int err = 0;
+
+ if (!nic_dev || !info || !hinic3_support_nic(nic_dev->hwdev, NULL)) {
+ pr_err("Outband cfg event invalid param\n");
+ return;
+ }
+
+ if (hinic3_func_type(nic_dev->hwdev) != TYPE_VF &&
+ info->func_id >= NIC_MAX_PF_NUM) {
+ err = hinic3_notify_vf_outband_cfg(nic_dev->hwdev,
+ info->func_id,
+ info->outband_default_vid);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev,
+ "Outband cfg event notify vf err: %d, func_id: 0x%x, vid: 0x%x\n",
+ err, info->func_id, info->outband_default_vid);
+ return;
+ }
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Change outband default vid from %u to %u\n",
+ nic_dev->outband_cfg.outband_default_vid,
+ info->outband_default_vid);
+
+ nic_dev->outband_cfg.outband_default_vid = info->outband_default_vid;
+}
+
static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
struct hinic3_event_info *event)
{
@@ -1014,21 +1352,35 @@ static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_DOWN):
+ if (!hinic3_need_proc_link_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc link event\n");
+ return;
+ }
hinic3_link_status_change(nic_dev, false);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_UP):
hinic3_link_status_change(nic_dev, true);
break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ hinic_porc_bond_state_change(lld_dev, adapter, event);
+ break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_PORT_MODULE_EVENT):
hinic3_port_module_event_handler(nic_dev, event);
break;
- case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_SRIOV_STATE_CHANGE):
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_OUTBAND_CFG):
+ hinic3_outband_cfg_event_handler(nic_dev,
+ (void *)event->event_data);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM,
+ EVENT_COMM_SRIOV_STATE_CHANGE):
sriov_state_change(nic_dev, (void *)event->event_data);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_FAULT):
fault = (void *)event->event_data;
if (fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
- fault->event.chip.func_id == hinic3_global_func_id(lld_dev->hwdev))
+ fault->event.chip.func_id ==
+ hinic3_global_func_id(lld_dev->hwdev))
hinic3_link_status_change(nic_dev, false);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_PCIE_LINK_DOWN):
@@ -1081,7 +1433,7 @@ struct hinic3_uld_info g_nic_uld_info = {
.resume = NULL,
.event = nic_event,
.ioctl = nic_ioctl,
-}; /*lint -e766*/
+};
struct hinic3_uld_info *get_nic_uld_info(void)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
index 94e606e..668f30e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
@@ -9,6 +9,7 @@
/* Interrupt at most records, interrupt will be recorded in the FFM */
#define NICTOOL_CMD_TYPE (0x18)
+#define HINIC3_CARD_NAME_MAX_LEN (128)
struct api_cmd_rd {
u32 pf_id;
@@ -110,7 +111,8 @@ enum dbgtool_cmd {
DBGTOOL_CMD_NUM
};
-#define PF_MAX_SIZE (16)
+#define HINIC_PF_MAX_SIZE (16)
+#define HINIC_VF_MAX_SIZE (4096)
#define BUSINFO_LEN (32)
enum module_name {
@@ -132,7 +134,8 @@ enum module_name {
SEND_TO_MIGRATE_DRIVER,
SEND_TO_PPA_DRIVER,
SEND_TO_CUSTOM_DRIVER = SEND_TO_SRV_DRV_BASE + 11,
- SEND_TO_BIFUR_DRIVER = SEND_TO_SRV_DRV_BASE + 15,
+ SEND_TO_VSOCK_DRIVER = SEND_TO_SRV_DRV_BASE + 14,
+ SEND_TO_BIFUR_DRIVER,
SEND_TO_DRIVER_MAX = SEND_TO_SRV_DRV_BASE + 16, /* reserved */
};
@@ -160,7 +163,7 @@ enum driver_cmd_type {
GET_CHIP_FAULT_STATS,
NIC_RSVD1,
NIC_RSVD2,
- NIC_RSVD3,
+ GET_OS_HOT_REPLACE_INFO,
GET_CHIP_ID,
GET_SINGLE_CARD_INFO,
GET_FIRMWARE_ACTIVE_STATUS,
@@ -171,7 +174,7 @@ enum driver_cmd_type {
GET_LOOPBACK_MODE = 32,
SET_LOOPBACK_MODE,
SET_LINK_MODE,
- SET_PF_BW_LIMIT,
+ SET_TX_PF_BW_LIMIT,
GET_PF_BW_LIMIT,
ROCE_CMD,
GET_POLL_WEIGHT,
@@ -189,6 +192,7 @@ enum driver_cmd_type {
GET_NIC_STATS_STRING,
GET_NIC_STATS_INFO,
GET_PF_ID,
+ GET_MBOX_CNT,
NIC_RSVD4,
NIC_RSVD5,
DCB_QOS_INFO,
@@ -205,6 +209,8 @@ enum driver_cmd_type {
RSS_INDIR,
PORT_ID,
+ SET_RX_PF_BW_LIMIT = 0x43,
+
GET_FUNC_CAP = 0x50,
GET_XSFP_PRESENT = 0x51,
GET_XSFP_INFO = 0x52,
@@ -216,6 +222,38 @@ enum driver_cmd_type {
WIN_CSR_WRITE = 0x62,
WIN_API_CMD_RD = 0x63,
+ GET_FUSION_Q = 0x64,
+ ROCE_CMD_SET_LDCP_PARAM = 0x70,
+
+ ROCE_CMD_GET_QPC_FROM_CACHE = 0x80,
+ ROCE_CMD_GET_QPC_FROM_HOST = 0x81,
+ ROCE_CMD_GET_CQC_FROM_CACHE = 0x82,
+ ROCE_CMD_GET_CQC_FROM_HOST = 0x83,
+ ROCE_CMD_GET_SRQC_FROM_CACHE = 0x84,
+ ROCE_CMD_GET_SRQC_FROM_HOST = 0x85,
+ ROCE_CMD_GET_MPT_FROM_CACHE = 0x86,
+ ROCE_CMD_GET_MPT_FROM_HOST = 0x87,
+ ROCE_CMD_GET_GID_FROM_CACHE = 0x88,
+ ROCE_CMD_GET_QPC_CQC_PI_CI = 0x89,
+ ROCE_CMD_GET_QP_COUNT = 0x8a,
+ ROCE_CMD_GET_DEV_ALGO = 0x8b,
+
+ ROCE_CMD_START_CAP_PACKET = 0x90,
+ ROCE_CMD_STOP_CAP_PACKET = 0x91,
+ ROCE_CMD_QUERY_CAP_INFO = 0x92,
+ ROCE_CMD_ENABLE_QP_CAP_PACKET = 0x93,
+ ROCE_CMD_DISABLE_QP_CAP_PACKET = 0x94,
+ ROCE_CMD_QUERY_QP_CAP_INFO = 0x95,
+
+ ROCE_CMD_ENABLE_BW_CTRL = 0xa0,
+ ROCE_CMD_DISABLE_BW_CTRL = 0xa1,
+ ROCE_CMD_CHANGE_BW_CTRL_PARAM = 0xa2,
+ ROCE_CMD_QUERY_BW_CTRL_PARAM = 0xa3,
+
+ ROCE_CMD_TIMEOUT_ALARM = 0xb0,
+ ROCE_CMD_PORT_TRAFFIC = 0Xb1,
+ ROCE_CMD_BOND_HASH_TYPE_SET = 0xb2,
+
BIFUR_SET_ENABLE = 0xc0,
BIFUR_GET_ENABLE = 0xc1,
@@ -234,7 +272,8 @@ enum sm_cmd_type {
SM_CTR_RD64,
SM_CTR_RD32_CLEAR,
SM_CTR_RD64_PAIR_CLEAR,
- SM_CTR_RD64_CLEAR
+ SM_CTR_RD64_CLEAR,
+ SM_CTR_RD16_CLEAR,
};
struct cqm_stats {
@@ -321,10 +360,22 @@ struct pf_info {
};
struct card_info {
- struct pf_info pf[PF_MAX_SIZE];
+ struct pf_info pf[HINIC_PF_MAX_SIZE];
u32 pf_num;
};
+struct func_mbox_cnt_info {
+ char bus_info[BUSINFO_LEN];
+ u64 send_cnt;
+ u64 ack_cnt;
+};
+
+struct card_mbox_cnt_info {
+ struct func_mbox_cnt_info func_info[HINIC_PF_MAX_SIZE +
+ HINIC_VF_MAX_SIZE];
+ u32 func_num;
+};
+
struct hinic3_nic_loop_mode {
u32 loop_mode;
u32 loop_ctrl;
@@ -665,6 +716,161 @@ struct get_card_bond_msg_s {
struct bond_all_msg_s all_msg[MAX_BONDING_CNT_PER_CARD];
};
+#define MAX_FUSION_Q_STATS_STR_LEN 16
+#define MAX_FUSION_Q_NUM 256
+struct queue_status_s {
+ pid_t tgid;
+ char status[MAX_FUSION_Q_STATS_STR_LEN];
+};
+struct fusion_q_status_s {
+ u16 queue_num;
+ struct queue_status_s queue[MAX_FUSION_Q_NUM];
+};
+
+struct fusion_q_tx_hw_page {
+ u64 phy_addr;
+ u64 *map_addr;
+};
+
+struct fusion_sq_info {
+ u16 q_id;
+ u16 pi;
+ u16 ci; /* sw_ci */
+ u16 fi; /* hw_ci */
+ u32 q_depth;
+ u16 pi_reverse;
+ u16 wqebb_size;
+ u8 priority;
+ u16 *ci_addr;
+ u64 cla_addr;
+ void *slq_handle;
+ struct fusion_q_tx_hw_page direct_wqe;
+ struct fusion_q_tx_hw_page doorbell;
+ u32 page_idx;
+ u32 glb_sq_id;
+};
+
+struct fusion_q_tx_wqe {
+ u32 data[4];
+};
+
+struct fusion_rq_info {
+ u16 q_id;
+ u16 delta;
+ u16 hw_pi;
+ u16 ci; /* sw_ci */
+ u16 sw_pi;
+ u16 wqebb_size;
+ u16 q_depth;
+ u16 buf_len;
+
+ void *slq_handle;
+ u64 ci_wqe_page_addr;
+ u64 ci_cla_tbl_addr;
+
+ u8 coalesc_timer_cfg;
+ u8 pending_limt;
+ u16 msix_idx;
+ u32 msix_vector;
+};
+
+struct fusion_q_rx_wqe {
+ u32 data[8];
+};
+
+struct fusion_q_rx_cqe {
+ union {
+ struct {
+ unsigned int checksum_err : 16;
+ unsigned int lro_num : 8;
+ unsigned int rsvd1 : 7;
+ unsigned int rx_done : 1;
+ } bs;
+ unsigned int value;
+ } dw0;
+
+ union {
+ struct {
+ unsigned int vlan : 16;
+ unsigned int length : 16;
+ } bs;
+ unsigned int value;
+ } dw1;
+
+ union {
+ struct {
+ unsigned int pkt_types : 12;
+ unsigned int rsvd : 4;
+ unsigned int udp_0 : 1;
+ unsigned int ipv6_ex_add : 1;
+ unsigned int loopback : 1;
+ unsigned int umbcast : 2;
+ unsigned int vlan_offload_en : 1;
+ unsigned int tag_num : 2;
+ unsigned int rss_type : 8;
+ } bs;
+ unsigned int value;
+ } dw2;
+
+ union {
+ struct {
+ unsigned int rss_hash_value;
+ } bs;
+ unsigned int value;
+ } dw3;
+
+ union {
+ struct {
+ unsigned int tx_ts_seq : 16;
+ unsigned int message_1588_offset : 8;
+ unsigned int message_1588_type : 4;
+ unsigned int rsvd : 1;
+ unsigned int if_rx_ts : 1;
+ unsigned int if_tx_ts : 1;
+ unsigned int if_1588 : 1;
+ } bs;
+ unsigned int value;
+ } dw4;
+
+ union {
+ struct {
+ unsigned int ts;
+ } bs;
+ unsigned int value;
+ } dw5;
+
+ union {
+ struct {
+ unsigned int lro_ts;
+ } bs;
+ unsigned int value;
+ } dw6;
+
+ union {
+ struct {
+ unsigned int rsvd0;
+ } bs;
+ unsigned int value;
+ } dw7; /* 16Bytes Align */
+};
+
+struct os_hot_repalce_func_info {
+ char card_name[HINIC3_CARD_NAME_MAX_LEN];
+ u32 bus_num;
+ u32 valid;
+ u32 bdf;
+ int partition;
+ u16 backup_pf;
+ u16 pf_idx;
+ int port_id;
+};
+
+#define ALL_CARD_PF_NUM 2048 /* 64 card * 32 pf */
+struct os_hot_replace_info {
+ struct os_hot_repalce_func_info func_infos[ALL_CARD_PF_NUM];
+ u32 func_cnt;
+};
+
int alloc_buff_in(void *hwdev, struct msg_module *nt_msg, u32 in_size, void **buf_in);
int alloc_buff_out(void *hwdev, struct msg_module *nt_msg, u32 out_size, void **buf_out);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
index ea1d506..66c41f8 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
@@ -15,6 +15,9 @@
#include <linux/ip.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#ifdef HAVE_XDP_SUPPORT
#include <linux/bpf.h>
#endif
@@ -28,6 +31,10 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
+#include "nic_npu_cmd.h"
+
+#include "vram_common.h"
+
#define HINIC3_DEFAULT_RX_CSUM_OFFLOAD 0xFFF
#define HINIC3_LRO_DEFAULT_COAL_PKT_SIZE 32
@@ -47,8 +54,63 @@ static void hinic3_nic_set_rx_mode(struct net_device *netdev)
queue_work(nic_dev->workq, &nic_dev->rx_mode_work);
}
+static void hinic3_free_irq_vram(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_dyna_txrxq_params *in_q_params)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ struct hinic3_dyna_txrxq_params q_params = nic_dev->q_params;
+
+ if (q_params.irq_cfg == NULL)
+ return;
+
+ size = sizeof(struct hinic3_irq) * (q_params.num_qps);
+
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)q_params.irq_cfg, q_params.irq_cfg_vram_name, size);
+ q_params.irq_cfg = NULL;
+ } else {
+ kfree(in_q_params->irq_cfg);
+ in_q_params->irq_cfg = NULL;
+ }
+}
+
+static int hinic3_alloc_irq_vram(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_dyna_txrxq_params *q_params, bool is_up_eth)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ u16 func_id;
+
+ size = sizeof(struct hinic3_irq) * q_params->num_qps;
+
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(q_params->irq_cfg_vram_name, VRAM_NAME_MAX_LEN,
+ "%s%hu", VRAM_NIC_IRQ_VRAM, func_id);
+ q_params->irq_cfg = (struct hinic3_irq *)hi_vram_kalloc(
+ q_params->irq_cfg_vram_name, size);
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq vram alloc failed.\n");
+ return -ENOMEM;
+ }
+ /* in order to clear napi stored in vram, irq need to init when eth up */
+ if (is_up_eth)
+ memset(q_params->irq_cfg, 0, size);
+ } else {
+ q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq alloc failed.\n");
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_txrxq_params *q_params)
+ struct hinic3_dyna_txrxq_params *q_params,
+ bool is_up_eth)
{
u32 size;
int err;
@@ -70,12 +132,9 @@ static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
goto alloc_rxqs_res_arr_err;
}
- size = sizeof(*q_params->irq_cfg) * q_params->num_qps;
- q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
- if (!q_params->irq_cfg) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to alloc irq resource array\n");
- err = -ENOMEM;
+ err = hinic3_alloc_irq_vram(nic_dev, q_params, is_up_eth);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc irq resource array\n");
goto alloc_irq_cfg_err;
}
@@ -102,8 +161,7 @@ alloc_rxqs_res_err:
q_params->txqs_res);
alloc_txqs_res_err:
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ hinic3_free_irq_vram(nic_dev, q_params);
alloc_irq_cfg_err:
kfree(q_params->rxqs_res);
@@ -117,15 +175,17 @@ alloc_rxqs_res_arr_err:
}
static void hinic3_free_txrxq_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_txrxq_params *q_params)
+ struct hinic3_dyna_txrxq_params *q_params)
{
+ int is_in_kexec = vram_get_kexec_flag();
+
hinic3_free_rxqs_res(nic_dev, q_params->num_qps, q_params->rq_depth,
q_params->rxqs_res);
hinic3_free_txqs_res(nic_dev, q_params->num_qps, q_params->sq_depth,
q_params->txqs_res);
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ if (is_in_kexec == 0)
+ hinic3_free_irq_vram(nic_dev, q_params);
kfree(q_params->rxqs_res);
q_params->rxqs_res = NULL;
@@ -161,6 +221,7 @@ static int hinic3_configure_txrxqs(struct hinic3_nic_dev *nic_dev,
static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos;
if (!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
@@ -171,12 +232,13 @@ static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
num_cos = hinic3_get_dev_user_cos_num(nic_dev);
hinic3_update_qp_cos_cfg(nic_dev, num_cos);
/* For now, we don't support to change num_cos */
- if (num_cos > nic_dev->cos_config_num_max ||
+ if (num_cos > dcb->cos_config_num_max ||
nic_dev->q_params.num_qps < num_cos) {
nicif_err(nic_dev, drv, netdev, "Invalid num_cos: %u or num_qps: %u, disable DCB\n",
num_cos, nic_dev->q_params.num_qps);
nic_dev->q_params.num_cos = 0;
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
/* if we can't enable rss or get enough num_qps,
* need to sync default configure to hw
*/
@@ -190,17 +252,22 @@ static int hinic3_configure(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
- err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
- if (err) {
- nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
- return err;
+ if (is_in_kexec == 0) {
+ err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
+ return err;
+ }
}
config_dcb_qps_map(nic_dev);
/* rx rss init */
- err = hinic3_rx_configure(netdev, test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ err = hinic3_rx_configure(netdev,
+ test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)
+ ? 1 : 0);
if (err) {
nicif_err(nic_dev, drv, netdev, "Failed to configure rx\n");
return err;
@@ -256,10 +323,11 @@ static void config_dcb_num_qps(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dyna_txrxq_params *q_params,
u16 max_qps)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos = q_params->num_cos;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (!num_cos || num_cos > nic_dev->cos_config_num_max || num_cos > max_qps)
+ if (!num_cos || num_cos > dcb->cos_config_num_max || num_cos > max_qps)
return; /* will disable DCB in config_dcb_qps_map() */
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
@@ -313,8 +381,10 @@ static int hinic3_setup_num_qps(struct hinic3_nic_dev *nic_dev)
return -EINVAL;
}
nic_dev->qps_irq_info = kzalloc(irq_size, GFP_KERNEL);
- if (!nic_dev->qps_irq_info)
+ if (!nic_dev->qps_irq_info) {
+ nicif_err(nic_dev, drv, netdev, "Failed to alloc qps_irq_info\n");
return -ENOMEM;
+ }
hinic3_config_num_qps(nic_dev, &nic_dev->q_params);
@@ -332,57 +402,10 @@ static void hinic3_destroy_num_qps(struct hinic3_nic_dev *nic_dev)
kfree(nic_dev->qps_irq_info);
}
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev)
-{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- err = hinic3_set_port_enable(nic_dev->hwdev, false, HINIC3_CHANNEL_NIC);
- if (!err)
- nic_dev->force_port_disable = true;
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
-{
- int err = 0;
-
- down(&nic_dev->port_state_sem);
-
- nic_dev->force_port_disable = false;
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
- HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- /* Do nothing when force disable
- * Port will disable when call force port disable
- * and should not enable port when in force mode
- */
- if (nic_dev->force_port_disable) {
- up(&nic_dev->port_state_sem);
- return 0;
- }
-
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
- HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
+ return hinic3_set_port_enable(nic_dev->hwdev, enable,
+ HINIC3_CHANNEL_NIC);
}
static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
@@ -398,8 +421,8 @@ static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
}
static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+ struct hinic3_dyna_qp_params *qp_params,
+ struct hinic3_dyna_txrxq_params *trxq_params, bool is_up_eth)
{
int err;
@@ -414,7 +437,7 @@ static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
return err;
}
- err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params);
+ err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params, is_up_eth);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc txrxq resources\n");
hinic3_free_qps(nic_dev->hwdev, qp_params);
@@ -425,8 +448,8 @@ static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
}
static void hinic3_free_channel_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+ struct hinic3_dyna_qp_params *qp_params,
+ struct hinic3_dyna_txrxq_params *trxq_params)
{
mutex_lock(&nic_dev->nic_mutex);
hinic3_free_txrxq_resources(nic_dev, trxq_params);
@@ -521,7 +544,8 @@ int hinic3_vport_up(struct hinic3_nic_dev *nic_dev)
queue_delayed_work(nic_dev->workq, &nic_dev->moderation_task,
HINIC3_MODERATONE_DELAY);
if (test_bit(HINIC3_RXQ_RECOVERY, &nic_dev->flags))
- queue_delayed_work(nic_dev->workq, &nic_dev->rxq_check_work, HZ);
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->rxq_check_work, HZ);
hinic3_print_link_message(nic_dev, link_status);
@@ -542,9 +566,52 @@ vport_enable_err:
return err;
}
+static int hinic3_flush_rq_and_check(struct hinic3_nic_dev *nic_dev, u16 glb_func_id)
+{
+ struct hinic3_flush_rq *rq_flush_msg = NULL;
+ struct hinic3_cmd_buf *cmd_buf = NULL;
+ int out_buf_len = sizeof(struct hinic3_flush_rq);
+ u16 rq_id;
+ u64 out_param = 0;
+ int ret;
+
+ cmd_buf = hinic3_alloc_cmd_buf(nic_dev->hwdev);
+ if (!cmd_buf) {
+ nic_err(&nic_dev->pdev->dev, "Failed to allocate cmd buf\n");
+ return -ENOMEM;
+ }
+
+ cmd_buf->size = sizeof(struct hinic3_flush_rq);
+ rq_flush_msg = (struct hinic3_flush_rq *)cmd_buf->buf;
+ rq_flush_msg->dw.bs.func_id = glb_func_id;
+ for (rq_id = 0; rq_id < nic_dev->q_params.num_qps; rq_id++) {
+ rq_flush_msg->dw.bs.rq_id = rq_id;
+ hinic3_cpu_to_be32(rq_flush_msg, out_buf_len);
+ ret = hinic3_cmdq_direct_resp(nic_dev->hwdev, HINIC3_MOD_L2NIC,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ cmd_buf, &out_param, 0,
+ HINIC3_CHANNEL_NIC);
+ if (ret != 0 || out_param != 0) {
+ nic_err(&nic_dev->pdev->dev, "Failed to flush rq, ret:%d, func:%u, rq:%u\n",
+ ret, glb_func_id, rq_id);
+ goto err;
+ }
+ hinic3_be32_to_cpu(rq_flush_msg, out_buf_len);
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Func:%u rq_num:%u flush rq success\n",
+ glb_func_id, nic_dev->q_params.num_qps);
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return 0;
+err:
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return -1;
+}
+
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
{
u16 glb_func_id;
+ int is_in_kexec = vram_get_kexec_flag();
netif_carrier_off(nic_dev->netdev);
netif_tx_disable(nic_dev->netdev);
@@ -557,18 +624,21 @@ void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, 0);
- hinic3_maybe_set_port_state(nic_dev, false);
+ if (is_in_kexec != 0)
+ nicif_info(nic_dev, drv, nic_dev->netdev, "Skip changing mag status!\n");
+ else
+ hinic3_maybe_set_port_state(nic_dev, false);
glb_func_id = hinic3_global_func_id(nic_dev->hwdev);
hinic3_set_vport_enable(nic_dev->hwdev, glb_func_id, false,
HINIC3_CHANNEL_NIC);
hinic3_flush_txqs(nic_dev->netdev);
- /* After set vport disable 100ms,
- * no packets will be send to host
- * FPGA set 2000ms
- */
- msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+
+ if (is_in_kexec == 0)
+ msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+ else
+ (void)hinic3_flush_rq_and_check(nic_dev, glb_func_id);
hinic3_flush_qps_res(nic_dev->hwdev);
}
}
@@ -581,11 +651,12 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_qp_params new_qp_params = {0};
struct hinic3_dyna_qp_params cur_qp_params = {0};
int err;
+ bool is_free_resources = false;
hinic3_config_num_qps(nic_dev, trxq_params);
err = hinic3_alloc_channel_resources(nic_dev, &new_qp_params,
- trxq_params);
+ trxq_params, false);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc channel resources\n");
@@ -597,10 +668,19 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
hinic3_close_channel(nic_dev, &cur_qp_params);
hinic3_free_channel_resources(nic_dev, &cur_qp_params,
&nic_dev->q_params);
+ is_free_resources = true;
}
if (nic_dev->num_qp_irq > trxq_params->num_qps)
hinic3_qp_irq_change(nic_dev, trxq_params->num_qps);
+
+ if (is_free_resources) {
+ err = hinic3_alloc_irq_vram(nic_dev, trxq_params, false);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Change chl alloc irq failed\n");
+ goto alloc_irq_err;
+ }
+ }
nic_dev->q_params = *trxq_params;
if (reopen_handler)
@@ -621,7 +701,7 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
vport_up_err:
hinic3_close_channel(nic_dev, &new_qp_params);
-
+alloc_irq_err:
open_channel_err:
hinic3_free_channel_resources(nic_dev, &new_qp_params, trxq_params);
@@ -652,7 +732,7 @@ int hinic3_open(struct net_device *netdev)
}
err = hinic3_alloc_channel_resources(nic_dev, &qp_params,
- &nic_dev->q_params);
+ &nic_dev->q_params, true);
if (err)
goto alloc_channel_res_err;
@@ -691,12 +771,31 @@ setup_qps_err:
return err;
}
+static void hinic3_delete_napi(struct hinic3_nic_dev *nic_dev)
+{
+ u16 q_id;
+ int is_in_kexec = vram_get_kexec_flag();
+ struct hinic3_irq *irq_cfg = NULL;
+
+ if (is_in_kexec == 0 || nic_dev->q_params.irq_cfg == NULL)
+ return;
+
+ for (q_id = 0; q_id < nic_dev->q_params.num_qps; q_id++) {
+ irq_cfg = &(nic_dev->q_params.irq_cfg[q_id]);
+ qp_del_napi(irq_cfg);
+ }
+
+ hinic3_free_irq_vram(nic_dev, &nic_dev->q_params);
+}
+
int hinic3_close(struct net_device *netdev)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic3_dyna_qp_params qp_params = {0};
if (!test_and_clear_bit(HINIC3_INTF_UP, &nic_dev->flags)) {
+ /* delete napi in os hotreplace rollback */
+ hinic3_delete_napi(nic_dev);
nicif_info(nic_dev, drv, netdev, "Netdev already close, do nothing\n");
return 0;
}
@@ -776,7 +875,8 @@ static u8 parse_ipv6_info(struct sk_buff *skb, u32 *rss_tunple,
return 0;
}
-static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb,
+static u16 select_queue_by_hash_func(struct net_device *dev,
+ struct sk_buff *skb,
unsigned int num_tx_queues)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(dev);
@@ -831,17 +931,20 @@ static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb
}
#define GET_DSCP_PRI_OFFSET 2
-static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev, struct sk_buff *skb)
+static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev,
+ struct sk_buff *skb)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int dscp_cp;
if (skb->protocol == htons(ETH_P_IP))
dscp_cp = ipv4_get_dsfield(ip_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
else if (skb->protocol == htons(ETH_P_IPV6))
- dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
+ dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >>
+ GET_DSCP_PRI_OFFSET;
else
- return nic_dev->hw_dcb_cfg.default_cos;
- return nic_dev->hw_dcb_cfg.dscp2cos[dscp_cp];
+ return dcb->hw_dcb_cfg.default_cos;
+ return dcb->hw_dcb_cfg.dscp2cos[dscp_cp];
}
#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY)
@@ -867,11 +970,13 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif /* end of HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK */
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u16 txq;
u8 cos, qp_num;
if (test_bit(HINIC3_SAME_RXTX, &nic_dev->flags))
- return select_queue_by_hash_func(netdev, skb, netdev->real_num_tx_queues);
+ return select_queue_by_hash_func(netdev, skb,
+ netdev->real_num_tx_queues);
txq =
#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY)
@@ -887,18 +992,19 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (nic_dev->hw_dcb_cfg.trust == DCB_PCP) {
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP) {
if (skb->vlan_tci)
- cos = nic_dev->hw_dcb_cfg.pcp2cos[skb->vlan_tci >> VLAN_PRIO_SHIFT];
+ cos = dcb->hw_dcb_cfg.pcp2cos[skb->vlan_tci >>
+ VLAN_PRIO_SHIFT];
else
- cos = nic_dev->hw_dcb_cfg.default_cos;
+ cos = dcb->hw_dcb_cfg.default_cos;
} else {
cos = hinic3_get_dscp_up(nic_dev, skb);
}
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cos] ?
- txq % nic_dev->hw_dcb_cfg.cos_qp_num[cos] : 0;
- txq = nic_dev->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
+ qp_num = dcb->hw_dcb_cfg.cos_qp_num[cos] ?
+ txq % dcb->hw_dcb_cfg.cos_qp_num[cos] : 0;
+ txq = dcb->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
}
return txq;
@@ -976,7 +1082,7 @@ static struct net_device_stats *hinic3_get_stats(struct net_device *netdev)
stats->rx_packets = packets;
stats->rx_bytes = bytes;
stats->rx_errors = errors;
- stats->rx_dropped = dropped;
+ stats->rx_dropped = dropped + nic_dev->vport_stats.rx_discard_vport;
#ifndef HAVE_VOID_NDO_GET_STATS64
return stats;
@@ -1023,10 +1129,18 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
u32 mtu = (u32)new_mtu;
int err = 0;
+ int is_in_kexec = vram_get_kexec_flag();
#ifdef HAVE_XDP_SUPPORT
u32 xdp_max_mtu;
+#endif
+ if (is_in_kexec != 0) {
+ nicif_info(nic_dev, drv, netdev, "Hotreplace skip change mtu\n");
+ return err;
+ }
+
+#ifdef HAVE_XDP_SUPPORT
if (hinic3_is_xdp_enable(nic_dev)) {
xdp_max_mtu = hinic3_xdp_max_mtu(nic_dev);
if (mtu > xdp_max_mtu) {
@@ -1045,6 +1159,7 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
nicif_info(nic_dev, drv, nic_dev->netdev, "Change mtu from %u to %d\n",
netdev->mtu, new_mtu);
netdev->mtu = mtu;
+ nic_dev->nic_vram->vram_mtu = mtu;
}
return err;
@@ -1078,6 +1193,76 @@ static int hinic3_set_mac_addr(struct net_device *netdev, void *addr)
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+static int hinic3_udp_tunnel_port_config(struct net_device *netdev,
+ struct udp_tunnel_info *ti,
+ u8 action)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u16 func_id = hinic3_global_func_id(nic_dev->hwdev);
+ u16 dst_port;
+ int ret = 0;
+
+ switch (ti->type) {
+ case UDP_TUNNEL_TYPE_VXLAN:
+ dst_port = ntohs(ti->port);
+ ret = hinic3_vlxan_port_config(nic_dev->hwdev,
+ func_id, dst_port, action);
+ if (ret != 0) {
+ nicif_warn(nic_dev, drv, netdev,
+ "Failed to set vxlan port %u to device\n",
+ dst_port);
+ break;
+ }
+ nicif_info(nic_dev, link, netdev, "Vxlan dst port set to %u\n",
+ action == HINIC3_CMD_OP_ADD
+ ? dst_port : ntohs(VXLAN_OFFLOAD_PORT_LE));
+ break;
+ default:
+ nicif_err(nic_dev, drv, netdev, "Failed to add port, only vxlan dst port is supported\n");
+ ret = -EINVAL;
+ }
+ return ret;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+static void hinic3_udp_tunnel_add(struct net_device *netdev,
+ struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+static void hinic3_udp_tunnel_del(struct net_device *netdev,
+ struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD */
+
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev,
+ __always_unused unsigned int table,
+ __always_unused unsigned int entry,
+ struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev,
+ __always_unused unsigned int table,
+ __always_unused unsigned int entry,
+ struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static int
hinic3_vlan_rx_add_vid(struct net_device *netdev,
__always_unused __be16 proto,
@@ -1124,7 +1309,7 @@ hinic3_vlan_rx_kill_vid(struct net_device *netdev,
int err = 0;
col = VID_COL(nic_dev, vid);
- line = VID_LINE(nic_dev, vid);
+ line = (int)VID_LINE(nic_dev, vid);
/* In the broadcast scenario, ucode finds the corresponding function
* based on VLAN 0 of vlan table. If we delete VLAN 0, the VLAN function
@@ -1163,14 +1348,12 @@ static int hinic3_vlan_restore(struct net_device *netdev)
return -EFAULT;
rcu_read_lock();
for (i = 0; i < VLAN_N_VID; i++) {
-/* lint -e778 */
#ifdef HAVE_VLAN_FIND_DEV_DEEP_RCU
vlandev =
__vlan_find_dev_deep_rcu(netdev, htons(ETH_P_8021Q), i);
#else
vlandev = __vlan_find_dev_deep(netdev, htons(ETH_P_8021Q), i);
#endif
-/* lint +e778 */
col = VID_COL(nic_dev, i);
line = VID_LINE(nic_dev, i);
if (!vlandev && (vlan_bitmap[line] & (1UL << col)) != 0) {
@@ -1328,12 +1511,17 @@ static int set_feature_vlan_filter(struct hinic3_nic_dev *nic_dev,
return 0;
#ifdef NEED_VLAN_RESTORE
- if (en)
+ if (en) {
err = hinic3_vlan_restore(nic_dev->netdev);
+ if (err) {
+ hinic3_err(nic_dev, drv, "vlan restore failed\n");
+ *failed_features |= vlan_filter_feature;
+ return err;
+ }
+ }
#endif
- if (err == 0)
- err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
+ err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
if (err) {
hinic3_err(nic_dev, drv, "%s rx vlan filter failed\n",
SET_FEATURES_OP_STR(en));
@@ -1427,8 +1615,8 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
struct hinic3_nic_dev *adapter = netdev_priv(netdev);
int err;
- if (is_multicast_ether_addr(mac) || /*lint !e574*/
- vf >= pci_num_vf(adapter->pdev)) /*lint !e574*/
+ if (is_multicast_ether_addr(mac) ||
+ vf >= pci_num_vf(adapter->pdev))
return -EINVAL;
err = hinic3_set_vf_mac(adapter->hwdev, OS_VF_ID_TO_HW(vf), mac);
@@ -1446,7 +1634,6 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
return 0;
}
-/*lint -save -e574 -e734*/
#ifdef IFLA_VF_MAX
static int set_hw_vf_vlan(void *hwdev, u16 cur_vlanprio, int vf,
u16 vlan, u8 qos)
@@ -1529,7 +1716,8 @@ static int hinic3_ndo_set_vf_spoofchk(struct net_device *netdev, int vf,
#endif
#ifdef HAVE_NDO_SET_VF_TRUST
-static int hinic3_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting)
+static int hinic3_ndo_set_vf_trust(struct net_device *netdev, int vf,
+ bool setting)
{
struct hinic3_nic_dev *adapter = netdev_priv(netdev);
int err;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
index 11c1731..7288c5c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
@@ -10,6 +10,8 @@
#include "hinic3_common.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
/* ************************ array index define ********************* */
#define ARRAY_INDEX_0 0
@@ -21,6 +23,36 @@
#define ARRAY_INDEX_6 6
#define ARRAY_INDEX_7 7
+#define XSFP_TLV_PRE_INFO_LEN 4
+
+enum hinic3_link_port_type {
+ LINK_PORT_UNKNOWN,
+ LINK_PORT_OPTICAL_MM,
+ LINK_PORT_OPTICAL_SM,
+ LINK_PORT_PAS_COPPER,
+ LINK_PORT_ACC,
+ LINK_PORT_BASET,
+ LINK_PORT_AOC = 0x40,
+ LINK_PORT_ELECTRIC,
+ LINK_PORT_BACKBOARD_INTERFACE,
+};
+
+enum hilink_fibre_subtype {
+ FIBRE_SUBTYPE_SR = 1,
+ FIBRE_SUBTYPE_LR,
+ FIBRE_SUBTYPE_MAX,
+};
+
+enum hilink_fec_type {
+ HILINK_FEC_NOT_SET,
+ HILINK_FEC_RSFEC,
+ HILINK_FEC_BASEFEC,
+ HILINK_FEC_NOFEC,
+ HILINK_FEC_LLRSFE,
+ HILINK_FEC_MAX_TYPE,
+};
+
+
#define SQ_CI_ADDR_SHIFT 2
#define RQ_CI_ADDR_SHIFT 4
@@ -71,6 +103,12 @@ struct hinic3_port_routine_cmd {
struct mag_cmd_get_xsfp_present abs;
};
+struct hinic3_port_routine_cmd_extern {
+ bool mpu_send_xsfp_tlv_info;
+
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp std_xsfp_tlv_info;
+};
+
struct hinic3_nic_cfg {
struct semaphore cfg_lock;
@@ -84,11 +122,13 @@ struct hinic3_nic_cfg {
struct nic_port_info port_info;
/* percentage of pf link bandwidth */
- u32 pf_bw_limit;
- u32 rsvd2;
+ u32 pf_bw_tx_limit;
+ u32 pf_bw_rx_limit;
- struct hinic3_port_routine_cmd rt_cmd;
- struct mutex sfp_mutex; /* mutex used for copy sfp info */
+ struct hinic3_port_routine_cmd rt_cmd;
+ struct hinic3_port_routine_cmd_extern rt_cmd_ext;
+ /* mutex used for copy sfp info */
+ struct mutex sfp_mutex;
};
struct hinic3_nic_cmdq_ops;
@@ -98,7 +138,7 @@ struct hinic3_nic_io {
void *dev_hdl;
u8 link_status;
- u8 rsvd1;
+ u8 direct;
u32 rsvd2;
struct hinic3_io_queue *sq;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
index 747ac03..f136893 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
@@ -21,11 +21,132 @@
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_nic_cmdq.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_common.h"
#include "hinic3_nic_cfg.h"
-int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_sq_attr *attr)
+#include "vram_common.h"
+
+int hinic3_delete_bond(void *hwdev)
+{
+ struct hinic3_cmd_delete_bond cmd_delete_bond;
+ u16 out_size = sizeof(cmd_delete_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_delete_bond, 0, sizeof(cmd_delete_bond));
+ cmd_delete_bond.bond_id = HINIC3_INVALID_BOND_ID;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_DELETE,
+ &cmd_delete_bond, sizeof(cmd_delete_bond),
+ &cmd_delete_bond, &out_size);
+ if (err || !out_size || cmd_delete_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to delete bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_delete_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_delete_bond.bond_id != HINIC3_INVALID_BOND_ID)
+ nic_info(nic_io->dev_hdl, "Delete bond success\n");
+
+ return 0;
+}
+
+int hinic3_open_close_bond(void *hwdev, u32 bond_en)
+{
+ struct hinic3_cmd_open_close_bond cmd_open_close_bond;
+ u16 out_size = sizeof(cmd_open_close_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_open_close_bond, 0, sizeof(cmd_open_close_bond));
+ cmd_open_close_bond.open_close_bond_info.bond_id =
+ HINIC3_INVALID_BOND_ID;
+ cmd_open_close_bond.open_close_bond_info.open_close_flag = bond_en;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_OPEN_CLOSE,
+ &cmd_open_close_bond,
+ sizeof(cmd_open_close_bond),
+ &cmd_open_close_bond, &out_size);
+ if (err || !out_size || cmd_open_close_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to %s bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ bond_en == true ? "open" : "close", err,
+ cmd_open_close_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_open_close_bond.open_close_bond_info.bond_id !=
+ HINIC3_INVALID_BOND_ID) {
+ nic_info(nic_io->dev_hdl, "%s bond success\n", bond_en == true ? "Open" : "Close");
+ }
+
+ return 0;
+}
+
+int hinic3_create_bond(void *hwdev, u32 *bond_id)
+{
+ struct hinic3_cmd_create_bond cmd_create_bond;
+ u16 out_size = sizeof(cmd_create_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_create_bond, 0, sizeof(cmd_create_bond));
+ cmd_create_bond.create_bond_info.default_param_flag = true;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_CREATE,
+ &cmd_create_bond, sizeof(cmd_create_bond),
+ &cmd_create_bond, &out_size);
+ if (err || !out_size || cmd_create_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to create default bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_create_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_create_bond.create_bond_info.bond_id !=
+ HINIC3_INVALID_BOND_ID) {
+ *bond_id = cmd_create_bond.create_bond_info.bond_id;
+ nic_info(nic_io->dev_hdl, "Create bond success\n");
+ }
+
+ return 0;
+}
+
+int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io,
+ struct hinic3_sq_attr *attr)
{
struct hinic3_cmd_cons_idx_attr cons_idx_attr;
u16 out_size = sizeof(cons_idx_attr);
@@ -48,7 +169,8 @@ int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_sq_attr *at
cons_idx_attr.l2nic_sqn = attr->l2nic_sqn;
cons_idx_attr.ci_addr = attr->ci_dma_base >> SQ_CI_ADDR_SHIFT;
- err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_SQ_CI_ATTR_SET,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC3_NIC_CMD_SQ_CI_ATTR_SET,
&cons_idx_attr, sizeof(cons_idx_attr),
&cons_idx_attr, &out_size);
if (err || !out_size || cons_idx_attr.msg_head.status) {
@@ -61,7 +183,8 @@ int hinic3_set_sq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_sq_attr *at
return 0;
}
-int hinic3_set_rq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_rq_attr *attr)
+int hinic3_set_rq_ci_ctx(struct hinic3_nic_io *nic_io,
+ struct hinic3_rq_attr *attr)
{
struct hinic3_rq_cqe_ctx cons_idx_ctx;
u16 out_size = sizeof(cons_idx_ctx);
@@ -76,15 +199,19 @@ int hinic3_set_rq_ci_ctx(struct hinic3_nic_io *nic_io, struct hinic3_rq_attr *at
cons_idx_ctx.timer_loop = attr->coalescing_time;
cons_idx_ctx.threshold_cqe_num = attr->pending_limit;
cons_idx_ctx.msix_entry_idx = attr->intr_idx;
- cons_idx_ctx.ci_addr_hi = upper_32_bits(attr->ci_dma_base >> RQ_CI_ADDR_SHIFT);
- cons_idx_ctx.ci_addr_lo = lower_32_bits(attr->ci_dma_base >> RQ_CI_ADDR_SHIFT);
+ cons_idx_ctx.ci_addr_hi = upper_32_bits(attr->ci_dma_base >>
+ RQ_CI_ADDR_SHIFT);
+ cons_idx_ctx.ci_addr_lo = lower_32_bits(attr->ci_dma_base >>
+ RQ_CI_ADDR_SHIFT);
- err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_SET_RQ_CI_CTX,
+ err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
+ HINIC3_NIC_CMD_SET_RQ_CI_CTX,
&cons_idx_ctx, sizeof(cons_idx_ctx),
&cons_idx_ctx, &out_size);
if (err || !out_size || cons_idx_ctx.msg_head.status) {
nic_err(nic_io->dev_hdl, "Set rq cqe ctx fail, qid: %d, err: %d, status: 0x%x, out_size: 0x%x",
- attr->l2nic_rqn, err, cons_idx_ctx.msg_head.status, out_size);
+ attr->l2nic_rqn, err,
+ cons_idx_ctx.msg_head.status, out_size);
return -EFAULT;
}
@@ -142,8 +269,8 @@ int hinic3_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
&mac_info, sizeof(mac_info),
&mac_info, &out_size, channel);
if (err || !out_size ||
- hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
- mac_info.vlan_id)) {
+ (hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
+ mac_info.vlan_id) != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, mac_info.msg_head.status, out_size, channel);
@@ -178,6 +305,8 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -193,7 +322,8 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
&mac_info, sizeof(mac_info), &mac_info,
&out_size, channel);
if (err || !out_size ||
- (mac_info.msg_head.status && !PF_SET_VF_MAC(hwdev, mac_info.msg_head.status))) {
+ (mac_info.msg_head.status &&
+ !PF_SET_VF_MAC(hwdev, mac_info.msg_head.status))) {
nic_err(nic_io->dev_hdl,
"Failed to delete MAC, err: %d, status: 0x%x, out size: 0x%x, channel: 0x%x\n",
err, mac_info.msg_head.status, out_size, channel);
@@ -223,6 +353,8 @@ int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -239,8 +371,8 @@ int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
&mac_info, sizeof(mac_info),
&mac_info, &out_size);
if (err || !out_size ||
- hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
- mac_info.vlan_id)) {
+ (hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
+ mac_info.vlan_id) != 0)) {
nic_err(nic_io->dev_hdl,
"Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x\n",
err, mac_info.msg_head.status, out_size);
@@ -273,6 +405,8 @@ int hinic3_get_default_mac(void *hwdev, u8 *mac_addr)
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
mac_info.func_id = hinic3_global_func_id(hwdev);
@@ -318,6 +452,44 @@ static int hinic3_config_vlan(struct hinic3_nic_io *nic_io, u8 opcode,
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action)
+{
+ struct hinic3_cmd_vxlan_port_info vxlan_port_info;
+ u16 out_size = sizeof(vxlan_port_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ memset(&vxlan_port_info, 0, sizeof(vxlan_port_info));
+ vxlan_port_info.opcode = action;
+ vxlan_port_info.cfg_mode = 0; // other tool set
+ vxlan_port_info.func_id = func_id;
+ vxlan_port_info.vxlan_port = port;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+ &vxlan_port_info, sizeof(vxlan_port_info), &vxlan_port_info, &out_size);
+ if (err || !out_size || vxlan_port_info.msg_head.status) {
+ if (vxlan_port_info.msg_head.status == 0x2) // other tool set failed
+ nic_warn(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port because it has already been set by hinicadm\n",
+ action == HINIC3_CMD_OP_ADD
+ ? "add" : "delete");
+ else
+ nic_err(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port, err: %d, status: 0x%x, out size: 0x%x\n",
+ action == HINIC3_CMD_OP_ADD ? "add" : "delete",
+ err, vxlan_port_info.msg_head.status, out_size);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
{
struct hinic3_nic_io *nic_io = NULL;
@@ -326,6 +498,8 @@ int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan_id, func_id);
}
@@ -337,6 +511,8 @@ int hinic3_del_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_DEL, vlan_id, func_id);
}
@@ -380,6 +556,8 @@ int hinic3_set_dcb_state(void *hwdev, struct hinic3_dcb_state *dcb_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (!memcmp(&nic_io->dcb_state, dcb_state, sizeof(nic_io->dcb_state)))
return 0;
@@ -423,7 +601,8 @@ int hinic3_get_cos_by_pri(void *hwdev, u8 pri, u8 *cos)
if (pri >= NIC_DCB_UP_MAX && nic_io->dcb_state.trust == HINIC3_DCB_PCP)
return -EINVAL;
- if (pri >= NIC_DCB_IP_PRI_MAX && nic_io->dcb_state.trust == HINIC3_DCB_DSCP)
+ if (pri >= NIC_DCB_IP_PRI_MAX &&
+ nic_io->dcb_state.trust == HINIC3_DCB_DSCP)
return -EINVAL;
/*lint -e662*/
@@ -541,13 +720,15 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_cfg = &nic_io->nic_cfg;
down(&nic_cfg->cfg_lock);
err = hinic3_cfg_hw_pause(nic_io, HINIC3_CMD_OP_SET, &nic_pause);
- if (err) {
+ if (err != 0) {
up(&nic_cfg->cfg_lock);
return err;
}
@@ -566,7 +747,6 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
{
- struct hinic3_nic_cfg *nic_cfg = NULL;
struct hinic3_nic_io *nic_io = NULL;
int err = 0;
@@ -574,17 +754,13 @@ int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- nic_cfg = &nic_io->nic_cfg;
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_hw_pause(nic_io, HINIC3_CMD_OP_GET, nic_pause);
- if (err)
+ if (err != 0)
return err;
- if (nic_cfg->pause_set || !nic_pause->auto_neg) {
- nic_pause->rx_pause = nic_cfg->nic_pause.rx_pause;
- nic_pause->tx_pause = nic_cfg->nic_pause.tx_pause;
- }
-
return 0;
}
@@ -599,6 +775,8 @@ int hinic3_sync_dcb_state(void *hwdev, u8 op_code, u8 state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&dcb_state, 0, sizeof(dcb_state));
@@ -607,7 +785,8 @@ int hinic3_sync_dcb_state(void *hwdev, u8 op_code, u8 state)
dcb_state.func_id = hinic3_global_func_id(hwdev);
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_QOS_DCB_STATE,
- &dcb_state, sizeof(dcb_state), &dcb_state, &out_size);
+ &dcb_state, sizeof(dcb_state),
+ &dcb_state, &out_size);
if (err || dcb_state.head.status || !out_size) {
nic_err(nic_io->dev_hdl,
"Failed to set dcb state, err: %d, status: 0x%x, out size: 0x%x\n",
@@ -675,7 +854,8 @@ int hinic3_cache_out_qps_res(void *hwdev)
qp_res.func_id = hinic3_global_func_id(hwdev);
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
- &qp_res, sizeof(qp_res), &qp_res, &out_size);
+ &qp_res, sizeof(qp_res),
+ &qp_res, &out_size);
if (err || !out_size || qp_res.msg_head.status) {
nic_err(nic_io->dev_hdl, "Failed to cache out qp resources, err: %d, status: 0x%x, out size: 0x%x\n",
err, qp_res.msg_head.status, out_size);
@@ -685,45 +865,8 @@ int hinic3_cache_out_qps_res(void *hwdev)
return 0;
}
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats)
-{
- struct hinic3_port_stats *port_stats = NULL;
- struct hinic3_port_stats_info stats_info;
- u16 out_size = sizeof(*port_stats);
- struct hinic3_nic_io *nic_io = NULL;
- int err;
-
- port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
- if (!port_stats)
- return -ENOMEM;
-
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
-
- memset(&stats_info, 0, sizeof(stats_info));
-
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_PORT_STAT,
- &stats_info, sizeof(stats_info),
- port_stats, &out_size);
- if (err || !out_size || port_stats->msg_head.status) {
- nic_err(nic_io->dev_hdl,
- "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
- err, port_stats->msg_head.status, out_size);
- err = -EIO;
- goto out;
- }
-
- memcpy(stats, &port_stats->stats, sizeof(*stats));
-
-out:
- kfree(port_stats);
-
- return err;
-}
-EXPORT_SYMBOL(hinic3_get_fpga_phy_port_stats);
-
-int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *stats)
+int hinic3_get_vport_stats(void *hwdev, u16 func_id,
+ struct hinic3_vport_stats *stats)
{
struct hinic3_port_stats_info stats_info;
struct hinic3_cmd_vport_stats vport_stats;
@@ -738,6 +881,8 @@ int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *
memset(&vport_stats, 0, sizeof(vport_stats));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
stats_info.func_id = func_id;
@@ -756,7 +901,8 @@ int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *
return 0;
}
-static int hinic3_set_function_table(struct hinic3_nic_io *nic_io, u32 cfg_bitmap,
+static int hinic3_set_function_table(struct hinic3_nic_io *nic_io,
+ u32 cfg_bitmap,
const struct hinic3_func_tbl_cfg *cfg)
{
struct hinic3_cmd_set_func_tbl cmd_func_tbl;
@@ -804,6 +950,8 @@ int hinic3_set_port_mtu(void *hwdev, u16 new_mtu)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (new_mtu < HINIC3_MIN_MTU_SIZE) {
nic_err(nic_io->dev_hdl,
@@ -834,6 +982,8 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&feature_nego, 0, sizeof(feature_nego));
feature_nego.func_id = hinic3_global_func_id(hwdev);
feature_nego.opcode = opcode;
@@ -855,29 +1005,24 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return 0;
}
-static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
+static int hinic3_get_bios_pf_bw_tx_limit(void *hwdev,
+ struct hinic3_nic_io *nic_io,
+ u16 func_id, u32 *pf_rate)
{
- struct hinic3_nic_io *nic_io = NULL;
+ int err = 0; // default success
struct nic_cmd_bios_cfg cfg = {{0}};
u16 out_size = sizeof(cfg);
- int err;
-
- if (!hwdev || !pf_bw_limit)
- return -EINVAL;
-
- if (hinic3_func_type(hwdev) == TYPE_VF || !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
- return 0;
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- cfg.bios_cfg.func_id = (u8)hinic3_global_func_id(hwdev);
+ cfg.bios_cfg.func_id = (u8)func_id;
cfg.bios_cfg.func_valid = 1;
- cfg.op_code = 0 | NIC_NVM_DATA_PF_SPEED_LIMIT;
+ cfg.op_code = 0 | NIC_NVM_DATA_PF_TX_SPEED_LIMIT;
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BIOS_CFG, &cfg, sizeof(cfg),
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BIOS_CFG,
+ &cfg, sizeof(cfg),
&cfg, &out_size);
if (err || !out_size || cfg.head.status) {
nic_err(nic_io->dev_hdl,
- "Failed to get bios pf bandwidth limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ "Failed to get bios pf bandwidth tx limit, err: %d, status: 0x%x, out size: 0x%x\n",
err, cfg.head.status, out_size);
return -EIO;
}
@@ -887,13 +1032,86 @@ static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
nic_warn(nic_io->dev_hdl, "Invalid bios configuration data, signature: 0x%x\n",
cfg.bios_cfg.signature);
- if (cfg.bios_cfg.pf_bw > MAX_LIMIT_BW) {
+ if (cfg.bios_cfg.pf_tx_bw > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
+ cfg.bios_cfg.pf_tx_bw);
+ return -EINVAL;
+ }
+
+ (*pf_rate) = cfg.bios_cfg.pf_tx_bw;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_rx_limit(void *hwdev,
+ struct hinic3_nic_io *nic_io,
+ u16 func_id, u32 *pf_rate)
+{
+ int err = 0; // default success
+ struct nic_rx_rate_bios_cfg rx_bios_conf = {{0}};
+ u16 out_size = sizeof(rx_bios_conf);
+
+ rx_bios_conf.func_id = (u8)func_id;
+ rx_bios_conf.op_code = 0; /* 1-save, 0-read */
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_RX_RATE_CFG,
+ &rx_bios_conf, sizeof(rx_bios_conf),
+ &rx_bios_conf, &out_size);
+ if (rx_bios_conf.msg_head.status == HINIC3_MGMT_CMD_UNSUPPORTED &&
+ err == 0) { // Compatible older firmware
+ nic_warn(nic_io->dev_hdl, "Not support get bios pf bandwidth rx limit\n");
+ return 0;
+ } else if (err || !out_size || rx_bios_conf.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get bios pf bandwidth rx limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, rx_bios_conf.msg_head.status, out_size);
+ return -EIO;
+ }
+ if (rx_bios_conf.rx_rate_limit > MAX_LIMIT_BW) {
nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
- cfg.bios_cfg.pf_bw);
+ rx_bios_conf.rx_rate_limit);
return -EINVAL;
}
- *pf_bw_limit = cfg.bios_cfg.pf_bw;
+ (*pf_rate) = rx_bios_conf.rx_rate_limit;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit, u8 direct)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u32 pf_rate = 0;
+ int err = 0;
+ u16 func_id;
+
+ func_id = hinic3_global_func_id(hwdev);
+
+ if (!hwdev || !pf_bw_limit)
+ return -EINVAL;
+
+ if (hinic3_func_type(hwdev) == TYPE_VF ||
+ !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
+ return 0;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (direct == HINIC3_NIC_TX)
+ err = hinic3_get_bios_pf_bw_tx_limit(hwdev, nic_io,
+ func_id, &pf_rate);
+ else if (direct == HINIC3_NIC_RX)
+ err = hinic3_get_bios_pf_bw_rx_limit(hwdev, nic_io,
+ func_id, &pf_rate);
+
+ if (err != 0)
+ return err;
+
+ if (pf_rate > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl,
+ "Invalid bios cfg pf bandwidth limit: %u\n", pf_rate);
+ return -EINVAL;
+ }
+
+ *pf_bw_limit = pf_rate;
return 0;
}
@@ -902,8 +1120,9 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
{
struct hinic3_cmd_tx_rate_cfg rate_cfg = {{0}};
struct hinic3_nic_io *nic_io = NULL;
+ u32 rate_limit;
u16 out_size = sizeof(rate_cfg);
- u32 pf_rate;
+ u32 pf_rate = 0;
int err;
u32 speed_convert[PORT_SPEED_UNKNOWN] = {
0, 10, 100, 1000, 10000, 25000, 40000, 50000, 100000, 200000
@@ -914,30 +1133,34 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
return -EINVAL;
if (speed_level >= PORT_SPEED_UNKNOWN) {
- nic_err(nic_io->dev_hdl, "Invalid speed level: %u\n", speed_level);
+ nic_err(nic_io->dev_hdl,
+ "Invalid speed level: %u\n", speed_level);
return -EINVAL;
}
- if (nic_io->nic_cfg.pf_bw_limit == MAX_LIMIT_BW) {
- pf_rate = 0;
- } else {
+ rate_limit = (nic_io->direct == HINIC3_NIC_TX) ?
+ nic_io->nic_cfg.pf_bw_tx_limit : nic_io->nic_cfg.pf_bw_rx_limit;
+ if (rate_limit != MAX_LIMIT_BW) {
/* divided by 100 to convert to percentage */
- pf_rate = (speed_convert[speed_level] / 100) * nic_io->nic_cfg.pf_bw_limit;
+ pf_rate = (speed_convert[speed_level] / 100) * rate_limit;
/* bandwidth limit is very small but not unlimit in this case */
- if (pf_rate == 0 && speed_level != PORT_SPEED_NOT_SET)
+ if ((pf_rate == 0) && (speed_level != PORT_SPEED_NOT_SET))
pf_rate = 1;
}
rate_cfg.func_id = hinic3_global_func_id(hwdev);
rate_cfg.min_rate = 0;
rate_cfg.max_rate = pf_rate;
+ rate_cfg.direct = nic_io->direct;
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_MAX_MIN_RATE, &rate_cfg,
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
+ &rate_cfg,
sizeof(rate_cfg), &rate_cfg, &out_size);
if (err || !out_size || rate_cfg.msg_head.status) {
nic_err(nic_io->dev_hdl, "Failed to set rate(%u), err: %d, status: 0x%x, out size: 0x%x\n",
pf_rate, err, rate_cfg.msg_head.status, out_size);
- return rate_cfg.msg_head.status ? rate_cfg.msg_head.status : -EIO;
+ return rate_cfg.msg_head.status
+ ? rate_cfg.msg_head.status : -EIO;
}
return 0;
@@ -954,7 +1177,8 @@ int hinic3_set_nic_feature_to_hw(void *hwdev)
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- return nic_feature_nego(hwdev, HINIC3_CMD_OP_SET, &nic_io->feature_cap, 1);
+ return nic_feature_nego(hwdev, HINIC3_CMD_OP_SET,
+ &nic_io->feature_cap, 1);
}
u64 hinic3_get_feature_cap(void *hwdev)
@@ -962,6 +1186,8 @@ u64 hinic3_get_feature_cap(void *hwdev)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
return nic_io->feature_cap;
}
@@ -971,12 +1197,17 @@ void hinic3_update_nic_feature(void *hwdev, u64 s_feature)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
nic_io->feature_cap = s_feature;
- nic_info(nic_io->dev_hdl, "Update nic feature to 0x%llx\n", nic_io->feature_cap);
+ nic_info(nic_io->dev_hdl,
+ "Update nic feature to 0x%llx\n",
+ nic_io->feature_cap);
}
-static inline int init_nic_hwdev_param_valid(const void *hwdev, const void *pcidev_hdl,
+static inline int init_nic_hwdev_param_valid(const void *hwdev,
+ const void *pcidev_hdl,
const void *dev_hdl)
{
if (!hwdev || !pcidev_hdl || !dev_hdl)
@@ -1004,6 +1235,7 @@ static int hinic3_init_nic_io(void *hwdev, void *pcidev_hdl, void *dev_hdl,
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_abs = false;
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_info = false;
+ (*nic_io)->nic_cfg.rt_cmd_ext.mpu_send_xsfp_tlv_info = false;
return 0;
}
@@ -1020,27 +1252,34 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
{
struct hinic3_nic_io *nic_io = NULL;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
err = hinic3_init_nic_io(hwdev, pcidev_hdl, dev_hdl, &nic_io);
- if (err)
+ if (err != 0)
return err;
+ nic_io->rx_buff_len = rx_buff_len;
+
err = hinic3_register_service_adapter(hwdev, nic_io, SERVICE_T_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to register service adapter\n");
goto register_sa_err;
}
- err = hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 1, HINIC3_CHANNEL_NIC);
- if (err) {
+ err = hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC,
+ 1, HINIC3_CHANNEL_NIC);
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set function svc used state\n");
goto set_used_state_err;
}
- err = hinic3_init_function_table(nic_io);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to init function table\n");
- goto err_out;
+ if (is_in_kexec == 0) {
+ err = hinic3_init_function_table(nic_io);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to init function table\n");
+ goto err_out;
+ }
}
err = hinic3_get_nic_feature_from_hw(hwdev, &nic_io->feature_cap, 1);
@@ -1052,24 +1291,35 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
sdk_info(dev_hdl, "nic features: 0x%llx\n", nic_io->feature_cap);
hinic3_nic_cmdq_adapt_init(nic_io);
- err = hinic3_get_bios_pf_bw_limit(hwdev, &nic_io->nic_cfg.pf_bw_limit);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to get pf bandwidth limit\n");
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_tx_limit,
+ HINIC3_NIC_TX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf tx bandwidth limit\n");
+ goto err_out;
+ }
+
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_rx_limit,
+ HINIC3_NIC_RX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf rx bandwidth limit\n");
goto err_out;
}
err = hinic3_vf_func_init(nic_io);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to init vf info\n");
goto err_out;
}
- nic_io->rx_buff_len = rx_buff_len;
-
return 0;
err_out:
- hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 0, HINIC3_CHANNEL_NIC);
+ if (hinic3_set_func_svc_used_state(
+ hwdev, SVC_T_NIC, 0, HINIC3_CHANNEL_NIC) != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to set function svc used state\n");
+ }
set_used_state_err:
hinic3_unregister_service_adapter(hwdev, SERVICE_T_NIC);
@@ -1119,6 +1369,8 @@ int hinic3_force_drop_tx_pkt(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&pkt_drop, 0, sizeof(pkt_drop));
pkt_drop.port = hinic3_physical_port_id(hwdev);
@@ -1147,6 +1399,8 @@ int hinic3_set_rx_mode(void *hwdev, u32 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&rx_mode_cfg, 0, sizeof(rx_mode_cfg));
rx_mode_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1175,6 +1429,8 @@ int hinic3_set_rx_vlan_offload(void *hwdev, u8 en)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_cfg, 0, sizeof(vlan_cfg));
vlan_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1192,7 +1448,8 @@ int hinic3_set_rx_vlan_offload(void *hwdev, u8 en)
return 0;
}
-int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
+int hinic3_update_mac_vlan(void *hwdev, const u16 old_vlan,
+ u16 new_vlan, int vf_id)
{
struct vf_data_storage *vf_info = NULL;
struct hinic3_nic_io *nic_io = NULL;
@@ -1203,6 +1460,8 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
if (!nic_io->vf_infos || is_zero_ether_addr(vf_info->drv_mac_addr))
return 0;
@@ -1211,7 +1470,7 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
err = hinic3_del_mac(nic_io->hwdev, vf_info->drv_mac_addr,
old_vlan, func_id, HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to delete VF %d MAC %pM vlan %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->drv_mac_addr, old_vlan);
return err;
@@ -1219,7 +1478,7 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
err = hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
new_vlan, func_id, HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to add VF %d MAC %pM vlan %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->drv_mac_addr, new_vlan);
hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
@@ -1242,6 +1501,8 @@ static int hinic3_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en,
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_cfg, 0, sizeof(lro_cfg));
lro_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1273,6 +1534,8 @@ static int hinic3_set_rx_lro_timer(void *hwdev, u32 timer_value)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_timer, 0, sizeof(lro_timer));
lro_timer.opcode = HINIC3_CMD_OP_SET;
@@ -1305,12 +1568,14 @@ int hinic3_set_rx_lro_state(void *hwdev, u8 lro_en, u32 lro_timer,
ipv6_en = lro_en ? 1 : 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_info(nic_io->dev_hdl, "Set LRO max coalesce packet size to %uK\n",
lro_max_pkt_len);
err = hinic3_set_rx_lro(hwdev, ipv4_en, ipv6_en, (u8)lro_max_pkt_len);
- if (err)
+ if (err != 0)
return err;
/* we don't set LRO timer for VF */
@@ -1333,6 +1598,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_filter, 0, sizeof(vlan_filter));
vlan_filter.func_id = hinic3_global_func_id(hwdev);
@@ -1352,7 +1619,6 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
{
- // struct hinic_hwdev *dev = hwdev;
struct nic_cmd_capture_info cap_info = {{0}};
u16 out_size = sizeof(cap_info);
int err;
@@ -1361,7 +1627,6 @@ int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
return -EINVAL;
/* 2 function capture types */
- // cap_info.op_type = UP_UCAPTURE_OP_TYPE_FUNC;
cap_info.is_en_trx = cap_en;
cap_info.func_port = func_id;
@@ -1386,6 +1651,8 @@ int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (tcam_rule->index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to add is invalid\n");
return -EINVAL;
@@ -1421,6 +1688,8 @@ int hinic3_del_tcam_rule(void *hwdev, u32 index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to del is invalid\n");
return -EINVAL;
@@ -1470,6 +1739,8 @@ static int hinic3_mgmt_tcam_block(void *hwdev, u8 alloc_en, u16 *index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&tcam_block_info, 0,
sizeof(struct nic_cmd_ctrl_tcam_block_out));
@@ -1515,6 +1786,8 @@ int hinic3_set_fdir_tcam_rule_filter(void *hwdev, bool enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
port_tcam_cmd.func_id = hinic3_global_func_id(hwdev);
port_tcam_cmd.tcam_enable = (u8)enable;
@@ -1543,6 +1816,8 @@ int hinic3_flush_tcam_rule(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&tcam_flush, 0, sizeof(struct nic_cmd_flush_tcam_rules));
tcam_flush.func_id = hinic3_global_func_id(hwdev);
@@ -1560,7 +1835,8 @@ int hinic3_flush_tcam_rule(void *hwdev)
return 0;
}
-int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type)
+int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info,
+ u16 num_qps, u16 wqe_type)
{
struct hinic3_cmd_buf *cmd_buf = NULL;
struct hinic3_nic_io *nic_io = NULL;
@@ -1573,6 +1849,8 @@ int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -1587,9 +1865,11 @@ int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
cmd_buf->size = sizeof(struct hinic3_rxq_hw);
- err = hinic3_cmdq_detail_resp(hwdev, HINIC3_MOD_L2NIC, HINIC3_UCODE_CMD_RXQ_INFO_GET,
- cmd_buf, cmd_buf, NULL, 0, HINIC3_CHANNEL_NIC);
- if (err)
+ err = hinic3_cmdq_detail_resp(hwdev, HINIC3_MOD_L2NIC,
+ HINIC3_UCODE_CMD_RXQ_INFO_GET,
+ cmd_buf, cmd_buf, NULL, 0,
+ HINIC3_CHANNEL_NIC);
+ if (err != 0)
goto get_rxq_info_failed;
rxq_info_out = cmd_buf->buf;
@@ -1604,7 +1884,8 @@ get_rxq_info_failed:
return err;
}
-int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_state)
+int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced,
+ bool link_state)
{
struct hinic3_nic_io *nic_io = NULL;
struct vf_data_storage *vf_infos = NULL;
@@ -1615,8 +1896,10 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return -EINVAL;
}
- if (hinic3_func_type(hwdev) == TYPE_VF)
+ if (hinic3_func_type(hwdev) == TYPE_VF) {
+ pr_err("VF are not supported to set link state.\n");
return -EINVAL;
+ }
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
if (!nic_io) {
@@ -1633,3 +1916,35 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return 0;
}
EXPORT_SYMBOL(hinic3_pf_set_vf_link_state);
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid)
+{
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ u16 out_size = sizeof(outband_cfg_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !outband_default_vid)
+ return -EINVAL;
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_OUTBAND_CFG,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size);
+ if (err || !out_size || outband_cfg_info.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get outband cfg, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, outband_cfg_info.msg_head.status, out_size);
+ return -EINVAL;
+ }
+
+ *outband_default_vid = outband_cfg_info.outband_default_vid;
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
index dd2c2fd..e0350e3 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
@@ -7,9 +7,10 @@
#include <linux/types.h>
#include <linux/netdevice.h>
-#include "hinic3_mgmt_interface.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
+#include "nic_cfg_comm.h"
+#include "nic_mpu_cmd_defs.h"
#define OS_VF_ID_TO_HW(os_vf_id) ((os_vf_id) + 1)
#define HW_VF_ID_TO_OS(hw_vf_id) ((hw_vf_id) - 1)
@@ -54,6 +55,8 @@
#define MAX_LIMIT_BW 100
+#define HINIC3_INVALID_BOND_ID 0xffffffff
+
enum hinic3_valid_link_settings {
HILINK_LINK_SET_SPEED = 0x1,
HILINK_LINK_SET_AUTONEG = 0x2,
@@ -67,6 +70,11 @@ enum hinic3_link_follow_status {
HINIC3_LINK_FOLLOW_STATUS_MAX,
};
+enum hinic3_nic_pf_direct {
+ HINIC3_NIC_RX = 0,
+ HINIC3_NIC_TX,
+};
+
struct hinic3_link_ksettings {
u32 valid_bitmap;
u8 speed; /* enum nic_speed_level */
@@ -152,8 +160,12 @@ struct nic_port_info {
u8 duplex;
u8 speed;
u8 fec;
+ u8 lanes;
+ u8 rsvd;
u32 supported_mode;
u32 advertised_mode;
+ u32 supported_fec_mode;
+ u32 bond_speed;
};
struct nic_pause_config {
@@ -178,11 +190,17 @@ struct hinic3_rxq_hw {
#define MODULE_TYPE_QSFP28 0x11
#define MODULE_TYPE_QSFP 0x0C
#define MODULE_TYPE_QSFP_PLUS 0x0D
+#define MODULE_TYPE_DSFP 0x1B
+#define MODULE_TYPE_QSFP_CMIS 0x1E
#define TCAM_IP_TYPE_MASK 0x1
#define TCAM_TUNNEL_TYPE_MASK 0xF
#define TCAM_FUNC_ID_MASK 0x7FFF
+int hinic3_delete_bond(void *hwdev);
+int hinic3_open_close_bond(void *hwdev, u32 bond_en);
+int hinic3_create_bond(void *hwdev, u32 *bond_id);
+
int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule);
int hinic3_del_tcam_rule(void *hwdev, u32 index);
@@ -335,7 +353,7 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr);
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr);
/* *
* @brief hinic3_vf_info_vlanprio - get vf vlan priority
@@ -510,7 +528,14 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table);
*/
int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats);
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats);
+/* *
+ * @brief hinic3_get_phy_rsfec_stats - get rsfec stats
+ * @param hwdev: device pointer to hwdev
+ * @param stats: rsfec(Reed-Solomon Forward Error Correction) stats
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats);
int hinic3_set_port_funcs_state(void *hwdev, bool enable);
@@ -546,6 +571,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl);
void hinic3_clear_vfs_info(void *hwdev);
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id);
+
int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id);
int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
@@ -565,9 +592,13 @@ int hinic3_set_autoneg(void *hwdev, bool enable);
int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext);
int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len);
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len);
bool hinic3_if_sfp_absent(void *hwdev);
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info);
+int hinic3_get_sfp_tlv_info(void *hwdev,
+ struct drv_tag_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info,
+ const struct tag_mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req);
/* *
* @brief hinic3_set_nic_feature_to_hw - sync nic feature to hardware
@@ -620,4 +651,19 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level);
int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type);
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+/* *
+ * @brief hinic3_vlxan_port_config - add/del vxlan dst port
+ * @param hwdev: device pointer to hwdev
+ * @param func_id: function id
+ * @param port: vxlan dst port
+ * @param action: add or del, del will set to default value (0x12B5)
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action);
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
index 15d081b..c0e0a61 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
@@ -22,7 +22,8 @@
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_nic_cmdq.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
/*lint -e806*/
static unsigned char set_vf_link_state;
@@ -59,7 +60,8 @@ static int hinic3_set_vlan_ctx(struct hinic3_nic_io *nic_io, u16 func_id,
vlan_tag, q_id, vlan_mode);
err = hinic3_cmdq_direct_resp(nic_io->hwdev, HINIC3_MOD_L2NIC,
- cmd, cmd_buf, &out_param, 0, HINIC3_CHANNEL_NIC);
+ cmd, cmd_buf, &out_param,
+ 0, HINIC3_CHANNEL_NIC);
hinic3_free_cmd_buf(nic_io->hwdev, cmd_buf);
@@ -108,7 +110,7 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
err = hinic3_set_vlan_ctx(nic_io, glb_func_id, vlan_tag,
NIC_CONFIG_ALL_QUEUE_VLAN_CTX,
opcode == HINIC3_CMD_OP_ADD);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d vlan ctx, err: %d\n",
HW_VF_ID_TO_OS(vf_id), err);
@@ -129,12 +131,15 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
/* this function just be called by hinic3_ndo_set_vf_mac,
* others are not permitted.
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr)
{
- struct vf_data_storage *vf_info;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_info = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
#ifndef __VMWARE__
/* duplicate request, so just return success */
@@ -152,13 +157,15 @@ int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan, qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan = vlan;
@@ -172,17 +179,19 @@ int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
vf_infos = nic_io->vf_infos;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_DEL,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_info(nic_io->dev_hdl, "Remove VLAN %u on VF %d\n",
@@ -197,11 +206,13 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
u16 hinic3_vf_info_vlanprio(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
u16 pf_vlan, vlanprio;
u8 pf_qos;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
pf_vlan = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan;
pf_qos = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos;
@@ -214,9 +225,14 @@ int hinic3_set_vf_link_state(void *hwdev, u16 vf_id, int link)
{
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ struct vf_data_storage *vf_infos = NULL;
u8 link_status = 0;
+ if (!nic_io)
+ return -EINVAL;
+
+ vf_infos = nic_io->vf_infos;
+
switch (link) {
case HINIC3_IFLA_VF_LINK_STATE_AUTO:
vf_infos[HW_VF_ID_TO_OS(vf_id)].link_forced = false;
@@ -256,6 +272,8 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
vf_infos = nic_io->vf_infos;
memset(&spoofchk_cfg, 0, sizeof(spoofchk_cfg));
@@ -280,9 +298,11 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
bool hinic3_vf_info_spoofchk(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].spoofchk;
}
@@ -296,7 +316,7 @@ int hinic3_set_vf_trust(void *hwdev, u16 vf_id, bool trust)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
+ if (!nic_io || vf_id > nic_io->max_vfs)
return -EINVAL;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust = trust;
@@ -309,11 +329,11 @@ bool hinic3_get_vf_trust(void *hwdev, int vf_id)
struct hinic3_nic_io *nic_io = NULL;
if (!hwdev)
- return -EINVAL;
+ return false;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
- return -EINVAL;
+ if (!nic_io || vf_id > nic_io->max_vfs)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust;
}
@@ -331,6 +351,7 @@ static int hinic3_set_vf_tx_rate_max_min(struct hinic3_nic_io *nic_io,
rate_cfg.func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf_id;
rate_cfg.max_rate = max_rate;
rate_cfg.min_rate = min_rate;
+ rate_cfg.direct = HINIC3_NIC_TX;
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
&rate_cfg, sizeof(rate_cfg), &rate_cfg,
@@ -351,13 +372,15 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (!HINIC3_SUPPORT_RATE_LIMIT(hwdev)) {
nic_err(nic_io->dev_hdl, "Current function doesn't support to set vf rate limit\n");
return -EOPNOTSUPP;
}
err = hinic3_set_vf_tx_rate_max_min(nic_io, vf_id, max_rate, min_rate);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].max_rate = max_rate;
@@ -368,12 +391,16 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
void hinic3_get_vf_config(void *hwdev, u16 vf_id, struct ifla_vf_info *ivi)
{
- struct vf_data_storage *vfinfo;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vfinfo = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
vfinfo = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vfinfo)
+ return;
ivi->vf = HW_VF_ID_TO_OS(vf_id);
ether_addr_copy(ivi->mac, vfinfo->user_mac_addr);
@@ -446,13 +473,15 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
int err;
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
- nic_io->hwdev, hinic3_vf_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_vf_event_handler);
+ if (err != 0)
return err;
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
- nic_io->hwdev, hinic3_vf_mag_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_vf_mag_event_handler);
+ if (err != 0)
goto reg_hilink_err;
memset(®ister_info, 0, sizeof(register_info));
@@ -464,6 +493,11 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
®ister_info, &out_size, 0,
HINIC3_CHANNEL_NIC);
if (err || !out_size || register_info.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev)) {
+ nic_warn(nic_io->dev_hdl, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, register_info.msg_head.status, out_size);
+ return 0;
+ }
nic_err(nic_io->dev_hdl, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
err, register_info.msg_head.status, out_size);
err = -EIO;
@@ -498,18 +532,20 @@ static int pf_init_vf_infos(struct hinic3_nic_io *nic_io)
for (i = 0; i < nic_io->max_vfs; i++) {
err = hinic3_init_vf_infos(nic_io, i);
- if (err)
+ if (err != 0)
goto init_vf_infos_err;
}
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
- nic_io->hwdev, hinic3_pf_mbox_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_mbox_handler);
+ if (err != 0)
goto register_pf_mbox_cb_err;
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
- nic_io->hwdev, hinic3_pf_mag_mbox_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_mag_mbox_handler);
+ if (err != 0)
goto register_pf_mag_mbox_cb_err;
return 0;
@@ -531,17 +567,19 @@ int hinic3_vf_func_init(struct hinic3_nic_io *nic_io)
return vf_func_register(nic_io);
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
- nic_io->hwdev, hinic3_pf_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_event_handler);
+ if (err != 0)
return err;
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
- nic_io->hwdev, hinic3_pf_mag_event_handler);
- if (err)
+ nic_io->hwdev,
+ hinic3_pf_mag_event_handler);
+ if (err != 0)
goto register_mgmt_msg_cb_err;
err = pf_init_vf_infos(nic_io);
- if (err)
+ if (err != 0)
goto pf_init_vf_infos_err;
return 0;
@@ -568,17 +606,24 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
&unregister, sizeof(unregister),
&unregister, &out_size, 0,
HINIC3_CHANNEL_NIC);
- if (err || !out_size || unregister.msg_head.status)
- nic_err(nic_io->dev_hdl, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
- err, unregister.msg_head.status, out_size);
-
+ if (err || !out_size || unregister.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev)) {
+ nic_info(nic_io->dev_hdl, "vRoCE VF notify PF unsuccessful is allowed");
+ } else {
+ nic_err(nic_io->dev_hdl, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, unregister.msg_head.status, out_size);
+ }
+ }
hinic3_unregister_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
} else {
if (nic_io->vf_infos) {
- hinic3_unregister_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK);
- hinic3_unregister_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
+ hinic3_unregister_pf_mbox_cb(nic_io->hwdev,
+ HINIC3_MOD_HILINK);
+ hinic3_unregister_pf_mbox_cb(nic_io->hwdev,
+ HINIC3_MOD_L2NIC);
hinic3_clear_vfs_info(nic_io->hwdev);
kfree(nic_io->vf_infos);
+ nic_io->vf_infos = NULL;
}
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
@@ -587,11 +632,15 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
static void clear_vf_infos(void *hwdev, u16 vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
u16 func_id;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
func_id = hinic3_glb_pf_vf_offset(hwdev) + vf_id;
vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
@@ -620,10 +669,59 @@ static void clear_vf_infos(void *hwdev, u16 vf_id)
void hinic3_clear_vfs_info(void *hwdev)
{
+ u16 i;
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- u16 i;
+
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
for (i = 0; i < nic_io->max_vfs; i++)
clear_vf_infos(hwdev, OS_VF_ID_TO_HW(i));
}
+
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id)
+{
+ int err = 0;
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ struct vf_data_storage *vf_infos = NULL;
+ u16 out_size = sizeof(outband_cfg_info);
+ u16 vf_id;
+ struct hinic3_nic_io *nic_io =
+ hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return 0;
+ }
+
+ vf_id = func_id - hinic3_glb_pf_vf_offset(nic_io->hwdev);
+ vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+ if (vf_infos->registered) {
+ outband_cfg_info.func_id = func_id;
+ outband_cfg_info.outband_default_vid = vlan_id;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_L2NIC,
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return 0;
+ }
+ if (err || !out_size || outband_cfg_info.msg_head.status)
+ nic_err(nic_io->dev_hdl,
+ "outband cfg event to VF %d failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err,
+ outband_cfg_info.msg_head.status, out_size);
+ }
+
+ return err;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
index 0ec4b32..b45c875 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
@@ -30,6 +30,8 @@ int hinic3_dbg_get_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (q_id >= nic_io->num_qps) {
pr_err("q_id[%u] > num_qps_cfg[%u].\n", q_id, nic_io->num_qps);
return -EINVAL;
@@ -69,6 +71,8 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -82,6 +86,8 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
sq = &nic_io->sq[q_id];
+ if (!sq)
+ return -EINVAL;
sq_info->q_id = q_id;
sq_info->pi = hinic3_get_sq_local_pi(sq);
@@ -112,6 +118,8 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -125,6 +133,8 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
rq = &nic_io->rq[q_id];
+ if (!rq)
+ return -EINVAL;
rq_info->q_id = q_id;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
index e76a66b..38aa8f7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
@@ -15,9 +15,10 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
#include "hinic3_dcb.h"
+#include "vram_common.h"
#define HINIC3_NIC_DRV_NAME "hinic3"
-#define HINIC3_NIC_DRV_VERSION HINIC3_DRV_VERSION
+#define HINIC3_NIC_DRV_VERSION "17.7.8.1"
#define HINIC3_FUNC_IS_VF(hwdev) (hinic3_func_type(hwdev) == TYPE_VF)
@@ -25,6 +26,10 @@
#define HINIC3_MODERATONE_DELAY HZ
#define LP_PKT_CNT 64
+#define LP_PKT_LEN 60
+
+#define NAPI_IS_REGIN 1
+#define NAPI_NOT_REGIN 0
enum hinic3_flags {
HINIC3_INTF_UP,
@@ -91,6 +96,8 @@ struct hinic3_irq {
u16 rsvd1;
u32 irq_id; /* The IRQ number from OS */
+ u32 napi_reign;
+
char irq_name[IFNAMSIZ + 16];
struct napi_struct napi;
cpumask_t affinity_mask;
@@ -123,6 +130,41 @@ struct hinic3_dyna_txrxq_params {
struct hinic3_dyna_txq_res *txqs_res;
struct hinic3_dyna_rxq_res *rxqs_res;
struct hinic3_irq *irq_cfg;
+ char irq_cfg_vram_name[VRAM_NAME_MAX_LEN];
+};
+
+struct hinic3_flush_rq {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 lb_proc : 1;
+ u32 rsvd : 10;
+ u32 rq_id : 8;
+ u32 func_id : 13;
+#else
+ u32 func_id : 13;
+ u32 rq_id : 8;
+ u32 rsvd : 10;
+ u32 lb_proc : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd2 : 2;
+ u32 src_chnl : 12;
+ u32 pkt_len : 18;
+#else
+ u32 pkt_len : 18;
+ u32 src_chnl : 12;
+ u32 rsvd2 : 2;
+#endif
+ } bs;
+ u32 value;
+ } lb_info0; /* loop back information, used by uCode */
};
#define HINIC3_NIC_STATS_INC(nic_dev, field) \
@@ -147,6 +189,11 @@ struct hinic3_nic_stats {
#endif
};
+struct hinic3_nic_vport_stats {
+ u64 rx_discard_vport;
+};
+
+
#define HINIC3_TCAM_DYNAMIC_BLOCK_SIZE 16
#define HINIC3_MAX_TCAM_FILTERS 512
@@ -185,6 +232,29 @@ struct hinic3_tcam_info {
struct hinic3_tcam_dynamic_block_info tcam_dynamic_info;
};
+struct hinic3_dcb {
+ u8 cos_config_num_max;
+ u8 func_dft_cos_bitmap;
+ /* used to tool validity check */
+ u16 port_dft_cos_bitmap;
+
+ struct hinic3_dcb_config hw_dcb_cfg;
+ struct hinic3_dcb_config wanted_dcb_cfg;
+ unsigned long dcb_flags;
+};
+
+struct hinic3_vram {
+ u32 vram_mtu;
+ u16 vram_num_qps;
+ unsigned long flags;
+};
+
+struct hinic3_outband_cfg {
+ u16 outband_default_vid;
+ u16 rsvd;
+};
+
+
struct hinic3_nic_dev {
struct pci_dev *pdev;
struct net_device *netdev;
@@ -204,6 +274,7 @@ struct hinic3_nic_dev {
u32 dma_rx_buff_size;
u16 rx_buff_len;
u32 page_order;
+ bool page_pool_enabled;
/* Rss related varibles */
u8 rss_hash_engine;
@@ -213,17 +284,13 @@ struct hinic3_nic_dev {
u32 *rss_hkey_be;
u32 *rss_indir;
- u8 cos_config_num_max;
- u8 func_dft_cos_bitmap;
- u16 port_dft_cos_bitmap; /* used to tool validity check */
+ struct hinic3_dcb *dcb;
+ char dcb_name[VRAM_NAME_MAX_LEN];
+
+ struct hinic3_vram *nic_vram;
+ char nic_vram_name[VRAM_NAME_MAX_LEN];
- struct hinic3_dcb_config hw_dcb_cfg;
- struct hinic3_dcb_config wanted_dcb_cfg;
- struct hinic3_dcb_config dcb_cfg;
- unsigned long dcb_flags;
int disable_port_cnt;
- /* lock for disable or enable traffic flow */
- struct semaphore dcb_sem;
struct hinic3_intr_coal_info *intr_coalesce;
unsigned long last_moder_jiffies;
@@ -235,11 +302,10 @@ struct hinic3_nic_dev {
#endif
struct hinic3_nic_stats stats;
+ struct hinic3_nic_vport_stats vport_stats;
/* lock for nic resource */
struct mutex nic_mutex;
- bool force_port_disable;
- struct semaphore port_state_sem;
u8 link_status;
struct nic_service_cap nic_cap;
@@ -281,9 +347,10 @@ struct hinic3_nic_dev {
struct hinic3_nic_prof_attr *prof_attr;
struct hinic3_prof_adapter *prof_adap;
u64 rsvd8[7];
- u32 rsvd9;
+ struct hinic3_outband_cfg outband_cfg;
u32 rxq_get_err_times;
struct delayed_work rxq_check_work;
+ struct delayed_work vport_stats_work;
struct hinic3_tx_rx_ops tx_rx_ops;
};
@@ -312,7 +379,7 @@ struct hinic3_uld_info *get_nic_uld_info(void);
u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev);
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
int hinic3_open(struct net_device *netdev);
@@ -331,6 +398,8 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev);
void hinic3_qps_irq_deinit(struct hinic3_nic_dev *nic_dev);
+void qp_del_napi(struct hinic3_irq *irq_cfg);
+
void hinic3_set_netdev_ops(struct hinic3_nic_dev *nic_dev);
bool hinic3_is_netdev_ops_match(const struct net_device *netdev);
@@ -348,10 +417,6 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
int hinic3_get_sset_count(struct net_device *netdev, int sset);
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev);
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
#ifdef ETHTOOL_GLINKSETTINGS
@@ -386,5 +451,18 @@ bool hinic3_is_xdp_enable(struct hinic3_nic_dev *nic_dev);
int hinic3_xdp_max_mtu(struct hinic3_nic_dev *nic_dev);
#endif
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+int set_fecparam(void *hwdev, u8 fecparam);
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec);
+#endif
+
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
index 57cf07c..c53c125 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
@@ -21,11 +21,12 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
{
- struct vf_data_storage *vf_info;
+ struct vf_data_storage *vf_info = NULL;
u16 func_id;
int err = 0;
@@ -38,7 +39,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
vf_info->pf_vlan, func_id,
HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d MAC\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -51,7 +52,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD,
vf_info->pf_vlan, vf_info->pf_qos,
vf_id);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to add VF %d VLAN_QOS\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -62,7 +63,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_vf_tx_rate(nic_io->hwdev, vf_id,
vf_info->max_rate,
vf_info->min_rate);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d max rate %u, min rate %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->max_rate,
vf_info->min_rate);
@@ -84,7 +85,7 @@ static int register_vf_msg_handler(struct hinic3_nic_io *nic_io, u16 vf_id)
}
err = hinic3_init_vf_config(nic_io, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].registered = true;
@@ -137,6 +138,9 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
int err;
+ if (!vf_info)
+ return -EINVAL;
+
if (register_vf->op_register) {
vf_info->support_extra_feature = register_vf->support_extra_feature;
err = register_vf_msg_handler(nic_io, vf_id);
@@ -145,7 +149,7 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
vf_info->support_extra_feature = 0;
}
- if (err)
+ if (err != 0)
register_info->msg_head.status = EFAULT;
*out_size = sizeof(*register_info);
@@ -157,6 +161,8 @@ void hinic3_unregister_vf(struct hinic3_nic_io *nic_io, u16 vf_id)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vf_info)
+ return;
unregister_vf_msg_handler(nic_io, vf_id);
vf_info->support_extra_feature = 0;
}
@@ -181,14 +187,21 @@ static int hinic3_get_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
void *buf_out, u16 *out_size)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf);
+ struct hinic3_port_mac_set *mac_in =
+ (struct hinic3_port_mac_set *)buf_in;
struct hinic3_port_mac_set *mac_info = buf_out;
int err;
+ if (!mac_info || !vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (HINIC3_SUPPORT_VF_MAC(nic_io->hwdev)) {
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_GET_MAC, buf_in,
in_size, buf_out, out_size);
- if (!err) {
+ if (err == 0) {
if (is_zero_ether_addr(mac_info->mac))
ether_addr_copy(mac_info->mac, vf_info->drv_mac_addr);
}
@@ -211,6 +224,11 @@ static int hinic3_set_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -247,6 +265,10 @@ static int hinic3_del_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -283,10 +305,13 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
struct hinic3_port_mac_update *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
if (!is_valid_ether_addr(mac_in->new_mac)) {
nic_err(nic_io->dev_hdl, "Update VF MAC is invalid.\n");
return -EINVAL;
}
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
#ifndef __VMWARE__
if (vf_info->use_specified_mac && !vf_info->trust) {
@@ -301,7 +326,7 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
HW_VF_ID_TO_OS(vf),
HINIC_CFG_VF_MAC_CHANGED,
(void *)mac_in->new_mac);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to config VF %d MAC request, err: %d\n",
HW_VF_ID_TO_OS(vf), err);
return err;
@@ -359,10 +384,11 @@ static int _l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u16 in_size, void *buf_out, u16 *out_size,
u16 channel)
{
- u32 i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
+ int i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_cmd_handler[i].cmd)
cmd_to_pf = true;
@@ -397,13 +423,15 @@ int hinic3_pf_mbox_handler(void *hwdev,
u16 vf_id, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- u32 index, cmd_size = ARRAY_LEN(vf_cmd_handler);
+ int index, cmd_size = ARRAY_LEN(vf_cmd_handler);
struct hinic3_nic_io *nic_io = NULL;
if (!hwdev)
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (index = 0; index < cmd_size; index++) {
if (cmd == vf_cmd_handler[index].cmd)
@@ -460,10 +488,14 @@ void hinic3_notify_dcb_state_event(struct hinic3_nic_io *nic_io,
static void dcb_state_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- struct hinic3_cmd_vf_dcb_state *vf_dcb;
- struct hinic3_nic_io *nic_io;
+ struct hinic3_cmd_vf_dcb_state *vf_dcb = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
vf_dcb = buf_in;
if (!vf_dcb)
@@ -479,6 +511,10 @@ static void tx_pause_excp_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*excp_info)) {
nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
@@ -501,6 +537,10 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_event_info event_info = {0};
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*active_info)) {
nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
@@ -515,6 +555,36 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
hinic3_event_callback(nic_io->hwdev, &event_info);
}
+static void outband_vlan_cfg_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out,
+ u16 *out_size)
+{
+ struct hinic3_outband_cfg_info *outband_cfg_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info = {0};
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ nic_info(nic_io->dev_hdl, "outband vlan cfg event received\n");
+
+ if (in_size != sizeof(*outband_cfg_info)) {
+ nic_err(nic_io->dev_hdl, "outband cfg info invalid in_size: %u, should be %lu\n",
+ in_size, sizeof(*outband_cfg_info));
+ return;
+ }
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = EVENT_NIC_OUTBAND_CFG;
+ memcpy((void *)event_info.event_data,
+ outband_cfg_info, sizeof(*outband_cfg_info));
+
+ hinic3_event_callback(nic_io->hwdev, &event_info);
+}
+
static const struct nic_event_handler nic_cmd_handler[] = {
{
.cmd = HINIC3_NIC_CMD_VF_COS,
@@ -529,6 +599,11 @@ static const struct nic_event_handler nic_cmd_handler[] = {
.cmd = HINIC3_NIC_CMD_BOND_ACTIVE_NOTICE,
.handler = bond_active_event_handler,
},
+
+ {
+ .cmd = HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ .handler = outband_vlan_cfg_event_handler,
+ },
};
static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
@@ -543,6 +618,8 @@ static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (i = 0; i < size; i++) {
if (cmd == nic_cmd_handler[i].cmd) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
index a827f44..f3bb4c5 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
@@ -16,9 +16,10 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
-#include "hinic3_nic_io.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_nic_cmdq.h"
+#include "hinic3_nic_io.h"
#define HINIC3_DEAULT_TX_CI_PENDING_LIMIT 1
#define HINIC3_DEAULT_TX_CI_COALESCING_TIME 1
@@ -35,7 +36,7 @@ MODULE_PARM_DESC(tx_coalescing_time, "TX CI coalescing parameter coalescing_time
static unsigned char rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
module_param(rq_wqe_type, byte, 0444);
-MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 0-8Bytes, 1-16Bytes, 2-32Bytes (default=1)");
+MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 1-16Bytes, 2-32Bytes (default=2)");
/*lint +e806*/
static u32 tx_drop_thd_on = HINIC3_DEAULT_DROP_THD_ON;
@@ -46,7 +47,7 @@ static u32 tx_drop_thd_off = HINIC3_DEAULT_DROP_THD_OFF;
module_param(tx_drop_thd_off, uint, 0644);
MODULE_PARM_DESC(tx_drop_thd_off, "TX parameter drop_thd_off (default=0)");
/* performance: ci addr RTE_CACHE_SIZE(64B) alignment */
-#define HINIC3_CI_Q_ADDR_SIZE (64)
+#define HINIC3_CI_Q_ADDR_SIZE (64U)
#define CI_TABLE_SIZE(num_qps, pg_sz) \
(ALIGN((num_qps) * HINIC3_CI_Q_ADDR_SIZE, pg_sz))
@@ -255,7 +256,7 @@ static int hinic3_create_sq(struct hinic3_nic_io *nic_io, struct hinic3_io_queue
err = hinic3_wq_create(nic_io->hwdev, &sq->wq, sq_depth,
(u16)BIT(HINIC3_SQ_WQEBB_SHIFT));
- if (err) {
+ if (err != 0) {
sdk_err(nic_io->dev_hdl, "Failed to create tx queue(%u) wq\n",
q_id);
return err;
@@ -291,13 +292,22 @@ static int hinic3_create_rq(struct hinic3_nic_io *nic_io, struct hinic3_io_queue
{
int err;
- rq->wqe_type = (u8)(hinic3_get_rq_wqe_type(nic_io->hwdev));
+ /* rq_wqe_type Only support type 1-16Bytes, 2-32Bytes */
+ if (rq_wqe_type != HINIC3_NORMAL_RQ_WQE &&
+ rq_wqe_type != HINIC3_EXTEND_RQ_WQE) {
+ sdk_warn(nic_io->dev_hdl, "Module Parameter rq_wqe_type value %d is out of range: [%d, %d].",
+ rq_wqe_type, HINIC3_NORMAL_RQ_WQE,
+ HINIC3_EXTEND_RQ_WQE);
+ rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
+ }
+
+ rq->wqe_type = rq_wqe_type;
rq->q_id = q_id;
rq->msix_entry_idx = rq_msix_idx;
err = hinic3_wq_create(nic_io->hwdev, &rq->wq, rq_depth,
(u16)BIT(HINIC3_RQ_WQEBB_SHIFT + rq->wqe_type));
- if (err) {
+ if (err != 0) {
sdk_err(nic_io->dev_hdl, "Failed to create rx queue(%u) wq\n",
q_id);
return err;
@@ -318,14 +328,14 @@ static int create_qp(struct hinic3_nic_io *nic_io, struct hinic3_io_queue *sq,
int err;
err = hinic3_create_sq(nic_io, sq, q_id, sq_depth, qp_msix_idx);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to create sq, qid: %u\n",
q_id);
return err;
}
err = hinic3_create_rq(nic_io, rq, q_id, rq_depth, qp_msix_idx);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to create rq, qid: %u\n",
q_id);
goto create_rq_err;
@@ -364,14 +374,14 @@ int hinic3_init_nicio_res(void *hwdev)
nic_io->max_qps = hinic3_func_max_qnum(hwdev);
err = hinic3_alloc_db_addr(hwdev, &db_base, NULL);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to allocate doorbell for sqs\n");
goto alloc_sq_db_fail;
}
nic_io->sqs_db_addr = (u8 *)db_base;
err = hinic3_alloc_db_addr(hwdev, &db_base, NULL);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to allocate doorbell for rqs\n");
goto alloc_rq_db_fail;
}
@@ -474,7 +484,7 @@ int hinic3_alloc_qps(void *hwdev, struct irq_info *qps_msix_arry,
for (q_id = 0; q_id < num_qps; q_id++) {
err = create_qp(nic_io, &sqs[q_id], &rqs[q_id], q_id, qp_params->sq_depth,
qp_params->rq_depth, qps_msix_arry[q_id].msix_entry_idx);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to allocate qp %u, err: %d\n", q_id, err);
goto create_qp_err;
}
@@ -599,14 +609,14 @@ int hinic3_create_qps(void *hwdev, u16 num_qp, u32 sq_depth, u32 rq_depth,
}
err = hinic3_init_nicio_res(hwdev);
- if (err)
+ if (err != 0)
return err;
qp_params.num_qps = num_qp;
qp_params.sq_depth = sq_depth;
qp_params.rq_depth = rq_depth;
err = hinic3_alloc_qps(hwdev, qps_msix_arry, &qp_params);
- if (err) {
+ if (err != 0) {
hinic3_deinit_nicio_res(hwdev);
nic_err(nic_io->dev_hdl,
"Failed to allocate qps, err: %d\n", err);
@@ -906,11 +916,11 @@ static int init_qp_ctxts(struct hinic3_nic_io *nic_io)
int err;
err = init_sq_ctxts(nic_io);
- if (err)
+ if (err != 0)
return err;
err = init_rq_ctxts(nic_io);
- if (err)
+ if (err != 0)
return err;
return 0;
@@ -1026,14 +1036,14 @@ int hinic3_init_qp_ctxts(void *hwdev)
return -EFAULT;
err = init_qp_ctxts(nic_io);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to init QP ctxts\n");
return err;
}
/* clean LRO/TSO context space */
err = clean_qp_offload_ctxt(nic_io);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to clean qp offload ctxts\n");
return err;
}
@@ -1042,13 +1052,13 @@ int hinic3_init_qp_ctxts(void *hwdev)
err = hinic3_set_root_ctxt(hwdev, rq_depth, nic_io->sq[0].wq.q_depth,
nic_io->rx_buff_len, HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set root context\n");
return err;
}
err = init_sq_ci_ctxts(nic_io);
- if (err)
+ if (err != 0)
goto clean_root_ctxt;
if (HINIC3_SUPPORT_RX_COMPACT_CQE(hwdev)) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
index 37f923d..c5e02ad 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
@@ -317,7 +317,7 @@ static inline void hinic3_write_db(struct hinic3_io_queue *queue, int cos,
wmb(); /* Write all before the doorbell */
- writeq(*((u64 *)&db), DB_ADDR(queue, pi));
+ writeq(*((u64 *)(u8 *)&db), DB_ADDR(queue, pi));
}
struct hinic3_dyna_qp_params {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
index 78d943d..9ea93a0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
@@ -32,7 +32,7 @@ struct hinic3_prof_adapter nic_prof_adap_objs[] = {
void hinic3_init_nic_prof_adapter(struct hinic3_nic_dev *nic_dev)
{
- u16 num_adap = ARRAY_SIZE(nic_prof_adap_objs);
+ int num_adap = ARRAY_LEN(nic_prof_adap_objs);
nic_dev->prof_adap = hinic3_prof_init(nic_dev, nic_prof_adap_objs, num_adap,
(void *)&nic_dev->prof_attr);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
index 6302fb8..dc4bb9e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
@@ -430,7 +430,8 @@ hinic3_dynamic_lookup_tcam_filter(struct hinic3_nic_dev *nic_dev,
list_for_each_entry(tmp,
&tcam_info->tcam_dynamic_info.tcam_dynamic_list,
block_list)
- if (tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)
+ if (tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE ||
+ !tmp)
break;
if (!tmp || tmp->dynamic_index_cnt >= HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) {
@@ -512,7 +513,7 @@ static int hinic3_add_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, queue: %d, tcam_rule_nums: %d succeed\n",
+ "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, queue: %u, tcam_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev),
tcam_filter->dynamic_block_id, index, fdir_tcam_rule->index,
fdir_tcam_rule->data.qid, tcam_info->tcam_rule_nums + 1);
@@ -579,7 +580,7 @@ static int hinic3_del_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, local_rules_nums: %d, global_rule_nums: %d succeed\n",
+ "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, local_rules_nums: %u, global_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev), dynamic_block_id,
tcam_filter->index, index, tmp->dynamic_index_cnt - 1,
tcam_info->tcam_rule_nums - 1);
@@ -605,7 +606,7 @@ static inline struct hinic3_tcam_filter *
hinic3_tcam_filter_lookup(const struct list_head *filter_list,
struct tag_tcam_key *key)
{
- struct hinic3_tcam_filter *iter;
+ struct hinic3_tcam_filter *iter = NULL;
list_for_each_entry(iter, filter_list, tcam_filter_list) {
if (memcmp(key, &iter->tcam_key,
@@ -630,7 +631,7 @@ static int hinic3_remove_one_rule(struct hinic3_nic_dev *nic_dev,
struct hinic3_ethtool_rx_flow_rule *eth_rule)
{
struct hinic3_tcam_info *tcam_info = &nic_dev->tcam;
- struct hinic3_tcam_filter *tcam_filter;
+ struct hinic3_tcam_filter *tcam_filter = NULL;
struct nic_tcam_cfg_rule fdir_tcam_rule;
struct tag_tcam_key tcam_key;
int err;
@@ -751,7 +752,7 @@ static int validate_flow(struct hinic3_nic_dev *nic_dev,
{
if (fs->location >= MAX_NUM_OF_ETHTOOL_NTUPLE_RULES) {
nicif_err(nic_dev, drv, nic_dev->netdev, "loc exceed limit[0,%lu]\n",
- MAX_NUM_OF_ETHTOOL_NTUPLE_RULES);
+ MAX_NUM_OF_ETHTOOL_NTUPLE_RULES - 1);
return -EINVAL;
}
@@ -872,7 +873,7 @@ int hinic3_ethtool_get_flow(const struct hinic3_nic_dev *nic_dev,
int hinic3_ethtool_get_all_flows(const struct hinic3_nic_dev *nic_dev,
struct ethtool_rxnfc *info, u32 *rule_locs)
{
- int idx = 0;
+ u32 idx = 0;
struct hinic3_ethtool_rx_flow_rule *eth_rule = NULL;
if (!HINIC3_SUPPORT_FDIR(nic_dev->hwdev)) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h b/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
index a93f3b6..9202218 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
@@ -38,13 +38,12 @@ struct hinic3_prof_adapter {
#define LLT_STATIC_DEF_SAVED
#endif
-/*lint -save -e661 */
static inline struct hinic3_prof_adapter *
hinic3_prof_init(void *device, struct hinic3_prof_adapter *adap_objs, int num_adap,
void **prof_attr)
{
struct hinic3_prof_adapter *prof_obj = NULL;
- u16 i;
+ int i;
for (i = 0; i < num_adap; i++) {
prof_obj = &adap_objs[i];
@@ -68,7 +67,6 @@ static inline void hinic3_prof_deinit(struct hinic3_prof_adapter *prof_obj, void
prof_obj->deinit(prof_attr);
}
-/*lint -restore*/
/* module-level interface */
#ifdef CONFIG_MODULE_PROF
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
index e4705c2..9b4eca8 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/dcbnl.h>
+#include <linux/init.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -23,8 +24,7 @@
#include "hinic3_hw.h"
#include "hinic3_rss.h"
-/*lint -e806*/
-static u16 num_qps;
+static u16 num_qps = 0;
module_param(num_qps, ushort, 0444);
MODULE_PARM_DESC(num_qps, "Number of Queue Pairs (default=0)");
@@ -104,88 +104,84 @@ static int hinic3_get_rq2iq_map(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev, u8 num_cos, u32 *indir)
+static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev,
+ u8 group_num, u32 *indir)
{
- u16 k, group_size, start_qid = 0, qp_num = 0;
- int i = 0;
- u8 j, cur_cos = 0, default_cos;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ u16 k, group_size, start_qid = 0, cur_cos_qnum = 0;
+ u32 i = 0;
+ u8 j, cur_cos = 0, group = 0;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
- if (num_cos == 0) {
+ if (group_num == 0) {
for (i = 0; i < NIC_RSS_INDIR_SIZE; i++)
indir[i] = i % nic_dev->q_params.num_qps;
} else {
- group_size = NIC_RSS_INDIR_SIZE / num_cos;
-
- for (j = 0; j < num_cos; j++) {
- while (cur_cos < NIC_DCB_COS_MAX &&
- nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos] == 0)
- cur_cos++;
-
- if (cur_cos >= NIC_DCB_COS_MAX) {
- if (BIT(nic_dev->hw_dcb_cfg.default_cos) & valid_cos_map)
- default_cos = nic_dev->hw_dcb_cfg.default_cos;
- else
- default_cos = (u8)fls(valid_cos_map) - 1;
+ group_size = NIC_RSS_INDIR_SIZE / group_num;
+
+ for (group = 0; group < group_num; group++) {
+ cur_cos = dcb->hw_dcb_cfg.default_cos;
+ for (j = 0; j < NIC_DCB_COS_MAX; j++) {
+ if ((BIT(j) & valid_cos_map) != 0) {
+ cur_cos = j;
+ valid_cos_map -= (u8)BIT(j);
+ break;
+ }
+ }
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[default_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[default_cos];
+ cur_cos_qnum = dcb->hw_dcb_cfg.cos_qp_num[cur_cos];
+ if (cur_cos_qnum > 0) {
+ start_qid =
+ dcb->hw_dcb_cfg.cos_qp_offset[cur_cos];
} else {
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[cur_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos];
+ start_qid = cur_cos % nic_dev->q_params.num_qps;
+ /* Ensure that the offset of start_id is 0. */
+ cur_cos_qnum = 1;
}
for (k = 0; k < group_size; k++)
- indir[i++] = start_qid + k % qp_num;
-
- cur_cos++;
+ indir[i++] = start_qid + k % cur_cos_qnum;
}
}
}
-/*lint -e528*/
int hinic3_rss_init(struct hinic3_nic_dev *nic_dev, u8 *rq2iq_map, u32 map_size, u8 dcb_en)
{
struct net_device *netdev = nic_dev->netdev;
- u8 i, cos_num;
- u8 cos_map[NIC_DCB_UP_MAX] = {0};
- u8 cfg_map[NIC_DCB_UP_MAX] = {0};
+ u8 i, group_num, cos_bitmap, group = 0;
+ u8 cos_group[NIC_DCB_UP_MAX] = {0};
int err;
- if (dcb_en) {
- cos_num = hinic3_get_dev_user_cos_num(nic_dev);
+ if (dcb_en != 0) {
+ group_num = (u8)roundup_pow_of_two(
+ hinic3_get_dev_user_cos_num(nic_dev));
- if (nic_dev->hw_dcb_cfg.trust == 0) {
- memcpy(cfg_map, nic_dev->hw_dcb_cfg.pcp2cos, sizeof(cfg_map));
- } else if (nic_dev->hw_dcb_cfg.trust == 1) {
- for (i = 0; i < NIC_DCB_UP_MAX; i++)
- cfg_map[i] = nic_dev->hw_dcb_cfg.dscp2cos[i * NIC_DCB_DSCP_NUM];
- }
-#define COS_CHANGE_OFFSET 4
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[COS_CHANGE_OFFSET + i] = cfg_map[i];
-
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[i] = cfg_map[NIC_DCB_UP_MAX - (i + 1)];
+ cos_bitmap = hinic3_get_dev_valid_cos_map(nic_dev);
- while (cos_num & (cos_num - 1))
- cos_num++;
+ for (i = 0; i < NIC_DCB_UP_MAX; i++) {
+ if ((BIT(i) & cos_bitmap) != 0)
+ cos_group[NIC_DCB_UP_MAX - i - 1] = group++;
+ else
+ cos_group[NIC_DCB_UP_MAX - i - 1] =
+ group_num - 1;
+ }
} else {
- cos_num = 0;
+ group_num = 0;
}
- err = hinic3_set_hw_rss_parameters(netdev, 1, cos_num, cos_map, dcb_en);
+ err = hinic3_set_hw_rss_parameters(netdev, 1, group_num,
+ cos_group, dcb_en);
if (err)
return err;
- err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps, cos_num, cos_map,
- NIC_DCB_UP_MAX, nic_dev->rss_indir, rq2iq_map, map_size);
+ err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps,
+ group_num, cos_group, NIC_DCB_UP_MAX,
+ nic_dev->rss_indir, rq2iq_map, map_size);
if (err)
nicif_err(nic_dev, drv, netdev, "Failed to get rq map\n");
return err;
}
-/*lint -e528*/
void hinic3_rss_deinit(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -246,11 +242,28 @@ discard_user_rss_indir:
hinic3_set_default_rss_indir(netdev);
}
+#ifdef HAVE_HOT_REPLACE_FUNC
+bool partition_slave_doing_hotupgrade(void)
+{
+ return get_partition_role() && partition_doing_hotupgrade();
+}
+#endif
+
static void decide_num_qps(struct hinic3_nic_dev *nic_dev)
{
u16 tmp_num_qps = nic_dev->max_qps;
u16 num_cpus = 0;
+ u16 max_num_cpus;
int i, node;
+ int is_in_kexec = vram_get_kexec_flag();
+
+ if (is_in_kexec != 0) {
+ nic_dev->q_params.num_qps = nic_dev->nic_vram->vram_num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Os hotreplace use vram to init num qps 1:%u 2:%u\n",
+ nic_dev->q_params.num_qps, nic_dev->nic_vram->vram_num_qps);
+ return;
+ }
if (nic_dev->nic_cap.default_num_queues != 0 &&
nic_dev->nic_cap.default_num_queues < nic_dev->max_qps)
@@ -258,16 +271,29 @@ static void decide_num_qps(struct hinic3_nic_dev *nic_dev)
MOD_PARA_VALIDATE_NUM_QPS(nic_dev, num_qps, tmp_num_qps);
- for (i = 0; i < (int)num_online_cpus(); i++) {
+#ifdef HAVE_HOT_REPLACE_FUNC
+ if (partition_slave_doing_hotupgrade())
+ max_num_cpus = (u16)num_present_cpus();
+ else
+ max_num_cpus = (u16)num_online_cpus();
+#else
+ max_num_cpus = (u16)num_online_cpus();
+#endif
+
+ for (i = 0; i < max_num_cpus; i++) {
node = (int)cpu_to_node(i);
if (node == dev_to_node(&nic_dev->pdev->dev))
num_cpus++;
}
if (!num_cpus)
- num_cpus = (u16)num_online_cpus();
+ num_cpus = max_num_cpus;
nic_dev->q_params.num_qps = (u16)min_t(u16, tmp_num_qps, num_cpus);
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "init num qps 1:%u 2:%u\n",
+ nic_dev->q_params.num_qps, nic_dev->nic_vram->vram_num_qps);
}
static void copy_value_to_rss_hkey(struct hinic3_nic_dev *nic_dev,
@@ -312,6 +338,8 @@ static int alloc_rss_resource(struct hinic3_nic_dev *nic_dev)
nic_dev->rss_indir = kzalloc(sizeof(u32) * NIC_RSS_INDIR_SIZE, GFP_KERNEL);
if (!nic_dev->rss_indir) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to alloc memory for rss_indir\n");
kfree(nic_dev->rss_hkey);
nic_dev->rss_hkey = NULL;
return -ENOMEM;
@@ -322,7 +350,6 @@ static int alloc_rss_resource(struct hinic3_nic_dev *nic_dev)
return 0;
}
-/*lint -e528*/
void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -361,6 +388,7 @@ void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
set_q_params:
clear_bit(HINIC3_RSS_ENABLE, &nic_dev->flags);
nic_dev->q_params.num_qps = nic_dev->max_qps;
+ nic_dev->nic_vram->vram_num_qps = nic_dev->max_qps;
}
static int hinic3_config_rss_hw_resource(struct hinic3_nic_dev *nic_dev,
@@ -754,6 +782,7 @@ int hinic3_set_channels(struct net_device *netdev,
nic_dev->q_params.num_qps = (u16)count;
}
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
return 0;
}
@@ -814,7 +843,7 @@ int hinic3_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
int err = 0;
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
@@ -921,7 +950,7 @@ int hinic3_get_rxfh_indir(struct net_device *netdev, u32 *indir)
indir = indir1->ring_index;
#endif
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
index 071418d..4f4b18c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
@@ -15,14 +15,15 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_nic_cfg.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_hw.h"
#include "hinic3_nic.h"
#include "hinic3_nic_cmdq.h"
#include "hinic3_common.h"
static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
- u8 *key)
+ u8 *key, u16 key_size)
{
struct hinic3_cmd_rss_hash_key hash_key;
u16 out_size = sizeof(hash_key);
@@ -33,7 +34,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
hash_key.opcode = opcode;
if (opcode == HINIC3_CMD_OP_SET)
- memcpy(hash_key.key, key, NIC_RSS_KEY_SIZE);
+ memcpy(hash_key.key, key, key_size);
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_CFG_RSS_HASH_KEY,
@@ -47,7 +48,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
}
if (opcode == HINIC3_CMD_OP_GET)
- memcpy(key, hash_key.key, NIC_RSS_KEY_SIZE);
+ memcpy(key, hash_key.key, key_size);
return 0;
}
@@ -61,8 +62,12 @@ int hinic3_rss_set_hash_key(void *hwdev, const u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memcpy(hash_key, key, NIC_RSS_KEY_SIZE);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET, hash_key);
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET,
+ hash_key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
@@ -73,7 +78,11 @@ int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET, key);
+ if (!nic_io)
+ return -EINVAL;
+
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET,
+ key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
@@ -89,6 +98,7 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
if (nic_io == NULL)
return -EINVAL;
+
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (cmd_buf == NULL) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -159,6 +169,8 @@ static int hinic3_cmdq_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
@@ -210,6 +222,9 @@ static int hinic3_mgmt_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&ctx_tbl, 0, sizeof(ctx_tbl));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
ctx |= HINIC3_RSS_TYPE_SET(1, VALID) |
@@ -259,6 +274,8 @@ int hinic3_get_rss_type(void *hwdev, struct nic_rss_type *rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&ctx_tbl, 0, sizeof(struct hinic3_rss_context_table));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
@@ -292,6 +309,9 @@ static int hinic3_rss_cfg_hash_engine(struct hinic3_nic_io *nic_io, u8 opcode,
u16 out_size = sizeof(hash_type);
int err;
+ if (!nic_io)
+ return -EINVAL;
+
memset(&hash_type, 0, sizeof(struct hinic3_cmd_rss_engine_type));
hash_type.func_id = hinic3_global_func_id(nic_io->hwdev);
@@ -325,6 +345,9 @@ int hinic3_rss_set_hash_engine(void *hwdev, u8 type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_SET, &type);
}
@@ -336,6 +359,9 @@ int hinic3_rss_get_hash_engine(void *hwdev, u8 *type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_GET, type);
}
@@ -351,6 +377,9 @@ int hinic3_rss_cfg(void *hwdev, u8 rss_en, u8 cos_num, u8 *prio_tc, u16 num_qps)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&rss_cfg, 0, sizeof(struct hinic3_cmd_rss_config));
rss_cfg.func_id = hinic3_global_func_id(hwdev);
rss_cfg.rss_en = rss_en;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
index f8a866d..9027a3d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
@@ -21,6 +21,7 @@
#include <linux/ipv6.h>
#include <linux/module.h>
#include <linux/compiler.h>
+#include <linux/filter.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -63,19 +64,31 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
struct pci_dev *pdev = nic_dev->pdev;
struct page *page = rx_info->page;
dma_addr_t dma = rx_info->buf_dma_addr;
+ u32 page_offset = 0;
if (likely(dma))
return true;
/* alloc new page for storage */
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page = page_pool_alloc_frag(rx_info->page_pool, &page_offset,
+ nic_dev->rx_buff_len,
+ GFP_ATOMIC | __GFP_COLD | __GFP_COMP);
+ if (unlikely(!page))
+ return false;
+ dma = page_pool_get_dma_addr(page);
+ goto set_rx_info;
+ }
+#endif
page = alloc_pages_node(NUMA_NO_NODE, GFP_ATOMIC | __GFP_COLD |
__GFP_COMP, nic_dev->page_order);
if (unlikely(!page))
return false;
/* map page for use */
- dma = dma_map_page(&pdev->dev, page, 0, nic_dev->dma_rx_buff_size,
- DMA_FROM_DEVICE);
+ dma = dma_map_page(&pdev->dev, page, page_offset,
+ nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
/* if mapping failed free memory back to system since
* there isn't much point in holding memory we can't use
*/
@@ -83,10 +96,12 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
__free_pages(page, nic_dev->page_order);
return false;
}
+ goto set_rx_info;
+set_rx_info:
rx_info->page = page;
rx_info->buf_dma_addr = dma;
- rx_info->page_offset = 0;
+ rx_info->page_offset = page_offset;
return true;
}
@@ -108,7 +123,7 @@ static u32 hinic3_rx_fill_wqe(struct hinic3_rxq *rxq)
/* unit of cqe length is 16B */
hinic3_set_sge(&rq_wqe->extend_wqe.cqe_sect.sge,
rx_info->cqe_dma,
- (sizeof(struct hinic3_rq_cqe) >>
+ (HINIC3_CQE_LEN >>
HINIC3_CQE_SIZE_SHIFT));
/* use fixed len */
rq_wqe->extend_wqe.buf_desc.sge.len =
@@ -169,7 +184,7 @@ static u32 hinic3_rx_fill_buffers(struct hinic3_rxq *rxq)
if (likely(i)) {
hinic3_write_db(rxq->rq,
- rxq->q_id & 3,
+ rxq->q_id & (NIC_RX_DB_COS_MAX - 1),
RQ_CFLAG_DP,
(u16)((u32)rxq->next_to_update <<
rxq->rq->wqe_type));
@@ -206,6 +221,18 @@ static void hinic3_rx_free_buffers(struct hinic3_nic_dev *nic_dev, u32 q_depth,
for (i = 0; i < q_depth; i++) {
rx_info = &rx_info_arr[i];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ if (rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool,
+ rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ }
+ continue;
+ }
+#endif
+
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev,
rx_info->buf_dma_addr,
@@ -265,8 +292,15 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
DMA_FROM_DEVICE);
if (size <= HINIC3_RX_HDR_SIZE && !skb_is_nonlinear(skb)) {
- memcpy(__skb_put(skb, size), va + offset,
- ALIGN(size, sizeof(long))); /*lint !e666*/
+ __skb_put_data(skb, va + offset, size);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool,
+ page, false);
+ return false;
+ }
+#endif
/* page is not reserved, we can reuse buffer as-is */
if (likely(page_to_nid(page) == numa_node_id()))
@@ -274,25 +308,38 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
/* this page cannot be reused so discard it */
put_page(page);
- return false;
+ goto discard_page;
}
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
- (int)(rx_info->page_offset + offset), (int)size, rxq->buf_len);
+ (int)(rx_info->page_offset + offset), (int)size,
+ rxq->buf_len);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
/* avoid re-using remote pages */
if (unlikely(page_to_nid(page) != numa_node_id()))
- return false;
+ goto discard_page;
/* if we are only owner of page we can reuse it */
if (unlikely(page_count(page) != 1))
- return false;
+ goto discard_page;
/* flip page offset to other buffer */
rx_info->page_offset ^= rxq->buf_len;
get_page(page);
return true;
+
+discard_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
}
static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
@@ -338,10 +385,6 @@ static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
if (likely(hinic3_add_rx_frag(rxq, rx_info, skb, frag_size, tmp_pkt_offset))) {
hinic3_reuse_rx_page(rxq, rx_info);
- } else {
- /* we are not reusing the buffer so unmap it */
- dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
- rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
}
/* clear contents of buffer_info */
rx_info->buf_dma_addr = 0;
@@ -486,9 +529,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
protocol = hdr.eth->h_proto;
/* L2 header */
- /*lint -save -e778*/
if (protocol == htons(ETH_P_8021_AD) ||
- protocol == htons(ETH_P_8021_Q)) { /*lint -restore*/
+ protocol == htons(ETH_P_8021_Q)) {
if (unlikely(max_len < ETH_HLEN + VLAN_HLEN))
return max_len;
@@ -500,9 +542,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
}
/* L3 header */
- /*lint -save -e778*/
switch (protocol) {
- case htons(ETH_P_IP): /*lint -restore*/
+ case htons(ETH_P_IP):
if ((int)(hdr.data - data) >
(int)(max_len - sizeof(struct iphdr)))
return max_len;
@@ -713,7 +754,10 @@ static inline void hinic3_lro_set_gso_params(struct sk_buff *skb, u16 num_lro)
}
#ifdef HAVE_XDP_SUPPORT
-enum hinic3_xdp_pkt {
+enum hinic3_xdp_status {
+ // bpf_prog status
+ HINIC3_XDP_PROG_EMPTY,
+ // pkt action
HINIC3_XDP_PKT_PASS,
HINIC3_XDP_PKT_DROP,
};
@@ -724,9 +768,15 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
while (weqbb_num) {
rx_info = &rxq->rx_info[rxq->cons_idx & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool)
+ goto discard_direct;
+#endif
if (likely(page_to_nid(rx_info->page) == numa_node_id()))
hinic3_reuse_rx_page(rxq, rx_info);
+ goto discard_direct;
+discard_direct:
rx_info->buf_dma_addr = 0;
rx_info->page = NULL;
rxq->cons_idx++;
@@ -736,11 +786,11 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
}
}
-int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
+int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len, struct xdp_buff *xdp)
{
struct bpf_prog *xdp_prog = NULL;
struct hinic3_rx_info *rx_info = NULL;
- struct xdp_buff xdp;
+ struct net_device *netdev = rxq->netdev;
int result = HINIC3_XDP_PKT_PASS;
u16 weqbb_num = 1; /* xdp can only use one rx_buff */
u8 *va = NULL;
@@ -748,13 +798,14 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
rcu_read_lock();
xdp_prog = READ_ONCE(rxq->xdp_prog);
- if (!xdp_prog)
+ if (!xdp_prog) {
+ result = HINIC3_XDP_PROG_EMPTY;
goto unlock_rcu;
+ }
if (unlikely(pkt_len > rxq->buf_len)) {
RXQ_STATS_INC(rxq, xdp_large_pkt);
- weqbb_num = (u16)(pkt_len >> rxq->rx_buff_shift) +
- ((pkt_len & (rxq->buf_len - 1)) ? 1 : 0);
+ weqbb_num = HINIC3_GET_SGE_NUM(pkt_len, rxq);
result = HINIC3_XDP_PKT_DROP;
goto xdp_out;
}
@@ -765,26 +816,27 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
dma_sync_single_range_for_cpu(rxq->dev, rx_info->buf_dma_addr,
rx_info->page_offset,
rxq->buf_len, DMA_FROM_DEVICE);
- xdp.data = va;
- xdp.data_hard_start = xdp.data;
- xdp.data_end = xdp.data + pkt_len;
+ xdp->data = va;
+ xdp->data_hard_start = xdp->data;
+ xdp->data_end = xdp->data + pkt_len;
#ifdef HAVE_XDP_FRAME_SZ
- xdp.frame_sz = rxq->buf_len;
+ xdp->frame_sz = rxq->buf_len;
#endif
#ifdef HAVE_XDP_DATA_META
- xdp_set_data_meta_invalid(&xdp);
+ xdp_set_data_meta_invalid(xdp);
#endif
- prefetchw(xdp.data_hard_start);
- act = bpf_prog_run_xdp(xdp_prog, &xdp);
+ prefetchw(xdp->data_hard_start);
+ act = bpf_prog_run_xdp(xdp_prog, xdp);
switch (act) {
case XDP_PASS:
+ result = HINIC3_XDP_PKT_PASS;
break;
case XDP_DROP:
result = HINIC3_XDP_PKT_DROP;
break;
default:
result = HINIC3_XDP_PKT_DROP;
- bpf_warn_invalid_xdp_action(rxq->netdev, xdp_prog, act);
+ bpf_warn_invalid_xdp_action(netdev, xdp_prog, act);
}
xdp_out:
@@ -798,9 +850,86 @@ unlock_rcu:
return result;
}
+
+static bool hinic3_add_rx_frag_with_xdp(struct hinic3_rxq *rxq, u32 pkt_len,
+ struct hinic3_rx_info *rx_info,
+ struct sk_buff *skb, struct xdp_buff *xdp)
+{
+ struct page *page = rx_info->page;
+
+ if (pkt_len <= HINIC3_RX_HDR_SIZE) {
+ __skb_put_data(skb, xdp->data, pkt_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool, page, false);
+ return false;
+ }
+#endif
+ if (likely(page_to_nid(page) == numa_node_id()))
+ return true;
+
+ put_page(page);
+ goto umap_page;
+ }
+
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
+ (int)(rx_info->page_offset +
+ (xdp->data - xdp->data_hard_start)),
+ (int)pkt_len, rxq->buf_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
+ if (unlikely(page_to_nid(page) != numa_node_id()))
+ goto umap_page;
+ if (unlikely(page_count(page) != 1))
+ goto umap_page;
+
+ rx_info->page_offset ^= rxq->buf_len;
+ get_page(page);
+
+ return true;
+umap_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
+}
+
+static struct sk_buff *hinic3_fetch_rx_buffer_xdp(struct hinic3_rxq *rxq,
+ u32 pkt_len,
+ struct xdp_buff *xdp)
+{
+ struct sk_buff *skb;
+ struct hinic3_rx_info *rx_info;
+ u32 sw_ci;
+ bool reuse;
+
+ sw_ci = rxq->cons_idx & rxq->q_mask;
+ rx_info = &rxq->rx_info[sw_ci];
+
+ skb = netdev_alloc_skb_ip_align(rxq->netdev, HINIC3_RX_HDR_SIZE);
+ if (unlikely(!skb))
+ return NULL;
+
+ reuse = hinic3_add_rx_frag_with_xdp(rxq, pkt_len, rx_info, skb, xdp);
+ if (likely(reuse))
+ hinic3_reuse_rx_page(rxq, rx_info);
+
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+
+ rxq->cons_idx += 1;
+ rxq->delta += 1;
+
+ return skb;
+}
+
#endif
-static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_cqe_info *cqe_info)
+static int recv_one_pkt(struct hinic3_rxq *rxq,
+ struct hinic3_cqe_info *cqe_info)
{
struct sk_buff *skb = NULL;
struct net_device *netdev = rxq->netdev;
@@ -808,13 +937,25 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_cqe_info *cqe_info
#ifdef HAVE_XDP_SUPPORT
u32 xdp_status;
+ struct xdp_buff xdp = { 0 };
- xdp_status = (u32)(hinic3_run_xdp(rxq, cqe_info->pkt_len));
+ xdp_status = (u32)(hinic3_run_xdp(rxq, cqe_info->pkt_len, &xdp));
if (xdp_status == HINIC3_XDP_PKT_DROP)
return 0;
-#endif
+ // build skb
+ if (xdp_status != HINIC3_XDP_PROG_EMPTY) {
+ // xdp_prog configured, build skb with xdp
+ skb = hinic3_fetch_rx_buffer_xdp(rxq, cqe_info->pkt_len, &xdp);
+ } else {
+ // xdp_prog not configured, build skb
+ skb = hinic3_fetch_rx_buffer(rxq, cqe_info);
+ }
+#else
+
+ // xdp is not supported
skb = hinic3_fetch_rx_buffer(rxq, cqe_info);
+#endif
if (unlikely(!skb)) {
RXQ_STATS_INC(rxq, alloc_skb_err);
return -ENOMEM;
@@ -842,7 +983,7 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_cqe_info *cqe_info
if (unlikely(test_bit(HINIC3_LP_TEST, &nic_dev->flags)))
hinic3_copy_lp_data(nic_dev, skb);
- if (cqe_info->lro_num)
+ if (cqe_info->lro_num > 1)
hinic3_lro_set_gso_params(skb, cqe_info->lro_num);
skb_record_rx_queue(skb, rxq->q_id);
@@ -1021,12 +1162,39 @@ int hinic3_rx_poll(struct hinic3_rxq *rxq, int budget)
return pkts;
}
+#ifdef HAVE_PAGE_POOL_SUPPORT
+static struct page_pool *hinic3_create_page_pool(struct hinic3_nic_dev *nic_dev,
+ u32 rq_depth,
+ struct hinic3_rx_info *rx_info_arr)
+{
+ struct page_pool_params pp_params = {
+ .flags = PP_FLAG_DMA_MAP | PP_FLAG_PAGE_FRAG | PP_FLAG_DMA_SYNC_DEV,
+ .order = nic_dev->page_order,
+ .pool_size = rq_depth * nic_dev->rx_buff_len /
+ (PAGE_SIZE << nic_dev->page_order),
+ .nid = dev_to_node(&(nic_dev->pdev->dev)),
+ .dev = &(nic_dev->pdev->dev),
+ .dma_dir = DMA_FROM_DEVICE,
+ .offset = 0,
+ .max_len = PAGE_SIZE << nic_dev->page_order,
+ };
+ struct page_pool *page_pool;
+ int i;
+
+ page_pool = nic_dev->page_pool_enabled ?
+ page_pool_create(&pp_params) : NULL;
+ for (i = 0; i < rq_depth; i++)
+ rx_info_arr[i].page_pool = page_pool;
+ return page_pool;
+}
+#endif
+
int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
u32 rq_depth, struct hinic3_dyna_rxq_res *rxqs_res)
{
struct hinic3_dyna_rxq_res *rqres = NULL;
u64 cqe_mem_size = sizeof(struct hinic3_rq_cqe) * rq_depth;
- int idx, i;
+ int idx;
u32 pkts;
u64 size;
@@ -1045,51 +1213,53 @@ int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
if (!rqres->rx_info) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx info\n", idx);
- goto err_out;
+ goto err_alloc_rx_info;
}
-
if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
rqres->cqe_start_vaddr =
- dma_zalloc_coherent(&nic_dev->pdev->dev, cqe_mem_size,
+ dma_zalloc_coherent(&nic_dev->pdev->dev,
+ cqe_mem_size,
&rqres->cqe_start_paddr,
GFP_KERNEL);
if (!rqres->cqe_start_vaddr) {
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d cqe\n", idx);
- goto err_out;
+ goto err_alloc_cqe;
}
}
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ rqres->page_pool = hinic3_create_page_pool(nic_dev, rq_depth,
+ rqres->rx_info);
+ if (nic_dev->page_pool_enabled && !rqres->page_pool) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to create rxq%d page pool\n", idx);
+ goto err_create_page_pool;
+ }
+#endif
pkts = hinic3_rx_alloc_buffers(nic_dev, rq_depth,
rqres->rx_info);
if (!pkts) {
- if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- }
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx buffers\n", idx);
- goto err_out;
+ goto err_alloc_buffers;
}
rqres->next_to_alloc = (u16)pkts;
}
return 0;
-err_out:
- for (i = 0; i < idx; i++) {
- rqres = &rxqs_res[i];
-
- hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
- if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- }
- kfree(rqres->rx_info);
- }
-
+err_alloc_buffers:
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ page_pool_destroy(rqres->page_pool);
+err_create_page_pool:
+#endif
+ dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
+ rqres->cqe_start_vaddr,
+ rqres->cqe_start_paddr);
+err_alloc_cqe:
+ kfree(rqres->rx_info);
+err_alloc_rx_info:
+ hinic3_free_rxqs_res(nic_dev, idx, rq_depth, rxqs_res);
return -ENOMEM;
}
@@ -1104,6 +1274,10 @@ void hinic3_free_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
rqres = &rxqs_res[idx];
hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rqres->page_pool)
+ page_pool_destroy(rqres->page_pool);
+#endif
if (nic_dev->cqe_mode == HINIC3_RQ_CQE_SEPARATE) {
dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
rqres->cqe_start_vaddr,
@@ -1191,6 +1365,7 @@ void hinic3_free_rxqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->rxqs);
+ nic_dev->rxqs = NULL;
}
int hinic3_alloc_rxqs(struct net_device *netdev)
@@ -1312,6 +1487,14 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
nic_info(&nic_dev->pdev->dev, "rxq %u restore_buf_num:%u\n", q_id, rxq->restore_buf_num);
rx_info = &rxq->rx_info[(hw_ci + rxq->q_depth - 1) & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool && rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool, rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ goto reset_rxq;
+ }
+#endif
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev, rx_info->buf_dma_addr,
nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
@@ -1322,7 +1505,9 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
__free_pages(rx_info->page, nic_dev->page_order);
rx_info->page = NULL;
}
+ goto reset_rxq;
+reset_rxq:
rxq->delta = 1;
rxq->next_to_update = (u16)((hw_ci + rxq->q_depth - 1) & rxq->q_mask);
rxq->cons_idx = (u16)((rxq->next_to_update + 1) & rxq->q_mask);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
index 586a221..480f787 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
@@ -4,6 +4,10 @@
#ifndef HINIC3_RX_H
#define HINIC3_RX_H
+#ifdef HAVE_PAGE_POOL_SUPPORT
+#include <net/page_pool/helpers.h>
+#endif
+
#include <linux/types.h>
#include <linux/device.h>
#include <linux/mm_types.h>
@@ -27,6 +31,7 @@
#define HINIC3_RX_CSUM_IPSU_OTHER_ERR BIT(8)
#define HINIC3_HEADER_DATA_UNIT 2
+#define HINIC3_CQE_LEN 32
#define HINIC3_COMPACT_CQE_8B 8
#define HINIC3_COMPACT_CQE_16B 16
@@ -35,20 +40,20 @@
#define HINIC3_RQ_CQE_INTEGRATE 1
struct hinic3_rxq_stats {
- u64 packets;
- u64 bytes;
- u64 errors;
- u64 csum_errors;
- u64 other_errors;
- u64 dropped;
- u64 xdp_dropped;
- u64 rx_buf_empty;
-
- u64 alloc_skb_err;
- u64 alloc_rx_buf_err;
- u64 xdp_large_pkt;
- u64 restore_drop_sge;
- u64 rsvd2;
+ u64 packets;
+ u64 bytes;
+ u64 errors;
+ u64 csum_errors;
+ u64 other_errors;
+ u64 dropped;
+ u64 xdp_dropped;
+ u64 rx_buf_empty;
+
+ u64 alloc_skb_err;
+ u64 alloc_rx_buf_err;
+ u64 xdp_large_pkt;
+ u64 restore_drop_sge;
+ u64 rsvd2;
#ifdef HAVE_NDO_GET_STATS64
struct u64_stats_sync syncp;
#else
@@ -62,6 +67,9 @@ struct hinic3_rx_info {
struct hinic3_rq_cqe *cqe;
dma_addr_t cqe_dma;
struct page *page;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
u32 page_offset;
u32 rsvd1;
struct hinic3_rq_wqe *rq_wqe;
@@ -102,7 +110,7 @@ struct hinic3_rxq {
u16 next_to_update;
struct device *dev; /* device for DMA mapping */
- unsigned long status;
+ u64 status;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
@@ -130,6 +138,9 @@ struct hinic3_dyna_rxq_res {
struct hinic3_rx_info *rx_info;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
};
int hinic3_alloc_rxqs(struct net_device *netdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
index bdd5a8e..d816609 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
@@ -11,10 +11,12 @@
#ifndef HINIC3_SRV_NIC_H
#define HINIC3_SRV_NIC_H
-#include "hinic3_mgmt_interface.h"
+#include <linux/netdevice.h>
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_lld.h"
+#include "nic_cfg_comm.h"
+#include "nic_mpu_cmd_defs.h"
enum hinic3_queue_type {
HINIC3_SQ,
@@ -64,6 +66,7 @@ enum hinic3_nic_event_type {
EVENT_NIC_DCB_STATE_CHANGE,
EVENT_NIC_BOND_DOWN,
EVENT_NIC_BOND_UP,
+ EVENT_NIC_OUTBAND_CFG,
};
/* *
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
index bc1a8ef..d05813e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
@@ -223,24 +223,72 @@ static void get_inner_l3_l4_type(struct sk_buff *skb, union hinic3_ip *ip,
enum sq_l3_type *l3_type, u8 *l4_proto)
{
unsigned char *exthdr = NULL;
- __be16 frag_off = 0;
if (ip->v4->version == IP4_VERSION) {
*l3_type = IPV4_PKT_WITH_CHKSUM_OFFLOAD;
*l4_proto = ip->v4->protocol;
+
+#ifdef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
+ /* inner_transport_header is wrong in centos7.0 and suse12.1 */
+ l4->hdr = ip->hdr + ((u8)ip->v4->ihl << IP_HDR_IHL_UNIT_SHIFT);
+#endif
} else if (ip->v4->version == IP6_VERSION) {
*l3_type = IPV6_PKT;
exthdr = ip->hdr + sizeof(*ip->v6);
*l4_proto = ip->v6->nexthdr;
- if (exthdr != l4->hdr)
+ if (exthdr != l4->hdr) {
+ __be16 frag_off = 0;
+#ifndef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
ipv6_skip_exthdr(skb, (int)(exthdr - skb->data),
- l4_proto, &frag_off);
+ l4_proto, &frag_off);
+#else
+ int pld_off = 0;
+
+ pld_off = ipv6_skip_exthdr(skb,
+ (int)(exthdr - skb->data),
+ l4_proto, &frag_off);
+ l4->hdr = skb->data + pld_off;
+#endif
+ }
} else {
*l3_type = UNKNOWN_L3TYPE;
*l4_proto = 0;
}
}
+static u8 hinic3_get_inner_l4_type(struct sk_buff *skb)
+{
+ enum sq_l3_type l3_type;
+ u8 l4_proto;
+ union hinic3_ip ip;
+ union hinic3_l4 l4;
+
+ ip.hdr = skb_inner_network_header(skb);
+ l4.hdr = skb_inner_transport_header(skb);
+
+ get_inner_l3_l4_type(skb, &ip, &l4, &l3_type, &l4_proto);
+
+ return l4_proto;
+}
+
+static void hinic3_set_unknown_tunnel_csum(struct sk_buff *skb)
+{
+ int csum_offset;
+ __sum16 skb_csum;
+ u8 l4_proto;
+
+ l4_proto = hinic3_get_inner_l4_type(skb);
+ /* Unsupport tunnel packet, disable csum offload */
+ skb_checksum_help(skb);
+ /* The value of csum is changed from 0xffff to 0 according to RFC1624. */
+ if (skb->ip_summed == CHECKSUM_NONE && l4_proto != IPPROTO_UDP) {
+ csum_offset = skb_checksum_start_offset(skb) + skb->csum_offset;
+ skb_csum = *(__sum16 *)(skb->data + csum_offset);
+ if (skb_csum == 0xffff)
+ *(__sum16 *)(skb->data + csum_offset) = 0;
+ }
+}
+
static int hinic3_tx_csum(struct hinic3_txq *txq, struct sk_buff *skb,
struct hinic3_offload_info *offload_info,
struct hinic3_queue_info *queue_info)
@@ -276,10 +324,9 @@ static int hinic3_tx_csum(struct hinic3_txq *txq, struct sk_buff *skb,
if (l4_proto == IPPROTO_UDP)
queue_info->udp_dp_en = 1;
- if (l4_proto != IPPROTO_UDP ||
- ((struct udphdr *)skb_transport_header(skb))->dest != VXLAN_OFFLOAD_PORT_LE) {
+ if (l4_proto != IPPROTO_UDP) {
TXQ_STATS_INC(txq, unknown_tunnel_pkt);
- skb_checksum_help(skb);
+ hinic3_set_unknown_tunnel_csum(skb);
return 0;
}
}
@@ -682,6 +729,14 @@ static netdev_tx_t hinic3_send_one_skb(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
+ /* l2nic outband vlan cfg enable */
+ if ((!skb_vlan_tag_present(skb)) &&
+ (nic_dev->nic_cap.outband_vlan_cfg_en == 1) &&
+ nic_dev->outband_cfg.outband_default_vid != 0) {
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+ (u16)nic_dev->outband_cfg.outband_default_vid);
+ }
+
offload = hinic3_tx_offload(skb, &offload_info, &queue_info, txq);
if (unlikely(offload == TX_OFFLOAD_INVALID)) {
TXQ_STATS_INC(txq, offload_cow_skb_err);
@@ -880,6 +935,7 @@ int hinic3_alloc_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
tqres->bds = kzalloc(size, GFP_KERNEL);
if (!tqres->bds) {
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc txq%d bds info\n", idx);
goto err_out;
@@ -893,7 +949,9 @@ err_out:
tqres = &txqs_res[i];
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
return -ENOMEM;
@@ -910,7 +968,9 @@ void hinic3_free_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
free_all_tx_skbs(nic_dev, sq_depth, tqres->tx_info);
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
}
@@ -982,6 +1042,7 @@ void hinic3_free_txqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->txqs);
+ nic_dev->txqs = NULL;
}
static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
@@ -998,7 +1059,7 @@ static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
static int hinic3_stop_sq(struct hinic3_txq *txq)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(txq->netdev);
- unsigned long timeout;
+ u64 timeout;
int err;
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -1007,7 +1068,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
return 0;
usleep_range(900, 1000); /* sleep 900 us ~ 1000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* force hardware to drop packets */
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -1020,7 +1081,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
break;
usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* Avoid msleep takes too long and get a fake result */
if (is_hw_complete_sq_process(txq->sq))
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
index 1b9e509..7ae029b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
@@ -29,7 +29,7 @@ struct hinic3_wq {
#define WQ_MASK_IDX(wq, idx) ((idx) & (wq)->idx_mask)
#define WQ_MASK_PAGE(wq, pg_idx) \
- ((pg_idx) < (wq)->num_wq_pages ? (pg_idx) : 0)
+ (((pg_idx) < ((wq)->num_wq_pages)) ? (pg_idx) : 0)
#define WQ_PAGE_IDX(wq, idx) ((idx) >> (wq)->wqebbs_per_page_shift)
#define WQ_OFFSET_IN_PAGE(wq, idx) ((idx) & (wq)->wqebbs_per_page_mask)
#define WQ_GET_WQEBB_ADDR(wq, pg_idx, idx_in_pg) \
@@ -75,7 +75,7 @@ static inline void *hinic3_wq_get_multi_wqebbs(struct hinic3_wq *wq,
pg_idx = WQ_PAGE_IDX(wq, *prod_idx);
off_in_page = WQ_OFFSET_IN_PAGE(wq, *prod_idx);
- if (off_in_page + num_wqebbs > wq->wqebbs_per_page) {
+ if ((off_in_page + num_wqebbs) > wq->wqebbs_per_page) {
/* wqe across wq page boundary */
*second_part_wqebbs_addr =
WQ_GET_WQEBB_ADDR(wq, WQ_MASK_PAGE(wq, pg_idx + 1), 0);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
index 597d3fe..468351f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
@@ -400,12 +400,15 @@ static int wait_for_status_poll(struct hinic3_api_cmd_chain *chain)
API_CMD_STATUS_TIMEOUT, 100); /* wait 100 us once */
}
-static void copy_resp_data(struct hinic3_api_cmd_cell_ctxt *ctxt, void *ack,
+static void copy_resp_data(struct hinic3_api_cmd_chain *chain,
+ struct hinic3_api_cmd_cell_ctxt *ctxt, void *ack,
u16 ack_size)
{
struct hinic3_api_cmd_resp_fmt *resp = ctxt->resp;
+ int rsp_size_align = chain->rsp_size_align - 0x8;
+ int rsp_size = (ack_size > rsp_size_align) ? rsp_size_align : ack_size;
- memcpy(ack, &resp->resp_data, ack_size);
+ memcpy(ack, &resp->resp_data, rsp_size);
ctxt->status = 0;
}
@@ -464,7 +467,7 @@ static int wait_for_api_cmd_completion(struct hinic3_api_cmd_chain *chain,
case HINIC3_API_CMD_POLL_READ:
err = wait_for_resp_polling(ctxt);
if (err == 0)
- copy_resp_data(ctxt, ack, ack_size);
+ copy_resp_data(chain, ctxt, ack, ack_size);
else
sdk_err(dev, "API CMD poll response timeout\n");
break;
@@ -1054,13 +1057,11 @@ alloc_cells_buf_err:
alloc_wb_status_err:
kfree(chain->cell_ctxt);
-/*lint -save -e548*/
alloc_cell_ctxt_err:
if (chain->chain_type == HINIC3_API_CMD_WRITE_ASYNC_TO_MGMT_CPU)
spin_lock_deinit(&chain->async_lock);
else
sema_deinit(&chain->sem);
-/*lint -restore*/
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
index 38474ba..9f10131 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
@@ -801,7 +801,7 @@ static int cmdq_sync_cmd(struct hinic3_cmdq *cmdq, u8 mod, u8 cmd,
hinic3_cmdq_fill_completion_info(cmd_info, &cmpt_code, &done, &errcode, out_param);
cmdq_set_cmd_buf(cmd_info, cmdq->hwdev, buf_in, buf_out);
- memcpy(&saved_cmd_info, cmd_info, sizeof(*cmd_info));
+ memcpy(&saved_cmd_info, cmd_info, sizeof(struct hinic3_cmdq_cmd_info));
cmdq_sync_wqe_prepare(cmdq, mod, cmd, buf_in, buf_out, curr_wqe, curr_pi, nic_cmd_type);
@@ -1075,6 +1075,7 @@ int hinic3_cmdq_async(void *hwdev, u8 mod, u8 cmd, struct hinic3_cmd_buf *buf_in
return cmdq_async_cmd(&cmdqs->cmdq[HINIC3_CMDQ_SYNC], mod,
cmd, buf_in, channel);
}
+EXPORT_SYMBOL(hinic3_cmdq_async);
int hinic3_cmdq_async_cos(void *hwdev, u8 mod, u8 cmd,
u8 cos_id, struct hinic3_cmd_buf *buf_in, u16 channel)
@@ -1320,6 +1321,7 @@ cmd_infos_err:
static void free_cmdq(struct hinic3_cmdq *cmdq)
{
kfree(cmdq->cmd_infos);
+ cmdq->cmd_infos = NULL;
spin_lock_deinit(&cmdq->cmdq_lock);
}
@@ -1530,7 +1532,7 @@ static int create_cmdq_wq(struct hinic3_cmdqs *cmdqs)
type = HINIC3_CMDQ_SYNC;
for (; type < cmdqs->cmdq_num; type++)
memcpy((u8 *)cmdqs->wq_block_vaddr +
- CMDQ_WQ_CLA_SIZE * type,
+ ((u64)type * CMDQ_WQ_CLA_SIZE),
cmdqs->cmdq[type].wq.wq_block_vaddr,
cmdqs->cmdq[type].wq.num_wq_pages * sizeof(u64));
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
index b9b884f..4f4639d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
@@ -15,11 +15,6 @@
#include "hinic3_common.h"
#include "hinic3_hwdev.h"
-struct dma_pool {
- unsigned int size;
- void *dev_hdl;
-};
-
#define HINIC3_SCMD_DATA_LEN 16
#define HINIC3_CMDQ_DEPTH 4096
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c
index c212bcc..d7e4985 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq_enhance.c
@@ -16,7 +16,6 @@
#include "ossl_knl.h"
#include "npu_cmdq_base_defs.h"
-#include "comm_defs.h"
#include "hinic3_crm.h"
#include "hinic3_hw.h"
#include "hinic3_hwdev.h"
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
index 5e0139a..f0b2b1a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
@@ -22,11 +22,15 @@
#include "hinic3_sriov.h"
#include "hinic3_nictool.h"
#include "hinic3_pci_id_tbl.h"
+#include "hinic3_hwdev.h"
+#include "cfg_mgmt_mpu_cmd_defs.h"
+#include "mpu_cmd_base_defs.h"
#include "hinic3_dev_mgmt.h"
#define HINIC3_WAIT_TOOL_CNT_TIMEOUT 10000
#define HINIC3_WAIT_TOOL_MIN_USLEEP_TIME 9900
#define HINIC3_WAIT_TOOL_MAX_USLEEP_TIME 10000
+#define HIGHT_BDF 8
static unsigned long card_bit_map;
@@ -60,14 +64,24 @@ void lld_dev_cnt_init(struct hinic3_pcidev *pci_adapter)
void lld_dev_hold(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_inc(&pci_adapter->ref_cnt);
}
void lld_dev_put(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_dec(&pci_adapter->ref_cnt);
}
@@ -236,6 +250,40 @@ void hinic3_get_all_chip_id(void *id_info)
card_id->num = (u32)i;
}
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+ u64 bar1_phy_addr = 0;
+ u64 bar3_phy_addr = 0;
+ u64 bar1_size = 0;
+ u64 bar3_size = 0;
+
+ lld_hold();
+
+ /* get PF bar1 or bar3 physical address to verify */
+ list_for_each_entry(chip_node, &g_hinic3_chip_list, node) {
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (hinic3_func_type(dev->hwdev) == TYPE_VF)
+ continue;
+
+ bar1_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+ bar1_size = pci_resource_len(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+
+ bar3_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ bar3_size = pci_resource_len(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ if ((phy_addr == bar1_phy_addr && vmsize <= bar1_size) ||
+ (phy_addr == bar3_phy_addr && vmsize <= bar3_size)) {
+ lld_put();
+ return 0;
+ }
+ }
+ }
+
+ lld_put();
+ return -EINVAL;
+}
+
void hinic3_get_card_func_info_by_card_name(const char *chip_name,
struct hinic3_card_func_info *card_func)
{
@@ -422,6 +470,29 @@ struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name
return NULL;
}
+void *hinic3_get_ppf_dev(void)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct list_head *chip_list = NULL;
+
+ lld_hold();
+ chip_list = get_hinic3_chip_list();
+
+ list_for_each_entry(chip_node, chip_list, node)
+ list_for_each_entry(pci_adapter, &chip_node->func_list, node)
+ if (hinic3_func_type(pci_adapter->hwdev) == TYPE_PPF) {
+ pr_info("Get ppf_func_id:%u",
+ hinic3_global_func_id(pci_adapter->hwdev));
+ lld_put();
+ return pci_adapter->lld_dev.hwdev;
+ }
+
+ lld_put();
+ return NULL;
+}
+EXPORT_SYMBOL(hinic3_get_ppf_dev);
+
struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
enum hinic3_service_type type)
{
@@ -518,6 +589,7 @@ EXPORT_SYMBOL(hinic3_get_ppf_lld_dev_unsafe);
int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len)
{
struct hinic3_pcidev *pci_adapter = NULL;
+ int ret = 0;
if (!lld_dev || !chip_name || !max_len)
return -EINVAL;
@@ -527,12 +599,18 @@ int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 ma
return -EFAULT;
lld_hold();
- strscpy(chip_name, pci_adapter->chip_node->chip_name, max_len);
+ if (strscpy(chip_name, pci_adapter->chip_node->chip_name, max_len) < 0)
+ goto RELEASE;
chip_name[max_len - 1] = '\0';
lld_put();
return 0;
+
+RELEASE:
+ lld_put();
+
+ return ret;
}
EXPORT_SYMBOL(hinic3_get_chip_name);
@@ -541,6 +619,87 @@ struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev)
return lld_dev->hwdev;
}
+void hinic3_write_oshr_info(struct os_hot_replace_info *out_oshr_info,
+ struct hw_pf_info *info,
+ struct hinic3_board_info *board_info,
+ struct card_node *chip_node, u32 serivce_enable,
+ u32 func_info_idx)
+{
+ out_oshr_info->func_infos[func_info_idx].pf_idx = info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].backup_pf =
+ (((info->glb_func_idx) / (board_info->port_num)) %
+ HOT_REPLACE_PARTITION_NUM == 0) ?
+ ((info->glb_func_idx) + (board_info->port_num)) :
+ ((info->glb_func_idx) - (board_info->port_num));
+ out_oshr_info->func_infos[func_info_idx].partition =
+ ((info->glb_func_idx) / (board_info->port_num)) %
+ HOT_REPLACE_PARTITION_NUM;
+ out_oshr_info->func_infos[func_info_idx].port_id = info->port_id;
+ out_oshr_info->func_infos[func_info_idx].bdf =
+ (info->bus_num << HIGHT_BDF) + info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].bus_num = chip_node->bus_num;
+ out_oshr_info->func_infos[func_info_idx].valid = serivce_enable;
+ memcpy(out_oshr_info->func_infos[func_info_idx].card_name,
+ chip_node->chip_name, IFNAMSIZ);
+}
+
+void hinic3_get_os_hot_replace_info(void *oshr_info)
+{
+ struct os_hot_replace_info *out_oshr_info =
+ (struct os_hot_replace_info *)oshr_info;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dst_dev = NULL;
+ struct hinic3_board_info *board_info = NULL;
+ struct hw_pf_info *infos = NULL;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ struct hinic3_hwdev *hwdev = NULL;
+ u32 func_info_idx = 0, func_id = 0, func_num, serivce_enable = 0;
+ struct list_head *hinic3_chip_list = get_hinic3_chip_list();
+ int err;
+
+ lld_hold();
+ pf_infos = kzalloc(sizeof(struct hinic3_hw_pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ pr_err("kzalloc pf_infos fail\n");
+ lld_put();
+ return;
+ }
+ list_for_each_entry(chip_node, hinic3_chip_list, node) {
+ list_for_each_entry(dst_dev, &chip_node->func_list, node) {
+ err = hinic3_get_hw_pf_infos(dst_dev->hwdev,
+ pf_infos,
+ HINIC3_CHANNEL_COMM);
+ if (err != 0) {
+ pr_err("get pf info failed\n");
+ break;
+ }
+ hwdev = (struct hinic3_hwdev *)dst_dev->hwdev;
+ serivce_enable = 0;
+ infos = pf_infos->infos;
+ board_info = &hwdev->board_info;
+ if (hwdev->hot_replace_mode == HOT_REPLACE_ENABLE)
+ serivce_enable = 1;
+ break;
+ }
+
+ func_num = pf_infos->num_pfs;
+ if (func_num <= 0) {
+ pr_err("get pf num failed\n");
+ break;
+ }
+
+ for (func_id = 0; func_id < func_num; func_id++) {
+ hinic3_write_oshr_info(out_oshr_info, &infos[func_id],
+ board_info, chip_node,
+ serivce_enable, func_info_idx);
+ func_info_idx++;
+ }
+ }
+ out_oshr_info->func_cnt = func_info_idx;
+ kfree(pf_infos);
+ lld_put();
+}
+
struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(lld_dev->pdev);
@@ -608,21 +767,24 @@ void hinic3_get_card_info(const void *hwdev, void *bufin)
if (hinic3_support_nic(fun_hwdev, NULL)) {
if (dev->uld_dev[SERVICE_T_NIC]) {
info->pf[i].pf_type |= (u32)BIT(SERVICE_T_NIC);
- get_dynamic_uld_dev_name(dev, SERVICE_T_NIC, info->pf[i].name);
+ get_dynamic_uld_dev_name(dev, SERVICE_T_NIC,
+ info->pf[i].name);
}
}
if (hinic3_support_ppa(fun_hwdev, NULL)) {
if (dev->uld_dev[SERVICE_T_PPA]) {
info->pf[i].pf_type |= (u32)BIT(SERVICE_T_PPA);
- get_dynamic_uld_dev_name(dev, SERVICE_T_PPA, info->pf[i].name);
+ get_dynamic_uld_dev_name(dev, SERVICE_T_PPA,
+ info->pf[i].name);
}
}
if (hinic3_func_for_mgmt(fun_hwdev))
strscpy(info->pf[i].name, "FOR_MGMT", IFNAMSIZ);
- if (dev->lld_dev.pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID)
+ if (dev->lld_dev.pdev->subsystem_device ==
+ BIFUR_RESOURCE_PF_SSID)
strscpy(info->pf[i].name, "bifur", IFNAMSIZ);
strscpy(info->pf[i].bus_info, pci_name(dev->pcidev),
@@ -721,6 +883,7 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
struct card_node *chip_node = NULL;
unsigned char i;
unsigned char bus_number = 0;
+ int err;
if (chip_node_is_exist(pci_adapter, &bus_number))
return 0;
@@ -746,7 +909,10 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
/* bus number */
chip_node->bus_num = bus_number;
- if (snprintf(chip_node->chip_name, IFNAMSIZ, "%s%u", HINIC3_CHIP_NAME, i) < 0) {
+ snprintf(chip_node->chip_name, IFNAMSIZ, "%s%u", HINIC3_CHIP_NAME, i);
+
+ err = sscanf(chip_node->chip_name, HINIC3_CHIP_NAME "%d", &(chip_node->chip_id));
+ if (err <= 0) {
clear_bit(i, &card_bit_map);
kfree(chip_node);
return -EINVAL;
@@ -803,3 +969,36 @@ int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *
return 0;
}
+
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin)
+{
+ struct card_node *chip_node = NULL;
+ struct card_mbox_cnt_info *info = (struct card_mbox_cnt_info *)bufin;
+ struct hinic3_pcidev *dev = NULL;
+ struct hinic3_hwdev *func_hwdev = NULL;
+ u32 i = 0;
+
+ info->func_num = 0;
+ chip_node = hinic3_get_chip_node_by_hwdev(hwdev);
+ if (chip_node == NULL)
+ return;
+
+ lld_hold();
+
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ func_hwdev = (struct hinic3_hwdev *)dev->hwdev;
+ strscpy(info->func_info[i].bus_info, pci_name(dev->pcidev),
+ sizeof(info->func_info[i].bus_info));
+
+ info->func_info[i].send_cnt = func_hwdev->mbox_send_cnt;
+ info->func_info[i].ack_cnt = func_hwdev->mbox_ack_cnt;
+ info->func_num++;
+ i = info->func_num;
+ if (i >= ARRAY_SIZE(info->func_info)) {
+ sdk_err(&dev->pcidev->dev, "chip_node->func_list bigger than pf_max + vf_max\n");
+ break;
+ }
+ }
+
+ lld_put();
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
index 5c7c7cd..9815082 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
@@ -22,8 +22,13 @@
#define BIFUR_RESOURCE_PF_SSID 0x05a1
-#define HINIC3_IS_VF_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_VF)
-#define HINIC3_IS_SPU_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_SPU)
+#define HINIC3_IS_VF_DEV(pdev) \
+ ((pdev)->device == HINIC3_DEV_ID_VF || \
+ (pdev)->device == HINIC3_DEV_SDI_5_1_ID_VF)
+#define HINIC3_IS_SPU_DEV(pdev) \
+ (((pdev)->device == HINIC3_DEV_ID_SPU) || \
+ ((pdev)->device == HINIC3_DEV_ID_SDI_5_0_PF) || \
+ (((pdev)->device == HINIC3_DEV_ID_DPU_PF)))
enum {
HINIC3_NOT_PROBE = 1,
@@ -79,6 +84,13 @@ struct hinic3_pcidev {
u16 probe_fault_level;
u16 rsvd2;
u64 rsvd4;
+
+ struct workqueue_struct *multi_host_mgmt_workq;
+ struct work_struct slave_nic_work;
+ struct work_struct slave_vroce_work;
+
+ struct workqueue_struct *migration_probe_workq;
+ struct delayed_work migration_probe_dwork;
};
struct hinic_chip_info {
@@ -104,4 +116,6 @@ void wait_lld_dev_unused(struct hinic3_pcidev *pci_adapter);
void *hinic3_get_hwdev_by_pcidev(struct pci_dev *pdev);
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
index 11561a0..59ff722 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
@@ -101,7 +101,8 @@ static bool check_image_device_type(struct hinic3_hwdev *hwdev, u32 device_type)
static void encapsulate_update_cmd(struct hinic3_cmd_update_firmware *msg,
struct firmware_section *section_info,
- int *remain_len, u32 *send_len, u32 *send_pos)
+ const int *remain_len, u32 *send_len,
+ u32 *send_pos)
{
memset(msg->data, 0, sizeof(msg->data));
msg->ctl_info.sf = (*remain_len == section_info->section_len) ? true : false;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
index 937d699..be7c82b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
@@ -26,6 +26,8 @@
#include "hinic3_prof_adap.h"
#include "hinic3_eqs.h"
+#include "vram_common.h"
+
#define HINIC3_EQS_WQ_NAME "hinic3_eqs"
#define AEQ_CTRL_0_INTR_IDX_SHIFT 0
@@ -66,7 +68,6 @@
#define HINIC3_TASK_PROCESS_EQE_LIMIT 1024
#define HINIC3_EQ_UPDATE_CI_STEP 64
-/*lint -e806*/
static uint g_aeq_len = HINIC3_DEFAULT_AEQ_LEN;
module_param(g_aeq_len, uint, 0444);
MODULE_PARM_DESC(g_aeq_len,
@@ -83,7 +84,6 @@ static uint g_num_ceqe_in_tasklet = HINIC3_TASK_PROCESS_EQE_LIMIT;
module_param(g_num_ceqe_in_tasklet, uint, 0444);
MODULE_PARM_DESC(g_num_ceqe_in_tasklet,
"The max number of ceqe can be processed in tasklet, default = 1024");
-/*lint +e806*/
#define CEQ_CTRL_0_INTR_IDX_SHIFT 0
#define CEQ_CTRL_0_DMA_ATTR_SHIFT 12
@@ -819,18 +819,22 @@ static int alloc_eq_pages(struct hinic3_eq *eq)
u32 reg, init_val;
u16 pg_idx, i;
int err;
+ gfp_t gfp_vram;
eq->eq_pages = kcalloc(eq->num_pages, sizeof(*eq->eq_pages),
GFP_KERNEL);
if (!eq->eq_pages)
return -ENOMEM;
+ gfp_vram = hi_vram_get_gfp_vram();
+
for (pg_idx = 0; pg_idx < eq->num_pages; pg_idx++) {
eq_page = &eq->eq_pages[pg_idx];
err = hinic3_dma_zalloc_coherent_align(eq->hwdev->dev_hdl,
eq->page_size,
HINIC3_MIN_EQ_PAGE_SIZE,
- GFP_KERNEL, eq_page);
+ GFP_KERNEL | gfp_vram,
+ eq_page);
if (err) {
sdk_err(eq->hwdev->dev_hdl, "Failed to alloc eq page, page index: %u\n",
pg_idx);
@@ -881,6 +885,7 @@ static void free_eq_pages(struct hinic3_eq *eq)
&eq->eq_pages[pg_idx]);
kfree(eq->eq_pages);
+ eq->eq_pages = NULL;
}
static inline u32 get_page_size(const struct hinic3_eq *eq)
@@ -1120,7 +1125,8 @@ int hinic3_aeqs_init(struct hinic3_hwdev *hwdev, u16 num_aeqs,
hwdev->aeqs = aeqs;
aeqs->hwdev = hwdev;
aeqs->num_aeqs = num_aeqs;
- aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME, WQ_MEM_RECLAIM,
+ aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME,
+ WQ_MEM_RECLAIM | WQ_HIGHPRI,
HINIC3_MAX_AEQS);
if (!aeqs->workq) {
sdk_err(hwdev->dev_hdl, "Failed to initialize aeq workqueue\n");
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
index a4cbac8..6b96b87 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
@@ -82,6 +82,48 @@ int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id,
return 0;
}
+/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read and clear to zero
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
+ u16 *value)
+{
+ struct chipif_sml_ctr_rd_req req;
+ union ctr_rd_rsp rsp;
+ int ret;
+
+ if (!hwdev || !value)
+ return -EFAULT;
+
+ if (!COMM_SUPPORT_API_CHAIN((struct hinic3_hwdev *)hwdev))
+ return -EPERM;
+
+ memset(&req, 0, sizeof(req));
+
+ hinic3_sml_ctr_read_build_req(&req, instance,
+ CHIPIF_SM_CTR_OP_READ_CLEAR,
+ CHIPIF_ACK, ctr_id, 0);
+
+ ret = hinic3_api_cmd_read_ack(hwdev, node, (u8 *)&req,
+ (unsigned short)sizeof(req),
+ (void *)&rsp,
+ (unsigned short)sizeof(rsp));
+ if (ret) {
+ sdk_err(((struct hinic3_hwdev *)hwdev)->dev_hdl,
+ "Sm 16bit counter clear fail, err(%d)\n", ret);
+ return ret;
+ }
+ sml_ctr_htonl_n((u32 *)&rsp, sizeof(rsp) / sizeof(u32));
+ *value = rsp.bs_ss16_rsp.value1;
+
+ return 0;
+}
+
/**
* hinic3_sm_ctr_rd32 - small single 32 counter read
* @hwdev: the hardware device
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
index 030ef6d..5a8d2a4 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
@@ -34,13 +34,18 @@ static void parse_pub_res_cap_dfx(struct hinic3_hwdev *hwdev,
cap->max_vf);
sdk_info(hwdev->dev_hdl, "Host_pf_num: 0x%x, pf_id_start: 0x%x, host_vf_num: 0x%x, vf_id_start: 0x%x\n",
cap->pf_num, cap->pf_id_start, cap->vf_num, cap->vf_id_start);
- sdk_info(hwdev->dev_hdl, "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x\n",
- cap->host_valid_bitmap, cap->master_host_id, cap->srv_multi_host_mode);
sdk_info(hwdev->dev_hdl,
- "fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
- cap->fake_vf_start_id, cap->fake_vf_num, cap->fake_vf_max_pctx);
- sdk_info(hwdev->dev_hdl, "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x\n",
- cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len);
+ "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x, hot_plug_disable: 0x%x\n",
+ cap->host_valid_bitmap, cap->master_host_id,
+ cap->srv_multi_host_mode, cap->hot_plug_disable);
+ sdk_info(hwdev->dev_hdl,
+ "os_hot_replace: 0x%x, fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
+ cap->os_hot_replace, cap->fake_vf_start_id,
+ cap->fake_vf_num, cap->fake_vf_max_pctx);
+ sdk_info(hwdev->dev_hdl,
+ "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x, bond_create_mode: 0x%x\n",
+ cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len,
+ cap->bond_create_mode);
}
static void parse_cqm_res_cap(struct hinic3_hwdev *hwdev, struct service_cap *cap,
@@ -109,6 +114,9 @@ static void parse_pub_res_cap(struct hinic3_hwdev *hwdev,
cap->host_valid_bitmap = dev_cap->host_valid_bitmap;
cap->master_host_id = dev_cap->master_host_id;
cap->srv_multi_host_mode = dev_cap->srv_multi_host_mode;
+ cap->hot_plug_disable = dev_cap->hot_plug_disable;
+ cap->bond_create_mode = dev_cap->bond_create_mode;
+ cap->os_hot_replace = dev_cap->os_hot_replace;
cap->fake_vf_en = dev_cap->fake_vf_en;
cap->fake_vf_start_bit = dev_cap->fake_vf_start_bit;
cap->fake_vf_end_bit = dev_cap->fake_vf_end_bit;
@@ -148,18 +156,27 @@ static void parse_l2nic_res_cap(struct hinic3_hwdev *hwdev,
nic_cap->max_sqs = dev_cap->nic_max_sq_id + 1;
nic_cap->max_rqs = dev_cap->nic_max_rq_id + 1;
nic_cap->default_num_queues = dev_cap->nic_default_num_queues;
+ nic_cap->outband_vlan_cfg_en = dev_cap->outband_vlan_cfg_en;
+ nic_cap->lro_enable = dev_cap->lro_enable;
sdk_info(hwdev->dev_hdl, "L2nic resource capbility, max_sqs: 0x%x, max_rqs: 0x%x\n",
nic_cap->max_sqs, nic_cap->max_rqs);
/* Check parameters from firmware */
- if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP ||
- nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
- sdk_info(hwdev->dev_hdl, "Number of qp exceed limit[1-%d]: sq: %u, rq: %u\n",
- HINIC3_CFG_MAX_QP, nic_cap->max_sqs, nic_cap->max_rqs);
+ if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of sq exceed limit[1-%d]: sq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_sqs);
nic_cap->max_sqs = HINIC3_CFG_MAX_QP;
+ }
+
+ if (nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of rq exceed limit[1-%d]: rq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_rqs);
nic_cap->max_rqs = HINIC3_CFG_MAX_QP;
}
+
+ if (nic_cap->outband_vlan_cfg_en)
+ sdk_info(hwdev->dev_hdl, "L2nic outband vlan cfg enabled\n");
}
static void parse_fc_res_cap(struct hinic3_hwdev *hwdev,
@@ -333,6 +350,28 @@ static void parse_ipsec_res_cap(struct hinic3_hwdev *hwdev,
dev_cap->ipsec_max_sactx, dev_cap->ipsec_max_cq);
}
+static void parse_vbs_res_cap(struct hinic3_hwdev *hwdev,
+ struct service_cap *cap,
+ struct cfg_cmd_dev_cap *dev_cap,
+ enum func_type type)
+{
+ struct vbs_service_cap *vbs_cap = &cap->vbs_cap;
+
+ vbs_cap->vbs_max_volq = dev_cap->vbs_max_volq;
+ vbs_cap->vbs_main_pf_enable = dev_cap->vbs_main_pf_enable;
+ vbs_cap->vbs_vsock_pf_enable = dev_cap->vbs_vsock_pf_enable;
+ vbs_cap->vbs_fushion_queue_pf_enable = dev_cap->vbs_fushion_queue_pf_enable;
+
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS resource capbility, vbs_max_volq: 0x%x\n",
+ dev_cap->vbs_max_volq);
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS pf info, vbs_main_pf_enable: 0x%x, vbs_vsock_pf_enable: 0x%x, vbs_fushion_queue_pf_enable: 0x%x\n",
+ dev_cap->vbs_main_pf_enable,
+ dev_cap->vbs_vsock_pf_enable,
+ dev_cap->vbs_fushion_queue_pf_enable);
+}
+
static void parse_dev_cap(struct hinic3_hwdev *dev,
struct cfg_cmd_dev_cap *dev_cap, enum func_type type)
{
@@ -375,6 +414,9 @@ static void parse_dev_cap(struct hinic3_hwdev *dev,
if (IS_PPA_TYPE(dev))
parse_ppa_res_cap(dev, cap, dev_cap, type);
+
+ if (IS_VBS_TYPE(dev))
+ parse_vbs_res_cap(dev, cap, dev_cap, type);
}
static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
@@ -404,6 +446,23 @@ static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
return 0;
}
+u8 hinic3_get_bond_create_mode(void *dev)
+{
+ struct hinic3_hwdev *hwdev = NULL;
+ struct service_cap *cap = NULL;
+
+ if (!dev) {
+ pr_err("pointer dev is NULL\n");
+ return -EINVAL;
+ }
+
+ hwdev = (struct hinic3_hwdev *)dev;
+ cap = &hwdev->cfg_mgmt->svc_cap;
+
+ return cap->bond_create_mode;
+}
+EXPORT_SYMBOL(hinic3_get_bond_create_mode);
+
int hinic3_get_dev_cap(void *dev)
{
enum func_type type;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
index 671eed6..2f2310a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
@@ -166,6 +166,11 @@ struct service_cap {
u8 srv_multi_host_mode;
u16 virtio_vq_size;
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 os_hot_replace;
+ u8 rsvd1;
+
u8 timer_pf_num;
u8 timer_pf_id_start;
u16 timer_vf_num;
@@ -335,5 +340,7 @@ void free_capability(struct hinic3_hwdev *dev);
int hinic3_init_vf_dev_cap(void *hwdev);
+u8 hinic3_get_bond_create_mode(void *dev);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
index 8a87d25..cb3b609 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
@@ -21,6 +21,7 @@
#include "hinic3_hw_cfg.h"
#include "hinic3_cmdq.h"
#include "mpu_inband_cmd_defs.h"
+#include "vram_common.h"
#include "hinic3_hw_comm.h"
#define HINIC3_MSIX_CNT_LLI_TIMER_SHIFT 0
@@ -242,12 +243,19 @@ int hinic3_func_reset(void *dev, u16 func_id, u64 reset_flag, u16 channel)
struct hinic3_hwdev *hwdev = dev;
u16 out_size = sizeof(func_reset);
int err = 0;
+ int is_in_kexec;
if (!dev) {
pr_err("Invalid para: dev is null.\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ sdk_info(hwdev->dev_hdl, "Skip function reset!\n");
+ return 0;
+ }
+
sdk_info(hwdev->dev_hdl, "Function is reset, flag: 0x%llx, channel:0x%x\n",
reset_flag, channel);
@@ -554,7 +562,7 @@ EXPORT_SYMBOL(hinic3_set_ppf_flr_type);
int hinic3_set_ppf_tbl_hotreplace_flag(void *hwdev, u8 flag)
{
- struct comm_cmd_ppf_tbl_htrp_config htr_info = {0};
+ struct comm_cmd_ppf_tbl_htrp_config htr_info = {};
u16 out_size = sizeof(struct comm_cmd_ppf_tbl_htrp_config);
struct hinic3_hwdev *dev = hwdev;
int ret;
@@ -899,11 +907,19 @@ static int set_ppf_tmr_status(struct hinic3_hwdev *hwdev,
int hinic3_ppf_tmr_start(void *hwdev)
{
+ int is_in_kexec;
+
if (!hwdev) {
pr_err("Hwdev pointer is NULL for starting ppf timer\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ pr_info("Skip starting ppt timer during kexec");
+ return 0;
+ }
+
return set_ppf_tmr_status(hwdev, HINIC_PPF_TMR_FLAG_START);
}
EXPORT_SYMBOL(hinic3_ppf_tmr_start);
@@ -919,18 +935,114 @@ int hinic3_ppf_tmr_stop(void *hwdev)
}
EXPORT_SYMBOL(hinic3_ppf_tmr_stop);
+static int hi_vram_kalloc_align(struct hinic3_hwdev *hwdev, char *name, u32 page_size, u32 page_num,
+ struct hinic3_dma_addr_align *mem_align)
+{
+ void *vaddr = NULL, *align_vaddr = NULL;
+ dma_addr_t paddr, align_paddr;
+ u64 real_size = page_size;
+ u64 align = page_size;
+
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ /* align */
+ if (align_paddr == paddr) {
+ align_vaddr = vaddr;
+ goto out;
+ }
+
+ hi_vram_kfree((void *)vaddr, name, real_size);
+
+ /* realloc memory for align */
+ real_size = page_size + align;
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc align failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ align_vaddr = (void *)((u64)vaddr + (align_paddr - paddr));
+
+out:
+ mem_align->real_size = (u32)real_size;
+ mem_align->ori_vaddr = vaddr;
+ mem_align->ori_paddr = paddr;
+ mem_align->align_vaddr = align_vaddr;
+ mem_align->align_paddr = align_paddr;
+
+ return 0;
+}
+
+static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
+{
+ u32 i;
+ struct hinic3_dma_addr_align *page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = hwdev->mqm_eqm_vram_name;
+
+ page_addr = hwdev->mqm_att.brm_srch_page_addr;
+
+ for (i = 0; i < hwdev->mqm_att.page_num; i++) {
+ if (is_use_vram != 0) {
+ hi_vram_kfree(page_addr->ori_vaddr, mqm_eqm_vram_name[i].vram_name,
+ page_addr->real_size);
+ } else {
+ hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
+ }
+ page_addr->ori_vaddr = NULL;
+ page_addr++;
+ }
+
+ kfree(mqm_eqm_vram_name);
+ hwdev->mqm_eqm_vram_name = NULL;
+}
+
static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
u32 page_num)
{
struct hinic3_dma_addr_align *page_addr = hwdev->mqm_att.brm_srch_page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = NULL;
u32 valid_num = 0;
u32 flag = 1;
u32 i = 0;
int err;
+ u16 func_id;
+
+ mqm_eqm_vram_name = kcalloc(page_num, sizeof(struct mqm_eqm_vram_name_s), GFP_KERNEL);
+ if (mqm_eqm_vram_name == NULL) {
+ sdk_err(hwdev->dev_hdl, "mqm eqm alloc vram name failed.\n");
+ return -ENOMEM;
+ }
+
+ hwdev->mqm_eqm_vram_name = mqm_eqm_vram_name;
+ func_id = hinic3_global_func_id(hwdev);
for (i = 0; i < page_num; i++) {
- err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl, page_size,
- page_size, GFP_KERNEL, page_addr);
+ if (is_use_vram != 0) {
+ snprintf(mqm_eqm_vram_name[i].vram_name,
+ VRAM_NAME_MAX_LEN, "%s%hu%s%u",
+ VRAM_CQM_GLB_FUNC_BASE, func_id,
+ VRAM_NIC_MQM, i);
+ err = hi_vram_kalloc_align(hwdev,
+ mqm_eqm_vram_name[i].vram_name,
+ page_size, page_num,
+ page_addr);
+ } else {
+ err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl,
+ page_size,
+ page_size,
+ GFP_KERNEL,
+ page_addr);
+ }
if (err) {
flag = 0;
break;
@@ -939,15 +1051,12 @@ static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
page_addr++;
}
+ hwdev->mqm_att.page_num = valid_num;
+
if (flag == 1) {
hwdev->mqm_att.page_size = page_size;
- hwdev->mqm_att.page_num = page_num;
} else {
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
- for (i = 0; i < valid_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
+ mqm_eqm_free_page_mem(hwdev);
return -EFAULT;
}
@@ -986,19 +1095,6 @@ static int mqm_eqm_alloc_page_mem(struct hinic3_hwdev *hwdev)
return ret;
}
-static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
-{
- u32 i;
- struct hinic3_dma_addr_align *page_addr;
-
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
-
- for (i = 0; i < hwdev->mqm_att.page_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
-}
-
static int mqm_eqm_set_cfg_2_hw(struct hinic3_hwdev *hwdev, u8 valid)
{
struct comm_cmd_eqm_cfg info_eqm_cfg;
@@ -1129,6 +1225,7 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
{
struct comm_cmd_get_eqm_num info_eqm_fix;
int ret;
+ int is_in_kexec;
if (hwdev->hwif->attr.func_type != TYPE_PPF)
return 0;
@@ -1158,10 +1255,16 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
goto err_page;
}
- ret = mqm_eqm_set_page_2_hw(hwdev);
- if (ret) {
- sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
- goto err_ecmd;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ ret = mqm_eqm_set_page_2_hw(hwdev);
+ if (ret) {
+ sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
+ goto err_ecmd;
+ }
+ } else {
+ sdk_info(hwdev->dev_hdl,
+ "Mqm db don't set to chip when os hot replace.\r\n");
}
ret = mqm_eqm_set_cfg_2_hw(hwdev, 1);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
index e8aa7ef..722fecd 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
@@ -252,97 +252,6 @@ static u32 get_up_timeout_val(enum hinic3_mod_type mod, u16 cmd)
return 0; /* use default mbox/apichain timeout time */
}
-static int api_csr_read(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
-{
- struct up_log_msg_st *up_log_msg = (struct up_log_msg_st *)buf_in;
- u8 *buf_out_tmp = (u8 *)buf_out;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
-
- if (!buf_in || !buf_out || in_size != sizeof(*up_log_msg) ||
- *out_size != up_log_msg->rd_len || up_log_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = up_log_msg->rd_len;
- rd_addr = up_log_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_rd32(hwdev, node_id,
- rd_addr + offset,
- (u32 *)(buf_out_tmp + offset));
- if (ret) {
- pr_err("Csr rd fail, err: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, node_id, rd_addr + offset);
- return ret;
- }
- offset += DW_WIDTH;
- }
- *out_size = rd_len;
-
- return ret;
-}
-
-static int api_csr_write(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out,
- u32 *out_size)
-{
- struct csr_write_st *csr_write_msg = (struct csr_write_st *)buf_in;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
- u8 *data = NULL;
-
- if (!buf_in || in_size != sizeof(*csr_write_msg) || csr_write_msg->rd_len == 0 ||
- csr_write_msg->rd_len > API_CSR_MAX_RD_LEN || csr_write_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = csr_write_msg->rd_len;
- rd_addr = csr_write_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- data = kzalloc(rd_len, GFP_KERNEL);
- if (!data)
- return -EFAULT;
-
- if (copy_from_user(data, (void *)csr_write_msg->data, rd_len)) {
- pr_err("Copy information from user failed\n");
- kfree(data);
- return -EFAULT;
- }
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_wr32(hwdev, node_id,
- rd_addr + offset,
- *((u32 *)(data + offset)));
- if (ret) {
- pr_err("Csr wr fail, ret: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, rd_addr + offset, node_id);
- kfree(data);
- return ret;
- }
- offset += DW_WIDTH;
- }
-
- *out_size = 0;
- kfree(data);
- return ret;
-}
-
int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
@@ -369,10 +278,8 @@ int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
return ret;
}
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_BYPASS) {
- if (nt_msg->mpu_cmd.cmd == API_CSR_WRITE)
- return api_csr_write(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
-
- ret = api_csr_read(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
+ pr_err("Unsupported api_type %u\n", nt_msg->mpu_cmd.api_type);
+ return -EINVAL;
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_TO_MPU) {
timeout = get_up_timeout_val(mod, cmd);
if (hinic3_pcie_itf_id(hwdev) != SPU_HOST_ID)
@@ -439,6 +346,23 @@ static int sm_rd16(void *hwdev, u32 id, u8 instance,
return ret;
}
+static int sm_rd16_clear(void *hwdev, u32 id, u8 instance,
+ u8 node, struct sm_out_st *buf_out)
+{
+ u16 val1;
+ int ret;
+
+ ret = hinic3_sm_ctr_rd16_clear(hwdev, node, instance, id, &val1);
+ if (ret != 0) {
+ pr_err("Get sm ctr clear information (16 bits)failed!\n");
+ val1 = 0xffff;
+ }
+
+ buf_out->val1 = val1;
+
+ return ret;
+}
+
static int sm_rd32(void *hwdev, u32 id, u8 instance,
u8 node, struct sm_out_st *buf_out)
{
@@ -558,6 +482,7 @@ const struct sm_module_handle sm_module_cmd_handle[] = {
{SM_CTR_RD32, sm_rd32},
{SM_CTR_RD64_PAIR, sm_rd64_pair},
{SM_CTR_RD64, sm_rd64},
+ {SM_CTR_RD16_CLEAR, sm_rd16_clear},
{SM_CTR_RD32_CLEAR, sm_rd32_clear},
{SM_CTR_RD64_PAIR_CLEAR, sm_rd64_pair_clear},
{SM_CTR_RD64_CLEAR, sm_rd64_clear}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
index 83e7b63..c317f4a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
@@ -101,6 +101,12 @@ enum hinic3_pcie_tph {
#define SLAVE_HOST_STATUS_SET(host_id, enable) (((u8)(enable) & 1U) << (host_id))
#define SLAVE_HOST_STATUS_GET(host_id, val) (!!((val) & (1U << (host_id))))
+#ifdef HAVE_HOT_REPLACE_FUNC
+ extern int get_partition_id(void);
+#else
+ static int get_partition_id(void) {return 0; }
+#endif
+
void set_slave_host_enable(void *hwdev, u8 host_id, bool enable)
{
u32 reg_val;
@@ -207,6 +213,27 @@ static void hinic3_init_host_mode_pre(struct hinic3_hwdev *hwdev)
}
}
+static void hinic3_init_hot_plug_status(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->hot_plug_disable)
+ hwdev->hot_plug_mode = HOT_PLUG_DISABLE;
+ else
+ hwdev->hot_plug_mode = HOT_PLUG_ENABLE;
+}
+
+static void hinic3_init_os_hot_replace(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->os_hot_replace) {
+ hwdev->hot_replace_mode = HOT_REPLACE_ENABLE;
+ } else {
+ hwdev->hot_replace_mode = HOT_REPLACE_DISABLE;
+ }
+}
+
static u8 hinic3_nic_sw_aeqe_handler(void *hwdev, u8 event, u8 *data)
{
struct hinic3_hwdev *dev = hwdev;
@@ -270,14 +297,20 @@ static void chip_fault_show(struct hinic3_hwdev *hwdev,
"fatal", "reset", "host", "flr", "general", "suggestion"};
char level_str[FAULT_SHOW_STR_LEN + 1];
u8 level;
+ int ret;
memset(level_str, 0, FAULT_SHOW_STR_LEN + 1);
level = event->event.chip.err_level;
- if (level < FAULT_LEVEL_MAX)
- strscpy(level_str, fault_level[level],
- FAULT_SHOW_STR_LEN);
- else
- strscpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (level < FAULT_LEVEL_MAX) {
+ ret = strscpy(level_str, fault_level[level],
+ FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ } else {
+ ret = strscpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ }
if (level == FAULT_LEVEL_SERIOUS_FLR)
dev_err(hwdev->dev_hdl, "err_level: %u [%s], flr func_id: %u\n",
@@ -299,6 +332,7 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
"reg rd timeout", "reg wr timeout", "phy fault", "tsensor fault"};
char type_str[FAULT_SHOW_STR_LEN + 1] = {0};
struct fault_event_stats *fault = NULL;
+ int ret;
sdk_err(hwdev->dev_hdl, "Fault event report received, func_id: %u\n",
hinic3_global_func_id(hwdev));
@@ -306,10 +340,14 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
fault = &hwdev->hw_stats.fault_event_stats;
if (event->type < FAULT_TYPE_MAX) {
- strscpy(type_str, fault_type[event->type], sizeof(type_str));
+ ret = strscpy(type_str, fault_type[event->type], sizeof(type_str));
+ if (ret < 0)
+ return;
atomic_inc(&fault->fault_type_stat[event->type]);
} else {
- strscpy(type_str, "Unknown", sizeof(type_str));
+ ret = strscpy(type_str, "Unknown", sizeof(type_str));
+ if (ret < 0)
+ return;
}
sdk_err(hwdev->dev_hdl, "Fault type: %u [%s]\n", event->type, type_str);
@@ -1536,15 +1574,29 @@ int hinic3_init_hwdev(struct hinic3_init_para *para)
hinic3_init_host_mode_pre(hwdev);
+ hinic3_init_hot_plug_status(hwdev);
+
+ hinic3_init_os_hot_replace(hwdev);
+
err = hinic3_multi_host_mgmt_init(hwdev);
if (err != 0) {
sdk_err(hwdev->dev_hdl, "Failed to init function mode\n");
goto init_multi_host_fail;
}
- err = hinic3_init_ppf_work(hwdev);
- if (err != 0)
- goto init_ppf_work_fail;
+ // hot_replace_mode is enable, run ppf function only when partition_id is 0
+ // or run ppf function directly
+ if (hwdev->hot_replace_mode == HOT_REPLACE_ENABLE) {
+ if (get_partition_id() == 0) {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0)
+ goto init_ppf_work_fail;
+ }
+ } else {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0)
+ goto init_ppf_work_fail;
+ }
err = hinic3_set_comm_features(hwdev, hwdev->features, COMM_MAX_FEATURE_QWORD);
if (err != 0) {
@@ -1948,6 +2000,19 @@ void hinic3_link_event_stats(void *dev, u8 link)
}
EXPORT_SYMBOL(hinic3_link_event_stats);
+int hinic3_get_link_event_stats(void *dev, int *link_state)
+{
+ struct hinic3_hwdev *hwdev = dev;
+
+ if (!hwdev || !link_state)
+ return -EINVAL;
+
+ *link_state = hwdev->hw_stats.link_event_stats.link_down_stats.counter;
+
+ return 0;
+}
+EXPORT_SYMBOL(hinic3_get_link_event_stats);
+
u8 hinic3_max_pf_num(void *hwdev)
{
if (!hwdev)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
index b8a3356..0ca639f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
@@ -10,6 +10,7 @@
#include "hinic3_hw.h"
#include "mpu_inband_cmd_defs.h"
#include "hinic3_profile.h"
+#include "vram_common.h"
struct cfg_mgmt_info;
@@ -82,6 +83,22 @@ enum hinic3_host_mode_e {
HINIC3_SDI_MODE_MAX,
};
+enum hinic3_hot_plug_mode {
+ HOT_PLUG_ENABLE,
+ HOT_PLUG_DISABLE,
+};
+
+enum hinic3_os_hot_replace_mode {
+ HOT_REPLACE_DISABLE,
+ HOT_REPLACE_ENABLE,
+};
+
+#define UNSUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_DISABLE)
+
+#define SUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_ENABLE)
+
#define MULTI_HOST_CHIP_MODE_SHIFT 0
#define MULTI_HOST_MASTER_MBX_STS_SHIFT 17
#define MULTI_HOST_PRIV_DATA_SHIFT 0x8
@@ -100,6 +117,10 @@ enum hinic3_host_mode_e {
((val) & (~(MULTI_HOST_##member##_MASK \
<< MULTI_HOST_##member##_SHIFT)))
+struct mqm_eqm_vram_name_s {
+ char vram_name[VRAM_NAME_MAX_LEN];
+};
+
struct hinic3_hwdev {
void *adapter_hdl; /* pointer to hinic3_pcidev or NDIS_Adapter */
void *pcidev_hdl; /* pointer to pcidev or Handler */
@@ -138,6 +159,9 @@ struct hinic3_hwdev {
u32 rsvd2;
struct hinic3_multi_host_mgmt *mhost_mgmt;
+ char mhost_mgmt_name[VRAM_NAME_MAX_LEN];
+
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name;
struct mutex stateful_mutex; /* protect cqm init and deinit */
@@ -170,6 +194,8 @@ struct hinic3_hwdev {
struct hinic3_devlink *devlink_dev;
enum hinic3_func_mode func_mode;
+ enum hinic3_hot_plug_mode hot_plug_mode;
+ enum hinic3_os_hot_replace_mode hot_replace_mode;
u32 rsvd3;
DECLARE_BITMAP(func_probe_in_host, MAX_FUNCTION_NUM);
@@ -179,7 +205,10 @@ struct hinic3_hwdev {
u64 last_recv_aeq_cnt;
u16 aeq_busy_cnt;
- u64 rsvd4[8];
+ u64 mbox_send_cnt;
+ u64 mbox_ack_cnt;
+
+ u64 rsvd4[5];
u8 cmdq_mode;
};
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
index 33f1210..8590f70 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
@@ -544,6 +544,7 @@ static void free_db_area(struct hinic3_free_db_area *free_db_area)
{
spin_lock_deinit(&free_db_area->idx_lock);
kfree(free_db_area->db_bitmap_array);
+ free_db_area->db_bitmap_array = NULL;
}
static int get_db_idx(struct hinic3_hwif *hwif, u32 *idx)
@@ -841,6 +842,7 @@ void hinic3_free_hwif(struct hinic3_hwdev *hwdev)
free_db_area(&hwdev->hwif->free_db_area);
enable_all_msix(hwdev);
kfree(hwdev->hwif);
+ hwdev->hwif = NULL;
}
u16 hinic3_global_func_id(void *hwdev)
@@ -856,6 +858,44 @@ u16 hinic3_global_func_id(void *hwdev)
}
EXPORT_SYMBOL(hinic3_global_func_id);
+/**
+ * get function id from register,used by sriov hot migration process
+ * @hwdev: the pointer to hw device
+ */
+u16 hinic3_global_func_id_hw(void *hwdev)
+{
+ u32 addr, attr0;
+ struct hinic3_hwdev *dev;
+
+ dev = (struct hinic3_hwdev *)hwdev;
+ addr = HINIC3_CSR_FUNC_ATTR0_ADDR;
+ attr0 = hinic3_hwif_read_reg(dev->hwif, addr);
+
+ return HINIC3_AF0_GET(attr0, FUNC_GLOBAL_IDX);
+}
+
+/**
+ * get function id, used by sriov hot migratition process.
+ * @hwdev: the pointer to hw device
+ * @func_id: function id
+ */
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id)
+{
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)hwdev;
+
+ if (!hwdev || !func_id)
+ return -EINVAL;
+
+ /* only vf get func_id from chip reg for sriov migrate */
+ if (!HINIC3_IS_VF(dev)) {
+ *func_id = hinic3_global_func_id(hwdev);
+ return 0;
+ }
+
+ *func_id = hinic3_global_func_id_hw(dev);
+ return 0;
+}
+
u16 hinic3_intr_num(void *hwdev)
{
struct hinic3_hwif *hwif = NULL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
index 6ab1b92..1f770db 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
@@ -16,6 +16,7 @@
#include <linux/rtc.h>
#include <linux/aer.h>
#include <linux/debugfs.h>
+#include <linux/notifier.h>
#include "ossl_knl.h"
#include "hinic3_mt.h"
@@ -26,28 +27,55 @@
#include "hinic3_dev_mgmt.h"
#include "hinic3_nictool.h"
#include "hinic3_hw.h"
+#include "hinic3_multi_host_mgmt.h"
+#include "hinic3_hw_cfg.h"
#include "hinic3_lld.h"
#include "hinic3_profile.h"
#include "hinic3_hwdev.h"
#include "hinic3_prof_adap.h"
-#include "comm_msg_intf.h"
+#include "hinic3_devlink.h"
+#include "vram_common.h"
-static bool disable_vf_load;
+
+enum partition_dev_type {
+ PARTITION_DEV_NONE = 0,
+ PARTITION_DEV_SHARED,
+ PARTITION_DEV_EXCLUSIVE,
+ PARTITION_DEV_BACKUP,
+};
+
+#ifdef HAVE_HOT_REPLACE_FUNC
+static int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type,
+ unsigned int partition_id);
+static int get_partition_id(void);
+#else
+static int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type,
+ unsigned int partition_id)
+{
+ return 0;
+}
+static int get_partition_id(void) { return 0; }
+#endif
+
+static bool g_is_pf_migrated = false;
+static bool disable_vf_load = false;
module_param(disable_vf_load, bool, 0444);
MODULE_PARM_DESC(disable_vf_load,
"Disable virtual functions probe or not - default is false");
-static bool disable_attach;
+static bool disable_attach = false;
module_param(disable_attach, bool, 0444);
MODULE_PARM_DESC(disable_attach, "disable_attach or not - default is false");
#define HINIC3_WAIT_SRIOV_CFG_TIMEOUT 15000
-MODULE_AUTHOR("Huawei Technologies CO., Ltd");
-MODULE_DESCRIPTION(HINIC3_DRV_DESC);
-MODULE_VERSION(HINIC3_DRV_VERSION);
-MODULE_LICENSE("GPL");
+#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
+static DEVICE_ATTR_RW(sriov_numvfs, 0644,
+ sriov_numvfs_show, sriov_numvfs_store);
+static DEVICE_ATTR_RO(sriov_totalvfs, 0444,
+ sriov_totalvfs_show, NULL);
+#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
static struct attribute *hinic3_attributes[] = {
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
@@ -64,7 +92,18 @@ static const struct attribute_group hinic3_attr_group = {
struct hinic3_uld_info g_uld_info[SERVICE_T_MAX] = { {0} };
#define HINIC3_EVENT_PROCESS_TIMEOUT 10000
+#define HINIC3_WAIT_EVENT_PROCESS_TIMEOUT 100
struct mutex g_uld_mutex; /* g_uld_info lock */
+#define BUS_MAX_DEV_NUM 256
+#define HINIC3_SLAVE_WORK_MAX_NUM 20
+
+struct vf_offset_info {
+ u8 valid;
+ u16 vf_offset_from_pf[CMD_MAX_MAX_PF_NUM];
+};
+
+static struct vf_offset_info g_vf_offset;
+DEFINE_MUTEX(g_vf_offset_lock);
void hinic3_uld_lock_init(void)
{
@@ -73,13 +112,23 @@ void hinic3_uld_lock_init(void)
static const char *s_uld_name[SERVICE_T_MAX] = {
"nic", "ovs", "roce", "toe", "ioe",
- "fc", "vbs", "ipsec", "virtio", "migrate", "ppa", "bifur", "custom"};
+ "fc", "vbs", "ipsec", "virtio", "migrate",
+ "ppa", "custom", "vroce", "crypt", "vsock", "bifur"};
const char **hinic3_get_uld_names(void)
{
return s_uld_name;
}
+#ifdef CONFIG_PCI_IOV
+static int hinic3_get_pf_device_id(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_dev = pci_physfn(pdev);
+
+ return pf_dev->device;
+}
+#endif
+
static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
const struct hinic3_uld_info *uld_info)
{
@@ -98,6 +147,10 @@ static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
atomic_set(&dev->uld_ref_cnt[type], 0);
+ if (!uld_info->probe) {
+ err = 0;
+ goto out_unlock;
+ }
err = uld_info->probe(&dev->lld_dev, &uld_dev, dev->uld_dev_name[type]);
if (err) {
sdk_err(&dev->pcidev->dev,
@@ -166,6 +219,10 @@ static void detach_uld(struct hinic3_pcidev *dev,
wait_uld_unused(dev, type);
+ if (!uld_info->remove) {
+ mutex_unlock(&dev->pdev_mutex);
+ return;
+ }
uld_info->remove(&dev->lld_dev, dev->uld_dev[type]);
dev->uld_dev[type] = NULL;
@@ -182,11 +239,14 @@ static void attach_ulds(struct hinic3_pcidev *dev)
{
enum hinic3_service_type type;
struct pci_dev *pdev = dev->pcidev;
+ int is_in_kexec = vram_get_kexec_flag();
+
+ if (is_in_kexec == 0)
+ lld_hold();
- lld_hold();
mutex_lock(&g_uld_mutex);
- for (type = SERVICE_T_NIC; type < SERVICE_T_MAX; type++) {
+ for (type = SERVICE_T_OVS; type < SERVICE_T_MAX; type++) {
if (g_uld_info[type].probe) {
if (pdev->is_virtfn &&
(!hinic3_get_vf_service_load(pdev, (u16)type))) {
@@ -198,7 +258,9 @@ static void attach_ulds(struct hinic3_pcidev *dev)
}
}
mutex_unlock(&g_uld_mutex);
- lld_put();
+
+ if (is_in_kexec == 0)
+ lld_put();
}
static void detach_ulds(struct hinic3_pcidev *dev)
@@ -305,7 +367,7 @@ void hinic3_unregister_uld(enum hinic3_service_type type)
}
uld_info = &g_uld_info[type];
- memset(uld_info, 0, sizeof(*uld_info));
+ memset(uld_info, 0, sizeof(struct hinic3_uld_info));
mutex_unlock(&g_uld_mutex);
lld_put();
}
@@ -359,6 +421,26 @@ void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_ser
}
EXPORT_SYMBOL(hinic3_detach_service);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ __module_get(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_get);
+
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ module_put(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_put);
+
static void hinic3_sync_time_to_fmw(struct hinic3_pcidev *pdev_pri)
{
struct timeval tv = {0};
@@ -441,23 +523,447 @@ static void send_event_to_all_pf(struct hinic3_pcidev *dev,
lld_put();
}
+u32 hinic3_pdev_is_virtfn(struct pci_dev *pdev)
+{
+#ifdef CONFIG_PCI_IOV
+ return pdev->is_virtfn;
+#else
+ return 0;
+#endif
+}
+
+static int hinic3_get_function_enable(struct pci_dev *pdev, bool *en)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+ int err;
+
+ /* PF in host os or function in guest os, probe sdk in default */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev) {
+ *en = true;
+ return 0;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev) {
+ /* vf in host and pf sdk not probed */
+ return -EFAULT;
+ }
+ pf_hwdev = pci_adapter->hwdev;
+
+ err = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (err) {
+ sdk_err(&pci_adapter->pcidev->dev,
+ "Func hinic3_get_vfid_by_vfpci fail %d\n", err);
+ return err;
+ }
+
+ err = hinic3_get_func_nic_enable(pf_hwdev, global_func_id, en);
+ if (!!err) {
+ sdk_info(&pdev->dev, "Failed to get function nic status, err %d.\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+int hinic3_set_func_probe_in_host(void *hwdev, u16 func_id, bool probe)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (hinic3_func_type(hwdev) != TYPE_PPF)
+ return -EINVAL;
+
+ if (probe)
+ set_bit(func_id, dev->func_probe_in_host);
+ else
+ clear_bit(func_id, dev->func_probe_in_host);
+
+ return 0;
+}
+
+bool hinic3_get_func_probe_in_host(void *hwdev, u16 func_id)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+ bool probed = false;
+
+ if (!hwdev)
+ return false;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return false;
+ }
+
+ probed = !!test_bit(func_id, ppf_dev->func_probe_in_host);
+ up(&dev->ppf_sem);
+
+ return probed;
+}
+
+void *hinic3_get_ppf_hwdev_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ chip_node = pci_adapter->chip_node;
+ lld_dev_hold(&pci_adapter->lld_dev);
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (dev->lld_state == HINIC3_IN_REMOVE)
+ continue;
+
+ if (dev->hwdev && hinic3_func_type(dev->hwdev) == TYPE_PPF) {
+ lld_dev_put(&pci_adapter->lld_dev);
+ return dev->hwdev;
+ }
+ }
+ lld_dev_put(&pci_adapter->lld_dev);
+
+ return NULL;
+}
+
+static int hinic3_set_vf_nic_used_state(void *hwdev, u16 func_id, bool opened)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+
+ if (!dev || func_id >= MAX_FUNCTION_NUM)
+ return -EINVAL;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return -EINVAL;
+ }
+
+ if (opened)
+ set_bit(func_id, ppf_dev->netdev_setup_state);
+ else
+ clear_bit(func_id, ppf_dev->netdev_setup_state);
+
+ up(&dev->ppf_sem);
+
+ return 0;
+}
+
+static void set_vf_func_in_use(struct pci_dev *pdev, bool in_use)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+
+ /* only need to be set when VF is on the host */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev)
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev)
+ return;
+
+ pf_hwdev = pci_adapter->hwdev;
+
+ global_func_id = (u16)pdev->devfn + hinic3_glb_pf_vf_offset(pf_hwdev);
+ (void)hinic3_set_vf_nic_used_state(pf_hwdev, global_func_id, in_use);
+}
+
+
+static int hinic3_pf_get_vf_offset_info(struct hinic3_pcidev *des_dev, u16 *vf_offset)
+{
+ int err, i;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ u16 pf_func_id;
+ struct hinic3_pcidev *pf_pci_adapter = NULL;
+
+ pf_pci_adapter = (hinic3_pdev_is_virtfn(des_dev->pcidev)) ?
+ pci_get_drvdata(des_dev->pcidev->physfn) : des_dev;
+ pf_func_id = hinic3_global_func_id(pf_pci_adapter->hwdev);
+ if (pf_func_id >= CMD_MAX_MAX_PF_NUM || !vf_offset)
+ return -EINVAL;
+
+ mutex_lock(&g_vf_offset_lock);
+ if (g_vf_offset.valid == 0) {
+ pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ sdk_err(&pf_pci_adapter->pcidev->dev, "Malloc pf_infos fail\n");
+ err = -ENOMEM;
+ goto err_malloc;
+ }
+
+ err = hinic3_get_hw_pf_infos(pf_pci_adapter->hwdev,
+ pf_infos, HINIC3_CHANNEL_COMM);
+ if (err) {
+ sdk_warn(&pf_pci_adapter->pcidev->dev,
+ "Hinic3_get_hw_pf_infos fail err %d\n", err);
+ err = -EFAULT;
+ goto err_out;
+ }
+
+ g_vf_offset.valid = 1;
+ for (i = 0; i < CMD_MAX_MAX_PF_NUM; i++)
+ g_vf_offset.vf_offset_from_pf[i] = pf_infos->infos[i].vf_offset;
+
+ kfree(pf_infos);
+ }
+
+ *vf_offset = g_vf_offset.vf_offset_from_pf[pf_func_id];
+
+ mutex_unlock(&g_vf_offset_lock);
+
+ return 0;
+
+err_out:
+ kfree(pf_infos);
+err_malloc:
+ mutex_unlock(&g_vf_offset_lock);
+ return err;
+}
+
+static struct pci_dev *get_vf_pdev_by_pf(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ int err;
+ u16 bus_num;
+ u16 vf_start, vf_end;
+ u16 des_fn, pf_func_id, vf_offset;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ pf_func_id = hinic3_global_func_id(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end || pf_func_id >= CMD_MAX_MAX_PF_NUM)
+ return NULL;
+
+ err = hinic3_pf_get_vf_offset_info(des_dev, &vf_offset);
+ if (err) {
+ sdk_warn(&des_dev->pcidev->dev, "Hinic3_pf_get_vf_offset_info fail\n");
+ return NULL;
+ }
+
+ des_fn = ((func_id - vf_start) - 1) + pf_func_id + vf_offset;
+ bus_num = des_dev->pcidev->bus->number + des_fn / BUS_MAX_DEV_NUM;
+
+ return pci_get_domain_bus_and_slot(0, bus_num, (des_fn % BUS_MAX_DEV_NUM));
+}
+
+static struct hinic3_pcidev *get_des_pci_adapter(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ struct pci_dev *des_pdev = NULL;
+ u16 vf_start, vf_end;
+ bool probe_in_host = false;
+
+ if (hinic3_global_func_id(des_dev->hwdev) == func_id)
+ return des_dev;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end)
+ return NULL;
+
+ des_pdev = get_vf_pdev_by_pf(des_dev, func_id);
+ if (!des_pdev)
+ return NULL;
+
+ pci_dev_put(des_pdev);
+
+ probe_in_host = hinic3_get_func_probe_in_host(des_dev->hwdev, func_id);
+ if (!probe_in_host)
+ return NULL;
+
+ return pci_get_drvdata(des_pdev);
+}
+
+int __set_vroce_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ u8 enable_vroce = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_vroce_enable(pci_adapter->hwdev,
+ func_id, &enable_vroce);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Failed to get vroce state.\n");
+ return err;
+ }
+
+ mutex_lock(&g_uld_mutex);
+
+ if (!!enable_vroce) {
+ if (!g_uld_info[SERVICE_T_ROCE].probe) {
+ sdk_info(&pdev->dev, "Uld(roce_info) has not been registered!\n");
+ mutex_unlock(&g_uld_mutex);
+ return 0;
+ }
+
+ err = attach_uld(pci_adapter, SERVICE_T_ROCE,
+ &g_uld_info[SERVICE_T_ROCE]);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Failed to initialize VROCE.\n");
+ mutex_unlock(&g_uld_mutex);
+ return err;
+ }
+ } else {
+ sdk_info(&pdev->dev, "Func %u vroce state: disable.\n", func_id);
+ if (g_uld_info[SERVICE_T_ROCE].remove)
+ detach_uld(pci_adapter, SERVICE_T_ROCE);
+ }
+
+ mutex_unlock(&g_uld_mutex);
+
+ return 0;
+}
+
+void slave_host_mgmt_vroce_work(struct work_struct *work)
+{
+#ifndef __HIFC__
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_vroce_work);
+
+ __set_vroce_func_state(pci_adapter);
+#endif
+}
+
+void *hinic3_get_roce_uld_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ return pci_adapter->uld_dev[SERVICE_T_ROCE];
+}
+
+static int func_service_state_process(struct hinic3_pcidev *event_dev,
+ struct hinic3_pcidev *des_dev,
+ struct hinic3_mhost_nic_func_state *state,
+ u16 cmd)
+{
+ int err = 0;
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)event_dev->hwdev;
+
+ switch (cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ state->enable = hinic3_get_roce_uld_by_pdev(des_dev->pcidev) ? 1 : 0;
+ break;
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive nic[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ if (event_dev->multi_host_mgmt_workq) {
+ queue_work(event_dev->multi_host_mgmt_workq,
+ &des_dev->slave_nic_work);
+ } else {
+ sdk_err(&des_dev->pcidev->dev, "Can not schedule slave nic work\n");
+ err = -EFAULT;
+ }
+ break;
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive vroce[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ queue_work_on(hisdk3_get_work_cpu_affinity(dev, WORK_TYPE_MBOX),
+ event_dev->multi_host_mgmt_workq,
+ &des_dev->slave_vroce_work);
+ break;
+ default:
+ sdk_warn(&des_dev->pcidev->dev,
+ "Service state process with unknown cmd: %u\n", cmd);
+ err = -EFAULT;
+ break;
+ }
+
+ return err;
+}
+
+static void multi_host_mgmt(struct hinic3_pcidev *dev,
+ struct hinic3_multi_host_mgmt_event *mhost_mgmt)
+{
+ struct hinic3_pcidev *cur_dev = NULL;
+ struct hinic3_pcidev *des_dev = NULL;
+ struct hinic3_mhost_nic_func_state *nic_state = NULL;
+ u16 sub_cmd = mhost_mgmt->sub_cmd;
+
+ switch (sub_cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ nic_state = mhost_mgmt->data;
+ nic_state->status = 0;
+ if (!dev->hwdev)
+ return;
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)dev->hwdev))
+ return;
+
+ /* find func_idx pci_adapter and disable or enable nic */
+ lld_dev_hold(&dev->lld_dev);
+ list_for_each_entry(cur_dev, &dev->chip_node->func_list, node) {
+ if (cur_dev->lld_state == HINIC3_IN_REMOVE ||
+ hinic3_pdev_is_virtfn(cur_dev->pcidev))
+ continue;
+
+ des_dev = get_des_pci_adapter(cur_dev, nic_state->func_idx);
+ if (!des_dev)
+ continue;
+
+ if (func_service_state_process(dev, des_dev, nic_state, sub_cmd))
+ nic_state->status = 1;
+ break;
+ }
+ lld_dev_put(&dev->lld_dev);
+ break;
+ default:
+ sdk_warn(&dev->pcidev->dev, "Received unknown multi-host mgmt event: %u\n",
+ mhost_mgmt->sub_cmd);
+ break;
+ }
+}
+
static void hinic3_event_process(void *adapter, struct hinic3_event_info *event)
{
struct hinic3_pcidev *dev = adapter;
struct hinic3_fault_event *fault = (void *)event->event_data;
+ struct hinic3_multi_host_mgmt_event *mhost_event =
+ (void *)event->event_data;
u16 func_id;
- if ((event->service == EVENT_SRV_COMM && event->type == EVENT_COMM_FAULT) &&
- fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
- fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
- func_id = fault->event.chip.func_id;
- return send_event_to_dst_pf(adapter, func_id, event);
- }
-
- if (event->type == EVENT_COMM_MGMT_WATCHDOG)
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MULTI_HOST_MGMT):
+ multi_host_mgmt(dev, mhost_event);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_FAULT):
+ if (fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
+ fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
+ func_id = fault->event.chip.func_id;
+ return send_event_to_dst_pf(adapter, func_id, event);
+ }
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MGMT_WATCHDOG):
send_event_to_all_pf(adapter, event);
- else
+ break;
+ default:
send_uld_dev_event(adapter, event);
+ break;
+ }
}
static void uld_def_init(struct hinic3_pcidev *pci_adapter)
@@ -605,31 +1111,70 @@ static void hinic3_pci_deinit(struct pci_dev *pdev)
kfree(pci_adapter);
}
-#ifdef CONFIG_X86
-/**
- * cfg_order_reg - when cpu model is haswell or broadwell, should configure dma
- * order register to zero
- * @pci_adapter: pci_adapter
- **/
-/*lint -save -e40 */
-static void cfg_order_reg(struct hinic3_pcidev *pci_adapter)
+static void set_vf_load_state(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
{
- u8 cpu_model[] = {0x3c, 0x3f, 0x45, 0x46, 0x3d, 0x47, 0x4f, 0x56};
- struct cpuinfo_x86 *cpuinfo = NULL;
- u32 i;
+ /* In bm mode, slave host will load vfs in default */
+ if (IS_BMGW_SLAVE_HOST(((struct hinic3_hwdev *)pci_adapter->hwdev)) &&
+ hinic3_func_type(pci_adapter->hwdev) != TYPE_VF)
+ hinic3_set_vf_load_state(pdev, false);
- if (hinic3_func_type(pci_adapter->hwdev) == TYPE_VF)
- return;
+ if (!disable_attach) {
+ if ((hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) &&
+ hinic3_is_bm_slave_host(pci_adapter->hwdev)) {
+ if (hinic3_func_max_vf(pci_adapter->hwdev) == 0) {
+ sdk_warn(&pdev->dev, "The sriov enabling process is skipped, vfs_num: 0.\n");
+ return;
+ }
+ hinic3_pci_sriov_enable(
+ pdev, hinic3_func_max_vf(pci_adapter->hwdev));
+ }
+ }
+}
- cpuinfo = &cpu_data(0);
- for (i = 0; i < sizeof(cpu_model); i++) {
- if (cpu_model[i] == cpuinfo->x86_model)
- hinic3_set_pcie_order_cfg(pci_adapter->hwdev);
+static void hinic3_init_ppf_hwdev(struct hinic3_hwdev *hwdev)
+{
+ if (!hwdev) {
+ pr_err("[%s:%d] null hwdev pointer\n", __FILE__, __LINE__);
+ return;
}
+
+ hwdev->ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(hwdev->pcidev_hdl);
}
-/*lint -restore*/
-#endif
+static int set_nic_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ bool enable_nic = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_nic_enable(pci_adapter->hwdev, func_id, &enable_nic);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Failed to get nic state.\n");
+ return err;
+ }
+
+ if (!enable_nic) {
+ sdk_info(&pdev->dev, "Func %u nic state: disable.\n", func_id);
+ detach_uld(pci_adapter, SERVICE_T_NIC);
+ return 0;
+ }
+
+ if (IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ (void)hinic3_init_vf_dev_cap(pci_adapter->hwdev);
+
+ if (g_uld_info[SERVICE_T_NIC].probe) {
+ err = attach_uld(pci_adapter, SERVICE_T_NIC, &g_uld_info[SERVICE_T_NIC]);
+ if (err != 0) {
+ sdk_err(&pdev->dev, "Initialize NIC failed\n");
+ return err;
+ }
+ }
+
+ return 0;
+}
static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
{
@@ -689,7 +1234,16 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
list_add_tail(&pci_adapter->node, &pci_adapter->chip_node->func_list);
lld_unlock_chip_node();
+ hinic3_init_ppf_hwdev((struct hinic3_hwdev *)pci_adapter->hwdev);
+
+ set_vf_load_state(pdev, pci_adapter);
+
if (!disable_attach) {
+ /* NIC is base driver, probe firstly */
+ err = set_nic_func_state(pci_adapter);
+ if (err)
+ goto set_nic_func_state_err;
+
attach_ulds(pci_adapter);
if (hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) {
@@ -700,10 +1254,6 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
goto create_sysfs_err;
}
}
-
-#ifdef CONFIG_X86
- cfg_order_reg(pci_adapter);
-#endif
}
return 0;
@@ -711,6 +1261,8 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
create_sysfs_err:
detach_ulds(pci_adapter);
+
+set_nic_func_state_err:
lld_lock_chip_node();
list_del(&pci_adapter->node);
lld_unlock_chip_node();
@@ -759,6 +1311,7 @@ static void hinic3_func_deinit(struct pci_dev *pdev)
hinic3_free_stateful(pci_adapter->hwdev);
hinic3_free_hwdev(pci_adapter->hwdev);
+ pci_adapter->hwdev = NULL;
}
static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
@@ -770,14 +1323,57 @@ static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
clear_bit(HINIC3_FUNC_PERSENT, &sriov_info->state);
usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- end = jiffies + msecs_to_jiffies(HINIC3_WAIT_SRIOV_CFG_TIMEOUT);
- do {
- if (!test_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state) &&
- !test_bit(HINIC3_SRIOV_DISABLE, &sriov_info->state))
- return;
+ end = jiffies + msecs_to_jiffies(HINIC3_WAIT_SRIOV_CFG_TIMEOUT);
+ do {
+ if (!test_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state) &&
+ !test_bit(HINIC3_SRIOV_DISABLE, &sriov_info->state))
+ return;
+
+ usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
+ } while (time_before(jiffies, end));
+}
+
+static bool hinic3_get_vf_nic_en_status(struct pci_dev *pdev)
+{
+ bool nic_en = false;
+ u16 global_func_id;
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev) {
+ pr_err("pdev is null.\n");
+ return false;
+ }
+
+ if (pdev->is_virtfn)
+ pf_pdev = pdev->physfn;
+ else
+ return false;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return false;
+ }
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ return false;
+
+ if (hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id)) {
+ sdk_err(&pdev->dev, "Get vf id by vfpci failed\n");
+ return false;
+ }
+
+ if (hinic3_get_mhost_func_nic_enable(pci_adapter->hwdev,
+ global_func_id, &nic_en)) {
+ sdk_err(&pdev->dev, "Get function nic status failed\n");
+ return false;
+ }
+
+ sdk_info(&pdev->dev, "Func %hu %s default probe in host\n",
+ global_func_id, (nic_en) ? "enable" : "disable");
- usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- } while (time_before(jiffies, end));
+ return nic_en;
}
bool hinic3_get_vf_load_state(struct pci_dev *pdev)
@@ -834,6 +1430,8 @@ int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state)
}
EXPORT_SYMBOL(hinic3_set_vf_load_state);
+
+
bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service)
{
struct hinic3_pcidev *pci_adapter = NULL;
@@ -897,6 +1495,32 @@ int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
}
EXPORT_SYMBOL(hinic3_set_vf_service_load);
+static bool hinic3_is_host_vmsec_enable(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct pci_dev *pf_pdev = NULL;
+
+ if (pdev->is_virtfn)
+ pf_pdev = pdev->physfn;
+ else
+ pf_pdev = pdev;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ pr_err("Pci_adapter is null.\n");
+ return false;
+ }
+
+ /* pf/vf used in host */
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ (hinic3_func_type(pci_adapter->hwdev) == TYPE_PF) &&
+ IS_RDMA_TYPE((struct hinic3_hwdev *)pci_adapter->hwdev)) {
+ return true;
+ }
+
+ return false;
+}
+
static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
@@ -910,6 +1534,13 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
pci_adapter->lld_state = HINIC3_IN_REMOVE;
mutex_unlock(&pci_adapter->pdev_mutex);
+ if (!(pdev->is_virtfn) && (hinic3_is_host_vmsec_enable(pdev) == true) &&
+ (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF)) {
+ cancel_delayed_work_sync(&pci_adapter->migration_probe_dwork);
+ flush_workqueue(pci_adapter->migration_probe_workq);
+ destroy_workqueue(pci_adapter->migration_probe_workq);
+ }
+
hinic3_detect_hw_present(pci_adapter->hwdev);
hisdk3_remove_pre_process(pci_adapter->hwdev);
@@ -934,23 +1565,128 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
sdk_info(&pdev->dev, "Pcie device removed function\n");
+ set_vf_func_in_use(pdev, false);
+
return 0;
}
+int hinic3_get_vfid_by_vfpci(void *hwdev, struct pci_dev *pdev, u16 *global_func_id)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ u16 pf_bus, vf_bus, vf_offset;
+ int err;
+
+ if (!pdev || !global_func_id || !hinic3_pdev_is_virtfn(pdev))
+ return -EINVAL;
+ (void)hwdev;
+ pf_pdev = pdev->physfn;
+
+ vf_bus = pdev->bus->number;
+ pf_bus = pf_pdev->bus->number;
+
+ if (pdev->vendor == HINIC3_VIRTIO_VNEDER_ID)
+ return -EPERM;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return -EINVAL;
+ }
+
+ err = hinic3_pf_get_vf_offset_info(pci_adapter, &vf_offset);
+ if (err) {
+ sdk_err(&pdev->dev, "Func hinic3_pf_get_vf_offset_info fail\n");
+ return -EFAULT;
+ }
+
+ *global_func_id = (u16)((vf_bus - pf_bus) * BUS_MAX_DEV_NUM) + (u16)pdev->devfn +
+ (u16)(CMD_MAX_MAX_PF_NUM - g_vf_offset.vf_offset_from_pf[0]);
+
+ return 0;
+}
+EXPORT_SYMBOL(hinic3_get_vfid_by_vfpci);
+
+static void hinic3_set_vf_status_in_host(struct pci_dev *pdev, bool status)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ void *ppf_hwdev = NULL;
+ u16 global_func_id;
+ int ret;
+
+ if (!pf_pdev)
+ return;
+
+ if (!hinic3_pdev_is_virtfn(pdev))
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ pf_hwdev = pci_adapter->hwdev;
+ ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(pf_pdev);
+ if (!pf_hwdev || !ppf_hwdev)
+ return;
+
+ ret = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (ret) {
+ sdk_err(&pci_adapter->pcidev->dev,
+ "Func hinic3_get_vfid_by_vfpci fail %d\n", ret);
+ return;
+ }
+
+ ret = hinic3_set_func_probe_in_host(ppf_hwdev, global_func_id, status);
+ if (ret)
+ sdk_err(&pci_adapter->pcidev->dev,
+ "Set the function probe status in host failed\n");
+}
+
+#ifdef CONFIG_PCI_IOV
+/* Check whether pdev is a VF and whether it belongs to the PF of the SDI card */
+static bool check_pdev_type_and_state(struct pci_dev *pdev)
+{
+ if (!(pdev->is_virtfn))
+ return false;
+
+ if ((hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_1_PF) &&
+ (hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_0_PF)) {
+ return false;
+ }
+
+ if (!hinic3_get_vf_load_state(pdev))
+ return false;
+
+ return true;
+}
+#endif
+
static void hinic3_remove(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
+ sdk_info(&pdev->dev, "Pcie device remove begin\n");
+
if (!pci_adapter)
- return;
+ goto out;
- sdk_info(&pdev->dev, "Pcie device remove begin\n");
+
+#ifdef CONFIG_PCI_IOV
+ if (check_pdev_type_and_state(pdev))
+ goto out;
+#endif
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
hinic3_remove_func(pci_adapter);
+ if (!pci_adapter->pcidev->is_virtfn &&
+ pci_adapter->multi_host_mgmt_workq)
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
hinic3_pci_deinit(pdev);
hinic3_probe_pre_unprocess(pdev);
+out:
+ hinic3_set_vf_status_in_host(pdev, false);
sdk_info(&pdev->dev, "Pcie device removed\n");
}
@@ -969,7 +1705,7 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
if (pci_adapter->lld_state >= HINIC3_PROBE_START) {
sdk_warn(&pdev->dev, "Don not probe repeat\n");
mutex_unlock(&pci_adapter->pdev_mutex);
- return 0;
+ return -EEXIST;
}
pci_adapter->lld_state = HINIC3_PROBE_START;
mutex_unlock(&pci_adapter->pdev_mutex);
@@ -977,15 +1713,28 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
return 0;
}
+static void hinic3_probe_success_process(struct hinic3_pcidev *pci_adapter)
+{
+ hinic3_probe_success(pci_adapter->hwdev);
+
+ mutex_lock(&pci_adapter->pdev_mutex);
+ pci_adapter->lld_state = HINIC3_PROBE_OK;
+ mutex_unlock(&pci_adapter->pdev_mutex);
+}
+
static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
int err;
err = probe_func_param_init(pci_adapter);
- if (err)
+ if (err == -EEXIST)
+ return 0;
+ else if (err)
return err;
+ set_vf_func_in_use(pdev, true);
+
err = mapping_bar(pdev, pci_adapter);
if (err) {
sdk_err(&pdev->dev, "Failed to map bar\n");
@@ -1017,11 +1766,7 @@ static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
}
}
- hinic3_probe_success(pci_adapter->hwdev);
-
- mutex_lock(&pci_adapter->pdev_mutex);
- pci_adapter->lld_state = HINIC3_PROBE_OK;
- mutex_unlock(&pci_adapter->pdev_mutex);
+ hinic3_probe_success_process(pci_adapter);
return 0;
@@ -1037,18 +1782,298 @@ alloc_chip_node_fail:
unmapping_bar(pci_adapter);
map_bar_failed:
+ set_vf_func_in_use(pdev, false);
sdk_err(&pdev->dev, "Pcie device probe function failed\n");
return err;
}
+void hinic3_set_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int err;
+ bool enable_func = false;
+
+ err = hinic3_get_function_enable(pdev, &enable_func);
+ if (err) {
+ sdk_info(&pdev->dev, "Get function enable failed\n");
+ return;
+ }
+
+ sdk_info(&pdev->dev, "%s function resource start\n",
+ enable_func ? "Initialize" : "Free");
+ if (enable_func) {
+ err = hinic3_probe_func(pci_adapter);
+ if (err)
+ sdk_info(&pdev->dev, "Function probe failed\n");
+ } else {
+ hinic3_remove_func(pci_adapter);
+ }
+ if (err == 0)
+ sdk_info(&pdev->dev, "%s function resource end\n",
+ enable_func ? "Initialize" : "Free");
+}
+
+void slave_host_mgmt_work(struct work_struct *work)
+{
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_nic_work);
+
+ if (hinic3_pdev_is_virtfn(pci_adapter->pcidev))
+ hinic3_set_func_state(pci_adapter);
+ else
+ set_nic_func_state(pci_adapter);
+}
+
+static int pci_adapter_assign_val(struct hinic3_pcidev **ppci_adapter,
+ struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ *ppci_adapter = pci_get_drvdata(pdev);
+ (*ppci_adapter)->disable_vf_load = disable_vf_load;
+ (*ppci_adapter)->id = *id;
+ (*ppci_adapter)->lld_state = HINIC3_NOT_PROBE;
+ (*ppci_adapter)->probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ lld_dev_cnt_init(*ppci_adapter);
+
+ (*ppci_adapter)->multi_host_mgmt_workq = alloc_workqueue(
+ "hinic_mhost_mgmt",
+ WQ_UNBOUND,
+ HINIC3_SLAVE_WORK_MAX_NUM);
+ if (!(*ppci_adapter)->multi_host_mgmt_workq) {
+ hinic3_pci_deinit(pdev);
+ sdk_err(&pdev->dev, "Alloc multi host mgmt workqueue failed\n");
+ return -ENOMEM;
+ }
+
+ INIT_WORK(&(*ppci_adapter)->slave_nic_work, slave_host_mgmt_work);
+ INIT_WORK(&(*ppci_adapter)->slave_vroce_work,
+ slave_host_mgmt_vroce_work);
+
+ return 0;
+}
+
+static void slave_host_vfio_probe_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_pcidev *pci_adapter = container_of(delay, struct hinic3_pcidev,
+ migration_probe_dwork);
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int (*dev_migration_probe)(struct pci_dev *pdev);
+ int rc;
+
+ if (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) != TYPE_PF)
+ return;
+
+ dev_migration_probe = __symbol_get("migration_dev_migration_probe");
+ if (!(dev_migration_probe)) {
+ sdk_err(&pdev->dev,
+ "Failed to find: migration_dev_migration_probe");
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork,
+ WAIT_TIME * HZ);
+ } else {
+ rc = dev_migration_probe(pdev);
+ __symbol_put("migration_dev_migration_probe");
+ if (rc) {
+ sdk_err(&pdev->dev,
+ "Failed to __dev_migration_probe, rc:0x%x, pf migrated(%d).\n",
+ rc, g_is_pf_migrated);
+ } else {
+ g_is_pf_migrated = true;
+ sdk_info(&pdev->dev,
+ "Succeeded in __dev_migration_probe, pf migrated(%d).\n",
+ g_is_pf_migrated);
+ }
+ }
+}
+
+struct vf_add_delaywork {
+ struct pci_dev *vf_pdev;
+ struct delayed_work migration_vf_add_dwork;
+};
+
+static void slave_host_migration_vf_add_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct vf_add_delaywork *vf_add = container_of(delay, struct vf_add_delaywork,
+ migration_vf_add_dwork);
+ struct pci_dev *vf_pdev = vf_add->vf_pdev;
+ struct pci_dev *pf_pdev = NULL;
+ int (*migration_dev_add_vf)(struct pci_dev *vf_pdev);
+ int ret;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!vf_pdev) {
+ pr_err("vf pdev is null.\n");
+ goto err1;
+ }
+ if (!vf_pdev->is_virtfn) {
+ sdk_err(&vf_pdev->dev, "Pdev is not virtfn.\n");
+ goto err1;
+ }
+
+ pf_pdev = vf_pdev->physfn;
+ if (!pf_pdev) {
+ sdk_err(&vf_pdev->dev, "pf_pdev is null.\n");
+ goto err1;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&vf_pdev->dev, "Pci_adapter is null.\n");
+ goto err1;
+ }
+
+ if (!g_is_pf_migrated) {
+ sdk_info(&vf_pdev->dev, "pf is not migrated yet, so vf continues to try again.\n");
+ goto delay_work;
+ }
+
+ migration_dev_add_vf = __symbol_get("migration_dev_add_vf");
+ if (migration_dev_add_vf) {
+ ret = migration_dev_add_vf(vf_pdev);
+ __symbol_put("migration_dev_add_vf");
+ if (ret)
+ sdk_err(&vf_pdev->dev, "vf get migration symbol succeeded, but dev add vf failed, ret:%d.\n",
+ ret);
+ else
+ sdk_info(&vf_pdev->dev, "vf get migration symbol succeeded, and dev add vf success.\n");
+ goto err1;
+ }
+ sdk_info(&vf_pdev->dev, "pf is migrated, but vf get migration symbol failed.\n");
+
+delay_work:
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork, WAIT_TIME * HZ);
+ return;
+
+err1:
+ kfree(vf_add);
+}
+
+static void hinic3_probe_vf_add_dwork(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!hinic3_is_host_vmsec_enable(pdev))
+ return;
+
+#if defined(CONFIG_SP_VID_DID)
+ if ((pdev->vendor == PCI_VENDOR_ID_SPNIC) && (pdev->device == HINIC3_DEV_SDI_5_1_ID_VF)) {
+#elif defined(CONFIG_NF_VID_DID)
+ if ((pdev->vendor == PCI_VENDOR_ID_NF) && (pdev->device == NFNIC_DEV_ID_VF)) {
+#else
+ if ((pdev->vendor == PCI_VENDOR_ID_HUAWEI) && (pdev->device == HINIC3_DEV_SDI_5_0_ID_VF)) {
+#endif
+ struct vf_add_delaywork *vf_add = kmalloc(sizeof(struct vf_add_delaywork),
+ GFP_ATOMIC);
+
+ if (!vf_add) {
+ sdk_info(&pdev->dev, "vf_add is null.\n");
+ return;
+ }
+ vf_add->vf_pdev = pdev;
+
+ pf_pdev = pdev->physfn;
+
+ if (!pf_pdev) {
+ sdk_info(&pdev->dev, "Vf-pf_pdev is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_info(&pdev->dev, "Pci_adapter is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ INIT_DELAYED_WORK(&vf_add->migration_vf_add_dwork,
+ slave_host_migration_vf_add_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork,
+ WAIT_TIME * HZ);
+ }
+}
+
+static int hinic3_probe_migration_dwork(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+{
+ if (!hinic3_is_host_vmsec_enable(pdev)) {
+ sdk_info(&pdev->dev, "Probe_migration : hinic3_is_host_vmsec_enable is (0).\n");
+ return 0;
+ }
+
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF) {
+ pci_adapter->migration_probe_workq =
+ create_singlethread_workqueue("hinic3_migration_probe_delay");
+ if (!pci_adapter->migration_probe_workq) {
+ sdk_err(&pdev->dev, "Failed to create work queue:%s\n",
+ "hinic3_migration_probe_delay");
+ return -EINVAL;
+ }
+
+ INIT_DELAYED_WORK(&pci_adapter->migration_probe_dwork,
+ slave_host_vfio_probe_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork, WAIT_TIME * HZ);
+ }
+
+ return 0;
+}
+
+static bool hinic3_os_hot_replace_allow(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_hwdev *hwdev = (struct hinic3_hwdev *)pci_adapter->hwdev;
+ // check service enable and dev is not VF
+ if (hinic3_func_type(hwdev) == TYPE_VF || hwdev->hot_replace_mode == HOT_REPLACE_DISABLE)
+ return false;
+
+ return true;
+}
+
+static bool hinic3_os_hot_replace_process(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_board_info *board_info;
+ u16 cur_pf_id = hinic3_global_func_id(pci_adapter->hwdev);
+ u8 cur_partion_id;
+
+ board_info = &((struct hinic3_hwdev *)(pci_adapter->hwdev))->board_info;
+ // probe to os
+ vpci_set_partition_attrs(pci_adapter->pcidev, PARTITION_DEV_EXCLUSIVE,
+ get_function_partition(cur_pf_id, board_info->port_num));
+
+ // check pf_id is in the right partition_id
+ cur_partion_id = get_partition_id();
+ if (get_function_partition(cur_pf_id, board_info->port_num) ==
+ cur_partion_id)
+ return true;
+
+ pci_adapter->probe_fault_level = FAULT_LEVEL_SUGGESTION;
+ return false;
+}
+
static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct hinic3_pcidev *pci_adapter = NULL;
u16 probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ u32 device_id, function_id;
int err;
sdk_info(&pdev->dev, "Pcie device probe begin\n");
+#ifdef CONFIG_PCI_IOV
+ hinic3_set_vf_status_in_host(pdev, true);
+ if (check_pdev_type_and_state(pdev)) {
+ sdk_info(&pdev->dev, "VFs are not binded to hinic\n");
+ hinic3_probe_vf_add_dwork(pdev);
+ return -EINVAL;
+ }
+#endif
+
err = hinic3_probe_pre_process(pdev);
if (err != 0 && err != HINIC3_NOT_PROBE)
goto out;
@@ -1060,26 +2085,48 @@ static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (err)
goto pci_init_err;
- pci_adapter = pci_get_drvdata(pdev);
- pci_adapter->disable_vf_load = disable_vf_load;
- pci_adapter->id = *id;
- pci_adapter->lld_state = HINIC3_NOT_PROBE;
- pci_adapter->probe_fault_level = probe_fault_level;
- lld_dev_cnt_init(pci_adapter);
+ err = pci_adapter_assign_val(&pci_adapter, pdev, id);
+ if (err)
+ goto allco_queue_err;
- if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev))) {
+ if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev)) &&
+ (!hinic3_get_vf_nic_en_status(pdev))) {
sdk_info(&pdev->dev, "VF device disable load in host\n");
return 0;
}
- err = hinic3_probe_func(pci_adapter);
- if (err)
+ if (hinic3_probe_func(pci_adapter))
+ goto hinic3_probe_func_fail;
+
+ if (hinic3_os_hot_replace_allow(pci_adapter)) {
+ if (!hinic3_os_hot_replace_process(pci_adapter)) {
+ device_id = PCI_SLOT(pdev->devfn);
+ function_id = PCI_FUNC(pdev->devfn);
+ sdk_info(&pdev->dev,
+ "os hot replace: skip function %d:%d for partition %d",
+ device_id, function_id, get_partition_id());
+ goto os_hot_repalce_not_allow;
+ }
+ }
+
+ if (hinic3_probe_migration_dwork(pdev, pci_adapter))
goto hinic3_probe_func_fail;
sdk_info(&pdev->dev, "Pcie device probed\n");
return 0;
+os_hot_repalce_not_allow:
+ hinic3_func_deinit(pdev);
+ lld_lock_chip_node();
+ free_chip_node(pci_adapter);
+ lld_unlock_chip_node();
+ unmapping_bar(pci_adapter);
+ set_vf_func_in_use(pdev, false);
hinic3_probe_func_fail:
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
+allco_queue_err:
probe_fault_level = pci_adapter->probe_fault_level;
hinic3_pci_deinit(pdev);
@@ -1105,6 +2152,11 @@ static int hinic3_get_pf_info(struct pci_dev *pdev, u16 service,
}
*pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (*pf_infos == NULL) {
+ sdk_err(&pdev->dev, "pf_infos kzalloc failed\n");
+ return -EFAULT;
+ }
+
err = hinic3_get_hw_pf_infos(dev->hwdev, *pf_infos, HINIC3_CHANNEL_COMM);
if (err) {
kfree(*pf_infos);
@@ -1120,6 +2172,7 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
{
int err;
+ mutex_lock(&dst_dev->pdev_mutex);
/* unload invalid vf func id */
if (!en && vf_func_id != hinic3_global_func_id(dst_dev->hwdev) &&
!strcmp(des_pdev->driver->name, HINIC3_DRV_NAME)) {
@@ -1137,6 +2190,8 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
err = hinic3_probe_func(dst_dev);
if (err)
return -EFAULT;
+ } else {
+ mutex_unlock(&dst_dev->pdev_mutex);
}
return 0;
@@ -1161,7 +2216,6 @@ static int get_vf_service_state_param(struct pci_dev *pdev, struct hinic3_pcidev
return 0;
}
-#define BUS_MAX_DEV_NUM 256
static int hinic3_dst_pdev_valid(struct hinic3_pcidev *dst_dev, struct pci_dev **des_pdev_ptr,
u16 vf_devfn, bool en)
{
@@ -1175,7 +2229,7 @@ static int hinic3_dst_pdev_valid(struct hinic3_pcidev *dst_dev, struct pci_dev
return -EFAULT;
}
- if (!(*des_pdev_ptr)->driver) {
+ if ((*des_pdev_ptr)->driver == NULL) {
pr_err("des_pdev_ptr->driver is NULL\n");
return -EFAULT;
}
@@ -1243,7 +2297,6 @@ int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id, u16 servic
if (en)
pci_dev_put(des_pdev);
- mutex_lock(&dst_dev->pdev_mutex);
find_dst_dev = true;
break;
}
@@ -1263,19 +2316,30 @@ free_pf_info:
}
EXPORT_SYMBOL(hinic3_set_vf_service_state);
-/*lint -save -e133 -e10*/
static const struct pci_device_id hinic3_pci_table[] = {
+#if defined(CONFIG_SP_VID_DID)
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_STANDARD), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_SDI_5_1_PF), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_SDI_5_0_PF), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_SPN120), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_ID_VF), 0},
+ {PCI_VDEVICE(SPNIC, HINIC3_DEV_SDI_5_1_ID_VF), 0},
+#elif defined(CONFIG_NF_VID_DID)
+ {PCI_VDEVICE(NF, NFNIC_DEV_ID_STANDARD), 0},
+ {PCI_VDEVICE(NF, NFNIC_DEV_ID_VF), 0},
+#else
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SPU), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_STANDARD), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_1_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_SDI_5_1_ID_VF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_VF), 0},
+#endif
{0, 0}
};
-/*lint -restore*/
-
MODULE_DEVICE_TABLE(pci, hinic3_pci_table);
/**
@@ -1307,14 +2371,27 @@ static pci_ers_result_t hinic3_io_error_detected(struct pci_dev *pdev,
return PCI_ERS_RESULT_CAN_RECOVER;
}
+static void hinic3_timer_disable(void *hwdev)
+{
+ if (!hwdev)
+ return;
+
+ if (hinic3_get_stateful_enable(hwdev) && hinic3_get_timer_enable(hwdev))
+ (void)hinic3_func_tmr_bitmap_set(hwdev,
+ hinic3_global_func_id(hwdev),
+ false);
+}
+
static void hinic3_shutdown(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
sdk_info(&pdev->dev, "Shutdown device\n");
- if (pci_adapter)
+ if (pci_adapter) {
+ hinic3_timer_disable(pci_adapter->hwdev);
hinic3_shutdown_hwdev(pci_adapter->hwdev);
+ }
pci_disable_device(pdev);
@@ -1341,6 +2418,9 @@ static struct pci_driver hinic3_driver = {
.probe = hinic3_probe,
.remove = hinic3_remove,
.shutdown = hinic3_shutdown,
+#ifdef CONFIG_PARTITION_DEVICE
+ .driver.probe_concurrency = true,
+#endif
#if defined(HAVE_SRIOV_CONFIGURE)
.sriov_configure = hinic3_pci_sriov_configure,
#elif defined(HAVE_RHEL6_SRIOV_CONFIGURE)
@@ -1362,16 +2442,21 @@ int hinic3_lld_init(void)
err = hinic3_module_pre_init();
if (err) {
pr_err("Init custom failed\n");
- return err;
+ goto module_pre_init_err;
}
err = pci_register_driver(&hinic3_driver);
if (err) {
- hinic3_module_post_exit();
- return err;
+ pr_err("sdk3 pci register driver failed\n");
+ goto register_pci_driver_err;
}
return 0;
+
+register_pci_driver_err:
+ hinic3_module_post_exit();
+module_pre_init_err:
+ return err;
}
void hinic3_lld_exit(void)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
index b2851c6..3626262 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
@@ -584,6 +584,7 @@ static void free_recv_mbox(struct hinic3_recv_mbox *recv_msg)
kfree(recv_msg->resp_buff);
kfree(recv_msg->msg);
kfree(recv_msg);
+ recv_msg = NULL;
}
static void recv_func_mbox_work_handler(struct work_struct *work)
@@ -1232,6 +1233,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
set_mbox_to_func_event(func_to_func, EVENT_FAIL);
goto send_err;
}
+ func_to_func->hwdev->mbox_send_cnt++;
if (wait_mbox_msg_completion(func_to_func, timeout) != 0) {
sdk_err(func_to_func->hwdev->dev_hdl,
@@ -1240,6 +1242,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
err = -ETIMEDOUT;
goto send_err;
}
+ func_to_func->hwdev->mbox_ack_cnt++;
if (mod != msg_desc->mod || cmd != msg_desc->cmd) {
sdk_err(func_to_func->hwdev->dev_hdl,
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
index 2bd63f1..4718458 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
@@ -861,6 +861,7 @@ static int alloc_recv_msg(struct hinic3_recv_msg *recv_msg)
static void free_recv_msg(struct hinic3_recv_msg *recv_msg)
{
kfree(recv_msg->msg);
+ recv_msg->msg = NULL;
}
/**
@@ -932,6 +933,9 @@ static void free_msg_buf(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt)
free_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
+ pf_to_mgmt->mgmt_ack_buf = NULL;
+ pf_to_mgmt->sync_msg_buf = NULL;
+ pf_to_mgmt->async_msg_buf = NULL;
}
/**
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
index 3548410..a0f5e73 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
@@ -676,6 +676,9 @@ static int hinic3_register_slave_ppf(struct hinic3_hwdev *hwdev, bool registered
if (!IS_SLAVE_HOST(hwdev))
return -EINVAL;
+ if (UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev))
+ return 0;
+
host_info = kcalloc(1, sizeof(struct register_slave_host), GFP_KERNEL);
if (!host_info)
return -ENOMEM;
@@ -1075,7 +1078,8 @@ int hinic3_get_func_nic_enable(void *hwdev, u16 glb_func_idx, bool *en)
return -EINVAL;
/* if single host, return true. */
- if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev)) {
+ if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev) ||
+ UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev)) {
*en = true;
return 0;
}
@@ -1145,11 +1149,21 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
{
int err;
struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+ int is_use_vram, is_in_kexec;
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
- hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0) {
+ snprintf(hwdev->mhost_mgmt_name, VRAM_NAME_MAX_LEN, "%s",
+ VRAM_NIC_MHOST_MGMT);
+ hwdev->mhost_mgmt = hi_vram_kalloc(hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ } else {
+ hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ }
+
if (!hwdev->mhost_mgmt)
return -ENOMEM;
@@ -1165,8 +1179,11 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK, hwdev, hilink_ppf_mbox_handler);
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC, hwdev, sw_func_ppf_mbox_handler);
- bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
- bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ }
/* Slave host:
* register slave host ppf functions
@@ -1179,7 +1196,11 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
return 0;
out_free_mhost_mgmt:
- kfree(hwdev->mhost_mgmt);
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)hwdev->mhost_mgmt, hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ else
+ kfree(hwdev->mhost_mgmt);
hwdev->mhost_mgmt = NULL;
return err;
@@ -1187,6 +1208,8 @@ out_free_mhost_mgmt:
int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
{
+ int is_use_vram;
+
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
@@ -1203,7 +1226,13 @@ int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC);
- kfree(hwdev->mhost_mgmt);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)hwdev->mhost_mgmt, hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ else
+ kfree(hwdev->mhost_mgmt);
+
hwdev->mhost_mgmt = NULL;
return 0;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
index 5e4804a..a0340d9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
@@ -17,14 +17,13 @@
#include "hinic3_hwdev.h"
#include "hinic3_lld.h"
#include "hinic3_hw_mt.h"
+#include "hinic3_dev_mgmt.h"
#include "hinic3_nictool.h"
static int g_nictool_ref_cnt;
static dev_t g_dev_id = {0};
-/*lint -save -e104 -e808*/
static struct class *g_nictool_class;
-/*lint -restore*/
static struct cdev g_nictool_cdev;
#define HINIC3_MAX_BUF_SIZE (2048 * 1024)
@@ -92,6 +91,23 @@ static int get_all_chip_id_cmd(struct hinic3_lld_dev *lld_dev, const void *buf_i
return 0;
}
+#ifndef __HIFC__
+static int get_os_hot_replace_info(struct hinic3_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ if (*out_size != sizeof(struct os_hot_replace_info) || !buf_out) {
+ pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
+ *out_size, sizeof(struct os_hot_replace_info));
+ return -EFAULT;
+ }
+
+ hinic3_get_os_hot_replace_info(buf_out);
+
+ return 0;
+}
+#endif
+
static int get_card_usr_api_chain_mem(int card_idx)
{
unsigned char *tmp = NULL;
@@ -166,7 +182,7 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
if (!buf_out || *out_size != sizeof(struct pf_dev_info) * PF_DEV_INFO_NUM) {
pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
- *out_size, sizeof(dev_info) * PF_DEV_INFO_NUM);
+ *out_size, sizeof(*dev_info) * PF_DEV_INFO_NUM);
return -EFAULT;
}
@@ -193,13 +209,18 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
return 0;
}
-static long dbgtool_knl_free_mem(int id)
+static void dbgtool_knl_free_mem(int id)
{
unsigned char *tmp = NULL;
int i;
+ if (id < 0 || id >= MAX_CARD_NUM) {
+ pr_err("Invalid card id\n");
+ return;
+ }
+
if (!g_card_vir_addr[id])
- return 0;
+ return;
tmp = g_card_vir_addr[id];
for (i = 0; i < (1 << DBGTOOL_PAGE_ORDER); i++) {
@@ -211,7 +232,6 @@ static long dbgtool_knl_free_mem(int id)
g_card_vir_addr[id] = NULL;
g_card_phy_addr[id] = 0;
- return 0;
}
static int free_knl_mem(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_size,
@@ -337,7 +357,6 @@ static int get_hw_drv_version(struct hinic3_lld_dev *lld_dev, const void *buf_in
void *buf_out, u32 *out_size)
{
struct drv_version_info *ver_info = buf_out;
- int err;
if (!buf_out) {
pr_err("Buf_out is NULL.\n");
@@ -350,10 +369,8 @@ static int get_hw_drv_version(struct hinic3_lld_dev *lld_dev, const void *buf_in
return -EINVAL;
}
- err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s", HINIC3_DRV_VERSION,
- "2023-05-17_19:56:38");
- if (err < 0)
- return -EINVAL;
+ snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s", HINIC3_DRV_VERSION,
+ "2025-05-08_00:00:08");
return 0;
}
@@ -386,6 +403,22 @@ static int get_pf_id(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_
return 0;
}
+#ifndef __HIFC__
+/* not support fc yet */
+static int get_mbox_cnt(struct hinic3_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ if (buf_out == NULL || *out_size != sizeof(struct card_mbox_cnt_info)) {
+ pr_err("buf_out is NULL, or out_size != %lu\n", sizeof(struct card_info));
+ return -EINVAL;
+ }
+
+ hinic3_get_mbox_cnt(hinic3_get_sdk_hwdev_by_lld(lld_dev), buf_out);
+
+ return 0;
+}
+#endif
+
struct hw_drv_module_handle hw_driv_module_cmd_handle[] = {
{FUNC_TYPE, get_func_type},
{GET_FUNC_IDX, get_func_id},
@@ -402,6 +435,10 @@ struct hw_drv_module_handle hw_driv_module_cmd_handle[] = {
{GET_FUNC_CAP, get_pf_cap_info},
{GET_DRV_VERSION, get_hw_drv_version},
{GET_PF_ID, get_pf_id},
+#ifndef __HIFC__
+ {GET_OS_HOT_REPLACE_INFO, get_os_hot_replace_info},
+ {GET_MBOX_CNT, (hw_driv_module)get_mbox_cnt},
+#endif
};
static int alloc_tmp_buf(void *hwdev, struct msg_module *nt_msg, u32 in_size,
@@ -439,8 +476,8 @@ static void free_tmp_buf(void *hwdev, struct msg_module *nt_msg,
static int send_to_hw_driver(struct hinic3_lld_dev *lld_dev, struct msg_module *nt_msg,
const void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(hw_driv_module_cmd_handle) /
- sizeof(hw_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(hw_driv_module_cmd_handle) /
+ sizeof(hw_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type =
(enum driver_cmd_type)(nt_msg->msg_formate);
int err = 0;
@@ -482,8 +519,8 @@ static int send_to_service_driver(struct hinic3_lld_dev *lld_dev, struct msg_mod
if (nt_msg->msg_formate == GET_DRV_VERSION)
return 0;
- pr_err("Can not get the uld dev correctly: %s, %s driver may be not register\n",
- nt_msg->device_name, service_name[type]);
+ pr_err("Can not get the uld dev correctly: %s driver may be not register\n",
+ service_name[type]);
return -EINVAL;
}
@@ -566,8 +603,8 @@ static struct hinic3_lld_dev *get_lld_dev_by_nt_msg(struct msg_module *nt_msg)
} else {
lld_dev = hinic3_get_lld_dev_by_chip_name(nt_msg->device_name);
if (!lld_dev)
- lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
- SERVICE_T_MAX);
+ lld_dev = hinic3_get_lld_dev_by_dev_name(
+ nt_msg->device_name, SERVICE_T_MAX);
}
return lld_dev;
@@ -597,8 +634,10 @@ static long hinicadm_k_unlocked_ioctl(struct file *pfile, unsigned long arg)
return -ENODEV;
}
- if (nt_msg.msg_formate == DEV_NAME_TEST)
+ if (nt_msg.msg_formate == DEV_NAME_TEST) {
+ lld_dev_put(lld_dev);
return 0;
+ }
ret = alloc_tmp_buf(hinic3_get_sdk_hwdev_by_lld(lld_dev), &nt_msg,
in_size, &buf_in, out_size_expect, &buf_out);
@@ -642,6 +681,9 @@ out_free_lock:
static long dbgtool_knl_ffm_info_rd(struct dbgtool_param *para,
struct dbgtool_k_glb_info *dbgtool_info)
{
+ if (!para->param.ffm_rd || !dbgtool_info->ffm)
+ return -EINVAL;
+
/* Copy the ffm_info to user mode */
if (copy_to_user(para->param.ffm_rd, dbgtool_info->ffm,
(unsigned int)sizeof(struct ffm_record_info))) {
@@ -674,13 +716,14 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
card_info = (struct card_node *)g_card_node_array[i];
if (!card_info)
continue;
- if (!strncmp(param.chip_name, card_info->chip_name, IFNAMSIZ))
+ if (memcmp(param.chip_name, card_info->chip_name,
+ strlen(card_info->chip_name) + 1) == 0)
break;
}
if (i == MAX_CARD_NUM || !card_info) {
lld_put();
- pr_err("Can't find this card %s\n", param.chip_name);
+ pr_err("Can't find this card.\n");
return -EFAULT;
}
@@ -697,10 +740,10 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
pr_err("Not suppose to use this cmd(0x%x).\n", real_cmd);
ret = 0;
break;
-
default:
pr_err("Dbgtool cmd(0x%x) not support now\n", real_cmd);
ret = -EFAULT;
+ break;
}
up(&dbgtool_info->dbgtool_sem);
@@ -746,9 +789,11 @@ static long nictool_k_unlocked_ioctl(struct file *pfile,
static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
{
+ pgprot_t vm_page_prot;
unsigned long vmsize = vma->vm_end - vma->vm_start;
phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
phys_addr_t phy_addr;
+ int err = 0;
if (vmsize > (PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER))) {
pr_err("Map size = %lu is bigger than alloc\n", vmsize);
@@ -758,13 +803,18 @@ static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
/* old version of tool set vma->vm_pgoff to 0 */
phy_addr = offset ? offset : g_card_phy_addr[card_id];
- if (!phy_addr) {
- pr_err("Card_id = %d physical address is 0\n", card_id);
- return -EAGAIN;
+ /* check phy_addr valid */
+ if (phy_addr != g_card_phy_addr[card_id]) {
+ err = hinic3_bar_mmap_param_valid(phy_addr, vmsize);
+ if (err != 0) {
+ pr_err("mmap param invalid, err: %d\n", err);
+ return err;
+ }
}
/* Disable cache and write buffer in the mapping area */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_page_prot = vm_page_prot;
if (remap_pfn_range(vma, vma->vm_start, (phy_addr >> PAGE_SHIFT),
vmsize, vma->vm_page_prot)) {
pr_err("Remap pfn range failed.\n");
@@ -787,7 +837,6 @@ static const struct file_operations fifo_operations = {
static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
{
struct dbgtool_k_glb_info *dbgtool_info = NULL;
- int err, id;
if (hinic3_func_type(hwdev) != TYPE_VF)
chip_info->func_handle_array[hinic3_global_func_id(hwdev)] = NULL;
@@ -795,23 +844,22 @@ static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
if (--chip_info->func_num)
return;
- err = sscanf(chip_info->chip_name, HINIC3_CHIP_NAME "%d", &id);
- if (err < 0)
- pr_err("Failed to get card id\n");
-
- if (id < MAX_CARD_NUM)
- g_card_node_array[id] = NULL;
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ g_card_node_array[chip_info->chip_id] = NULL;
dbgtool_info = chip_info->dbgtool_info;
/* FFM deinit */
- kfree(dbgtool_info->ffm);
- dbgtool_info->ffm = NULL;
+ if (dbgtool_info && dbgtool_info->ffm) {
+ kfree(dbgtool_info->ffm);
+ dbgtool_info->ffm = NULL;
+ }
kfree(dbgtool_info);
+
chip_info->dbgtool_info = NULL;
- if (id < MAX_CARD_NUM)
- (void)dbgtool_knl_free_mem(id);
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ dbgtool_knl_free_mem(chip_info->chip_id);
}
static int alloc_dbgtool_info(void *hwdev, struct card_node *chip_info)
@@ -872,7 +920,7 @@ dbgtool_info_fail:
* nictool_k_init - initialize the hw interface
**/
/* temp for dbgtool_info */
-/*lint -e438*/
+
int nictool_k_init(void *hwdev, void *chip_node)
{
struct card_node *chip_info = (struct card_node *)chip_node;
@@ -895,9 +943,7 @@ int nictool_k_init(void *hwdev, void *chip_node)
}
/* Create equipment */
- /*lint -save -e160*/
g_nictool_class = class_create(HIADM3_DEV_CLASS);
- /*lint -restore*/
if (IS_ERR(g_nictool_class)) {
pr_err("Create nictool_class fail\n");
err = -EFAULT;
@@ -944,7 +990,7 @@ alloc_chdev_fail:
free_dbgtool_info(hwdev, chip_info);
return err;
-} /*lint +e438*/
+}
void nictool_k_uninit(void *hwdev, void *chip_node)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
index f368133..c943dfc 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
@@ -18,6 +18,8 @@
int nictool_k_init(void *hwdev, void *chip_node);
void nictool_k_uninit(void *hwdev, void *chip_node);
+void hinic3_get_os_hot_replace_info(void *oshr_info);
+
void hinic3_get_all_chip_id(void *id_info);
void hinic3_get_card_func_info_by_card_name
@@ -29,6 +31,8 @@ bool hinic3_is_in_host(void);
int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *isvalid);
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin);
+
extern struct hinic3_uld_info g_uld_info[SERVICE_T_MAX];
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
index 2d5423e..e961ef7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
@@ -19,6 +19,20 @@
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
+#elif defined(CONFIG_NF_VID_DID)
+#define PCI_VENDOR_ID_NF 0x2036
+#define NFNIC_DEV_ID_STANDARD 0x1618
+#define NFNIC_DEV_ID_SDI_5_1_PF 0x0226
+#define NFNIC_DEV_ID_SDI_5_0_PF 0x0225
+#define NFNIC_DEV_ID_DPU_PF 0x0224
+#define NFNIC_DEV_ID_VF 0x1619
+#define NFNIC_DEV_ID_VF_HV 0x379F
+#define NFNIC_DEV_SDI_5_1_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_0_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_1_ID_VF_HV 0x379F
+#define NFNIC_DEV_ID_SPU 0xAC00
+#define NFNIC_DEV_SDI_5_1_SSDID_VF 0x1000
+#define NFNIC_DEV_SDI_V100_SSDID_MASK (3 << 12)
#else
#define PCI_VENDOR_ID_HUAWEI 0x19e5
#define HINIC3_DEV_ID_STANDARD 0x0222
@@ -28,16 +42,33 @@
#define HINIC3_DEV_ID_VF 0x375F
#define HINIC3_DEV_ID_VF_HV 0x379F
#define HINIC3_DEV_SDI_5_1_ID_VF 0x375F
+#define HINIC3_DEV_SDI_5_0_ID_VF 0x375F
#define HINIC3_DEV_SDI_5_1_ID_VF_HV 0x379F
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
#endif
+#define NFNIC_DEV_SSID_2X25G_NF 0x0860
+#define NFNIC_DEV_SSID_4X25G_NF 0x0861
+#define NFNIC_DEV_SSID_2x100G_NF 0x0862
+#define NFNIC_DEV_SSID_2x200G_NF 0x0863
+
+#define HINIC3_DEV_SSID_2X10G 0x0035
#define HINIC3_DEV_SSID_2X25G 0x0051
#define HINIC3_DEV_SSID_4X25G 0x0052
+#define HINIC3_DEV_SSID_4X25G_BD 0x0252
+#define HINIC3_DEV_SSID_4X25G_SMARTNIC 0x0152
+#define HINIC3_DEV_SSID_6X25G_VL 0x0356
#define HINIC3_DEV_SSID_2X100G 0x00A1
+#define HINIC3_DEV_SSID_2X100G_SMARTNIC 0x01A1
+#define HINIC3_DEV_SSID_2X200G 0x04B1
#define HINIC3_DEV_SSID_2X100G_VF 0x1000
+#define HINIC3_DEV_SSID_HPC_4_HOST_NIC 0x005A
+#define HINIC3_DEV_SSID_2X200G_VL 0x00B1
+#define HINIC3_DEV_SSID_1X100G 0x02A4
+
+#define BIFUR_RESOURCE_PF_SSID 0x05a1
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
index b23b69f..056397f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
@@ -52,7 +52,7 @@ static int hinic3_deinit_vf_hw(void *hwdev, u16 start_vf_id, u16 end_vf_id)
}
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
-ssize_t hinic3_sriov_totalvfs_show(struct device *dev,
+ssize_t sriov_totalvfs_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
@@ -60,7 +60,7 @@ ssize_t hinic3_sriov_totalvfs_show(struct device *dev,
return sprintf(buf, "%d\n", pci_sriov_get_totalvfs(pdev));
}
-ssize_t hinic3_sriov_numvfs_show(struct device *dev,
+ssize_t sriov_numvfs_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
@@ -68,8 +68,7 @@ ssize_t hinic3_sriov_numvfs_show(struct device *dev,
return sprintf(buf, "%d\n", pci_num_vf(pdev));
}
-/*lint -save -e713*/
-ssize_t hinic3_sriov_numvfs_store(struct device *dev,
+ssize_t sriov_numvfs_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
@@ -116,7 +115,6 @@ ssize_t hinic3_sriov_numvfs_store(struct device *dev,
return count;
}
-/*lint -restore*/
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
int hinic3_pci_sriov_disable(struct pci_dev *dev)
@@ -174,24 +172,15 @@ int hinic3_pci_sriov_disable(struct pci_dev *dev)
return 0;
}
-int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
-{
#ifdef CONFIG_PCI_IOV
- struct hinic3_sriov_info *sriov_info = NULL;
- struct hinic3_event_info event = {0};
- void *hwdev = NULL;
- int pre_existing_vfs = 0;
- int err = 0;
-
- sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
- hwdev = hinic3_get_hwdev_by_pcidev(dev);
- if (!hwdev) {
- sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
- return -EPERM;
- }
+int hinic3_pci_sriov_check(struct hinic3_sriov_info *sriov_info, struct pci_dev *dev, int num_vfs)
+{
+ int pre_existing_vfs;
+ int err;
if (test_and_set_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state)) {
- sdk_err(&dev->dev, "SR-IOV enable in process, please wait, num_vfs %d\n",
+ sdk_err(&dev->dev,
+ "SR-IOV enable in process, please wait, num_vfs %d\n",
num_vfs);
return -EPERM;
}
@@ -202,6 +191,7 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
clear_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state);
return -ERANGE;
}
+
if (pre_existing_vfs && pre_existing_vfs != num_vfs) {
err = hinic3_pci_sriov_disable(dev);
if (err) {
@@ -213,6 +203,29 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
return num_vfs;
}
+ return 0;
+}
+#endif
+
+int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
+{
+#ifdef CONFIG_PCI_IOV
+ struct hinic3_sriov_info *sriov_info = NULL;
+ struct hinic3_event_info event = {0};
+ void *hwdev = NULL;
+ int err = 0;
+
+ sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
+ hwdev = hinic3_get_hwdev_by_pcidev(dev);
+ if (!hwdev) {
+ sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
+ return -EPERM;
+ }
+
+ err = hinic3_pci_sriov_check(sriov_info, dev, num_vfs);
+ if (err != 0)
+ return err;
+
err = hinic3_init_vf_hw(hwdev, 1, (u16)num_vfs);
if (err) {
sdk_err(&dev->dev, "Failed to init vf in hardware before enable sriov, error %d\n",
@@ -262,6 +275,3 @@ int hinic3_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
else
return hinic3_pci_sriov_enable(dev, num_vfs);
}
-
-/*lint -restore*/
-
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h
index 4a640ad..20eb728 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.h
@@ -7,11 +7,11 @@
#include <linux/pci.h>
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
-ssize_t hinic3_sriov_totalvfs_show(struct device *dev,
+ssize_t sriov_totalvfs_show(struct device *dev,
struct device_attribute *attr, char *buf);
-ssize_t hinic3_sriov_numvfs_show(struct device *dev,
+ssize_t sriov_numvfs_show(struct device *dev,
struct device_attribute *attr, char *buf);
-ssize_t hinic3_sriov_numvfs_store(struct device *dev,
+ssize_t sriov_numvfs_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count);
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c b/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c
index f8aea696..be83022 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/ossl_knl_linux.c
@@ -117,3 +117,4 @@ u64 ossl_get_real_time(void)
tv_msec = (u64)tv.tv_sec * MSEC_PER_SEC + (u64)tv.tv_usec / USEC_PER_MSEC;
return tv_msec;
}
+
diff --git a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
index 9e8fc75..01ab739 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
@@ -10,6 +10,10 @@
#define OVS_PORT_NUM_MAX BOND_PORT_MAX_NUM
#define DEFAULT_ROCE_BOND_FUNC 0xFFFFFFFF
+#define BOND_ID_IS_VALID(_id) \
+ (((_id) >= BOND_FIRST_ID) && ((_id) <= BOND_MAX_ID))
+#define BOND_ID_IS_INVALID(_id) (!(BOND_ID_IS_VALID(_id)))
+
enum bond_group_id {
BOND_FIRST_ID = 1,
BOND_MAX_ID = 4,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
index e7e16fc..f9737ea 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
@@ -52,6 +52,8 @@ enum scenes_id_define {
SCENES_ID_STORAGE_ROCE = 6,
SCENES_ID_COMPUTE_ROCE = 7,
SCENES_ID_STORAGE_TOE = 8,
+ SCENES_ID_COMPUTE_DPU = 100,
+ SCENES_ID_COMPUTE_SMART_NIC = 101,
SCENES_ID_MAX
};
@@ -122,13 +124,18 @@ struct cfg_cmd_dev_cap {
u8 srv_multi_host_mode;
u8 virtio_vq_size;
- u32 rsvd_func3[5];
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 lro_enable;
+ u8 os_hot_replace;
+
+ u32 rsvd_func3[4];
/* l2nic */
u16 nic_max_sq_id;
u16 nic_max_rq_id;
u16 nic_default_num_queues;
- u16 rsvd1_nic;
+ u16 outband_vlan_cfg_en;
u32 rsvd2_nic[2];
/* RoCE */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
index d9f67e2..6c5b995 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
@@ -37,7 +37,7 @@ static inline void hinic3_cpu_to_be32(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -59,7 +59,7 @@ static inline void hinic3_be32_to_cpu(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -86,52 +86,16 @@ static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
sge->len = (u32)len;
}
-#ifdef HW_CONVERT_ENDIAN
#define hinic3_hw_be32(val) (val)
#define hinic3_hw_cpu32(val) (val)
#define hinic3_hw_cpu16(val) (val)
-#else
-#define hinic3_hw_be32(val) cpu_to_be32(val)
-#define hinic3_hw_cpu32(val) be32_to_cpu(val)
-#define hinic3_hw_cpu16(val) be16_to_cpu(val)
-#endif
static inline void hinic3_hw_be32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_be32(*mem);
- mem++;
- }
-#endif
}
static inline void hinic3_hw_cpu32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_cpu32(*mem);
- mem++;
- }
-#endif
}
int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
@@ -149,6 +113,8 @@ int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
/* func_attr.glb_func_idx, global function index */
u16 hinic3_global_func_id(void *hwdev);
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id);
+
/* func_attr.p2p_idx, belongs to which pf */
u8 hinic3_pf_id_of_vf(void *hwdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
index 9a9bfe2..e36ba1d 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
@@ -219,5 +219,7 @@ void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
const char **hinic3_get_uld_names(void);
+int hinic3_lld_init(void);
+void hinic3_lld_exit(void);
#endif
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
index 97d34f0..4cd6f94 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
@@ -43,6 +43,10 @@ enum mag_cmd {
MAG_CMD_GET_XSFP_PRESENT = 62, /* get xsfp present status @see mag_cmd_get_xsfp_present */
MAG_CMD_SET_XSFP_RW = 63, /* sfp/qsfp single byte read/write, @see mag_cmd_set_xsfp_rw */
MAG_CMD_CFG_XSFP_TEMPERATURE = 64, /* get xsfp temp @see mag_cmd_sfp_temp_out_info */
+ /**< set xsfp tlv info @see struct mag_cmd_set_xsfp_tlv_req */
+ MAG_CMD_SET_XSFP_TLV_INFO = 65,
+ /**< get xsfp tlv info @see struct drv_tag_mag_cmd_get_xsfp_tlv_rsp */
+ MAG_CMD_GET_XSFP_TLV_INFO = 66,
/* Event reported 100-149 */
MAG_CMD_WIRE_EVENT = 100,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
index caaba5d..d33b9f4 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
@@ -31,17 +31,28 @@ enum board_type_define_e {
BOARD_TYPE_STRG_2X100G_ROCE_AA = 42, /* 2X100G SmartIO ROCE_AA Card */
BOARD_TYPE_CAL_2X25G_NIC_75MPPS = 100, /* 2X25G ETH Standard card 75MPPS */
BOARD_TYPE_CAL_2X25G_NIC_40MPPS = 101, /* 2X25G ETH Standard card 40MPPS */
- BOARD_TYPE_CAL_2X100G_DPU = 102, /* 2x100G DPU Card */
+ BOARD_TYPE_CAL_2X100G_DPU_VL = 102, /* 2x100G DPU Card */
BOARD_TYPE_CAL_4X25G_NIC_120MPPS = 105, /* 4X25G ETH Standard card 120MPPS */
BOARD_TYPE_CAL_4X25G_COMSTORAGE = 106, /* 4X25GE compute storage Onboard Card */
BOARD_TYPE_CAL_2X32G_FC_HBA = 110, /* 2X32G FC HBA card */
BOARD_TYPE_CAL_2X16G_FC_HBA = 111, /* 2X16G FC HBA card */
BOARD_TYPE_CAL_2X100G_NIC_120MPPS = 115, /* 2X100G ETH Standard card 120MPPS */
- BOARD_TYPE_CAL_2X25G_DPU = 116, /* 2x25G DPU Card */
- BOARD_TYPE_CAL_4X25G_DPU = 118, /* 4x25G DPU Card */
+ BOARD_TYPE_CAL_2X25G_DPU_BD = 116, /* 2x25G DPU Card */
+ BOARD_TYPE_CAL_2X100G_TCE_BACKPLANE = 117,
+ BOARD_TYPE_CAL_4X25G_DPU_VL = 118, /* 4x25G DPU Card */
+ BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS = 119,
+ BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS = 120,
+ BOARD_TYPE_CAL_6X25G_DPU_VL = 121, /* 6x25G DPU Card */
+ BOARD_TYPE_CAL_4X25G_DPU_BD = 122,
+ BOARD_TYPE_CAL_2X25G_NIC_4HOST = 123,
+ BOARD_TYPE_CAL_2X10G_LOW_POWER = 125,
+ BOARD_TYPE_CAL_2X200G_NIC_INTERNET = 127,
+ BOARD_TYPE_CAL_1X100GR2_OCP = 129, /* 1X100G ETH Standard card */
+ BOARD_TYPE_CAL_2X200G_DPU_VL = 130,
BOARD_TYPE_CLD_2X100G_SDI5_1 = 170, /* 2X100G SDI 5.1 Card */
BOARD_TYPE_CLD_2X25G_SDI5_0_LITE = 171, /* 2x25G SDI5.0 Lite Card */
BOARD_TYPE_CLD_2X100G_SDI5_0 = 172, /* 2x100G SDI5.0 Card */
+ BOARD_TYPE_CLD_4X25G_SDI5_0_C = 175,
BOARD_TYPE_MAX_INDEX = 0xFF
};
@@ -49,23 +60,62 @@ static inline u32 spu_board_type_valid(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
- ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
}
static inline int board_type_is_sdi(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_1) ||
((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
- ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0);
+ ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C);
+}
+
+static inline int board_type_is_dpu_spu(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
}
static inline int board_type_is_dpu(u32 board_type)
{
- return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_6X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
+}
+
+/* 此接口判断是否是分布式存储的标卡以及计算的标卡(含ROCE特性),
+ * 仅用于LLDP TX功能冲突命令字处理的判断
+ */
+static inline int board_type_is_compute(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_75MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_40MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_NIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_COMSTORAGE) ||
+ ((board_type) == BOARD_TYPE_CAL_2X10G_LOW_POWER) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_NIC_INTERNET) ||
+ ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_4HOST) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_NIC_120MPPS);
+}
+
+/* 此接口判断服务器输入reboot网卡是否需要复位 */
+static inline int board_type_is_multi_socket(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP);
}
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
index 291e475..4d4d543 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
@@ -4,8 +4,95 @@
#ifndef MPU_CMD_BASE_DEFS_H
#define MPU_CMD_BASE_DEFS_H
-#include "mgmt_msg_base.h"
-#include "comm_defs.h"
+/** MPU CMD MODULE TYPE */
+enum hinic3_mod_type {
+ HINIC3_MOD_COMM = 0, /* HW communication module */
+ HINIC3_MOD_L2NIC = 1, /* L2NIC module */
+ HINIC3_MOD_ROCE = 2,
+ HINIC3_MOD_PLOG = 3,
+ HINIC3_MOD_TOE = 4,
+ HINIC3_MOD_FLR = 5,
+ HINIC3_MOD_VROCE = 6,
+ HINIC3_MOD_CFGM = 7, /* Configuration management */
+ HINIC3_MOD_CQM = 8,
+ HINIC3_MOD_VMSEC = 9,
+ COMM_MOD_FC = 10,
+ HINIC3_MOD_OVS = 11,
+ HINIC3_MOD_DSW = 12,
+ HINIC3_MOD_MIGRATE = 13,
+ HINIC3_MOD_HILINK = 14,
+ HINIC3_MOD_CRYPT = 15, /* secure crypto module */
+ HINIC3_MOD_VIO = 16,
+ HINIC3_MOD_IMU = 17,
+ HINIC3_MOD_DFX = 18, /* DFX */
+ HINIC3_MOD_HW_MAX = 19, /* hardware max module id */
+ /* Software module id, for PF/VF and multi-host */
+ HINIC3_MOD_SW_FUNC = 20,
+ HINIC3_MOD_MAX,
+};
+
+/* func reset的flag ,用于指示清理哪种资源 */
+enum func_reset_flag_e {
+ RES_TYPE_FLUSH_BIT = 0,
+ RES_TYPE_MQM,
+ RES_TYPE_SMF,
+ RES_TYPE_PF_BW_CFG,
+
+ RES_TYPE_COMM = 10,
+ RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_NIC,
+ RES_TYPE_OVS,
+ RES_TYPE_VBS,
+ RES_TYPE_ROCE,
+ RES_TYPE_FC,
+ RES_TYPE_TOE,
+ RES_TYPE_IPSEC,
+ RES_TYPE_MAX,
+};
+
+#define HINIC3_COMM_RES \
+ ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
+ (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
+ (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
+
+#define HINIC3_NIC_RES (1 << RES_TYPE_NIC)
+#define HINIC3_OVS_RES (1 << RES_TYPE_OVS)
+#define HINIC3_VBS_RES (1 << RES_TYPE_VBS)
+#define HINIC3_ROCE_RES (1 << RES_TYPE_ROCE)
+#define HINIC3_FC_RES (1 << RES_TYPE_FC)
+#define HINIC3_TOE_RES (1 << RES_TYPE_TOE)
+#define HINIC3_IPSEC_RES (1 << RES_TYPE_IPSEC)
+
+/* MODE OVS、NIC、UNKNOWN */
+#define HINIC3_WORK_MODE_OVS 0
+#define HINIC3_WORK_MODE_UNKNOWN 1
+#define HINIC3_WORK_MODE_NIC 2
+
+#define DEVICE_TYPE_L2NIC 0
+#define DEVICE_TYPE_NVME 1
+#define DEVICE_TYPE_VIRTIO_NET 2
+#define DEVICE_TYPE_VIRTIO_BLK 3
+#define DEVICE_TYPE_VIRTIO_VSOCK 4
+#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
+#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
+#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
+#define DEVICE_TYPE_VIRTIO_HPC 8
+#define DEVICE_TYPE_VIRTIO_FS 9
+
+#define IS_STORAGE_DEVICE_TYPE(dev_type) \
+ ((dev_type) == DEVICE_TYPE_VIRTIO_BLK || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_BLK_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_SCSI_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_FS)
+
+#define MGMT_MSG_CMD_OP_SET 1
+#define MGMT_MSG_CMD_OP_GET 0
+
+#define MGMT_MSG_CMD_OP_START 1
+#define MGMT_MSG_CMD_OP_STOP 0
+
+#define HOT_REPLACE_PARTITION_NUM 2
enum hinic3_svc_type {
SVC_T_COMM = 0,
@@ -23,4 +110,54 @@ enum hinic3_svc_type {
SVC_T_MAX,
};
+/**
+ * Common header control information of the COMM message interaction
+ * command word between the driver and PF
+ * struct mgmt_msg_head and struct comm_info_head are the same structure
+ */
+struct mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+/**
+ * Common header control information of the COMM message interaction
+ * command word between the driver and PF
+ */
+struct comm_info_head {
+ /** response status code, 0: success, others: error code */
+ u8 status;
+
+ /** firmware version for command */
+ u8 version;
+
+ /** response aeq number, unused for now */
+ u8 rep_aeq_num;
+ u8 rsvd[5];
+};
+
+static inline u32 get_function_partition(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM;
+}
+
+static inline u32 is_primary_function(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0;
+}
+
+static inline u32 mpu_nic_get_primary_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ function_id : (function_id - port_num);
+}
+
+// when func_id is in partition 0/1, it will get its another func_id in partition 1/0
+static inline u32 mpu_nic_get_backup_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ (function_id + port_num) : (function_id - port_num);
+}
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
index a8e2d63..3841bb5 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
@@ -91,6 +91,10 @@ enum hinic3_mgmt_cmd {
* @see comm_read_ucode_sm_resp
*/
COMM_MGMT_CMD_CLEAR_LOG, /**< clear log @see comm_cmd_clear_log_s */
+ COMM_MGMT_CMD_UCODE_SM_COUNTER_PER,
+ /**< get ucode sm counter @see struct comm_read_ucode_sm_per_req
+ * @see struct comm_read_ucode_sm_per_resp
+ */
COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140, /* check if switch workmode reserved
* @see comm_cmd_check_if_switch_workmode
@@ -103,6 +107,7 @@ enum hinic3_mgmt_cmd {
COMM_MGMT_CMD_CPI_TCAM_DBG, /* enable or disable the scheduled cpi tcam task,
* set task interval time @see comm_cmd_cpi_tcam_dbg_s
*/
+ COMM_MGMT_CMD_LLDP_TX_FUNC_SET,
COMM_MGMT_CMD_SECTION_RSVD_0 = 160, /**< rsvd0 section */
COMM_MGMT_CMD_SECTION_RSVD_1 = 170, /**< rsvd1 section */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
index 674603d..698730f 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
@@ -338,7 +338,8 @@ struct comm_cmd_get_fw_version {
struct mgmt_msg_head head;
u16 fw_type; /**< firmware type @see enum hinic3_fw_ver_type */
- u16 rsvd1;
+ u16 fw_dfx_vld : 1; /**< 0: release, 1: debug */
+ u16 rsvd1 : 15;
u8 ver[HINIC3_FW_VERSION_LEN]; /**< firmware version */
u8 time[HINIC3_FW_COMPILE_TIME_LEN]; /**< firmware compile time */
};
@@ -430,6 +431,22 @@ struct comm_cmd_bdf_info {
u8 rsvd2[5];
};
+struct mpu_pcie_pf_info {
+ u32 device_id; /**< device id */
+ u32 vendor_id; /**< vendor id */
+};
+
+struct mpu_pcie_device_info {
+ u8 status;
+ u8 version;
+ u8 rep_aeq_num;
+ u8 rsvd[5];
+
+ struct mpu_pcie_pf_info pf_info[32];
+ u32 bus_id; /**< bus id */
+ u32 pf_num; /**< pf index */
+};
+
#define TABLE_INDEX_MAX 129
struct sml_table_id_info {
u8 node_id;
@@ -446,6 +463,13 @@ struct comm_cmd_sdi_info {
u32 cfg_sdi_mode; /**< host mode, 0:normal 1:virtual machine 2:bare metal */
};
+struct comm_cmd_root_ctx_load_req {
+ struct comm_info_head head;
+ u32 func_id; /**< function id */
+ u32 smf_id; /**< smf id */
+ u32 queue_id; /**< queue id */
+};
+
#define HINIC_OVS_BOND_DEFAULT_ID 1
struct hinic3_hw_bond_infos {
u8 bond_id;
@@ -685,6 +709,28 @@ struct comm_read_ucode_sm_resp {
u64 val2;
};
+#define PER_REQ_MAX_DATA_LEN 0x600
+
+struct comm_read_ucode_sm_per_req {
+ struct mgmt_msg_head msg_head;
+
+ u32 tbl_type;
+ u32 count_id;
+};
+
+struct comm_read_ucode_sm_per_resp {
+ struct mgmt_msg_head msg_head;
+
+ u8 data[PER_REQ_MAX_DATA_LEN];
+};
+
+struct ucode_sm_counter_get_info {
+ u32 width_type;
+ u32 tbl_type;
+ unsigned int base_count;
+ unsigned int count_num;
+};
+
enum log_type {
MPU_LOG_CLEAR = 0,
SMU_LOG_CLEAR = 1,
@@ -693,6 +739,11 @@ enum log_type {
ALL_LOG_CLEAR = 4,
};
+struct comm_cmd_clear_log {
+ struct comm_info_head head;
+ u32 type; /**< log type @see enum log_type */
+};
+
#define ABLESWITCH 1
#define IMABLESWITCH 2
enum switch_workmode_op {
@@ -717,6 +768,14 @@ struct comm_cmd_check_if_switch_workmode {
u32 rsvd3[3];
};
+struct comm_cmd_switch_workmode {
+ struct mgmt_msg_head head;
+ u8 operation;
+ u8 work_mode;
+ u16 rsvd1[3];
+ u32 rsvd2[3];
+};
+
#define MIG_NOR_VM_ONE_MAX_SGE_MEM (64 * 8)
#define MIG_NOR_VM_ONE_MAX_MEM (MIG_NOR_VM_ONE_MAX_SGE_MEM + 16)
#define MIG_VM_MAX_SML_ENTRY_NUM 24
@@ -755,6 +814,15 @@ struct cmd_get_bdf_info_s {
#define CPI_TCAM_DBG_CMD_TYPE_SET 0
#define CPI_TCAM_DBG_CMD_TYPE_GET 1
+struct comm_cmd_cpi_tcam_dbg {
+ struct comm_info_head head;
+ u8 type;
+ u8 set_bitmap;
+ u8 enable;
+ u8 rsvd;
+ u32 time_interval;
+};
+
#define UDIE_ID_DATA_LEN 8
#define TDIE_ID_DATA_LEN 18
struct comm_cmd_get_die_id {
@@ -808,6 +876,12 @@ struct cmd_query_fw {
u32 len; /**< length */
};
+struct comm_cmd_get_cfg_info_t {
+ struct comm_info_head head;
+ u8 rsvd[8];
+ u8 info[64]; /**< flash config info */
+};
+
struct nic_cmd_get_uart_log_info {
struct comm_info_head head;
struct {
@@ -969,6 +1043,7 @@ enum comm_virtio_dev_type {
COMM_VIRTIO_NET_TYPE = 0,
COMM_VIRTIO_BLK_TYPE = 1,
COMM_VIRTIO_SCSI_TYPE = 4,
+ COMM_VIRTIO_FS_TYPE = 5,
};
struct comm_virtio_dev_cmd {
@@ -1030,6 +1105,13 @@ struct cmd_patch_sram_optimize {
u32 data[4]; /**< reserved */
};
+struct comm_cmd_con_sel_sta {
+ struct comm_info_head head;
+ u8 valid;
+ u8 host_id; /**< host id, range[0,3] */
+ u8 rsvd[2];
+};
+
/* ncsi counter */
struct nsci_counter_in_info_s {
struct comm_info_head head;
@@ -1082,7 +1164,9 @@ struct comm_cmd_ncsi_settings {
u8 lldp_over_ncsi_enable;
u8 lldp_over_mctp_enable;
u32 magicwd;
- u8 rsvd[8];
+ u8 lldp_tx_enable;
+ u8 rsvd[3];
+ u32 crc;
struct tag_ncsi_chan_info ncsi_chan_info;
};
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
index fde8617..1ee44a8 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
@@ -114,6 +114,14 @@ struct tag_ncsi_client_info {
#define AEN_CTRL_CONFIG_REQ_SHIFT 1
#define AEN_CTRL_DRV_CHANGE_SHIFT 2
+/* AEN Type */
+enum aen_type_e {
+ AEN_LINK_STATUS_CHANGE_TYPE = 0x0,
+ AEN_CONFIG_REQUIRED_TYPE = 0x1,
+ OEM_AEN_CONFIG_REQUEST_TYPE = 0x80,
+ AEN_TYPE_MAX = 0x100
+};
+
/* get link status 0x0A */
#define GET_LINK_STATUS_REQ_LEN 0
#define GET_LINK_STATUS_RSP_LEN 16
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
index 0bd168c..5b2bdc8 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
@@ -36,6 +36,7 @@ enum nic_rss_hash_type {
#define NIC_RX_MODE_BC 0x04
#define NIC_RX_MODE_MC_ALL 0x08
#define NIC_RX_MODE_PROMISC 0x10
+#define NIC_RX_DB_COS_MAX 0x4
/* IEEE 802.1Qaz std */
#define NIC_DCB_COS_MAX 0x8
@@ -52,4 +53,7 @@ enum nic_rss_hash_type {
#define NIC_DCB_PRIO_STRICT 0x1
#define NIC_DCB_MAX_PFC_NUM 0x4
+
+#define NIC_ETS_PERCENT_WEIGHT 100
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
index 801aeed..5476287 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
@@ -23,7 +23,11 @@
#define VRAM_CQM_BITMAP_BASE "B"
#define VRAM_NIC_DCB "DCB"
+#define VRAM_NIC_MHOST_MGMT "MHOST_MGMT"
#define VRAM_NIC_VRAM "NIC_VRAM"
+#define VRAM_NIC_IRQ_VRAM "NIC_IRQ"
+
+#define VRAM_NIC_MQM "NM"
#define VRAM_VBS_BASE_IOCB "BASE_IOCB"
#define VRAM_VBS_EX_IOCB "EX_IOCB"
@@ -32,6 +36,9 @@
#define VRAM_VBS_VOLQ_MTT "VOLQ_MTT"
#define VRAM_VBS_VOLQ_MTT_PAGE "MTT_PAGE"
+#define VRAM_OVS_PORT_CONF "OVS_PORT_CONF"
+#define VRAM_OVS_DFX_MGR "OVS_DFX_MGR"
+
#define VRAM_VROCE_ENTRY_POOL "VROCE_ENTRY"
#define VRAM_VROCE_GROUP_POOL "VROCE_GROUP"
#define VRAM_VROCE_UUID "VROCE_UUID"
@@ -42,6 +49,17 @@
#define VRAM_VROCE_DEV "VROCE_DEV"
#define VRAM_VROCE_RGROUP_HT_CNT "RGROUP_CNT"
#define VRAM_VROCE_RACL_HT_CNT "RACL_CNT"
+#define VRAM_VROCE_MQM_ENQC "VROCE_MQM_ENQC"
+
+#define VRAM_DTOE_NUMA_MEM "DTOE_NUMA"
+#define VRAM_DTOE_CARD_MEM "DTOE_CARD"
+#define VRAM_DTOE_CONN_MEM "DTOE_CONN"
+#define VRAM_DTOE_SUB_LEN 10
+
+#define VRAM_VROCE_MIG_ENTRY_POOL "VROCE_MIG_ENTRY"
+#define VRAM_VROCE_MIG_ENTRY_HT_CNT "MIG_ENTRY_CNT"
+
+#define VRAM_VBS_DEV_INDEX "VBS_INDEX"
#define VRAM_NAME_APPLY_LEN 64
@@ -55,11 +73,16 @@ enum KUP_HOOK_POINT {
PRE_FREEZE,
FREEZE_TO_KILL,
PRE_UPDATE_KERNEL,
- FLUSH_DURING_KUP,
POST_UPDATE_KERNEL,
UNFREEZE_TO_RUN,
POST_RUN,
KUP_HOOK_MAX,
};
+#define hi_vram_kalloc(name, size) 0
+#define hi_vram_kfree(vaddr, name, size)
+#define get_use_vram_flag(void) 0
+#define vram_get_kexec_flag(void) 0
+#define hi_vram_get_gfp_vram(void) 0
+
#endif /* VRAM_COMMON_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
similarity index 79%
rename from drivers/net/ethernet/huawei/hinic3/mag_cmd.h
rename to drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
index 9649503..ead8e69 100644
--- a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
@@ -9,6 +9,7 @@
/* serdes cmd struct define */
#define CMD_ARRAY_BUF_SIZE 64
#define SERDES_CMD_DATA_BUF_SIZE 512
+#define RATE_MBPS_TO_GBPS 1000
struct serdes_in_info {
u32 chip_id : 16;
u32 macro_id : 16;
@@ -127,6 +128,7 @@ enum mag_cmd_cnt_type {
MAG_RX_PCS_E_BLK_CNT = 5,
MAG_RX_PCS_DEC_ERR_BLK_CNT = 6,
MAG_RX_PCS_LANE_BIP_ERR_CNT = 7,
+ MAG_RX_RSFEC_ERR_CW_CNT = 8,
MAG_CNT_NUM
};
@@ -208,7 +210,9 @@ struct mag_cmd_get_port_info {
u32 supported_mode;
u32 advertised_mode;
- u8 rsvd2[8];
+ u32 supported_fec_mode;
+ u16 bond_speed;
+ u8 rsvd2[2];
};
#define MAG_CMD_OPCODE_GET 0
@@ -330,8 +334,8 @@ struct mag_cmd_cfg_fec_mode {
u8 port_id;
u8 opcode; /* 0:get fec mode 1:set fec mode */
- u8 fec;
- u8 rsvd0;
+ u8 advertised_fec;
+ u8 supported_fec;
};
/* speed */
@@ -641,7 +645,7 @@ struct mag_cmd_event_port_info {
u32 cable_length; /* 1/3/5m */
u8 cable_temp; /* temp */
u8 max_speed; /* Maximum rate of an optical module */
- u8 sfp_type; /* sfp/qsfp */
+ u8 sfp_type; /* sfp/qsfp/dsfp */
u8 rsvd1;
u32 power[4]; /* Optical Power */
@@ -678,6 +682,10 @@ struct mag_cmd_event_port_info {
u8 rsvd3[360];
};
+struct mag_cmd_rsfec_stats {
+ u32 rx_err_lane_phy;
+};
+
struct mag_cmd_port_stats {
u64 mac_tx_fragment_pkt_num;
u64 mac_tx_undersize_pkt_num;
@@ -913,10 +921,223 @@ struct mag_cmd_sfp_temp_in_info {
};
struct mag_cmd_sfp_temp_out_info {
- struct mgmt_msg_head head; /* 8B */
- s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
- s32 max_temp; /* Chip optical module threshold */
- s32 min_temp; /* Chip optical module threshold */
+ struct mgmt_msg_head head; /* 8B */
+ s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
+ s32 max_temp; /* Chip optical module threshold */
+ s32 min_temp; /* Chip optical module threshold */
+};
+
+#define XSFP_CMIS_PARSE_PAGE_NUM 6
+#define XSFP_CMIS_INFO_MAX_SIZE 1536
+#define QSFP_CMIS_PAGE_SIZE 128
+#define QSFP_CMIS_MAX_CHANNEL_NUM 0x8
+
+/* Lower: Control and Essentials, Upper: Administrative Information */
+#define QSFP_CMIS_PAGE_00H 0x00
+/* Advertising */
+#define QSFP_CMIS_PAGE_01H 0x01
+/* Module and lane Thresholds */
+#define QSFP_CMIS_PAGE_02H 0x02
+/* User EEPROM */
+#define QSFP_CMIS_PAGE_03H 0x03
+/* Laser Capabilities Advertising (Page 04h, Optional) */
+#define QSFP_CMIS_PAGE_04H 0x04
+#define QSFP_CMIS_PAGE_05H 0x05
+/* Lane and Data Path Control */
+#define QSFP_CMIS_PAGE_10H 0x10
+/* Lane Status */
+#define QSFP_CMIS_PAGE_11H 0x11
+#define QSFP_CMIS_PAGE_12H 0x12
+
+#define MGMT_TLV_U8_SIZE 1
+#define MGMT_TLV_U16_SIZE 2
+#define MGMT_TLV_U32_SIZE 4
+
+#define MGMT_TLV_GET_U8(addr) (*((u8 *)(void *)(addr)))
+#define MGMT_TLV_SET_U8(addr, value) \
+ ((*((u8 *)(void *)(addr))) = ((u8)(value)))
+
+#define MGMT_TLV_GET_U16(addr) (*((u16 *)(void *)(addr)))
+#define MGMT_TLV_SET_U16(addr, value) \
+ ((*((u16 *)(void *)(addr))) = ((u16)(value)))
+
+#define MGMT_TLV_GET_U32(addr) (*((u32 *)(void *)(addr)))
+#define MGMT_TLV_SET_U32(addr, value) \
+ ((*((u32 *)(void *)(addr))) = ((u32)(value)))
+
+#define MGMT_TLV_TYPE_END 0xFFFF
+
+enum mag_xsfp_type {
+ MAG_XSFP_TYPE_PAGE = 0x01,
+ MAG_XSFP_TYPE_WIRE_TYPE = 0x02,
+ MAG_XSFP_TYPE_END = MGMT_TLV_TYPE_END
+};
+
+struct qsfp_cmis_lower_page_00_s {
+ u8 resv0[14];
+ u8 temperature_msb;
+ u8 temperature_lsb;
+ u8 volt_supply[2];
+ u8 resv1[67];
+ u8 media_type;
+ u8 electrical_interface_id;
+ u8 media_interface_id;
+ u8 lane_count;
+ u8 resv2[39];
+};
+
+struct qsfp_cmis_upper_page_00_s {
+ u8 identifier;
+ u8 vendor_name[16];
+ u8 vendor_oui[3];
+ u8 vendor_pn[16];
+ u8 vendor_rev[2];
+ u8 vendor_sn[16];
+ u8 date_code[8];
+ u8 clei_code[10];
+ u8 power_character[2];
+ u8 cable_len;
+ u8 connector;
+ u8 copper_cable_attenuation[6];
+ u8 near_end_implementation;
+ u8 far_end_config;
+ u8 media_technology;
+ u8 resv0[43];
+};
+
+struct qsfp_cmis_upper_page_01_s {
+ u8 firmware_rev[2];
+ u8 hardware_rev[2];
+ u8 smf_len_km;
+ u8 om5_len;
+ u8 om4_len;
+ u8 om3_len;
+ u8 om2_len;
+ u8 resv0;
+ u8 wavelength[2];
+ u8 wavelength_tolerance[2];
+ u8 pages_implement;
+ u8 resv1[16];
+ u8 monitor_implement[2];
+ u8 resv2[95];
+};
+
+struct qsfp_cmis_upper_page_02_s {
+ u8 temperature_high_alarm[2];
+ u8 temperature_low_alarm[2];
+ u8 temperature_high_warn[2];
+ u8 temperature_low_warn[2];
+ u8 volt_high_alarm[2];
+ u8 volt_low_alarm[2];
+ u8 volt_high_warn[2];
+ u8 volt_low_warn[2];
+ u8 resv0[32];
+ u8 tx_power_high_alarm[2];
+ u8 tx_power_low_alarm[2];
+ u8 tx_power_high_warn[2];
+ u8 tx_power_low_warn[2];
+ u8 tx_bias_high_alarm[2];
+ u8 tx_bias_low_alarm[2];
+ u8 tx_bias_high_warn[2];
+ u8 tx_bias_low_warn[2];
+ u8 rx_power_high_alarm[2];
+ u8 rx_power_low_alarm[2];
+ u8 rx_power_high_warn[2];
+ u8 rx_power_low_warn[2];
+ u8 resv1[56];
+};
+
+struct qsfp_cmis_upper_page_03_s {
+ u8 resv0[QSFP_CMIS_PAGE_SIZE]; /* Reg 128-255: Upper Memory: Page 03H */
+};
+
+struct qsfp_cmis_upper_page_10_s {
+ u8 resv0[2]; /* Reg 128-129: Upper Memory: Page 10H */
+ u8 tx_disable; /* Reg 130: Tx disable, 0b=enabled, 1b=disabled */
+ u8 resv1[125]; /* Reg 131-255 */
+};
+
+struct qsfp_cmis_upper_page_11_s {
+ u8 resv0[7];
+ u8 tx_fault;
+ u8 tx_los;
+ u8 resv1[10];
+ u8 rx_los;
+ u8 resv2[6];
+ u8 tx_power[16];
+ u8 tx_bias[16];
+ u8 rx_power[16];
+ u8 resv3[54];
+};
+
+struct qsfp_cmis_info_s {
+ struct qsfp_cmis_lower_page_00_s lower_page_00;
+ struct qsfp_cmis_upper_page_00_s upper_page_00;
+ struct qsfp_cmis_upper_page_01_s upper_page_01;
+ struct qsfp_cmis_upper_page_02_s upper_page_02;
+ struct qsfp_cmis_upper_page_10_s upper_page_10;
+ struct qsfp_cmis_upper_page_11_s upper_page_11;
+};
+
+struct qsfp_cmis_comm_power_s {
+ u32 chl_power[QSFP_CMIS_MAX_CHANNEL_NUM];
+};
+
+struct qsfp_cmis_wire_info_s {
+ struct qsfp_cmis_comm_power_s rx_power;
+ u8 rx_los;
+ u8 resv0[3];
+};
+
+struct mgmt_tlv_info {
+ u16 type;
+ u16 length;
+ u8 value[];
+};
+
+struct mag_cmd_set_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 tlv_buf[];
+};
+
+struct mag_cmd_set_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+};
+
+struct tag_mag_cmd_get_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd;
+ u16 rsp_buf_len;
+};
+
+struct mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[];
+};
+
+
+struct parse_tlv_info {
+ u8 tlv_page_info[XSFP_CMIS_INFO_MAX_SIZE + 1];
+ u32 tlv_page_info_len;
+ u32 tlv_page_num[XSFP_CMIS_PARSE_PAGE_NUM];
+ u32 wire_type;
+ u8 id;
+};
+
+struct drv_tag_mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[XSFP_CMIS_INFO_MAX_SIZE];
};
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h b/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
deleted file mode 100644
index 257bf67..0000000
--- a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : mgmt_msg_base.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef MGMT_MSG_BASE_H
-#define MGMT_MSG_BASE_H
-
-#define MGMT_MSG_CMD_OP_SET 1
-#define MGMT_MSG_CMD_OP_GET 0
-
-#define MGMT_MSG_CMD_OP_START 1
-#define MGMT_MSG_CMD_OP_STOP 0
-
-struct mgmt_msg_head {
- u8 status;
- u8 version;
- u8 rsvd0[6];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
deleted file mode 100644
index abcfa27..0000000
--- a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2001-2021, Huawei Tech. Co., Ltd.
- * File Name : nic_cfg_comm.h
- * Version : Initial Draft
- * Description : nic config common header file
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef NIC_CFG_COMM_H
-#define NIC_CFG_COMM_H
-
-#include <linux/types.h>
-
-/* rss */
-#define HINIC3_RSS_TYPE_VALID_SHIFT 23
-#define HINIC3_RSS_TYPE_TCP_IPV6_EXT_SHIFT 24
-#define HINIC3_RSS_TYPE_IPV6_EXT_SHIFT 25
-#define HINIC3_RSS_TYPE_TCP_IPV6_SHIFT 26
-#define HINIC3_RSS_TYPE_IPV6_SHIFT 27
-#define HINIC3_RSS_TYPE_TCP_IPV4_SHIFT 28
-#define HINIC3_RSS_TYPE_IPV4_SHIFT 29
-#define HINIC3_RSS_TYPE_UDP_IPV6_SHIFT 30
-#define HINIC3_RSS_TYPE_UDP_IPV4_SHIFT 31
-
-#define HINIC3_RSS_TYPE_SET(val, member) (((u32)(val) & 0x1) << HINIC3_RSS_TYPE_##member##_SHIFT)
-#define HINIC3_RSS_TYPE_GET(val, member) (((u32)(val) >> HINIC3_RSS_TYPE_##member##_SHIFT) & 0x1)
-
-enum nic_rss_hash_type {
- NIC_RSS_HASH_TYPE_XOR = 0,
- NIC_RSS_HASH_TYPE_TOEP,
-
- NIC_RSS_HASH_TYPE_MAX /* MUST BE THE LAST ONE */
-};
-
-#define NIC_RSS_INDIR_SIZE 256
-#define NIC_RSS_KEY_SIZE 40
-
-/* *
- * Definition of the NIC receiving mode
- */
-#define NIC_RX_MODE_UC 0x01
-#define NIC_RX_MODE_MC 0x02
-#define NIC_RX_MODE_BC 0x04
-#define NIC_RX_MODE_MC_ALL 0x08
-#define NIC_RX_MODE_PROMISC 0x10
-
-/* IEEE 802.1Qaz std */
-#define NIC_DCB_COS_MAX 0x8
-#define NIC_DCB_UP_MAX 0x8
-#define NIC_DCB_TC_MAX 0x8
-#define NIC_DCB_PG_MAX 0x8
-#define NIC_DCB_TSA_SP 0x0
-#define NIC_DCB_TSA_CBS 0x1
-#define NIC_DCB_TSA_ETS 0x2
-#define NIC_DCB_DSCP_NUM 0x8
-#define NIC_DCB_IP_PRI_MAX 0x40
-
-#define NIC_DCB_PRIO_DWRR 0x0
-#define NIC_DCB_PRIO_STRICT 0x1
-
-#define NIC_DCB_MAX_PFC_NUM 0x4
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
similarity index 77%
rename from drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
rename to drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
index c35bc82..a228522 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
- * File Name : hinic3_comm_cmd.h
+ * File Name : hinic3_nic_mpu_cmd.h
* Version : Initial Draft
* Created : 2019/4/25
* Last Modified :
@@ -33,10 +33,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_CFG_LOCAL_LRO_STATE,
HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
+ HINIC3_NIC_CMD_SET_FUNC_ER_FWD_ID,
HINIC3_NIC_CMD_SET_RQ_CI_CTX,
- /* MAC & VLAN CFG */
+ /* MAC & VLAN CFG & VXLAN CFG */
HINIC3_NIC_CMD_GET_MAC = 20,
HINIC3_NIC_CMD_SET_MAC,
HINIC3_NIC_CMD_DEL_MAC,
@@ -47,6 +48,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_VLAN_FILTER_EN,
HINIC3_NIC_CMD_SET_RX_VLAN_OFFLOAD,
HINIC3_NIC_CMD_SMAC_CHECK_STATE,
+ HINIC3_NIC_CMD_OUTBAND_SET_FUNC_VLAN,
+ HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+
+ HINIC3_NIC_CMD_RX_RATE_CFG,
+ HINIC3_NIC_CMD_WR_ORDERING_CFG,
/* SR-IOV */
HINIC3_NIC_CMD_CFG_VF_VLAN = 40,
@@ -63,6 +69,7 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC,
/* IP checksum error packets, enable rss quadruple hash */
HINIC3_NIC_CMD_IPCS_ERR_RSS_ENABLE_OP = 66,
+ HINIC3_NIC_CMD_GTP_INNER_PARSE_STATUS,
/* PPA/FDIR */
HINIC3_NIC_CMD_ADD_TC_FLOW = 80,
@@ -78,6 +85,10 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_CFG_PPA_FLUSH,
HINIC3_NIC_CMD_SET_FDIR_STATUS,
HINIC3_NIC_CMD_GET_PPA_COUNTER,
+ HINIC3_NIC_CMD_SET_FUNC_FLOW_BIFUR_ENABLE,
+ HINIC3_NIC_CMD_SET_BOND_MASK,
+ HINIC3_NIC_CMD_GET_BLOCK_TC_FLOWS,
+ HINIC3_NIC_CMD_GET_BOND_MASK,
/* PORT CFG */
HINIC3_NIC_CMD_SET_PORT_ENABLE = 100,
@@ -96,6 +107,8 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_QOS_PORT_CFG,
HINIC3_NIC_CMD_QOS_MAP_CFG,
HINIC3_NIC_CMD_FORCE_PKT_DROP,
+ HINIC3_NIC_CMD_CFG_TX_PROMISC_SKIP = 114,
+ HINIC3_NIC_CMD_SET_PORT_FLOW_BIFUR_ENABLE = 117,
HINIC3_NIC_CMD_TX_PAUSE_EXCP_NOTICE = 118,
HINIC3_NIC_CMD_INQUIRT_PAUSE_CFG = 119,
@@ -118,6 +131,11 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_SET_UCAPTURE_OPT = 160, /* TODO: move to roce */
HINIC3_NIC_CMD_SET_VHD_CFG,
+ /* OUT OF BAND */
+ HINIC3_NIC_CMD_GET_OUTBAND_CFG = 170, /* Get outband vlan cfg info */
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE, /* Outband vlan cfg info report */
+
+
/* TODO: move to HILINK */
HINIC3_NIC_CMD_GET_PORT_STAT = 200,
HINIC3_NIC_CMD_CLEAN_PORT_STAT,
@@ -138,24 +156,23 @@ enum hinic3_nic_cmd {
HINIC3_NIC_CMD_LINK_ERR_EVENT,
HINIC3_NIC_CMD_SET_LED_STATUS,
- HINIC3_NIC_CMD_MAX = 256,
-};
+ /* mig */
+ HINIC3_NIC_CMD_MIG_SET_CEQ_CTRL = 230,
+ HINIC3_NIC_CMD_MIG_CFG_MSIX_INFO,
+ HINIC3_NIC_CMD_MIG_CFG_FUNC_VAT_TBL,
+ HINIC3_NIC_CMD_MIG_GET_VF_INFO,
+ HINIC3_NIC_CMD_MIG_CHK_MBX_EMPTY,
+ HINIC3_NIC_CMD_MIG_SET_VPORT_ENABLE,
+ HINIC3_NIC_CMD_MIG_CFG_SQ_CI,
+ HINIC3_NIC_CMD_MIG_CFG_RSS_TBL,
+ HINIC3_NIC_CMD_MIG_CFG_MAC_TBL,
+ HINIC3_NIC_CMD_MIG_TMP_SET_CMDQ_CTX,
+
+ HINIC3_OSHR_CMD_ACTIVE_FUNCTION = 240,
-/* NIC CMDQ MODE */
-enum hinic3_ucode_cmd {
- HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
- HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
- HINIC3_UCODE_CMD_ARM_SQ,
- HINIC3_UCODE_CMD_ARM_RQ,
- HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_SET_IQ_ENABLE,
- HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
- HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
- HINIC3_UCODE_CMD_PPA_HASH_TABLE,
- HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_NIC_CMD_GET_RQ_INFO = 241,
+
+ HINIC3_NIC_CMD_MAX = 256,
};
#endif /* HINIC3_NIC_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
similarity index 86%
rename from drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h
rename to drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
index 18a85f4..5c28573 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
@@ -20,6 +20,10 @@
#define NIC_TCAM_BLOCK_LARGE_NUM 256
#define NIC_TCAM_BLOCK_LARGE_SIZE 16
+#define TRAFFIC_BIFUR_MODEL_TYPE 2
+
+#define NIC_TCAM_FLOW_BIFUR_FLAG (1 << 0)
+
#ifndef BIT
#define BIT(n) (1UL << (n))
#endif
@@ -106,6 +110,7 @@ struct hinic3_port_state {
#define HINIC3_SET_PORT_CAR_PROFILE 0
#define HINIC3_SET_PORT_CAR_STATE 1
+#define HINIC3_GET_PORT_CAR_LIMIT_SPEED 2
struct hinic3_port_car_info {
u32 cir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
@@ -120,7 +125,7 @@ struct hinic3_cmd_set_port_car {
u8 port_id;
u8 opcode; /* 0--set car profile, 1--set car state */
u8 state; /* 0--disable, 1--enable */
- u8 rsvd;
+ u8 level;
struct hinic3_port_car_info car;
};
@@ -371,6 +376,14 @@ struct hinic3_cmd_local_lro_state {
u8 state; /* 0: disable, 1: enable */
};
+struct hinic3_cmd_gtp_inner_parse_status {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 status; /* 0: disable, 1: enable */
+};
+
struct hinic3_cmd_vf_vlan_config {
struct hinic3_mgmt_msg_head msg_head;
@@ -394,7 +407,8 @@ struct hinic3_cmd_tx_rate_cfg {
struct hinic3_mgmt_msg_head msg_head;
u16 func_id;
- u16 rsvd1;
+ u8 rsvd1;
+ u8 direct;
u32 min_rate;
u32 max_rate;
u8 rsvd2[8];
@@ -437,8 +451,22 @@ struct hinic3_cmd_vlan_config {
u16 func_id;
u8 opcode;
- u8 rsvd1;
+ u8 outband_defvid_flag;
u16 vlan_id;
+ u8 blacklist_flag;
+ u8 rsvd2;
+};
+
+#define VLAN_BLACKLIST_ENABLE 1
+#define VLAN_BLACKLIST_DISABLE 0
+
+struct hinic3_cmd_vxlan_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 cfg_mode;
+ u16 vxlan_port;
u16 rsvd2;
};
@@ -587,6 +615,7 @@ struct hinic3_up_ets_cfg { /* delet */
#define CMD_QOS_ETS_COS_PRIO BIT(2)
#define CMD_QOS_ETS_COS_BW BIT(3)
#define CMD_QOS_ETS_TC_PRIO BIT(4)
+#define CMD_QOS_ETS_TC_RATELIMIT BIT(5)
struct hinic3_cmd_ets_cfg {
struct hinic3_mgmt_msg_head head;
@@ -601,6 +630,7 @@ struct hinic3_cmd_ets_cfg {
u8 cos_prio[NIC_DCB_COS_MAX]; /* 0 - DWRR, 1 - STRICT */
u8 cos_bw[NIC_DCB_COS_MAX];
u8 tc_prio[NIC_DCB_TC_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 rate_limit[NIC_DCB_TC_MAX];
};
struct hinic3_cmd_set_dcb_state {
@@ -687,6 +717,8 @@ struct nic_cmd_pause_inquiry_cfg {
u32 type; /* 1: set, 2: get */
+ u32 cos_id;
+
u32 rx_inquiry_pause_drop_pkts_en;
u32 rx_inquiry_pause_period_ms;
u32 rx_inquiry_pause_times;
@@ -699,7 +731,7 @@ struct nic_cmd_pause_inquiry_cfg {
u32 tx_inquiry_pause_times; /* tx pause Default Times Period 5 */
u32 tx_inquiry_pause_frame_thd; /* tx pause Detection Threshold */
u32 tx_inquiry_rx_total_pkts;
- u32 rsvd[4];
+ u32 rsvd[3];
};
/* pfc/pause Storm TX exception reporting */
@@ -924,7 +956,9 @@ struct nic_cmd_fdir_get_block_rules {
};
struct hinic3_tcam_key_ipv4_mem {
- u32 rsvd1 : 4;
+ u32 rsvd1 : 1;
+ u32 bifur_flag : 2;
+ u32 model : 1;
u32 tunnel_type : 4;
u32 ip_proto : 8;
u32 rsvd0 : 16;
@@ -956,14 +990,16 @@ union hinic3_tag_tcam_ext_info {
u32 id : 16; /* id */
u32 type : 4; /* type: 0-func, 1-vmdq, 2-port, 3-rsvd, 4-trunk, 5-dp, 6-mc */
u32 host_id : 3;
- u32 rsv : 8;
+ u32 rss_q_num : 8; /* rss queue num */
u32 ext : 1;
} bs;
u32 value;
};
struct hinic3_tcam_key_ipv6_mem {
- u32 rsvd1 : 4;
+ u32 bifur_flag : 2;
+ u32 vlan_flag : 1;
+ u32 outer_ip_type : 1;
u32 tunnel_type : 4;
u32 ip_proto : 8;
u32 rsvd0 : 16;
@@ -1065,7 +1101,7 @@ struct hinic3_ppa_cfg_ppa_en_cmd {
u16 func_id;
u8 ppa_en;
- u8 rsvd;
+ u8 ppa_miss_drop_en;
};
struct hinic3_func_flow_bifur_en_cmd {
@@ -1079,7 +1115,8 @@ struct hinic3_port_flow_bifur_en_cmd {
struct hinic3_mgmt_msg_head msg_head;
u16 port_id;
u8 flow_bifur_en;
- u8 rsvd[5];
+ u8 flow_bifur_type; /* 0->vf bifur, 2->traffic bifur */
+ u8 rsvd[4];
};
struct hinic3_bond_mask_cmd {
@@ -1146,53 +1183,88 @@ enum {
NIC_NVM_DATA_VLAN_PRI = BIT(3),
NIC_NVM_DATA_VLAN_ID = BIT(4),
NIC_NVM_DATA_WORK_MODE = BIT(5),
- NIC_NVM_DATA_PF_SPEED_LIMIT = BIT(6),
+ NIC_NVM_DATA_PF_TX_SPEED_LIMIT = BIT(6),
NIC_NVM_DATA_GE_MODE = BIT(7),
NIC_NVM_DATA_AUTO_NEG = BIT(8),
NIC_NVM_DATA_LINK_FEC = BIT(9),
NIC_NVM_DATA_PF_ADAPTIVE_LINK = BIT(10),
NIC_NVM_DATA_SRIOV_CONTROL = BIT(11),
NIC_NVM_DATA_EXTEND_MODE = BIT(12),
+ NIC_NVM_DATA_LEGACY_VLAN = BIT(13),
+ NIC_NVM_DATA_LEGACY_VLAN_PRI = BIT(14),
+ NIC_NVM_DATA_LEGACY_VLAN_ID = BIT(15),
NIC_NVM_DATA_RESET = BIT(31),
};
-#define BIOS_CFG_SIGNATURE 0x1923E518
-#define BIOS_OP_CFG_ALL(op_code_val) ((((op_code_val) >> 1) & (0xFFFFFFFF)) != 0)
-#define BIOS_OP_CFG_WRITE(op_code_val) ((((op_code_val) & NIC_NVM_DATA_SET)) != 0)
-#define BIOS_OP_CFG_PXE_EN(op_code_val) (((op_code_val) & NIC_NVM_DATA_PXE) != 0)
-#define BIOS_OP_CFG_VLAN_EN(op_code_val) (((op_code_val) & NIC_NVM_DATA_VLAN) != 0)
-#define BIOS_OP_CFG_VLAN_PRI(op_code_val) (((op_code_val) & NIC_NVM_DATA_VLAN_PRI) != 0)
-#define BIOS_OP_CFG_VLAN_ID(op_code_val) (((op_code_val) & NIC_NVM_DATA_VLAN_ID) != 0)
-#define BIOS_OP_CFG_WORK_MODE(op_code_val) (((op_code_val) & NIC_NVM_DATA_WORK_MODE) != 0)
-#define BIOS_OP_CFG_PF_BW(op_code_val) (((op_code_val) & NIC_NVM_DATA_PF_SPEED_LIMIT) != 0)
-#define BIOS_OP_CFG_GE_SPEED(op_code_val) (((op_code_val) & NIC_NVM_DATA_GE_MODE) != 0)
-#define BIOS_OP_CFG_AUTO_NEG(op_code_val) (((op_code_val) & NIC_NVM_DATA_AUTO_NEG) != 0)
-#define BIOS_OP_CFG_LINK_FEC(op_code_val) (((op_code_val) & NIC_NVM_DATA_LINK_FEC) != 0)
-#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) (((op_code_val) & NIC_NVM_DATA_PF_ADAPTIVE_LINK) != 0)
-#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val) (((op_code_val) & NIC_NVM_DATA_SRIOV_CONTROL) != 0)
-#define BIOS_OP_CFG_EXTEND_MODE(op_code_val) (((op_code_val) & NIC_NVM_DATA_EXTEND_MODE) != 0)
-#define BIOS_OP_CFG_RST_DEF_SET(op_code_val) (((op_code_val) & (u32)NIC_NVM_DATA_RESET) != 0)
+#define BIOS_CFG_SIGNATURE 0x1923E518
+#define BIOS_OP_CFG_ALL(op_code_val) \
+ ((((op_code_val) >> 1) & (0xFFFFFFFF)) != 0)
+#define BIOS_OP_CFG_WRITE(op_code_val) \
+ ((((op_code_val) & NIC_NVM_DATA_SET)) != 0)
+#define BIOS_OP_CFG_PXE_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PXE) != 0)
+#define BIOS_OP_CFG_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN) != 0)
+#define BIOS_OP_CFG_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_ID) != 0)
+#define BIOS_OP_CFG_WORK_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_WORK_MODE) != 0)
+#define BIOS_OP_CFG_PF_BW(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_TX_SPEED_LIMIT) != 0)
+#define BIOS_OP_CFG_GE_SPEED(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_GE_MODE) != 0)
+#define BIOS_OP_CFG_AUTO_NEG(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_AUTO_NEG) != 0)
+#define BIOS_OP_CFG_LINK_FEC(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LINK_FEC) != 0)
+#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_ADAPTIVE_LINK) != 0)
+#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_SRIOV_CONTROL) != 0)
+#define BIOS_OP_CFG_EXTEND_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_EXTEND_MODE) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_ID) != 0)
+#define BIOS_OP_CFG_RST_DEF_SET(op_code_val) \
+ (((op_code_val) & (u32)NIC_NVM_DATA_RESET) != 0)
+
#define NIC_BIOS_CFG_MAX_PF_BW 100
+
+struct nic_legacy_vlan_cfg {
+ /* Legacy mode PXE VLAN enable: 0 - disable 1 - enable */
+ u8 pxe_vlan_en : 1;
+ /* Legacy mode PXE VLAN priority: 0-7 */
+ u8 pxe_vlan_pri : 3;
+ /* Legacy mode PXE VLAN ID 1-4094 */
+ u16 pxe_vlan_id : 12;
+};
+
/* Note: This structure must be 4-byte aligned. */
struct nic_bios_cfg {
u32 signature;
- u8 pxe_en; /* PXE enable: 0 - disable 1 - enable */
+ u8 pxe_en;
u8 extend_mode;
- u8 rsvd0[2];
- u8 pxe_vlan_en; /* PXE VLAN enable: 0 - disable 1 - enable */
- u8 pxe_vlan_pri; /* PXE VLAN priority: 0-7 */
- u16 pxe_vlan_id; /* PXE VLAN ID 1-4094 */
- u32 service_mode; /* @See CHIPIF_SERVICE_MODE_x */
- u32 pf_bw; /* PF rate, in percentage. The value ranges from 0 to 100. */
- u8 speed; /* enum of port speed */
- u8 auto_neg; /* Auto-Negotiation Switch 0 - Invalid Field 1 - On 2 - Off */
- u8 lanes; /* lane num */
- u8 fec; /* FEC mode, @See enum mag_cmd_port_fec */
- u8 auto_adapt; /* Adaptive Mode Configuration 0 - Invalid Configuration 1 - On 2 - Off */
- u8 func_valid; /* Whether func_id is valid; 0: invalid; other: valid */
- u8 func_id; /* This member is valid only when func_valid is not set to 0. */
- u8 sriov_en; /* SRIOV-EN: 0 - Invalid configuration, 1 - On, 2 - Off */
+ struct nic_legacy_vlan_cfg nlvc;
+ u8 pxe_vlan_en;
+ u8 pxe_vlan_pri;
+ u16 pxe_vlan_id;
+ u32 service_mode;
+ u32 pf_tx_bw;
+ u8 speed;
+ u8 auto_neg;
+ u8 lanes;
+ u8 fec;
+ u8 auto_adapt;
+ u8 func_valid;
+ u8 func_id;
+ u8 sriov_en;
};
struct nic_cmd_bios_cfg {
@@ -1201,6 +1273,14 @@ struct nic_cmd_bios_cfg {
struct nic_bios_cfg bios_cfg;
};
+struct nic_rx_rate_bios_cfg {
+ struct mgmt_msg_head msg_head;
+
+ u32 op_code; /* Operation Code:[0:read 1:write] */
+ u8 rx_rate_limit;
+ u8 func_id;
+};
+
struct nic_cmd_vhd_config {
struct hinic3_mgmt_msg_head head;
@@ -1222,7 +1302,8 @@ struct hinic3_create_bond_info {
u32 active_port_max_num; /* Maximum number of active bond member interfaces */
u32 active_port_min_num; /* Minimum number of active bond member interfaces */
u32 xmit_hash_policy;
- u32 rsvd[2];
+ u32 default_param_flag;
+ u32 rsvd;
};
struct hinic3_cmd_create_bond {
@@ -1317,7 +1398,8 @@ struct hinic3_smac_check_state {
struct hinic3_mgmt_msg_head head;
u8 smac_check_en; /* 1: enable 0: disable */
u8 op_code; /* 1: set 0: get */
- u8 rsvd[2];
+ u8 flash_en; /* 1: enable 0: disable */
+ u8 rsvd;
};
struct hinic3_clear_log_state {
@@ -1325,4 +1407,34 @@ struct hinic3_clear_log_state {
u32 type;
};
+struct hinic3_outband_cfg_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 outband_default_vid;
+ u16 func_id;
+};
+
+struct hinic3_wr_ordering {
+ struct hinic3_mgmt_msg_head head;
+ u8 op_code; /* 1: set 0: get */
+ u8 wr_pkt_so_ro;
+ u8 rd_pkt_so_ro;
+ u8 rsvd;
+};
+
+struct hinic3_function_active_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_rq_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rq_depth;
+ u16 rq_num;
+ u16 pf_num;
+ u16 port_num;
+};
+
#endif /* HINIC_MGMT_INTERFACE_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
new file mode 100644
index 0000000..3e625fc
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
+ * File Name : nic_npu_cmd.h
+ * Version : Initial Draft
+ * Created : 2019/4/25
+ * Last Modified :
+ * Description : NIC Commands between Driver and NPU
+ * Function List :
+ */
+
+#ifndef NIC_NPU_CMD_H
+#define NIC_NPU_CMD_H
+
+/* NIC CMDQ MODE */
+enum hinic3_ucode_cmd {
+ HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
+ HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
+ HINIC3_UCODE_CMD_ARM_SQ, /**< Unused */
+ HINIC3_UCODE_CMD_ARM_RQ, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_IQ_ENABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
+ HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
+ HINIC3_UCODE_CMD_PPA_HASH_TABLE,
+ HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_UCODE_MIG_CFG_Q_CTX = 14,
+ HINIC3_UCODE_MIG_CHK_SQ_STOP,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ HINIC3_UCODE_MIG_CFG_BAT_INFO,
+};
+
+#endif /* NIC_NPU_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
index 78a8d7f..00f4a24 100644
--- a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
+++ b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
@@ -4,7 +4,9 @@
#ifndef OSSL_KNL_LINUX_H_
#define OSSL_KNL_LINUX_H_
+#include <net/checksum.h>
#include <net/ipv6.h>
+#include <net/devlink.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/device.h>
@@ -18,6 +20,12 @@
#include <linux/list.h>
#include <linux/bitmap.h>
#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/filter.h>
+#include <linux/aer.h>
+#include <linux/socket.h>
#ifndef NETIF_F_SCTP_CSUM
#define NETIF_F_SCTP_CSUM 0
@@ -173,12 +181,10 @@ static inline void *_hinic3_dma_zalloc_coherent(struct device *dev,
}
#endif
-#ifndef DT_KNL_EMU
struct timeval {
__kernel_old_time_t tv_sec; /* seconds */
__kernel_suseconds_t tv_usec; /* microseconds */
};
-#endif
#ifndef do_gettimeofday
#define do_gettimeofday(time) _kc_do_gettimeofday(time)
@@ -196,6 +202,10 @@ static inline void _kc_do_gettimeofday(struct timeval *tv)
#define ETH_GET_HEADLEN_NEED_DEV
#define HAVE_GENL_OPS_FIELD_VALIDATE
+#ifndef FIELD_SIZEOF
+#define FIELD_SIZEOF(t, f) (sizeof(((t *)0)->f))
+#endif
+
#define HAVE_DEVLINK_FLASH_UPDATE_PARAMS
#ifndef rtc_time_to_tm
@@ -253,12 +263,12 @@ static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size,
size, vaddr, dma_handle);
}
-#define HAVE_DEVLINK_FW_FILE_NAME_MEMBER
-
#define HAVE_ENCAPSULATION_TSO
#define HAVE_ENCAPSULATION_CSUM
+#define HAVE_UDP_TUNNEL_NIC_INFO
+
#ifndef eth_zero_addr
static inline void hinic3_eth_zero_addr(u8 *addr)
{
@@ -333,4 +343,15 @@ u64 ossl_get_real_time(void);
#define tasklet_state(tasklet) ((tasklet)->state)
+dma_addr_t pci_map_single(struct pci_dev *pdev,
+ void *ptr, size_t size, int direction);
+int pci_dma_mapping_error(struct pci_dev *pdev,
+ dma_addr_t dma_addr);
+void pci_unmap_single(struct pci_dev *pdev,
+ dma_addr_t dma_addr, size_t size, int direction);
+void *pci_alloc_consistent(struct pci_dev *pdev,
+ size_t size, dma_addr_t *dma_handle);
+void pci_free_consistent(struct pci_dev *pdev,
+ size_t size, void *vaddr, dma_addr_t dma_handle);
+
#endif
--
2.43.0
2
1

[openeuler:OLK-6.6] BUILD REGRESSION 66448995cc552d846c7442188f69e833f4a86676
by kernel test robot 08 May '25
by kernel test robot 08 May '25
08 May '25
tree/branch: https://gitee.com/openeuler/kernel.git OLK-6.6
branch HEAD: 66448995cc552d846c7442188f69e833f4a86676 !16087 CVE-2025-21979
Error/Warning (recently discovered and may have been fixed):
https://lore.kernel.org/oe-kbuild-all/202504240137.L2xvmv1X-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504240638.PM73jDId-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504250828.wJjuSU89-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290703.q8lvsdB3-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290927.uassI0w9-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504291722.ZB4nQmaR-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504300433.T31occlR-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505080526.qCQgtY7V-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505080910.94UlZrA0-lkp@intel.com
block/blk-io-hierarchy/iodump.c:561:7: warning: no previous prototype for '__bio_stage_hierarchy_start' [-Wmissing-prototypes]
block/blk-io-hierarchy/iodump.c:561:7: warning: no previous prototype for function '__bio_stage_hierarchy_start' [-Wmissing-prototypes]
crypto/asymmetric_keys/pgp_library.c:189: warning: Excess function parameter '_data' description in 'pgp_parse_packets'
crypto/asymmetric_keys/pgp_library.c:189: warning: Excess function parameter '_datalen' description in 'pgp_parse_packets'
crypto/asymmetric_keys/pgp_library.c:189: warning: Function parameter or member 'data' not described in 'pgp_parse_packets'
crypto/asymmetric_keys/pgp_library.c:189: warning: Function parameter or member 'datalen' not described in 'pgp_parse_packets'
drivers/irqchip/irq-gic-v3.c:1517:6: warning: no previous prototype for 'is_gicv4p1' [-Wmissing-prototypes]
drivers/irqchip/irq-gic-v3.c:1517:6: warning: no previous prototype for function 'is_gicv4p1' [-Wmissing-prototypes]
drivers/irqchip/irq-gic-v3.c:1526:6: warning: no previous prototype for 'gic_dist_enable_ipiv' [-Wmissing-prototypes]
drivers/irqchip/irq-gic-v3.c:1526:6: warning: no previous prototype for function 'gic_dist_enable_ipiv' [-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/base/trace/sxe_trace.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb_nl.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debug.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:432:6: error: no previous prototype for function 'sxe_debugfs_entries_init' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:459:6: error: no previous prototype for function 'sxe_debugfs_entries_exit' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:465:6: error: no previous prototype for function 'sxe_debugfs_init' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:470:6: error: no previous prototype for function 'sxe_debugfs_exit' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c:2022:5: error: no previous prototype for function 'sxe_reg_test' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c:2644:5: error: no previous prototype for function 'sxe_phys_id_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_filter.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_cli.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_hdc.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:230:6: error: no previous prototype for function 'sxe_hw_no_snoop_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:262:6: error: no previous prototype for function 'sxe_hw_uc_addr_pool_del' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:283:5: error: no previous prototype for function 'sxe_hw_uc_addr_pool_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:337:5: error: no previous prototype for function 'sxe_hw_nic_reset' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:367:6: error: no previous prototype for function 'sxe_hw_pf_rst_done_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:735:5: error: no previous prototype for function 'sxe_hw_pending_irq_read_clear' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:740:6: error: no previous prototype for function 'sxe_hw_pending_irq_write_clear' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:745:5: error: no previous prototype for function 'sxe_hw_irq_cause_get' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:765:6: error: no previous prototype for function 'sxe_hw_ring_irq_auto_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:775:6: error: no previous prototype for function 'sxe_hw_irq_general_reg_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:780:5: error: no previous prototype for function 'sxe_hw_irq_general_reg_get' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:790:6: error: no previous prototype for function 'sxe_hw_event_irq_map' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:806:6: error: no previous prototype for function 'sxe_hw_ring_irq_map' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:823:6: error: no previous prototype for function 'sxe_hw_ring_irq_interval_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:838:6: error: no previous prototype for function 'sxe_hw_event_irq_auto_clear_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:843:6: error: no previous prototype for function 'sxe_hw_specific_irq_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:848:6: error: no previous prototype for function 'sxe_hw_specific_irq_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:876:6: error: no previous prototype for function 'sxe_hw_all_irq_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:994:5: error: no previous prototype for function 'sxe_hw_link_speed_get' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ipsec.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:136:5: error: no previous prototype for function 'sxe_msi_irq_init' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:182:6: error: no previous prototype for function 'sxe_disable_dcb' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:212:6: error: no previous prototype for function 'sxe_disable_rss' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:729:6: error: no previous prototype for function 'sxe_lsc_irq_handler' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:745:6: error: no previous prototype for function 'sxe_mailbox_irq_handler' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c:70:6: error: no previous prototype for function 'sxe_allow_inval_mac' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_monitor.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_phy.c:733:5: error: no previous prototype for function 'sxe_multispeed_sfp_link_configure' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ptp.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ring.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c:1431:6: error: no previous prototype for function 'sxe_headers_cleanup' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c:1569:6: error: no previous prototype for function 'sxe_rx_buffer_page_offset_update' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c:1552:6: error: no previous prototype for function 'sxe_set_vf_link_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c:766:6: error: variable 'ret' set but not used [-Werror,-Wunused-but-set-variable]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_xdp.c:410:6: error: no previous prototype for function 'sxe_txrx_ring_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/base/trace/sxe_trace.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_debug.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ethtool.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:160:6: error: no previous prototype for function 'sxevf_hw_stop' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:187:6: error: no previous prototype for function 'sxevf_msg_write' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:196:5: error: no previous prototype for function 'sxevf_msg_read' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:206:5: error: no previous prototype for function 'sxevf_mailbox_read' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:211:6: error: no previous prototype for function 'sxevf_mailbox_write' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:216:6: error: no previous prototype for function 'sxevf_pf_req_irq_trigger' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:221:6: error: no previous prototype for function 'sxevf_pf_ack_irq_trigger' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:226:6: error: no previous prototype for function 'sxevf_event_irq_map' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:240:6: error: no previous prototype for function 'sxevf_specific_irq_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:245:6: error: no previous prototype for function 'sxevf_irq_enable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:251:6: error: no previous prototype for function 'sxevf_irq_disable' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:259:6: error: no previous prototype for function 'sxevf_hw_ring_irq_map' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:276:6: error: no previous prototype for function 'sxevf_ring_irq_interval_set' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:313:6: error: no previous prototype for function 'sxevf_hw_reset' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:324:5: error: no previous prototype for function 'sxevf_link_state_get' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:539:6: error: no previous prototype for function 'sxevf_tx_ring_switch' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:594:6: error: no previous prototype for function 'sxevf_rx_ring_switch' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:626:6: error: no previous prototype for function 'sxevf_rx_ring_desc_configure' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:640:6: error: no previous prototype for function 'sxevf_rx_rcv_ctl_configure' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ipsec.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_monitor.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_msg.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ring.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_rx_proc.c:362:6: error: no previous prototype for function 'sxevf_rx_ring_buffers_alloc' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:127:5: error: no previous prototype for function 'sxevf_tx_ring_alloc' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:88:6: error: no previous prototype for function 'sxevf_tx_ring_free' [-Werror,-Wmissing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
drivers/net/ethernet/yunsilicon/xsc/pci/sriov_sysfs.c:911:31: warning: unused variable 'vf_type_ib' [-Wunused-const-variable]
drivers/net/ethernet/yunsilicon/xsc/pci/xsc_lag.c:1128:21: warning: variable 'bond_dev' set but not used [-Wunused-but-set-variable]
include/linux/fortify-string.h:606:4: error: call to '__read_overflow2_field' declared with 'warning' attribute: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Werror,-Wattribute-warning]
include/trace/stages/init.h:2:23: warning: 'str__bonding__trace_system_name' defined but not used [-Wunused-const-variable=]
Error/Warning ids grouped by kconfigs:
recent_errors
|-- arm64-allmodconfig
| |-- block-blk-io-hierarchy-iodump.c:warning:no-previous-prototype-for-function-__bio_stage_hierarchy_start
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_data-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_datalen-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-data-not-described-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-datalen-not-described-in-pgp_parse_packets
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-gic_dist_enable_ipiv
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-function-is_gicv4p1
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-mucse-rnp-rnp_mbx_fw.c:warning:Cannot-understand-force_free:
| |-- drivers-net-ethernet-yunsilicon-xsc-pci-sriov_sysfs.c:warning:unused-variable-vf_type_ib
| |-- drivers-net-ethernet-yunsilicon-xsc-pci-xsc_lag.c:warning:variable-bond_dev-set-but-not-used
| `-- include-linux-fortify-string.h:error:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()-Werror-Wattribute-warnin
|-- arm64-allnoconfig
| |-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-gic_dist_enable_ipiv
| `-- drivers-irqchip-irq-gic-v3.c:warning:no-previous-prototype-for-is_gicv4p1
|-- loongarch-allmodconfig
| |-- block-blk-io-hierarchy-iodump.c:warning:no-previous-prototype-for-__bio_stage_hierarchy_start
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_data-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_datalen-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-data-not-described-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-datalen-not-described-in-pgp_parse_packets
| |-- drivers-net-ethernet-mucse-rnp-rnp_mbx_fw.c:warning:Cannot-understand-force_free:
| `-- include-trace-stages-init.h:warning:str__bonding__trace_system_name-defined-but-not-used
|-- x86_64-allyesconfig
| |-- block-blk-io-hierarchy-iodump.c:warning:no-previous-prototype-for-function-__bio_stage_hierarchy_start
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_data-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Excess-function-parameter-_datalen-description-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-data-not-described-in-pgp_parse_packets
| |-- crypto-asymmetric_keys-pgp_library.c:warning:Function-parameter-or-member-datalen-not-described-in-pgp_parse_packets
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_entries_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_exit-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-function-sxe_debugfs_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_phys_id_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-function-sxe_reg_test-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_all_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_auto_clear_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_cause_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_irq_general_reg_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_link_speed_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_nic_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_no_snoop_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_read_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pending_irq_write_clear-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_pf_rst_done_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_auto_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_del-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-function-sxe_hw_uc_addr_pool_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_dcb-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_disable_rss-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_lsc_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_mailbox_irq_handler-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-function-sxe_msi_irq_init-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-function-sxe_allow_inval_mac-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-function-sxe_multispeed_sfp_link_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_headers_cleanup-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-function-sxe_rx_buffer_page_offset_update-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-function-sxe_set_vf_link_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used-Werror-Wunused-but-set-variable
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-function-sxe_txrx_ring_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_event_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_reset-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_ring_irq_map-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_hw_stop-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_disable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_link_state_get-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_mailbox_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_read-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_msg_write-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_ack_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_pf_req_irq_trigger-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_ring_irq_interval_set-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_rcv_ctl_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_desc_configure-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_rx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_specific_irq_enable-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-function-sxevf_tx_ring_switch-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-function-sxevf_rx_ring_buffers_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_alloc-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-function-sxevf_tx_ring_free-Werror-Wmissing-prototypes
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
| |-- drivers-net-ethernet-mucse-rnp-rnp_mbx_fw.c:warning:Cannot-understand-force_free:
| |-- drivers-net-ethernet-yunsilicon-xsc-pci-sriov_sysfs.c:warning:unused-variable-vf_type_ib
| |-- drivers-net-ethernet-yunsilicon-xsc-pci-xsc_lag.c:warning:variable-bond_dev-set-but-not-used
| `-- include-linux-fortify-string.h:error:call-to-__read_overflow2_field-declared-with-warning-attribute:detected-read-beyond-size-of-field-(2nd-parameter)-maybe-use-struct_group()-Werror-Wattribute-warnin
`-- x86_64-defconfig
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
`-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:This-comment-starts-with-but-isn-t-a-kernel-doc-comment.-Refer-Documentation-doc-guide-kernel-doc.rst
elapsed time: 1380m
configs tested: 7
configs skipped: 48
tested configs:
arm64 allmodconfig clang-19
arm64 allnoconfig gcc-14.2.0
loongarch allmodconfig gcc-14.2.0
loongarch allnoconfig gcc-14.2.0
x86_64 allnoconfig clang-20
x86_64 allyesconfig clang-20
x86_64 defconfig gcc-11
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

08 May '25
From: z30065765 <zhuyikai1(a)h-partners.com>
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IC5K44?from=project-issue
CVE: NA
--------------------------------
Add optical module type adaptation.
Add ethtool fec function.
Add NIC XDP PASS function.
Add QoS persistence.
Add NIC out-of-band VLAN configuration function.
Fix NIC bifur bugs.
Fix performance test bugs.
Fix NIC RX bugs.
Fix NIC VF bugs.
Fix the bug of exiting when probing NIC.
Fix bond bugs.
Fix the bug of reading NIC status incorrectly.
Fix and add some statistics.
Signed-off-by: z30065765 <zhuyikai1(a)h-partners.com>
---
drivers/net/ethernet/huawei/hinic3/Makefile | 1 +
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c | 136 ++-
drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h | 1 +
drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h | 212 ----
drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h | 239 ----
drivers/net/ethernet/huawei/hinic3/comm_defs.h | 105 --
drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h | 103 --
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c | 51 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h | 2 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c | 86 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c | 1 -
drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c | 28 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c | 27 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h | 1 +
drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c | 37 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c | 9 +-
drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c | 12 +-
drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h | 185 ---
drivers/net/ethernet/huawei/hinic3/hinic3_common.h | 118 --
drivers/net/ethernet/huawei/hinic3/hinic3_crm.h | 30 +-
drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c | 305 +++--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c | 267 +++--
drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h | 7 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c | 227 +++-
drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c | 387 +++---
drivers/net/ethernet/huawei/hinic3/hinic3_filter.c | 4 +-
drivers/net/ethernet/huawei/hinic3/hinic3_hw.h | 18 +
drivers/net/ethernet/huawei/hinic3/hinic3_irq.c | 11 +-
drivers/net/ethernet/huawei/hinic3/hinic3_lld.h | 205 ----
drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c | 836 ++++++++++++-
drivers/net/ethernet/huawei/hinic3/hinic3_main.c | 476 +++++++-
drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h | 1298 ---------------------
drivers/net/ethernet/huawei/hinic3/hinic3_mt.h | 225 +++-
drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c | 372 ++++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic.h | 61 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c | 450 +++++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h | 55 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c | 167 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h | 159 ---
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c | 13 +
drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h | 221 ++--
drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c | 119 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c | 18 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c | 2 +-
drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c | 18 +-
drivers/net/ethernet/huawei/hinic3/hinic3_profile.h | 146 ---
drivers/net/ethernet/huawei/hinic3/hinic3_rss.c | 142 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c | 41 +-
drivers/net/ethernet/huawei/hinic3/hinic3_rx.c | 357 ++++--
drivers/net/ethernet/huawei/hinic3/hinic3_rx.h | 39 +-
drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h | 6 +-
drivers/net/ethernet/huawei/hinic3/hinic3_tx.c | 141 ++-
drivers/net/ethernet/huawei/hinic3/hinic3_wq.h | 4 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c | 15 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c | 13 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h | 5 -
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c | 206 +++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h | 13 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c | 5 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c | 14 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c | 42 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c | 91 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h | 13 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c | 163 ++-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c | 116 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c | 87 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h | 34 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c | 40 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c | 1223 +++++++++++++++++--
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c | 3 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c | 6 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c | 44 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c | 182 +--
drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h | 4 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h | 31 +
drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c | 52 +-
drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c | 2 +-
drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h | 13 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h | 42 +-
drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h | 2 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h | 4 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h | 130 ++-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h | 109 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h | 5 +
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h | 30 +-
drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h | 8 +
drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h | 16 +-
drivers/net/ethernet/huawei/hinic3/include/vram_common.h | 11 +-
drivers/net/ethernet/huawei/hinic3/mag_cmd.h | 922 ---------------
drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h | 1143 ++++++++++++++++++
drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h | 27 -
drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h | 63 -
drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h | 174 +++
drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h | 1420 +++++++++++++++++++++++
drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h | 36 +
drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h | 94 +-
99 files changed, 9448 insertions(+), 5393 deletions(-)
delete mode 100644 drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_defs.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_common.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/mag_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
delete mode 100644 drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
create mode 100644 drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
diff --git a/drivers/net/ethernet/huawei/hinic3/Makefile b/drivers/net/ethernet/huawei/hinic3/Makefile
index 11fe010..21d8093 100644
--- a/drivers/net/ethernet/huawei/hinic3/Makefile
+++ b/drivers/net/ethernet/huawei/hinic3/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/drivers/net/ethernet/huawei/hinic3/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/drivers/net/ethernet/huawei/hinic3/hw/
+ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/drivers/net/ethernet/huawei/hinic3/bond/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/drivers/net/ethernet/huawei/hinic3/cqm/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/drivers/net/ethernet/huawei/hinic3/include/
ccflags-y += -I$(srctree)/drivers/net/ethernet/huawei/drivers/net/ethernet/huawei/hinic3/include/cqm/
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
index ba3076c..a252e09 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.c
@@ -9,14 +9,18 @@
#include <linux/net.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
+#include <linux/version.h>
+#include "ossl_knl.h"
#include "hinic3_lld.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic_dev.h"
#include "hinic3_hw.h"
-#include "mpu_inband_cmd.h"
-#include "hinic3_hwdev.h"
#include "hinic3_bond.h"
+#include "hinic3_hwdev.h"
+
+#include "bond_common_defs.h"
+#include "vram_common.h"
#define PORT_INVALID_ID 0xFF
@@ -214,10 +218,10 @@ static void bond_dev_untrack_port(struct hinic3_bond_dev *bdev, u8 idx)
spin_lock(&bdev->lock);
if (bdev->tracker.ndev[idx]) {
- pr_info("hinic3_bond: untrack port:%u ndev:%s cnt:%d\n", idx,
- bdev->tracker.ndev[idx]->name, bdev->tracker.cnt);
bdev->tracker.ndev[idx] = NULL;
bdev->tracker.cnt--;
+ pr_info("hinic3_bond: untrack port:%u ndev:%s cnt:%d\n", idx,
+ bdev->tracker.ndev[idx]->name, bdev->tracker.cnt);
}
spin_unlock(&bdev->lock);
@@ -268,11 +272,16 @@ static void bond_master_event(struct hinic3_bond_dev *bdev,
queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
}
-static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
+static struct hinic3_bond_dev *bond_get_bdev(struct bonding *bond)
{
struct hinic3_bond_dev *bdev = NULL;
int bid;
+ if (bond == NULL) {
+ pr_err("hinic3_bond: bond is NULL\n");
+ return NULL;
+ }
+
mutex_lock(&g_bond_mutex);
for (bid = BOND_FIRST_ID; bid <= BOND_MAX_ID; bid++) {
bdev = bond_mngr.bond_dev[bid];
@@ -283,38 +292,72 @@ static struct hinic3_bond_dev *bond_get_bdev(const struct bonding *bond)
mutex_unlock(&g_bond_mutex);
return bdev;
}
+
+ if (strncmp(bond->dev->name, bdev->name, BOND_NAME_MAX_LEN) == 0) {
+ bdev->bond = bond;
+ return bdev;
+ }
}
mutex_unlock(&g_bond_mutex);
return NULL;
}
-static void bond_handle_rtnl_event(struct net_device *ndev)
+static struct bonding *get_bonding_by_netdev(struct net_device *ndev)
{
- struct hinic3_bond_dev *bdev = NULL;
struct bonding *bond = NULL;
struct slave *slave = NULL;
if (netif_is_bond_master(ndev)) {
bond = netdev_priv(ndev);
- bdev = bond_get_bdev(bond);
} else if (netif_is_bond_slave(ndev)) {
- /*lint -e(160) */
slave = bond_slave_get_rtnl(ndev);
if (slave) {
bond = bond_get_bond_by_slave(slave);
- bdev = bond_get_bdev(bond);
}
}
- if (!bond || !bdev)
+ return bond;
+}
+/*lint -e580 -e546*/
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+
+ if (!ndev) {
+ pr_err("hinic3_bond: netdev is NULL\n");
+ return false;
+ }
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
+ return false;
+
+ return bdev->status == BOND_DEV_STATUS_ACTIVATED;
+}
+EXPORT_SYMBOL(hinic3_is_bond_dev_status_actived);
+/*lint +e580 +e546*/
+
+static void bond_handle_rtnl_event(struct net_device *ndev)
+{
+ struct hinic3_bond_dev *bdev = NULL;
+ struct bonding *bond = NULL;
+ struct slave *slave = NULL;
+
+ bond = get_bonding_by_netdev(ndev);
+ bdev = bond_get_bdev(bond);
+ if (!bdev)
return;
bond_update_attr(bdev, bond);
- if (slave)
+ if (netif_is_bond_slave(ndev)) {
+ slave = bond_slave_get_rtnl(ndev);
bond_slave_event(bdev, slave);
- else
+ } else {
bond_master_event(bdev, bond);
+ }
}
static void bond_rtnl_data_ready(struct sock *sk)
@@ -478,7 +521,11 @@ static void bond_update_slave_info(struct hinic3_bond_dev *bdev,
continue;
}
+ if (!bdev->tracker.ndev[i])
+ continue;
+
bond_pf_bitmap_set(bdev, i);
+
if (!bdev->tracker.netdev_state[i].tx_enabled)
continue;
@@ -516,6 +563,7 @@ static int bond_upcmd_config(struct hinic3_bond_dev *bdev,
attr->active_slaves,
attr->lacp_collect_slaves);
pr_info("bond_pf_bitmap: 0x%x\n", attr->bond_pf_bitmap);
+ pr_info("bond user_bitmap 0x%x\n", attr->user_bitmap);
err = bond_send_upcmd(bdev, attr, MPU_CMD_BOND_SET_ATTR);
if (!err)
@@ -560,17 +608,36 @@ static void bond_call_service_func(struct hinic3_bond_dev *bdev, struct bond_att
mutex_unlock(&g_bond_service_func_mutex);
}
+static u32 bond_get_user_bitmap(struct hinic3_bond_dev *bdev)
+{
+ u32 user_bitmap = 0;
+ u8 user;
+
+ for (user = HINIC3_BOND_USER_OVS; user < HINIC3_BOND_USER_NUM; user++) {
+ if (bdev->slot_used[user] == 1)
+ BITMAP_SET(user_bitmap, user);
+ }
+ return user_bitmap;
+}
+
static void bond_do_work(struct hinic3_bond_dev *bdev)
{
bool is_bonded = 0;
struct bond_attr attr;
+ int is_in_kexec;
int err = 0;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ pr_info("Skip changing bond status during os replace\n");
+ return;
+ }
+
spin_lock(&bdev->lock);
is_bonded = bdev->tracker.is_bonded;
attr = bdev->new_attr;
spin_unlock(&bdev->lock);
- attr.user_bitmap = 0;
+ attr.user_bitmap = bond_get_user_bitmap(bdev);
/* is_bonded indicates whether bond should be activated. */
if (is_bonded && !bond_dev_is_activated(bdev)) {
@@ -591,17 +658,21 @@ static void bond_do_work(struct hinic3_bond_dev *bdev)
pr_err("hinic3_bond: Do bond failed\n");
}
-#define MIN_BOND_SLAVE_CNT 2
static void bond_try_do_work(struct work_struct *work)
{
struct delayed_work *delayed_work = to_delayed_work(work);
struct hinic3_bond_dev *bdev =
container_of(delayed_work, struct hinic3_bond_dev, bond_work);
+ int status;
- if (g_bond_service_func[HINIC3_BOND_USER_ROCE] && bdev->tracker.cnt < MIN_BOND_SLAVE_CNT)
+ status = mutex_trylock(&g_bond_mutex);
+ if (status == 0) {
+ /* Delay 1 sec and retry */
queue_delayed_work(bdev->wq, &bdev->bond_work, HZ);
- else
+ } else {
bond_do_work(bdev);
+ mutex_unlock(&g_bond_mutex);
+ }
}
static int bond_dev_init(struct hinic3_bond_dev *bdev, const char *name)
@@ -630,6 +701,7 @@ static int bond_dev_release(struct hinic3_bond_dev *bdev)
err = bond_upcmd_deactivate(bdev);
if (err) {
pr_err("hinic3_bond: Failed to deactivate dev\n");
+ mutex_unlock(&g_bond_mutex);
return err;
}
@@ -764,20 +836,28 @@ static struct hinic3_bond_dev *bond_dev_by_name(const char *name)
static void bond_dev_user_attach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user)
{
+ u32 user_bitmap;
+
+ if (user < 0 || user >= HINIC3_BOND_USER_NUM)
+ return;
+
if (bdev->slot_used[user])
return;
bdev->slot_used[user] = 1;
if (!kref_get_unless_zero(&bdev->ref))
kref_init(&bdev->ref);
+ else {
+ user_bitmap = bond_get_user_bitmap(bdev);
+ pr_info("hinic3_bond: user %u attach bond %s, user_bitmap %#x\n",
+ user, bdev->name, user_bitmap);
+ queue_delayed_work(bdev->wq, &bdev->bond_work, 0);
+ }
}
static void bond_dev_user_detach(struct hinic3_bond_dev *bdev,
enum hinic3_bond_user user, bool *freed)
{
- if (user < 0 || user >= HINIC3_BOND_USER_NUM)
- return;
-
if (bdev->slot_used[user]) {
bdev->slot_used[user] = 0;
if (kref_read(&bdev->ref) == 1)
@@ -790,12 +870,15 @@ static struct bonding *bond_get_knl_bonding(const char *name)
{
struct net_device *ndev_tmp = NULL;
+ rcu_read_lock();
for_each_netdev(&init_net, ndev_tmp) {
if (netif_is_bond_master(ndev_tmp) &&
- !strcmp(ndev_tmp->name, name))
+ !strcmp(ndev_tmp->name, name)) {
+ rcu_read_unlock();
return netdev_priv(ndev_tmp);
+ }
}
-
+ rcu_read_unlock();
return NULL;
}
@@ -852,8 +935,9 @@ int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user)
int err = 0;
bool lock_freed = false;
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
- pr_warn("hinic3_bond: Invalid bond id:%u to delete\n", bond_id);
+ if (!BOND_ID_IS_VALID(bond_id) || user >= HINIC3_BOND_USER_NUM) {
+ pr_warn("hinic3_bond: Invalid bond id or user, bond_id: %u, user: %d\n",
+ bond_id, user);
return -EINVAL;
}
@@ -891,7 +975,7 @@ EXPORT_SYMBOL(hinic3_bond_clean_user);
int hinic3_bond_get_uplink_id(u16 bond_id, u32 *uplink_id)
{
- if (bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID || !uplink_id) {
+ if (!BOND_ID_IS_VALID(bond_id) || !uplink_id) {
pr_warn("hinic3_bond: Invalid args, id: %u, uplink: %d\n",
bond_id, !!uplink_id);
return -EINVAL;
@@ -941,7 +1025,7 @@ int hinic3_bond_get_slaves(u16 bond_id, struct hinic3_bond_info_s *info)
int i;
int len;
- if (!info || bond_id < BOND_FIRST_ID || bond_id > BOND_MAX_ID) {
+ if (!info || !BOND_ID_IS_VALID(bond_id)) {
pr_warn("hinic3_bond: Invalid args, info: %d,id: %u\n",
!!info, bond_id);
return -EINVAL;
diff --git a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
index 024de95..5ab36f7 100644
--- a/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
+++ b/drivers/net/ethernet/huawei/hinic3/bond/hinic3_bond.h
@@ -82,6 +82,7 @@ struct hinic3_bond_cmd {
char bond_name[16];
};
+bool hinic3_is_bond_dev_status_actived(struct net_device *ndev);
void hinic3_bond_set_user_bitmap(struct bond_attr *attr, enum hinic3_bond_user user);
int hinic3_bond_attach(const char *name, enum hinic3_bond_user user, u16 *bond_id);
int hinic3_bond_detach(u16 bond_id, enum hinic3_bond_user user);
diff --git a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h b/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
deleted file mode 100644
index 557f326..0000000
--- a/drivers/net/ethernet/huawei/hinic3/cfg_mgt_comm_pub.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2016-2022. All rights reserved.
- * File name: Cfg_mgt_comm_pub.h
- * Version No.: Draft
- * Generation date: 2016 year 05 month 07 day
- * Latest modification:
- * Function description: Header file for communication between the: Host and FW
- * Function list:
- * Modification history:
- * 1. Date: 2016 May 07
- * Modify content: Create a file.
- */
-#ifndef CFG_MGT_COMM_PUB_H
-#define CFG_MGT_COMM_PUB_H
-
-#include "mgmt_msg_base.h"
-
-enum servic_bit_define {
- SERVICE_BIT_NIC = 0,
- SERVICE_BIT_ROCE = 1,
- SERVICE_BIT_VBS = 2,
- SERVICE_BIT_TOE = 3,
- SERVICE_BIT_IPSEC = 4,
- SERVICE_BIT_FC = 5,
- SERVICE_BIT_VIRTIO = 6,
- SERVICE_BIT_OVS = 7,
- SERVICE_BIT_NVME = 8,
- SERVICE_BIT_ROCEAA = 9,
- SERVICE_BIT_CURRENET = 10,
- SERVICE_BIT_PPA = 11,
- SERVICE_BIT_MIGRATE = 12,
- SERVICE_BIT_MAX
-};
-
-#define CFG_SERVICE_MASK_NIC (0x1 << SERVICE_BIT_NIC)
-#define CFG_SERVICE_MASK_ROCE (0x1 << SERVICE_BIT_ROCE)
-#define CFG_SERVICE_MASK_VBS (0x1 << SERVICE_BIT_VBS)
-#define CFG_SERVICE_MASK_TOE (0x1 << SERVICE_BIT_TOE)
-#define CFG_SERVICE_MASK_IPSEC (0x1 << SERVICE_BIT_IPSEC)
-#define CFG_SERVICE_MASK_FC (0x1 << SERVICE_BIT_FC)
-#define CFG_SERVICE_MASK_VIRTIO (0x1 << SERVICE_BIT_VIRTIO)
-#define CFG_SERVICE_MASK_OVS (0x1 << SERVICE_BIT_OVS)
-#define CFG_SERVICE_MASK_NVME (0x1 << SERVICE_BIT_NVME)
-#define CFG_SERVICE_MASK_ROCEAA (0x1 << SERVICE_BIT_ROCEAA)
-#define CFG_SERVICE_MASK_CURRENET (0x1 << SERVICE_BIT_CURRENET)
-#define CFG_SERVICE_MASK_PPA (0x1 << SERVICE_BIT_PPA)
-#define CFG_SERVICE_MASK_MIGRATE (0x1 << SERVICE_BIT_MIGRATE)
-
-/* Definition of the scenario ID in the cfg_data, which is used for SML memory allocation. */
-enum scenes_id_define {
- SCENES_ID_FPGA_ETH = 0,
- SCENES_ID_FPGA_TIOE = 1, /* Discarded */
- SCENES_ID_STORAGE_ROCEAA_2x100 = 2,
- SCENES_ID_STORAGE_ROCEAA_4x25 = 3,
- SCENES_ID_CLOUD = 4,
- SCENES_ID_FC = 5,
- SCENES_ID_STORAGE_ROCE = 6,
- SCENES_ID_COMPUTE_ROCE = 7,
- SCENES_ID_STORAGE_TOE = 8,
- SCENES_ID_MAX
-};
-
-/* struct cfg_cmd_dev_cap.sf_svc_attr */
-enum {
- SF_SVC_FT_BIT = (1 << 0),
- SF_SVC_RDMA_BIT = (1 << 1),
-};
-
-enum cfg_cmd {
- CFG_CMD_GET_DEV_CAP = 0,
- CFG_CMD_GET_HOST_TIMER = 1,
-};
-
-struct cfg_cmd_host_timer {
- struct mgmt_msg_head head;
-
- u8 host_id;
- u8 rsvd1;
-
- u8 timer_pf_num;
- u8 timer_pf_id_start;
- u16 timer_vf_num;
- u16 timer_vf_id_start;
- u32 rsvd2[8];
-};
-
-struct cfg_cmd_dev_cap {
- struct mgmt_msg_head head;
-
- u16 func_id;
- u16 rsvd1;
-
- /* Public resources */
- u8 host_id;
- u8 ep_id;
- u8 er_id;
- u8 port_id;
-
- u16 host_total_func;
- u8 host_pf_num;
- u8 pf_id_start;
- u16 host_vf_num;
- u16 vf_id_start;
- u8 host_oq_id_mask_val;
- u8 timer_en;
- u8 host_valid_bitmap;
- u8 rsvd_host;
-
- u16 svc_cap_en;
- u16 max_vf;
- u8 flexq_en;
- u8 valid_cos_bitmap;
- /* Reserved for func_valid_cos_bitmap */
- u8 port_cos_valid_bitmap;
- u8 rsvd_func1;
- u32 rsvd_func2;
-
- u8 sf_svc_attr;
- u8 func_sf_en;
- u8 lb_mode;
- u8 smf_pg;
-
- u32 max_conn_num;
- u16 max_stick2cache_num;
- u16 max_bfilter_start_addr;
- u16 bfilter_len;
- u16 hash_bucket_num;
-
- /* shared resource */
- u8 host_sf_en;
- u8 master_host_id;
- u8 srv_multi_host_mode;
- u8 virtio_vq_size;
-
- u32 rsvd_func3[5];
-
- /* l2nic */
- u16 nic_max_sq_id;
- u16 nic_max_rq_id;
- u16 nic_default_num_queues;
- u16 rsvd1_nic;
- u32 rsvd2_nic[2];
-
- /* RoCE */
- u32 roce_max_qp;
- u32 roce_max_cq;
- u32 roce_max_srq;
- u32 roce_max_mpt;
- u32 roce_max_drc_qp;
-
- u32 roce_cmtt_cl_start;
- u32 roce_cmtt_cl_end;
- u32 roce_cmtt_cl_size;
-
- u32 roce_dmtt_cl_start;
- u32 roce_dmtt_cl_end;
- u32 roce_dmtt_cl_size;
-
- u32 roce_wqe_cl_start;
- u32 roce_wqe_cl_end;
- u32 roce_wqe_cl_size;
- u8 roce_srq_container_mode;
- u8 rsvd_roce1[3];
- u32 rsvd_roce2[5];
-
- /* IPsec */
- u32 ipsec_max_sactx;
- u16 ipsec_max_cq;
- u16 rsvd_ipsec1;
- u32 rsvd_ipsec[2];
-
- /* OVS */
- u32 ovs_max_qpc;
- u32 rsvd_ovs1[3];
-
- /* ToE */
- u32 toe_max_pctx;
- u32 toe_max_cq;
- u16 toe_max_srq;
- u16 toe_srq_id_start;
- u16 toe_max_mpt;
- u16 toe_max_cctxt;
- u32 rsvd_toe[2];
-
- /* FC */
- u32 fc_max_pctx;
- u32 fc_max_scq;
- u32 fc_max_srq;
-
- u32 fc_max_cctx;
- u32 fc_cctx_id_start;
-
- u8 fc_vp_id_start;
- u8 fc_vp_id_end;
- u8 rsvd_fc1[2];
- u32 rsvd_fc2[5];
-
- /* VBS */
- u16 vbs_max_volq;
- u16 rsvd0_vbs;
- u32 rsvd1_vbs[3];
-
- u16 fake_vf_start_id;
- u16 fake_vf_num;
- u32 fake_vf_max_pctx;
- u16 fake_vf_bfilter_start_addr;
- u16 fake_vf_bfilter_len;
- u32 rsvd_glb[8];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
deleted file mode 100644
index 6f5f87b..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_cmdq_intf.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/******************************************************************************
- * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
- ******************************************************************************
- File Name : comm_cmdq_intf.h
- Version : Initial Draft
- Description : common command queue interface
- Function List :
- History :
- Modification: Created file
-
-******************************************************************************/
-
-#ifndef COMM_CMDQ_INTF_H
-#define COMM_CMDQ_INTF_H
-
-/* Cmdq ack type */
-enum hinic3_ack_type {
- HINIC3_ACK_TYPE_CMDQ,
- HINIC3_ACK_TYPE_SHARE_CQN,
- HINIC3_ACK_TYPE_APP_CQN,
-
- HINIC3_MOD_ACK_MAX = 15,
-};
-
-/* Defines the queue type of the set arm bit. */
-enum {
- SET_ARM_BIT_FOR_CMDQ = 0,
- SET_ARM_BIT_FOR_L2NIC_SQ,
- SET_ARM_BIT_FOR_L2NIC_RQ,
- SET_ARM_BIT_TYPE_NUM
-};
-
-/* Defines the type. Each function supports a maximum of eight CMDQ types. */
-enum {
- CMDQ_0 = 0,
- CMDQ_1 = 1, /* dedicated and non-blocking queues */
- CMDQ_NUM
-};
-
-/* *******************cmd common command data structure ************************ */
-// Func->ucode, which is used to set arm bit data,
-// The microcode needs to perform big-endian conversion.
-struct comm_info_ucode_set_arm_bit {
- u32 q_type;
- u32 q_id;
-};
-
-/* *******************WQE data structure ************************ */
-union cmdq_wqe_cs_dw0 {
- struct {
- u32 err_status : 29;
- u32 error_code : 2;
- u32 rsvd : 1;
- } bs;
- u32 val;
-};
-
-union cmdq_wqe_cs_dw1 {
- // This structure is used when the driver writes the wqe.
- struct {
- u32 token : 16; // [15:0]
- u32 cmd : 8; // [23:16]
- u32 mod : 5; // [28:24]
- u32 ack_type : 2; // [30:29]
- u32 obit : 1; // [31]
- } drv_wr;
-
- /* The uCode writes back the structure of the CS_DW1.
- * The driver reads and uses the structure. */
- struct {
- u32 mod : 5; // [4:0]
- u32 ack_type : 3; // [7:5]
- u32 cmd : 8; // [15:8]
- u32 arm : 1; // [16]
- u32 rsvd : 14; // [30:17]
- u32 obit : 1; // [31]
- } wb;
- u32 val;
-};
-
-/* CmdQ BD information or write back buffer information */
-struct cmdq_sge {
- u32 pa_h; // Upper 32 bits of the physical address
- u32 pa_l; // Upper 32 bits of the physical address
- u32 len; // Invalid bit[31].
- u32 resv;
-};
-
-/* Ctrls section definition of WQE */
-struct cmdq_wqe_ctrls {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
-};
-
-/* Complete section definition of WQE */
-struct cmdq_wqe_cs {
- union cmdq_wqe_cs_dw0 dw0;
- union cmdq_wqe_cs_dw1 dw1;
- union {
- struct cmdq_sge sge;
- u32 dw2_5[4];
- } ack;
-};
-
-/* Inline header in WQE inline, describing the length of inline data */
-union cmdq_wqe_inline_header {
- struct {
- u32 buf_len : 11; // [10:0] inline data len
- u32 rsv : 21; // [31:11]
- } bs;
- u32 val;
-};
-
-/* Definition of buffer descriptor section in WQE */
-union cmdq_wqe_bds {
- struct {
- struct cmdq_sge bds_sge;
- u32 rsvd[4]; /* Zwy is used to transfer the virtual address of the buffer. */
- } lcmd; /* Long command, non-inline, and SGE describe the buffer information. */
-};
-
-/* Definition of CMDQ WQE */
-/* (long cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(16B) |
- * | |
- * +----------------------------------------+
- * | driver section(16B) |
- * +----------------------------------------+
- *
- *
- * (middle cmd, 128B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(88B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- *
- *
- * (short cmd, 64B)
- * +----------------------------------------+
- * | ctrl section(8B) |
- * +----------------------------------------+
- * | |
- * | complete section(24B) |
- * | |
- * +----------------------------------------+
- * | |
- * | buffer descriptor section(24B) |
- * | |
- * +----------------------------------------+
- * | driver section(8B) |
- * +----------------------------------------+
- */
-struct cmdq_wqe {
- struct cmdq_wqe_ctrls ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds bds;
-};
-
-/* Definition of ctrls section in inline WQE */
-struct cmdq_wqe_ctrls_inline {
- union {
- struct {
- u32 bdsl : 8; // [7:0]
- u32 drvsl : 2; // [9:8]
- u32 rsv : 4; // [13:10]
- u32 wf : 1; // [14]
- u32 cf : 1; // [15]
- u32 tsl : 5; // [20:16]
- u32 va : 1; // [21]
- u32 df : 1; // [22]
- u32 cr : 1; // [23]
- u32 difsl : 3; // [26:24]
- u32 csl : 2; // [28:27]
- u32 ctrlsl : 2; // [30:29]
- u32 obit : 1; // [31]
- } bs;
- u32 val;
- } header;
- u32 qsf;
- u64 db;
-};
-
-/* Buffer descriptor section definition of WQE */
-union cmdq_wqe_bds_inline {
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[80];
- } mcmd; /* Middle command, inline mode */
-
- struct {
- union cmdq_wqe_inline_header header;
- u32 rsvd;
- u8 data_inline[16];
- } scmd; /* Short command, inline mode */
-};
-
-struct cmdq_wqe_inline {
- struct cmdq_wqe_ctrls_inline ctrls;
- struct cmdq_wqe_cs cs;
- union cmdq_wqe_bds_inline bds;
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_defs.h b/drivers/net/ethernet/huawei/hinic3/comm_defs.h
deleted file mode 100644
index 91d298d..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_defs.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_defs.h
- * Version : Initial Draft
- * Description : common definitions
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef COMM_DEFS_H
-#define COMM_DEFS_H
-
-/* CMDQ MODULE_TYPE */
-enum hinic3_mod_type {
- HINIC3_MOD_COMM = 0, /* HW communication module */
- HINIC3_MOD_L2NIC = 1, /* L2NIC module */
- HINIC3_MOD_ROCE = 2,
- HINIC3_MOD_PLOG = 3,
- HINIC3_MOD_TOE = 4,
- HINIC3_MOD_FLR = 5,
- HINIC3_MOD_RSVD1 = 6,
- HINIC3_MOD_CFGM = 7, /* Configuration module */
- HINIC3_MOD_CQM = 8,
- HINIC3_MOD_RSVD2 = 9,
- COMM_MOD_FC = 10,
- HINIC3_MOD_OVS = 11,
- HINIC3_MOD_DSW = 12,
- HINIC3_MOD_MIGRATE = 13,
- HINIC3_MOD_HILINK = 14,
- HINIC3_MOD_CRYPT = 15, /* secure crypto module */
- HINIC3_MOD_VIO = 16,
- HINIC3_MOD_IMU = 17,
- HINIC3_MOD_DFT = 18, /* DFT */
- HINIC3_MOD_HW_MAX = 19, /* hardware max module id */
- /* Software module id, for PF/VF and multi-host */
- HINIC3_MOD_SW_FUNC = 20,
- HINIC3_MOD_MAX,
-};
-
-/* func reset的flag ,用于指示清理哪种资源 */
-enum func_reset_flag {
- RES_TYPE_FLUSH_BIT = 0,
- RES_TYPE_MQM,
- RES_TYPE_SMF,
- RES_TYPE_PF_BW_CFG,
-
- RES_TYPE_COMM = 10,
- RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_NIC,
- RES_TYPE_OVS,
- RES_TYPE_VBS,
- RES_TYPE_ROCE,
- RES_TYPE_FC,
- RES_TYPE_TOE,
- RES_TYPE_IPSEC,
- RES_TYPE_MAX,
-};
-
-#define HINIC3_COMM_RES \
- ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
- (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
- (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
-
-#define HINIC3_NIC_RES (1 << RES_TYPE_NIC)
-#define HINIC3_OVS_RES (1 << RES_TYPE_OVS)
-#define HINIC3_VBS_RES (1 << RES_TYPE_VBS)
-#define HINIC3_ROCE_RES (1 << RES_TYPE_ROCE)
-#define HINIC3_FC_RES (1 << RES_TYPE_FC)
-#define HINIC3_TOE_RES (1 << RES_TYPE_TOE)
-#define HINIC3_IPSEC_RES (1 << RES_TYPE_IPSEC)
-
-/* MODE OVS、NIC、UNKNOWN */
-#define HINIC3_WORK_MODE_OVS 0
-#define HINIC3_WORK_MODE_UNKNOWN 1
-#define HINIC3_WORK_MODE_NIC 2
-
-#define DEVICE_TYPE_L2NIC 0
-#define DEVICE_TYPE_NVME 1
-#define DEVICE_TYPE_VIRTIO_NET 2
-#define DEVICE_TYPE_VIRTIO_BLK 3
-#define DEVICE_TYPE_VIRTIO_VSOCK 4
-#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
-#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
-#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
-#define DEVICE_TYPE_VIRTIO_HPC 8
-
-#define IS_STORAGE_DEVICE_TYPE(dev_type) \
- ((dev_type) == DEVICE_TYPE_VIRTIO_BLK || \
- (dev_type) == DEVICE_TYPE_VIRTIO_BLK_TRANSITION || \
- (dev_type) == DEVICE_TYPE_VIRTIO_SCSI_TRANSITION)
-
-/* Common header control information of the COMM message
- * interaction command word between the driver and PF
- */
-struct comm_info_head {
- u8 status;
- u8 version;
- u8 rep_aeq_num;
- u8 rsvd[5];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h b/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
deleted file mode 100644
index ae998cf..0000000
--- a/drivers/net/ethernet/huawei/hinic3/comm_msg_intf.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : comm_msg_intf.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef COMM_MSG_INTF_H
-#define COMM_MSG_INTF_H
-
-#include "comm_defs.h"
-#include "mgmt_msg_base.h"
-#include "mpu_cmd_base_defs.h"
-#include "mpu_inband_cmd_defs.h"
-
-struct spu_cmd_freq_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: check */
- u8 rsvd[3];
- u32 freq;
-};
-
-struct spu_cmd_power_operation {
- struct comm_info_head head;
-
- u8 op_code; /* 0: get 1: set 2: init */
- u8 slave_addr;
- u8 cmd_id;
- u8 size;
- u32 value;
-};
-
-struct spu_cmd_tsensor_operation {
- struct comm_info_head head;
-
- u8 op_code;
- u8 rsvd[3];
- s16 fabric_tsensor_temp_avg;
- s16 fabric_tsensor_temp;
- s16 sys_tsensor_temp_avg;
- s16 sys_tsensor_temp;
-};
-
-enum cfg_msix_operation {
- CFG_MSIX_OPERATION_FREE = 0,
- CFG_MSIX_OPERATION_ALLOC = 1,
-};
-
-struct comm_cmd_ffm_info {
- struct mgmt_msg_head head;
-
- u8 node_id;
- /* error level of the interrupt source */
- u8 err_level;
- /* Classification by interrupt source properties */
- u16 err_type;
- u32 err_csr_addr;
- u32 err_csr_value;
- u32 rsvd1;
-};
-
-struct hinic3_cmd_update_firmware {
- struct mgmt_msg_head msg_head;
-
- struct {
- u32 sl : 1;
- u32 sf : 1;
- u32 flag : 1;
- u32 bit_signed : 1;
- u32 reserved : 12;
- u32 fragment_len : 16;
- } ctl_info;
-
- struct {
- u32 section_crc;
- u32 section_type;
- } section_info;
-
- u32 total_len;
- u32 section_len;
- u32 section_version;
- u32 section_offset;
- u32 data[384];
-};
-
-struct hinic3_cmd_activate_firmware {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-struct hinic3_cmd_switch_config {
- struct mgmt_msg_head msg_head;
- u8 index; /* 0 ~ 7 */
- u8 data[7];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
index 76e128e..1562c59 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.c
@@ -28,6 +28,8 @@
#include "cqm_npu_cmd.h"
#include "cqm_npu_cmd_defs.h"
+#include "vram_common.h"
+
static void cqm_bat_fill_cla_common_gpa(struct tag_cqm_handle *cqm_handle,
struct tag_cqm_cla_table *cla_table,
struct tag_cqm_bat_entry_standerd *bat_entry_standerd)
@@ -367,6 +369,14 @@ static s32 cqm_bat_update_cmd(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
struct tag_cqm_cmdq_bat_update *bat_update_cmd = NULL;
s32 ret = CQM_FAIL;
+ int is_in_kexec;
+
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip updating the cqm_bat to chip during kexec!\n");
+ return CQM_SUCCESS;
+ }
+
bat_update_cmd = (struct tag_cqm_cmdq_bat_update *)(buf_in->buf);
bat_update_cmd->offset = 0;
@@ -644,6 +654,7 @@ void cqm_bat_uninit(struct tag_cqm_handle *cqm_handle)
static s32 cqm_cla_fill_buf(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *cla_base_buf,
struct tag_cqm_buf *cla_sub_buf, u8 gpa_check_enable)
{
+ struct hinic3_hwdev *handle = cqm_handle->ex_handle;
struct hinic3_func_attr *func_attr = NULL;
dma_addr_t *base = NULL;
u64 fake_en = 0;
@@ -655,13 +666,17 @@ static s32 cqm_cla_fill_buf(struct tag_cqm_handle *cqm_handle, struct tag_cqm_bu
/* Apply for space for base_buf */
if (!cla_base_buf->buf_list) {
- if (cqm_buf_alloc(cqm_handle, cla_base_buf, false) == CQM_FAIL)
+ if (cqm_buf_alloc(cqm_handle, cla_base_buf, false) ==
+ CQM_FAIL) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(cla_base_buf));
return CQM_FAIL;
+ }
}
/* Apply for space for sub_buf */
if (!cla_sub_buf->buf_list) {
if (cqm_buf_alloc(cqm_handle, cla_sub_buf, false) == CQM_FAIL) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(cla_sub_buf));
cqm_buf_free(cla_base_buf, cqm_handle);
return CQM_FAIL;
}
@@ -768,8 +783,10 @@ static s32 cqm_cla_xyz_lvl1(struct tag_cqm_handle *cqm_handle,
/* Applying for CLA_Z_BUF Space */
cla_z_buf = &cla_table->cla_z_buf;
cla_z_buf->buf_size = trunk_size;
- cla_z_buf->buf_number = (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
- cla_z_buf->page_number = cla_z_buf->buf_number << cla_table->trunk_order;
+ cla_z_buf->buf_number =
+ (ALIGN(cla_table->max_buffer_size, trunk_size)) / trunk_size;
+ cla_z_buf->page_number = cla_z_buf->buf_number <<
+ cla_table->trunk_order;
/* All buffer space must be statically allocated. */
if (cla_table->alloc_static) {
@@ -785,6 +802,7 @@ static s32 cqm_cla_xyz_lvl1(struct tag_cqm_handle *cqm_handle,
cla_z_buf->buf_list = vmalloc(cla_z_buf->buf_number *
sizeof(struct tag_cqm_buf_list));
if (!cla_z_buf->buf_list) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_1_z_buf));
cqm_buf_free(cla_y_buf, cqm_handle);
return CQM_FAIL;
}
@@ -840,6 +858,7 @@ static s32 cqm_cla_xyz_lvl2_xyz_apply(struct tag_cqm_handle *cqm_handle,
cla_x_buf->buf_size = trunk_size;
cla_x_buf->buf_number = 1;
cla_x_buf->page_number = cla_x_buf->buf_number << cla_table->trunk_order;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
ret = cqm_buf_alloc(cqm_handle, cla_x_buf, false);
if (ret != CQM_SUCCESS)
return CQM_FAIL;
@@ -869,14 +888,20 @@ static s32 cqm_cla_xyz_vram_name_init(struct tag_cqm_cla_table *cla_table,
cla_x_buf = &cla_table->cla_x_buf;
cla_z_buf = &cla_table->cla_z_buf;
cla_y_buf = &cla_table->cla_y_buf;
+ cla_x_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_x_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_X);
+ VRAM_NAME_APPLY_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_X);
+ cla_y_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_y_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Y);
+ VRAM_NAME_APPLY_LEN, "%s%s", cla_table->name,
+ VRAM_CQM_CLA_COORD_Y);
+ cla_z_buf->buf_info.use_vram = get_use_vram_flag();
snprintf(cla_z_buf->buf_info.buf_vram_name,
- VRAM_NAME_MAX_LEN - 1, "%s%s", cla_table->name, VRAM_CQM_CLA_COORD_Z);
+ VRAM_NAME_APPLY_LEN, "%s%s",
+ cla_table->name, VRAM_CQM_CLA_COORD_Z);
return CQM_SUCCESS;
}
@@ -925,6 +950,7 @@ static s32 cqm_cla_xyz_lvl2(struct tag_cqm_handle *cqm_handle,
cla_z_buf->buf_list = vmalloc(cla_z_buf->buf_number *
sizeof(struct tag_cqm_buf_list));
if (!cla_z_buf->buf_list) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_2_z_buf));
cqm_buf_free(cla_x_buf, cqm_handle);
return CQM_FAIL;
}
@@ -934,6 +960,7 @@ static s32 cqm_cla_xyz_lvl2(struct tag_cqm_handle *cqm_handle,
cla_y_buf->buf_list = vmalloc(cla_y_buf->buf_number *
sizeof(struct tag_cqm_buf_list));
if (!cla_y_buf->buf_list) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(lvl_2_y_buf));
cqm_buf_free(cla_z_buf, cqm_handle);
cqm_buf_free(cla_x_buf, cqm_handle);
return CQM_FAIL;
@@ -1188,7 +1215,7 @@ static void cqm_cla_init_entry_extern(struct tag_cqm_handle *cqm_handle,
* exceed 128 x 4 KB. Otherwise, clearing the timer buffer of
* the function is complex.
*/
- cla_table->trunk_order = CQM_4K_PAGE_ORDER;
+ cla_table->trunk_order = CQM_8K_PAGE_ORDER;
cla_table->max_buffer_size = capability->timer_number *
capability->timer_basic_size;
cla_table->obj_size = capability->timer_basic_size;
@@ -1237,7 +1264,7 @@ static s32 cqm_cla_init_entry_condition(struct tag_cqm_handle *cqm_handle, u32 e
memcpy(cla_table_timer, cla_table, sizeof(struct tag_cqm_cla_table));
snprintf(cla_table_timer->name,
- VRAM_NAME_MAX_LEN - 1, "%s%s%01u", cla_table->name,
+ VRAM_NAME_APPLY_LEN, "%s%s%01u", cla_table->name,
VRAM_CQM_CLA_SMF_BASE, i);
if (cqm_cla_xyz(cqm_handle, cla_table_timer) ==
@@ -1268,7 +1295,7 @@ static s32 cqm_cla_init_entry(struct tag_cqm_handle *cqm_handle,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
cla_table->type = bat_table->bat_entry_type[i];
- snprintf(cla_table->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(cla_table->name, VRAM_NAME_APPLY_LEN,
"%s%s%s%02u", cqm_handle->name, VRAM_CQM_CLA_BASE,
VRAM_CQM_CLA_TYPE_BASE, cla_table->type);
@@ -1485,11 +1512,11 @@ static s32 cqm_cla_update(struct tag_cqm_handle *cqm_handle,
spu_en = 0;
pa = ((buf_node_parent->pa + (child_index * sizeof(dma_addr_t))) |
- (u32)spu_en);
+ spu_en);
cmd.gpa_h = CQM_ADDR_HI(pa);
cmd.gpa_l = CQM_ADDR_LW(pa);
- pa = (buf_node_child->pa | (u32)spu_en);
+ pa = (buf_node_child->pa | spu_en);
cmd.value_h = CQM_ADDR_HI(pa);
cmd.value_l = CQM_ADDR_LW(pa);
@@ -1980,7 +2007,7 @@ struct tag_cqm_cla_table *cqm_cla_table_get(struct tag_cqm_bat_table *bat_table,
for (i = 0; i < CQM_BAT_ENTRY_MAX; i++) {
cla_table = &bat_table->entry[i];
- if (cla_table && entry_type == cla_table->type)
+ if ((cla_table != NULL) && (entry_type == cla_table->type))
return cla_table;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
index dd0766e..a51c1dc 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bat_cla.h
@@ -9,6 +9,7 @@
#include "cqm_bitmap_table.h"
#include "cqm_object.h"
+#include "vram_common.h"
/* When the connection check is enabled, the maximum number of connections
* supported by the chip is 1M - 63, which cannot reach 1M
@@ -19,6 +20,7 @@
#define CLA_TABLE_PAGE_ORDER 0
#define CQM_4K_PAGE_ORDER 0
#define CQM_4K_PAGE_SIZE 4096
+#define CQM_8K_PAGE_ORDER 1
#define CQM_BAT_ENTRY_MAX 16
#define CQM_BAT_ENTRY_SIZE 16
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
index f4844d5..86b268c 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.c
@@ -254,8 +254,10 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
}
pages = vmalloc(sizeof(struct page *) * buf->page_number);
- if (!pages)
+ if (!pages) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(pages));
return CQM_FAIL;
+ }
for (i = 0; i < buf->buf_number; i++) {
for (j = 0; j < ((u32)1 << order); j++)
@@ -273,6 +275,11 @@ s32 cqm_buf_alloc_direct(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *
return CQM_SUCCESS;
}
+static bool check_use_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ return buf->buf_info.use_vram ? true : false;
+}
+
static bool check_use_non_vram(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
{
return buf->buf_info.use_vram ? false : true;
@@ -294,11 +301,48 @@ static bool check_for_nouse_node_alloc(struct hinic3_hwdev *handle, struct tag_c
return false;
}
+static s32 cqm_buf_vram_kalloc(struct hinic3_hwdev *handle, struct tag_cqm_buf *buf)
+{
+ void *vaddr = NULL;
+ int i;
+
+ vaddr = hi_vram_kalloc(buf->buf_info.buf_vram_name, (u64)buf->buf_size * buf->buf_number);
+ if (!vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
+ return CQM_FAIL;
+ }
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = (void *)((char *)vaddr + i * (u64)buf->buf_size);
+
+ return CQM_SUCCESS;
+}
+
+static void cqm_buf_vram_free(struct tag_cqm_buf *buf)
+{
+ s32 i;
+
+ if (buf->buf_list == NULL) {
+ return;
+ }
+
+ if (buf->buf_list[0].va)
+ hi_vram_kfree(buf->buf_list[0].va, buf->buf_info.buf_vram_name,
+ (u64)buf->buf_size * buf->buf_number);
+
+ for (i = 0; i < (s32)buf->buf_number; i++)
+ buf->buf_list[i].va = NULL;
+}
+
static void cqm_buf_free_page_common(struct tag_cqm_buf *buf)
{
u32 order;
s32 i;
+ if (buf->buf_list == NULL) {
+ return;
+ }
+
order = (u32)get_order(buf->buf_size);
for (i = 0; i < (s32)buf->buf_number; i++) {
@@ -320,8 +364,10 @@ static s32 cqm_buf_use_node_alloc_page(struct hinic3_hwdev *handle, struct tag_c
node = dev_to_node(handle->dev_hdl);
for (i = 0; i < (s32)buf->buf_number; i++) {
newpage = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, order);
- if (!newpage)
+ if (!newpage) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
va = (void *)page_address(newpage);
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
@@ -349,8 +395,10 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
for (i = 0; i < (s32)buf->buf_number; i++) {
va = (void *)ossl_get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
- if (!va)
+ if (!va) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(buf_page));
break;
+ }
/* Initialize the page after the page is applied for.
* If hash entries are involved, the initialization
* value must be 0.
@@ -367,21 +415,21 @@ static s32 cqm_buf_unused_node_alloc_page(struct hinic3_hwdev *handle, struct ta
return CQM_SUCCESS;
}
-#define MALLOC_FUNCS_COUNT 2
-#define FREE_FUNCS_COUNT 1
-static const struct malloc_memory g_malloc_funcs[MALLOC_FUNCS_COUNT] = {
+static const struct malloc_memory g_malloc_funcs[] = {
+ {check_use_vram, cqm_buf_vram_kalloc},
{check_for_use_node_alloc, cqm_buf_use_node_alloc_page},
{check_for_nouse_node_alloc, cqm_buf_unused_node_alloc_page}
};
-static const struct free_memory g_free_funcs[FREE_FUNCS_COUNT] = {
+static const struct free_memory g_free_funcs[] = {
+ {check_use_vram, cqm_buf_vram_free},
{check_use_non_vram, cqm_buf_free_page_common}
};
static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_buf *buf)
{
struct hinic3_hwdev *handle = cqm_handle->ex_handle;
- u32 malloc_funcs_num = MALLOC_FUNCS_COUNT;
+ u32 malloc_funcs_num = ARRAY_SIZE(g_malloc_funcs);
u32 i;
for (i = 0; i < malloc_funcs_num; i++) {
@@ -398,7 +446,7 @@ static s32 cqm_buf_alloc_page(struct tag_cqm_handle *cqm_handle, struct tag_cqm_
static void cqm_buf_free_page(struct tag_cqm_buf *buf)
{
- u32 free_funcs_num = FREE_FUNCS_COUNT;
+ u32 free_funcs_num = ARRAY_SIZE(g_free_funcs);
u32 i;
for (i = 0; i < free_funcs_num; i++) {
@@ -447,8 +495,11 @@ static s32 cqm_buf_get_secure_mem_pages(struct tag_cqm_handle *cqm_handle, struc
cqm_get_secure_mem_pages(handle,
(u32)get_order(buf->buf_size),
&buf->buf_list[i].pa);
- if (!buf->buf_list[i].va)
+ if (!buf->buf_list[i].va) {
+ cqm_err(handle->dev_hdl,
+ CQM_ALLOC_FAIL(cqm_get_secure_mem_pages));
break;
+ }
}
if (i != buf->buf_number) {
@@ -780,7 +831,10 @@ static s32 cqm_single_bitmap_init(struct tag_cqm_bitmap *bitmap)
*/
bit_number = (ALIGN(bitmap->max_num, CQM_NUM_BIT_BYTE) >>
CQM_BYTE_BIT_SHIFT);
- bitmap->table = vmalloc(bit_number);
+ if (bitmap->bitmap_info.use_vram != 0)
+ bitmap->table = hi_vram_kalloc(bitmap->bitmap_info.buf_vram_name, bit_number);
+ else
+ bitmap->table = vmalloc(bit_number);
if (!bitmap->table)
return CQM_FAIL;
memset(bitmap->table, 0, bit_number);
@@ -859,7 +913,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
}
bitmap = &cla_table->bitmap;
- snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(bitmap->bitmap_info.buf_vram_name, VRAM_NAME_APPLY_LEN,
"%s%s%02d", cla_table->name,
VRAM_CQM_BITMAP_BASE, cla_table->type);
@@ -869,6 +923,7 @@ s32 cqm_bitmap_init(struct tag_cqm_handle *cqm_handle)
bitmap->reserved_top = capability->qpc_reserved;
bitmap->reserved_back = capability->qpc_reserved_back;
bitmap->last = capability->qpc_reserved;
+ bitmap->bitmap_info.use_vram = get_use_vram_flag();
cqm_info(handle->dev_hdl,
"Bitmap init: cla_table_type=%u, max_num=0x%x\n",
cla_table->type, bitmap->max_num);
@@ -948,7 +1003,12 @@ void cqm_bitmap_uninit(struct tag_cqm_handle *cqm_handle)
if (cla_table->type != CQM_BAT_ENTRY_T_INVALID &&
bitmap->table) {
spin_lock_deinit(&bitmap->lock);
- vfree(bitmap->table);
+ if (bitmap->bitmap_info.use_vram != 0)
+ hi_vram_kfree(bitmap->table, bitmap->bitmap_info.buf_vram_name,
+ ALIGN(bitmap->max_num, CQM_NUM_BIT_BYTE) >>
+ CQM_BYTE_BIT_SHIFT);
+ else
+ vfree(bitmap->table);
bitmap->table = NULL;
}
}
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
index 7febf76..06b8661 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_bitmap_table.h
@@ -9,6 +9,7 @@
#include <linux/spinlock.h>
#include "cqm_object.h"
+#include "vram_common.h"
struct tag_cqm_bitmap {
ulong *table;
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c
index cf7df37..3d38edc 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_cmd.c
@@ -15,7 +15,6 @@
#include "cqm_bitmap_table.h"
#include "cqm_bat_cla.h"
#include "cqm_main.h"
-#include "cqm_cmd.h"
/**
* cqm_cmd_alloc - Apply for a cmd buffer. The buffer size is fixed to 2 KB,
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
index 9a13ae0..db65c8b 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_db.c
@@ -196,6 +196,12 @@ void *cqm_get_db_addr(void *ex_handle, u32 service_type)
pr_err("[CQM]%s: ex_handle is null\n", __func__);
return NULL;
}
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return NULL;
+ }
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -218,6 +224,17 @@ s32 cqm_ring_hardware_db(void *ex_handle, u32 service_type, u8 db_count, u64 db)
struct tag_cqm_service *service = NULL;
struct hinic3_hwdev *handle = NULL;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
@@ -278,6 +295,17 @@ s32 cqm_ring_direct_wqe_db(void *ex_handle, u32 service_type, u8 db_count,
u64 *tmp = (u64 *)direct_wqe;
int i;
+ if (unlikely(!ex_handle)) {
+ pr_err("[CQM]%s: ex_handle is null\n", __func__);
+ return CQM_FAIL;
+ }
+
+ if (service_type >= CQM_SERVICE_T_MAX) {
+ pr_err("%s service_type = %d state is error\n", __func__,
+ service_type);
+ return CQM_FAIL;
+ }
+
handle = (struct hinic3_hwdev *)ex_handle;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
service = &cqm_handle->service[service_type];
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
index 19a8b56..0e8a579 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.c
@@ -23,6 +23,8 @@
#include "cqm_memsec.h"
#include "cqm_main.h"
+#include "vram_common.h"
+
static unsigned char roce_qpc_rsv_mode = CQM_QPC_ROCE_NORMAL;
module_param(roce_qpc_rsv_mode, byte, 0644);
MODULE_PARM_DESC(roce_qpc_rsv_mode,
@@ -98,10 +100,17 @@ static s32 cqm_set_timer_enable(void *ex_handle)
{
struct hinic3_hwdev *handle = (struct hinic3_hwdev *)ex_handle;
struct tag_cqm_handle *cqm_handle = NULL;
+ int is_in_kexec;
if (!ex_handle)
return CQM_FAIL;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ cqm_info(handle->dev_hdl, "Skip starting cqm timer during kexec\n");
+ return CQM_SUCCESS;
+ }
+
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
if (cqm_handle->func_capability.fake_func_type == CQM_FAKE_FUNC_PARENT &&
cqm_set_fake_vf_timer(cqm_handle) != CQM_SUCCESS)
@@ -456,7 +465,7 @@ static void cqm_service_capability_init_roce(struct tag_cqm_handle *cqm_handle,
cqm_info(handle->dev_hdl, "Cap init: roce qpc 0x%x, scqc 0x%x, srqc 0x%x, drc_qp 0x%x\n",
roce_own_cap->max_qps, roce_own_cap->max_cqs,
roce_own_cap->max_srqs, roce_own_cap->max_drc_qps);
- cqm_info(handle->dev_hdl, "Cap init: type 0x%x, scenes:0x%x, qpc_rsv:0x%x, srv_bmp:0x%x\n",
+ cqm_info(handle->dev_hdl, "Cap init: board_type 0x%x, scenes_id:0x%x, qpc_rsv_mode:0x%x, srv_bmp:0x%x\n",
board_info->board_type, board_info->scenes_id,
roce_qpc_rsv_mode, board_info->service_en_bitmap);
@@ -610,7 +619,7 @@ static void cqm_service_capability_init_ipsec(struct tag_cqm_handle *cqm_handle,
func_cap->scqc_basic_size);
func_cap->scqc_alloc_static = true;
cqm_info(handle->dev_hdl, "Cap init: ipsec is valid\n");
- cqm_info(handle->dev_hdl, "Cap init: ipsec 0x%x, childc %d, scqc 0x%x, scqc_bsize %d\n",
+ cqm_info(handle->dev_hdl, "Cap init: ipsec childc_num 0x%x, childc_bsize %d, scqc_num 0x%x, scqc_bsize %d\n",
ipsec_srvcap->max_sactxs, func_cap->childc_basic_size,
ipsec_srvcap->max_cqs, func_cap->scqc_basic_size);
}
@@ -812,7 +821,7 @@ static int cqm_capability_init_bloomfilter(struct hinic3_hwdev *handle)
func_cap->bloomfilter_addr = service_capability->bfilter_start_addr;
if (func_cap->bloomfilter_length != 0 &&
!cqm_check_align(func_cap->bloomfilter_length)) {
- cqm_err(handle->dev_hdl, "Cap bloomfilter len %u is not the power of 2\n",
+ cqm_err(handle->dev_hdl, "Cap init: bloomfilter_length %u is not the power of 2\n",
func_cap->bloomfilter_length);
return CQM_FAIL;
@@ -883,7 +892,7 @@ static int cqm_capability_init_timer(struct hinic3_hwdev *handle)
func_cap->timer_vf_num = service_capability->timer_vf_num;
func_cap->timer_vf_id_start = service_capability->timer_vf_id_start;
cqm_info(handle->dev_hdl,
- "timer init: pf_num 0x%x, pf_start 0x%x, vf_num 0x%x, vf_start 0x%x\n",
+ "host timer init: timer_pf_num 0x%x, timer_pf_id_start 0x%x, timer_vf_num 0x%x, timer_vf_id_start 0x%x\n",
func_cap->timer_pf_num, func_cap->timer_pf_id_start,
func_cap->timer_vf_num, func_cap->timer_vf_id_start);
@@ -891,7 +900,7 @@ static int cqm_capability_init_timer(struct hinic3_hwdev *handle)
if (IS_SLAVE_HOST(handle)) {
total_timer_num *= CQM_TIMER_NUM_MULTI;
cqm_info(handle->dev_hdl,
- "timer init: need double tw resources, total_timer_num=0x%x\n",
+ "host timer init: need double tw resources, total_timer_num=0x%x\n",
total_timer_num);
}
}
@@ -1059,8 +1068,10 @@ static s32 cqm_fake_init(struct tag_cqm_handle *cqm_handle)
for (i = 0; i < (u32)child_func_number; i++) {
fake_cqm_handle = kmalloc(sizeof(*fake_cqm_handle), GFP_KERNEL | __GFP_ZERO);
- if (!fake_cqm_handle)
+ if (!fake_cqm_handle) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(fake_cqm_handle));
goto err;
+ }
/* Copy the attributes of the parent CQM handle to the child CQM
* handle and modify the values of function.
@@ -1129,7 +1140,7 @@ static s32 cqm_fake_mem_init(struct tag_cqm_handle *cqm_handle)
for (i = 0; i < (u32)child_func_number; i++) {
fake_cqm_handle = cqm_handle->fake_cqm_handle[i];
- snprintf(fake_cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(fake_cqm_handle->name, VRAM_NAME_APPLY_LEN,
"%s%s%02u", cqm_handle->name, VRAM_CQM_FAKE_MEM_BASE, i);
if (cqm_bat_init(fake_cqm_handle) != CQM_SUCCESS) {
@@ -1174,7 +1185,7 @@ s32 cqm_mem_init(void *ex_handle)
struct tag_cqm_handle *cqm_handle = NULL;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
- snprintf(cqm_handle->name, VRAM_NAME_MAX_LEN - 1,
+ snprintf(cqm_handle->name, VRAM_NAME_APPLY_LEN,
"%s%02u", VRAM_CQM_GLB_FUNC_BASE, hinic3_global_func_id(handle));
if (cqm_fake_init(cqm_handle) != CQM_SUCCESS) {
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
index 4f87bd1..8d1e481 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_main.h
@@ -362,6 +362,7 @@ s32 cqm_fake_vf_num_set(void *ex_handle, u16 fake_vf_num_cfg);
#define CQM_LOG_ID 0
#define CQM_PTR_NULL(x) "%s: " #x " is null\n", __func__
+#define CQM_ALLOC_FAIL(x) "%s: " #x " alloc fail\n", __func__
#define CQM_MAP_FAIL(x) "%s: " #x " map fail\n", __func__
#define CQM_FUNCTION_FAIL(x) "%s: " #x " return failure\n", __func__
#define CQM_WRONG_VALUE(x) "%s: " #x " %u is wrong\n", __func__, (u32)(x)
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
index 4888b0a..d3def81 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_memsec.c
@@ -21,6 +21,7 @@
#include "cqm_bloomfilter.h"
#include "cqm_db.h"
#include "cqm_main.h"
+#include "vram_common.h"
#include "vmsec_mpu_common.h"
#include "cqm_memsec.h"
@@ -34,6 +35,8 @@
#define STD_INPUT_ONE_PARA 1
#define STD_INPUT_TWO_PARA 2
#define MR_KEY_2_INDEX_SHIFT 8
+#define IS_ADDR_IN_MEMSEC(va, len, start, end) \
+ ((va) >= (start) && (va) + (len) < (end))
static int memsec_proc_show(struct seq_file *seq, void *offset);
static int memsec_proc_open(struct inode *inode, struct file *file);
@@ -46,15 +49,24 @@ static int hinic3_secure_mem_proc_node_add(void *hwdev);
static ssize_t memsec_proc_write(struct file *file, const char __user *data, size_t len,
loff_t *pff);
-static struct proc_dir_entry *g_hinic3_memsec_proc_ent; /* proc dir */
+static struct proc_dir_entry *g_hinic3_memsec_proc_ent = NULL; /* proc dir */
static atomic_t g_memsec_proc_refcnt = ATOMIC_INIT(0);
+#if KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE
+static const struct file_operations memsec_proc_fops = {
+ .open = memsec_proc_open,
+ .read = seq_read,
+ .write = memsec_proc_write,
+ .release = memsec_proc_release,
+};
+#else
static const struct proc_ops memsec_proc_fops = {
.proc_open = memsec_proc_open,
.proc_read = seq_read,
.proc_write = memsec_proc_write,
.proc_release = memsec_proc_release,
};
+#endif
bool cqm_need_secure_mem(void *hwdev)
{
@@ -63,6 +75,9 @@ bool cqm_need_secure_mem(void *hwdev)
struct hinic3_hwdev *handle = (struct hinic3_hwdev *)hwdev;
cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
+ if (cqm_handle == NULL) {
+ return false;
+ }
info = &cqm_handle->secure_mem;
return ((info->need_secure_mem) && hinic3_is_guest_vmsec_enable(hwdev));
}
@@ -275,9 +290,10 @@ static int test_query_context(struct hinic3_hwdev *handle, char *data, size_t le
case CQM_OBJECT_SERVICE_CTX:
case CQM_OBJECT_MPT:
qpc_mpt = (struct tag_cqm_qpc_mpt *)cqm_obj;
- if (qpc_mpt->vaddr >= (u8 *)info->va_base &&
- (qpc_mpt->vaddr + cqm_obj->object_size) < (u8 *)info->va_end)
- in_secmem = true;
+ in_secmem = IS_ADDR_IN_MEMSEC(qpc_mpt->vaddr,
+ cqm_obj->object_size,
+ (u8 *)info->va_base,
+ (u8 *)info->va_end);
cqm_info(handle->dev_hdl,
"[memsec_dfx]Query %s:0x%x, va=%p %sin secure mem\n",
query_type == CQM_OBJECT_MPT ? "MPT, mpt_index" : "QPC, qpn",
@@ -286,9 +302,10 @@ static int test_query_context(struct hinic3_hwdev *handle, char *data, size_t le
case CQM_OBJECT_RDMA_SRQ:
case CQM_OBJECT_RDMA_SCQ:
cqm_queue = (struct tag_cqm_queue *)cqm_obj;
- if (cqm_queue->q_ctx_vaddr >= (u8 *)info->va_base &&
- (cqm_queue->q_ctx_vaddr + cqm_obj->object_size) < (u8 *)info->va_end)
- in_secmem = true;
+ in_secmem = IS_ADDR_IN_MEMSEC(cqm_queue->q_ctx_vaddr,
+ cqm_obj->object_size,
+ (u8 *)info->va_base,
+ (u8 *)info->va_end);
cqm_info(handle->dev_hdl,
"[memsec_dfx]Query %s:0x%x, va=%p %sin secure mem\n",
query_type == CQM_OBJECT_RDMA_SRQ ? "SRQC, srqn " : "SCQC, scqn",
@@ -378,7 +395,7 @@ static int hinic3_secure_mem_proc_node_remove(void *hwdev)
atomic_dec(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
@@ -401,7 +418,7 @@ static int hinic3_secure_mem_proc_node_add(void *hwdev)
atomic_inc(&g_memsec_proc_refcnt);
- snprintf(pci_name, PCI_PROC_NAME_LEN - 1,
+ snprintf(pci_name, PCI_PROC_NAME_LEN,
"%02x:%02x:%x", pdev->bus->number, pdev->slot->number,
PCI_FUNC(pdev->devfn));
/* 0400 Read by owner */
@@ -653,7 +670,7 @@ void cqm_free_secure_mem_pages(struct hinic3_hwdev *handle, void *va, u32 order)
return;
}
- if (va < info->va_base || va > (info->va_end - PAGE_SIZE) ||
+ if (va < info->va_base || (va > (info->va_end - PAGE_SIZE)) ||
!PAGE_ALIGNED((va - info->va_base)))
cqm_err(handle->dev_hdl, "%s va wrong value\n", __func__);
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c
index 7d1bd35..86359c0 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object.c
@@ -180,8 +180,10 @@ struct tag_cqm_queue *cqm_object_recv_queue_create(void *ex_handle, u32 service_
rq_qinfo->common.q_header_vaddr =
cqm_kmalloc_align(sizeof(struct tag_cqm_queue_header),
GFP_KERNEL | __GFP_ZERO, CQM_QHEAD_ALIGN_ORDER);
- if (!rq_qinfo->common.q_header_vaddr)
+ if (!rq_qinfo->common.q_header_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_header_vaddr));
goto err1;
+ }
rq_qinfo->common.q_header_paddr =
pci_map_single(cqm_handle->dev, rq_qinfo->common.q_header_vaddr,
@@ -484,7 +486,8 @@ static bool cqm_object_nonrdma_queue_param_check(struct hinic3_hwdev *handle, u3
struct tag_cqm_handle *cqm_handle = (struct tag_cqm_handle *)(handle->cqm_hdl);
/* exception of service registrion check */
- if (!cqm_handle->service[service_type].has_register) {
+ if (service_type >= CQM_SERVICE_T_MAX ||
+ !cqm_handle->service[service_type].has_register) {
cqm_err(handle->dev_hdl, CQM_WRONG_VALUE(service_type));
return false;
}
@@ -1487,4 +1490,4 @@ void cqm_srq_used_rq_container_delete(struct tag_cqm_object *object, u8 *contain
}
kfree((void *)addr);
}
-EXPORT_SYMBOL(cqm_srq_used_rq_container_delete);
+EXPORT_SYMBOL(cqm_srq_used_rq_container_delete);
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c
index 92c19c4..1007b44 100644
--- a/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c
+++ b/drivers/net/ethernet/huawei/hinic3/cqm/cqm_object_intern.c
@@ -127,8 +127,10 @@ s32 cqm_container_create(struct tag_cqm_object *object, u8 **container_addr, boo
* of the Container.
*/
new_container = kmalloc(qinfo->container_size, GFP_ATOMIC | __GFP_ZERO);
- if (!new_container)
+ if (!new_container) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(new_container));
return CQM_FAIL;
+ }
/* Container PCI mapping */
new_container_pa = pci_map_single(cqm_handle->dev, new_container,
@@ -299,8 +301,10 @@ s32 cqm_share_recv_queue_create(struct tag_cqm_object *object)
/* apply for buffer for SRQC */
common->q_ctx_vaddr = kmalloc(qinfo->q_ctx_size,
GFP_KERNEL | __GFP_ZERO);
- if (!common->q_ctx_vaddr)
+ if (!common->q_ctx_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_ctx_vaddr));
goto err2;
+ }
return CQM_SUCCESS;
err2:
@@ -808,8 +812,10 @@ static s32 cqm_nonrdma_queue_ctx_create(struct tag_cqm_object *object)
common->q_ctx_vaddr = cqm_kmalloc_align(qinfo->q_ctx_size,
GFP_KERNEL | __GFP_ZERO,
(u16)shift);
- if (!common->q_ctx_vaddr)
+ if (!common->q_ctx_vaddr) {
+ cqm_err(handle->dev_hdl, CQM_ALLOC_FAIL(q_ctx_vaddr));
return CQM_FAIL;
+ }
common->q_ctx_paddr = pci_map_single(cqm_handle->dev, common->q_ctx_vaddr,
qinfo->q_ctx_size, PCI_DMA_BIDIRECTIONAL);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h b/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
deleted file mode 100644
index ad732c3..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_comm_cmd.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2019-2022. All rights reserved.
- * File Name : hinic3_comm_cmd.h
- * Version : Initial Draft
- * Created : 2019/4/25
- * Last Modified :
- * Description : COMM Commands between Driver and MPU
- * Function List :
- */
-
-#ifndef HINIC3_COMMON_CMD_H
-#define HINIC3_COMMON_CMD_H
-
-/* COMM Commands between Driver to MPU */
-enum hinic3_mgmt_cmd {
- /* flr及资源清理相关命令 */
- COMM_MGMT_CMD_FUNC_RESET = 0,
- COMM_MGMT_CMD_FEATURE_NEGO,
- COMM_MGMT_CMD_FLUSH_DOORBELL,
- COMM_MGMT_CMD_START_FLUSH,
- COMM_MGMT_CMD_SET_FUNC_FLR,
- COMM_MGMT_CMD_GET_GLOBAL_ATTR,
- COMM_MGMT_CMD_SET_PPF_FLR_TYPE,
- COMM_MGMT_CMD_SET_FUNC_SVC_USED_STATE,
-
- /* 分配msi-x中断资源 */
- COMM_MGMT_CMD_CFG_MSIX_NUM = 10,
-
- /* 驱动相关配置命令 */
- COMM_MGMT_CMD_SET_CMDQ_CTXT = 20,
- COMM_MGMT_CMD_SET_VAT,
- COMM_MGMT_CMD_CFG_PAGESIZE,
- COMM_MGMT_CMD_CFG_MSIX_CTRL_REG,
- COMM_MGMT_CMD_SET_CEQ_CTRL_REG,
- COMM_MGMT_CMD_SET_DMA_ATTR,
-
- /* INFRA配置相关命令字 */
- COMM_MGMT_CMD_GET_MQM_FIX_INFO = 40,
- COMM_MGMT_CMD_SET_MQM_CFG_INFO,
- COMM_MGMT_CMD_SET_MQM_SRCH_GPA,
- COMM_MGMT_CMD_SET_PPF_TMR,
- COMM_MGMT_CMD_SET_PPF_HT_GPA,
- COMM_MGMT_CMD_SET_FUNC_TMR_BITMAT,
- COMM_MGMT_CMD_SET_MBX_CRDT,
- COMM_MGMT_CMD_CFG_TEMPLATE,
- COMM_MGMT_CMD_SET_MQM_LIMIT,
-
- /* 信息获取相关命令字 */
- COMM_MGMT_CMD_GET_FW_VERSION = 60,
- COMM_MGMT_CMD_GET_BOARD_INFO,
- COMM_MGMT_CMD_SYNC_TIME,
- COMM_MGMT_CMD_GET_HW_PF_INFOS,
- COMM_MGMT_CMD_SEND_BDF_INFO,
- COMM_MGMT_CMD_GET_VIRTIO_BDF_INFO,
- COMM_MGMT_CMD_GET_SML_TABLE_INFO,
- COMM_MGMT_CMD_GET_SDI_INFO,
-
- /* 升级相关命令字 */
- COMM_MGMT_CMD_UPDATE_FW = 80,
- COMM_MGMT_CMD_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_FW,
- COMM_MGMT_CMD_HOT_ACTIVE_DONE_NOTICE,
- COMM_MGMT_CMD_SWITCH_CFG,
- COMM_MGMT_CMD_CHECK_FLASH,
- COMM_MGMT_CMD_CHECK_FLASH_RW,
- COMM_MGMT_CMD_RESOURCE_CFG,
- COMM_MGMT_CMD_UPDATE_BIOS, /* TODO: merge to COMM_MGMT_CMD_UPDATE_FW */
- COMM_MGMT_CMD_MPU_GIT_CODE,
-
- /* chip reset相关 */
- COMM_MGMT_CMD_FAULT_REPORT = 100,
- COMM_MGMT_CMD_WATCHDOG_INFO,
- COMM_MGMT_CMD_MGMT_RESET,
- COMM_MGMT_CMD_FFM_SET, /* TODO: check if needed */
-
- /* chip info/log 相关 */
- COMM_MGMT_CMD_GET_LOG = 120,
- COMM_MGMT_CMD_TEMP_OP,
- COMM_MGMT_CMD_EN_AUTO_RST_CHIP,
- COMM_MGMT_CMD_CFG_REG,
- COMM_MGMT_CMD_GET_CHIP_ID,
- COMM_MGMT_CMD_SYSINFO_DFX,
- COMM_MGMT_CMD_PCIE_DFX_NTC,
- COMM_MGMT_CMD_DICT_LOG_STATUS, /* LOG STATUS 127 */
- COMM_MGMT_CMD_MSIX_INFO,
- COMM_MGMT_CMD_CHANNEL_DETECT,
- COMM_MGMT_CMD_DICT_COUNTER_STATUS,
-
- /* switch workmode 相关 */
- COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140,
- COMM_MGMT_CMD_SWITCH_WORKMODE,
-
- /* mpu 相关 */
- COMM_MGMT_CMD_MIGRATE_DFX_HPA = 150,
- COMM_MGMT_CMD_BDF_INFO,
- COMM_MGMT_CMD_NCSI_CFG_INFO_GET_PROC,
-
- /* rsvd0 section */
- COMM_MGMT_CMD_SECTION_RSVD_0 = 160,
-
- /* rsvd1 section */
- COMM_MGMT_CMD_SECTION_RSVD_1 = 170,
-
- /* rsvd2 section */
- COMM_MGMT_CMD_SECTION_RSVD_2 = 180,
-
- /* rsvd3 section */
- COMM_MGMT_CMD_SECTION_RSVD_3 = 190,
-
- /* TODO: move to DFT mode */
- COMM_MGMT_CMD_GET_DIE_ID = 200,
- COMM_MGMT_CMD_GET_EFUSE_TEST,
- COMM_MGMT_CMD_EFUSE_INFO_CFG,
- COMM_MGMT_CMD_GPIO_CTL,
- COMM_MGMT_CMD_HI30_SERLOOP_START, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_SERLOOP_STOP, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_SET_FLAG, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_HI30_MBIST_GET_RESULT, /* TODO: DFT or hilink */
- COMM_MGMT_CMD_ECC_TEST,
- COMM_MGMT_CMD_FUNC_BIST_TEST, /* 209 */
-
- COMM_MGMT_CMD_VPD_SET = 210,
- COMM_MGMT_CMD_VPD_GET,
-
- COMM_MGMT_CMD_ERASE_FLASH,
- COMM_MGMT_CMD_QUERY_FW_INFO,
- COMM_MGMT_CMD_GET_CFG_INFO,
- COMM_MGMT_CMD_GET_UART_LOG,
- COMM_MGMT_CMD_SET_UART_CMD,
- COMM_MGMT_CMD_SPI_TEST,
-
- /* TODO: ALL reg read/write merge to COMM_MGMT_CMD_CFG_REG */
- COMM_MGMT_CMD_UP_REG_GET,
- COMM_MGMT_CMD_UP_REG_SET, /* 219 */
-
- COMM_MGMT_CMD_REG_READ = 220,
- COMM_MGMT_CMD_REG_WRITE,
- COMM_MGMT_CMD_MAG_REG_WRITE,
- COMM_MGMT_CMD_ANLT_REG_WRITE,
-
- COMM_MGMT_CMD_HEART_EVENT, /* TODO: delete */
- COMM_MGMT_CMD_NCSI_OEM_GET_DRV_INFO, /* TODO: delete */
- COMM_MGMT_CMD_LASTWORD_GET,
- COMM_MGMT_CMD_READ_BIN_DATA, /* TODO: delete */
- /* COMM_MGMT_CMD_WWPN_GET, TODO: move to FC? */
- /* COMM_MGMT_CMD_WWPN_SET, TODO: move to FC? */ /* 229 */
-
- /* TODO: check if needed */
- COMM_MGMT_CMD_SET_VIRTIO_DEV = 230,
- COMM_MGMT_CMD_SET_MAC,
- /* MPU patch cmd */
- COMM_MGMT_CMD_LOAD_PATCH,
- COMM_MGMT_CMD_REMOVE_PATCH,
- COMM_MGMT_CMD_PATCH_ACTIVE,
- COMM_MGMT_CMD_PATCH_DEACTIVE,
- COMM_MGMT_CMD_PATCH_SRAM_OPTIMIZE,
- /* container host process */
- COMM_MGMT_CMD_CONTAINER_HOST_PROC,
- /* nsci counter */
- COMM_MGMT_CMD_NCSI_COUNTER_PROC,
- COMM_MGMT_CMD_CHANNEL_STATUS_CHECK, /* 239 */
-
- /* hot patch rsvd cmd */
- COMM_MGMT_CMD_RSVD_0 = 240,
- COMM_MGMT_CMD_RSVD_1,
- COMM_MGMT_CMD_RSVD_2,
- COMM_MGMT_CMD_RSVD_3,
- COMM_MGMT_CMD_RSVD_4,
- /* 无效字段,版本收编删除,编译使用 */
- COMM_MGMT_CMD_SEND_API_ACK_BY_UP,
-
- /* 注:添加cmd,不能修改已有命令字的值,请在前方rsvd
- * section中添加;原则上所有分支cmd表完全一致
- */
- COMM_MGMT_CMD_MAX = 255,
-};
-
-/* CmdQ Common subtype */
-enum comm_cmdq_cmd {
- COMM_CMD_UCODE_ARM_BIT_SET = 2,
- COMM_CMD_SEND_NPU_DFT_CMD,
-};
-
-#endif /* HINIC3_COMMON_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
deleted file mode 100644
index 9ce908e..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_common.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_COMMON_H
-#define HINIC3_COMMON_H
-
-#include <linux/types.h>
-
-struct hinic3_dma_addr_align {
- u32 real_size;
-
- void *ori_vaddr;
- dma_addr_t ori_paddr;
-
- void *align_vaddr;
- dma_addr_t align_paddr;
-};
-
-enum hinic3_wait_return {
- WAIT_PROCESS_CPL = 0,
- WAIT_PROCESS_WAITING = 1,
- WAIT_PROCESS_ERR = 2,
-};
-
-struct hinic3_sge {
- u32 hi_addr;
- u32 lo_addr;
- u32 len;
-};
-
-#ifdef static
-#undef static
-#define LLT_STATIC_DEF_SAVED
-#endif
-
-/* *
- * hinic_cpu_to_be32 - convert data to big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert, must be Multiple of 4B
- */
-static inline void hinic3_cpu_to_be32(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = cpu_to_be32(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_cpu_to_be32 - convert data from big endian 32 bit format
- * @data: the data to convert
- * @len: length of data to convert
- */
-static inline void hinic3_be32_to_cpu(void *data, int len)
-{
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = be32_to_cpu(*mem);
- mem++;
- }
-}
-
-/* *
- * hinic3_set_sge - set dma area in scatter gather entry
- * @sge: scatter gather entry
- * @addr: dma address
- * @len: length of relevant data in the dma address
- */
-static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
- int len)
-{
- sge->hi_addr = upper_32_bits(addr);
- sge->lo_addr = lower_32_bits(addr);
- sge->len = len;
-}
-
-#define hinic3_hw_be32(val) (val)
-#define hinic3_hw_cpu32(val) (val)
-#define hinic3_hw_cpu16(val) (val)
-
-static inline void hinic3_hw_be32_len(void *data, int len)
-{
-}
-
-static inline void hinic3_hw_cpu32_len(void *data, int len)
-{
-}
-
-int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
- unsigned int flag,
- struct hinic3_dma_addr_align *mem_align);
-
-void hinic3_dma_free_coherent_align(void *dev_hdl,
- struct hinic3_dma_addr_align *mem_align);
-
-typedef enum hinic3_wait_return (*wait_cpl_handler)(void *priv_data);
-
-int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
- u32 wait_total_ms, u32 wait_once_us);
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
index f269691..7979244 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_crm.h
@@ -8,7 +8,7 @@
#include "mpu_cmd_base_defs.h"
-#define HINIC3_DRV_VERSION "15.17.1.1"
+#define HINIC3_DRV_VERSION "17.7.8.1"
#define HINIC3_DRV_DESC "Intelligent Network Interface Card Driver"
#define HIUDK_DRV_DESC "Intelligent Network Unified Driver"
@@ -45,6 +45,8 @@ enum hinic3_service_type {
SERVICE_T_CUSTOM,
SERVICE_T_VROCE,
SERVICE_T_CRYPT,
+ SERVICE_T_VSOCK,
+ SERVICE_T_BIFUR,
SERVICE_T_MAX,
/* Only used for interruption resource management,
@@ -63,6 +65,9 @@ struct nic_service_cap {
u16 max_sqs;
u16 max_rqs;
u16 default_num_queues;
+ u16 outband_vlan_cfg_en;
+ u8 lro_enable;
+ u8 rsvd1[3];
};
struct ppa_service_cap {
@@ -76,6 +81,10 @@ struct ppa_service_cap {
u16 rsvd1;
};
+struct bifur_service_cap {
+ u8 rsvd;
+};
+
struct vbs_service_cap {
u16 vbs_max_volq;
u8 vbs_main_pf_enable;
@@ -786,6 +795,15 @@ bool hinic3_support_toe(void *hwdev, struct toe_service_cap *cap);
bool hinic3_support_ppa(void *hwdev, struct ppa_service_cap *cap);
/* *
+ * @brief hinic3_support_bifur - function support bifur
+ * @param hwdev: device pointer to hwdev
+ * @param cap: bifur service capbility
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+bool hinic3_support_bifur(void *hwdev, struct bifur_service_cap *cap);
+
+/* *
* @brief hinic3_support_migr - function support migrate
* @param hwdev: device pointer to hwdev
* @param cap: migrate service capbility
@@ -896,6 +914,13 @@ int hinic3_get_fw_version(void *hwdev, struct hinic3_fw_version *fw_ver,
u16 channel);
/* *
+ * @brief hinic3_get_bond_create_mode - get bond create mode
+ * @param hwdev: device pointer to hwdev
+ * @retval global function id
+ */
+u8 hinic3_get_bond_create_mode(void *udkdev);
+
+/* *
* @brief hinic3_global_func_id - get global function id
* @param hwdev: device pointer to hwdev
* @retval global function id
@@ -1249,4 +1274,7 @@ int hinic3_mbox_to_host_sync(void *hwdev, enum hinic3_mod_type mod,
int hinic3_get_func_vroce_enable(void *hwdev, u16 glb_func_idx, u8 *en);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type);
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
index 5863bee..9b5f017 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dbg.c
@@ -18,9 +18,8 @@
#include "hinic3_tx.h"
#include "hinic3_dcb.h"
#include "hinic3_nic.h"
-#include "hinic3_mgmt_interface.h"
-#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "hinic3_bond.h"
+#include "nic_mpu_cmd_defs.h"
typedef int (*nic_driv_module)(struct hinic3_nic_dev *nic_dev,
const void *buf_in, u32 in_size,
@@ -48,7 +47,7 @@ static int get_nic_drv_version(void *buf_out, const u32 *out_size)
}
err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s",
- HINIC3_NIC_DRV_VERSION, "2024-07-03_09:33:00");
+ HINIC3_NIC_DRV_VERSION, "2025-05-01_00:00:03");
if (err < 0)
return -EINVAL;
@@ -94,13 +93,13 @@ static int get_q_num(struct hinic3_nic_dev *nic_dev,
return -EFAULT;
}
- if (!buf_out) {
+ if (!buf_out || !out_size) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Get queue number para buf_out is NULL.\n");
return -EINVAL;
}
- if (!out_size || *out_size != sizeof(u16)) {
+ if (*out_size != sizeof(u16)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user: %u, expect: %lu\n",
*out_size, sizeof(u16));
@@ -126,7 +125,8 @@ static int get_tx_wqe_info(struct hinic3_nic_dev *nic_dev,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -178,7 +178,8 @@ static int get_rx_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
rq_info->delta = (u16)nic_dev->rxqs[q_id].delta;
- rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx & nic_dev->rxqs[q_id].q_mask);
+ rq_info->ci = (u16)(nic_dev->rxqs[q_id].cons_idx &
+ nic_dev->rxqs[q_id].q_mask);
rq_info->sw_pi = nic_dev->rxqs[q_id].next_to_update;
rq_info->msix_vector = nic_dev->rxqs[q_id].irq_id;
@@ -201,7 +202,8 @@ static int get_rx_wqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
}
if (!buf_in || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Buf_in or buf_out is NULL.\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_in or buf_out is NULL.\n");
return -EINVAL;
}
@@ -230,7 +232,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EFAULT;
}
- if (!buf_in || !buf_out) {
+ if (!buf_in || !buf_out || !out_size) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Buf_in or buf_out is NULL.\n");
return -EINVAL;
@@ -243,7 +245,7 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return -EINVAL;
}
- if (!out_size || *out_size != sizeof(struct hinic3_rq_cqe)) {
+ if (*out_size != sizeof(struct hinic3_rq_cqe)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(struct hinic3_rq_cqe));
@@ -252,10 +254,16 @@ static int get_rx_cqe_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
q_id = (u16)info->q_id;
idx = (u16)info->wqe_id;
- if (q_id >= nic_dev->q_params.num_qps || idx >= nic_dev->rxqs[q_id].q_depth) {
+ if (q_id >= nic_dev->q_params.num_qps) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid q_id[%u] >= %u.\n", q_id,
+ nic_dev->q_params.num_qps);
+ return -EFAULT;
+ }
+ if (idx >= nic_dev->rxqs[q_id].q_depth) {
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Invalid q_id[%u] >= %u, or wqe idx[%u] >= %u.\n",
- q_id, nic_dev->q_params.num_qps, idx, nic_dev->rxqs[q_id].q_depth);
+ "Invalid wqe idx[%u] >= %u.\n", idx,
+ nic_dev->rxqs[q_id].q_depth);
return -EFAULT;
}
@@ -338,7 +346,8 @@ static int set_loopback_mode(struct hinic3_nic_dev *nic_dev, const void *buf_in,
err = hinic3_set_loopback_mode(nic_dev->hwdev, (u8)mode->loop_mode,
(u8)mode->loop_ctrl);
if (err == 0)
- nicif_info(nic_dev, drv, nic_dev->netdev, "Set loopback mode %u en %u succeed\n",
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Set loopback mode %u en %u succeed\n",
mode->loop_mode, mode->loop_ctrl);
return err;
@@ -417,6 +426,59 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
{
u32 pf_bw_limit;
int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
+
+ if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To set VF bandwidth rate, please use ip link cmd\n");
+ return -EINVAL;
+ }
+
+ if (!buf_in || !buf_out || in_size != sizeof(u32) ||
+ !out_size || *out_size != sizeof(u8))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_TX;
+ pf_bw_limit = *((u32 *)buf_in);
+
+ err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
+ if (err) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %u%%\n",
+ pf_bw_limit);
+ if (err < 0)
+ return err;
+ }
+
+ *((u8 *)buf_out) = (u8)err;
+
+ return 0;
+}
+
+static int set_rx_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ u32 pf_bw_limit;
+ int err;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct net_device *net_dev = nic_dev->netdev;
+
+ if (hinic3_support_roce(nic_dev->hwdev, NULL) &&
+ hinic3_is_bond_dev_status_actived(net_dev)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "The rate limit func is not supported when RoCE bonding is enabled\n");
+ return -EINVAL;
+ }
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
nicif_err(nic_dev, drv, nic_dev->netdev, "To set VF bandwidth rate, please use ip link cmd\n");
@@ -426,11 +488,16 @@ static int set_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || !buf_out || in_size != sizeof(u32) || !out_size || *out_size != sizeof(u8))
return -EINVAL;
+ nic_io = hinic3_get_service_adapter(nic_dev->hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+ nic_io->direct = HINIC3_NIC_RX;
pf_bw_limit = *((u32 *)buf_in);
err = hinic3_set_pf_bw_limit(nic_dev->hwdev, pf_bw_limit);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to set pf bandwidth limit to %d%%\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to set pf bandwidth limit to %d%%\n",
pf_bw_limit);
if (err < 0)
return err;
@@ -445,19 +512,21 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
struct hinic3_nic_io *nic_io = NULL;
+ u32 *rate_limit = (u32 *)buf_out;
if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "To get VF bandwidth rate, please use ip link cmd\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "To get VF bandwidth rate, please use ip link cmd\n");
return -EINVAL;
}
if (!buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(u32)) {
+ if (*out_size != sizeof(u32) * 2) { // 2:Stored in an array, TX and RX, both length are u32
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user: %d, expect: %lu\n",
- *out_size, sizeof(u32));
+ *out_size, sizeof(u32) * 2);
return -EFAULT;
}
@@ -465,8 +534,12 @@ static int get_pf_bw_limit(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!nic_io)
return -EINVAL;
- *((u32 *)buf_out) = nic_io->nic_cfg.pf_bw_limit;
+ rate_limit[HINIC3_NIC_RX] = nic_io->nic_cfg.pf_bw_rx_limit;
+ rate_limit[HINIC3_NIC_TX] = nic_io->nic_cfg.pf_bw_tx_limit;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "read rate cfg success rx rate is: %u, tx rate is : %u\n",
+ rate_limit[HINIC3_NIC_RX], rate_limit[HINIC3_NIC_TX]);
return 0;
}
@@ -477,8 +550,8 @@ static int get_sset_count(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (!buf_in || in_size != sizeof(u32) || !out_size ||
*out_size != sizeof(u32) || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
@@ -504,16 +577,16 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
int err;
if (!buf_in || in_size != sizeof(u32) || !out_size || !buf_out) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Invalid parameters, in_size: %u\n",
- in_size);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Invalid parameters, in_size: %u\n", in_size);
return -EINVAL;
}
size = sizeof(u32);
err = get_sset_count(nic_dev, buf_in, in_size, &count, &size);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Get sset count failed, ret=%d\n",
- err);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Get sset count failed, ret=%d\n", err);
return -EINVAL;
}
if (count * sizeof(*items) != *out_size) {
@@ -527,12 +600,14 @@ static int get_sset_stats(struct hinic3_nic_dev *nic_dev, const void *buf_in,
switch (sset) {
case HINIC3_SHOW_SSET_IO_STATS:
- hinic3_get_io_stats(nic_dev, items);
+ err = hinic3_get_io_stats(nic_dev, items);
+ if (err < 0)
+ return -EINVAL;
break;
default:
- nicif_err(nic_dev, drv, nic_dev->netdev, "Unknown %u to get stats\n",
- sset);
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unknown %u to get stats\n", sset);
err = -EINVAL;
break;
}
@@ -544,15 +619,18 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int i;
u8 cos_num = 0, valid_cos_bitmap = 0;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_PCP2COS) {
for (i = 0; i < NIC_DCB_UP_MAX; i++) {
- if (!(nic_dev->func_dft_cos_bitmap & BIT(qos_in->pcp2cos[i]))) {
+ if (!(dcb->func_dft_cos_bitmap &
+ BIT(qos_in->pcp2cos[i]))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- qos_in->pcp2cos[i], nic_dev->func_dft_cos_bitmap);
+ qos_in->pcp2cos[i],
+ dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -562,7 +640,8 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
}
- memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos, sizeof(qos_in->pcp2cos));
+ memcpy(wanted_dcb_cfg->pcp2cos, qos_in->pcp2cos,
+ sizeof(qos_in->pcp2cos));
wanted_dcb_cfg->pcp_user_cos_num = cos_num;
wanted_dcb_cfg->pcp_valid_cos_map = valid_cos_bitmap;
}
@@ -572,12 +651,14 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = 0;
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++) {
u8 cos = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->wanted_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ dcb->wanted_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
- if (cos >= NIC_DCB_UP_MAX || !(nic_dev->func_dft_cos_bitmap & BIT(cos))) {
+ if (cos >= NIC_DCB_UP_MAX ||
+ !(dcb->func_dft_cos_bitmap & BIT(cos))) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid cos=%u, func cos valid map is %u",
- cos, nic_dev->func_dft_cos_bitmap);
+ cos, dcb->func_dft_cos_bitmap);
return -EINVAL;
}
@@ -588,8 +669,10 @@ static int update_pcp_dscp_cfg(struct hinic3_nic_dev *nic_dev,
}
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- wanted_dcb_cfg->dscp2cos[i] = qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
- nic_dev->hw_dcb_cfg.dscp2cos[i] : qos_in->dscp2cos[i];
+ wanted_dcb_cfg->dscp2cos[i] =
+ qos_in->dscp2cos[i] == DBG_DFLT_DSCP_VAL ?
+ dcb->hw_dcb_cfg.dscp2cos[i] :
+ qos_in->dscp2cos[i];
wanted_dcb_cfg->dscp_user_cos_num = cos_num;
wanted_dcb_cfg->dscp_valid_cos_map = valid_cos_bitmap;
}
@@ -601,11 +684,12 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *wanted_dcb_cfg,
const struct hinic3_mt_qos_dev_cfg *qos_in)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int ret;
u8 cos_num, valid_cos_bitmap;
if (qos_in->cfg_bitmap & CMD_QOS_DEV_TRUST) {
- if (qos_in->trust > DCB_DSCP) {
+ if (qos_in->trust > HINIC3_DCB_DSCP) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid trust=%u\n", qos_in->trust);
return -EINVAL;
@@ -615,7 +699,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
}
if (qos_in->cfg_bitmap & CMD_QOS_DEV_DFT_COS) {
- if (!(BIT(qos_in->dft_cos) & nic_dev->func_dft_cos_bitmap)) {
+ if (!(BIT(qos_in->dft_cos) & dcb->func_dft_cos_bitmap)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Invalid dft_cos=%u\n", qos_in->dft_cos);
return -EINVAL;
@@ -628,7 +712,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
if (ret)
return ret;
- if (wanted_dcb_cfg->trust == DCB_PCP) {
+ if (wanted_dcb_cfg->trust == HINIC3_DCB_PCP) {
cos_num = wanted_dcb_cfg->pcp_user_cos_num;
valid_cos_bitmap = wanted_dcb_cfg->pcp_valid_cos_map;
} else {
@@ -636,18 +720,11 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
valid_cos_bitmap = wanted_dcb_cfg->dscp_valid_cos_map;
}
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "DCB is on, cos num should not more than channel num:%u\n",
- nic_dev->q_params.num_qps);
- return -EOPNOTSUPP;
- }
- }
-
if (!(BIT(wanted_dcb_cfg->default_cos) & valid_cos_bitmap)) {
- nicif_info(nic_dev, drv, nic_dev->netdev, "Current default_cos=%u, change to %u\n",
- wanted_dcb_cfg->default_cos, (u8)fls(valid_cos_bitmap) - 1);
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Current default_cos=%u, change to %u\n",
+ wanted_dcb_cfg->default_cos,
+ (u8)fls(valid_cos_bitmap) - 1);
wanted_dcb_cfg->default_cos = (u8)fls(valid_cos_bitmap) - 1;
}
@@ -657,6 +734,7 @@ static int update_wanted_qos_cfg(struct hinic3_nic_dev *nic_dev,
static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_dev_cfg *qos_in = buf_in;
struct hinic3_mt_qos_dev_cfg *qos_out = buf_out;
u8 i;
@@ -675,9 +753,10 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(qos_out, qos_in, sizeof(*qos_in));
qos_out->head.status = 0;
if (qos_in->op_code & MT_DCB_OPCODE_WR) {
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg,
+ memcpy(&dcb->wanted_dcb_cfg, &dcb->hw_dcb_cfg,
sizeof(struct hinic3_dcb_config));
- err = update_wanted_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg, qos_in);
+ err = update_wanted_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg,
+ qos_in);
if (err) {
qos_out->head.status = MT_EINVAL;
return 0;
@@ -687,12 +766,12 @@ static int dcb_mt_qos_map(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
qos_out->head.status = MT_EIO;
} else {
- qos_out->dft_cos = nic_dev->hw_dcb_cfg.default_cos;
- qos_out->trust = nic_dev->hw_dcb_cfg.trust;
+ qos_out->dft_cos = dcb->hw_dcb_cfg.default_cos;
+ qos_out->trust = dcb->hw_dcb_cfg.trust;
for (i = 0; i < NIC_DCB_UP_MAX; i++)
- qos_out->pcp2cos[i] = nic_dev->hw_dcb_cfg.pcp2cos[i];
+ qos_out->pcp2cos[i] = dcb->hw_dcb_cfg.pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- qos_out->dscp2cos[i] = nic_dev->hw_dcb_cfg.dscp2cos[i];
+ qos_out->dscp2cos[i] = dcb->hw_dcb_cfg.dscp2cos[i];
}
return 0;
@@ -721,27 +800,17 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
memcpy(dcb_out, dcb_in, sizeof(*dcb_in));
dcb_out->head.status = 0;
if (dcb_in->op_code & MT_DCB_OPCODE_WR) {
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) == dcb_in->state)
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ==
+ dcb_in->state)
return 0;
- if (dcb_in->state) {
- if (user_cos_num > nic_dev->q_params.num_qps) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "cos num %u should not more than channel num %u\n",
- user_cos_num,
- nic_dev->q_params.num_qps);
-
- return -EOPNOTSUPP;
- }
- }
-
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? user_cos_num : 0,
+ err = hinic3_setup_cos(nic_dev->netdev,
+ dcb_in->state ? user_cos_num : 0,
netif_run);
if (err)
goto setup_cos_fail;
@@ -751,7 +820,6 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
if (err)
goto vport_up_fail;
}
- rtnl_unlock();
} else {
dcb_out->state = !!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
}
@@ -759,12 +827,12 @@ static int dcb_mt_dcb_state(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
vport_up_fail:
- hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, dcb_in->state ? 0 : user_cos_num,
+ netif_run);
setup_cos_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
return err;
}
@@ -772,13 +840,15 @@ setup_cos_fail:
static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
const struct hinic3_mt_qos_cos_cfg *cos_cfg_in = buf_in;
struct hinic3_mt_qos_cos_cfg *cos_cfg_out = buf_out;
if (!buf_in || !buf_out || !out_size)
return -EINVAL;
- if (*out_size != sizeof(*cos_cfg_out) || in_size != sizeof(*cos_cfg_in)) {
+ if (*out_size != sizeof(*cos_cfg_out) ||
+ in_size != sizeof(*cos_cfg_in)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
in_size, *out_size, sizeof(*cos_cfg_in));
@@ -789,9 +859,9 @@ static int dcb_mt_hw_qos_get(struct hinic3_nic_dev *nic_dev, const void *buf_in,
cos_cfg_out->head.status = 0;
cos_cfg_out->port_id = hinic3_physical_port_id(nic_dev->hwdev);
- cos_cfg_out->func_cos_bitmap = (u8)nic_dev->func_dft_cos_bitmap;
- cos_cfg_out->port_cos_bitmap = (u8)nic_dev->port_dft_cos_bitmap;
- cos_cfg_out->func_max_cos_num = nic_dev->cos_config_num_max;
+ cos_cfg_out->func_cos_bitmap = (u8)dcb->func_dft_cos_bitmap;
+ cos_cfg_out->port_cos_bitmap = (u8)dcb->port_dft_cos_bitmap;
+ cos_cfg_out->func_max_cos_num = dcb->cos_config_num_max;
return 0;
}
@@ -803,7 +873,13 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
intr_num = hinic3_intr_num(nic_dev->hwdev);
- if (!buf_out || !out_size || *out_size != sizeof(u16)) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != sizeof(u16)) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %lu\n",
*out_size, sizeof(u16));
@@ -817,20 +893,27 @@ static int get_inter_num(struct hinic3_nic_dev *nic_dev, const void *buf_in,
static int get_netdev_name(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- if (!buf_out || !out_size || *out_size != IFNAMSIZ) {
+ if (!buf_out || !out_size) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Buf_out or out_size is NULL.\n");
+ return -EINVAL;
+ }
+
+ if (*out_size != IFNAMSIZ) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Unexpect out buf size from user :%u, expect: %u\n",
*out_size, IFNAMSIZ);
return -EFAULT;
}
- strlcpy(buf_out, nic_dev->netdev->name, IFNAMSIZ);
+ strscpy(buf_out, nic_dev->netdev->name, IFNAMSIZ);
return 0;
}
-static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
int *tx_timeout = buf_out;
@@ -839,7 +922,8 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (*out_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, out_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, out_size: %u, expect: %lu\n",
*out_size, sizeof(int));
return -EINVAL;
}
@@ -849,8 +933,9 @@ static int get_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return 0;
}
-static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf_in,
- u32 in_size, void *buf_out, u32 *out_size)
+static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
{
struct net_device *net_dev = nic_dev->netdev;
const int *tx_timeout = buf_in;
@@ -859,13 +944,15 @@ static int set_netdev_tx_timeout(struct hinic3_nic_dev *nic_dev, const void *buf
return -EINVAL;
if (in_size != sizeof(int)) {
- nicif_err(nic_dev, drv, net_dev, "Unexpect buf size from user, in_size: %u, expect: %lu\n",
+ nicif_err(nic_dev, drv, net_dev,
+ "Unexpect buf size from user, in_size: %u, expect: %lu\n",
in_size, sizeof(int));
return -EINVAL;
}
net_dev->watchdog_timeo = *tx_timeout * HZ;
- nicif_info(nic_dev, drv, net_dev, "Set tx timeout check period to %ds\n", *tx_timeout);
+ nicif_info(nic_dev, drv, net_dev,
+ "Set tx timeout check period to %ds\n", *tx_timeout);
return 0;
}
@@ -891,6 +978,34 @@ static int get_xsfp_present(struct hinic3_nic_dev *nic_dev, const void *buf_in,
return 0;
}
+static int get_xsfp_tlv_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ struct drv_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info = buf_out;
+ const struct mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req = buf_in;
+ int err;
+
+ if ((buf_in == NULL) || (buf_out == NULL) || (out_size == NULL))
+ return -EINVAL;
+
+ if (*out_size != sizeof(*sfp_tlv_info) ||
+ in_size != sizeof(*sfp_tlv_info_req)) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Unexpect buf size from user, in_size: %u, out_size: %u, expect: %lu\n",
+ in_size, *out_size, sizeof(*sfp_tlv_info));
+ return -EINVAL;
+ }
+
+ err = hinic3_get_sfp_tlv_info(nic_dev->hwdev,
+ sfp_tlv_info, sfp_tlv_info_req);
+ if (err != 0) {
+ sfp_tlv_info->head.status = MT_EIO;
+ return 0;
+ }
+
+ return 0;
+}
+
static int get_xsfp_info(struct hinic3_nic_dev *nic_dev, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
@@ -928,7 +1043,7 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{GET_LOOPBACK_MODE, get_loopback_mode},
{SET_LOOPBACK_MODE, set_loopback_mode},
{SET_LINK_MODE, set_link_mode},
- {SET_PF_BW_LIMIT, set_pf_bw_limit},
+ {SET_TX_PF_BW_LIMIT, set_pf_bw_limit},
{GET_PF_BW_LIMIT, get_pf_bw_limit},
{GET_SSET_COUNT, get_sset_count},
{GET_SSET_ITEMS, get_sset_stats},
@@ -940,17 +1055,22 @@ static const struct nic_drv_module_handle nic_driv_module_cmd_handle[] = {
{SET_TX_TIMEOUT, set_netdev_tx_timeout},
{GET_XSFP_PRESENT, get_xsfp_present},
{GET_XSFP_INFO, get_xsfp_info},
+ {GET_XSFP_INFO_COMP_CMIS, get_xsfp_tlv_info},
+ {SET_RX_PF_BW_LIMIT, set_rx_pf_bw_limit}
};
static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
u32 cmd, const void *buf_in,
u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(nic_driv_module_cmd_handle) /
- sizeof(nic_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(nic_driv_module_cmd_handle) /
+ sizeof(nic_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type = (enum driver_cmd_type)cmd;
int err = 0;
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_lock();
+
mutex_lock(&nic_dev->nic_mutex);
for (index = 0; index < num_cmds; index++) {
if (cmd_type ==
@@ -963,6 +1083,9 @@ static int send_to_nic_driver(struct hinic3_nic_dev *nic_dev,
}
mutex_unlock(&nic_dev->nic_mutex);
+ if (cmd_type == DCB_STATE || cmd_type == QOS_DEV)
+ rtnl_unlock();
+
if (index == num_cmds) {
pr_err("Can't find callback for %d\n", cmd_type);
return -EINVAL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
index a1fb4af..aa53c19 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.c
@@ -24,82 +24,80 @@
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_user_cos_num;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_user_cos_num;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_user_cos_num;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_user_cos_num;
return 0;
}
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev)
{
- if (nic_dev->hw_dcb_cfg.trust == 0)
- return nic_dev->hw_dcb_cfg.pcp_valid_cos_map;
- if (nic_dev->hw_dcb_cfg.trust == 1)
- return nic_dev->hw_dcb_cfg.dscp_valid_cos_map;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP)
+ return dcb->hw_dcb_cfg.pcp_valid_cos_map;
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_DSCP)
+ return dcb->hw_dcb_cfg.dscp_valid_cos_map;
return 0;
}
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
- u8 i, remainder, num_sq_per_cos, cur_cos_num = 0;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ struct hinic3_dcb_config *wanted_dcb_cfg =
+ &nic_dev->dcb->wanted_dcb_cfg;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
+ u8 cos_qp_num, cos_qp_offset = 0;
+ u8 i, remainder, num_qp_per_cos;
- if (num_cos == 0)
- return;
-
- num_sq_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
- if (num_sq_per_cos == 0)
+ if (num_cos == 0 || nic_dev->q_params.num_qps == 0)
return;
- remainder = nic_dev->q_params.num_qps % num_sq_per_cos;
+ num_qp_per_cos = (u8)(nic_dev->q_params.num_qps / num_cos);
+ remainder = nic_dev->q_params.num_qps % num_cos;
- memset(dcb_cfg->cos_qp_offset, 0, sizeof(dcb_cfg->cos_qp_offset));
- memset(dcb_cfg->cos_qp_num, 0, sizeof(dcb_cfg->cos_qp_num));
+ memset(hw_dcb_cfg->cos_qp_offset, 0, sizeof(hw_dcb_cfg->cos_qp_offset));
+ memset(hw_dcb_cfg->cos_qp_num, 0, sizeof(hw_dcb_cfg->cos_qp_num));
for (i = 0; i < PCP_MAX_UP; i++) {
if (BIT(i) & valid_cos_map) {
- u8 cos_qp_num = num_sq_per_cos;
- u8 cos_qp_offset = (u8)(cur_cos_num * num_sq_per_cos);
-
- if (cur_cos_num < remainder) {
- cos_qp_num++;
- cos_qp_offset += cur_cos_num;
- } else {
- cos_qp_offset += remainder;
- }
-
- cur_cos_num++;
- valid_cos_map -= (u8)BIT(i);
+ cos_qp_num = num_qp_per_cos + ((remainder > 0) ?
+ (remainder--, 1) : 0);
- dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
- dcb_cfg->cos_qp_num[i] = cos_qp_num;
+ hw_dcb_cfg->cos_qp_offset[i] = cos_qp_offset;
+ hw_dcb_cfg->cos_qp_num[i] = cos_qp_num;
hinic3_info(nic_dev, drv, "cos %u, cos_qp_offset=%u cos_qp_num=%u\n",
i, cos_qp_offset, cos_qp_num);
+
+ cos_qp_offset += cos_qp_num;
+ valid_cos_map -= (int)BIT(i);
}
}
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_offset, dcb_cfg->cos_qp_offset,
- sizeof(dcb_cfg->cos_qp_offset));
- memcpy(nic_dev->wanted_dcb_cfg.cos_qp_num, dcb_cfg->cos_qp_num,
- sizeof(dcb_cfg->cos_qp_num));
+ memcpy(wanted_dcb_cfg->cos_qp_offset, hw_dcb_cfg->cos_qp_offset,
+ sizeof(hw_dcb_cfg->cos_qp_offset));
+ memcpy(wanted_dcb_cfg->cos_qp_num, hw_dcb_cfg->cos_qp_num,
+ sizeof(hw_dcb_cfg->cos_qp_num));
}
void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
u8 i;
u16 start_qid, q_num;
hinic3_set_txq_cos(nic_dev, 0, nic_dev->q_params.num_qps,
- nic_dev->hw_dcb_cfg.default_cos);
+ hw_dcb_cfg->default_cos);
if (!dcb_en)
return;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- q_num = (u16)nic_dev->hw_dcb_cfg.cos_qp_num[i];
+ q_num = (u16)hw_dcb_cfg->cos_qp_num[i];
if (q_num) {
- start_qid = (u16)nic_dev->hw_dcb_cfg.cos_qp_offset[i];
+ start_qid = (u16)hw_dcb_cfg->cos_qp_offset[i];
hinic3_set_txq_cos(nic_dev, start_qid, q_num, i);
hinic3_info(nic_dev, drv, "update tx db cos, start_qid %u, q_num=%u cos=%u\n",
@@ -110,30 +108,29 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ struct hinic3_dcb_config *hw_dcb_cfg = &dcb->hw_dcb_cfg;
struct hinic3_dcb_state dcb_state = {0};
u8 i;
int err;
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- /* VF does not support DCB, use the default cos */
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
-
- return 0;
- }
+ u32 pcp2cos_size = sizeof(dcb_state.pcp2cos);
+ u32 dscp2cos_size = sizeof(dcb_state.dscp2cos);
dcb_state.dcb_on = dcb_en;
- dcb_state.default_cos = dcb_cfg->default_cos;
- dcb_state.trust = dcb_cfg->trust;
+ dcb_state.default_cos = hw_dcb_cfg->default_cos;
+ dcb_state.trust = hw_dcb_cfg->trust;
if (dcb_en) {
for (i = 0; i < NIC_DCB_COS_MAX; i++)
- dcb_state.pcp2cos[i] = dcb_cfg->pcp2cos[i];
+ dcb_state.pcp2cos[i] = hw_dcb_cfg->pcp2cos[i];
for (i = 0; i < NIC_DCB_IP_PRI_MAX; i++)
- dcb_state.dscp2cos[i] = dcb_cfg->dscp2cos[i];
+ dcb_state.dscp2cos[i] = hw_dcb_cfg->dscp2cos[i];
} else {
- memset(dcb_state.pcp2cos, dcb_cfg->default_cos, sizeof(dcb_state.pcp2cos));
- memset(dcb_state.dscp2cos, dcb_cfg->default_cos, sizeof(dcb_state.dscp2cos));
+ memset(dcb_state.pcp2cos, hw_dcb_cfg->default_cos,
+ pcp2cos_size);
+ memset(dcb_state.dscp2cos, hw_dcb_cfg->default_cos,
+ dscp2cos_size);
}
err = hinic3_set_dcb_state(nic_dev->hwdev, &dcb_state);
@@ -143,7 +140,7 @@ static int hinic3_set_tx_cos_state(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
return err;
}
-static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
{
int err;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
@@ -169,11 +166,13 @@ static int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en)
goto rx_configure_fail;
}
- if (dcb_en)
+ if (dcb_en) {
set_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
- else
+ set_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ } else {
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
-
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
+ }
return 0;
rx_configure_fail:
hinic3_set_tx_cos_state(nic_dev, dcb_en ? 0 : 1);
@@ -188,6 +187,7 @@ set_tx_cos_fail:
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err;
if (cos && test_bit(HINIC3_SAME_RXTX, &nic_dev->flags)) {
@@ -195,9 +195,10 @@ int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run)
return -EOPNOTSUPP;
}
- if (cos > nic_dev->cos_config_num_max) {
- nicif_err(nic_dev, drv, netdev, "Invalid num_tc: %u, max cos: %u\n",
- cos, nic_dev->cos_config_num_max);
+ if (cos > dcb->cos_config_num_max) {
+ nicif_err(nic_dev, drv, netdev,
+ "Invalid num_tc: %u, max cos: %u\n",
+ cos, dcb->cos_config_num_max);
return -EINVAL;
}
@@ -223,36 +224,48 @@ static u8 get_cos_num(u8 hw_valid_cos_bitmap)
static void hinic3_sync_dcb_cfg(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dcb_config *dcb_cfg)
{
- struct hinic3_dcb_config *hw_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
- memcpy(hw_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(hw_dcb_cfg, dcb_cfg, sizeof(struct hinic3_dcb_config));
}
static int init_default_dcb_cfg(struct hinic3_nic_dev *nic_dev,
struct hinic3_dcb_config *dcb_cfg)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 i, hw_dft_cos_map, port_cos_bitmap, dscp_ind;
int err;
+ int is_in_kexec;
- err = hinic3_cos_valid_bitmap(nic_dev->hwdev, &hw_dft_cos_map, &port_cos_bitmap);
+ err = hinic3_cos_valid_bitmap(nic_dev->hwdev,
+ &hw_dft_cos_map, &port_cos_bitmap);
if (err) {
hinic3_err(nic_dev, drv, "None cos supported\n");
return -EFAULT;
}
- nic_dev->func_dft_cos_bitmap = hw_dft_cos_map;
- nic_dev->port_dft_cos_bitmap = port_cos_bitmap;
- nic_dev->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+ is_in_kexec = vram_get_kexec_flag();
- dcb_cfg->trust = DCB_PCP;
- dcb_cfg->pcp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->dscp_user_cos_num = nic_dev->cos_config_num_max;
- dcb_cfg->default_cos = (u8)fls(nic_dev->func_dft_cos_bitmap) - 1;
+ dcb->func_dft_cos_bitmap = hw_dft_cos_map;
+ dcb->port_dft_cos_bitmap = port_cos_bitmap;
+
+ dcb->cos_config_num_max = get_cos_num(hw_dft_cos_map);
+
+ if (is_in_kexec == 0) {
+ dcb_cfg->trust = HINIC3_DCB_PCP;
+ dcb_cfg->default_cos = (u8)fls(dcb->func_dft_cos_bitmap) - 1;
+ } else {
+ dcb_cfg->trust = nic_dev->dcb->hw_dcb_cfg.trust;
+ dcb_cfg->default_cos = nic_dev->dcb->hw_dcb_cfg.default_cos;
+ }
+ dcb_cfg->pcp_user_cos_num = dcb->cos_config_num_max;
+ dcb_cfg->dscp_user_cos_num = dcb->cos_config_num_max;
dcb_cfg->pcp_valid_cos_map = hw_dft_cos_map;
dcb_cfg->dscp_valid_cos_map = hw_dft_cos_map;
for (i = 0; i < NIC_DCB_COS_MAX; i++) {
- dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i) ? i : dcb_cfg->default_cos;
+ dcb_cfg->pcp2cos[i] = hw_dft_cos_map & BIT(i)
+ ? i : (u8)fls(dcb->func_dft_cos_bitmap) - 1;
for (dscp_ind = 0; dscp_ind < NIC_DCB_COS_MAX; dscp_ind++)
dcb_cfg->dscp2cos[i * NIC_DCB_DSCP_NUM + dscp_ind] = dcb_cfg->pcp2cos[i];
}
@@ -276,58 +289,121 @@ int hinic3_configure_dcb(struct net_device *netdev)
int err;
err = hinic3_sync_dcb_state(nic_dev->hwdev, 1,
- test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0);
+ test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)
+ ? 1 : 0);
if (err) {
hinic3_err(nic_dev, drv, "Set dcb state failed\n");
return err;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ hinic3_sync_dcb_cfg(nic_dev, &nic_dev->dcb->wanted_dcb_cfg);
else
hinic3_dcb_reset_hw_config(nic_dev);
return 0;
}
+static int hinic3_dcb_alloc(struct hinic3_nic_dev *nic_dev)
+{
+ u16 func_id;
+ int is_use_vram;
+ int ret;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ ret = snprintf(nic_dev->dcb_name, VRAM_NAME_MAX_LEN,
+ "%s%u%s", VRAM_CQM_GLB_FUNC_BASE, func_id,
+ VRAM_NIC_DCB);
+ if (ret < 0) {
+ hinic3_err(nic_dev, drv, "Nic dcb snprintf failed, ret:%d.\n", ret);
+ return ret;
+ }
+
+ nic_dev->dcb = (struct hinic3_dcb *)hi_vram_kalloc(nic_dev->dcb_name,
+ sizeof(*nic_dev->dcb));
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to vram alloc dcb.\n");
+ return -EFAULT;
+ }
+ } else {
+ nic_dev->dcb = kzalloc(sizeof(*nic_dev->dcb), GFP_KERNEL);
+ if (!nic_dev->dcb) {
+ hinic3_err(nic_dev, drv, "Failed to create dcb.\n");
+ return -EFAULT;
+ }
+ }
+
+ return 0;
+}
+
+static void hinic3_dcb_free(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram;
+
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram)
+ hi_vram_kfree((void *)nic_dev->dcb, nic_dev->dcb_name, sizeof(*nic_dev->dcb));
+ else
+ kfree(nic_dev->dcb);
+ nic_dev->dcb = NULL;
+}
+
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
+ hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+
+ hinic3_dcb_free(nic_dev);
+}
+
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev)
{
- struct hinic3_dcb_config *dcb_cfg = &nic_dev->hw_dcb_cfg;
+ struct hinic3_dcb_config *hw_dcb_cfg = NULL;
int err;
u8 dcb_en = test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags) ? 1 : 0;
- if (HINIC3_FUNC_IS_VF(nic_dev->hwdev))
- return hinic3_set_tx_cos_state(nic_dev, dcb_en);
+ err = hinic3_dcb_alloc(nic_dev);
+ if (err != 0) {
+ hinic3_err(nic_dev, drv, "Dcb alloc failed.\n");
+ return err;
+ }
- err = init_default_dcb_cfg(nic_dev, dcb_cfg);
+ hw_dcb_cfg = &nic_dev->dcb->hw_dcb_cfg;
+ err = init_default_dcb_cfg(nic_dev, hw_dcb_cfg);
if (err) {
- hinic3_err(nic_dev, drv, "Initialize dcb configuration failed\n");
+ hinic3_err(nic_dev, drv,
+ "Initialize dcb configuration failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- memcpy(&nic_dev->wanted_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&nic_dev->dcb->wanted_dcb_cfg, hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
hinic3_info(nic_dev, drv, "Support num cos %u, default cos %u\n",
- nic_dev->cos_config_num_max, dcb_cfg->default_cos);
+ nic_dev->dcb->cos_config_num_max, hw_dcb_cfg->default_cos);
err = hinic3_set_tx_cos_state(nic_dev, dcb_en);
if (err) {
hinic3_err(nic_dev, drv, "Set tx cos state failed\n");
+ hinic3_dcb_free(nic_dev);
return err;
}
- sema_init(&nic_dev->dcb_sem, 1);
-
return 0;
}
-static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dcb_config *dcb_cfg)
+static int change_qos_cfg(struct hinic3_nic_dev *nic_dev,
+ const struct hinic3_dcb_config *dcb_cfg)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err = 0;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags)) {
+ if (test_and_set_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags)) {
nicif_warn(nic_dev, drv, netdev,
"Cos_up map setting in inprocess, please try again later\n");
return -EFAULT;
@@ -337,40 +413,44 @@ static int change_qos_cfg(struct hinic3_nic_dev *nic_dev, const struct hinic3_dc
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
- clear_bit(HINIC3_DCB_UP_COS_SETTING, &nic_dev->dcb_flags);
+ clear_bit(HINIC3_DCB_UP_COS_SETTING, &dcb->dcb_flags);
return err;
}
int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int err, rollback_err;
u8 netif_run = 0;
struct hinic3_dcb_config old_dcb_cfg;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- memcpy(&old_dcb_cfg, &nic_dev->hw_dcb_cfg, sizeof(struct hinic3_dcb_config));
+ memcpy(&old_dcb_cfg, &dcb->hw_dcb_cfg,
+ sizeof(struct hinic3_dcb_config));
- if (!memcmp(&nic_dev->wanted_dcb_cfg, &old_dcb_cfg, sizeof(struct hinic3_dcb_config))) {
+ if (!memcmp(&dcb->wanted_dcb_cfg, &old_dcb_cfg,
+ sizeof(struct hinic3_dcb_config))) {
nicif_info(nic_dev, drv, nic_dev->netdev,
"Same valid up bitmap, don't need to change anything\n");
return 0;
}
- rtnl_lock();
if (netif_running(nic_dev->netdev)) {
netif_run = 1;
hinic3_vport_down(nic_dev);
}
- err = change_qos_cfg(nic_dev, &nic_dev->wanted_dcb_cfg);
+ err = change_qos_cfg(nic_dev, &dcb->wanted_dcb_cfg);
if (err) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Set cos_up map to hw failed\n");
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Set cos_up map to hw failed\n");
goto change_qos_cfg_fail;
}
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- err = hinic3_setup_cos(nic_dev->netdev, user_cos_num, netif_run);
+ err = hinic3_setup_cos(nic_dev->netdev,
+ user_cos_num, netif_run);
if (err)
goto set_err;
}
@@ -381,13 +461,12 @@ int hinic3_dcbcfg_set_up_bitmap(struct hinic3_nic_dev *nic_dev)
goto vport_up_fail;
}
- rtnl_unlock();
-
return 0;
vport_up_fail:
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_setup_cos(nic_dev->netdev, user_cos_num ? 0 : user_cos_num, netif_run);
+ hinic3_setup_cos(nic_dev->netdev, user_cos_num
+ ? 0 : user_cos_num, netif_run);
set_err:
rollback_err = change_qos_cfg(nic_dev, &old_dcb_cfg);
@@ -399,7 +478,5 @@ change_qos_cfg_fail:
if (netif_run)
hinic3_vport_up(nic_dev);
- rtnl_unlock();
-
return err;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
index 7987f56..e0b35cb 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_dcb.h
@@ -24,11 +24,6 @@ struct hinic3_tc_cfg {
u16 rsvd;
};
-enum HINIC3_DCB_TRUST {
- DCB_PCP,
- DCB_DSCP,
-};
-
#define PCP_MAX_UP 8
#define DSCP_MAC_UP 64
#define DBG_DFLT_DSCP_VAL 0xFF
@@ -50,6 +45,7 @@ struct hinic3_dcb_config {
u8 hinic3_get_dev_user_cos_num(struct hinic3_nic_dev *nic_dev);
u8 hinic3_get_dev_valid_cos_map(struct hinic3_nic_dev *nic_dev);
int hinic3_dcb_init(struct hinic3_nic_dev *nic_dev);
+void hinic3_dcb_deinit(struct hinic3_nic_dev *nic_dev);
void hinic3_dcb_reset_hw_config(struct hinic3_nic_dev *nic_dev);
int hinic3_configure_dcb(struct net_device *netdev);
int hinic3_setup_cos(struct net_device *netdev, u8 cos, u8 netif_run);
@@ -75,4 +71,5 @@ void hinic3_update_tx_db_cos(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
void hinic3_update_qp_cos_cfg(struct hinic3_nic_dev *nic_dev, u8 num_cos);
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev);
int hinic3_vport_up(struct hinic3_nic_dev *nic_dev);
+int hinic3_configure_dcb_hw(struct hinic3_nic_dev *nic_dev, u8 dcb_en);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
index 2b3561e..548d67d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c
@@ -44,9 +44,9 @@ static void hinic3_get_drvinfo(struct net_device *netdev,
u8 mgmt_ver[HINIC3_MGMT_VERSION_MAX_LEN] = {0};
int err;
- strlcpy(info->driver, HINIC3_NIC_DRV_NAME, sizeof(info->driver));
- strlcpy(info->version, HINIC3_NIC_DRV_VERSION, sizeof(info->version));
- strlcpy(info->bus_info, pci_name(pdev), sizeof(info->bus_info));
+ strscpy(info->driver, HINIC3_NIC_DRV_NAME, sizeof(info->driver));
+ strscpy(info->version, HINIC3_NIC_DRV_VERSION, sizeof(info->version));
+ strscpy(info->bus_info, pci_name(pdev), sizeof(info->bus_info));
err = hinic3_get_mgmt_version(nic_dev->hwdev, mgmt_ver,
HINIC3_MGMT_VERSION_MAX_LEN,
@@ -123,10 +123,15 @@ reset_err:
return err;
}
+#ifdef HAVE_ETHTOOL_RINGPARAM_EXTACK
static void hinic3_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring,
struct kernel_ethtool_ringparam *kernel_ring,
struct netlink_ext_ack *extack)
+#else
+static void hinic3_get_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+#endif
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
@@ -176,10 +181,15 @@ static int check_ringparam_valid(struct net_device *netdev,
return 0;
}
+#ifdef HAVE_ETHTOOL_RINGPARAM_EXTACK
static int hinic3_set_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring,
struct kernel_ethtool_ringparam *kernel_ring,
struct netlink_ext_ack *extack)
+#else
+static int hinic3_set_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+#endif
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic3_dyna_txrxq_params q_params = {0};
@@ -273,7 +283,7 @@ static int get_coalesce(struct net_device *netdev,
static int set_queue_coalesce(struct hinic3_nic_dev *nic_dev, u16 q_id,
struct hinic3_intr_coal_info *coal)
{
- struct hinic3_intr_coal_info *intr_coal;
+ struct hinic3_intr_coal_info *intr_coal = NULL;
struct interrupt_info info = {0};
struct net_device *netdev = nic_dev->netdev;
int err;
@@ -367,24 +377,11 @@ static int is_coalesce_exceed_limit(struct net_device *netdev,
return 0;
}
-static int is_coalesce_legal(struct net_device *netdev,
- const struct ethtool_coalesce *coal)
+static int is_coalesce_allowed_change(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct ethtool_coalesce tmp_coal = {0};
- int err;
-
- if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
- nicif_err(nic_dev, drv, netdev,
- "tx-usecs must be equal to rx-usecs\n");
- return -EINVAL;
- }
-
- if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
- nicif_err(nic_dev, drv, netdev,
- "tx-frames must be equal to rx-frames\n");
- return -EINVAL;
- }
tmp_coal.cmd = coal->cmd;
tmp_coal.rx_coalesce_usecs = coal->rx_coalesce_usecs;
@@ -409,6 +406,31 @@ static int is_coalesce_legal(struct net_device *netdev,
return -EOPNOTSUPP;
}
+ return 0;
+}
+
+static int is_coalesce_legal(struct net_device *netdev,
+ const struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (coal->rx_coalesce_usecs != coal->tx_coalesce_usecs) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-usecs must be equal to rx-usecs\n");
+ return -EINVAL;
+ }
+
+ if (coal->rx_max_coalesced_frames != coal->tx_max_coalesced_frames) {
+ nicif_err(nic_dev, drv, netdev,
+ "tx-frames must be equal to rx-frames\n");
+ return -EINVAL;
+ }
+
+ err = is_coalesce_allowed_change(netdev, coal);
+ if (err)
+ return err;
+
err = is_coalesce_exceed_limit(netdev, coal);
if (err)
return err;
@@ -491,19 +513,10 @@ static int set_hw_coal_param(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static int set_coalesce(struct net_device *netdev,
- struct ethtool_coalesce *coal, u16 queue)
+static void check_coalesce_align(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
- struct hinic3_intr_coal_info intr_coal = {0};
- struct hinic3_intr_coal_info *ori_intr_coal = NULL;
- u32 last_adaptive_rx;
- char obj_str[32] = {0};
- int err = 0;
-
- err = is_coalesce_legal(netdev, coal);
- if (err)
- return err;
CHECK_COALESCE_ALIGN(coal, rx_coalesce_usecs, COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal, rx_max_coalesced_frames,
@@ -516,6 +529,14 @@ static int set_coalesce(struct net_device *netdev,
COALESCE_TIMER_CFG_UNIT);
CHECK_COALESCE_ALIGN(coal, rx_max_coalesced_frames_low,
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int check_coalesce_change(struct net_device *netdev,
+ u16 queue, struct ethtool_coalesce *coal)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info *ori_intr_coal = NULL;
+ char obj_str[32] = {0};
if (queue == COALESCE_ALL_QUEUE) {
ori_intr_coal = &nic_dev->intr_coalesce[0];
@@ -524,6 +545,7 @@ static int set_coalesce(struct net_device *netdev,
ori_intr_coal = &nic_dev->intr_coalesce[queue];
snprintf(obj_str, sizeof(obj_str), "for queue %u", queue);
}
+
CHECK_COALESCE_CHANGED(coal, rx_coalesce_usecs, COALESCE_TIMER_CFG_UNIT,
ori_intr_coal->coalesce_timer_cfg, obj_str);
CHECK_COALESCE_CHANGED(coal, rx_max_coalesced_frames,
@@ -545,28 +567,52 @@ static int set_coalesce(struct net_device *netdev,
CHECK_COALESCE_CHANGED(coal, rx_max_coalesced_frames_low,
COALESCE_PENDING_LIMIT_UNIT,
ori_intr_coal->rx_pending_limt_low, obj_str);
+ return 0;
+}
- intr_coal.coalesce_timer_cfg =
+static void init_intr_coal_params(struct hinic3_intr_coal_info *intr_coal,
+ struct ethtool_coalesce *coal)
+{
+ intr_coal->coalesce_timer_cfg =
(u8)(coal->rx_coalesce_usecs / COALESCE_TIMER_CFG_UNIT);
- intr_coal.pending_limt = (u8)(coal->rx_max_coalesced_frames /
- COALESCE_PENDING_LIMIT_UNIT);
+ intr_coal->pending_limt = (u8)(coal->rx_max_coalesced_frames /
+ COALESCE_PENDING_LIMIT_UNIT);
- last_adaptive_rx = nic_dev->adaptive_rx_coal;
- nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
-
- intr_coal.pkt_rate_high = coal->pkt_rate_high;
- intr_coal.rx_usecs_high =
+ intr_coal->pkt_rate_high = coal->pkt_rate_high;
+ intr_coal->rx_usecs_high =
(u8)(coal->rx_coalesce_usecs_high / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_high =
+ intr_coal->rx_pending_limt_high =
(u8)(coal->rx_max_coalesced_frames_high /
COALESCE_PENDING_LIMIT_UNIT);
- intr_coal.pkt_rate_low = coal->pkt_rate_low;
- intr_coal.rx_usecs_low =
+ intr_coal->pkt_rate_low = coal->pkt_rate_low;
+ intr_coal->rx_usecs_low =
(u8)(coal->rx_coalesce_usecs_low / COALESCE_TIMER_CFG_UNIT);
- intr_coal.rx_pending_limt_low =
+ intr_coal->rx_pending_limt_low =
(u8)(coal->rx_max_coalesced_frames_low /
COALESCE_PENDING_LIMIT_UNIT);
+}
+
+static int set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal, u16 queue)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_intr_coal_info intr_coal = {0};
+ u32 last_adaptive_rx;
+ int err = 0;
+
+ err = is_coalesce_legal(netdev, coal);
+ if (err)
+ return err;
+
+ check_coalesce_align(netdev, coal);
+
+ check_coalesce_change(netdev, queue, coal);
+
+ init_intr_coal_params(&intr_coal, coal);
+
+ last_adaptive_rx = nic_dev->adaptive_rx_coal;
+ nic_dev->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
/* coalesce timer or pending set to zero will disable coalesce */
if (!nic_dev->adaptive_rx_coal &&
@@ -588,18 +634,28 @@ static int set_coalesce(struct net_device *netdev,
return set_hw_coal_param(nic_dev, &intr_coal, queue);
}
+#ifdef HAVE_ETHTOOL_COALESCE_EXTACK
static int hinic3_get_coalesce(struct net_device *netdev,
struct ethtool_coalesce *coal,
struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack)
+#else
+static int hinic3_get_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
+#endif
{
return get_coalesce(netdev, coal, COALESCE_ALL_QUEUE);
}
+#ifdef HAVE_ETHTOOL_COALESCE_EXTACK
static int hinic3_set_coalesce(struct net_device *netdev,
struct ethtool_coalesce *coal,
struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack)
+#else
+static int hinic3_set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *coal)
+#endif
{
return set_coalesce(netdev, coal, COALESCE_ALL_QUEUE);
}
@@ -762,6 +818,14 @@ static int hinic3_get_module_info(struct net_device *netdev,
modinfo->type = ETH_MODULE_SFF_8636;
modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
break;
+ case MODULE_TYPE_DSFP:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
+ case MODULE_TYPE_QSFP_CMIS:
+ modinfo->type = ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
default:
nicif_warn(nic_dev, drv, netdev,
"Optical module unknown: 0x%x\n", sfp_type);
@@ -784,6 +848,9 @@ static int hinic3_get_module_eeprom(struct net_device *netdev,
memset(data, 0, ee->len);
err = hinic3_get_sfp_eeprom(nic_dev->hwdev, (u8 *)sfp_data, ee->len);
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(nic_dev->hwdev, (u8 *)sfp_data, sizeof(sfp_data));
+
if (err)
return err;
@@ -814,7 +881,7 @@ static u32 hinic3_get_priv_flags(struct net_device *netdev)
return priv_flags;
}
-int hinic3_set_rxq_recovery_flag(struct net_device *netdev, u32 priv_flags)
+static int hinic3_set_rxq_recovery_flag(struct net_device *netdev, u32 priv_flags)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
@@ -844,12 +911,14 @@ static int hinic3_set_symm_rss_flag(struct net_device *netdev, u32 priv_flags)
if (priv_flags & HINIC3_PRIV_FLAGS_SYMM_RSS) {
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, netdev, "Failed to open Symmetric RSS while DCB is enabled\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to open Symmetric RSS while DCB is enabled\n");
return -EOPNOTSUPP;
}
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, netdev, "Failed to open Symmetric RSS while RSS is disabled\n");
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to open Symmetric RSS while RSS is disabled\n");
return -EOPNOTSUPP;
}
@@ -1129,10 +1198,61 @@ static void hinic3_diag_test(struct net_device *netdev,
hinic3_lp_test(netdev, eth_test, data, 0);
}
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+static int hinic3_get_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u8 advertised_fec = 0;
+ u8 supported_fec = 0;
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_GFECPARAM) {
+ nicif_err(nic_dev, drv, netdev,
+ "get fecparam cmd err.exp:0x%x,real:0x%x\n",
+ ETHTOOL_GFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = get_fecparam(nic_dev->hwdev, &advertised_fec, &supported_fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Get fec param failed\n");
+ return err;
+ }
+ fecparam->active_fec = (u32)advertised_fec;
+ fecparam->fec = (u32)supported_fec;
+
+ nicif_info(nic_dev, drv, netdev, "Get fec param success\n");
+ return 0;
+}
+
+static int hinic3_set_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ int err;
+
+ if (fecparam->cmd != ETHTOOL_SFECPARAM) {
+ nicif_err(nic_dev, drv, netdev, "Set fecparam cmd err.exp:0x%x,real:0x%x\n", ETHTOOL_SFECPARAM, fecparam->cmd);
+ return -EINVAL;
+ }
+
+ err = set_fecparam(nic_dev->hwdev, (u8)fecparam->fec);
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Set fec param failed\n");
+ return err;
+ }
+
+ nicif_info(nic_dev, drv, netdev, "Set fec param success\n");
+ return 0;
+}
+#endif
+
static const struct ethtool_ops hinic3_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1179,6 +1299,11 @@ static const struct ethtool_ops hinic3_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
+
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
@@ -1239,7 +1364,10 @@ static const struct ethtool_ops_ext hinic3_ethtool_ops_ext = {
static const struct ethtool_ops hinic3vf_ethtool_ops = {
#ifdef SUPPORTED_COALESCE_PARAMS
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
- ETHTOOL_COALESCE_PKT_RATE_RX_USECS,
+ ETHTOOL_COALESCE_PKT_RATE_RX_USECS |
+ ETHTOOL_COALESCE_MAX_FRAMES |
+ ETHTOOL_COALESCE_USECS_LOW_HIGH |
+ ETHTOOL_COALESCE_MAX_FRAMES_LOW_HIGH,
#endif
#ifdef ETHTOOL_GLINKSETTINGS
#ifndef XENSERVER_HAVE_NEW_ETHTOOL_OPS
@@ -1266,6 +1394,11 @@ static const struct ethtool_ops hinic3vf_ethtool_ops = {
.set_per_queue_coalesce = hinic3_set_per_queue_coalesce,
#endif
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+ .get_fecparam = hinic3_get_fecparam,
+ .set_fecparam = hinic3_set_fecparam,
+#endif
+
.get_rxnfc = hinic3_get_rxnfc,
.set_rxnfc = hinic3_set_rxnfc,
.get_priv_flags = hinic3_get_priv_flags,
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
index de59b76..ec89f62 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool_stats.c
@@ -24,11 +24,24 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
-#define FPGA_PORT_COUNTER 0
-#define EVB_PORT_COUNTER 1
-u16 mag_support_mode = EVB_PORT_COUNTER;
-module_param(mag_support_mode, ushort, 0444);
-MODULE_PARM_DESC(mag_support_mode, "Set mag port counter support mode, 0:FPGA 1:EVB, default is 1");
+#define HINIC_SET_LINK_STR_LEN 128
+#define HINIC_ETHTOOL_FEC_INFO_LEN 6
+#define HINIC_SUPPORTED_FEC_CMD 0
+#define HINIC_ADVERTISED_FEC_CMD 1
+
+struct hinic3_ethtool_fec {
+ u8 hinic_fec_offset;
+ u8 ethtool_bit_offset;
+};
+
+static struct hinic3_ethtool_fec hinic3_ethtool_fec_info[HINIC_ETHTOOL_FEC_INFO_LEN] = {
+ {PORT_FEC_NOT_SET, 0xFF}, /* The ethtool does not have the corresponding enumeration variable */
+ {PORT_FEC_RSFEC, 0x32}, /* ETHTOOL_LINK_MODE_FEC_RS_BIT */
+ {PORT_FEC_BASEFEC, 0x33}, /* ETHTOOL_LINK_MODE_FEC_BASER_BIT */
+ {PORT_FEC_NOFEC, 0x31}, /* ETHTOOL_LINK_MODE_FEC_NONE_BIT */
+ {PORT_FEC_LLRSFEC, 0x4A}, /* ETHTOOL_LINK_MODE_FEC_LLRS_BIT: Available only in later versions */
+ {PORT_FEC_AUTO, 0XFF} /* The ethtool does not have the corresponding enumeration variable */
+};
struct hinic3_stats {
char name[ETH_GSTRING_LEN];
@@ -36,6 +49,20 @@ struct hinic3_stats {
int offset;
};
+struct hinic3_netdev_link_count_str {
+ u64 link_down_events_phy;
+};
+
+#define HINIC3_NETDEV_LINK_COUNT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct hinic3_netdev_link_count_str, _stat_item), \
+ .offset = offsetof(struct hinic3_netdev_link_count_str, _stat_item) \
+}
+
+static struct hinic3_stats hinic3_netdev_link_count[] = {
+ HINIC3_NETDEV_LINK_COUNT(link_down_events_phy),
+};
+
#define HINIC3_NETDEV_STAT(_stat_item) { \
.name = #_stat_item, \
.size = FIELD_SIZEOF(struct rtnl_link_stats64, _stat_item), \
@@ -94,7 +121,6 @@ static struct hinic3_stats hinic3_nic_dev_stats_extern[] = {
.offset = offsetof(struct hinic3_txq_stats, _stat_item) \
}
-/*lint -save -e786*/
static struct hinic3_stats hinic3_rx_queue_stats[] = {
HINIC3_RXQ_STAT(packets),
HINIC3_RXQ_STAT(bytes),
@@ -135,8 +161,6 @@ static struct hinic3_stats hinic3_tx_queue_stats_extern[] = {
HINIC3_TXQ_STAT(rsvd2),
};
-/*lint -restore*/
-
#define HINIC3_FUNC_STAT(_stat_item) { \
.name = #_stat_item, \
.size = FIELD_SIZEOF(struct hinic3_vport_stats, _stat_item), \
@@ -260,49 +284,22 @@ static struct hinic3_stats hinic3_port_stats[] = {
HINIC3_PORT_STAT(mac_rx_unfilter_pkt_num),
};
+#define HINIC3_RSFEC_STAT(_stat_item) { \
+ .name = #_stat_item, \
+ .size = FIELD_SIZEOF(struct mag_cmd_rsfec_stats, _stat_item), \
+ .offset = offsetof(struct mag_cmd_rsfec_stats, _stat_item) \
+}
+
+static struct hinic3_stats g_hinic3_rsfec_stats[] = {
+ HINIC3_RSFEC_STAT(rx_err_lane_phy),
+};
+
#define HINIC3_FGPA_PORT_STAT(_stat_item) { \
.name = #_stat_item, \
.size = FIELD_SIZEOF(struct hinic3_phy_fpga_port_stats, _stat_item), \
.offset = offsetof(struct hinic3_phy_fpga_port_stats, _stat_item) \
}
-static struct hinic3_stats g_hinic3_fpga_port_stats[] = {
- HINIC3_FGPA_PORT_STAT(mac_rx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_total_octs_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_under_frame_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_frag_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_64_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_127_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_255_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_511_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_1023_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_max_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_over_oct_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_crc_error_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_length_err_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_pause_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_rx_unknown_mac_frame_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_good_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_broadcast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_multicast_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_underrun_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_mac_frame_ok_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_vlan_pkts_port),
- HINIC3_FGPA_PORT_STAT(mac_tx_pause_pkts_port),
-};
-
static char g_hinic_priv_flags_strings[][ETH_GSTRING_LEN] = {
"Symmetric-RSS",
"Force-Link-up",
@@ -313,12 +310,12 @@ u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev)
{
u32 count;
- count = ARRAY_LEN(hinic3_nic_dev_stats) +
+ count = (u32)(ARRAY_LEN(hinic3_nic_dev_stats) +
ARRAY_LEN(hinic3_nic_dev_stats_extern) +
(ARRAY_LEN(hinic3_tx_queue_stats) +
ARRAY_LEN(hinic3_tx_queue_stats_extern) +
ARRAY_LEN(hinic3_rx_queue_stats) +
- ARRAY_LEN(hinic3_rx_queue_stats_extern)) * nic_dev->max_qps;
+ ARRAY_LEN(hinic3_rx_queue_stats_extern)) * nic_dev->max_qps);
return count;
}
@@ -342,46 +339,81 @@ u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev)
} \
} while (0)
-#define QUEUE_STATS_PACK(items, item_idx, array, stats_ptr, qid) do { \
- int j; \
- for (j = 0; j < ARRAY_LEN(array); j++) { \
- memcpy((items)[item_idx].name, (array)[j].name, \
- HINIC3_SHOW_ITEM_LEN); \
- snprintf((items)[item_idx].name, HINIC3_SHOW_ITEM_LEN, \
- (array)[j].name, (qid)); \
- (items)[item_idx].hexadecimal = 0; \
- (items)[item_idx].value = \
- GET_VALUE_OF_PTR((array)[j].size, \
- (char *)(stats_ptr) + (array)[j].offset); \
- (item_idx)++; \
- } \
-} while (0)
+int hinic3_rx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat, struct hinic3_rxq_stats *rxq_stats, u16 qid)
+{
+ int ret;
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
+ ret = snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
+ if (ret < 0)
+ return -EINVAL;
+
+ item->hexadecimal = 0;
+ item->value = GET_VALUE_OF_PTR(stat->size, (char *)(rxq_stats) + stat->offset);
+
+ return 0;
+}
+
+int hinic3_tx_queue_stat_pack(struct hinic3_show_item *item,
+ struct hinic3_stats *stat, struct hinic3_txq_stats *txq_stats, u16 qid)
+{
+ int ret;
+
+ ret = snprintf(item->name, HINIC3_SHOW_ITEM_LEN, stat->name, qid);
+ if (ret < 0)
+ return -EINVAL;
+
+ item->hexadecimal = 0;
+ item->value = GET_VALUE_OF_PTR(stat->size, (char *)(txq_stats) + stat->offset);
+
+ return 0;
+}
+
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats)
{
struct hinic3_show_item *items = stats;
int item_idx = 0;
u16 qid;
+ int idx;
+ int ret;
DEV_STATS_PACK(items, item_idx, hinic3_nic_dev_stats, &nic_dev->stats);
- DEV_STATS_PACK(items, item_idx, hinic3_nic_dev_stats_extern,
- &nic_dev->stats);
+ DEV_STATS_PACK(items, item_idx, hinic3_nic_dev_stats_extern, &nic_dev->stats);
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- QUEUE_STATS_PACK(items, item_idx, hinic3_tx_queue_stats,
- &nic_dev->txqs[qid].txq_stats, qid);
- QUEUE_STATS_PACK(items, item_idx, hinic3_tx_queue_stats_extern,
- &nic_dev->txqs[qid].txq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++], &hinic3_tx_queue_stats[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_tx_queue_stats_extern); idx++) {
+ ret = hinic3_tx_queue_stat_pack(&items[item_idx++], &hinic3_tx_queue_stats_extern[idx],
+ &nic_dev->txqs[qid].txq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
}
for (qid = 0; qid < nic_dev->max_qps; qid++) {
- QUEUE_STATS_PACK(items, item_idx, hinic3_rx_queue_stats,
- &nic_dev->rxqs[qid].rxq_stats, qid);
- QUEUE_STATS_PACK(items, item_idx, hinic3_rx_queue_stats_extern,
- &nic_dev->rxqs[qid].rxq_stats, qid);
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++], &hinic3_rx_queue_stats[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
+
+ for (idx = 0; idx < ARRAY_LEN(hinic3_rx_queue_stats_extern); idx++) {
+ ret = hinic3_rx_queue_stat_pack(&items[item_idx++], &hinic3_rx_queue_stats_extern[idx],
+ &nic_dev->rxqs[qid].rxq_stats, qid);
+ if (ret != 0)
+ return -EINVAL;
+ }
}
-}
+ return 0;
+}
static char g_hinic3_test_strings[][ETH_GSTRING_LEN] = {
"Internal lb test (on/offline)",
"External lb test (external_lb)",
@@ -398,16 +430,15 @@ int hinic3_get_sset_count(struct net_device *netdev, int sset)
case ETH_SS_STATS:
q_num = nic_dev->q_params.num_qps;
count = ARRAY_LEN(hinic3_netdev_stats) +
- ARRAY_LEN(hinic3_nic_dev_stats) +
+ ARRAY_LEN(hinic3_nic_dev_stats) +
+ ARRAY_LEN(hinic3_netdev_link_count) +
ARRAY_LEN(hinic3_function_stats) +
(ARRAY_LEN(hinic3_tx_queue_stats) +
ARRAY_LEN(hinic3_rx_queue_stats)) * q_num;
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER)
- count += ARRAY_LEN(g_hinic3_fpga_port_stats);
- else
- count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(hinic3_port_stats);
+ count += ARRAY_LEN(g_hinic3_rsfec_stats);
}
return count;
@@ -452,9 +483,9 @@ static void get_drv_queue_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
}
}
-static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct hinic3_phy_fpga_port_stats *port_stats = NULL;
+ struct mag_cmd_port_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
@@ -464,19 +495,19 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to malloc port stats\n");
memset(&data[i], 0,
- ARRAY_LEN(g_hinic3_fpga_port_stats) * sizeof(*data));
- i += ARRAY_LEN(g_hinic3_fpga_port_stats);
+ ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
+ i += ARRAY_LEN(hinic3_port_stats);
return i;
}
- err = hinic3_get_fpga_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to get port stats from fw\n");
- for (j = 0; j < ARRAY_LEN(g_hinic3_fpga_port_stats); j++, i++) {
- p = (char *)(port_stats) + g_hinic3_fpga_port_stats[j].offset;
- data[i] = (g_hinic3_fpga_port_stats[j].size ==
+ for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
+ p = (char *)(port_stats) + hinic3_port_stats[j].offset;
+ data[i] = (hinic3_port_stats[j].size ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
@@ -485,35 +516,32 @@ static u16 get_fpga_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
return i;
}
-static u16 get_ethtool_port_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
+static u16 get_ethtool_rsfec_stats(struct hinic3_nic_dev *nic_dev, u64 *data)
{
- struct mag_cmd_port_stats *port_stats = NULL;
+ struct mag_cmd_rsfec_stats *port_stats = NULL;
char *p = NULL;
u16 i = 0, j = 0;
int err;
- if (mag_support_mode == FPGA_PORT_COUNTER)
- return get_fpga_port_stats(nic_dev, data);
-
port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
if (!port_stats) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to malloc port stats\n");
memset(&data[i], 0,
- ARRAY_LEN(hinic3_port_stats) * sizeof(*data));
- i += ARRAY_LEN(hinic3_port_stats);
+ ARRAY_LEN(g_hinic3_rsfec_stats) * sizeof(*data));
+ i += ARRAY_LEN(g_hinic3_rsfec_stats);
return i;
- }
+ }
- err = hinic3_get_phy_port_stats(nic_dev->hwdev, port_stats);
+ err = hinic3_get_phy_rsfec_stats(nic_dev->hwdev, port_stats);
if (err)
nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to get port stats from fw\n");
+ "Failed to get rsfec stats from fw\n");
- for (j = 0; j < ARRAY_LEN(hinic3_port_stats); j++, i++) {
- p = (char *)(port_stats) + hinic3_port_stats[j].offset;
- data[i] = (hinic3_port_stats[j].size ==
- sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+ for (j = 0; j < ARRAY_LEN(g_hinic3_rsfec_stats); j++, i++) {
+ p = (char *)(port_stats) + g_hinic3_rsfec_stats[j].offset;
+ data[i] = (g_hinic3_rsfec_stats[j].size ==
+ sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
kfree(port_stats);
@@ -537,6 +565,8 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
u16 i = 0, j = 0;
char *p = NULL;
int err;
+ int link_down_events_phy_tmp = 0;
+ struct hinic3_netdev_link_count_str link_count = {0};
#ifdef HAVE_NDO_GET_STATS64
net_stats = dev_get_stats(netdev, &temp);
@@ -554,6 +584,14 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = GET_VALUE_OF_PTR(hinic3_nic_dev_stats[j].size, p);
}
+ err = hinic3_get_link_event_stats(nic_dev->hwdev, &link_down_events_phy_tmp);
+
+ link_count.link_down_events_phy = (u64)link_down_events_phy_tmp;
+ for (j = 0; j < ARRAY_LEN(hinic3_netdev_link_count); j++, i++) {
+ p = (char *)(&link_count) + hinic3_netdev_link_count[j].offset;
+ data[i] = GET_VALUE_OF_PTR(hinic3_netdev_link_count[j].size, p);
+ }
+
err = hinic3_get_vport_stats(nic_dev->hwdev, hinic3_global_func_id(nic_dev->hwdev),
&vport_stats);
if (err)
@@ -565,8 +603,10 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
data[i] = GET_VALUE_OF_PTR(hinic3_function_stats[j].size, p);
}
- if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
i += get_ethtool_port_stats(nic_dev, data + i);
+ i += get_ethtool_rsfec_stats(nic_dev, data + i);
+ }
get_drv_queue_stats(nic_dev, data + i);
}
@@ -588,6 +628,12 @@ static u16 get_drv_dev_strings(struct hinic3_nic_dev *nic_dev, char *p)
cnt++;
}
+ for (i = 0; i < ARRAY_LEN(hinic3_netdev_link_count); i++) {
+ memcpy(p, hinic3_netdev_link_count[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+
return cnt;
}
@@ -603,18 +649,16 @@ static u16 get_hw_stats_strings(struct hinic3_nic_dev *nic_dev, char *p)
}
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- if (mag_support_mode == FPGA_PORT_COUNTER) {
- for (i = 0; i < ARRAY_LEN(g_hinic3_fpga_port_stats); i++) {
- memcpy(p, g_hinic3_fpga_port_stats[i].name, ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
- } else {
- for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
- memcpy(p, hinic3_port_stats[i].name, ETH_GSTRING_LEN);
- p += ETH_GSTRING_LEN;
- cnt++;
- }
+ for (i = 0; i < ARRAY_LEN(hinic3_port_stats); i++) {
+ memcpy(p, hinic3_port_stats[i].name, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
+ }
+ for (i = 0; i < ARRAY_LEN(g_hinic3_rsfec_stats); i++) {
+ memcpy(p, g_hinic3_rsfec_stats[i].name,
+ ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ cnt++;
}
}
@@ -758,7 +802,6 @@ struct hw2ethtool_link_mode {
u32 speed;
};
-/*lint -save -e26 */
static const struct hw2ethtool_link_mode
hw2ethtool_link_mode_table[LINK_MODE_MAX_NUMBERS] = {
[LINK_MODE_GE] = {
@@ -818,8 +861,6 @@ static const struct hw2ethtool_link_mode
},
};
-/*lint -restore */
-
#define GET_SUPPORTED_MODE 0
#define GET_ADVERTISED_MODE 1
@@ -838,29 +879,33 @@ struct cmd_link_settings {
#define ETHTOOL_ADD_ADVERTISED_LINK_MODE(ecmd, mode) \
set_bit(ETHTOOL_LINK_MODE_##mode##_BIT, (ecmd)->advertising)
-#define ETHTOOL_ADD_SUPPORTED_SPEED_LINK_MODE(ecmd, mode) \
-do { \
- u32 i; \
- for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) { \
- if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >= \
- __ETHTOOL_LINK_MODE_MASK_NBITS) \
- continue; \
- set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i], \
- (ecmd)->supported); \
- } \
-} while (0)
+static void ethtool_add_supported_speed_link_mode(struct cmd_link_settings *link_settings,
+ u32 mode)
+{
+ u32 i;
-#define ETHTOOL_ADD_ADVERTISED_SPEED_LINK_MODE(ecmd, mode) \
-do { \
- u32 i; \
- for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) { \
- if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >= \
- __ETHTOOL_LINK_MODE_MASK_NBITS) \
- continue; \
- set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i], \
- (ecmd)->advertising); \
- } \
-} while (0)
+ for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
+ if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
+ continue;
+ set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
+ link_settings->supported);
+ }
+}
+
+static void ethtool_add_advertised_speed_link_mode(struct cmd_link_settings *link_settings,
+ u32 mode)
+{
+ u32 i;
+
+ for (i = 0; i < hw2ethtool_link_mode_table[mode].arr_size; i++) {
+ if (hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i] >=
+ __ETHTOOL_LINK_MODE_MASK_NBITS)
+ continue;
+ set_bit(hw2ethtool_link_mode_table[mode].link_mode_bit_arr[i],
+ link_settings->advertising);
+ }
+}
/* Related to enum mag_cmd_port_speed */
static u32 hw_to_ethtool_speed[] = {
@@ -888,11 +933,11 @@ static void hinic3_add_ethtool_link_mode(struct cmd_link_settings *link_settings
for (link_mode = 0; link_mode < LINK_MODE_MAX_NUMBERS; link_mode++) {
if (hw_link_mode & BIT(link_mode)) {
if (name == GET_SUPPORTED_MODE)
- ETHTOOL_ADD_SUPPORTED_SPEED_LINK_MODE
- (link_settings, link_mode);
+ ethtool_add_supported_speed_link_mode(
+ link_settings, link_mode);
else
- ETHTOOL_ADD_ADVERTISED_SPEED_LINK_MODE
- (link_settings, link_mode);
+ ethtool_add_advertised_speed_link_mode(
+ link_settings, link_mode);
}
}
}
@@ -915,10 +960,15 @@ static int hinic3_link_speed_set(struct hinic3_nic_dev *nic_dev,
err = hinic3_get_link_state(nic_dev->hwdev, &link_state);
if (!err && link_state) {
- link_settings->speed =
- port_info->speed < ARRAY_LEN(hw_to_ethtool_speed) ?
- hw_to_ethtool_speed[port_info->speed] :
- (u32)SPEED_UNKNOWN;
+ if (hinic3_get_bond_create_mode(nic_dev->hwdev)) {
+ link_settings->speed = port_info->bond_speed;
+ } else {
+ link_settings->speed =
+ port_info->speed <
+ ARRAY_LEN(hw_to_ethtool_speed) ?
+ hw_to_ethtool_speed[port_info->speed] :
+ (u32)SPEED_UNKNOWN;
+ }
link_settings->duplex = port_info->duplex;
} else {
@@ -993,6 +1043,39 @@ static int get_link_pause_settings(struct hinic3_nic_dev *nic_dev,
return 0;
}
+static bool is_bit_offset_defined(u8 bit_offset)
+{
+ if (bit_offset < __ETHTOOL_LINK_MODE_MASK_NBITS)
+ return true;
+ return false;
+}
+
+static void
+ethtool_add_supported_advertised_fec(struct cmd_link_settings *link_settings,
+ u32 fec, u8 cmd)
+{
+ u8 i;
+ for (i = 0; i < HINIC_ETHTOOL_FEC_INFO_LEN; i++) {
+ if ((fec & BIT(hinic3_ethtool_fec_info[i].hinic_fec_offset)) == 0)
+ continue;
+ if ((is_bit_offset_defined(hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true) &&
+ (cmd == HINIC_ADVERTISED_FEC_CMD)) {
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset, link_settings->advertising);
+ return; /* There can be only one advertised fec mode. */
+ }
+ if ((is_bit_offset_defined(hinic3_ethtool_fec_info[i].ethtool_bit_offset) == true) &&
+ (cmd == HINIC_SUPPORTED_FEC_CMD))
+ set_bit(hinic3_ethtool_fec_info[i].ethtool_bit_offset, link_settings->supported);
+ }
+}
+
+static void hinic3_link_fec_type(struct cmd_link_settings *link_settings,
+ u32 fec, u32 supported_fec)
+{
+ ethtool_add_supported_advertised_fec(link_settings, supported_fec, HINIC_SUPPORTED_FEC_CMD);
+ ethtool_add_supported_advertised_fec(link_settings, fec, HINIC_ADVERTISED_FEC_CMD);
+}
+
static int get_link_settings(struct net_device *netdev,
struct cmd_link_settings *link_settings)
{
@@ -1013,6 +1096,9 @@ static int get_link_settings(struct net_device *netdev,
hinic3_link_port_type(link_settings, port_info.port_type);
+ hinic3_link_fec_type(link_settings, BIT(port_info.fec),
+ port_info.supported_fec_mode);
+
link_settings->autoneg = port_info.autoneg_state == PORT_CFG_AN_ON ?
AUTONEG_ENABLE : AUTONEG_DISABLE;
if (port_info.autoneg_cap)
@@ -1138,10 +1224,11 @@ static int hinic3_set_settings_to_hw(struct hinic3_nic_dev *nic_dev,
struct net_device *netdev = nic_dev->netdev;
struct hinic3_link_ksettings settings = {0};
int speed_level = 0;
- char set_link_str[128] = {0};
+ char set_link_str[HINIC_SET_LINK_STR_LEN] = {0};
+ char link_info[HINIC_SET_LINK_STR_LEN] = {0};
int err = 0;
- err = snprintf(set_link_str, sizeof(set_link_str) - 1, "%s",
+ err = snprintf(link_info, sizeof(link_info), "%s",
(bool)(set_settings & HILINK_LINK_SET_AUTONEG) ?
((bool)autoneg ? "autong enable " : "autong disable ") : "");
if (err < 0)
@@ -1149,8 +1236,8 @@ static int hinic3_set_settings_to_hw(struct hinic3_nic_dev *nic_dev,
if (set_settings & HILINK_LINK_SET_SPEED) {
speed_level = hinic3_ethtool_to_hw_speed_level(speed);
- err = snprintf(set_link_str, sizeof(set_link_str) - 1,
- "%sspeed %u ", set_link_str, speed);
+ err = snprintf(set_link_str, sizeof(set_link_str),
+ "%sspeed %u ", link_info, speed);
if (err < 0)
return -EINVAL;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
index 70346d6..2daa7f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c
@@ -82,7 +82,7 @@ static struct hinic3_mac_filter *hinic3_add_filter(struct hinic3_nic_dev *nic_de
struct list_head *mac_filter_list,
u8 *addr)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
@@ -117,7 +117,7 @@ static void hinic3_del_filter(struct hinic3_nic_dev *nic_dev,
static struct hinic3_mac_filter *hinic3_mac_filter_entry_clone(const struct hinic3_mac_filter *src)
{
- struct hinic3_mac_filter *f;
+ struct hinic3_mac_filter *f = NULL;
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (!f)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
index ef8c62b..7fed1c1 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw.h
@@ -40,6 +40,7 @@ enum hinic3_channel_id {
HINIC3_CHANNEL_DSW,
HINIC3_CHANNEL_MIG,
HINIC3_CHANNEL_CRYPT,
+ HINIC3_CHANNEL_VROCE,
HINIC3_CHANNEL_MAX = 32,
};
@@ -398,6 +399,16 @@ void hinic3_free_cmd_buf(void *hwdev, struct hinic3_cmd_buf *cmd_buf);
int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read clear
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id, u16 *value);
+
+/**
* @brief hinic3_sm_ctr_rd32 - small single 32 counter read
* @param hwdev: device pointer to hwdev
* @param node: the node id
@@ -811,6 +822,13 @@ int hinic3_dbg_lt_wr_16byte_mask(void *hwdev, u8 dest, u8 instance,
void hinic3_link_event_stats(void *dev, u8 link);
/**
+ * @brief hinic3_get_link_event_stats - link event stats
+ * @param hwdev: device pointer to hwdev
+ * @param link: link status
+ */
+int hinic3_get_link_event_stats(void *dev, int *link_state);
+
+/**
* @brief hinic3_get_hw_pf_infos - get pf infos
* @param hwdev: device pointer to hwdev
* @param infos: pf infos
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
index 3c835ff..7a2644c 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c
@@ -12,6 +12,7 @@
#include <linux/netdevice.h>
#include <linux/debugfs.h>
+#include "ossl_knl.h"
#include "hinic3_hw.h"
#include "hinic3_crm.h"
#include "hinic3_nic_io.h"
@@ -47,12 +48,16 @@ static void qp_add_napi(struct hinic3_irq *irq_cfg)
netif_napi_add(nic_dev->netdev, &irq_cfg->napi,
hinic3_poll, nic_dev->poll_weight);
napi_enable(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_IS_REGIN;
}
-static void qp_del_napi(struct hinic3_irq *irq_cfg)
+void qp_del_napi(struct hinic3_irq *irq_cfg)
{
- napi_disable(&irq_cfg->napi);
- netif_napi_del(&irq_cfg->napi);
+ if (irq_cfg->napi_reign == NAPI_IS_REGIN) {
+ napi_disable(&irq_cfg->napi);
+ netif_napi_del(&irq_cfg->napi);
+ irq_cfg->napi_reign = NAPI_NOT_REGIN;
+ }
}
static irqreturn_t qp_irq(int irq, void *data)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
deleted file mode 100644
index 2482c5f..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_LLD_H
-#define HINIC3_LLD_H
-
-#include "hinic3_crm.h"
-
-struct hinic3_lld_dev {
- struct pci_dev *pdev;
- void *hwdev;
-};
-
-struct hinic3_uld_info {
- /* When the function does not need to initialize the corresponding uld,
- * @probe needs to return 0 and uld_dev is set to NULL;
- * if uld_dev is NULL, @remove will not be called when uninstalling
- */
- int (*probe)(struct hinic3_lld_dev *lld_dev, void **uld_dev, char *uld_dev_name);
- void (*remove)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- int (*suspend)(struct hinic3_lld_dev *lld_dev, void *uld_dev, pm_message_t state);
- int (*resume)(struct hinic3_lld_dev *lld_dev, void *uld_dev);
- void (*event)(struct hinic3_lld_dev *lld_dev, void *uld_dev,
- struct hinic3_event_info *event);
- int (*ioctl)(void *uld_dev, u32 cmd, const void *buf_in, u32 in_size,
- void *buf_out, u32 *out_size);
-};
-
-/* hinic3_register_uld - register an upper-layer driver
- * @type: uld service type
- * @uld_info: uld callback
- *
- * Registers an upper-layer driver.
- * Traverse existing devices and call @probe to initialize the uld device.
- */
-int hinic3_register_uld(enum hinic3_service_type type, struct hinic3_uld_info *uld_info);
-
-/**
- * hinic3_unregister_uld - unregister an upper-layer driver
- * @type: uld service type
- *
- * Traverse existing devices and call @remove to uninstall the uld device.
- * Unregisters an existing upper-layer driver.
- */
-void hinic3_unregister_uld(enum hinic3_service_type type);
-
-void lld_hold(void);
-void lld_put(void);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_name - get lld device by chip name
- * @param chip_name: chip name
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_name(const char *chip_name);
-
-/**
- * @brief lld_dev_hold - get reference to lld_dev
- * @param dev: lld device
- *
- * Hold reference to device to keep it from being freed
- **/
-void lld_dev_hold(struct hinic3_lld_dev *dev);
-
-/**
- * @brief lld_dev_put - release reference to lld_dev
- * @param dev: lld device
- *
- * Release reference to device to allow it to be freed
- **/
-void lld_dev_put(struct hinic3_lld_dev *dev);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_dev_name_unsafe - get lld device by uld device name
- * @param dev_name: uld device name
- * @param type: uld service type, When the type is SERVICE_T_MAX, try to match
- * all ULD names to get uld_dev
- *
- * hinic3_get_lld_dev_by_dev_name_unsafe() is completely analogous to
- * hinic3_get_lld_dev_by_dev_name(), The only difference is that the reference
- * of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that lld_dev will not be freed during the remove process
- * when using lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name_unsafe(const char *dev_name,
- enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_lld_dev_by_chip_and_port - get lld device by chip name and port id
- * @param chip_name: chip name
- * @param port_id: port id
- **/
-struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name, u8 port_id);
-
-/**
- * @brief hinic3_get_ppf_lld_dev - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * The value of lld_dev reference increases when lld_dev is obtained. The caller needs
- * to release the reference by calling lld_dev_put.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief hinic3_get_ppf_lld_dev_unsafe - get ppf lld device by current function's lld device
- * @param lld_dev: current function's lld device
- *
- * hinic3_get_ppf_lld_dev_unsafe() is completely analogous to hinic3_get_ppf_lld_dev(),
- * The only difference is that the reference of lld_dev is not increased when lld_dev is obtained.
- *
- * The caller must ensure that ppf's lld_dev will not be freed during the remove process
- * when using ppf lld_dev.
- **/
-struct hinic3_lld_dev *hinic3_get_ppf_lld_dev_unsafe(struct hinic3_lld_dev *lld_dev);
-
-/**
- * @brief uld_dev_hold - get reference to uld_dev
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * Hold reference to uld device to keep it from being freed
- **/
-void uld_dev_hold(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief uld_dev_put - release reference to lld_dev
- * @param dev: lld device
- * @param type: uld service type
- *
- * Release reference to uld device to allow it to be freed
- **/
-void uld_dev_put(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * The value of uld_dev reference increases when uld_dev is obtained. The caller needs
- * to release the reference by calling uld_dev_put.
- **/
-void *hinic3_get_uld_dev(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_uld_dev_unsafe - get uld device by lld device
- * @param lld_dev: lld device
- * @param type: uld service type
- *
- * hinic3_get_uld_dev_unsafe() is completely analogous to hinic3_get_uld_dev(),
- * The only difference is that the reference of uld_dev is not increased when uld_dev is obtained.
- *
- * The caller must ensure that uld_dev will not be freed during the remove process
- * when using uld_dev.
- **/
-void *hinic3_get_uld_dev_unsafe(struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-
-/**
- * @brief hinic3_get_chip_name - get chip name by lld device
- * @param lld_dev: lld device
- * @param chip_name: String for storing the chip name
- * @param max_len: Maximum number of characters to be copied for chip_name
- **/
-int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len);
-
-struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev);
-
-struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev);
-
-bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service);
-
-int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
- bool vf_srv_load);
-
-int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id,
- u16 service, bool en);
-
-bool hinic3_get_vf_load_state(struct pci_dev *pdev);
-
-int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state);
-
-int hinic3_attach_nic(struct hinic3_lld_dev *lld_dev);
-
-void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
-
-int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
-const char **hinic3_get_uld_names(void);
-int hinic3_lld_init(void);
-void hinic3_lld_exit(void);
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
index 2fe808b..8cd891e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mag_cfg.c
@@ -17,12 +17,22 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_hw.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
#include "hinic3_common.h"
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
+#define CAP_INFO_MAX_LEN 512
+#define DEVICE_VENDOR_MAX_LEN 17
+#define READ_RSFEC_REGISTER_DELAY_TIME_MS 500
+
+struct parse_tlv_info g_page_info = {0};
+struct drv_mag_cmd_get_xsfp_tlv_rsp g_xsfp_tlv_info = {0};
+
static int mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size);
static int mag_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in,
@@ -78,8 +88,10 @@ int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats)
return -ENOMEM;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
memset(&stats_info, 0, sizeof(stats_info));
stats_info.port_id = hinic3_physical_port_id(hwdev);
@@ -104,6 +116,64 @@ out:
}
EXPORT_SYMBOL(hinic3_get_phy_port_stats);
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats)
+{
+ struct mag_cmd_get_mag_cnt *port_stats = NULL;
+ struct mag_cmd_get_mag_cnt stats_info;
+ u16 out_size = sizeof(*port_stats);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !stats)
+ return -EINVAL;
+
+ port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
+ if (!port_stats)
+ return -ENOMEM;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ memset(&stats_info, 0, sizeof(stats_info));
+ stats_info.port_id = hinic3_physical_port_id(hwdev);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT,
+ &stats_info, sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+ /* 读2遍, 清除误码残留 */
+ msleep(READ_RSFEC_REGISTER_DELAY_TIME_MS);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_MAG_CNT, &stats_info,
+ sizeof(stats_info),
+ port_stats, &out_size);
+ if (err || !out_size || port_stats->head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get rsfec statistics, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, port_stats->head.status, out_size);
+ err = -EIO;
+ goto out;
+ }
+
+ memcpy(stats, &port_stats->mag_csr[MAG_RX_RSFEC_ERR_CW_CNT],
+ sizeof(u32));
+
+out:
+ kfree(port_stats);
+
+ return err;
+}
+EXPORT_SYMBOL(hinic3_get_phy_rsfec_stats);
+
int hinic3_set_port_funcs_state(void *hwdev, bool enable)
{
return 0;
@@ -180,6 +250,8 @@ int hinic3_get_loopback_mode(void *hwdev, u8 *mode, u8 *enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return hinic3_cfg_loopback_mode(nic_io, MGMT_MSG_CMD_OP_GET, mode,
enable);
@@ -195,6 +267,8 @@ int hinic3_set_loopback_mode(void *hwdev, u8 mode, u8 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (mode < LOOP_MODE_MIN || mode > LOOP_MODE_MAX) {
nic_err(nic_io->dev_hdl, "Invalid loopback mode %u to set\n",
@@ -218,6 +292,9 @@ int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&led_info, 0, sizeof(led_info));
led_info.function_id = hinic3_global_func_id(hwdev);
@@ -249,6 +326,8 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
memset(&port_msg, 0, sizeof(port_msg));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
port_msg.port_id = hinic3_physical_port_id(hwdev);
@@ -268,9 +347,12 @@ int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info,
port_info->port_type = port_msg.wire_type;
port_info->speed = port_msg.speed;
port_info->fec = port_msg.fec;
+ port_info->lanes = port_msg.lanes;
port_info->supported_mode = port_msg.supported_mode;
port_info->advertised_mode = port_msg.advertised_mode;
-
+ port_info->supported_fec_mode = port_msg.supported_fec_mode;
+ /* switch Gbps to Mbps */
+ port_info->bond_speed = (u32)port_msg.bond_speed * RATE_MBPS_TO_GBPS;
return 0;
}
@@ -306,6 +388,8 @@ int hinic3_set_link_settings(void *hwdev,
memset(&info, 0, sizeof(info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
info.port_id = hinic3_physical_port_id(hwdev);
info.config_bitmap = settings->valid_bitmap;
@@ -335,6 +419,8 @@ int hinic3_get_link_state(void *hwdev, u8 *link_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&get_link, 0, sizeof(get_link));
get_link.port_id = hinic3_physical_port_id(hwdev);
@@ -364,9 +450,10 @@ void hinic3_notify_vf_link_status(struct hinic3_nic_io *nic_io,
if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
link.status = link_status;
link.port_id = hinic3_physical_port_id(nic_io->hwdev);
- err = hinic3_mbox_to_vf(nic_io->hwdev, vf_id, HINIC3_MOD_HILINK,
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
MAG_CMD_GET_LINK_STATUS, &link,
- sizeof(link), &link, &out_size, 0,
+ sizeof(link), &link, &out_size,
HINIC3_CHANNEL_NIC);
if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
@@ -387,6 +474,9 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
u16 i;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
+
nic_io->link_status = link_status;
for (i = 1; i <= nic_io->max_vfs; i++) {
if (!nic_io->vf_infos[HW_VF_ID_TO_OS(i)].link_forced)
@@ -394,6 +484,167 @@ void hinic3_notify_all_vfs_link_changed(void *hwdev, u8 link_status)
}
}
+static char *g_hw_to_char_fec[HILINK_FEC_MAX_TYPE] = {
+ "not set", "rsfec", "basefec",
+ "nofec", "llrsfec"};
+static char *g_hw_to_speed_info[PORT_SPEED_UNKNOWN] = {
+ "not set", "10MB", "100MB", "1GB", "10GB",
+ "25GB", "40GB", "50GB", "100GB", "200GB"};
+static char *g_hw_to_an_state_info[PORT_CFG_AN_OFF + 1] = {
+ "not set", "on", "off"};
+
+struct port_type_table {
+ u32 port_type;
+ char *port_type_name;
+};
+
+static const struct port_type_table port_optical_type_table_s[] = {
+ {LINK_PORT_UNKNOWN, "UNKNOWN"},
+ {LINK_PORT_OPTICAL_MM, "optical_sr"},
+ {LINK_PORT_OPTICAL_SM, "optical_lr"},
+ {LINK_PORT_PAS_COPPER, "copper"},
+ {LINK_PORT_ACC, "ACC"},
+ {LINK_PORT_BASET, "baset"},
+ {LINK_PORT_AOC, "AOC"},
+ {LINK_PORT_ELECTRIC, "electric"},
+ {LINK_PORT_BACKBOARD_INTERFACE, "interface"},
+};
+
+static char *get_port_type_name(u32 type)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(port_optical_type_table_s); i++) {
+ if (type == port_optical_type_table_s[i].port_type)
+ return port_optical_type_table_s[i].port_type_name;
+ }
+ return "UNKNOWN TYPE";
+}
+
+static void get_port_type(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ char **port_type)
+{
+ if (info->port_type <= LINK_PORT_BACKBOARD_INTERFACE)
+ *port_type = get_port_type_name(info->port_type);
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown port type: %u\n",
+ info->port_type);
+}
+
+static int get_port_temperature_power(struct mag_cmd_event_port_info *info,
+ char *str)
+{
+ char cap_info[CAP_INFO_MAX_LEN];
+
+ memset(cap_info, 0, sizeof(cap_info));
+ snprintf(cap_info, CAP_INFO_MAX_LEN, "%s, %s, Temperature: %u", str,
+ info->sfp_type ? "QSFP" : "SFP", info->cable_temp);
+
+ if (info->sfp_type)
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuw %uuW %uuW %uuW",
+ cap_info, info->power[0x0], info->power[0x1],
+ info->power[0x2], info->power[0x3]);
+ else
+ snprintf(str, CAP_INFO_MAX_LEN, "%s, rx power: %uuW, tx power: %uuW",
+ cap_info, info->power[0x0], info->power[0x1]);
+
+ return 0;
+}
+
+static void print_cable_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info)
+{
+ char tmp_str[CAP_INFO_MAX_LEN] = {0};
+ char tmp_vendor[DEVICE_VENDOR_MAX_LEN] = {0};
+ char *port_type = "Unknown port type";
+ int i;
+ int err = 0;
+
+ if (info->gpio_insert) {
+ sdk_info(nic_io->dev_hdl, "Cable unpresent\n");
+ return;
+ }
+
+ get_port_type(nic_io, info, &port_type);
+
+ for (i = sizeof(info->vendor_name) - 1; i >= 0; i--) {
+ if (info->vendor_name[i] == ' ')
+ info->vendor_name[i] = '\0';
+ else
+ break;
+ }
+
+ memcpy(tmp_vendor, info->vendor_name, sizeof(info->vendor_name));
+ snprintf(tmp_str, CAP_INFO_MAX_LEN, "Vendor: %s, %s, length: %um, max_speed: %uGbps",
+ tmp_vendor, port_type, info->cable_length, info->max_speed);
+
+ if (info->port_type == LINK_PORT_OPTICAL_MM ||
+ info->port_type == LINK_PORT_AOC) {
+ err = get_port_temperature_power(info, tmp_str);
+ if (err)
+ return;
+ }
+
+ sdk_info(nic_io->dev_hdl, "Cable information: %s\n", tmp_str);
+}
+
+static void print_link_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *info,
+ enum hinic3_nic_event_type type)
+{
+ char *fec = "None";
+ char *speed = "None";
+ char *an_state = "None";
+
+ if (info->fec < HILINK_FEC_MAX_TYPE)
+ fec = g_hw_to_char_fec[info->fec];
+ else
+ sdk_info(nic_io->dev_hdl, "Unknown fec type: %u\n", info->fec);
+
+ if (info->an_state > PORT_CFG_AN_OFF) {
+ sdk_info(nic_io->dev_hdl, "an_state %u is invalid",
+ info->an_state);
+ return;
+ }
+
+ an_state = g_hw_to_an_state_info[info->an_state];
+
+ if (info->speed >= PORT_SPEED_UNKNOWN) {
+ sdk_info(nic_io->dev_hdl, "speed %u is invalid", info->speed);
+ return;
+ }
+
+ speed = g_hw_to_speed_info[info->speed];
+ sdk_info(nic_io->dev_hdl, "Link information: speed %s, %s, autoneg %s",
+ speed, fec, an_state);
+}
+
+void print_port_info(struct hinic3_nic_io *nic_io,
+ struct mag_cmd_event_port_info *port_info,
+ enum hinic3_nic_event_type type)
+{
+ print_cable_info(nic_io, port_info);
+
+ print_link_info(nic_io, port_info, type);
+
+ if (type == EVENT_NIC_LINK_UP)
+ return;
+
+ sdk_info(nic_io->dev_hdl, "PMA ctrl: %s, tx %s, rx %s, PMA fifo reg: 0x%x, PMA signal ok reg: 0x%x, RF/LF status reg: 0x%x\n",
+ port_info->pma_ctrl == 1 ? "off" : "on",
+ port_info->tx_enable ? "enable" : "disable",
+ port_info->rx_enable ? "enable" : "disable", port_info->pma_fifo_reg,
+ port_info->pma_signal_ok_reg, port_info->rf_lf);
+ sdk_info(nic_io->dev_hdl, "alos: %u, rx_los: %u, PCS 64 66b reg: 0x%x, PCS link: 0x%x, MAC link: 0x%x PCS_err_cnt: 0x%x\n",
+ port_info->alos, port_info->rx_los, port_info->pcs_64_66b_reg,
+ port_info->pcs_link, port_info->pcs_mac_link,
+ port_info->pcs_err_cnt);
+ sdk_info(nic_io->dev_hdl, "his_link_machine_state = 0x%08x, cur_link_machine_state = 0x%08x\n",
+ port_info->his_link_machine_state,
+ port_info->cur_link_machine_state);
+}
+
static int hinic3_get_vf_link_status_msg_handler(struct hinic3_nic_io *nic_io,
u16 vf_id, void *buf_in,
u16 in_size, void *buf_out,
@@ -433,6 +684,10 @@ static void get_port_info(void *hwdev,
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (hinic3_func_type(hwdev) != TYPE_VF && link_status->status) {
err = hinic3_get_port_info(hwdev, &port_info, HINIC3_CHANNEL_NIC);
if (err) {
@@ -457,8 +712,17 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
struct hinic3_event_info event_info = {0};
struct hinic3_event_link_info *link_info = (void *)event_info.event_data;
struct hinic3_nic_io *nic_io = NULL;
+ struct pci_dev *pdev = NULL;
+
+ /* Ignore link change event */
+ if (hinic3_is_bm_slave_host(hwdev))
+ return;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
link_status = buf_in;
sdk_info(nic_io->dev_hdl, "Link status report received, func_id: %u, status: %u\n",
@@ -475,6 +739,13 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
hinic3_event_callback(hwdev, &event_info);
+ if (nic_io->pcidev_hdl != NULL) {
+ pdev = nic_io->pcidev_hdl;
+ if (pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID) {
+ return;
+ }
+ }
+
if (hinic3_func_type(hwdev) != TYPE_VF) {
hinic3_notify_all_vfs_link_changed(hwdev, link_status->status);
ret_link_status = buf_out;
@@ -483,20 +754,142 @@ static void link_status_event_handler(void *hwdev, void *buf_in,
}
}
+static void port_info_event_printf(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_event_port_info *port_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info;
+ enum hinic3_nic_event_type type;
+
+ if (!hwdev) {
+ pr_err("hwdev is NULL\n");
+ return;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ if (in_size != sizeof(*port_info)) {
+ sdk_info(nic_io->dev_hdl, "Invalid port info message size %u, should be %lu\n",
+ in_size, sizeof(*port_info));
+ return;
+ }
+
+ ((struct mag_cmd_event_port_info *)buf_out)->head.status = 0;
+
+ type = port_info->event_type;
+ if (type < EVENT_NIC_LINK_DOWN || type > EVENT_NIC_LINK_UP) {
+ sdk_info(nic_io->dev_hdl, "Invalid hilink info report, type: %d\n",
+ type);
+ return;
+ }
+
+ print_port_info(nic_io, port_info, type);
+
+ memset(&event_info, 0, sizeof(event_info));
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = type;
+
+ *out_size = sizeof(*port_info);
+
+ hinic3_event_callback(hwdev, &event_info);
+}
+
+void hinic3_notify_vf_bond_status(struct hinic3_nic_io *nic_io,
+ u16 vf_id, u8 bond_status)
+{
+ struct mag_cmd_get_bond_status bond;
+ struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ u16 out_size = sizeof(bond);
+ int err;
+
+ memset(&bond, 0, sizeof(bond));
+ if (vf_infos[HW_VF_ID_TO_OS(vf_id)].registered) {
+ bond.status = bond_status;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_HILINK,
+ MAG_CMD_GET_BOND_STATUS, &bond,
+ sizeof(bond), &bond, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF %hu not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return;
+ }
+ if (err || !out_size || bond.head.status)
+ nic_err(nic_io->dev_hdl,
+ "Send bond change event to VF %hu failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err, bond.head.status,
+ out_size);
+ }
+}
+
+void hinic3_notify_all_vfs_bond_changed(void *hwdev, u8 bond_status)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 i;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ nic_io->link_status = bond_status;
+ for (i = 1; i <= nic_io->max_vfs; i++)
+ hinic3_notify_vf_bond_status(nic_io, i, bond_status);
+}
+
+static void bond_status_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_get_bond_status *bond_status = NULL;
+ struct hinic3_event_info event_info = {};
+ struct hinic3_nic_io *nic_io = NULL;
+ struct mag_cmd_get_bond_status *ret_bond_status = NULL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+
+ bond_status = (struct mag_cmd_get_bond_status *)buf_in;
+ sdk_info(nic_io->dev_hdl, "bond status report received, func_id: %u, status: %u\n",
+ hinic3_global_func_id(hwdev), bond_status->status);
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = bond_status->status ?
+ EVENT_NIC_BOND_UP : EVENT_NIC_BOND_DOWN;
+
+ hinic3_event_callback(hwdev, &event_info);
+
+ if (hinic3_func_type(hwdev) != TYPE_VF) {
+ hinic3_notify_all_vfs_bond_changed(hwdev, bond_status->status);
+ ret_bond_status = buf_out;
+ ret_bond_status->head.status = 0;
+ *out_size = sizeof(*ret_bond_status);
+ }
+}
+
static void cable_plug_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
struct mag_cmd_wire_event *plug_event = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_event_info event_info;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
rt_cmd->mpu_send_sfp_abs = false;
rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
memset(&event_info, 0, sizeof(event_info));
@@ -518,20 +911,54 @@ static void port_sfp_info_event(void *hwdev, void *buf_in, u16 in_size,
{
struct mag_cmd_get_xsfp_info *sfp_info = buf_in;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_info)) {
- sdk_err(nic_io->dev_hdl, "Invalid sfp info cmd, length: %u, should be %ld\n",
+ sdk_err(nic_io->dev_hdl, "Invalid sfp info cmd, length: %u, should be %lu\n",
in_size, sizeof(*sfp_info));
return;
}
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
memcpy(&rt_cmd->std_sfp_info, sfp_info,
sizeof(struct mag_cmd_get_xsfp_info));
rt_cmd->mpu_send_sfp_info = true;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = false;
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+}
+
+static void port_xsfp_tlv_info_event(void *hwdev, void *buf_in, u16 in_size,
+ void *buf_out, u16 *out_size)
+{
+ struct mag_cmd_get_xsfp_tlv_rsp *xsfp_tlv_info = buf_in;
+ struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
+ size_t cpy_len = in_size - sizeof(struct mgmt_msg_head) -
+ XSFP_TLV_PRE_INFO_LEN;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL)
+ return;
+
+ if (cpy_len > XSFP_CMIS_INFO_MAX_SIZE) {
+ sdk_err(nic_io->dev_hdl, "invalid cpy_len(%lu)\n", cpy_len);
+ return;
+ }
+ rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ rt_cmd_ext->std_xsfp_tlv_info.port_id = xsfp_tlv_info->port_id;
+ memcpy(&(rt_cmd_ext->std_xsfp_tlv_info.tlv_buf[0]),
+ &(xsfp_tlv_info->tlv_buf[0]), cpy_len);
+ rt_cmd->mpu_send_sfp_info = false;
+ rt_cmd_ext->mpu_send_xsfp_tlv_info = true;
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
}
@@ -543,8 +970,10 @@ static void port_sfp_abs_event(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
if (in_size != sizeof(*sfp_abs)) {
- sdk_err(nic_io->dev_hdl, "Invalid sfp absent cmd, length: %u, should be %ld\n",
+ sdk_err(nic_io->dev_hdl, "Invalid sfp absent cmd, length: %u, should be %lu\n",
in_size, sizeof(*sfp_abs));
return;
}
@@ -564,9 +993,11 @@ bool hinic3_if_sfp_absent(void *hwdev)
u8 port_id = hinic3_physical_port_id(hwdev);
u16 out_size = sizeof(sfp_abs);
int err;
- bool sfp_abs_status;
+ bool sfp_abs_status = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return true;
memset(&sfp_abs, 0, sizeof(sfp_abs));
rt_cmd = &nic_io->nic_cfg.rt_cmd;
@@ -597,10 +1028,187 @@ bool hinic3_if_sfp_absent(void *hwdev)
return (sfp_abs.abs_status == 0 ? false : true);
}
+int hinic3_get_sfp_tlv_info(void *hwdev, struct drv_mag_cmd_get_xsfp_tlv_rsp
+ *sfp_tlv_info,
+ const struct mag_cmd_get_xsfp_tlv_req
+ *sfp_tlv_info_req)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_port_routine_cmd_extern *rt_cmd_ext = NULL;
+ u16 out_size = sizeof(*sfp_tlv_info);
+ int err;
+
+ if ((hwdev == NULL) || (sfp_tlv_info == NULL))
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (nic_io == NULL)
+ return -EINVAL;
+
+ rt_cmd_ext = &nic_io->nic_cfg.rt_cmd_ext;
+ mutex_lock(&nic_io->nic_cfg.sfp_mutex);
+ if (rt_cmd_ext->mpu_send_xsfp_tlv_info == true) {
+ if (rt_cmd_ext->std_xsfp_tlv_info.head.status != 0) {
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return -EIO;
+ }
+
+ memcpy(sfp_tlv_info, &rt_cmd_ext->std_xsfp_tlv_info,
+ sizeof(*sfp_tlv_info));
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+
+ err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_TLV_INFO,
+ (void *)sfp_tlv_info_req,
+ sizeof(*sfp_tlv_info_req),
+ sfp_tlv_info, &out_size);
+ if ((sfp_tlv_info->head.status != 0) || (err != 0) || (out_size == 0)) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get port%u tlv sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
+ hinic3_physical_port_id(hwdev), err,
+ sfp_tlv_info->head.status, out_size);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_get_page_pos(u32 page_id, u32 content_len, u32 *pos)
+{
+ if (page_id <= QSFP_CMIS_PAGE_03H) {
+ *pos = (page_id * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_11H) {
+ *pos = (QSFP_CMIS_PAGE_04H * content_len);
+ return 0;
+ }
+
+ if (page_id == QSFP_CMIS_PAGE_12H) {
+ *pos = (QSFP_CMIS_PAGE_05H * content_len);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int hinic3_get_page_key_info(struct mgmt_tlv_info *tlv_info,
+ struct parse_tlv_info *page_info, u8 idx,
+ u32 *total_len)
+{
+ u8 *src_addr = NULL;
+ u8 *dst_addr = NULL;
+ u8 *tmp_addr = NULL;
+ u32 page_id = 0;
+ u32 content_len = 0;
+ u32 src_pos = 0;
+ int ret;
+
+ page_id = MGMT_TLV_GET_U32(tlv_info->value);
+ content_len = tlv_info->length - MGMT_TLV_U32_SIZE;
+ if (page_id == QSFP_CMIS_PAGE_00H) {
+ tmp_addr = (u8 *)(tlv_info + 1);
+ page_info->id = *(tmp_addr + MGMT_TLV_U32_SIZE);
+ }
+
+ ret = hinic3_trans_cmis_get_page_pos(page_id, content_len, &src_pos);
+ if (ret != 0)
+ return ret;
+
+ src_addr = page_info->tlv_page_info + src_pos;
+ tmp_addr = (u8 *)(tlv_info + 1);
+ dst_addr = tmp_addr + MGMT_TLV_U32_SIZE;
+ memcpy(src_addr, dst_addr, content_len);
+ if (ret != 0)
+ return ret;
+
+ if (idx < XSFP_CMIS_PARSE_PAGE_NUM)
+ page_info->tlv_page_num[idx] = page_id;
+
+ *total_len += content_len;
+
+ return 0;
+}
+
+static int hinic3_trans_cmis_tlv_info_to_buf(u8 *sfp_tlv_info,
+ struct parse_tlv_info *page_info)
+{
+ struct mgmt_tlv_info *tlv_info = NULL;
+ u8 *tlv_buf = sfp_tlv_info;
+ u8 idx = 0;
+ u32 total_len = 0;
+ int ret = 0;
+ bool need_continue = true;
+
+ if ((sfp_tlv_info == NULL) || (page_info == NULL))
+ return -EIO;
+
+ while (need_continue) {
+ tlv_info = (struct mgmt_tlv_info *)tlv_buf;
+ switch (tlv_info->type) {
+ case MAG_XSFP_TYPE_PAGE:
+ ret = hinic3_get_page_key_info(
+ tlv_info, page_info, idx, &total_len);
+ if (ret != 0) {
+ pr_err("lib_get_page_key_info fail,ret:0x%x.\n",
+ ret);
+ break;
+ }
+ idx++;
+ break;
+
+ case MAG_XSFP_TYPE_WIRE_TYPE:
+ page_info->wire_type =
+ MGMT_TLV_GET_U32(&(tlv_info->value[0]));
+ break;
+
+ case MAG_XSFP_TYPE_END:
+ need_continue = false;
+ break;
+
+ default:
+ break;
+ }
+
+ tlv_buf += (sizeof(struct mgmt_tlv_info) + tlv_info->length);
+ }
+
+ page_info->tlv_page_info_len = total_len;
+
+ return 0;
+}
+
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len)
+{
+ int err = 0;
+ struct mag_cmd_get_xsfp_tlv_req xsfp_tlv_info_req = {0};
+
+ xsfp_tlv_info_req.rsp_buf_len = XSFP_CMIS_INFO_MAX_SIZE;
+ xsfp_tlv_info_req.port_id = hinic3_physical_port_id(hwdev);
+ err = hinic3_get_sfp_tlv_info(hwdev, &g_xsfp_tlv_info,
+ &xsfp_tlv_info_req);
+ if (err != 0)
+ return err;
+
+ err = hinic3_trans_cmis_tlv_info_to_buf(g_xsfp_tlv_info.tlv_buf,
+ &g_page_info);
+ if (err)
+ return -ENOMEM;
+
+ memcpy(data, g_page_info.tlv_page_info, len);
+
+ return (err == 0) ? 0 : -ENOMEM;
+}
+
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
{
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
+ u8 sfp_info_status = 0;
u16 out_size = sizeof(*sfp_info);
int err;
@@ -608,13 +1216,17 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
+ sfp_info_status = rt_cmd->std_sfp_info.head.status;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (sfp_info_status != 0) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return -EIO;
+ return (sfp_info_status == HINIC3_MGMT_CMD_UNSUPPORTED)
+ ? HINIC3_MGMT_CMD_UNSUPPORTED : -EIO;
}
memcpy(sfp_info, &rt_cmd->std_sfp_info, sizeof(*sfp_info));
@@ -626,7 +1238,14 @@ int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info)
sfp_info->port_id = hinic3_physical_port_id(hwdev);
err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_XSFP_INFO, sfp_info,
sizeof(*sfp_info), sfp_info, &out_size);
- if (sfp_info->head.status || err || !out_size) {
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED) {
+ return HINIC3_MGMT_CMD_UNSUPPORTED;
+ }
+
+ if (sfp_info->head.status == HINIC3_MGMT_CMD_UNSUPPORTED) {
+ return -EOPNOTSUPP;
+ }
+ if ((sfp_info->head.status != 0) || (err != 0) || (out_size == 0)) {
nic_err(nic_io->dev_hdl,
"Failed to get port%u sfp eeprom information, err: %d, status: 0x%x, out size: 0x%x\n",
hinic3_physical_port_id(hwdev), err,
@@ -642,7 +1261,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
struct mag_cmd_get_xsfp_info sfp_info;
int err;
- if (!hwdev || !data)
+ if (!hwdev || !data || len > PAGE_SIZE)
return -EINVAL;
if (hinic3_if_sfp_absent(hwdev))
@@ -654,7 +1273,7 @@ int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len)
if (err)
return err;
- memcpy(data, sfp_info.sfp_info, len);
+ memcpy(data, sfp_info.sfp_info, sizeof(sfp_info.sfp_info));
return 0;
}
@@ -664,7 +1283,7 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
struct hinic3_nic_io *nic_io = NULL;
struct hinic3_port_routine_cmd *rt_cmd = NULL;
u8 sfp_data[STD_SFP_INFO_MAX_SIZE];
- int err;
+ int err = 0;
if (!hwdev || !sfp_type || !sfp_type_ext)
return -EINVAL;
@@ -673,24 +1292,41 @@ int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext)
return -ENXIO;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
rt_cmd = &nic_io->nic_cfg.rt_cmd;
mutex_lock(&nic_io->nic_cfg.sfp_mutex);
if (rt_cmd->mpu_send_sfp_info) {
- if (rt_cmd->std_sfp_info.head.status) {
+ if (rt_cmd->std_sfp_info.head.status == 0) {
+ *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
+ *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
+ mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
+ return 0;
+ }
+
+ if (rt_cmd->std_sfp_info.head.status != HINIC3_MGMT_CMD_UNSUPPORTED) {
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
return -EIO;
}
- *sfp_type = rt_cmd->std_sfp_info.sfp_info[0];
- *sfp_type_ext = rt_cmd->std_sfp_info.sfp_info[1];
- mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- return 0;
+ err = HINIC3_MGMT_CMD_UNSUPPORTED; /* cmis */
}
mutex_unlock(&nic_io->nic_cfg.sfp_mutex);
- err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
- STD_SFP_INFO_MAX_SIZE);
+ if (err == 0) {
+ err = hinic3_get_sfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ } else {
+ /* mpu_send_sfp_info is false */
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+ }
+
+ if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+ err = hinic3_get_tlv_xsfp_eeprom(hwdev, (u8 *)sfp_data,
+ STD_SFP_INFO_MAX_SIZE);
+
if (err)
return err;
@@ -796,12 +1432,20 @@ int hinic3_set_pf_bw_limit(void *hwdev, u32 bw_limit)
return -EINVAL;
}
- old_bw_limit = nic_io->nic_cfg.pf_bw_limit;
- nic_io->nic_cfg.pf_bw_limit = bw_limit;
+ if (nic_io->direct == HINIC3_NIC_TX) {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_tx_limit;
+ nic_io->nic_cfg.pf_bw_tx_limit = bw_limit;
+ } else {
+ old_bw_limit = nic_io->nic_cfg.pf_bw_rx_limit;
+ nic_io->nic_cfg.pf_bw_rx_limit = bw_limit;
+ }
err = hinic3_update_pf_bw(hwdev);
if (err) {
- nic_io->nic_cfg.pf_bw_limit = old_bw_limit;
+ if (nic_io->direct == HINIC3_NIC_TX)
+ nic_io->nic_cfg.pf_bw_tx_limit = old_bw_limit;
+ else
+ nic_io->nic_cfg.pf_bw_rx_limit = old_bw_limit;
return err;
}
@@ -828,6 +1472,8 @@ int hinic3_pf_mag_mbox_handler(void *hwdev, u16 vf_id,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (index = 0; index < cmd_size; index++) {
handler = &vf_mag_cmd_handler[index];
@@ -849,6 +1495,11 @@ static struct nic_event_handler mag_cmd_handler[] = {
},
{
+ .cmd = MAG_CMD_EVENT_PORT_INFO,
+ .handler = port_info_event_printf,
+ },
+
+ {
.cmd = MAG_CMD_WIRE_EVENT,
.handler = cable_plug_event,
},
@@ -862,6 +1513,16 @@ static struct nic_event_handler mag_cmd_handler[] = {
.cmd = MAG_CMD_GET_XSFP_PRESENT,
.handler = port_sfp_abs_event,
},
+
+ {
+ .cmd = MAG_CMD_GET_BOND_STATUS,
+ .handler = bond_status_event_handler,
+ },
+
+ {
+ .cmd = MAG_CMD_GET_XSFP_TLV_INFO,
+ .handler = port_xsfp_tlv_info_event,
+ },
};
static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
@@ -877,6 +1538,9 @@ static int hinic3_mag_event_handler(void *hwdev, u16 cmd,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
for (i = 0; i < size; i++) {
if (cmd == mag_cmd_handler[i].cmd) {
mag_cmd_handler[i].handler(hwdev, buf_in, in_size,
@@ -917,7 +1581,8 @@ static int _mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u32 i, cmd_cnt = ARRAY_LEN(vf_mag_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_mag_cmd_handler[i].cmd) {
cmd_to_pf = true;
@@ -949,3 +1614,124 @@ static int mag_msg_to_mgmt_sync_ch(void *hwdev, u16 cmd, void *buf_in,
return _mag_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out,
out_size, channel);
}
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+struct fecparam_value_map {
+ u8 hinic3_fec_offset;
+ u8 hinic3_fec_value;
+ u8 ethtool_fec_value;
+};
+
+static void fecparam_convert(u32 opcode, u8 in_fec_param, u8 *out_fec_param)
+{
+ u8 i;
+ u8 fec_value_table_lenth;
+ struct fecparam_value_map fec_value_table[] = {
+ {PORT_FEC_NOT_SET, BIT(PORT_FEC_NOT_SET), ETHTOOL_FEC_NONE},
+ {PORT_FEC_RSFEC, BIT(PORT_FEC_RSFEC), ETHTOOL_FEC_RS},
+ {PORT_FEC_BASEFEC, BIT(PORT_FEC_BASEFEC), ETHTOOL_FEC_BASER},
+ {PORT_FEC_NOFEC, BIT(PORT_FEC_NOFEC), ETHTOOL_FEC_OFF},
+#ifdef ETHTOOL_FEC_LLRS
+ {PORT_FEC_LLRSFEC, BIT(PORT_FEC_LLRSFEC), ETHTOOL_FEC_LLRS},
+#endif
+ {PORT_FEC_AUTO, BIT(PORT_FEC_AUTO), ETHTOOL_FEC_AUTO}
+ };
+
+ *out_fec_param = 0;
+ fec_value_table_lenth = (u8)(sizeof(fec_value_table) / sizeof(struct fecparam_value_map));
+
+ if (opcode == MAG_CMD_OPCODE_SET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].ethtool_fec_value) != 0)
+ /* The MPU uses the offset to determine the FEC mode. */
+ *out_fec_param =
+ fec_value_table[i].hinic3_fec_offset;
+ }
+ }
+
+ if (opcode == MAG_CMD_OPCODE_GET) {
+ for (i = 0; i < fec_value_table_lenth; i++) {
+ if ((in_fec_param &
+ fec_value_table[i].hinic3_fec_value) != 0)
+ *out_fec_param |=
+ fec_value_table[i].ethtool_fec_value;
+ }
+ }
+}
+
+/* When the ethtool is used to set the FEC mode */
+static bool check_fecparam_is_valid(u8 fec_param)
+{
+ if (
+#ifdef ETHTOOL_FEC_LLRS
+ (fec_param == ETHTOOL_FEC_LLRS) ||
+#endif
+ (fec_param == ETHTOOL_FEC_RS) ||
+ (fec_param == ETHTOOL_FEC_BASER) ||
+ (fec_param == ETHTOOL_FEC_OFF)) {
+ return true;
+ }
+ return false;
+}
+
+int set_fecparam(void *hwdev, u8 fecparam)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ u8 advertised_fec = 0;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (check_fecparam_is_valid(fecparam) == false) {
+ nic_err(nic_io->dev_hdl, "fec param is invalid, failed to set fec param\n");
+ return -EINVAL;
+ }
+ fecparam_convert(MAG_CMD_OPCODE_SET, fecparam, &advertised_fec);
+ fec_msg.opcode = MAG_CMD_OPCODE_SET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ fec_msg.advertised_fec = advertised_fec;
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0))
+ return -EINVAL;
+ return 0;
+}
+
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec)
+{
+ struct mag_cmd_cfg_fec_mode fec_msg = {0};
+ struct hinic3_nic_io *nic_io = NULL;
+ u16 out_size = sizeof(fec_msg);
+ int err;
+
+ if (!hwdev)
+ return -EINVAL;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ fec_msg.opcode = MAG_CMD_OPCODE_GET;
+ fec_msg.port_id = hinic3_physical_port_id(hwdev);
+ err = mag_msg_to_mgmt_sync_ch(hwdev, MAG_CMD_CFG_FEC_MODE,
+ &fec_msg, sizeof(fec_msg),
+ &fec_msg, &out_size, HINIC3_CHANNEL_NIC);
+ if ((err != 0) || (fec_msg.head.status != 0))
+ return -EINVAL;
+
+ /* fec_msg.advertised_fec: bit offset,
+ *value is BIT(fec_msg.advertised_fec); fec_msg.supported_fec: value
+ */
+ fecparam_convert(MAG_CMD_OPCODE_GET, BIT(fec_msg.advertised_fec),
+ advertised_fec);
+ fecparam_convert(MAG_CMD_OPCODE_GET, fec_msg.supported_fec,
+ supported_fec);
+ return 0;
+}
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
index 307ad8d..7790ae2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c
@@ -20,6 +20,9 @@
#include <linux/debugfs.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#include "hinic3_hw.h"
#include "hinic3_crm.h"
#include "hinic3_mt.h"
@@ -35,8 +38,8 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
#include "hinic3_profile.h"
+#include "hinic3_bond.h"
-/*lint -e806*/
#define DEFAULT_POLL_WEIGHT 64
static unsigned int poll_weight = DEFAULT_POLL_WEIGHT;
module_param(poll_weight, uint, 0444);
@@ -68,7 +71,9 @@ static unsigned char set_link_status_follow = HINIC3_LINK_FOLLOW_STATUS_MAX;
module_param(set_link_status_follow, byte, 0444);
MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=default,1=follow,2=separate,3=unset");
-/*lint +e806*/
+static bool page_pool_enabled = true;
+module_param(page_pool_enabled, bool, 0444);
+MODULE_PARM_DESC(page_pool_enabled, "enable/disable page_pool feature for rxq page management (default enable)");
#define HINIC3_NIC_DEV_WQ_NAME "hinic3_nic_dev_wq"
@@ -80,6 +85,8 @@ MODULE_PARM_DESC(set_link_status_follow, "Set link status follow port status (0=
#define HINIC3_SQ_DEPTH 1024
#define HINIC3_RQ_DEPTH 1024
+#define LRO_ENABLE 1
+
enum hinic3_rx_buff_len {
RX_BUFF_VALID_2KB = 2,
RX_BUFF_VALID_4KB = 4,
@@ -88,6 +95,9 @@ enum hinic3_rx_buff_len {
};
#define CONVERT_UNIT 1024
+#define NIC_MAX_PF_NUM 32
+
+#define BIFUR_RESOURCE_PF_SSID 0x5a1
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
static int hinic3_netdev_event(struct notifier_block *notifier, unsigned long event, void *ptr);
@@ -99,6 +109,17 @@ static struct notifier_block hinic3_netdev_notifier = {
.notifier_call = hinic3_netdev_event,
};
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+static const struct udp_tunnel_nic_info hinic3_udp_tunnels = {
+ .set_port = hinic3_udp_tunnel_set_port,
+ .unset_port = hinic3_udp_tunnel_unset_port,
+ .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP,
+ .tables = {
+ { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, },
+ },
+};
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static void hinic3_register_notifier(struct hinic3_nic_dev *nic_dev)
{
int err;
@@ -264,6 +285,11 @@ static void netdev_feature_init(struct net_device *netdev)
netdev->features |= dft_fts | cso_fts | tso_fts | vlan_fts;
netdev->vlan_features |= dft_fts | cso_fts | tso_fts;
+ if (nic_dev->nic_cap.lro_enable == LRO_ENABLE) {
+ netdev->features |= NETIF_F_LRO;
+ netdev->vlan_features |= NETIF_F_LRO;
+ }
+
#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT
hw_features |= get_netdev_hw_features(netdev);
#else
@@ -350,6 +376,7 @@ static int hinic3_init_intr_coalesce(struct hinic3_nic_dev *nic_dev)
static void hinic3_free_intr_coalesce(struct hinic3_nic_dev *nic_dev)
{
kfree(nic_dev->intr_coalesce);
+ nic_dev->intr_coalesce = NULL;
}
static int hinic3_alloc_txrxqs(struct hinic3_nic_dev *nic_dev)
@@ -404,8 +431,85 @@ static void hinic3_sw_deinit(struct hinic3_nic_dev *nic_dev)
HINIC3_CHANNEL_NIC);
hinic3_clear_rss_config(nic_dev);
- if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags))
- hinic3_sync_dcb_state(nic_dev->hwdev, 1, 0);
+ hinic3_dcb_deinit(nic_dev);
+}
+
+static void hinic3_netdev_mtu_init(struct net_device *netdev)
+{
+ /* MTU range: 384 - 9600 */
+#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
+ netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+
+#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
+ netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
+ netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
+#endif
+}
+
+static int hinic3_set_default_mac(struct hinic3_nic_dev *nic_dev)
+{
+ struct net_device *netdev = nic_dev->netdev;
+ u8 mac_addr[ETH_ALEN];
+ int err = 0;
+
+ err = hinic3_get_default_mac(nic_dev->hwdev, mac_addr);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev, "Failed to get MAC address\n");
+ return err;
+ }
+
+ ether_addr_copy(netdev->dev_addr, mac_addr);
+
+ if (!is_valid_ether_addr(netdev->dev_addr)) {
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
+ nic_err(&nic_dev->pdev->dev,
+ "Invalid MAC address %pM\n",
+ netdev->dev_addr);
+ return -EIO;
+ }
+
+ nic_info(&nic_dev->pdev->dev,
+ "Invalid MAC address %pM, using random\n",
+ netdev->dev_addr);
+ eth_hw_addr_random(netdev);
+ }
+
+ err = hinic3_set_mac(nic_dev->hwdev, netdev->dev_addr, 0,
+ hinic3_global_func_id(nic_dev->hwdev),
+ HINIC3_CHANNEL_NIC);
+ /* When this is VF driver, we must consider that PF has already set VF
+ * MAC, and we can't consider this condition is error status during
+ * driver probe procedure.
+ */
+ if (err && err != HINIC3_PF_SET_VF_ALREADY) {
+ nic_err(&nic_dev->pdev->dev, "Failed to set default MAC\n");
+ }
+
+ if (err == HINIC3_PF_SET_VF_ALREADY)
+ return 0;
+
+ return err;
+}
+
+static void hinic3_outband_cfg_init(struct hinic3_nic_dev *nic_dev)
+{
+ u16 outband_default_vid = 0;
+ int err = 0;
+
+ if (!nic_dev->nic_cap.outband_vlan_cfg_en)
+ return;
+
+ err = hinic3_get_outband_vlan_cfg(nic_dev->hwdev, &outband_default_vid);
+ if (err) {
+ nic_err(&nic_dev->pdev->dev, "Failed to get_outband_cfg, err: %d\n", err);
+ return;
+ }
+
+ nic_dev->outband_cfg.outband_default_vid = outband_default_vid;
+
+ return;
}
static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
@@ -421,8 +525,6 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
nic_features &= NIC_DRV_DEFAULT_FEATURE;
hinic3_update_nic_feature(nic_dev->hwdev, nic_features);
- sema_init(&nic_dev->port_state_sem, 1);
-
err = hinic3_dcb_init(nic_dev);
if (err) {
nic_err(&nic_dev->pdev->dev, "Failed to init dcb\n");
@@ -434,47 +536,12 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
hinic3_try_to_enable_rss(nic_dev);
- err = hinic3_get_default_mac(nic_dev->hwdev, netdev->dev_addr);
+ err = hinic3_set_default_mac(nic_dev);
if (err) {
- nic_err(&nic_dev->pdev->dev, "Failed to get MAC address\n");
- goto get_mac_err;
- }
-
- if (!is_valid_ether_addr(netdev->dev_addr)) {
- if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev)) {
- nic_err(&nic_dev->pdev->dev, "Invalid MAC address %pM\n",
- netdev->dev_addr);
- err = -EIO;
- goto err_mac;
- }
-
- nic_info(&nic_dev->pdev->dev, "Invalid MAC address %pM, using random\n",
- netdev->dev_addr);
- eth_hw_addr_random(netdev);
- }
-
- err = hinic3_set_mac(nic_dev->hwdev, netdev->dev_addr, 0,
- hinic3_global_func_id(nic_dev->hwdev),
- HINIC3_CHANNEL_NIC);
- /* When this is VF driver, we must consider that PF has already set VF
- * MAC, and we can't consider this condition is error status during
- * driver probe procedure.
- */
- if (err && err != HINIC3_PF_SET_VF_ALREADY) {
- nic_err(&nic_dev->pdev->dev, "Failed to set default MAC\n");
goto set_mac_err;
}
- /* MTU range: 384 - 9600 */
-#ifdef HAVE_NETDEVICE_MIN_MAX_MTU
- netdev->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
-
-#ifdef HAVE_NETDEVICE_EXTENDED_MIN_MAX_MTU
- netdev->extended->min_mtu = HINIC3_MIN_MTU_SIZE;
- netdev->extended->max_mtu = HINIC3_MAX_JUMBO_FRAME_SIZE;
-#endif
+ hinic3_netdev_mtu_init(netdev);
err = hinic3_alloc_txrxqs(nic_dev);
if (err) {
@@ -482,6 +549,8 @@ static int hinic3_sw_init(struct hinic3_nic_dev *nic_dev)
goto alloc_qps_err;
}
+ hinic3_outband_cfg_init(nic_dev);
+
return 0;
alloc_qps_err:
@@ -490,8 +559,6 @@ alloc_qps_err:
HINIC3_CHANNEL_NIC);
set_mac_err:
-err_mac:
-get_mac_err:
hinic3_clear_rss_config(nic_dev);
return err;
@@ -690,20 +757,51 @@ static void hinic3_periodic_work_handler(struct work_struct *work)
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
}
+static void hinic3_vport_stats_work_handler(struct work_struct *work)
+{
+ int err;
+ struct hinic3_vport_stats vport_stats = {0};
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_nic_dev *nic_dev = container_of(delay, struct hinic3_nic_dev, vport_stats_work);
+ err = hinic3_get_vport_stats(nic_dev->hwdev, hinic3_global_func_id(nic_dev->hwdev), &vport_stats);
+ if (err)
+ nic_err(&nic_dev->pdev->dev, "Failed to get dropped stats from fw\n");
+ else
+ nic_dev->vport_stats.rx_discard_vport = vport_stats.rx_discard_vport;
+ queue_delayed_work(nic_dev->workq, &nic_dev->vport_stats_work, HZ);
+}
+
+static void free_nic_dev_vram(struct hinic3_nic_dev *nic_dev)
+{
+ int is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0)
+ hi_vram_kfree((void *)nic_dev->nic_vram, nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ else
+ kfree(nic_dev->nic_vram);
+ nic_dev->nic_vram = NULL;
+}
+
static void free_nic_dev(struct hinic3_nic_dev *nic_dev)
{
hinic3_deinit_nic_prof_adapter(nic_dev);
destroy_workqueue(nic_dev->workq);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+ free_nic_dev_vram(nic_dev);
}
static int setup_nic_dev(struct net_device *netdev,
struct hinic3_lld_dev *lld_dev)
{
struct pci_dev *pdev = lld_dev->pdev;
- struct hinic3_nic_dev *nic_dev;
- char *netdev_name_fmt;
+ struct hinic3_nic_dev *nic_dev = NULL;
+ char *netdev_name_fmt = NULL;
u32 page_num;
+ u16 func_id;
+ int ret;
+ int is_in_kexec = vram_get_kexec_flag();
+ int is_use_vram = get_use_vram_flag();
nic_dev = (struct hinic3_nic_dev *)netdev_priv(netdev);
nic_dev->netdev = netdev;
@@ -718,24 +816,65 @@ static int setup_nic_dev(struct net_device *netdev,
nic_dev->dma_rx_buff_size = RX_BUFF_NUM_PER_PAGE * nic_dev->rx_buff_len;
page_num = nic_dev->dma_rx_buff_size / PAGE_SIZE;
nic_dev->page_order = page_num > 0 ? ilog2(page_num) : 0;
+ nic_dev->page_pool_enabled = page_pool_enabled;
+ nic_dev->outband_cfg.outband_default_vid = 0;
+
+ // value other than 0 indicates hot replace
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ ret = snprintf(nic_dev->nic_vram_name,
+ VRAM_NAME_MAX_LEN,
+ "%s%u", VRAM_NIC_VRAM, func_id);
+ if (ret < 0) {
+ nic_err(&pdev->dev, "NIC vram name snprintf failed, ret:%d.\n",
+ ret);
+ return -EINVAL;
+ }
+
+ nic_dev->nic_vram = (struct hinic3_vram *)hi_vram_kalloc(nic_dev->nic_vram_name,
+ sizeof(struct hinic3_vram));
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+
+ if (is_in_kexec == 0)
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ else
+ netdev->mtu = nic_dev->nic_vram->vram_mtu;
+ } else {
+ nic_dev->nic_vram = kzalloc(sizeof(struct hinic3_vram),
+ GFP_KERNEL);
+ if (!nic_dev->nic_vram) {
+ nic_err(&pdev->dev, "Failed to allocate nic vram\n");
+ return -ENOMEM;
+ }
+ nic_dev->nic_vram->vram_mtu = netdev->mtu;
+ }
mutex_init(&nic_dev->nic_mutex);
nic_dev->vlan_bitmap = kzalloc(VLAN_BITMAP_SIZE(nic_dev), GFP_KERNEL);
if (!nic_dev->vlan_bitmap) {
nic_err(&pdev->dev, "Failed to allocate vlan bitmap\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto vlan_bitmap_error;
}
nic_dev->workq = create_singlethread_workqueue(HINIC3_NIC_DEV_WQ_NAME);
if (!nic_dev->workq) {
nic_err(&pdev->dev, "Failed to initialize nic workqueue\n");
- kfree(nic_dev->vlan_bitmap);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto create_workq_error;
}
- INIT_DELAYED_WORK(&nic_dev->periodic_work, hinic3_periodic_work_handler);
- INIT_DELAYED_WORK(&nic_dev->rxq_check_work, hinic3_rxq_check_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->periodic_work,
+ hinic3_periodic_work_handler);
+ INIT_DELAYED_WORK(&nic_dev->rxq_check_work,
+ hinic3_rxq_check_work_handler);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ INIT_DELAYED_WORK(&nic_dev->vport_stats_work,
+ hinic3_vport_stats_work_handler);
INIT_LIST_HEAD(&nic_dev->uc_filter_list);
INIT_LIST_HEAD(&nic_dev->mc_filter_list);
@@ -748,10 +887,23 @@ static int setup_nic_dev(struct net_device *netdev,
hinic3_init_nic_prof_adapter(nic_dev);
netdev_name_fmt = hinic3_get_dft_netdev_name_fmt(nic_dev);
- if (netdev_name_fmt)
- strncpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (netdev_name_fmt) {
+ ret = strscpy(netdev->name, netdev_name_fmt, IFNAMSIZ);
+ if (ret < 0)
+ goto get_netdev_name_error;
+ }
return 0;
+
+get_netdev_name_error:
+ hinic3_deinit_nic_prof_adapter(nic_dev);
+ destroy_workqueue(nic_dev->workq);
+create_workq_error:
+ kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
+vlan_bitmap_error:
+ free_nic_dev_vram(nic_dev);
+ return ret;
}
static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
@@ -790,6 +942,32 @@ static int hinic3_set_default_hw_feature(struct hinic3_nic_dev *nic_dev)
return 0;
}
+static void hinic3_bond_init(struct hinic3_nic_dev *nic_dev)
+{
+ u32 bond_id = HINIC3_INVALID_BOND_ID;
+ int err = hinic3_create_bond(nic_dev->hwdev, &bond_id);
+ if (err != 0) {
+ goto bond_init_failed;
+ }
+
+ /* bond id does not change, means this pf is not bond active pf, no log is generated */
+ if (bond_id == HINIC3_INVALID_BOND_ID) {
+ return;
+ }
+
+ err = hinic3_open_close_bond(nic_dev->hwdev, true);
+ if (err != 0) {
+ hinic3_delete_bond(nic_dev->hwdev);
+ goto bond_init_failed;
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Bond %d init success\n", bond_id);
+ return;
+
+bond_init_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond init failed\n");
+}
+
static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
char *uld_dev_name)
{
@@ -820,6 +998,12 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
goto err_out;
}
+ err = hinic3_get_dev_cap(lld_dev->hwdev);
+ if (err != 0) {
+ nic_err(&pdev->dev, "Failed to get dev cap\n");
+ goto err_out;
+ }
+
max_qps = hinic3_func_max_nic_qnum(lld_dev->hwdev);
netdev = alloc_etherdev_mq(sizeof(*nic_dev), max_qps);
if (!netdev) {
@@ -851,23 +1035,35 @@ static int nic_probe(struct hinic3_lld_dev *lld_dev, void **uld_dev,
hinic3_assign_netdev_ops(nic_dev);
netdev_feature_init(netdev);
-
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+ netdev->udp_tunnel_nic_info = &hinic3_udp_tunnels;
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
err = hinic3_set_default_hw_feature(nic_dev);
if (err)
goto set_features_err;
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0) {
+ hinic3_bond_init(nic_dev);
+ }
+
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
hinic3_register_notifier(nic_dev);
#endif
- err = register_netdev(netdev);
- if (err) {
- nic_err(&pdev->dev, "Failed to register netdev\n");
- err = -ENOMEM;
- goto netdev_err;
+ if (pdev->subsystem_device != BIFUR_RESOURCE_PF_SSID) {
+ err = register_netdev(netdev);
+ if (err) {
+ nic_err(&pdev->dev, "Failed to register netdev\n");
+ err = -ENOMEM;
+ goto netdev_err;
+ }
}
queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ queue_delayed_work(nic_dev->workq,
+ &nic_dev->vport_stats_work, HZ);
+
netif_carrier_off(netdev);
*uld_dev = nic_dev;
@@ -900,6 +1096,27 @@ err_out:
return err;
}
+static void hinic3_bond_deinit(struct hinic3_nic_dev *nic_dev)
+{
+ int ret = 0;
+
+ ret = hinic3_open_close_bond(nic_dev->hwdev, false);
+ if (ret != 0) {
+ goto bond_deinit_failed;
+ }
+
+ ret = hinic3_delete_bond(nic_dev->hwdev);
+ if (ret != 0) {
+ goto bond_deinit_failed;
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Bond deinit success\n");
+ return;
+
+bond_deinit_failed:
+ nic_err(&nic_dev->pdev->dev, "Bond deinit failed\n");
+}
+
static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
{
struct hinic3_nic_dev *nic_dev = adapter;
@@ -912,11 +1129,16 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
netdev = nic_dev->netdev;
- unregister_netdev(netdev);
+ if (lld_dev->pdev->subsystem_device != BIFUR_RESOURCE_PF_SSID) {
+ unregister_netdev(netdev);
+ }
#ifdef HAVE_MULTI_VLAN_OFFLOAD_EN
hinic3_unregister_notifier(nic_dev);
#endif
+ if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
+ cancel_delayed_work_sync(&nic_dev->vport_stats_work);
+
cancel_delayed_work_sync(&nic_dev->periodic_work);
cancel_delayed_work_sync(&nic_dev->rxq_check_work);
cancel_work_sync(&nic_dev->rx_mode_work);
@@ -924,6 +1146,10 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_flush_rx_flow_rule(nic_dev);
+ if (hinic3_get_bond_create_mode(lld_dev->hwdev) != 0) {
+ hinic3_bond_deinit(nic_dev);
+ }
+
hinic3_update_nic_feature(nic_dev->hwdev, 0);
hinic3_set_nic_feature_to_hw(nic_dev->hwdev);
@@ -933,6 +1159,7 @@ static void nic_remove(struct hinic3_lld_dev *lld_dev, void *adapter)
hinic3_deinit_nic_prof_adapter(nic_dev);
kfree(nic_dev->vlan_bitmap);
+ nic_dev->vlan_bitmap = NULL;
free_netdev(netdev);
@@ -981,6 +1208,120 @@ static void hinic3_port_module_event_handler(struct hinic3_nic_dev *nic_dev,
}
}
+bool hinic3_need_proc_link_event(struct hinic3_lld_dev *lld_dev)
+{
+ int ret = 0;
+ u16 func_id;
+ u8 roce_enable = false;
+ bool is_slave_func = false;
+ struct hinic3_hw_bond_infos hw_bond_infos = {0};
+
+ if (!lld_dev)
+ return false;
+
+ /* 非slave设备需要处理link down事件 */
+ ret = hinic3_is_slave_func(lld_dev->hwdev, &is_slave_func);
+ if (ret != 0) {
+ nic_err(&lld_dev->pdev->dev, "NIC get info, lld_dev is null\n");
+ return true;
+ }
+
+ if (!is_slave_func)
+ return true;
+
+ /* 未使能了vroce功能,需处理link down事件 */
+ func_id = hinic3_global_func_id(lld_dev->hwdev);
+ ret = hinic3_get_func_vroce_enable(lld_dev->hwdev, func_id,
+ &roce_enable);
+ if (ret != 0)
+ return true;
+
+ if (!roce_enable)
+ return true;
+
+ /* 未创建bond,需要处理link down事件 */
+ hw_bond_infos.bond_id = HINIC_OVS_BOND_DEFAULT_ID;
+
+ ret = hinic3_get_hw_bond_infos(lld_dev->hwdev, &hw_bond_infos,
+ HINIC3_CHANNEL_COMM);
+ if (ret != 0) {
+ pr_err("[ROCE, ERR] Get chipf bond info failed (%d)\n", ret);
+ return true;
+ }
+
+ if (!hw_bond_infos.valid)
+ return true;
+
+ return false;
+}
+
+bool hinic3_need_proc_bond_event(struct hinic3_lld_dev *lld_dev)
+{
+ return !hinic3_need_proc_link_event(lld_dev);
+}
+
+static void hinic_porc_bond_state_change(struct hinic3_lld_dev *lld_dev,
+ void *adapter,
+ struct hinic3_event_info *event)
+{
+ struct hinic3_nic_dev *nic_dev = adapter;
+
+ if (!nic_dev || !event || !hinic3_support_nic(lld_dev->hwdev, NULL))
+ return;
+
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond down\n");
+ hinic3_link_status_change(nic_dev, false);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ if (!hinic3_need_proc_bond_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc bond event\n");
+ return;
+ }
+ nic_info(&lld_dev->pdev->dev, "NIC proc bond up\n");
+ hinic3_link_status_change(nic_dev, true);
+ break;
+ default:
+ break;
+ }
+}
+
+static void hinic3_outband_cfg_event_handler(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_outband_cfg_info *info)
+{
+ int err = 0;
+ if (!nic_dev || !info || !hinic3_support_nic(nic_dev->hwdev, NULL)) {
+ pr_err("Outband cfg event invalid param\n");
+ return;
+ }
+
+ if (hinic3_func_type(nic_dev->hwdev) != TYPE_VF &&
+ info->func_id >= NIC_MAX_PF_NUM) {
+ err = hinic3_notify_vf_outband_cfg(nic_dev->hwdev,
+ info->func_id,
+ info->outband_default_vid);
+ if (err)
+ nic_err(&nic_dev->pdev->dev, "Outband cfg event notify vf err: %d,"
+ "func_id: 0x%x, vid: 0x%x\n",
+ err, info->func_id, info->outband_default_vid);
+ return;
+ }
+
+ nic_info(&nic_dev->pdev->dev,
+ "Change outband default vid from %u to %u\n",
+ nic_dev->outband_cfg.outband_default_vid,
+ info->outband_default_vid);
+
+ nic_dev->outband_cfg.outband_default_vid = info->outband_default_vid;
+
+ return;
+}
+
static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
struct hinic3_event_info *event)
{
@@ -992,14 +1333,25 @@ static void nic_event(struct hinic3_lld_dev *lld_dev, void *adapter,
switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_DOWN):
+ if (!hinic3_need_proc_link_event(lld_dev)) {
+ nic_info(&lld_dev->pdev->dev, "NIC don't need proc link event\n");
+ return;
+ }
hinic3_link_status_change(nic_dev, false);
break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_LINK_UP):
hinic3_link_status_change(nic_dev, true);
break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_DOWN):
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_BOND_UP):
+ hinic_porc_bond_state_change(lld_dev, adapter, event);
+ break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_PORT_MODULE_EVENT):
hinic3_port_module_event_handler(nic_dev, event);
break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_NIC, EVENT_NIC_OUTBAND_CFG):
+ hinic3_outband_cfg_event_handler(nic_dev, (void *)event->event_data);
+ break;
case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_SRIOV_STATE_CHANGE):
sriov_state_change(nic_dev, (void *)event->event_data);
break;
@@ -1059,7 +1411,7 @@ struct hinic3_uld_info g_nic_uld_info = {
.resume = NULL,
.event = nic_event,
.ioctl = nic_ioctl,
-}; /*lint -e766*/
+};
struct hinic3_uld_info *get_nic_uld_info(void)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h b/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h
deleted file mode 100644
index 522518d..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt_interface.h
+++ /dev/null
@@ -1,1298 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
-
-#ifndef NIC_MPU_CMD_DEFS_H
-#define NIC_MPU_CMD_DEFS_H
-
-#include "nic_cfg_comm.h"
-#include "mpu_cmd_base_defs.h"
-
-#ifndef ETH_ALEN
-#define ETH_ALEN 6
-#endif
-
-#define HINIC3_CMD_OP_SET 1
-#define HINIC3_CMD_OP_GET 0
-
-#define HINIC3_CMD_OP_ADD 1
-#define HINIC3_CMD_OP_DEL 0
-
-#define NIC_TCAM_BLOCK_LARGE_NUM 256
-#define NIC_TCAM_BLOCK_LARGE_SIZE 16
-
-#ifndef BIT
-#define BIT(n) (1UL << (n))
-#endif
-
-enum nic_feature_cap {
- NIC_F_CSUM = BIT(0),
- NIC_F_SCTP_CRC = BIT(1),
- NIC_F_TSO = BIT(2),
- NIC_F_LRO = BIT(3),
- NIC_F_UFO = BIT(4),
- NIC_F_RSS = BIT(5),
- NIC_F_RX_VLAN_FILTER = BIT(6),
- NIC_F_RX_VLAN_STRIP = BIT(7),
- NIC_F_TX_VLAN_INSERT = BIT(8),
- NIC_F_VXLAN_OFFLOAD = BIT(9),
- NIC_F_IPSEC_OFFLOAD = BIT(10),
- NIC_F_FDIR = BIT(11),
- NIC_F_PROMISC = BIT(12),
- NIC_F_ALLMULTI = BIT(13),
- NIC_F_XSFP_REPORT = BIT(14),
- NIC_F_VF_MAC = BIT(15),
- NIC_F_RATE_LIMIT = BIT(16),
- NIC_F_RXQ_RECOVERY = BIT(17),
-};
-
-#define NIC_F_ALL_MASK 0x3FFFF /* 使能所有属性 */
-
-struct hinic3_mgmt_msg_head {
- u8 status;
- u8 version;
- u8 rsvd0[6];
-};
-
-#define NIC_MAX_FEATURE_QWORD 4
-struct hinic3_cmd_feature_nego {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 opcode; /* 1: set, 0: get */
- u8 rsvd;
- u64 s_feature[NIC_MAX_FEATURE_QWORD];
-};
-
-struct hinic3_port_mac_set {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 vlan_id;
- u16 rsvd1;
- u8 mac[ETH_ALEN];
-};
-
-struct hinic3_port_mac_update {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 vlan_id;
- u16 rsvd1;
- u8 old_mac[ETH_ALEN];
- u16 rsvd2;
- u8 new_mac[ETH_ALEN];
-};
-
-struct hinic3_vport_state {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd1;
- u8 state; /* 0--disable, 1--enable */
- u8 rsvd2[3];
-};
-
-struct hinic3_port_state {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd1;
- u8 state; /* 0--disable, 1--enable */
- u8 rsvd2[3];
-};
-
-#define HINIC3_SET_PORT_CAR_PROFILE 0
-#define HINIC3_SET_PORT_CAR_STATE 1
-
-struct hinic3_port_car_info {
- u32 cir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
- u32 xir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
- u32 cbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
- u32 xbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
-};
-
-struct hinic3_cmd_set_port_car {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 opcode; /* 0--set car profile, 1--set car state */
- u8 state; /* 0--disable, 1--enable */
- u8 rsvd;
-
- struct hinic3_port_car_info car;
-};
-
-struct hinic3_cmd_clear_qp_resource {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd1;
-};
-
-struct hinic3_cmd_cache_out_qp_resource {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd1;
-};
-
-struct hinic3_port_stats_info {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd1;
-};
-
-struct hinic3_vport_stats {
- u64 tx_unicast_pkts_vport;
- u64 tx_unicast_bytes_vport;
- u64 tx_multicast_pkts_vport;
- u64 tx_multicast_bytes_vport;
- u64 tx_broadcast_pkts_vport;
- u64 tx_broadcast_bytes_vport;
-
- u64 rx_unicast_pkts_vport;
- u64 rx_unicast_bytes_vport;
- u64 rx_multicast_pkts_vport;
- u64 rx_multicast_bytes_vport;
- u64 rx_broadcast_pkts_vport;
- u64 rx_broadcast_bytes_vport;
-
- u64 tx_discard_vport;
- u64 rx_discard_vport;
- u64 tx_err_vport;
- u64 rx_err_vport;
-};
-
-struct hinic3_phy_fpga_port_stats {
- u64 mac_rx_total_octs_port;
- u64 mac_tx_total_octs_port;
- u64 mac_rx_under_frame_pkts_port;
- u64 mac_rx_frag_pkts_port;
- u64 mac_rx_64_oct_pkts_port;
- u64 mac_rx_127_oct_pkts_port;
- u64 mac_rx_255_oct_pkts_port;
- u64 mac_rx_511_oct_pkts_port;
- u64 mac_rx_1023_oct_pkts_port;
- u64 mac_rx_max_oct_pkts_port;
- u64 mac_rx_over_oct_pkts_port;
- u64 mac_tx_64_oct_pkts_port;
- u64 mac_tx_127_oct_pkts_port;
- u64 mac_tx_255_oct_pkts_port;
- u64 mac_tx_511_oct_pkts_port;
- u64 mac_tx_1023_oct_pkts_port;
- u64 mac_tx_max_oct_pkts_port;
- u64 mac_tx_over_oct_pkts_port;
- u64 mac_rx_good_pkts_port;
- u64 mac_rx_crc_error_pkts_port;
- u64 mac_rx_broadcast_ok_port;
- u64 mac_rx_multicast_ok_port;
- u64 mac_rx_mac_frame_ok_port;
- u64 mac_rx_length_err_pkts_port;
- u64 mac_rx_vlan_pkts_port;
- u64 mac_rx_pause_pkts_port;
- u64 mac_rx_unknown_mac_frame_port;
- u64 mac_tx_good_pkts_port;
- u64 mac_tx_broadcast_ok_port;
- u64 mac_tx_multicast_ok_port;
- u64 mac_tx_underrun_pkts_port;
- u64 mac_tx_mac_frame_ok_port;
- u64 mac_tx_vlan_pkts_port;
- u64 mac_tx_pause_pkts_port;
-};
-
-struct hinic3_port_stats {
- struct hinic3_mgmt_msg_head msg_head;
-
- struct hinic3_phy_fpga_port_stats stats;
-};
-
-struct hinic3_cmd_vport_stats {
- struct hinic3_mgmt_msg_head msg_head;
-
- u32 stats_size;
- u32 rsvd1;
- struct hinic3_vport_stats stats;
- u64 rsvd2[6];
-};
-
-struct hinic3_cmd_qpn {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 base_qpn;
-};
-
-enum hinic3_func_tbl_cfg_bitmap {
- FUNC_CFG_INIT,
- FUNC_CFG_RX_BUF_SIZE,
- FUNC_CFG_MTU,
-};
-
-struct hinic3_func_tbl_cfg {
- u16 rx_wqe_buf_size;
- u16 mtu;
- u32 rsvd[9];
-};
-
-struct hinic3_cmd_set_func_tbl {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd;
-
- u32 cfg_bitmap;
- struct hinic3_func_tbl_cfg tbl_cfg;
-};
-
-struct hinic3_cmd_cons_idx_attr {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_idx;
- u8 dma_attr_off;
- u8 pending_limit;
- u8 coalescing_time;
- u8 intr_en;
- u16 intr_idx;
- u32 l2nic_sqn;
- u32 rsvd;
- u64 ci_addr;
-};
-
-union sm_tbl_args {
- struct {
- u32 tbl_index;
- u32 cnt;
- u32 total_cnt;
- } mac_table_arg;
- struct {
- u32 er_id;
- u32 vlan_id;
- } vlan_elb_table_arg;
- struct {
- u32 func_id;
- } vlan_filter_arg;
- struct {
- u32 mc_id;
- } mc_elb_arg;
- struct {
- u32 func_id;
- } func_tbl_arg;
- struct {
- u32 port_id;
- } port_tbl_arg;
- struct {
- u32 tbl_index;
- u32 cnt;
- u32 total_cnt;
- } fdir_io_table_arg;
- struct {
- u32 tbl_index;
- u32 cnt;
- u32 total_cnt;
- } flexq_table_arg;
- u32 args[4];
-};
-
-#define DFX_SM_TBL_BUF_MAX (768)
-
-struct nic_cmd_dfx_sm_table {
- struct hinic3_mgmt_msg_head msg_head;
- u32 tbl_type;
- union sm_tbl_args args;
- u8 tbl_buf[DFX_SM_TBL_BUF_MAX];
-};
-
-struct hinic3_cmd_vlan_offload {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 vlan_offload;
- u8 rsvd1[5];
-};
-
-/* ucode capture cfg info */
-struct nic_cmd_capture_info {
- struct hinic3_mgmt_msg_head msg_head;
- u32 op_type;
- u32 func_port;
- u32 is_en_trx;
- u32 offset_cos;
- u32 data_vlan;
-};
-
-struct hinic3_cmd_lro_config {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 opcode;
- u8 rsvd1;
- u8 lro_ipv4_en;
- u8 lro_ipv6_en;
- u8 lro_max_pkt_len; /* unit is 1K */
- u8 resv2[13];
-};
-
-struct hinic3_cmd_lro_timer {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 opcode; /* 1: set timer value, 0: get timer value */
- u8 rsvd1;
- u16 rsvd2;
- u32 timer;
-};
-
-struct hinic3_cmd_local_lro_state {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 opcode; /* 0: get state, 1: set state */
- u8 state; /* 0: disable, 1: enable */
-};
-
-struct hinic3_cmd_vf_vlan_config {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 opcode;
- u8 rsvd1;
- u16 vlan_id;
- u8 qos;
- u8 rsvd2[5];
-};
-
-struct hinic3_cmd_spoofchk_set {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 state;
- u8 rsvd1;
-};
-
-struct hinic3_cmd_tx_rate_cfg {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd1;
- u32 min_rate;
- u32 max_rate;
- u8 rsvd2[8];
-};
-
-struct hinic3_cmd_port_info {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 rsvd1[3];
- u8 port_type;
- u8 autoneg_cap;
- u8 autoneg_state;
- u8 duplex;
- u8 speed;
- u8 fec;
- u16 rsvd2;
- u32 rsvd3[4];
-};
-
-struct hinic3_cmd_register_vf {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 op_register; /* 0 - unregister, 1 - register */
- u8 rsvd1[3];
- u32 support_extra_feature;
- u8 rsvd2[32];
-};
-
-struct hinic3_cmd_link_state {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 state;
- u16 rsvd1;
-};
-
-struct hinic3_cmd_vlan_config {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 opcode;
- u8 rsvd1;
- u16 vlan_id;
- u16 rsvd2;
-};
-
-/* set vlan filter */
-struct hinic3_cmd_set_vlan_filter {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 resvd[2];
- u32 vlan_filter_ctrl; /* bit0:vlan filter en; bit1:broadcast_filter_en */
-};
-
-struct hinic3_cmd_link_ksettings_info {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 rsvd1[3];
-
- u32 valid_bitmap;
- u8 speed; /* enum nic_speed_level */
- u8 autoneg; /* 0 - off, 1 - on */
- u8 fec; /* 0 - RSFEC, 1 - BASEFEC, 2 - NOFEC */
- u8 rsvd2[21]; /* reserved for duplex, port, etc. */
-};
-
-struct mpu_lt_info {
- u8 node;
- u8 inst;
- u8 entry_size;
- u8 rsvd;
- u32 lt_index;
- u32 offset;
- u32 len;
-};
-
-struct nic_mpu_lt_opera {
- struct hinic3_mgmt_msg_head msg_head;
- struct mpu_lt_info net_lt_cmd;
- u8 data[100];
-};
-
-struct hinic3_force_pkt_drop {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port;
- u8 rsvd1[3];
-};
-
-struct hinic3_rx_mode_config {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd1;
- u32 rx_mode;
-};
-
-/* rss */
-struct hinic3_rss_context_table {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd1;
- u32 context;
-};
-
-struct hinic3_cmd_rss_engine_type {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 opcode;
- u8 hash_engine;
- u8 rsvd1[4];
-};
-
-struct hinic3_cmd_rss_hash_key {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 opcode;
- u8 rsvd1;
- u8 key[NIC_RSS_KEY_SIZE];
-};
-
-struct hinic3_rss_indir_table {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u16 rsvd1;
- u8 indir[NIC_RSS_INDIR_SIZE];
-};
-
-#define NIC_RSS_CMD_TEMP_ALLOC 0x01
-#define NIC_RSS_CMD_TEMP_FREE 0x02
-
-struct hinic3_rss_template_mgmt {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 cmd;
- u8 template_id;
- u8 rsvd1[4];
-};
-
-struct hinic3_cmd_rss_config {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 rss_en;
- u8 rq_priority_number;
- u8 prio_tc[NIC_DCB_COS_MAX];
- u16 num_qps;
- u16 rsvd1;
-};
-
-struct hinic3_dcb_state {
- u8 dcb_on;
- u8 default_cos;
- u8 trust;
- u8 rsvd1;
- u8 pcp2cos[NIC_DCB_UP_MAX];
- u8 dscp2cos[64];
- u32 rsvd2[7];
-};
-
-struct hinic3_cmd_vf_dcb_state {
- struct hinic3_mgmt_msg_head msg_head;
-
- struct hinic3_dcb_state state;
-};
-
-struct hinic3_up_ets_cfg { /* delet */
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 rsvd1[3];
-
- u8 cos_tc[NIC_DCB_COS_MAX];
- u8 tc_bw[NIC_DCB_TC_MAX];
- u8 cos_prio[NIC_DCB_COS_MAX];
- u8 cos_bw[NIC_DCB_COS_MAX];
- u8 tc_prio[NIC_DCB_TC_MAX];
-};
-
-#define CMD_QOS_ETS_COS_TC BIT(0)
-#define CMD_QOS_ETS_TC_BW BIT(1)
-#define CMD_QOS_ETS_COS_PRIO BIT(2)
-#define CMD_QOS_ETS_COS_BW BIT(3)
-#define CMD_QOS_ETS_TC_PRIO BIT(4)
-struct hinic3_cmd_ets_cfg {
- struct hinic3_mgmt_msg_head head;
-
- u8 port_id;
- u8 op_code; /* 1 - set, 0 - get */
- /* bit0 - cos_tc, bit1 - tc_bw, bit2 - cos_prio, bit3 - cos_bw, bit4 - tc_prio */
- u8 cfg_bitmap;
- u8 rsvd;
-
- u8 cos_tc[NIC_DCB_COS_MAX];
- u8 tc_bw[NIC_DCB_TC_MAX];
- u8 cos_prio[NIC_DCB_COS_MAX]; /* 0 - DWRR, 1 - STRICT */
- u8 cos_bw[NIC_DCB_COS_MAX];
- u8 tc_prio[NIC_DCB_TC_MAX]; /* 0 - DWRR, 1 - STRICT */
-};
-
-struct hinic3_cmd_set_dcb_state {
- struct hinic3_mgmt_msg_head head;
-
- u16 func_id;
- u8 op_code; /* 0 - get dcb state, 1 - set dcb state */
- u8 state; /* 0 - disable, 1 - enable dcb */
- u8 port_state; /* 0 - disable, 1 - enable dcb */
- u8 rsvd[7];
-};
-
-#define PFC_BIT_MAP_NUM 8
-struct hinic3_cmd_set_pfc {
- struct hinic3_mgmt_msg_head head;
-
- u8 port_id;
- u8 op_code; /* 0:get 1: set pfc_en 2: set pfc_bitmap 3: set all */
- u8 pfc_en; /* pfc_en 和 pfc_bitmap 必须同时设置 */
- u8 pfc_bitmap;
- u8 rsvd[4];
-};
-
-#define CMD_QOS_PORT_TRUST BIT(0)
-#define CMD_QOS_PORT_DFT_COS BIT(1)
-struct hinic3_cmd_qos_port_cfg {
- struct hinic3_mgmt_msg_head head;
-
- u8 port_id;
- u8 op_code; /* 0 - get, 1 - set */
- u8 cfg_bitmap; /* bit0 - trust, bit1 - dft_cos */
- u8 rsvd0;
-
- u8 trust;
- u8 dft_cos;
- u8 rsvd1[18];
-};
-
-#define MAP_COS_MAX_NUM 8
-#define CMD_QOS_MAP_PCP2COS BIT(0)
-#define CMD_QOS_MAP_DSCP2COS BIT(1)
-struct hinic3_cmd_qos_map_cfg {
- struct hinic3_mgmt_msg_head head;
-
- u8 op_code;
- u8 cfg_bitmap; /* bit0 - pcp2cos, bit1 - dscp2cos */
- u16 rsvd0;
-
- u8 pcp2cos[8]; /* 8 must be configured together */
- /* If the dscp2cos parameter is set to 0xFF, the MPU ignores the DSCP priority,
- * Multiple mappings between DSCP values and CoS values can be configured at a time.
- */
- u8 dscp2cos[64];
- u32 rsvd1[4];
-};
-
-struct hinic3_cos_up_map {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 cos_valid_mask; /* every bit indicate index of map is valid 1 or not 0 */
- u16 rsvd1;
-
- /* user priority in cos(index:cos, value: up pri) */
- u8 map[NIC_DCB_UP_MAX];
-};
-
-struct hinic3_cmd_pause_config {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 opcode;
- u16 rsvd1;
- u8 auto_neg;
- u8 rx_pause;
- u8 tx_pause;
- u8 rsvd2[5];
-};
-
-struct nic_cmd_pause_inquiry_cfg {
- struct hinic3_mgmt_msg_head head;
-
- u32 valid;
-
- u32 type; /* 1: set, 2: get */
-
- u32 rx_inquiry_pause_drop_pkts_en;
- u32 rx_inquiry_pause_period_ms;
- u32 rx_inquiry_pause_times;
- /* rx pause Detection Threshold, Default PAUSE_FRAME_THD_10G/25G/40G/100 */
- u32 rx_inquiry_pause_frame_thd;
- u32 rx_inquiry_tx_total_pkts;
-
- u32 tx_inquiry_pause_en; /* tx pause detect enable */
- u32 tx_inquiry_pause_period_ms; /* tx pause Default Detection Period 200ms */
- u32 tx_inquiry_pause_times; /* tx pause Default Times Period 5 */
- u32 tx_inquiry_pause_frame_thd; /* tx pause Detection Threshold */
- u32 tx_inquiry_rx_total_pkts;
- u32 rsvd[4];
-};
-
-/* pfc/pause Storm TX exception reporting */
-struct nic_cmd_tx_pause_notice {
- struct hinic3_mgmt_msg_head head;
-
- u32 tx_pause_except; /* 1: abnormality,0: normal */
- u32 except_level;
- u32 rsvd;
-};
-
-#define HINIC3_CMD_OP_FREE 0
-#define HINIC3_CMD_OP_ALLOC 1
-
-struct hinic3_cmd_cfg_qps {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 opcode; /* 1: alloc qp, 0: free qp */
- u8 rsvd1;
- u16 num_qps;
- u16 rsvd2;
-};
-
-struct hinic3_cmd_led_config {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port;
- u8 type;
- u8 mode;
- u8 rsvd1;
-};
-
-struct hinic3_cmd_port_loopback {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 opcode;
- u8 mode;
- u8 en;
- u32 rsvd1[2];
-};
-
-struct hinic3_cmd_get_light_module_abs {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 abs_status; /* 0:present, 1:absent */
- u8 rsv[2];
-};
-
-#define STD_SFP_INFO_MAX_SIZE 640
-struct hinic3_cmd_get_std_sfp_info {
- struct hinic3_mgmt_msg_head msg_head;
-
- u8 port_id;
- u8 wire_type;
- u16 eeprom_len;
- u32 rsvd;
- u8 sfp_info[STD_SFP_INFO_MAX_SIZE];
-};
-
-struct hinic3_cable_plug_event {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 plugged; /* 0: unplugged, 1: plugged */
- u8 port_id;
-};
-
-struct nic_cmd_mac_info {
- struct hinic3_mgmt_msg_head head;
-
- u32 valid_bitmap;
- u16 rsvd;
-
- u8 host_id[32];
- u8 port_id[32];
- u8 mac_addr[192];
-};
-
-struct nic_cmd_set_tcam_enable {
- struct hinic3_mgmt_msg_head head;
-
- u16 func_id;
- u8 tcam_enable;
- u8 rsvd1;
- u32 rsvd2;
-};
-
-struct nic_cmd_set_fdir_status {
- struct hinic3_mgmt_msg_head head;
-
- u16 func_id;
- u16 rsvd1;
- u8 pkt_type_en;
- u8 pkt_type;
- u8 qid;
- u8 rsvd2;
-};
-
-#define HINIC3_TCAM_BLOCK_ENABLE 1
-#define HINIC3_TCAM_BLOCK_DISABLE 0
-#define HINIC3_MAX_TCAM_RULES_NUM 4096
-
-/* tcam block type, according to tcam block size */
-enum {
- NIC_TCAM_BLOCK_TYPE_LARGE = 0, /* block_size: 16 */
- NIC_TCAM_BLOCK_TYPE_SMALL, /* block_size: 0 */
- NIC_TCAM_BLOCK_TYPE_MAX
-};
-
-/* alloc tcam block input struct */
-struct nic_cmd_ctrl_tcam_block_in {
- struct hinic3_mgmt_msg_head head;
-
- u16 func_id; /* func_id */
- u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
- /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
- u8 tcam_type;
- u16 tcam_block_index;
- /* Size of the block that the driver wants to allocate
- * Interface returned by the UP to the driver,
- * indicating the size of the allocated TCAM block supported by the UP
- */
- u16 alloc_block_num;
-};
-
-/* alloc tcam block output struct */
-struct nic_cmd_ctrl_tcam_block_out {
- struct hinic3_mgmt_msg_head head;
-
- u16 func_id; /* func_id */
- u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
- /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
- u8 tcam_type;
- u16 tcam_block_index;
- /* Size of the block that the driver wants to allocate
- * Interface returned by the UP to the driver,
- * indicating the size of the allocated TCAM block supported by the UP
- */
- u16 mpu_alloc_block_size;
-};
-
-struct nic_cmd_flush_tcam_rules {
- struct hinic3_mgmt_msg_head head;
-
- u16 func_id; /* func_id */
- u16 rsvd;
-};
-
-struct nic_cmd_dfx_fdir_tcam_block_table {
- struct hinic3_mgmt_msg_head head;
- u8 tcam_type;
- u8 valid;
- u16 tcam_block_index;
- u16 use_function_id;
- u16 rsvd;
-};
-
-struct tcam_result {
- u32 qid;
- u32 rsvd;
-};
-
-#define TCAM_FLOW_KEY_SIZE (44)
-
-struct tcam_key_x_y {
- u8 x[TCAM_FLOW_KEY_SIZE];
- u8 y[TCAM_FLOW_KEY_SIZE];
-};
-
-struct nic_tcam_cfg_rule {
- u32 index;
- struct tcam_result data;
- struct tcam_key_x_y key;
-};
-
-#define TCAM_RULE_FDIR_TYPE 0
-#define TCAM_RULE_PPA_TYPE 1
-
-struct nic_cmd_fdir_add_rule {
- struct hinic3_mgmt_msg_head head;
-
- u16 func_id;
- u8 type;
- u8 fdir_ext; /* 0x1: flow bifur en bit */
- struct nic_tcam_cfg_rule rule;
-};
-
-struct nic_cmd_fdir_del_rules {
- struct hinic3_mgmt_msg_head head;
-
- u16 func_id;
- u8 type;
- u8 rsvd;
- u32 index_start;
- u32 index_num;
-};
-
-struct nic_cmd_fdir_get_rule {
- struct hinic3_mgmt_msg_head head;
-
- u32 index;
- u8 valid;
- u8 type;
- u16 rsvd;
- struct tcam_key_x_y key;
- struct tcam_result data;
- u64 packet_count;
- u64 byte_count;
-};
-
-struct nic_cmd_fdir_get_block_rules {
- struct hinic3_mgmt_msg_head head;
- u8 tcam_block_type; // only NIC_TCAM_BLOCK_TYPE_LARGE
- u8 tcam_table_type; // TCAM_RULE_PPA_TYPE or TCAM_RULE_FDIR_TYPE
- u16 tcam_block_index;
- u8 valid[NIC_TCAM_BLOCK_LARGE_SIZE];
- struct tcam_key_x_y key[NIC_TCAM_BLOCK_LARGE_SIZE];
- struct tcam_result data[NIC_TCAM_BLOCK_LARGE_SIZE];
-};
-
-struct hinic3_tcam_key_ipv4_mem {
- u32 rsvd1 : 4;
- u32 tunnel_type : 4;
- u32 ip_proto : 8;
- u32 rsvd0 : 16;
- u32 sipv4_h : 16;
- u32 ip_type : 1;
- u32 function_id : 15;
- u32 dipv4_h : 16;
- u32 sipv4_l : 16;
- u32 vlan_id : 15;
- u32 vlan_flag : 1;
- u32 dipv4_l : 16;
- u32 rsvd3;
- u32 dport : 16;
- u32 rsvd4 : 16;
- u32 rsvd5 : 16;
- u32 sport : 16;
- u32 outer_sipv4_h : 16;
- u32 rsvd6 : 16;
- u32 outer_dipv4_h : 16;
- u32 outer_sipv4_l : 16;
- u32 vni_h : 16;
- u32 outer_dipv4_l : 16;
- u32 rsvd7 : 16;
- u32 vni_l : 16;
-};
-
-union hinic3_tag_tcam_ext_info {
- struct {
- u32 id : 16; /* id */
- u32 type : 4; /* type: 0-func, 1-vmdq, 2-port, 3-rsvd, 4-trunk, 5-dp, 6-mc */
- u32 host_id : 3;
- u32 rsv : 8;
- u32 ext : 1;
- } bs;
- u32 value;
-};
-
-struct hinic3_tcam_key_ipv6_mem {
- u32 rsvd1 : 4;
- u32 tunnel_type : 4;
- u32 ip_proto : 8;
- u32 rsvd0 : 16;
- u32 sipv6_key0 : 16;
- u32 ip_type : 1;
- u32 function_id : 15;
- u32 sipv6_key2 : 16;
- u32 sipv6_key1 : 16;
- u32 sipv6_key4 : 16;
- u32 sipv6_key3 : 16;
- u32 sipv6_key6 : 16;
- u32 sipv6_key5 : 16;
- u32 dport : 16;
- u32 sipv6_key7 : 16;
- u32 dipv6_key0 : 16;
- u32 sport : 16;
- u32 dipv6_key2 : 16;
- u32 dipv6_key1 : 16;
- u32 dipv6_key4 : 16;
- u32 dipv6_key3 : 16;
- u32 dipv6_key6 : 16;
- u32 dipv6_key5 : 16;
- u32 rsvd2 : 16;
- u32 dipv6_key7 : 16;
-};
-
-struct hinic3_tcam_key_vxlan_ipv6_mem {
- u32 rsvd1 : 4;
- u32 tunnel_type : 4;
- u32 ip_proto : 8;
- u32 rsvd0 : 16;
-
- u32 dipv6_key0 : 16;
- u32 ip_type : 1;
- u32 function_id : 15;
-
- u32 dipv6_key2 : 16;
- u32 dipv6_key1 : 16;
-
- u32 dipv6_key4 : 16;
- u32 dipv6_key3 : 16;
-
- u32 dipv6_key6 : 16;
- u32 dipv6_key5 : 16;
-
- u32 dport : 16;
- u32 dipv6_key7 : 16;
-
- u32 rsvd2 : 16;
- u32 sport : 16;
-
- u32 outer_sipv4_h : 16;
- u32 rsvd3 : 16;
-
- u32 outer_dipv4_h : 16;
- u32 outer_sipv4_l : 16;
-
- u32 vni_h : 16;
- u32 outer_dipv4_l : 16;
-
- u32 rsvd4 : 16;
- u32 vni_l : 16;
-};
-
-struct tag_tcam_key {
- union {
- struct hinic3_tcam_key_ipv4_mem key_info;
- struct hinic3_tcam_key_ipv6_mem key_info_ipv6;
- struct hinic3_tcam_key_vxlan_ipv6_mem key_info_vxlan_ipv6;
- };
-
- union {
- struct hinic3_tcam_key_ipv4_mem key_mask;
- struct hinic3_tcam_key_ipv6_mem key_mask_ipv6;
- struct hinic3_tcam_key_vxlan_ipv6_mem key_mask_vxlan_ipv6;
- };
-};
-
-enum {
- PPA_TABLE_ID_CLEAN_CMD = 0,
- PPA_TABLE_ID_ADD_CMD,
- PPA_TABLE_ID_DEL_CMD,
- FDIR_TABLE_ID_ADD_CMD,
- FDIR_TABLE_ID_DEL_CMD,
- PPA_TABEL_ID_MAX
-};
-
-struct hinic3_ppa_cfg_table_id_cmd {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 rsvd0;
- u16 cmd;
- u16 table_id;
- u16 rsvd1;
-};
-
-struct hinic3_ppa_cfg_ppa_en_cmd {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 func_id;
- u8 ppa_en;
- u8 rsvd;
-};
-
-struct hinic3_func_flow_bifur_en_cmd {
- struct hinic3_mgmt_msg_head msg_head;
- u16 func_id;
- u8 flow_bifur_en;
- u8 rsvd[5];
-};
-
-struct hinic3_port_flow_bifur_en_cmd {
- struct hinic3_mgmt_msg_head msg_head;
- u16 port_id;
- u8 flow_bifur_en;
- u8 rsvd[5];
-};
-
-struct hinic3_bond_mask_cmd {
- struct hinic3_mgmt_msg_head msg_head;
- u16 func_id;
- u8 bond_mask;
- u8 bond_en;
- u8 func_valid;
- u8 rsvd[3];
-};
-
-#define HINIC3_TX_SET_PROMISC_SKIP 0
-#define HINIC3_TX_GET_PROMISC_SKIP 1
-
-struct hinic3_tx_promisc_cfg {
- struct hinic3_mgmt_msg_head msg_head;
- u8 port_id;
- u8 promisc_skip_en; /* 0: disable tx promisc replication, 1: enable */
- u8 opcode; /* 0: set, 1: get */
- u8 rsvd1;
-};
-
-struct hinic3_ppa_cfg_mode_cmd {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 rsvd0;
- u8 ppa_mode;
- u8 qpc_func_nums;
- u16 base_qpc_func_id;
- u16 rsvd1;
-};
-
-struct hinic3_ppa_flush_en_cmd {
- struct hinic3_mgmt_msg_head msg_head;
-
- u16 rsvd0;
- u8 flush_en; /* 0 flush done, 1 in flush operation */
- u8 rsvd1;
-};
-
-struct hinic3_ppa_fdir_query_cmd {
- struct hinic3_mgmt_msg_head msg_head;
-
- u32 index;
- u32 rsvd;
- u64 pkt_nums;
- u64 pkt_bytes;
-};
-
-/* BIOS CONF */
-enum {
- NIC_NVM_DATA_SET = BIT(0), /* 1-save, 0-read */
- NIC_NVM_DATA_PXE = BIT(1),
- NIC_NVM_DATA_VLAN = BIT(2),
- NIC_NVM_DATA_VLAN_PRI = BIT(3),
- NIC_NVM_DATA_VLAN_ID = BIT(4),
- NIC_NVM_DATA_WORK_MODE = BIT(5),
- NIC_NVM_DATA_PF_SPEED_LIMIT = BIT(6),
- NIC_NVM_DATA_GE_MODE = BIT(7),
- NIC_NVM_DATA_AUTO_NEG = BIT(8),
- NIC_NVM_DATA_LINK_FEC = BIT(9),
- NIC_NVM_DATA_PF_ADAPTIVE_LINK = BIT(10),
- NIC_NVM_DATA_SRIOV_CONTROL = BIT(11),
- NIC_NVM_DATA_EXTEND_MODE = BIT(12),
- NIC_NVM_DATA_RESET = BIT(31),
-};
-
-#define BIOS_CFG_SIGNATURE 0x1923E518
-#define BIOS_OP_CFG_ALL(op_code_val) ((((op_code_val) >> 1) & (0xFFFFFFFF)) != 0)
-#define BIOS_OP_CFG_WRITE(op_code_val) ((((op_code_val) & NIC_NVM_DATA_SET)) != 0)
-#define BIOS_OP_CFG_PXE_EN(op_code_val) (((op_code_val) & NIC_NVM_DATA_PXE) != 0)
-#define BIOS_OP_CFG_VLAN_EN(op_code_val) (((op_code_val) & NIC_NVM_DATA_VLAN) != 0)
-#define BIOS_OP_CFG_VLAN_PRI(op_code_val) (((op_code_val) & NIC_NVM_DATA_VLAN_PRI) != 0)
-#define BIOS_OP_CFG_VLAN_ID(op_code_val) (((op_code_val) & NIC_NVM_DATA_VLAN_ID) != 0)
-#define BIOS_OP_CFG_WORK_MODE(op_code_val) (((op_code_val) & NIC_NVM_DATA_WORK_MODE) != 0)
-#define BIOS_OP_CFG_PF_BW(op_code_val) (((op_code_val) & NIC_NVM_DATA_PF_SPEED_LIMIT) != 0)
-#define BIOS_OP_CFG_GE_SPEED(op_code_val) (((op_code_val) & NIC_NVM_DATA_GE_MODE) != 0)
-#define BIOS_OP_CFG_AUTO_NEG(op_code_val) (((op_code_val) & NIC_NVM_DATA_AUTO_NEG) != 0)
-#define BIOS_OP_CFG_LINK_FEC(op_code_val) (((op_code_val) & NIC_NVM_DATA_LINK_FEC) != 0)
-#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) (((op_code_val) & NIC_NVM_DATA_PF_ADAPTIVE_LINK) != 0)
-#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val) (((op_code_val) & NIC_NVM_DATA_SRIOV_CONTROL) != 0)
-#define BIOS_OP_CFG_EXTEND_MODE(op_code_val) (((op_code_val) & NIC_NVM_DATA_EXTEND_MODE) != 0)
-#define BIOS_OP_CFG_RST_DEF_SET(op_code_val) (((op_code_val) & (u32)NIC_NVM_DATA_RESET) != 0)
-
-#define NIC_BIOS_CFG_MAX_PF_BW 100
-/* Note: This structure must be 4-byte aligned. */
-struct nic_bios_cfg {
- u32 signature;
- u8 pxe_en; /* PXE enable: 0 - disable 1 - enable */
- u8 extend_mode;
- u8 rsvd0[2];
- u8 pxe_vlan_en; /* PXE VLAN enable: 0 - disable 1 - enable */
- u8 pxe_vlan_pri; /* PXE VLAN priority: 0-7 */
- u16 pxe_vlan_id; /* PXE VLAN ID 1-4094 */
- u32 service_mode; /* @See CHIPIF_SERVICE_MODE_x */
- u32 pf_bw; /* PF rate, in percentage. The value ranges from 0 to 100. */
- u8 speed; /* enum of port speed */
- u8 auto_neg; /* Auto-Negotiation Switch 0 - Invalid Field 1 - On 2 - Off */
- u8 lanes; /* lane num */
- u8 fec; /* FEC mode, @See enum mag_cmd_port_fec */
- u8 auto_adapt; /* Adaptive Mode Configuration 0 - Invalid Configuration 1 - On 2 - Off */
- u8 func_valid; /* Whether func_id is valid; 0: invalid; other: valid */
- u8 func_id; /* This member is valid only when func_valid is not set to 0. */
- u8 sriov_en; /* SRIOV-EN: 0 - Invalid configuration, 1 - On, 2 - Off */
-};
-
-struct nic_cmd_bios_cfg {
- struct hinic3_mgmt_msg_head head;
- u32 op_code; /* Operation Code: Bit0[0: read 1:write, BIT1-6: cfg_mask */
- struct nic_bios_cfg bios_cfg;
-};
-
-struct nic_cmd_vhd_config {
- struct hinic3_mgmt_msg_head head;
-
- u16 func_id;
- u8 vhd_type;
- u8 virtio_small_enable; /* 0: mergeable mode, 1: small mode */
-};
-
-/* BOND */
-struct hinic3_create_bond_info {
- u32 bond_id;
- u32 master_slave_port_id;
- u32 slave_bitmap; /* bond port id bitmap */
- u32 poll_timeout; /* Bond device link check time */
- u32 up_delay; /* Temporarily reserved */
- u32 down_delay; /* Temporarily reserved */
- u32 bond_mode; /* Temporarily reserved */
- u32 active_pf; /* bond use active pf id */
- u32 active_port_max_num; /* Maximum number of active bond member interfaces */
- u32 active_port_min_num; /* Minimum number of active bond member interfaces */
- u32 xmit_hash_policy;
- u32 rsvd[2];
-};
-
-struct hinic3_cmd_create_bond {
- struct hinic3_mgmt_msg_head head;
- struct hinic3_create_bond_info create_bond_info;
-};
-
-struct hinic3_cmd_delete_bond {
- struct hinic3_mgmt_msg_head head;
- u32 bond_id;
- u32 rsvd[2];
-};
-
-struct hinic3_open_close_bond_info {
- u32 bond_id;
- u32 open_close_flag; /* Bond flag. 1: open; 0: close. */
- u32 rsvd[2];
-};
-
-struct hinic3_cmd_open_close_bond {
- struct hinic3_mgmt_msg_head head;
- struct hinic3_open_close_bond_info open_close_bond_info;
-};
-
-struct lacp_port_params {
- u16 port_number;
- u16 port_priority;
- u16 key;
- u16 system_priority;
- u8 system[ETH_ALEN];
- u8 port_state;
- u8 rsvd;
-};
-
-struct lacp_port_info {
- u32 selected;
- u32 aggregator_port_id;
-
- struct lacp_port_params actor;
- struct lacp_port_params partner;
-
- u64 tx_lacp_pkts;
- u64 rx_lacp_pkts;
- u64 rx_8023ad_drop;
- u64 tx_8023ad_drop;
- u64 unknown_pkt_drop;
- u64 rx_marker_pkts;
- u64 tx_marker_pkts;
-};
-
-struct hinic3_bond_status_info {
- struct hinic3_mgmt_msg_head head;
- u32 bond_id;
- u32 bon_mmi_status;
- u32 active_bitmap;
- u32 port_count;
-
- struct lacp_port_info port_info[4];
-
- u64 success_report_cnt[4];
- u64 fail_report_cnt[4];
-
- u64 poll_timeout;
- u64 fast_periodic_timeout;
- u64 slow_periodic_timeout;
- u64 short_timeout;
- u64 long_timeout;
- u64 aggregate_wait_timeout;
- u64 tx_period_timeout;
- u64 rx_marker_timer;
-};
-
-struct hinic3_bond_active_report_info {
- struct hinic3_mgmt_msg_head head;
- u32 bond_id;
- u32 bon_mmi_status;
- u32 active_bitmap;
-
- u8 rsvd[16];
-};
-
-/* IP checksum error packets, enable rss quadruple hash. */
-struct hinic3_ipcs_err_rss_enable_operation_s {
- struct hinic3_mgmt_msg_head head;
-
- u8 en_tag;
- u8 type; /* 1: set 0: get */
- u8 rsvd[2];
-};
-
-struct hinic3_smac_check_state {
- struct hinic3_mgmt_msg_head head;
- u8 smac_check_en; /* 1: enable 0: disable */
- u8 op_code; /* 1: set 0: get */
- u8 rsvd[2];
-};
-
-struct hinic3_clear_log_state {
- struct hinic3_mgmt_msg_head head;
- u32 type;
-};
-
-#endif /* HINIC_MGMT_INTERFACE_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
index 774193a..7bc9376 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mt.h
@@ -4,11 +4,12 @@
#ifndef HINIC3_MT_H
#define HINIC3_MT_H
-#define HINIC3_DRV_NAME "hisdk3"
+#define HINIC3_DRV_NAME "hinic3"
#define HINIC3_CHIP_NAME "hinic"
/* Interrupt at most records, interrupt will be recorded in the FFM */
#define NICTOOL_CMD_TYPE (0x18)
+#define HINIC3_CARD_NAME_MAX_LEN (128)
struct api_cmd_rd {
u32 pf_id;
@@ -110,7 +111,8 @@ enum dbgtool_cmd {
DBGTOOL_CMD_NUM
};
-#define PF_MAX_SIZE (16)
+#define HINIC_PF_MAX_SIZE (16)
+#define HINIC_VF_MAX_SIZE (4096)
#define BUSINFO_LEN (32)
enum module_name {
@@ -132,7 +134,9 @@ enum module_name {
SEND_TO_MIGRATE_DRIVER,
SEND_TO_PPA_DRIVER,
SEND_TO_CUSTOM_DRIVER = SEND_TO_SRV_DRV_BASE + 11,
- SEND_TO_DRIVER_MAX = SEND_TO_SRV_DRV_BASE + 15, /* reserved */
+ SEND_TO_VSOCK_DRIVER = SEND_TO_SRV_DRV_BASE + 14,
+ SEND_TO_BIFUR_DRIVER,
+ SEND_TO_DRIVER_MAX = SEND_TO_SRV_DRV_BASE + 16, /* reserved */
};
enum driver_cmd_type {
@@ -159,7 +163,7 @@ enum driver_cmd_type {
GET_CHIP_FAULT_STATS,
NIC_RSVD1,
NIC_RSVD2,
- NIC_RSVD3,
+ GET_OS_HOT_REPLACE_INFO,
GET_CHIP_ID,
GET_SINGLE_CARD_INFO,
GET_FIRMWARE_ACTIVE_STATUS,
@@ -170,7 +174,7 @@ enum driver_cmd_type {
GET_LOOPBACK_MODE = 32,
SET_LOOPBACK_MODE,
SET_LINK_MODE,
- SET_PF_BW_LIMIT,
+ SET_TX_PF_BW_LIMIT,
GET_PF_BW_LIMIT,
ROCE_CMD,
GET_POLL_WEIGHT,
@@ -188,6 +192,7 @@ enum driver_cmd_type {
GET_NIC_STATS_STRING,
GET_NIC_STATS_INFO,
GET_PF_ID,
+ GET_MBOX_CNT,
NIC_RSVD4,
NIC_RSVD5,
DCB_QOS_INFO,
@@ -204,16 +209,54 @@ enum driver_cmd_type {
RSS_INDIR,
PORT_ID,
+ SET_RX_PF_BW_LIMIT = 0x43,
+
GET_FUNC_CAP = 0x50,
GET_XSFP_PRESENT = 0x51,
GET_XSFP_INFO = 0x52,
DEV_NAME_TEST = 0x53,
+ GET_XSFP_INFO_COMP_CMIS = 0x54,
GET_WIN_STAT = 0x60,
WIN_CSR_READ = 0x61,
WIN_CSR_WRITE = 0x62,
WIN_API_CMD_RD = 0x63,
+ GET_FUSION_Q = 0x64,
+ ROCE_CMD_SET_LDCP_PARAM = 0x70,
+
+ ROCE_CMD_GET_QPC_FROM_CACHE = 0x80,
+ ROCE_CMD_GET_QPC_FROM_HOST = 0x81,
+ ROCE_CMD_GET_CQC_FROM_CACHE = 0x82,
+ ROCE_CMD_GET_CQC_FROM_HOST = 0x83,
+ ROCE_CMD_GET_SRQC_FROM_CACHE = 0x84,
+ ROCE_CMD_GET_SRQC_FROM_HOST = 0x85,
+ ROCE_CMD_GET_MPT_FROM_CACHE = 0x86,
+ ROCE_CMD_GET_MPT_FROM_HOST = 0x87,
+ ROCE_CMD_GET_GID_FROM_CACHE = 0x88,
+ ROCE_CMD_GET_QPC_CQC_PI_CI = 0x89,
+ ROCE_CMD_GET_QP_COUNT = 0x8a,
+ ROCE_CMD_GET_DEV_ALGO = 0x8b,
+
+ ROCE_CMD_START_CAP_PACKET = 0x90,
+ ROCE_CMD_STOP_CAP_PACKET = 0x91,
+ ROCE_CMD_QUERY_CAP_INFO = 0x92,
+ ROCE_CMD_ENABLE_QP_CAP_PACKET = 0x93,
+ ROCE_CMD_DISABLE_QP_CAP_PACKET = 0x94,
+ ROCE_CMD_QUERY_QP_CAP_INFO = 0x95,
+
+ ROCE_CMD_ENABLE_BW_CTRL = 0xa0,
+ ROCE_CMD_DISABLE_BW_CTRL = 0xa1,
+ ROCE_CMD_CHANGE_BW_CTRL_PARAM = 0xa2,
+ ROCE_CMD_QUERY_BW_CTRL_PARAM = 0xa3,
+
+ ROCE_CMD_TIMEOUT_ALARM = 0xb0,
+ ROCE_CMD_PORT_TRAFFIC = 0Xb1,
+ ROCE_CMD_BOND_HASH_TYPE_SET = 0xb2,
+
+ BIFUR_SET_ENABLE = 0xc0,
+ BIFUR_GET_ENABLE = 0xc1,
+
VM_COMPAT_TEST = 0xFF
};
@@ -229,7 +272,8 @@ enum sm_cmd_type {
SM_CTR_RD64,
SM_CTR_RD32_CLEAR,
SM_CTR_RD64_PAIR_CLEAR,
- SM_CTR_RD64_CLEAR
+ SM_CTR_RD64_CLEAR,
+ SM_CTR_RD16_CLEAR,
};
struct cqm_stats {
@@ -317,10 +361,22 @@ struct pf_info {
};
struct card_info {
- struct pf_info pf[PF_MAX_SIZE];
+ struct pf_info pf[HINIC_PF_MAX_SIZE];
u32 pf_num;
};
+struct func_mbox_cnt_info {
+ char bus_info[BUSINFO_LEN];
+ u64 send_cnt;
+ u64 ack_cnt;
+};
+
+struct card_mbox_cnt_info {
+ struct func_mbox_cnt_info func_info[HINIC_PF_MAX_SIZE +
+ HINIC_VF_MAX_SIZE];
+ u32 func_num;
+};
+
struct hinic3_nic_loop_mode {
u32 loop_mode;
u32 loop_ctrl;
@@ -661,6 +717,161 @@ struct get_card_bond_msg_s {
struct bond_all_msg_s all_msg[MAX_BONDING_CNT_PER_CARD];
};
+#define MAX_FUSION_Q_STATS_STR_LEN 16
+#define MAX_FUSION_Q_NUM 256
+struct queue_status_s {
+ pid_t tgid;
+ char status[MAX_FUSION_Q_STATS_STR_LEN];
+};
+struct fusion_q_status_s {
+ u16 queue_num;
+ struct queue_status_s queue[MAX_FUSION_Q_NUM];
+};
+
+struct fusion_q_tx_hw_page {
+ u64 phy_addr;
+ u64 *map_addr;
+};
+
+struct fusion_sq_info {
+ u16 q_id;
+ u16 pi;
+ u16 ci; /* sw_ci */
+ u16 fi; /* hw_ci */
+ u32 q_depth;
+ u16 pi_reverse;
+ u16 wqebb_size;
+ u8 priority;
+ u16 *ci_addr;
+ u64 cla_addr;
+ void *slq_handle;
+ struct fusion_q_tx_hw_page direct_wqe;
+ struct fusion_q_tx_hw_page doorbell;
+ u32 page_idx;
+ u32 glb_sq_id;
+};
+
+struct fusion_q_tx_wqe {
+ u32 data[4];
+};
+
+struct fusion_rq_info {
+ u16 q_id;
+ u16 delta;
+ u16 hw_pi;
+ u16 ci; /* sw_ci */
+ u16 sw_pi;
+ u16 wqebb_size;
+ u16 q_depth;
+ u16 buf_len;
+
+ void *slq_handle;
+ u64 ci_wqe_page_addr;
+ u64 ci_cla_tbl_addr;
+
+ u8 coalesc_timer_cfg;
+ u8 pending_limt;
+ u16 msix_idx;
+ u32 msix_vector;
+};
+
+struct fusion_q_rx_wqe {
+ u32 data[8];
+};
+
+struct fusion_q_rx_cqe {
+ union {
+ struct {
+ unsigned int checksum_err : 16;
+ unsigned int lro_num : 8;
+ unsigned int rsvd1 : 7;
+ unsigned int rx_done : 1;
+ } bs;
+ unsigned int value;
+ } dw0;
+
+ union {
+ struct {
+ unsigned int vlan : 16;
+ unsigned int length : 16;
+ } bs;
+ unsigned int value;
+ } dw1;
+
+ union {
+ struct {
+ unsigned int pkt_types : 12;
+ unsigned int rsvd : 4;
+ unsigned int udp_0 : 1;
+ unsigned int ipv6_ex_add : 1;
+ unsigned int loopback : 1;
+ unsigned int umbcast : 2;
+ unsigned int vlan_offload_en : 1;
+ unsigned int tag_num : 2;
+ unsigned int rss_type : 8;
+ } bs;
+ unsigned int value;
+ } dw2;
+
+ union {
+ struct {
+ unsigned int rss_hash_value;
+ } bs;
+ unsigned int value;
+ } dw3;
+
+ union {
+ struct {
+ unsigned int tx_ts_seq : 16;
+ unsigned int message_1588_offset : 8;
+ unsigned int message_1588_type : 4;
+ unsigned int rsvd : 1;
+ unsigned int if_rx_ts : 1;
+ unsigned int if_tx_ts : 1;
+ unsigned int if_1588 : 1;
+ } bs;
+ unsigned int value;
+ } dw4;
+
+ union {
+ struct {
+ unsigned int ts;
+ } bs;
+ unsigned int value;
+ } dw5;
+
+ union {
+ struct {
+ unsigned int lro_ts;
+ } bs;
+ unsigned int value;
+ } dw6;
+
+ union {
+ struct {
+ unsigned int rsvd0;
+ } bs;
+ unsigned int value;
+ } dw7; /* 16Bytes Align */
+};
+
+struct os_hot_repalce_func_info {
+ char card_name[HINIC3_CARD_NAME_MAX_LEN];
+ int bus_num;
+ int valid;
+ int bdf;
+ int partition;
+ int backup_pf;
+ int pf_idx;
+ int port_id;
+};
+
+#define ALL_CARD_PF_NUM 2048 /* 64 card * 32 pf */
+struct os_hot_replace_info {
+ struct os_hot_repalce_func_info func_infos[ALL_CARD_PF_NUM];
+ u32 func_cnt;
+};
+
int alloc_buff_in(void *hwdev, struct msg_module *nt_msg, u32 in_size, void **buf_in);
int alloc_buff_out(void *hwdev, struct msg_module *nt_msg, u32 out_size, void **buf_out);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
index 81e4030..7cd9e4d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
@@ -15,6 +15,9 @@
#include <linux/ip.h>
#include "ossl_knl.h"
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+#include <net/udp_tunnel.h>
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
#ifdef HAVE_XDP_SUPPORT
#include <linux/bpf.h>
#endif
@@ -28,6 +31,10 @@
#include "hinic3_dcb.h"
#include "hinic3_nic_prof.h"
+#include "nic_npu_cmd.h"
+
+#include "vram_common.h"
+
#define HINIC3_DEFAULT_RX_CSUM_OFFLOAD 0xFFF
#define HINIC3_LRO_DEFAULT_COAL_PKT_SIZE 32
@@ -47,8 +54,64 @@ static void hinic3_nic_set_rx_mode(struct net_device *netdev)
queue_work(nic_dev->workq, &nic_dev->rx_mode_work);
}
+static void hinic3_free_irq_vram(struct hinic3_nic_dev *nic_dev, struct hinic3_dyna_txrxq_params *in_q_params)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ struct hinic3_dyna_txrxq_params q_params = nic_dev->q_params;
+
+ if (q_params.irq_cfg == NULL)
+ return;
+
+ size = sizeof(struct hinic3_irq) * (q_params.num_qps);
+
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)q_params.irq_cfg, q_params.irq_cfg_vram_name, size);
+ q_params.irq_cfg = NULL;
+ } else {
+ kfree(in_q_params->irq_cfg);
+ in_q_params->irq_cfg = NULL;
+ }
+}
+
+static int hinic3_alloc_irq_vram(struct hinic3_nic_dev *nic_dev,
+ struct hinic3_dyna_txrxq_params *q_params, bool is_up_eth)
+{
+ u32 size;
+ int is_use_vram = get_use_vram_flag();
+ u16 func_id;
+
+ size = sizeof(struct hinic3_irq) * q_params->num_qps;
+
+ if (is_use_vram != 0) {
+ func_id = hinic3_global_func_id(nic_dev->hwdev);
+ snprintf(q_params->irq_cfg_vram_name,
+ VRAM_NAME_MAX_LEN, "%s%u",
+ VRAM_NIC_IRQ_VRAM, func_id);
+ q_params->irq_cfg = (struct hinic3_irq *)hi_vram_kalloc(
+ q_params->irq_cfg_vram_name, size);
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq vram alloc failed.\n");
+ return -ENOMEM;
+ }
+ /* in order to clear napi stored in vram, irq need to init when eth up */
+ if (is_up_eth) {
+ memset(q_params->irq_cfg, 0, size);
+ }
+ } else {
+ q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
+ if (q_params->irq_cfg == NULL) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "NIC irq alloc failed.\n");
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
- struct hinic3_dyna_txrxq_params *q_params)
+ struct hinic3_dyna_txrxq_params *q_params,
+ bool is_up_eth)
{
u32 size;
int err;
@@ -70,12 +133,9 @@ static int hinic3_alloc_txrxq_resources(struct hinic3_nic_dev *nic_dev,
goto alloc_rxqs_res_arr_err;
}
- size = sizeof(*q_params->irq_cfg) * q_params->num_qps;
- q_params->irq_cfg = kzalloc(size, GFP_KERNEL);
- if (!q_params->irq_cfg) {
- nicif_err(nic_dev, drv, nic_dev->netdev,
- "Failed to alloc irq resource array\n");
- err = -ENOMEM;
+ err = hinic3_alloc_irq_vram(nic_dev, q_params, is_up_eth);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc irq resource array\n");
goto alloc_irq_cfg_err;
}
@@ -102,8 +162,7 @@ alloc_rxqs_res_err:
q_params->txqs_res);
alloc_txqs_res_err:
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ hinic3_free_irq_vram(nic_dev, q_params);
alloc_irq_cfg_err:
kfree(q_params->rxqs_res);
@@ -119,13 +178,14 @@ alloc_rxqs_res_arr_err:
static void hinic3_free_txrxq_resources(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_txrxq_params *q_params)
{
+ int is_in_kexec = vram_get_kexec_flag();
hinic3_free_rxqs_res(nic_dev, q_params->num_qps, q_params->rq_depth,
q_params->rxqs_res);
hinic3_free_txqs_res(nic_dev, q_params->num_qps, q_params->sq_depth,
q_params->txqs_res);
- kfree(q_params->irq_cfg);
- q_params->irq_cfg = NULL;
+ if (is_in_kexec == 0)
+ hinic3_free_irq_vram(nic_dev, q_params);
kfree(q_params->rxqs_res);
q_params->rxqs_res = NULL;
@@ -161,6 +221,7 @@ static int hinic3_configure_txrxqs(struct hinic3_nic_dev *nic_dev,
static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos;
if (!test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
@@ -171,12 +232,13 @@ static void config_dcb_qps_map(struct hinic3_nic_dev *nic_dev)
num_cos = hinic3_get_dev_user_cos_num(nic_dev);
hinic3_update_qp_cos_cfg(nic_dev, num_cos);
/* For now, we don't support to change num_cos */
- if (num_cos > nic_dev->cos_config_num_max ||
+ if (num_cos > dcb->cos_config_num_max ||
nic_dev->q_params.num_qps < num_cos) {
nicif_err(nic_dev, drv, netdev, "Invalid num_cos: %u or num_qps: %u, disable DCB\n",
num_cos, nic_dev->q_params.num_qps);
nic_dev->q_params.num_cos = 0;
clear_bit(HINIC3_DCB_ENABLE, &nic_dev->flags);
+ clear_bit(HINIC3_DCB_ENABLE, &nic_dev->nic_vram->flags);
/* if we can't enable rss or get enough num_qps,
* need to sync default configure to hw
*/
@@ -190,11 +252,14 @@ static int hinic3_configure(struct hinic3_nic_dev *nic_dev)
{
struct net_device *netdev = nic_dev->netdev;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
- err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
- if (err) {
- nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
- return err;
+ if (is_in_kexec == 0) {
+ err = hinic3_set_port_mtu(nic_dev->hwdev, (u16)netdev->mtu);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, netdev, "Failed to set mtu\n");
+ return err;
+ }
}
config_dcb_qps_map(nic_dev);
@@ -256,10 +321,11 @@ static void config_dcb_num_qps(struct hinic3_nic_dev *nic_dev,
const struct hinic3_dyna_txrxq_params *q_params,
u16 max_qps)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u8 num_cos = q_params->num_cos;
u8 user_cos_num = hinic3_get_dev_user_cos_num(nic_dev);
- if (!num_cos || num_cos > nic_dev->cos_config_num_max || num_cos > max_qps)
+ if (!num_cos || num_cos > dcb->cos_config_num_max || num_cos > max_qps)
return; /* will disable DCB in config_dcb_qps_map() */
hinic3_update_qp_cos_cfg(nic_dev, user_cos_num);
@@ -334,57 +400,10 @@ static void hinic3_destroy_num_qps(struct hinic3_nic_dev *nic_dev)
kfree(nic_dev->qps_irq_info);
}
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev)
-{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- err = hinic3_set_port_enable(nic_dev->hwdev, false, HINIC3_CHANNEL_NIC);
- if (!err)
- nic_dev->force_port_disable = true;
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
-{
- int err = 0;
-
- down(&nic_dev->port_state_sem);
-
- nic_dev->force_port_disable = false;
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
- HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
-}
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable)
{
- int err;
-
- down(&nic_dev->port_state_sem);
-
- /* Do nothing when force disable
- * Port will disable when call force port disable
- * and should not enable port when in force mode
- */
- if (nic_dev->force_port_disable) {
- up(&nic_dev->port_state_sem);
- return 0;
- }
-
- err = hinic3_set_port_enable(nic_dev->hwdev, enable,
+ return hinic3_set_port_enable(nic_dev->hwdev, enable,
HINIC3_CHANNEL_NIC);
-
- up(&nic_dev->port_state_sem);
-
- return err;
}
static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
@@ -401,7 +420,8 @@ static void hinic3_print_link_message(struct hinic3_nic_dev *nic_dev,
static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+ struct hinic3_dyna_txrxq_params *trxq_params,
+ bool is_up_eth)
{
int err;
@@ -416,7 +436,7 @@ static int hinic3_alloc_channel_resources(struct hinic3_nic_dev *nic_dev,
return err;
}
- err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params);
+ err = hinic3_alloc_txrxq_resources(nic_dev, trxq_params, is_up_eth);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to alloc txrxq resources\n");
hinic3_free_qps(nic_dev->hwdev, qp_params);
@@ -544,9 +564,53 @@ vport_enable_err:
return err;
}
+static int hinic3_flush_rq_and_check(struct hinic3_nic_dev *nic_dev,
+ u16 glb_func_id)
+{
+ struct hinic3_flush_rq *rq_flush_msg = NULL;
+ struct hinic3_cmd_buf *cmd_buf = NULL;
+ int out_buf_len = sizeof(struct hinic3_flush_rq);
+ u16 rq_id;
+ u64 out_param = 0;
+ int ret;
+
+ cmd_buf = hinic3_alloc_cmd_buf(nic_dev->hwdev);
+ if (!cmd_buf) {
+ nic_err(&nic_dev->pdev->dev, "Failed to allocate cmd buf\n");
+ return -ENOMEM;
+ }
+
+ cmd_buf->size = sizeof(struct hinic3_flush_rq);
+ rq_flush_msg = (struct hinic3_flush_rq *)cmd_buf->buf;
+ rq_flush_msg->dw.bs.func_id = glb_func_id;
+ for (rq_id = 0; rq_id < nic_dev->q_params.num_qps; rq_id++) {
+ rq_flush_msg->dw.bs.rq_id = rq_id;
+ hinic3_cpu_to_be32(rq_flush_msg, out_buf_len);
+ ret = hinic3_cmdq_direct_resp(nic_dev->hwdev, HINIC3_MOD_L2NIC,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ cmd_buf, &out_param, 0,
+ HINIC3_CHANNEL_NIC);
+ if (ret != 0 || out_param != 0) {
+ nic_err(&nic_dev->pdev->dev, "Failed to flush rq, ret:%d, func:%u, rq:%u\n",
+ ret, glb_func_id, rq_id);
+ goto err;
+ }
+ hinic3_be32_to_cpu(rq_flush_msg, out_buf_len);
+ }
+
+ nic_info(&nic_dev->pdev->dev, "Func:%u rq_num:%u flush rq success\n",
+ glb_func_id, nic_dev->q_params.num_qps);
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return 0;
+err:
+ hinic3_free_cmd_buf(nic_dev->hwdev, cmd_buf);
+ return -1;
+}
+
void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
{
u16 glb_func_id;
+ int is_in_kexec = vram_get_kexec_flag();
netif_carrier_off(nic_dev->netdev);
netif_tx_disable(nic_dev->netdev);
@@ -559,18 +623,21 @@ void hinic3_vport_down(struct hinic3_nic_dev *nic_dev)
if (!HINIC3_FUNC_IS_VF(nic_dev->hwdev))
hinic3_notify_all_vfs_link_changed(nic_dev->hwdev, 0);
- hinic3_maybe_set_port_state(nic_dev, false);
+ if (is_in_kexec != 0)
+ nicif_info(nic_dev, drv, nic_dev->netdev, "Skip changing mag status!\n");
+ else
+ hinic3_maybe_set_port_state(nic_dev, false);
glb_func_id = hinic3_global_func_id(nic_dev->hwdev);
hinic3_set_vport_enable(nic_dev->hwdev, glb_func_id, false,
HINIC3_CHANNEL_NIC);
hinic3_flush_txqs(nic_dev->netdev);
- /* After set vport disable 100ms,
- * no packets will be send to host
- * FPGA set 2000ms
- */
- msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+ if (is_in_kexec == 0) {
+ msleep(HINIC3_WAIT_FLUSH_QP_RESOURCE_TIMEOUT);
+ } else {
+ (void)hinic3_flush_rq_and_check(nic_dev, glb_func_id);
+ }
hinic3_flush_qps_res(nic_dev->hwdev);
}
}
@@ -583,11 +650,12 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
struct hinic3_dyna_qp_params new_qp_params = {0};
struct hinic3_dyna_qp_params cur_qp_params = {0};
int err;
+ bool is_free_resources = false;
hinic3_config_num_qps(nic_dev, trxq_params);
err = hinic3_alloc_channel_resources(nic_dev, &new_qp_params,
- trxq_params);
+ trxq_params, false);
if (err) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc channel resources\n");
@@ -599,10 +667,19 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
hinic3_close_channel(nic_dev, &cur_qp_params);
hinic3_free_channel_resources(nic_dev, &cur_qp_params,
&nic_dev->q_params);
+ is_free_resources = true;
}
if (nic_dev->num_qp_irq > trxq_params->num_qps)
hinic3_qp_irq_change(nic_dev, trxq_params->num_qps);
+
+ if (is_free_resources) {
+ err = hinic3_alloc_irq_vram(nic_dev, trxq_params, false);
+ if (err != 0) {
+ nicif_err(nic_dev, drv, nic_dev->netdev, "Change chl alloc irq failed\n");
+ goto alloc_irq_err;
+ }
+ }
nic_dev->q_params = *trxq_params;
if (reopen_handler)
@@ -623,7 +700,7 @@ int hinic3_change_channel_settings(struct hinic3_nic_dev *nic_dev,
vport_up_err:
hinic3_close_channel(nic_dev, &new_qp_params);
-
+alloc_irq_err:
open_channel_err:
hinic3_free_channel_resources(nic_dev, &new_qp_params, trxq_params);
@@ -654,7 +731,7 @@ int hinic3_open(struct net_device *netdev)
}
err = hinic3_alloc_channel_resources(nic_dev, &qp_params,
- &nic_dev->q_params);
+ &nic_dev->q_params, true);
if (err)
goto alloc_channel_res_err;
@@ -693,12 +770,31 @@ setup_qps_err:
return err;
}
+static void hinic3_delete_napi(struct hinic3_nic_dev *nic_dev)
+{
+ u16 q_id;
+ int is_in_kexec = vram_get_kexec_flag();
+ struct hinic3_irq *irq_cfg = NULL;
+
+ if (is_in_kexec == 0 || nic_dev->q_params.irq_cfg == NULL)
+ return;
+
+ for (q_id = 0; q_id < nic_dev->q_params.num_qps; q_id++) {
+ irq_cfg = &(nic_dev->q_params.irq_cfg[q_id]);
+ qp_del_napi(irq_cfg);
+ }
+
+ hinic3_free_irq_vram(nic_dev, &nic_dev->q_params);
+}
+
int hinic3_close(struct net_device *netdev)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
struct hinic3_dyna_qp_params qp_params = {0};
if (!test_and_clear_bit(HINIC3_INTF_UP, &nic_dev->flags)) {
+ /* delete napi in os hotreplace rollback */
+ hinic3_delete_napi(nic_dev);
nicif_info(nic_dev, drv, netdev, "Netdev already close, do nothing\n");
return 0;
}
@@ -835,6 +931,7 @@ static u16 select_queue_by_hash_func(struct net_device *dev, struct sk_buff *skb
#define GET_DSCP_PRI_OFFSET 2
static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev, struct sk_buff *skb)
{
+ struct hinic3_dcb *dcb = nic_dev->dcb;
int dscp_cp;
if (skb->protocol == htons(ETH_P_IP))
@@ -842,8 +939,8 @@ static u8 hinic3_get_dscp_up(struct hinic3_nic_dev *nic_dev, struct sk_buff *skb
else if (skb->protocol == htons(ETH_P_IPV6))
dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >> GET_DSCP_PRI_OFFSET;
else
- return nic_dev->hw_dcb_cfg.default_cos;
- return nic_dev->hw_dcb_cfg.dscp2cos[dscp_cp];
+ return dcb->hw_dcb_cfg.default_cos;
+ return dcb->hw_dcb_cfg.dscp2cos[dscp_cp];
}
#if defined(HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY)
@@ -869,6 +966,7 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif /* end of HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK */
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ struct hinic3_dcb *dcb = nic_dev->dcb;
u16 txq;
u8 cos, qp_num;
@@ -889,18 +987,19 @@ static u16 hinic3_select_queue(struct net_device *netdev, struct sk_buff *skb)
#endif
if (test_bit(HINIC3_DCB_ENABLE, &nic_dev->flags)) {
- if (nic_dev->hw_dcb_cfg.trust == DCB_PCP) {
+ if (dcb->hw_dcb_cfg.trust == HINIC3_DCB_PCP) {
if (skb->vlan_tci)
- cos = nic_dev->hw_dcb_cfg.pcp2cos[skb->vlan_tci >> VLAN_PRIO_SHIFT];
+ cos = dcb->hw_dcb_cfg.pcp2cos[skb->vlan_tci >>
+ VLAN_PRIO_SHIFT];
else
- cos = nic_dev->hw_dcb_cfg.default_cos;
+ cos = dcb->hw_dcb_cfg.default_cos;
} else {
cos = hinic3_get_dscp_up(nic_dev, skb);
}
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cos] ?
- txq % nic_dev->hw_dcb_cfg.cos_qp_num[cos] : 0;
- txq = nic_dev->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
+ qp_num = dcb->hw_dcb_cfg.cos_qp_num[cos] ?
+ txq % dcb->hw_dcb_cfg.cos_qp_num[cos] : 0;
+ txq = dcb->hw_dcb_cfg.cos_qp_offset[cos] + qp_num;
}
return txq;
@@ -978,7 +1077,7 @@ static struct net_device_stats *hinic3_get_stats(struct net_device *netdev)
stats->rx_packets = packets;
stats->rx_bytes = bytes;
stats->rx_errors = errors;
- stats->rx_dropped = dropped;
+ stats->rx_dropped = dropped + nic_dev->vport_stats.rx_discard_vport;
#ifndef HAVE_VOID_NDO_GET_STATS64
return stats;
@@ -1025,10 +1124,17 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
u32 mtu = (u32)new_mtu;
int err = 0;
-
+ int is_in_kexec = vram_get_kexec_flag();
#ifdef HAVE_XDP_SUPPORT
u32 xdp_max_mtu;
+#endif
+ if (is_in_kexec != 0) {
+ nicif_info(nic_dev, drv, netdev, "Hotreplace skip change mtu\n");
+ return err;
+ }
+
+#ifdef HAVE_XDP_SUPPORT
if (hinic3_is_xdp_enable(nic_dev)) {
xdp_max_mtu = hinic3_xdp_max_mtu(nic_dev);
if (mtu > xdp_max_mtu) {
@@ -1047,6 +1153,7 @@ static int hinic3_change_mtu(struct net_device *netdev, int new_mtu)
nicif_info(nic_dev, drv, nic_dev->netdev, "Change mtu from %u to %d\n",
netdev->mtu, new_mtu);
netdev->mtu = mtu;
+ nic_dev->nic_vram->vram_mtu = mtu;
}
return err;
@@ -1080,6 +1187,71 @@ static int hinic3_set_mac_addr(struct net_device *netdev, void *addr)
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+static int hinic3_udp_tunnel_port_config(struct net_device *netdev,
+ struct udp_tunnel_info *ti,
+ u8 action)
+{
+ struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
+ u16 func_id = hinic3_global_func_id(nic_dev->hwdev);
+ u16 dst_port;
+ int ret = 0;
+
+ switch (ti->type) {
+ case UDP_TUNNEL_TYPE_VXLAN:
+ dst_port = ntohs(ti->port);
+ ret = hinic3_vlxan_port_config(nic_dev->hwdev, func_id,
+ dst_port, action);
+ if (ret != 0) {
+ nicif_warn(nic_dev, drv, netdev,
+ "Failed to set vxlan port %u to device(%d)\n",
+ dst_port, ret);
+ break;
+ }
+ nicif_info(nic_dev, link, netdev, "Vxlan dst port set to %u\n",
+ action == HINIC3_CMD_OP_ADD ?
+ dst_port : ntohs(VXLAN_OFFLOAD_PORT_LE));
+ break;
+ default:
+ nicif_err(nic_dev, drv, netdev,
+ "Failed to add port, only vxlan dst port is supported\n");
+ ret = -EINVAL;
+ }
+ return ret;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+static void hinic3_udp_tunnel_add(struct net_device *netdev, struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+static void hinic3_udp_tunnel_del(struct net_device *netdev, struct udp_tunnel_info *ti)
+{
+ if (ti->sa_family != AF_INET && ti->sa_family != AF_INET6)
+ return;
+
+ hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD */
+
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev, __attribute__((unused)) unsigned int table,
+ __attribute__((unused))unsigned int entry, struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_ADD);
+}
+
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev, __attribute__((unused)) unsigned int table,
+ __attribute__((unused)) unsigned int entry, struct udp_tunnel_info *ti)
+{
+ return hinic3_udp_tunnel_port_config(netdev, ti, HINIC3_CMD_OP_DEL);
+}
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
static int
hinic3_vlan_rx_add_vid(struct net_device *netdev,
__always_unused __be16 proto,
@@ -1126,7 +1298,7 @@ hinic3_vlan_rx_kill_vid(struct net_device *netdev,
int err = 0;
col = VID_COL(nic_dev, vid);
- line = VID_LINE(nic_dev, vid);
+ line = (int)VID_LINE(nic_dev, vid);
/* In the broadcast scenario, ucode finds the corresponding function
* based on VLAN 0 of vlan table. If we delete VLAN 0, the VLAN function
@@ -1165,14 +1337,12 @@ static int hinic3_vlan_restore(struct net_device *netdev)
return -EFAULT;
rcu_read_lock();
for (i = 0; i < VLAN_N_VID; i++) {
-/* lint -e778 */
#ifdef HAVE_VLAN_FIND_DEV_DEEP_RCU
vlandev =
__vlan_find_dev_deep_rcu(netdev, htons(ETH_P_8021Q), i);
#else
vlandev = __vlan_find_dev_deep(netdev, htons(ETH_P_8021Q), i);
#endif
-/* lint +e778 */
col = VID_COL(nic_dev, i);
line = VID_LINE(nic_dev, i);
if (!vlandev && (vlan_bitmap[line] & (1UL << col)) != 0) {
@@ -1330,12 +1500,17 @@ static int set_feature_vlan_filter(struct hinic3_nic_dev *nic_dev,
return 0;
#ifdef NEED_VLAN_RESTORE
- if (en)
+ if (en) {
err = hinic3_vlan_restore(nic_dev->netdev);
+ if (err) {
+ hinic3_err(nic_dev, drv, "vlan restore failed\n");
+ *failed_features |= vlan_filter_feature;
+ return err;
+ }
+ }
#endif
- if (err == 0)
- err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
+ err = hinic3_set_vlan_fliter(nic_dev->hwdev, en);
if (err) {
hinic3_err(nic_dev, drv, "%s rx vlan filter failed\n",
SET_FEATURES_OP_STR(en));
@@ -1429,8 +1604,8 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
struct hinic3_nic_dev *adapter = netdev_priv(netdev);
int err;
- if (is_multicast_ether_addr(mac) || /*lint !e574*/
- vf >= pci_num_vf(adapter->pdev)) /*lint !e574*/
+ if (is_multicast_ether_addr(mac) ||
+ vf >= pci_num_vf(adapter->pdev))
return -EINVAL;
err = hinic3_set_vf_mac(adapter->hwdev, OS_VF_ID_TO_HW(vf), mac);
@@ -1448,7 +1623,6 @@ static int hinic3_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
return 0;
}
-/*lint -save -e574 -e734*/
#ifdef IFLA_VF_MAX
static int set_hw_vf_vlan(void *hwdev, u16 cur_vlanprio, int vf,
u16 vlan, u8 qos)
@@ -1670,7 +1844,7 @@ static int hinic3_ndo_set_vf_bw(struct net_device *netdev, int vf,
return -EIO;
/* rate limit cannot be less than 0 and greater than link speed */
- if (max_tx_rate < 0 || max_tx_rate > speeds[port_info.speed]) {
+ if (max_tx_rate < 0 || max_tx_rate > (int)(speeds[port_info.speed])) {
nicif_err(adapter, drv, netdev, "Set vf max tx rate must be in [0 - %u]\n",
speeds[port_info.speed]);
return -EINVAL;
@@ -1719,7 +1893,7 @@ static int hinic3_xdp_setup(struct hinic3_nic_dev *nic_dev,
int max_mtu = hinic3_xdp_max_mtu(nic_dev);
int q_id;
- if (nic_dev->netdev->mtu > max_mtu) {
+ if (nic_dev->netdev->mtu > (u32)max_mtu) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to setup xdp program, the current MTU %d is larger than max allowed MTU %d\n",
nic_dev->netdev->mtu, max_mtu);
@@ -1844,6 +2018,10 @@ static const struct net_device_ops hinic3_netdev_ops = {
.ndo_xdp = hinic3_xdp,
#endif
#endif
+#ifdef HAVE_NDO_UDP_TUNNEL_ADD
+ .ndo_udp_tunnel_add = hinic3_udp_tunnel_add,
+ .ndo_udp_tunnel_del = hinic3_udp_tunnel_del,
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD */
#ifdef HAVE_RHEL6_NET_DEVICE_OPS_EXT
};
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
index cc00bdc..1bc6a14 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic.h
@@ -10,6 +10,8 @@
#include "hinic3_common.h"
#include "hinic3_nic_io.h"
#include "hinic3_nic_cfg.h"
+#include "mag_mpu_cmd.h"
+#include "mag_mpu_cmd_defs.h"
/* ************************ array index define ********************* */
#define ARRAY_INDEX_0 0
@@ -21,6 +23,35 @@
#define ARRAY_INDEX_6 6
#define ARRAY_INDEX_7 7
+#define XSFP_TLV_PRE_INFO_LEN 4
+
+enum hinic3_link_port_type {
+ LINK_PORT_UNKNOWN,
+ LINK_PORT_OPTICAL_MM,
+ LINK_PORT_OPTICAL_SM,
+ LINK_PORT_PAS_COPPER,
+ LINK_PORT_ACC,
+ LINK_PORT_BASET,
+ LINK_PORT_AOC = 0x40,
+ LINK_PORT_ELECTRIC,
+ LINK_PORT_BACKBOARD_INTERFACE,
+};
+
+enum hilink_fibre_subtype {
+ FIBRE_SUBTYPE_SR = 1,
+ FIBRE_SUBTYPE_LR,
+ FIBRE_SUBTYPE_MAX,
+};
+
+enum hilink_fec_type {
+ HILINK_FEC_NOT_SET,
+ HILINK_FEC_RSFEC,
+ HILINK_FEC_BASEFEC,
+ HILINK_FEC_NOFEC,
+ HILINK_FEC_LLRSFE,
+ HILINK_FEC_MAX_TYPE,
+};
+
struct hinic3_sq_attr {
u8 dma_attr_off;
u8 pending_limit;
@@ -58,24 +89,32 @@ struct hinic3_port_routine_cmd {
struct mag_cmd_get_xsfp_present abs;
};
+struct hinic3_port_routine_cmd_extern {
+ bool mpu_send_xsfp_tlv_info;
+
+ struct drv_mag_cmd_get_xsfp_tlv_rsp std_xsfp_tlv_info;
+};
+
struct hinic3_nic_cfg {
- struct semaphore cfg_lock;
+ struct semaphore cfg_lock;
/* Valid when pfc is disable */
- bool pause_set;
- struct nic_pause_config nic_pause;
+ bool pause_set;
+ struct nic_pause_config nic_pause;
- u8 pfc_en;
- u8 pfc_bitmap;
+ u8 pfc_en;
+ u8 pfc_bitmap;
- struct nic_port_info port_info;
+ struct nic_port_info port_info;
/* percentage of pf link bandwidth */
- u32 pf_bw_limit;
- u32 rsvd2;
+ u32 pf_bw_tx_limit;
+ u32 pf_bw_rx_limit;
- struct hinic3_port_routine_cmd rt_cmd;
- struct mutex sfp_mutex; /* mutex used for copy sfp info */
+ struct hinic3_port_routine_cmd rt_cmd;
+ struct hinic3_port_routine_cmd_extern rt_cmd_ext;
+ /* mutex used for copy sfp info */
+ struct mutex sfp_mutex;
};
struct hinic3_nic_io {
@@ -84,7 +123,7 @@ struct hinic3_nic_io {
void *dev_hdl;
u8 link_status;
- u8 rsvd1;
+ u8 direct;
u32 rsvd2;
struct hinic3_io_queue *sq;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
index 2c1b565..525a353 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c
@@ -20,10 +20,126 @@
#include "hinic3_nic_io.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_common.h"
#include "hinic3_nic_cfg.h"
+#include "vram_common.h"
+
+int hinic3_delete_bond(void *hwdev)
+{
+ struct hinic3_cmd_delete_bond cmd_delete_bond;
+ u16 out_size = sizeof(cmd_delete_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_delete_bond, 0, sizeof(cmd_delete_bond));
+ cmd_delete_bond.bond_id = HINIC3_INVALID_BOND_ID;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_DELETE,
+ &cmd_delete_bond, sizeof(cmd_delete_bond),
+ &cmd_delete_bond, &out_size);
+ if (err || !out_size || cmd_delete_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to delete bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_delete_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_delete_bond.bond_id != HINIC3_INVALID_BOND_ID) {
+ nic_info(nic_io->dev_hdl, "Delete bond success\n");
+ }
+
+ return 0;
+}
+
+int hinic3_open_close_bond(void *hwdev, u32 bond_en)
+{
+ struct hinic3_cmd_open_close_bond cmd_open_close_bond;
+ u16 out_size = sizeof(cmd_open_close_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_open_close_bond, 0, sizeof(cmd_open_close_bond));
+ cmd_open_close_bond.open_close_bond_info.bond_id = HINIC3_INVALID_BOND_ID;
+ cmd_open_close_bond.open_close_bond_info.open_close_flag = bond_en;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_OPEN_CLOSE,
+ &cmd_open_close_bond, sizeof(cmd_open_close_bond),
+ &cmd_open_close_bond, &out_size);
+ if (err || !out_size || cmd_open_close_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to %s bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ bond_en == true ? "open" : "close", err, cmd_open_close_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_open_close_bond.open_close_bond_info.bond_id != HINIC3_INVALID_BOND_ID) {
+ nic_info(nic_io->dev_hdl, "%s bond success\n", bond_en == true ? "Open" : "Close");
+ }
+
+ return 0;
+}
+
+int hinic3_create_bond(void *hwdev, u32 *bond_id)
+{
+ struct hinic3_cmd_create_bond cmd_create_bond;
+ u16 out_size = sizeof(cmd_create_bond);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err = 0;
+
+ if (!hwdev) {
+ pr_err("hwdev is null.\n");
+ return -EINVAL;
+ }
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is null.\n");
+ return -EINVAL;
+ }
+
+ memset(&cmd_create_bond, 0, sizeof(cmd_create_bond));
+ cmd_create_bond.create_bond_info.default_param_flag = true;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BOND_DEV_CREATE,
+ &cmd_create_bond, sizeof(cmd_create_bond),
+ &cmd_create_bond, &out_size);
+ if (err || !out_size || cmd_create_bond.head.status) {
+ nic_err(nic_io->dev_hdl, "Failed to create default bond, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, cmd_create_bond.head.status, out_size);
+ return -EFAULT;
+ }
+
+ if (cmd_create_bond.create_bond_info.bond_id != HINIC3_INVALID_BOND_ID) {
+ *bond_id = cmd_create_bond.create_bond_info.bond_id;
+ nic_info(nic_io->dev_hdl, "Create bond success\n");
+ }
+
+ return 0;
+}
+
int hinic3_set_ci_table(void *hwdev, struct hinic3_sq_attr *attr)
{
struct hinic3_cmd_cons_idx_attr cons_idx_attr;
@@ -37,6 +153,8 @@ int hinic3_set_ci_table(void *hwdev, struct hinic3_sq_attr *attr)
memset(&cons_idx_attr, 0, sizeof(cons_idx_attr));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cons_idx_attr.func_idx = hinic3_global_func_id(hwdev);
@@ -152,6 +270,8 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -183,7 +303,7 @@ int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id,
}
EXPORT_SYMBOL(hinic3_del_mac);
-int hinic3_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
+int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
u16 func_id)
{
struct hinic3_port_mac_update mac_info;
@@ -197,6 +317,8 @@ int hinic3_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if ((vlan_id & HINIC_VLAN_ID_MASK) >= VLAN_N_VID) {
nic_err(nic_io->dev_hdl, "Invalid VLAN number: %d\n",
@@ -247,6 +369,8 @@ int hinic3_get_default_mac(void *hwdev, u8 *mac_addr)
memset(&mac_info, 0, sizeof(mac_info));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
mac_info.func_id = hinic3_global_func_id(hwdev);
@@ -292,6 +416,45 @@ static int hinic3_config_vlan(struct hinic3_nic_io *nic_io, u8 opcode,
return 0;
}
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action)
+{
+ struct hinic3_cmd_vxlan_port_info vxlan_port_info;
+ u16 out_size = sizeof(vxlan_port_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ memset(&vxlan_port_info, 0, sizeof(vxlan_port_info));
+ vxlan_port_info.opcode = action;
+ vxlan_port_info.cfg_mode = 0; // other ethtool set
+ vxlan_port_info.func_id = func_id;
+ vxlan_port_info.vxlan_port = port;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+ &vxlan_port_info, sizeof(vxlan_port_info),
+ &vxlan_port_info, &out_size);
+ if (err || !out_size || vxlan_port_info.msg_head.status) {
+ if (vxlan_port_info.msg_head.status == 0x2) {
+ nic_warn(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port because it has already been set by hinicadm\n",
+ action == HINIC3_CMD_OP_ADD ? "add" : "delete");
+ } else {
+ nic_err(nic_io->dev_hdl,
+ "Failed to %s vxlan dst port, err: %d, status: 0x%x, out size: 0x%x\n",
+ action == HINIC3_CMD_OP_ADD ? "add" : "delete",
+ err, vxlan_port_info.msg_head.status, out_size);
+ }
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
{
struct hinic3_nic_io *nic_io = NULL;
@@ -300,6 +463,9 @@ int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan_id, func_id);
}
@@ -311,6 +477,9 @@ int hinic3_del_vlan(void *hwdev, u16 vlan_id, u16 func_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_config_vlan(nic_io, HINIC3_CMD_OP_DEL, vlan_id, func_id);
}
@@ -354,6 +523,9 @@ int hinic3_set_dcb_state(void *hwdev, struct hinic3_dcb_state *dcb_state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (!memcmp(&nic_io->dcb_state, dcb_state, sizeof(nic_io->dcb_state)))
return 0;
@@ -515,6 +687,8 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_cfg = &nic_io->nic_cfg;
@@ -540,7 +714,6 @@ int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
{
- struct hinic3_nic_cfg *nic_cfg = NULL;
struct hinic3_nic_io *nic_io = NULL;
int err = 0;
@@ -548,17 +721,13 @@ int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- nic_cfg = &nic_io->nic_cfg;
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_hw_pause(nic_io, HINIC3_CMD_OP_GET, nic_pause);
if (err)
return err;
- if (nic_cfg->pause_set || !nic_pause->auto_neg) {
- nic_pause->rx_pause = nic_cfg->nic_pause.rx_pause;
- nic_pause->tx_pause = nic_cfg->nic_pause.tx_pause;
- }
-
return 0;
}
@@ -573,6 +742,8 @@ int hinic3_sync_dcb_state(void *hwdev, u8 op_code, u8 state)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&dcb_state, 0, sizeof(dcb_state));
@@ -659,44 +830,6 @@ int hinic3_cache_out_qps_res(void *hwdev)
return 0;
}
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats)
-{
- struct hinic3_port_stats *port_stats = NULL;
- struct hinic3_port_stats_info stats_info;
- u16 out_size = sizeof(*port_stats);
- struct hinic3_nic_io *nic_io = NULL;
- int err;
-
- port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
- if (!port_stats)
- return -ENOMEM;
-
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (!nic_io)
- return -EINVAL;
-
- memset(&stats_info, 0, sizeof(stats_info));
-
- err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_PORT_STAT,
- &stats_info, sizeof(stats_info),
- port_stats, &out_size);
- if (err || !out_size || port_stats->msg_head.status) {
- nic_err(nic_io->dev_hdl,
- "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x\n",
- err, port_stats->msg_head.status, out_size);
- err = -EIO;
- goto out;
- }
-
- memcpy(stats, &port_stats->stats, sizeof(*stats));
-
-out:
- kfree(port_stats);
-
- return err;
-}
-EXPORT_SYMBOL(hinic3_get_fpga_phy_port_stats);
-
int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *stats)
{
struct hinic3_port_stats_info stats_info;
@@ -712,6 +845,8 @@ int hinic3_get_vport_stats(void *hwdev, u16 func_id, struct hinic3_vport_stats *
memset(&vport_stats, 0, sizeof(vport_stats));
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
stats_info.func_id = func_id;
@@ -778,6 +913,8 @@ int hinic3_set_port_mtu(void *hwdev, u16 new_mtu)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (new_mtu < HINIC3_MIN_MTU_SIZE) {
nic_err(nic_io->dev_hdl,
@@ -808,6 +945,9 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&feature_nego, 0, sizeof(feature_nego));
feature_nego.func_id = hinic3_global_func_id(hwdev);
feature_nego.opcode = opcode;
@@ -829,29 +969,21 @@ static int nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
return 0;
}
-static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
+static int hinic3_get_bios_pf_bw_tx_limit(void *hwdev, struct hinic3_nic_io *nic_io, u16 func_id, u32 *pf_rate)
{
- struct hinic3_nic_io *nic_io = NULL;
+ int err = 0; // default success
struct nic_cmd_bios_cfg cfg = {{0}};
u16 out_size = sizeof(cfg);
- int err;
- if (!hwdev || !pf_bw_limit)
- return -EINVAL;
-
- if (hinic3_func_type(hwdev) == TYPE_VF || !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
- return 0;
-
- nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- cfg.bios_cfg.func_id = (u8)hinic3_global_func_id(hwdev);
+ cfg.bios_cfg.func_id = (u8)func_id;
cfg.bios_cfg.func_valid = 1;
- cfg.op_code = 0 | NIC_NVM_DATA_PF_SPEED_LIMIT;
+ cfg.op_code = 0 | NIC_NVM_DATA_PF_TX_SPEED_LIMIT;
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_BIOS_CFG, &cfg, sizeof(cfg),
&cfg, &out_size);
if (err || !out_size || cfg.head.status) {
nic_err(nic_io->dev_hdl,
- "Failed to get bios pf bandwidth limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ "Failed to get bios pf bandwidth tx limit, err: %d, status: 0x%x, out size: 0x%x\n",
err, cfg.head.status, out_size);
return -EIO;
}
@@ -861,13 +993,77 @@ static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit)
nic_warn(nic_io->dev_hdl, "Invalid bios configuration data, signature: 0x%x\n",
cfg.bios_cfg.signature);
- if (cfg.bios_cfg.pf_bw > MAX_LIMIT_BW) {
+ if (cfg.bios_cfg.pf_tx_bw > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
+ cfg.bios_cfg.pf_tx_bw);
+ return -EINVAL;
+ }
+
+ (*pf_rate) = cfg.bios_cfg.pf_tx_bw;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_rx_limit(void *hwdev, struct hinic3_nic_io *nic_io, u16 func_id, u32 *pf_rate)
+{
+ int err = 0; // default success
+ struct nic_rx_rate_bios_cfg rx_bios_conf = {{0}};
+ u16 out_size = sizeof(rx_bios_conf);
+
+ rx_bios_conf.func_id = (u8)func_id;
+ rx_bios_conf.op_code = 0; /* 1-save, 0-read */
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_RX_RATE_CFG, &rx_bios_conf, sizeof(rx_bios_conf),
+ &rx_bios_conf, &out_size);
+ if (rx_bios_conf.msg_head.status == HINIC3_MGMT_CMD_UNSUPPORTED && err == 0) { // Compatible older firmware
+ nic_warn(nic_io->dev_hdl, "Not support get bios pf bandwidth rx limit\n");
+ return 0;
+ } else if (err || !out_size || rx_bios_conf.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get bios pf bandwidth rx limit, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, rx_bios_conf.msg_head.status, out_size);
+ return -EIO;
+ }
+ if (rx_bios_conf.rx_rate_limit > MAX_LIMIT_BW) {
nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n",
- cfg.bios_cfg.pf_bw);
+ rx_bios_conf.rx_rate_limit);
return -EINVAL;
}
- *pf_bw_limit = cfg.bios_cfg.pf_bw;
+ (*pf_rate) = rx_bios_conf.rx_rate_limit;
+ return err;
+}
+
+static int hinic3_get_bios_pf_bw_limit(void *hwdev, u32 *pf_bw_limit, u8 direct)
+{
+ struct hinic3_nic_io *nic_io = NULL;
+ u32 pf_rate = 0;
+ int err = 0;
+ u16 func_id;
+ func_id = hinic3_global_func_id(hwdev);
+
+ if (!hwdev || !pf_bw_limit)
+ return -EINVAL;
+
+ if (hinic3_func_type(hwdev) == TYPE_VF || !HINIC3_SUPPORT_RATE_LIMIT(hwdev))
+ return 0;
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ if (direct == HINIC3_NIC_TX) {
+ err = hinic3_get_bios_pf_bw_tx_limit(hwdev, nic_io, func_id, &pf_rate);
+ } else if (direct == HINIC3_NIC_RX) {
+ err = hinic3_get_bios_pf_bw_rx_limit(hwdev, nic_io, func_id, &pf_rate);
+ }
+
+ if (err != 0)
+ return err;
+
+ if (pf_rate > MAX_LIMIT_BW) {
+ nic_err(nic_io->dev_hdl, "Invalid bios cfg pf bandwidth limit: %u\n", pf_rate);
+ return -EINVAL;
+ }
+ *pf_bw_limit = pf_rate;
return 0;
}
@@ -876,8 +1072,9 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
{
struct hinic3_cmd_tx_rate_cfg rate_cfg = {{0}};
struct hinic3_nic_io *nic_io = NULL;
+ u32 rate_limit;
u16 out_size = sizeof(rate_cfg);
- u32 pf_rate;
+ u32 pf_rate = 0;
int err;
u32 speed_convert[PORT_SPEED_UNKNOWN] = {
0, 10, 100, 1000, 10000, 25000, 40000, 50000, 100000, 200000
@@ -892,19 +1089,21 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level)
return -EINVAL;
}
- if (nic_io->nic_cfg.pf_bw_limit == MAX_LIMIT_BW) {
- pf_rate = 0;
- } else {
+ rate_limit = (nic_io->direct == HINIC3_NIC_TX) ?
+ nic_io->nic_cfg.pf_bw_tx_limit : nic_io->nic_cfg.pf_bw_rx_limit;
+
+ if (rate_limit != MAX_LIMIT_BW) {
/* divided by 100 to convert to percentage */
- pf_rate = (speed_convert[speed_level] / 100) * nic_io->nic_cfg.pf_bw_limit;
+ pf_rate = (speed_convert[speed_level] / 100) * rate_limit;
/* bandwidth limit is very small but not unlimit in this case */
- if (pf_rate == 0 && speed_level != PORT_SPEED_NOT_SET)
+ if ((pf_rate == 0) && (speed_level != PORT_SPEED_NOT_SET))
pf_rate = 1;
}
rate_cfg.func_id = hinic3_global_func_id(hwdev);
rate_cfg.min_rate = 0;
rate_cfg.max_rate = pf_rate;
+ rate_cfg.direct = nic_io->direct;
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_MAX_MIN_RATE, &rate_cfg,
sizeof(rate_cfg), &rate_cfg, &out_size);
@@ -927,6 +1126,8 @@ int hinic3_set_nic_feature_to_hw(void *hwdev)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
return nic_feature_nego(hwdev, HINIC3_CMD_OP_SET, &nic_io->feature_cap, 1);
}
@@ -936,6 +1137,8 @@ u64 hinic3_get_feature_cap(void *hwdev)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
return nic_io->feature_cap;
}
@@ -945,6 +1148,9 @@ void hinic3_update_nic_feature(void *hwdev, u64 s_feature)
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
+
nic_io->feature_cap = s_feature;
nic_info(nic_io->dev_hdl, "Update nic feature to 0x%llx\n", nic_io->feature_cap);
@@ -978,6 +1184,7 @@ static int hinic3_init_nic_io(void *hwdev, void *pcidev_hdl, void *dev_hdl,
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_abs = false;
(*nic_io)->nic_cfg.rt_cmd.mpu_send_sfp_info = false;
+ (*nic_io)->nic_cfg.rt_cmd_ext.mpu_send_xsfp_tlv_info = false;
return 0;
}
@@ -994,11 +1201,14 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
{
struct hinic3_nic_io *nic_io = NULL;
int err;
+ int is_in_kexec = vram_get_kexec_flag();
err = hinic3_init_nic_io(hwdev, pcidev_hdl, dev_hdl, &nic_io);
if (err)
return err;
+ nic_io->rx_buff_len = rx_buff_len;
+
err = hinic3_register_service_adapter(hwdev, nic_io, SERVICE_T_NIC);
if (err) {
nic_err(nic_io->dev_hdl, "Failed to register service adapter\n");
@@ -1011,10 +1221,12 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
goto set_used_state_err;
}
- err = hinic3_init_function_table(nic_io);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to init function table\n");
- goto err_out;
+ if (is_in_kexec == 0) {
+ err = hinic3_init_function_table(nic_io);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to init function table\n");
+ goto err_out;
+ }
}
err = hinic3_get_nic_feature_from_hw(hwdev, &nic_io->feature_cap, 1);
@@ -1025,9 +1237,19 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
sdk_info(dev_hdl, "nic features: 0x%llx\n", nic_io->feature_cap);
- err = hinic3_get_bios_pf_bw_limit(hwdev, &nic_io->nic_cfg.pf_bw_limit);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to get pf bandwidth limit\n");
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_tx_limit,
+ HINIC3_NIC_TX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf tx bandwidth limit\n");
+ goto err_out;
+ }
+
+ err = hinic3_get_bios_pf_bw_limit(hwdev,
+ &nic_io->nic_cfg.pf_bw_rx_limit,
+ HINIC3_NIC_RX);
+ if (err != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to get pf rx bandwidth limit\n");
goto err_out;
}
@@ -1037,12 +1259,13 @@ int hinic3_init_nic_hwdev(void *hwdev, void *pcidev_hdl, void *dev_hdl,
goto err_out;
}
- nic_io->rx_buff_len = rx_buff_len;
-
return 0;
err_out:
- hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 0, HINIC3_CHANNEL_NIC);
+ if (hinic3_set_func_svc_used_state(hwdev, SVC_T_NIC, 0,
+ HINIC3_CHANNEL_NIC) != 0) {
+ nic_err(nic_io->dev_hdl, "Failed to set function svc used state\n");
+ }
set_used_state_err:
hinic3_unregister_service_adapter(hwdev, SERVICE_T_NIC);
@@ -1092,6 +1315,8 @@ int hinic3_force_drop_tx_pkt(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&pkt_drop, 0, sizeof(pkt_drop));
pkt_drop.port = hinic3_physical_port_id(hwdev);
@@ -1120,6 +1345,8 @@ int hinic3_set_rx_mode(void *hwdev, u32 enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&rx_mode_cfg, 0, sizeof(rx_mode_cfg));
rx_mode_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1148,6 +1375,8 @@ int hinic3_set_rx_vlan_offload(void *hwdev, u8 en)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_cfg, 0, sizeof(vlan_cfg));
vlan_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1176,6 +1405,9 @@ int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
if (!nic_io->vf_infos || is_zero_ether_addr(vf_info->drv_mac_addr))
return 0;
@@ -1215,6 +1447,8 @@ static int hinic3_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en,
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_cfg, 0, sizeof(lro_cfg));
lro_cfg.func_id = hinic3_global_func_id(hwdev);
@@ -1246,6 +1480,8 @@ static int hinic3_set_rx_lro_timer(void *hwdev, u32 timer_value)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&lro_timer, 0, sizeof(lro_timer));
lro_timer.opcode = HINIC3_CMD_OP_SET;
@@ -1278,6 +1514,8 @@ int hinic3_set_rx_lro_state(void *hwdev, u8 lro_en, u32 lro_timer,
ipv6_en = lro_en ? 1 : 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
nic_info(nic_io->dev_hdl, "Set LRO max coalesce packet size to %uK\n",
lro_max_pkt_len);
@@ -1306,6 +1544,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&vlan_filter, 0, sizeof(vlan_filter));
vlan_filter.func_id = hinic3_global_func_id(hwdev);
@@ -1325,7 +1565,6 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
{
- // struct hinic_hwdev *dev = hwdev;
struct nic_cmd_capture_info cap_info = {{0}};
u16 out_size = sizeof(cap_info);
int err;
@@ -1334,7 +1573,6 @@ int hinic3_set_func_capture_en(void *hwdev, u16 func_id, bool cap_en)
return -EINVAL;
/* 2 function capture types */
- // cap_info.op_type = UP_UCAPTURE_OP_TYPE_FUNC;
cap_info.is_en_trx = cap_en;
cap_info.func_port = func_id;
@@ -1359,6 +1597,8 @@ int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (tcam_rule->index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to add is invalid\n");
return -EINVAL;
@@ -1394,6 +1634,8 @@ int hinic3_del_tcam_rule(void *hwdev, u32 index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
if (index >= HINIC3_MAX_TCAM_RULES_NUM) {
nic_err(nic_io->dev_hdl, "Tcam rules num to del is invalid\n");
return -EINVAL;
@@ -1443,6 +1685,8 @@ static int hinic3_mgmt_tcam_block(void *hwdev, u8 alloc_en, u16 *index)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&tcam_block_info, 0,
sizeof(struct nic_cmd_ctrl_tcam_block_out));
@@ -1488,6 +1732,8 @@ int hinic3_set_fdir_tcam_rule_filter(void *hwdev, bool enable)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
port_tcam_cmd.func_id = hinic3_global_func_id(hwdev);
port_tcam_cmd.tcam_enable = (u8)enable;
@@ -1516,6 +1762,9 @@ int hinic3_flush_tcam_rule(void *hwdev)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
memset(&tcam_flush, 0, sizeof(struct nic_cmd_flush_tcam_rules));
tcam_flush.func_id = hinic3_global_func_id(hwdev);
@@ -1546,6 +1795,9 @@ int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -1588,8 +1840,10 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return -EINVAL;
}
- if (hinic3_func_type(hwdev) == TYPE_VF)
+ if (hinic3_func_type(hwdev) == TYPE_VF) {
+ pr_err("VF are not supported to set link state.\n");
return -EINVAL;
+ }
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
if (!nic_io) {
@@ -1606,3 +1860,35 @@ int hinic3_pf_set_vf_link_state(void *hwdev, bool vf_link_forced, bool link_stat
return 0;
}
EXPORT_SYMBOL(hinic3_pf_set_vf_link_state);
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid)
+{
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ u16 out_size = sizeof(outband_cfg_info);
+ struct hinic3_nic_io *nic_io = NULL;
+ int err;
+
+ if (!hwdev || !outband_default_vid)
+ return -EINVAL;
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
+ err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_OUTBAND_CFG,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size);
+ if (err || !out_size || outband_cfg_info.msg_head.status) {
+ nic_err(nic_io->dev_hdl,
+ "Failed to get outband cfg, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, outband_cfg_info.msg_head.status, out_size);
+ return -EINVAL;
+ }
+
+ *outband_default_vid = outband_cfg_info.outband_default_vid;
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
index ee0587c..0fe7b9f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h
@@ -7,9 +7,9 @@
#include <linux/types.h>
#include <linux/netdevice.h>
-#include "hinic3_mgmt_interface.h"
+#include "nic_mpu_cmd_defs.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#define OS_VF_ID_TO_HW(os_vf_id) ((os_vf_id) + 1)
#define HW_VF_ID_TO_OS(hw_vf_id) ((hw_vf_id) - 1)
@@ -54,6 +54,8 @@
#define MAX_LIMIT_BW 100
+#define HINIC3_INVALID_BOND_ID 0xffffffff
+
enum hinic3_valid_link_settings {
HILINK_LINK_SET_SPEED = 0x1,
HILINK_LINK_SET_AUTONEG = 0x2,
@@ -67,6 +69,11 @@ enum hinic3_link_follow_status {
HINIC3_LINK_FOLLOW_STATUS_MAX,
};
+enum hinic3_nic_pf_direct {
+ HINIC3_NIC_RX = 0,
+ HINIC3_NIC_TX,
+};
+
struct hinic3_link_ksettings {
u32 valid_bitmap;
u8 speed; /* enum nic_speed_level */
@@ -150,8 +157,12 @@ struct nic_port_info {
u8 duplex;
u8 speed;
u8 fec;
+ u8 lanes;
+ u8 rsvd;
u32 supported_mode;
u32 advertised_mode;
+ u32 supported_fec_mode;
+ u32 bond_speed;
};
struct nic_pause_config {
@@ -176,11 +187,17 @@ struct hinic3_rxq_hw {
#define MODULE_TYPE_QSFP28 0x11
#define MODULE_TYPE_QSFP 0x0C
#define MODULE_TYPE_QSFP_PLUS 0x0D
+#define MODULE_TYPE_DSFP 0x1B
+#define MODULE_TYPE_QSFP_CMIS 0x1E
#define TCAM_IP_TYPE_MASK 0x1
#define TCAM_TUNNEL_TYPE_MASK 0xF
#define TCAM_FUNC_ID_MASK 0x7FFF
+int hinic3_delete_bond(void *hwdev);
+int hinic3_open_close_bond(void *hwdev, u32 bond_en);
+int hinic3_create_bond(void *hwdev, u32 *bond_id);
+
int hinic3_add_tcam_rule(void *hwdev, struct nic_tcam_cfg_rule *tcam_rule);
int hinic3_del_tcam_rule(void *hwdev, u32 index);
@@ -201,7 +218,7 @@ int hinic3_flush_tcam_rule(void *hwdev);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic3_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
+int hinic3_update_mac(void *hwdev, const u8 *old_mac, u8 *new_mac, u16 vlan_id,
u16 func_id);
/* *
@@ -333,7 +350,7 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id);
* @retval zero: success
* @retval non-zero: failure
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr);
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr);
/* *
* @brief hinic3_vf_info_vlanprio - get vf vlan priority
@@ -508,7 +525,14 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table);
*/
int hinic3_get_phy_port_stats(void *hwdev, struct mag_cmd_port_stats *stats);
-int hinic3_get_fpga_phy_port_stats(void *hwdev, struct hinic3_phy_fpga_port_stats *stats);
+/* *
+ * @brief hinic3_get_phy_rsfec_stats - get rsfec stats
+ * @param hwdev: device pointer to hwdev
+ * @param stats: rsfec(Reed-Solomon Forward Error Correction) stats
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_get_phy_rsfec_stats(void *hwdev, struct mag_cmd_rsfec_stats *stats);
int hinic3_set_port_funcs_state(void *hwdev, bool enable);
@@ -544,6 +568,8 @@ int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl);
void hinic3_clear_vfs_info(void *hwdev);
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id);
+
int hinic3_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id);
int hinic3_set_led_status(void *hwdev, enum mag_led_type type,
@@ -563,10 +589,13 @@ int hinic3_set_autoneg(void *hwdev, bool enable);
int hinic3_get_sfp_type(void *hwdev, u8 *sfp_type, u8 *sfp_type_ext);
int hinic3_get_sfp_eeprom(void *hwdev, u8 *data, u32 len);
+int hinic3_get_tlv_xsfp_eeprom(void *hwdev, u8 *data, u32 len);
bool hinic3_if_sfp_absent(void *hwdev);
int hinic3_get_sfp_info(void *hwdev, struct mag_cmd_get_xsfp_info *sfp_info);
-
+int hinic3_get_sfp_tlv_info(void *hwdev,
+ struct drv_mag_cmd_get_xsfp_tlv_rsp *sfp_tlv_info,
+ const struct mag_cmd_get_xsfp_tlv_req *sfp_tlv_info_req);
/* *
* @brief hinic3_set_nic_feature_to_hw - sync nic feature to hardware
* @param hwdev: device pointer to hwdev
@@ -618,4 +647,18 @@ int hinic3_set_pf_rate(void *hwdev, u8 speed_level);
int hinic3_get_rxq_hw_info(void *hwdev, struct rxq_check_info *rxq_info, u16 num_qps, u16 wqe_type);
+#if defined(HAVE_NDO_UDP_TUNNEL_ADD) || defined(HAVE_UDP_TUNNEL_NIC_INFO)
+/* *
+ * @brief hinic3_vlxan_port_config - add/del vxlan dst port
+ * @param hwdev: device pointer to hwdev
+ * @param func_id: function id
+ * @param port: vxlan dst port
+ * @param action: add or del, del will set to default value (0x12B5)
+ * @retval zero: success
+ * @retval non-zero: failure
+ */
+int hinic3_vlxan_port_config(void *hwdev, u16 func_id, u16 port, u8 action);
+#endif /* HAVE_NDO_UDP_TUNNEL_ADD || HAVE_UDP_TUNNEL_NIC_INFO */
+
+int hinic3_get_outband_vlan_cfg(void *hwdev, u16 *outband_default_vid);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
index b46cf78..654673f 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg_vf.c
@@ -21,7 +21,8 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
/*lint -e806*/
static unsigned char set_vf_link_state;
@@ -116,7 +117,7 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
err = hinic3_set_vlan_ctx(nic_io, glb_func_id, vlan_tag,
NIC_CONFIG_ALL_QUEUE_VLAN_CTX,
opcode == HINIC3_CMD_OP_ADD);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d vlan ctx, err: %d\n",
HW_VF_ID_TO_OS(vf_id), err);
@@ -137,22 +138,21 @@ int hinic3_cfg_vf_vlan(struct hinic3_nic_io *nic_io, u8 opcode, u16 vid,
/* this function just be called by hinic3_ndo_set_vf_mac,
* others are not permitted.
*/
-int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
+int hinic3_set_vf_mac(void *hwdev, int vf_id, const unsigned char *mac_addr)
{
- struct vf_data_storage *vf_info;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_info = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
-#ifndef __VMWARE__
+
/* duplicate request, so just return success */
if (ether_addr_equal(vf_info->user_mac_addr, mac_addr))
return 0;
-#else
- if (ether_addr_equal(vf_info->user_mac_addr, mac_addr))
- return 0;
-#endif
ether_addr_copy(vf_info->user_mac_addr, mac_addr);
return 0;
@@ -160,13 +160,15 @@ int hinic3_set_vf_mac(void *hwdev, int vf_id, unsigned char *mac_addr)
int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD, vlan, qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan = vlan;
@@ -180,17 +182,20 @@ int hinic3_add_vf_vlan(void *hwdev, int vf_id, u16 vlan, u8 qos)
int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_infos = nic_io->vf_infos;
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_DEL,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan,
vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_info(nic_io->dev_hdl, "Remove VLAN %u on VF %d\n",
@@ -205,11 +210,13 @@ int hinic3_kill_vf_vlan(void *hwdev, int vf_id)
u16 hinic3_vf_info_vlanprio(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
u16 pf_vlan, vlanprio;
u8 pf_qos;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return 0;
pf_vlan = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_vlan;
pf_qos = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].pf_qos;
@@ -222,9 +229,14 @@ int hinic3_set_vf_link_state(void *hwdev, u16 vf_id, int link)
{
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- struct vf_data_storage *vf_infos = nic_io->vf_infos;
+ struct vf_data_storage *vf_infos = NULL;
u8 link_status = 0;
+ if (!nic_io)
+ return -EINVAL;
+
+ vf_infos = nic_io->vf_infos;
+
switch (link) {
case HINIC3_IFLA_VF_LINK_STATE_AUTO:
vf_infos[HW_VF_ID_TO_OS(vf_id)].link_forced = false;
@@ -264,6 +276,9 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
vf_infos = nic_io->vf_infos;
memset(&spoofchk_cfg, 0, sizeof(spoofchk_cfg));
@@ -288,9 +303,11 @@ int hinic3_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk)
bool hinic3_vf_info_spoofchk(void *hwdev, int vf_id)
{
- struct hinic3_nic_io *nic_io;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].spoofchk;
}
@@ -304,7 +321,7 @@ int hinic3_set_vf_trust(void *hwdev, u16 vf_id, bool trust)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
+ if (!nic_io || vf_id > nic_io->max_vfs)
return -EINVAL;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust = trust;
@@ -317,11 +334,11 @@ bool hinic3_get_vf_trust(void *hwdev, int vf_id)
struct hinic3_nic_io *nic_io = NULL;
if (!hwdev)
- return -EINVAL;
+ return false;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- if (vf_id > nic_io->max_vfs)
- return -EINVAL;
+ if (!nic_io || vf_id > nic_io->max_vfs)
+ return false;
return nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust;
}
@@ -339,6 +356,7 @@ static int hinic3_set_vf_tx_rate_max_min(struct hinic3_nic_io *nic_io,
rate_cfg.func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf_id;
rate_cfg.max_rate = max_rate;
rate_cfg.min_rate = min_rate;
+ rate_cfg.direct = HINIC3_NIC_TX;
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
&rate_cfg, sizeof(rate_cfg), &rate_cfg,
@@ -359,13 +377,16 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
int err;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (!HINIC3_SUPPORT_RATE_LIMIT(hwdev)) {
nic_err(nic_io->dev_hdl, "Current function doesn't support to set vf rate limit\n");
return -EOPNOTSUPP;
}
err = hinic3_set_vf_tx_rate_max_min(nic_io, vf_id, max_rate, min_rate);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].max_rate = max_rate;
@@ -376,12 +397,16 @@ int hinic3_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate)
void hinic3_get_vf_config(void *hwdev, u16 vf_id, struct ifla_vf_info *ivi)
{
- struct vf_data_storage *vfinfo;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vfinfo = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return;
vfinfo = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vfinfo)
+ return;
ivi->vf = HW_VF_ID_TO_OS(vf_id);
ether_addr_copy(ivi->mac, vfinfo->user_mac_addr);
@@ -455,12 +480,12 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
nic_io->hwdev, hinic3_vf_event_handler);
- if (err)
+ if (err != 0)
return err;
err = hinic3_register_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
nic_io->hwdev, hinic3_vf_mag_event_handler);
- if (err)
+ if (err != 0)
goto reg_hilink_err;
memset(®ister_info, 0, sizeof(register_info));
@@ -472,6 +497,12 @@ static int vf_func_register(struct hinic3_nic_io *nic_io)
®ister_info, &out_size, 0,
HINIC3_CHANNEL_NIC);
if (err || !out_size || register_info.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev)) {
+ nic_warn(nic_io->dev_hdl,
+ "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
+ err, register_info.msg_head.status, out_size);
+ return 0;
+ }
nic_err(nic_io->dev_hdl, "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
err, register_info.msg_head.status, out_size);
err = -EIO;
@@ -506,18 +537,18 @@ static int pf_init_vf_infos(struct hinic3_nic_io *nic_io)
for (i = 0; i < nic_io->max_vfs; i++) {
err = hinic3_init_vf_infos(nic_io, i);
- if (err)
+ if (err != 0)
goto init_vf_infos_err;
}
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
nic_io->hwdev, hinic3_pf_mbox_handler);
- if (err)
+ if (err != 0)
goto register_pf_mbox_cb_err;
err = hinic3_register_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
nic_io->hwdev, hinic3_pf_mag_mbox_handler);
- if (err)
+ if (err != 0)
goto register_pf_mag_mbox_cb_err;
return 0;
@@ -540,16 +571,16 @@ int hinic3_vf_func_init(struct hinic3_nic_io *nic_io)
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC,
nic_io->hwdev, hinic3_pf_event_handler);
- if (err)
+ if (err != 0)
return err;
err = hinic3_register_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK,
nic_io->hwdev, hinic3_pf_mag_event_handler);
- if (err)
+ if (err != 0)
goto register_mgmt_msg_cb_err;
err = pf_init_vf_infos(nic_io);
- if (err)
+ if (err != 0)
goto pf_init_vf_infos_err;
return 0;
@@ -576,9 +607,15 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
&unregister, sizeof(unregister),
&unregister, &out_size, 0,
HINIC3_CHANNEL_NIC);
- if (err || !out_size || unregister.msg_head.status)
- nic_err(nic_io->dev_hdl, "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
- err, unregister.msg_head.status, out_size);
+ if (err || !out_size || unregister.msg_head.status) {
+ if (hinic3_is_slave_host(nic_io->hwdev))
+ nic_info(nic_io->dev_hdl,
+ "vRoCE VF notify PF unsuccessful is allowed");
+ else
+ nic_err(nic_io->dev_hdl,
+ "Failed to unregister VF, err: %d, status: 0x%x, out_size: 0x%x\n",
+ err, unregister.msg_head.status, out_size);
+ }
hinic3_unregister_vf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
} else {
@@ -587,6 +624,7 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
hinic3_unregister_pf_mbox_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
hinic3_clear_vfs_info(nic_io->hwdev);
kfree(nic_io->vf_infos);
+ nic_io->vf_infos = NULL;
}
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_mgmt_msg_cb(nic_io->hwdev, HINIC3_MOD_L2NIC);
@@ -595,11 +633,15 @@ void hinic3_vf_func_free(struct hinic3_nic_io *nic_io)
static void clear_vf_infos(void *hwdev, u16 vf_id)
{
- struct vf_data_storage *vf_infos;
- struct hinic3_nic_io *nic_io;
+ struct vf_data_storage *vf_infos = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
u16 func_id;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
func_id = hinic3_glb_pf_vf_offset(hwdev) + vf_id;
vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
@@ -628,10 +670,57 @@ static void clear_vf_infos(void *hwdev, u16 vf_id)
void hinic3_clear_vfs_info(void *hwdev)
{
+ u16 i;
struct hinic3_nic_io *nic_io =
hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- u16 i;
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
for (i = 0; i < nic_io->max_vfs; i++)
clear_vf_infos(hwdev, OS_VF_ID_TO_HW(i));
}
+
+int hinic3_notify_vf_outband_cfg(void *hwdev, u16 func_id, u16 vlan_id)
+{
+ int err = 0;
+ struct hinic3_outband_cfg_info outband_cfg_info;
+ struct vf_data_storage *vf_infos = NULL;
+ u16 out_size = sizeof(outband_cfg_info);
+ u16 vf_id;
+ struct hinic3_nic_io *nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return 0;
+ }
+
+ vf_id = func_id - hinic3_glb_pf_vf_offset(nic_io->hwdev);
+ vf_infos = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+
+ memset(&outband_cfg_info, 0, sizeof(outband_cfg_info));
+ if (vf_infos->registered) {
+ outband_cfg_info.func_id = func_id;
+ outband_cfg_info.outband_default_vid = vlan_id;
+ err = hinic3_mbox_to_vf_no_ack(nic_io->hwdev, vf_id,
+ HINIC3_MOD_L2NIC,
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ &outband_cfg_info,
+ sizeof(outband_cfg_info),
+ &outband_cfg_info, &out_size,
+ HINIC3_CHANNEL_NIC);
+ if (err == MBOX_ERRCODE_UNKNOWN_DES_FUNC) {
+ nic_warn(nic_io->dev_hdl, "VF%d not initialized, disconnect it\n",
+ HW_VF_ID_TO_OS(vf_id));
+ hinic3_unregister_vf(nic_io, vf_id);
+ return 0;
+ }
+ if (err || !out_size || outband_cfg_info.msg_head.status)
+ nic_err(nic_io->dev_hdl,
+ "outband cfg event to VF %d failed, err: %d, status: 0x%x, out_size: 0x%x\n",
+ HW_VF_ID_TO_OS(vf_id), err,
+ outband_cfg_info.msg_head.status, out_size);
+ }
+
+ return err;
+}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
deleted file mode 100644
index 31e224a..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cmd.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
- * File Name : hinic3_comm_cmd.h
- * Version : Initial Draft
- * Created : 2019/4/25
- * Last Modified :
- * Description : NIC Commands between Driver and MPU
- * Function List :
- */
-
-#ifndef HINIC3_NIC_CMD_H
-#define HINIC3_NIC_CMD_H
-
-/* Commands between NIC to MPU
- */
-enum hinic3_nic_cmd {
- HINIC3_NIC_CMD_VF_REGISTER = 0, /* only for PFD and VFD */
-
- /* FUNC CFG */
- HINIC3_NIC_CMD_SET_FUNC_TBL = 5,
- HINIC3_NIC_CMD_SET_VPORT_ENABLE,
- HINIC3_NIC_CMD_SET_RX_MODE,
- HINIC3_NIC_CMD_SQ_CI_ATTR_SET,
- HINIC3_NIC_CMD_GET_VPORT_STAT,
- HINIC3_NIC_CMD_CLEAN_VPORT_STAT,
- HINIC3_NIC_CMD_CLEAR_QP_RESOURCE,
- HINIC3_NIC_CMD_CFG_FLEX_QUEUE,
- /* LRO CFG */
- HINIC3_NIC_CMD_CFG_RX_LRO,
- HINIC3_NIC_CMD_CFG_LRO_TIMER,
- HINIC3_NIC_CMD_FEATURE_NEGO,
- HINIC3_NIC_CMD_CFG_LOCAL_LRO_STATE,
-
- HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
-
- /* MAC & VLAN CFG */
- HINIC3_NIC_CMD_GET_MAC = 20,
- HINIC3_NIC_CMD_SET_MAC,
- HINIC3_NIC_CMD_DEL_MAC,
- HINIC3_NIC_CMD_UPDATE_MAC,
- HINIC3_NIC_CMD_GET_ALL_DEFAULT_MAC,
-
- HINIC3_NIC_CMD_CFG_FUNC_VLAN,
- HINIC3_NIC_CMD_SET_VLAN_FILTER_EN,
- HINIC3_NIC_CMD_SET_RX_VLAN_OFFLOAD,
- HINIC3_NIC_CMD_SMAC_CHECK_STATE,
-
- /* SR-IOV */
- HINIC3_NIC_CMD_CFG_VF_VLAN = 40,
- HINIC3_NIC_CMD_SET_SPOOPCHK_STATE,
- /* RATE LIMIT */
- HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
-
- /* RSS CFG */
- HINIC3_NIC_CMD_RSS_CFG = 60,
- HINIC3_NIC_CMD_RSS_TEMP_MGR, /* TODO: delete after implement nego cmd */
- HINIC3_NIC_CMD_GET_RSS_CTX_TBL, /* TODO: delete: move to ucode cmd */
- HINIC3_NIC_CMD_CFG_RSS_HASH_KEY,
- HINIC3_NIC_CMD_CFG_RSS_HASH_ENGINE,
- HINIC3_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC,
- /* IP checksum error packets, enable rss quadruple hash */
- HINIC3_NIC_CMD_IPCS_ERR_RSS_ENABLE_OP = 66,
-
- /* PPA/FDIR */
- HINIC3_NIC_CMD_ADD_TC_FLOW = 80,
- HINIC3_NIC_CMD_DEL_TC_FLOW,
- HINIC3_NIC_CMD_GET_TC_FLOW,
- HINIC3_NIC_CMD_FLUSH_TCAM,
- HINIC3_NIC_CMD_CFG_TCAM_BLOCK,
- HINIC3_NIC_CMD_ENABLE_TCAM,
- HINIC3_NIC_CMD_GET_TCAM_BLOCK,
- HINIC3_NIC_CMD_CFG_PPA_TABLE_ID,
- HINIC3_NIC_CMD_SET_PPA_EN = 88,
- HINIC3_NIC_CMD_CFG_PPA_MODE,
- HINIC3_NIC_CMD_CFG_PPA_FLUSH,
- HINIC3_NIC_CMD_SET_FDIR_STATUS,
- HINIC3_NIC_CMD_GET_PPA_COUNTER,
-
- /* PORT CFG */
- HINIC3_NIC_CMD_SET_PORT_ENABLE = 100,
- HINIC3_NIC_CMD_CFG_PAUSE_INFO,
-
- HINIC3_NIC_CMD_SET_PORT_CAR,
- HINIC3_NIC_CMD_SET_ER_DROP_PKT,
-
- HINIC3_NIC_CMD_VF_COS,
- HINIC3_NIC_CMD_SETUP_COS_MAPPING,
- HINIC3_NIC_CMD_SET_ETS,
- HINIC3_NIC_CMD_SET_PFC,
- HINIC3_NIC_CMD_QOS_ETS,
- HINIC3_NIC_CMD_QOS_PFC,
- HINIC3_NIC_CMD_QOS_DCB_STATE,
- HINIC3_NIC_CMD_QOS_PORT_CFG,
- HINIC3_NIC_CMD_QOS_MAP_CFG,
- HINIC3_NIC_CMD_FORCE_PKT_DROP,
- HINIC3_NIC_CMD_TX_PAUSE_EXCP_NOTICE = 118,
- HINIC3_NIC_CMD_INQUIRT_PAUSE_CFG = 119,
-
- /* MISC */
- HINIC3_NIC_CMD_BIOS_CFG = 120,
- HINIC3_NIC_CMD_SET_FIRMWARE_CUSTOM_PACKETS_MSG,
-
- /* BOND */
- HINIC3_NIC_CMD_BOND_DEV_CREATE = 134,
- HINIC3_NIC_CMD_BOND_DEV_DELETE,
- HINIC3_NIC_CMD_BOND_DEV_OPEN_CLOSE,
- HINIC3_NIC_CMD_BOND_INFO_GET,
- HINIC3_NIC_CMD_BOND_ACTIVE_INFO_GET,
- HINIC3_NIC_CMD_BOND_ACTIVE_NOTICE,
-
- /* DFX */
- HINIC3_NIC_CMD_GET_SM_TABLE = 140,
- HINIC3_NIC_CMD_RD_LINE_TBL,
-
- HINIC3_NIC_CMD_SET_UCAPTURE_OPT = 160, /* TODO: move to roce */
- HINIC3_NIC_CMD_SET_VHD_CFG,
-
- /* TODO: move to HILINK */
- HINIC3_NIC_CMD_GET_PORT_STAT = 200,
- HINIC3_NIC_CMD_CLEAN_PORT_STAT,
- HINIC3_NIC_CMD_CFG_LOOPBACK_MODE,
- HINIC3_NIC_CMD_GET_SFP_QSFP_INFO,
- HINIC3_NIC_CMD_SET_SFP_STATUS,
- HINIC3_NIC_CMD_GET_LIGHT_MODULE_ABS,
- HINIC3_NIC_CMD_GET_LINK_INFO,
- HINIC3_NIC_CMD_CFG_AN_TYPE,
- HINIC3_NIC_CMD_GET_PORT_INFO,
- HINIC3_NIC_CMD_SET_LINK_SETTINGS,
- HINIC3_NIC_CMD_ACTIVATE_BIOS_LINK_CFG,
- HINIC3_NIC_CMD_RESTORE_LINK_CFG,
- HINIC3_NIC_CMD_SET_LINK_FOLLOW,
- HINIC3_NIC_CMD_GET_LINK_STATE,
- HINIC3_NIC_CMD_LINK_STATUS_REPORT,
- HINIC3_NIC_CMD_CABLE_PLUG_EVENT,
- HINIC3_NIC_CMD_LINK_ERR_EVENT,
- HINIC3_NIC_CMD_SET_LED_STATUS,
-
- HINIC3_NIC_CMD_MAX = 256,
-};
-
-/* NIC CMDQ MODE */
-enum hinic3_ucode_cmd {
- HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
- HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
- HINIC3_UCODE_CMD_ARM_SQ,
- HINIC3_UCODE_CMD_ARM_RQ,
- HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
- HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE,
- HINIC3_UCODE_CMD_SET_IQ_ENABLE,
- HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
- HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
- HINIC3_UCODE_CMD_PPA_HASH_TABLE,
- HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
-};
-
-#endif /* HINIC3_NIC_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
index 17d48c4..2878f66 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dbg.c
@@ -30,6 +30,9 @@ int hinic3_dbg_get_wqe_info(void *hwdev, u16 q_id, u16 idx, u16 wqebb_cnt,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (q_id >= nic_io->num_qps) {
pr_err("q_id[%u] > num_qps_cfg[%u].\n", q_id, nic_io->num_qps);
return -EINVAL;
@@ -69,6 +72,9 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -82,6 +88,8 @@ int hinic3_dbg_get_sq_info(void *hwdev, u16 q_id, struct nic_sq_info *sq_info,
}
sq = &nic_io->sq[q_id];
+ if (!sq)
+ return -EINVAL;
sq_info->q_id = q_id;
sq_info->pi = hinic3_get_sq_local_pi(sq);
@@ -112,6 +120,9 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
if (q_id >= nic_io->num_qps) {
nic_err(nic_io->dev_hdl, "Input queue id(%u) is larger than the actual queue number\n",
q_id);
@@ -125,6 +136,8 @@ int hinic3_dbg_get_rq_info(void *hwdev, u16 q_id, struct nic_rq_info *rq_info,
}
rq = &nic_io->rq[q_id];
+ if (!rq)
+ return -EINVAL;
rq_info->q_id = q_id;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
index 800fa73..137098b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h
@@ -15,9 +15,10 @@
#include "hinic3_tx.h"
#include "hinic3_rx.h"
#include "hinic3_dcb.h"
+#include "vram_common.h"
#define HINIC3_NIC_DRV_NAME "hinic3"
-#define HINIC3_NIC_DRV_VERSION "15.17.1.1"
+#define HINIC3_NIC_DRV_VERSION "17.7.8.1"
#define HINIC3_FUNC_IS_VF(hwdev) (hinic3_func_type(hwdev) == TYPE_VF)
@@ -25,6 +26,10 @@
#define HINIC3_MODERATONE_DELAY HZ
#define LP_PKT_CNT 64
+#define LP_PKT_LEN 60
+
+#define NAPI_IS_REGIN 1
+#define NAPI_NOT_REGIN 0
enum hinic3_flags {
HINIC3_INTF_UP,
@@ -91,6 +96,8 @@ struct hinic3_irq {
u16 rsvd1;
u32 irq_id; /* The IRQ number from OS */
+ u32 napi_reign;
+
char irq_name[IFNAMSIZ + 16];
struct napi_struct napi;
cpumask_t affinity_mask;
@@ -123,6 +130,41 @@ struct hinic3_dyna_txrxq_params {
struct hinic3_dyna_txq_res *txqs_res;
struct hinic3_dyna_rxq_res *rxqs_res;
struct hinic3_irq *irq_cfg;
+ char irq_cfg_vram_name[VRAM_NAME_MAX_LEN];
+};
+
+struct hinic3_flush_rq {
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 lb_proc : 1;
+ u32 rsvd : 10;
+ u32 rq_id : 8;
+ u32 func_id : 13;
+#else
+ u32 func_id : 13;
+ u32 rq_id : 8;
+ u32 rsvd : 10;
+ u32 lb_proc : 1;
+#endif
+ } bs;
+ u32 value;
+ } dw;
+
+ union {
+ struct {
+#if defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
+ u32 rsvd2 : 2;
+ u32 src_chnl : 12;
+ u32 pkt_len : 18;
+#else
+ u32 pkt_len : 18;
+ u32 src_chnl : 12;
+ u32 rsvd2 : 2;
+#endif
+ } bs;
+ u32 value;
+ } lb_info0; /* loop back information, used by uCode */
};
#define HINIC3_NIC_STATS_INC(nic_dev, field) \
@@ -147,6 +189,10 @@ struct hinic3_nic_stats {
#endif
};
+struct hinic3_nic_vport_stats {
+ u64 rx_discard_vport;
+};
+
#define HINIC3_TCAM_DYNAMIC_BLOCK_SIZE 16
#define HINIC3_MAX_TCAM_FILTERS 512
@@ -185,104 +231,123 @@ struct hinic3_tcam_info {
struct hinic3_tcam_dynamic_block_info tcam_dynamic_info;
};
+struct hinic3_dcb {
+ u8 cos_config_num_max;
+ u8 func_dft_cos_bitmap;
+ /* used to tool validity check */
+ u16 port_dft_cos_bitmap;
+
+ struct hinic3_dcb_config hw_dcb_cfg;
+ struct hinic3_dcb_config wanted_dcb_cfg;
+ unsigned long dcb_flags;
+};
+
+struct hinic3_vram {
+ u32 vram_mtu;
+ u16 vram_num_qps;
+ unsigned long flags;
+};
+
+struct hinic3_outband_cfg {
+ u16 outband_default_vid;
+ u16 rsvd;
+};
+
struct hinic3_nic_dev {
- struct pci_dev *pdev;
- struct net_device *netdev;
- struct hinic3_lld_dev *lld_dev;
- void *hwdev;
+ struct pci_dev *pdev;
+ struct net_device *netdev;
+ struct hinic3_lld_dev *lld_dev;
+ void *hwdev;
- int poll_weight;
- u32 rsvd1;
- unsigned long *vlan_bitmap;
+ int poll_weight;
+ u32 rsvd1;
+ unsigned long *vlan_bitmap;
- u16 max_qps;
+ u16 max_qps;
- u32 msg_enable;
- unsigned long flags;
+ u32 msg_enable;
+ unsigned long flags;
- u32 lro_replenish_thld;
- u32 dma_rx_buff_size;
- u16 rx_buff_len;
- u32 page_order;
+ u32 lro_replenish_thld;
+ u32 dma_rx_buff_size;
+ u16 rx_buff_len;
+ u32 page_order;
+ bool page_pool_enabled;
/* Rss related varibles */
- u8 rss_hash_engine;
- struct nic_rss_type rss_type;
- u8 *rss_hkey;
+ u8 rss_hash_engine;
+ struct nic_rss_type rss_type;
+ u8 *rss_hkey;
/* hkey in big endian */
- u32 *rss_hkey_be;
- u32 *rss_indir;
+ u32 *rss_hkey_be;
+ u32 *rss_indir;
- u8 cos_config_num_max;
- u8 func_dft_cos_bitmap;
- u16 port_dft_cos_bitmap; /* used to tool validity check */
+ struct hinic3_dcb *dcb;
+ char dcb_name[VRAM_NAME_MAX_LEN];
- struct hinic3_dcb_config hw_dcb_cfg;
- struct hinic3_dcb_config wanted_dcb_cfg;
- struct hinic3_dcb_config dcb_cfg;
- unsigned long dcb_flags;
- int disable_port_cnt;
- /* lock for disable or enable traffic flow */
- struct semaphore dcb_sem;
+ struct hinic3_vram *nic_vram;
+ char nic_vram_name[VRAM_NAME_MAX_LEN];
- struct hinic3_intr_coal_info *intr_coalesce;
- unsigned long last_moder_jiffies;
- u32 adaptive_rx_coal;
- u8 intr_coal_set_flag;
+ int disable_port_cnt;
+
+ struct hinic3_intr_coal_info *intr_coalesce;
+ unsigned long last_moder_jiffies;
+ u32 adaptive_rx_coal;
+ u8 intr_coal_set_flag;
#ifndef HAVE_NETDEV_STATS_IN_NETDEV
- struct net_device_stats net_stats;
+ struct net_device_stats net_stats;
#endif
- struct hinic3_nic_stats stats;
+ struct hinic3_nic_stats stats;
+ struct hinic3_nic_vport_stats vport_stats;
/* lock for nic resource */
- struct mutex nic_mutex;
- bool force_port_disable;
- struct semaphore port_state_sem;
- u8 link_status;
+ struct mutex nic_mutex;
+ u8 link_status;
- struct nic_service_cap nic_cap;
+ struct nic_service_cap nic_cap;
- struct hinic3_txq *txqs;
- struct hinic3_rxq *rxqs;
+ struct hinic3_txq *txqs;
+ struct hinic3_rxq *rxqs;
struct hinic3_dyna_txrxq_params q_params;
- u16 num_qp_irq;
- struct irq_info *qps_irq_info;
+ u16 num_qp_irq;
+ struct irq_info *qps_irq_info;
- struct workqueue_struct *workq;
+ struct workqueue_struct *workq;
- struct work_struct rx_mode_work;
- struct delayed_work moderation_task;
+ struct work_struct rx_mode_work;
+ struct delayed_work moderation_task;
- struct list_head uc_filter_list;
- struct list_head mc_filter_list;
- unsigned long rx_mod_state;
- int netdev_uc_cnt;
- int netdev_mc_cnt;
+ struct list_head uc_filter_list;
+ struct list_head mc_filter_list;
+ unsigned long rx_mod_state;
+ int netdev_uc_cnt;
+ int netdev_mc_cnt;
- int lb_test_rx_idx;
- int lb_pkt_len;
- u8 *lb_test_rx_buf;
+ int lb_test_rx_idx;
+ int lb_pkt_len;
+ u8 *lb_test_rx_buf;
- struct hinic3_tcam_info tcam;
- struct hinic3_rx_flow_rule rx_flow_rule;
+ struct hinic3_tcam_info tcam;
+ struct hinic3_rx_flow_rule rx_flow_rule;
#ifdef HAVE_XDP_SUPPORT
- struct bpf_prog *xdp_prog;
+ struct bpf_prog *xdp_prog;
#endif
- struct delayed_work periodic_work;
+ struct delayed_work periodic_work;
/* reference to enum hinic3_event_work_flags */
- unsigned long event_flag;
-
- struct hinic3_nic_prof_attr *prof_attr;
- struct hinic3_prof_adapter *prof_adap;
- u64 rsvd8[7];
- u32 rsvd9;
- u32 rxq_get_err_times;
- struct delayed_work rxq_check_work;
+ unsigned long event_flag;
+
+ struct hinic3_nic_prof_attr *prof_attr;
+ struct hinic3_prof_adapter *prof_adap;
+ u64 rsvd8[7];
+ struct hinic3_outband_cfg outband_cfg;
+ u32 rxq_get_err_times;
+ struct delayed_work rxq_check_work;
+ struct delayed_work vport_stats_work;
};
#define hinic_msg(level, nic_dev, msglvl, format, arg...) \
@@ -309,7 +374,7 @@ struct hinic3_uld_info *get_nic_uld_info(void);
u32 hinic3_get_io_stats_size(const struct hinic3_nic_dev *nic_dev);
-void hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
+int hinic3_get_io_stats(const struct hinic3_nic_dev *nic_dev, void *stats);
int hinic3_open(struct net_device *netdev);
@@ -328,6 +393,8 @@ int hinic3_qps_irq_init(struct hinic3_nic_dev *nic_dev);
void hinic3_qps_irq_deinit(struct hinic3_nic_dev *nic_dev);
+void qp_del_napi(struct hinic3_irq *irq_cfg);
+
void hinic3_set_netdev_ops(struct hinic3_nic_dev *nic_dev);
bool hinic3_is_netdev_ops_match(const struct net_device *netdev);
@@ -345,10 +412,6 @@ void hinic3_get_ethtool_stats(struct net_device *netdev,
int hinic3_get_sset_count(struct net_device *netdev, int sset);
-int hinic3_force_port_disable(struct hinic3_nic_dev *nic_dev);
-
-int hinic3_force_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
-
int hinic3_maybe_set_port_state(struct hinic3_nic_dev *nic_dev, bool enable);
#ifdef ETHTOOL_GLINKSETTINGS
@@ -383,5 +446,17 @@ bool hinic3_is_xdp_enable(struct hinic3_nic_dev *nic_dev);
int hinic3_xdp_max_mtu(struct hinic3_nic_dev *nic_dev);
#endif
+#ifdef HAVE_UDP_TUNNEL_NIC_INFO
+int hinic3_udp_tunnel_set_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+int hinic3_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table,
+ unsigned int entry, struct udp_tunnel_info *ti);
+#endif /* HAVE_UDP_TUNNEL_NIC_INFO */
+
+#if defined(ETHTOOL_GFECPARAM) && defined(ETHTOOL_SFECPARAM)
+int set_fecparam(void *hwdev, u8 fecparam);
+int get_fecparam(void *hwdev, u8 *advertised_fec, u8 *supported_fec);
+#endif
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
index 57cf07c..6cc294e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_event.c
@@ -21,11 +21,12 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
{
- struct vf_data_storage *vf_info;
+ struct vf_data_storage *vf_info = NULL;
u16 func_id;
int err = 0;
@@ -38,7 +39,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_mac(nic_io->hwdev, vf_info->drv_mac_addr,
vf_info->pf_vlan, func_id,
HINIC3_CHANNEL_NIC);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d MAC\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -51,7 +52,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_cfg_vf_vlan(nic_io, HINIC3_CMD_OP_ADD,
vf_info->pf_vlan, vf_info->pf_qos,
vf_id);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to add VF %d VLAN_QOS\n",
HW_VF_ID_TO_OS(vf_id));
return err;
@@ -62,7 +63,7 @@ static int hinic3_init_vf_config(struct hinic3_nic_io *nic_io, u16 vf_id)
err = hinic3_set_vf_tx_rate(nic_io->hwdev, vf_id,
vf_info->max_rate,
vf_info->min_rate);
- if (err) {
+ if (err != 0) {
nic_err(nic_io->dev_hdl, "Failed to set VF %d max rate %u, min rate %u\n",
HW_VF_ID_TO_OS(vf_id), vf_info->max_rate,
vf_info->min_rate);
@@ -84,7 +85,7 @@ static int register_vf_msg_handler(struct hinic3_nic_io *nic_io, u16 vf_id)
}
err = hinic3_init_vf_config(nic_io, vf_id);
- if (err)
+ if (err != 0)
return err;
nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].registered = true;
@@ -137,6 +138,9 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
int err;
+ if (!vf_info)
+ return -EINVAL;
+
if (register_vf->op_register) {
vf_info->support_extra_feature = register_vf->support_extra_feature;
err = register_vf_msg_handler(nic_io, vf_id);
@@ -145,7 +149,7 @@ static int hinic3_register_vf_msg_handler(struct hinic3_nic_io *nic_io,
vf_info->support_extra_feature = 0;
}
- if (err)
+ if (err != 0)
register_info->msg_head.status = EFAULT;
*out_size = sizeof(*register_info);
@@ -157,6 +161,9 @@ void hinic3_unregister_vf(struct hinic3_nic_io *nic_io, u16 vf_id)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
+ if (!vf_info)
+ return;
+
unregister_vf_msg_handler(nic_io, vf_id);
vf_info->support_extra_feature = 0;
}
@@ -181,14 +188,21 @@ static int hinic3_get_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
void *buf_out, u16 *out_size)
{
struct vf_data_storage *vf_info = nic_io->vf_infos + HW_VF_ID_TO_OS(vf);
+ struct hinic3_port_mac_set *mac_in =
+ (struct hinic3_port_mac_set *)buf_in;
struct hinic3_port_mac_set *mac_info = buf_out;
int err;
- if (HINIC3_SUPPORT_VF_MAC(nic_io->hwdev)) {
+ if (!mac_info || !vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
+ if (HINIC3_SUPPORT_VF_MAC(nic_io->hwdev) != 0) {
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_GET_MAC, buf_in,
in_size, buf_out, out_size);
- if (!err) {
+ if (err == 0) {
if (is_zero_ether_addr(mac_info->mac))
ether_addr_copy(mac_info->mac, vf_info->drv_mac_addr);
}
@@ -211,6 +225,11 @@ static int hinic3_set_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -247,6 +266,11 @@ static int hinic3_del_vf_mac_msg_handler(struct hinic3_nic_io *nic_io, u16 vf,
struct hinic3_port_mac_set *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
+
if (vf_info->use_specified_mac && !vf_info->trust &&
is_valid_ether_addr(mac_in->mac)) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
@@ -283,12 +307,15 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
struct hinic3_port_mac_update *mac_out = buf_out;
int err;
+ if (!vf_info)
+ return -EINVAL;
+
if (!is_valid_ether_addr(mac_in->new_mac)) {
nic_err(nic_io->dev_hdl, "Update VF MAC is invalid.\n");
return -EINVAL;
}
+ mac_in->func_id = hinic3_glb_pf_vf_offset(nic_io->hwdev) + vf;
-#ifndef __VMWARE__
if (vf_info->use_specified_mac && !vf_info->trust) {
nic_warn(nic_io->dev_hdl, "PF has already set VF %d MAC address, and vf trust is off.\n",
HW_VF_ID_TO_OS(vf));
@@ -296,17 +323,7 @@ static int hinic3_update_vf_mac_msg_handler(struct hinic3_nic_io *nic_io,
*out_size = sizeof(*mac_out);
return 0;
}
-#else
- err = hinic_config_vf_request(nic_io->hwdev->pcidev_hdl,
- HW_VF_ID_TO_OS(vf),
- HINIC_CFG_VF_MAC_CHANGED,
- (void *)mac_in->new_mac);
- if (err) {
- nic_err(nic_io->dev_hdl, "Failed to config VF %d MAC request, err: %d\n",
- HW_VF_ID_TO_OS(vf), err);
- return err;
- }
-#endif
+
mac_in->vlan_id = vf_info->pf_vlan;
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev, HINIC3_NIC_CMD_UPDATE_MAC,
buf_in, in_size, buf_out, out_size);
@@ -362,7 +379,8 @@ static int _l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in,
u32 i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
bool cmd_to_pf = false;
- if (hinic3_func_type(hwdev) == TYPE_VF) {
+ if (hinic3_func_type(hwdev) == TYPE_VF &&
+ !hinic3_is_slave_host(hwdev)) {
for (i = 0; i < cmd_cnt; i++) {
if (cmd == vf_cmd_handler[i].cmd)
cmd_to_pf = true;
@@ -404,6 +422,8 @@ int hinic3_pf_mbox_handler(void *hwdev,
return -EFAULT;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (index = 0; index < cmd_size; index++) {
if (cmd == vf_cmd_handler[index].cmd)
@@ -460,10 +480,14 @@ void hinic3_notify_dcb_state_event(struct hinic3_nic_io *nic_io,
static void dcb_state_event(void *hwdev, void *buf_in, u16 in_size,
void *buf_out, u16 *out_size)
{
- struct hinic3_cmd_vf_dcb_state *vf_dcb;
- struct hinic3_nic_io *nic_io;
+ struct hinic3_cmd_vf_dcb_state *vf_dcb = NULL;
+ struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
vf_dcb = buf_in;
if (!vf_dcb)
@@ -479,9 +503,13 @@ static void tx_pause_excp_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_nic_io *nic_io = NULL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*excp_info)) {
- nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
+ nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %lu\n",
in_size, sizeof(*excp_info));
return;
}
@@ -501,6 +529,10 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
struct hinic3_event_info event_info = {0};
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
if (in_size != sizeof(*active_info)) {
nic_err(nic_io->dev_hdl, "Invalid in_size: %u, should be %ld\n",
@@ -515,6 +547,36 @@ static void bond_active_event_handler(void *hwdev, void *buf_in, u16 in_size,
hinic3_event_callback(nic_io->hwdev, &event_info);
}
+static void outband_vlan_cfg_event_handler(void *hwdev, void *buf_in,
+ u16 in_size, void *buf_out,
+ u16 *out_size)
+{
+ struct hinic3_outband_cfg_info *outband_cfg_info = buf_in;
+ struct hinic3_nic_io *nic_io = NULL;
+ struct hinic3_event_info event_info = {0};
+
+ nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io) {
+ pr_err("nic_io is NULL\n");
+ return;
+ }
+
+ nic_info(nic_io->dev_hdl, "outband vlan cfg event received\n");
+
+ if (in_size != sizeof(*outband_cfg_info)) {
+ nic_err(nic_io->dev_hdl, "outband cfg info invalid in_size: %u, should be %lu\n",
+ in_size, sizeof(*outband_cfg_info));
+ return;
+ }
+
+ event_info.service = EVENT_SRV_NIC;
+ event_info.type = EVENT_NIC_OUTBAND_CFG;
+ memcpy((void *)event_info.event_data,
+ outband_cfg_info, sizeof(*outband_cfg_info));
+
+ hinic3_event_callback(nic_io->hwdev, &event_info);
+}
+
static const struct nic_event_handler nic_cmd_handler[] = {
{
.cmd = HINIC3_NIC_CMD_VF_COS,
@@ -529,6 +591,11 @@ static const struct nic_event_handler nic_cmd_handler[] = {
.cmd = HINIC3_NIC_CMD_BOND_ACTIVE_NOTICE,
.handler = bond_active_event_handler,
},
+
+ {
+ .cmd = HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+ .handler = outband_vlan_cfg_event_handler,
+ },
};
static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
@@ -543,6 +610,8 @@ static int _event_handler(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
*out_size = 0;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
for (i = 0; i < size; i++) {
if (cmd == nic_cmd_handler[i].cmd) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
index 22670ff..a9768b7 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c
@@ -16,7 +16,8 @@
#include "hinic3_nic_cfg.h"
#include "hinic3_srv_nic.h"
#include "hinic3_nic.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_nic_io.h"
#define HINIC3_DEAULT_TX_CI_PENDING_LIMIT 1
@@ -34,7 +35,7 @@ MODULE_PARM_DESC(tx_coalescing_time, "TX CI coalescing parameter coalescing_time
static unsigned char rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
module_param(rq_wqe_type, byte, 0444);
-MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 0-8Bytes, 1-16Bytes, 2-32Bytes (default=2)");
+MODULE_PARM_DESC(rq_wqe_type, "RQ WQE type 1-16Bytes, 2-32Bytes (default=2)");
/*lint +e806*/
static u32 tx_drop_thd_on = HINIC3_DEAULT_DROP_THD_ON;
@@ -45,7 +46,7 @@ static u32 tx_drop_thd_off = HINIC3_DEAULT_DROP_THD_OFF;
module_param(tx_drop_thd_off, uint, 0644);
MODULE_PARM_DESC(tx_drop_thd_off, "TX parameter drop_thd_off (default=0)");
/* performance: ci addr RTE_CACHE_SIZE(64B) alignment */
-#define HINIC3_CI_Q_ADDR_SIZE (64)
+#define HINIC3_CI_Q_ADDR_SIZE (64U)
#define CI_TABLE_SIZE(num_qps, pg_sz) \
(ALIGN((num_qps) * HINIC3_CI_Q_ADDR_SIZE, pg_sz))
@@ -350,6 +351,13 @@ static int hinic3_create_rq(struct hinic3_nic_io *nic_io, struct hinic3_io_queue
{
int err;
+ /* rq_wqe_type Only support type 1-16Bytes, 2-32Bytes */
+ if (rq_wqe_type != HINIC3_NORMAL_RQ_WQE && rq_wqe_type != HINIC3_EXTEND_RQ_WQE) {
+ sdk_warn(nic_io->dev_hdl, "Module Parameter rq_wqe_type value %d is out of range: [%d, %d].",
+ rq_wqe_type, HINIC3_NORMAL_RQ_WQE, HINIC3_EXTEND_RQ_WQE);
+ rq_wqe_type = HINIC3_NORMAL_RQ_WQE;
+ }
+
rq->wqe_type = rq_wqe_type;
rq->q_id = q_id;
rq->msix_entry_idx = rq_msix_idx;
@@ -1044,8 +1052,8 @@ static int clean_queue_offload_ctxt(struct hinic3_nic_io *nic_io,
static int clean_qp_offload_ctxt(struct hinic3_nic_io *nic_io)
{
/* clean LRO/TSO context space */
- return (clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_SQ) ||
- clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_RQ));
+ return ((clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_SQ) != 0) ||
+ (clean_queue_offload_ctxt(nic_io, HINIC3_QP_CTXT_TYPE_RQ) != 0));
}
/* init qps ctxt and set sq ci attr and arm all sq */
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
index 5c5585a..943a736 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.h
@@ -303,7 +303,7 @@ static inline void hinic3_write_db(struct hinic3_io_queue *queue, int cos,
wmb(); /* Write all before the doorbell */
- writeq(*((u64 *)&db), DB_ADDR(queue, pi));
+ writeq(*((u64 *)(u8 *)&db), DB_ADDR(queue, pi));
}
struct hinic3_dyna_qp_params {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
index 78d943d..9ea93a0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_prof.c
@@ -32,7 +32,7 @@ struct hinic3_prof_adapter nic_prof_adap_objs[] = {
void hinic3_init_nic_prof_adapter(struct hinic3_nic_dev *nic_dev)
{
- u16 num_adap = ARRAY_SIZE(nic_prof_adap_objs);
+ int num_adap = ARRAY_LEN(nic_prof_adap_objs);
nic_dev->prof_adap = hinic3_prof_init(nic_dev, nic_prof_adap_objs, num_adap,
(void *)&nic_dev->prof_attr);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
index 283c544..6d9b0c1 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ntuple.c
@@ -394,7 +394,8 @@ hinic3_alloc_dynamic_block_resource(struct hinic3_nic_dev *nic_dev,
dynamic_block_ptr = kzalloc(sizeof(*dynamic_block_ptr), GFP_KERNEL);
if (!dynamic_block_ptr) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "fdir filter dynamic alloc block index %d memory failed\n",
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "fdir filter dynamic alloc block index %u memory failed\n",
dynamic_block_id);
return NULL;
}
@@ -433,7 +434,8 @@ hinic3_dynamic_lookup_tcam_filter(struct hinic3_nic_dev *nic_dev,
list_for_each_entry(tmp,
&tcam_info->tcam_dynamic_info.tcam_dynamic_list,
block_list)
- if (tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)
+ if (!tmp ||
+ tmp->dynamic_index_cnt < HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)
break;
if (!tmp || tmp->dynamic_index_cnt >= HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) {
@@ -515,7 +517,7 @@ static int hinic3_add_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, queue: %d, tcam_rule_nums: %d succeed\n",
+ "Add fdir tcam rule, function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, queue: %u, tcam_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev),
tcam_filter->dynamic_block_id, index, fdir_tcam_rule->index,
fdir_tcam_rule->data.qid, tcam_info->tcam_rule_nums + 1);
@@ -582,7 +584,7 @@ static int hinic3_del_tcam_filter(struct hinic3_nic_dev *nic_dev,
}
nicif_info(nic_dev, drv, nic_dev->netdev,
- "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %d, local_index: %d, global_index: %d, local_rules_nums: %d, global_rule_nums: %d succeed\n",
+ "Del fdir_tcam_dynamic_rule function_id: 0x%x, tcam_block_id: %u, local_index: %u, global_index: %u, local_rules_nums: %u, global_rule_nums: %u succeed\n",
hinic3_global_func_id(nic_dev->hwdev), dynamic_block_id,
tcam_filter->index, index, tmp->dynamic_index_cnt - 1,
tcam_info->tcam_rule_nums - 1);
@@ -608,7 +610,7 @@ static inline struct hinic3_tcam_filter *
hinic3_tcam_filter_lookup(const struct list_head *filter_list,
struct tag_tcam_key *key)
{
- struct hinic3_tcam_filter *iter;
+ struct hinic3_tcam_filter *iter = NULL;
list_for_each_entry(iter, filter_list, tcam_filter_list) {
if (memcmp(key, &iter->tcam_key,
@@ -633,7 +635,7 @@ static int hinic3_remove_one_rule(struct hinic3_nic_dev *nic_dev,
struct hinic3_ethtool_rx_flow_rule *eth_rule)
{
struct hinic3_tcam_info *tcam_info = &nic_dev->tcam;
- struct hinic3_tcam_filter *tcam_filter;
+ struct hinic3_tcam_filter *tcam_filter = NULL;
struct nic_tcam_cfg_rule fdir_tcam_rule;
struct tag_tcam_key tcam_key;
int err;
@@ -754,7 +756,7 @@ static int validate_flow(struct hinic3_nic_dev *nic_dev,
{
if (fs->location >= MAX_NUM_OF_ETHTOOL_NTUPLE_RULES) {
nicif_err(nic_dev, drv, nic_dev->netdev, "loc exceed limit[0,%lu]\n",
- MAX_NUM_OF_ETHTOOL_NTUPLE_RULES);
+ MAX_NUM_OF_ETHTOOL_NTUPLE_RULES - 1);
return -EINVAL;
}
@@ -875,7 +877,7 @@ int hinic3_ethtool_get_flow(const struct hinic3_nic_dev *nic_dev,
int hinic3_ethtool_get_all_flows(const struct hinic3_nic_dev *nic_dev,
struct ethtool_rxnfc *info, u32 *rule_locs)
{
- int idx = 0;
+ u32 idx = 0;
struct hinic3_ethtool_rx_flow_rule *eth_rule = NULL;
if (!HINIC3_SUPPORT_FDIR(nic_dev->hwdev)) {
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h b/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
deleted file mode 100644
index a93f3b6..0000000
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_profile.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2021 Huawei Technologies Co., Ltd */
-
-#ifndef HINIC3_PROFILE_H
-#define HINIC3_PROFILE_H
-
-typedef bool (*hinic3_is_match_prof)(void *device);
-typedef void *(*hinic3_init_prof_attr)(void *device);
-typedef void (*hinic3_deinit_prof_attr)(void *porf_attr);
-
-enum prof_adapter_type {
- PROF_ADAP_TYPE_INVALID,
- PROF_ADAP_TYPE_PANGEA = 1,
-
- /* Add prof adapter type before default */
- PROF_ADAP_TYPE_DEFAULT,
-};
-
-/**
- * struct hinic3_prof_adapter - custom scene's profile adapter
- * @type: adapter type
- * @match: Check whether the current function is used in the custom scene.
- * Implemented in the current source file
- * @init: When @match return true, the initialization function called in probe.
- * Implemented in the source file of the custom scene
- * @deinit: When @match return true, the deinitialization function called when
- * remove. Implemented in the source file of the custom scene
- */
-struct hinic3_prof_adapter {
- enum prof_adapter_type type;
- hinic3_is_match_prof match;
- hinic3_init_prof_attr init;
- hinic3_deinit_prof_attr deinit;
-};
-
-#ifdef static
-#undef static
-#define LLT_STATIC_DEF_SAVED
-#endif
-
-/*lint -save -e661 */
-static inline struct hinic3_prof_adapter *
-hinic3_prof_init(void *device, struct hinic3_prof_adapter *adap_objs, int num_adap,
- void **prof_attr)
-{
- struct hinic3_prof_adapter *prof_obj = NULL;
- u16 i;
-
- for (i = 0; i < num_adap; i++) {
- prof_obj = &adap_objs[i];
- if (!(prof_obj->match && prof_obj->match(device)))
- continue;
-
- *prof_attr = prof_obj->init ? prof_obj->init(device) : NULL;
-
- return prof_obj;
- }
-
- return NULL;
-}
-
-static inline void hinic3_prof_deinit(struct hinic3_prof_adapter *prof_obj, void *prof_attr)
-{
- if (!prof_obj)
- return;
-
- if (prof_obj->deinit)
- prof_obj->deinit(prof_attr);
-}
-
-/*lint -restore*/
-
-/* module-level interface */
-#ifdef CONFIG_MODULE_PROF
-struct hinic3_module_ops {
- int (*module_prof_init)(void);
- void (*module_prof_exit)(void);
- void (*probe_fault_process)(void *pdev, u16 level);
- int (*probe_pre_process)(void *pdev);
- void (*probe_pre_unprocess)(void *pdev);
-};
-
-struct hinic3_module_ops *hinic3_get_module_prof_ops(void);
-
-static inline void hinic3_probe_fault_process(void *pdev, u16 level)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (ops && ops->probe_fault_process)
- ops->probe_fault_process(pdev, level);
-}
-
-static inline int hinic3_module_pre_init(void)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (!ops || !ops->module_prof_init)
- return -EINVAL;
-
- return ops->module_prof_init();
-}
-
-static inline void hinic3_module_post_exit(void)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (ops && ops->module_prof_exit)
- ops->module_prof_exit();
-}
-
-static inline int hinic3_probe_pre_process(void *pdev)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (!ops || !ops->probe_pre_process)
- return -EINVAL;
-
- return ops->probe_pre_process(pdev);
-}
-
-static inline void hinic3_probe_pre_unprocess(void *pdev)
-{
- struct hinic3_module_ops *ops = hinic3_get_module_prof_ops();
-
- if (ops && ops->probe_pre_unprocess)
- ops->probe_pre_unprocess(pdev);
-}
-#else
-static inline void hinic3_probe_fault_process(void *pdev, u16 level) { };
-
-static inline int hinic3_module_pre_init(void)
-{
- return 0;
-}
-
-static inline void hinic3_module_post_exit(void) { };
-
-static inline int hinic3_probe_pre_process(void *pdev)
-{
- return 0;
-}
-
-static inline void hinic3_probe_pre_unprocess(void *pdev) { };
-#endif
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
index 6bf3b11..655d2b8 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/dcbnl.h>
+#include <linux/init.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -23,8 +24,9 @@
#include "hinic3_hw.h"
#include "hinic3_rss.h"
-/*lint -e806*/
-static u16 num_qps;
+#include "vram_common.h"
+
+static u16 num_qps = 0;
module_param(num_qps, ushort, 0444);
MODULE_PARM_DESC(num_qps, "Number of Queue Pairs (default=0)");
@@ -104,88 +106,84 @@ static int hinic3_get_rq2iq_map(struct hinic3_nic_dev *nic_dev,
return 0;
}
-static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev, u8 num_cos, u32 *indir)
+static void hinic3_fillout_indir_tbl(struct hinic3_nic_dev *nic_dev,
+ u8 group_num, u32 *indir)
{
- u16 k, group_size, start_qid = 0, qp_num = 0;
- int i = 0;
- u8 j, cur_cos = 0, default_cos;
+ struct hinic3_dcb *dcb = nic_dev->dcb;
+ u16 k, group_size, start_qid = 0, cur_cos_qnum = 0;
+ u32 i = 0;
+ u8 j, cur_cos = 0, group = 0;
u8 valid_cos_map = hinic3_get_dev_valid_cos_map(nic_dev);
- if (num_cos == 0) {
+ if (group_num == 0) {
for (i = 0; i < NIC_RSS_INDIR_SIZE; i++)
indir[i] = i % nic_dev->q_params.num_qps;
} else {
- group_size = NIC_RSS_INDIR_SIZE / num_cos;
-
- for (j = 0; j < num_cos; j++) {
- while (cur_cos < NIC_DCB_COS_MAX &&
- nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos] == 0)
- cur_cos++;
-
- if (cur_cos >= NIC_DCB_COS_MAX) {
- if (BIT(nic_dev->hw_dcb_cfg.default_cos) & valid_cos_map)
- default_cos = nic_dev->hw_dcb_cfg.default_cos;
- else
- default_cos = (u8)fls(valid_cos_map) - 1;
+ group_size = NIC_RSS_INDIR_SIZE / group_num;
+
+ for (group = 0; group < group_num; group++) {
+ cur_cos = dcb->hw_dcb_cfg.default_cos;
+ for (j = 0; j < NIC_DCB_COS_MAX; j++) {
+ if ((BIT(j) & valid_cos_map) != 0) {
+ cur_cos = j;
+ valid_cos_map -= (u8)BIT(j);
+ break;
+ }
+ }
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[default_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[default_cos];
+ cur_cos_qnum = dcb->hw_dcb_cfg.cos_qp_num[cur_cos];
+ if (cur_cos_qnum > 0) {
+ start_qid =
+ dcb->hw_dcb_cfg.cos_qp_offset[cur_cos];
} else {
- start_qid = nic_dev->hw_dcb_cfg.cos_qp_offset[cur_cos];
- qp_num = nic_dev->hw_dcb_cfg.cos_qp_num[cur_cos];
+ start_qid = cur_cos % nic_dev->q_params.num_qps;
+ /* Ensure that the offset of start_id is 0. */
+ cur_cos_qnum = 1;
}
for (k = 0; k < group_size; k++)
- indir[i++] = start_qid + k % qp_num;
-
- cur_cos++;
+ indir[i++] = start_qid + k % cur_cos_qnum;
}
}
}
-/*lint -e528*/
int hinic3_rss_init(struct hinic3_nic_dev *nic_dev, u8 *rq2iq_map, u32 map_size, u8 dcb_en)
{
struct net_device *netdev = nic_dev->netdev;
- u8 i, cos_num;
- u8 cos_map[NIC_DCB_UP_MAX] = {0};
- u8 cfg_map[NIC_DCB_UP_MAX] = {0};
+ u8 i, group_num, cos_bitmap, group = 0;
+ u8 cos_group[NIC_DCB_UP_MAX] = {0};
int err;
- if (dcb_en) {
- cos_num = hinic3_get_dev_user_cos_num(nic_dev);
-
- if (nic_dev->hw_dcb_cfg.trust == 0) {
- memcpy(cfg_map, nic_dev->hw_dcb_cfg.pcp2cos, sizeof(cfg_map));
- } else if (nic_dev->hw_dcb_cfg.trust == 1) {
- for (i = 0; i < NIC_DCB_UP_MAX; i++)
- cfg_map[i] = nic_dev->hw_dcb_cfg.dscp2cos[i * NIC_DCB_DSCP_NUM];
- }
-#define COS_CHANGE_OFFSET 4
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[COS_CHANGE_OFFSET + i] = cfg_map[i];
+ if (dcb_en != 0) {
+ group_num = (u8)roundup_pow_of_two(
+ hinic3_get_dev_user_cos_num(nic_dev));
- for (i = 0; i < COS_CHANGE_OFFSET; i++)
- cos_map[i] = cfg_map[NIC_DCB_UP_MAX - (i + 1)];
+ cos_bitmap = hinic3_get_dev_valid_cos_map(nic_dev);
- while (cos_num & (cos_num - 1))
- cos_num++;
+ for (i = 0; i < NIC_DCB_UP_MAX; i++) {
+ if ((BIT(i) & cos_bitmap) != 0)
+ cos_group[NIC_DCB_UP_MAX - i - 1] = group++;
+ else
+ cos_group[NIC_DCB_UP_MAX - i - 1] =
+ group_num - 1;
+ }
} else {
- cos_num = 0;
+ group_num = 0;
}
- err = hinic3_set_hw_rss_parameters(netdev, 1, cos_num, cos_map, dcb_en);
+ err = hinic3_set_hw_rss_parameters(netdev, 1, group_num,
+ cos_group, dcb_en);
if (err)
return err;
- err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps, cos_num, cos_map,
- NIC_DCB_UP_MAX, nic_dev->rss_indir, rq2iq_map, map_size);
+ err = hinic3_get_rq2iq_map(nic_dev, nic_dev->q_params.num_qps,
+ group_num, cos_group, NIC_DCB_UP_MAX,
+ nic_dev->rss_indir, rq2iq_map, map_size);
if (err)
nicif_err(nic_dev, drv, netdev, "Failed to get rq map\n");
return err;
}
-/*lint -e528*/
void hinic3_rss_deinit(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -246,28 +244,59 @@ discard_user_rss_indir:
hinic3_set_default_rss_indir(netdev);
}
+#ifdef HAVE_HOT_REPLACE_FUNC
+bool partition_slave_doing_hotupgrade(void)
+{
+ return get_partition_role() && partition_doing_hotupgrade();
+}
+#endif
+
static void decide_num_qps(struct hinic3_nic_dev *nic_dev)
{
u16 tmp_num_qps = nic_dev->max_qps;
u16 num_cpus = 0;
+ u16 max_num_cpus;
int i, node;
+ int is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ nic_dev->q_params.num_qps = nic_dev->nic_vram->vram_num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "Os hotreplace use vram to init num qps 1:%hu 2:%hu\n",
+ nic_dev->q_params.num_qps,
+ nic_dev->nic_vram->vram_num_qps);
+ return;
+ }
+
if (nic_dev->nic_cap.default_num_queues != 0 &&
nic_dev->nic_cap.default_num_queues < nic_dev->max_qps)
tmp_num_qps = nic_dev->nic_cap.default_num_queues;
MOD_PARA_VALIDATE_NUM_QPS(nic_dev, num_qps, tmp_num_qps);
- for (i = 0; i < (int)num_online_cpus(); i++) {
+#ifdef HAVE_HOT_REPLACE_FUNC
+ if (partition_slave_doing_hotupgrade())
+ max_num_cpus = (u16)num_present_cpus();
+ else
+ max_num_cpus = (u16)num_online_cpus();
+#else
+ max_num_cpus = (u16)num_online_cpus();
+#endif
+
+ for (i = 0; i < max_num_cpus; i++) {
node = (int)cpu_to_node(i);
if (node == dev_to_node(&nic_dev->pdev->dev))
num_cpus++;
}
if (!num_cpus)
- num_cpus = (u16)num_online_cpus();
+ num_cpus = max_num_cpus;
nic_dev->q_params.num_qps = (u16)min_t(u16, tmp_num_qps, num_cpus);
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
+ nicif_info(nic_dev, drv, nic_dev->netdev,
+ "init num qps 1:%u 2:%u\n",
+ nic_dev->q_params.num_qps, nic_dev->nic_vram->vram_num_qps);
}
static void copy_value_to_rss_hkey(struct hinic3_nic_dev *nic_dev,
@@ -324,7 +353,6 @@ static int alloc_rss_resource(struct hinic3_nic_dev *nic_dev)
return 0;
}
-/*lint -e528*/
void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
{
u8 cos_map[NIC_DCB_UP_MAX] = {0};
@@ -363,6 +391,7 @@ void hinic3_try_to_enable_rss(struct hinic3_nic_dev *nic_dev)
set_q_params:
clear_bit(HINIC3_RSS_ENABLE, &nic_dev->flags);
nic_dev->q_params.num_qps = nic_dev->max_qps;
+ nic_dev->nic_vram->vram_num_qps = nic_dev->max_qps;
}
static int hinic3_config_rss_hw_resource(struct hinic3_nic_dev *nic_dev,
@@ -756,6 +785,7 @@ int hinic3_set_channels(struct net_device *netdev,
nic_dev->q_params.num_qps = (u16)count;
}
+ nic_dev->nic_vram->vram_num_qps = nic_dev->q_params.num_qps;
return 0;
}
@@ -816,7 +846,7 @@ int hinic3_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
int err = 0;
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
@@ -923,7 +953,7 @@ int hinic3_get_rxfh_indir(struct net_device *netdev, u32 *indir)
indir = indir1->ring_index;
#endif
if (!test_bit(HINIC3_RSS_ENABLE, &nic_dev->flags)) {
- nicif_err(nic_dev, drv, nic_dev->netdev, "Rss is disable\n");
+ netdev_warn_once(nic_dev->netdev, "Rss is disable\n");
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
index 175c4d6..902d7e2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss_cfg.c
@@ -15,13 +15,14 @@
#include "ossl_knl.h"
#include "hinic3_crm.h"
#include "hinic3_nic_cfg.h"
-#include "hinic3_nic_cmd.h"
+#include "nic_mpu_cmd.h"
+#include "nic_npu_cmd.h"
#include "hinic3_hw.h"
#include "hinic3_nic.h"
#include "hinic3_common.h"
static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
- u8 *key)
+ u8 *key, u16 key_size)
{
struct hinic3_cmd_rss_hash_key hash_key;
u16 out_size = sizeof(hash_key);
@@ -32,7 +33,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
hash_key.opcode = opcode;
if (opcode == HINIC3_CMD_OP_SET)
- memcpy(hash_key.key, key, NIC_RSS_KEY_SIZE);
+ memcpy(hash_key.key, key, key_size);
err = l2nic_msg_to_mgmt_sync(nic_io->hwdev,
HINIC3_NIC_CMD_CFG_RSS_HASH_KEY,
@@ -46,7 +47,7 @@ static int hinic3_rss_cfg_hash_key(struct hinic3_nic_io *nic_io, u8 opcode,
}
if (opcode == HINIC3_CMD_OP_GET)
- memcpy(key, hash_key.key, NIC_RSS_KEY_SIZE);
+ memcpy(key, hash_key.key, key_size);
return 0;
}
@@ -60,8 +61,11 @@ int hinic3_rss_set_hash_key(void *hwdev, const u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memcpy(hash_key, key, NIC_RSS_KEY_SIZE);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET, hash_key);
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_SET,
+ hash_key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
@@ -72,7 +76,10 @@ int hinic3_rss_get_hash_key(void *hwdev, u8 *key)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
- return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET, key);
+ if (!nic_io)
+ return -EINVAL;
+ return hinic3_rss_cfg_hash_key(nic_io, HINIC3_CMD_OP_GET,
+ key, NIC_RSS_KEY_SIZE);
}
int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
@@ -86,6 +93,9 @@ int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd_buf.\n");
@@ -126,6 +136,8 @@ int hinic3_rss_set_indir_tbl(void *hwdev, const u32 *indir_table)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
nic_err(nic_io->dev_hdl, "Failed to allocate cmd buf\n");
@@ -170,6 +182,8 @@ static int hinic3_cmdq_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
cmd_buf = hinic3_alloc_cmd_buf(hwdev);
if (!cmd_buf) {
@@ -221,6 +235,8 @@ static int hinic3_mgmt_set_rss_type(void *hwdev, struct nic_rss_type rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&ctx_tbl, 0, sizeof(ctx_tbl));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
ctx |= HINIC3_RSS_TYPE_SET(1, VALID) |
@@ -270,6 +286,8 @@ int hinic3_get_rss_type(void *hwdev, struct nic_rss_type *rss_type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&ctx_tbl, 0, sizeof(struct hinic3_rss_context_table));
ctx_tbl.func_id = hinic3_global_func_id(hwdev);
@@ -303,6 +321,9 @@ static int hinic3_rss_cfg_hash_engine(struct hinic3_nic_io *nic_io, u8 opcode,
u16 out_size = sizeof(hash_type);
int err;
+ if (!nic_io)
+ return -EINVAL;
+
memset(&hash_type, 0, sizeof(struct hinic3_cmd_rss_engine_type));
hash_type.func_id = hinic3_global_func_id(nic_io->hwdev);
@@ -336,6 +357,9 @@ int hinic3_rss_set_hash_engine(void *hwdev, u8 type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_SET, &type);
}
@@ -347,6 +371,9 @@ int hinic3_rss_get_hash_engine(void *hwdev, u8 *type)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
+
return hinic3_rss_cfg_hash_engine(nic_io, HINIC3_CMD_OP_GET, type);
}
@@ -362,6 +389,8 @@ int hinic3_rss_cfg(void *hwdev, u8 rss_en, u8 cos_num, u8 *prio_tc, u16 num_qps)
return -EINVAL;
nic_io = hinic3_get_service_adapter(hwdev, SERVICE_T_NIC);
+ if (!nic_io)
+ return -EINVAL;
memset(&rss_cfg, 0, sizeof(struct hinic3_cmd_rss_config));
rss_cfg.func_id = hinic3_global_func_id(hwdev);
rss_cfg.rss_en = rss_en;
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
index 5c60d01..4dbd6dd 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
@@ -10,6 +10,7 @@
#include <linux/interrupt.h>
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
+#include <net/xdp.h>
#include <linux/device.h>
#include <linux/pci.h>
#include <linux/u64_stats_sync.h>
@@ -20,6 +21,7 @@
#include <linux/ipv6.h>
#include <linux/module.h>
#include <linux/compiler.h>
+#include <linux/filter.h>
#include "ossl_knl.h"
#include "hinic3_crm.h"
@@ -31,10 +33,6 @@
#include "hinic3_rss.h"
#include "hinic3_rx.h"
-static u32 rq_pi_rd_en;
-module_param(rq_pi_rd_en, uint, 0644);
-MODULE_PARM_DESC(rq_pi_rd_en, "Enable rq read pi from host, defaut update pi by doorbell (default=0)");
-
/* performance: ci addr RTE_CACHE_SIZE(64B) alignment */
#define HINIC3_RX_HDR_SIZE 256
#define HINIC3_RX_BUFFER_WRITE 16
@@ -63,19 +61,34 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
struct pci_dev *pdev = nic_dev->pdev;
struct page *page = rx_info->page;
dma_addr_t dma = rx_info->buf_dma_addr;
+ u32 page_offset = 0;
if (likely(dma))
return true;
/* alloc new page for storage */
- page = alloc_pages_node(NUMA_NO_NODE, GFP_ATOMIC | __GFP_COLD |
- __GFP_COMP, nic_dev->page_order);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page = page_pool_alloc_frag(rx_info->page_pool, &page_offset,
+ nic_dev->rx_buff_len,
+ GFP_ATOMIC | __GFP_COLD |
+ __GFP_COMP);
+ if (unlikely(!page))
+ return false;
+ dma = page_pool_get_dma_addr(page);
+ goto set_rx_info;
+ }
+#endif
+ page = alloc_pages_node(NUMA_NO_NODE,
+ GFP_ATOMIC | __GFP_COLD | __GFP_COMP,
+ nic_dev->page_order);
+
if (unlikely(!page))
return false;
/* map page for use */
- dma = dma_map_page(&pdev->dev, page, 0, nic_dev->dma_rx_buff_size,
- DMA_FROM_DEVICE);
+ dma = dma_map_page(&pdev->dev, page, page_offset,
+ nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
/* if mapping failed free memory back to system since
* there isn't much point in holding memory we can't use
*/
@@ -83,10 +96,12 @@ static bool rx_alloc_mapped_page(struct hinic3_nic_dev *nic_dev,
__free_pages(page, nic_dev->page_order);
return false;
}
+ goto set_rx_info;
+set_rx_info:
rx_info->page = page;
rx_info->buf_dma_addr = dma;
- rx_info->page_offset = 0;
+ rx_info->page_offset = page_offset;
return true;
}
@@ -108,8 +123,8 @@ static u32 hinic3_rx_fill_wqe(struct hinic3_rxq *rxq)
/* unit of cqe length is 16B */
hinic3_set_sge(&rq_wqe->extend_wqe.cqe_sect.sge,
rx_info->cqe_dma,
- (sizeof(struct hinic3_rq_cqe) >>
- HINIC3_CQE_SIZE_SHIFT));
+ (HINIC3_CQE_LEN >>
+ HINIC3_CQE_SIZE_SHIFT));
/* use fixed len */
rq_wqe->extend_wqe.buf_desc.sge.len =
nic_dev->rx_buff_len;
@@ -163,18 +178,11 @@ static u32 hinic3_rx_fill_buffers(struct hinic3_rxq *rxq)
}
if (likely(i)) {
- if (!rq_pi_rd_en) {
- hinic3_write_db(rxq->rq,
- rxq->q_id & (NIC_DCB_COS_MAX - 1),
- RQ_CFLAG_DP,
- (u16)((u32)rxq->next_to_update <<
- rxq->rq->wqe_type));
- } else {
- /* Write all the wqes before pi update */
- wmb();
-
- hinic3_update_rq_hw_pi(rxq->rq, rxq->next_to_update);
- }
+ hinic3_write_db(rxq->rq,
+ rxq->q_id & (NIC_RX_DB_COS_MAX - 1),
+ RQ_CFLAG_DP,
+ (u16)((u32)rxq->next_to_update <<
+ rxq->rq->wqe_type));
rxq->delta -= i;
rxq->next_to_alloc = rxq->next_to_update;
} else if (free_wqebbs == rxq->q_depth - 1) {
@@ -208,6 +216,18 @@ static void hinic3_rx_free_buffers(struct hinic3_nic_dev *nic_dev, u32 q_depth,
for (i = 0; i < q_depth; i++) {
rx_info = &rx_info_arr[i];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ if (rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool,
+ rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ }
+ continue;
+ }
+#endif
+
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev,
rx_info->buf_dma_addr,
@@ -226,7 +246,7 @@ static void hinic3_rx_free_buffers(struct hinic3_nic_dev *nic_dev, u32 q_depth,
static void hinic3_reuse_rx_page(struct hinic3_rxq *rxq,
struct hinic3_rx_info *old_rx_info)
{
- struct hinic3_rx_info *new_rx_info;
+ struct hinic3_rx_info *new_rx_info = NULL;
u16 nta = rxq->next_to_alloc;
new_rx_info = &rxq->rx_info[nta];
@@ -250,8 +270,8 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
struct hinic3_rx_info *rx_info,
struct sk_buff *skb, u32 size)
{
- struct page *page;
- u8 *va;
+ struct page *page = NULL;
+ u8 *va = NULL;
page = rx_info->page;
va = (u8 *)page_address(page) + rx_info->page_offset;
@@ -267,8 +287,15 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
DMA_FROM_DEVICE);
if (size <= HINIC3_RX_HDR_SIZE && !skb_is_nonlinear(skb)) {
- memcpy(__skb_put(skb, size), va,
- ALIGN(size, sizeof(long))); /*lint !e666*/
+ __skb_put_data(skb, va, size);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool,
+ page, false);
+ return false;
+ }
+#endif
/* page is not reserved, we can reuse buffer as-is */
if (likely(page_to_nid(page) == numa_node_id()))
@@ -276,25 +303,37 @@ static bool hinic3_add_rx_frag(struct hinic3_rxq *rxq,
/* this page cannot be reused so discard it */
put_page(page);
- return false;
+ goto discard_page;
}
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
(int)rx_info->page_offset, (int)size, rxq->buf_len);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
+
/* avoid re-using remote pages */
if (unlikely(page_to_nid(page) != numa_node_id()))
- return false;
+ goto discard_page;
/* if we are only owner of page we can reuse it */
if (unlikely(page_count(page) != 1))
- return false;
+ goto discard_page;
/* flip page offset to other buffer */
rx_info->page_offset ^= rxq->buf_len;
get_page(page);
return true;
+
+discard_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
}
static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
@@ -334,13 +373,9 @@ static void packaging_skb(struct hinic3_rxq *rxq, struct sk_buff *head_skb,
head_skb->truesize += rxq->buf_len;
}
- if (likely(hinic3_add_rx_frag(rxq, rx_info, skb, size))) {
+ if (likely(hinic3_add_rx_frag(rxq, rx_info, skb, size)))
hinic3_reuse_rx_page(rxq, rx_info);
- } else {
- /* we are not reusing the buffer so unmap it */
- dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
- rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
- }
+
/* clear contents of buffer_info */
rx_info->buf_dma_addr = 0;
rx_info->page = NULL;
@@ -481,9 +516,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
protocol = hdr.eth->h_proto;
/* L2 header */
- /*lint -save -e778*/
if (protocol == htons(ETH_P_8021_AD) ||
- protocol == htons(ETH_P_8021_Q)) { /*lint -restore*/
+ protocol == htons(ETH_P_8021_Q)) {
if (unlikely(max_len < ETH_HLEN + VLAN_HLEN))
return max_len;
@@ -495,9 +529,8 @@ static unsigned int hinic3_eth_get_headlen(unsigned char *data, unsigned int max
}
/* L3 header */
- /*lint -save -e778*/
switch (protocol) {
- case htons(ETH_P_IP): /*lint -restore*/
+ case htons(ETH_P_IP):
if ((int)(hdr.data - data) >
(int)(max_len - sizeof(struct iphdr)))
return max_len;
@@ -680,7 +713,7 @@ static void hinic3_copy_lp_data(struct hinic3_nic_dev *nic_dev,
nicif_warn(nic_dev, rx_err, netdev, "Loopback test warning, receive too many test pkts\n");
}
- if (skb->len != nic_dev->lb_pkt_len) {
+ if (skb->len != (u32)(nic_dev->lb_pkt_len)) {
nicif_warn(nic_dev, rx_err, netdev, "Wrong packet length\n");
nic_dev->lb_test_rx_idx++;
return;
@@ -714,7 +747,10 @@ static inline void hinic3_lro_set_gso_params(struct sk_buff *skb, u16 num_lro)
}
#ifdef HAVE_XDP_SUPPORT
-enum hinic3_xdp_pkt {
+enum hinic3_xdp_status {
+ // bpf_prog status
+ HINIC3_XDP_PROG_EMPTY,
+ // pkt action
HINIC3_XDP_PKT_PASS,
HINIC3_XDP_PKT_DROP,
};
@@ -725,9 +761,15 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
while (weqbb_num) {
rx_info = &rxq->rx_info[rxq->cons_idx & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool)
+ goto discard_direct;
+#endif
if (likely(page_to_nid(rx_info->page) == numa_node_id()))
hinic3_reuse_rx_page(rxq, rx_info);
+ goto discard_direct;
+discard_direct:
rx_info->buf_dma_addr = 0;
rx_info->page = NULL;
rxq->cons_idx++;
@@ -737,11 +779,10 @@ static void update_drop_rx_info(struct hinic3_rxq *rxq, u16 weqbb_num)
}
}
-int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
+int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len, struct xdp_buff *xdp)
{
struct bpf_prog *xdp_prog = NULL;
struct hinic3_rx_info *rx_info = NULL;
- struct xdp_buff xdp;
int result = HINIC3_XDP_PKT_PASS;
u16 weqbb_num = 1; /* xdp can only use one rx_buff */
u8 *va = NULL;
@@ -749,13 +790,14 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
rcu_read_lock();
xdp_prog = READ_ONCE(rxq->xdp_prog);
- if (!xdp_prog)
+ if (!xdp_prog) {
+ result = HINIC3_XDP_PROG_EMPTY;
goto unlock_rcu;
+ }
if (unlikely(pkt_len > rxq->buf_len)) {
RXQ_STATS_INC(rxq, xdp_large_pkt);
- weqbb_num = (u16)(pkt_len >> rxq->rx_buff_shift) +
- ((pkt_len & (rxq->buf_len - 1)) ? 1 : 0);
+ weqbb_num = HINIC3_GET_SGE_NUM(pkt_len, rxq);
result = HINIC3_XDP_PKT_DROP;
goto xdp_out;
}
@@ -766,19 +808,20 @@ int hinic3_run_xdp(struct hinic3_rxq *rxq, u32 pkt_len)
dma_sync_single_range_for_cpu(rxq->dev, rx_info->buf_dma_addr,
rx_info->page_offset,
rxq->buf_len, DMA_FROM_DEVICE);
- xdp.data = va;
- xdp.data_hard_start = xdp.data;
- xdp.data_end = xdp.data + pkt_len;
+ xdp->data = va;
+ xdp->data_hard_start = xdp->data;
+ xdp->data_end = xdp->data + pkt_len;
#ifdef HAVE_XDP_FRAME_SZ
- xdp.frame_sz = rxq->buf_len;
+ xdp->frame_sz = rxq->buf_len;
#endif
#ifdef HAVE_XDP_DATA_META
- xdp_set_data_meta_invalid(&xdp);
+ xdp_set_data_meta_invalid(xdp);
#endif
- prefetchw(xdp.data_hard_start);
- act = bpf_prog_run_xdp(xdp_prog, &xdp);
+ prefetchw(xdp->data_hard_start);
+ act = bpf_prog_run_xdp(xdp_prog, xdp);
switch (act) {
case XDP_PASS:
+ result = HINIC3_XDP_PKT_PASS;
break;
case XDP_DROP:
result = HINIC3_XDP_PKT_DROP;
@@ -799,12 +842,94 @@ unlock_rcu:
return result;
}
+
+static bool hinic3_add_rx_frag_with_xdp(struct hinic3_rxq *rxq, u32 pkt_len,
+ struct hinic3_rx_info *rx_info,
+ struct sk_buff *skb,
+ struct xdp_buff *xdp)
+{
+ struct page *page = rx_info->page;
+
+ if (pkt_len <= HINIC3_RX_HDR_SIZE) {
+ __skb_put_data(skb, xdp->data, pkt_len);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ page_pool_put_full_page(rx_info->page_pool,
+ page, false);
+ return false;
+ }
+#endif
+
+ if (likely(page_to_nid(page) == numa_node_id()))
+ return true;
+
+ put_page(page);
+ goto umap_page;
+ }
+
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
+ (int)(rx_info->page_offset +
+ (xdp->data - xdp->data_hard_start)),
+ (int)pkt_len, rxq->buf_len);
+
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool) {
+ skb_mark_for_recycle(skb);
+ return false;
+ }
+#endif
+ if (unlikely(page_to_nid(page) != numa_node_id()))
+ goto umap_page;
+ if (unlikely(page_count(page) != 1))
+ goto umap_page;
+
+ rx_info->page_offset ^= rxq->buf_len;
+ get_page(page);
+
+ return true;
+
+umap_page:
+ dma_unmap_page(rxq->dev, rx_info->buf_dma_addr,
+ rxq->dma_rx_buff_size, DMA_FROM_DEVICE);
+ return false;
+}
+
+static struct sk_buff *hinic3_fetch_rx_buffer_xdp(struct hinic3_rxq *rxq,
+ u32 pkt_len,
+ struct xdp_buff *xdp)
+{
+ struct sk_buff *skb;
+ struct hinic3_rx_info *rx_info;
+ u32 sw_ci;
+ bool reuse;
+
+ sw_ci = rxq->cons_idx & rxq->q_mask;
+ rx_info = &rxq->rx_info[sw_ci];
+
+ skb = netdev_alloc_skb_ip_align(rxq->netdev, HINIC3_RX_HDR_SIZE);
+ if (unlikely(!skb))
+ return NULL;
+
+ reuse = hinic3_add_rx_frag_with_xdp(rxq, pkt_len, rx_info, skb, xdp);
+ if (likely(reuse))
+ hinic3_reuse_rx_page(rxq, rx_info);
+
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+
+ rxq->cons_idx += 1;
+ rxq->delta += 1;
+
+ return skb;
+}
+
#endif
static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_rq_cqe *rx_cqe,
u32 pkt_len, u32 vlan_len, u32 status)
{
- struct sk_buff *skb;
+ struct sk_buff *skb = NULL;
struct net_device *netdev = rxq->netdev;
u32 offload_type;
u16 num_lro;
@@ -812,13 +937,25 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_rq_cqe *rx_cqe,
#ifdef HAVE_XDP_SUPPORT
u32 xdp_status;
+ struct xdp_buff xdp = { 0 };
- xdp_status = hinic3_run_xdp(rxq, pkt_len);
+ xdp_status = (u32)(hinic3_run_xdp(rxq, pkt_len, &xdp));
if (xdp_status == HINIC3_XDP_PKT_DROP)
return 0;
-#endif
+ // build skb
+ if (xdp_status != HINIC3_XDP_PROG_EMPTY) {
+ // xdp_prog configured, build skb with xdp
+ skb = hinic3_fetch_rx_buffer_xdp(rxq, pkt_len, &xdp);
+ } else {
+ // xdp_prog not configured, build skb
+ skb = hinic3_fetch_rx_buffer(rxq, pkt_len);
+ }
+#else
+
+ // xdp is not supported
skb = hinic3_fetch_rx_buffer(rxq, pkt_len);
+#endif
if (unlikely(!skb)) {
RXQ_STATS_INC(rxq, alloc_skb_err);
return -ENOMEM;
@@ -852,7 +989,7 @@ static int recv_one_pkt(struct hinic3_rxq *rxq, struct hinic3_rq_cqe *rx_cqe,
hinic3_copy_lp_data(nic_dev, skb);
num_lro = HINIC3_GET_RX_NUM_LRO(status);
- if (num_lro)
+ if (num_lro > 1)
hinic3_lro_set_gso_params(skb, num_lro);
skb_record_rx_queue(skb, rxq->q_id);
@@ -931,12 +1068,40 @@ int hinic3_rx_poll(struct hinic3_rxq *rxq, int budget)
return pkts;
}
+#ifdef HAVE_PAGE_POOL_SUPPORT
+static struct page_pool *hinic3_create_page_pool(struct hinic3_nic_dev *nic_dev,
+ u32 rq_depth,
+ struct hinic3_rx_info *rx_info_arr)
+{
+ struct page_pool_params pp_params = {
+ .flags = PP_FLAG_DMA_MAP | PP_FLAG_PAGE_FRAG |
+ PP_FLAG_DMA_SYNC_DEV,
+ .order = nic_dev->page_order,
+ .pool_size = rq_depth * nic_dev->rx_buff_len /
+ (PAGE_SIZE << nic_dev->page_order),
+ .nid = dev_to_node(&(nic_dev->pdev->dev)),
+ .dev = &(nic_dev->pdev->dev),
+ .dma_dir = DMA_FROM_DEVICE,
+ .offset = 0,
+ .max_len = PAGE_SIZE << nic_dev->page_order,
+ };
+ struct page_pool *page_pool;
+ int i;
+
+ page_pool = nic_dev->page_pool_enabled ?
+ page_pool_create(&pp_params) : NULL;
+ for (i = 0; i < rq_depth; i++)
+ rx_info_arr[i].page_pool = page_pool;
+ return page_pool;
+}
+#endif
+
int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
u32 rq_depth, struct hinic3_dyna_rxq_res *rxqs_res)
{
struct hinic3_dyna_rxq_res *rqres = NULL;
u64 cqe_mem_size = sizeof(struct hinic3_rq_cqe) * rq_depth;
- int idx, i;
+ int idx;
u32 pkts;
u64 size;
@@ -947,46 +1112,49 @@ int hinic3_alloc_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
if (!rqres->rx_info) {
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx info\n", idx);
- goto err_out;
+ goto err_alloc_rx_info;
}
-
rqres->cqe_start_vaddr =
dma_zalloc_coherent(&nic_dev->pdev->dev, cqe_mem_size,
&rqres->cqe_start_paddr,
GFP_KERNEL);
if (!rqres->cqe_start_vaddr) {
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d cqe\n", idx);
- goto err_out;
+ goto err_alloc_cqe;
}
-
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ rqres->page_pool = hinic3_create_page_pool(nic_dev, rq_depth,
+ rqres->rx_info);
+ if (nic_dev->page_pool_enabled && !rqres->page_pool) {
+ nicif_err(nic_dev, drv, nic_dev->netdev,
+ "Failed to create rxq%d page pool\n", idx);
+ goto err_create_page_pool;
+ }
+#endif
pkts = hinic3_rx_alloc_buffers(nic_dev, rq_depth,
rqres->rx_info);
if (!pkts) {
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- kfree(rqres->rx_info);
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc rxq%d rx buffers\n", idx);
- goto err_out;
+ goto err_alloc_buffers;
}
rqres->next_to_alloc = (u16)pkts;
}
return 0;
-err_out:
- for (i = 0; i < idx; i++) {
- rqres = &rxqs_res[i];
-
- hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
- dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
- rqres->cqe_start_vaddr,
- rqres->cqe_start_paddr);
- kfree(rqres->rx_info);
- }
-
+err_alloc_buffers:
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ page_pool_destroy(rqres->page_pool);
+err_create_page_pool:
+#endif
+ dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
+ rqres->cqe_start_vaddr,
+ rqres->cqe_start_paddr);
+err_alloc_cqe:
+ kfree(rqres->rx_info);
+err_alloc_rx_info:
+ hinic3_free_rxqs_res(nic_dev, idx, rq_depth, rxqs_res);
return -ENOMEM;
}
@@ -1001,6 +1169,10 @@ void hinic3_free_rxqs_res(struct hinic3_nic_dev *nic_dev, u16 num_rq,
rqres = &rxqs_res[idx];
hinic3_rx_free_buffers(nic_dev, rq_depth, rqres->rx_info);
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rqres->page_pool)
+ page_pool_destroy(rqres->page_pool);
+#endif
dma_free_coherent(&nic_dev->pdev->dev, cqe_mem_size,
rqres->cqe_start_vaddr,
rqres->cqe_start_paddr);
@@ -1084,6 +1256,7 @@ void hinic3_free_rxqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->rxqs);
+ nic_dev->rxqs = NULL;
}
int hinic3_alloc_rxqs(struct net_device *netdev)
@@ -1207,6 +1380,15 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
nic_info(&nic_dev->pdev->dev, "rxq %u restore_buf_num:%u\n", q_id, rxq->restore_buf_num);
rx_info = &rxq->rx_info[(hw_ci + rxq->q_depth - 1) & rxq->q_mask];
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ if (rx_info->page_pool && rx_info->page) {
+ page_pool_put_full_page(rx_info->page_pool,
+ rx_info->page, false);
+ rx_info->buf_dma_addr = 0;
+ rx_info->page = NULL;
+ goto reset_rxq;
+ }
+#endif
if (rx_info->buf_dma_addr) {
dma_unmap_page(&nic_dev->pdev->dev, rx_info->buf_dma_addr,
nic_dev->dma_rx_buff_size, DMA_FROM_DEVICE);
@@ -1217,7 +1399,9 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
__free_pages(rx_info->page, nic_dev->page_order);
rx_info->page = NULL;
}
+ goto reset_rxq;
+reset_rxq:
rxq->delta = 1;
rxq->next_to_update = (u16)((hw_ci + rxq->q_depth - 1) & rxq->q_mask);
rxq->cons_idx = (u16)((rxq->next_to_update + 1) & rxq->q_mask);
@@ -1238,15 +1422,10 @@ int rxq_restore(struct hinic3_nic_dev *nic_dev, u16 q_id, u16 hw_ci)
return err;
}
- if (!rq_pi_rd_en) {
- hinic3_write_db(rxq->rq, rxq->q_id & (NIC_DCB_COS_MAX - 1),
- RQ_CFLAG_DP, (u16)((u32)rxq->next_to_update << rxq->rq->wqe_type));
- } else {
- /* Write all the wqes before pi update */
- wmb();
+ hinic3_write_db(rxq->rq, rxq->q_id & (NIC_DCB_COS_MAX - 1),
+ RQ_CFLAG_DP,
+ (u16)((u32)rxq->next_to_update << rxq->rq->wqe_type));
- hinic3_update_rq_hw_pi(rxq->rq, rxq->next_to_update);
- }
return 0;
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
index f4d6f4f..7dd4618 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.h
@@ -4,6 +4,9 @@
#ifndef HINIC3_RX_H
#define HINIC3_RX_H
+#ifdef HAVE_PAGE_POOL_SUPPORT
+#include <net/page_pool.h>
+#endif
#include <linux/types.h>
#include <linux/device.h>
#include <linux/mm_types.h>
@@ -27,22 +30,22 @@
#define HINIC3_RX_CSUM_IPSU_OTHER_ERR BIT(8)
#define HINIC3_HEADER_DATA_UNIT 2
+#define HINIC3_CQE_LEN 32
struct hinic3_rxq_stats {
- u64 packets;
- u64 bytes;
- u64 errors;
- u64 csum_errors;
- u64 other_errors;
- u64 dropped;
- u64 xdp_dropped;
- u64 rx_buf_empty;
-
- u64 alloc_skb_err;
- u64 alloc_rx_buf_err;
- u64 xdp_large_pkt;
- u64 restore_drop_sge;
- u64 rsvd2;
+ u64 packets;
+ u64 bytes;
+ u64 errors;
+ u64 csum_errors;
+ u64 other_errors;
+ u64 dropped;
+ u64 xdp_dropped;
+ u64 rx_buf_empty;
+ u64 alloc_skb_err;
+ u64 alloc_rx_buf_err;
+ u64 xdp_large_pkt;
+ u64 restore_drop_sge;
+ u64 rsvd2;
#ifdef HAVE_NDO_GET_STATS64
struct u64_stats_sync syncp;
#else
@@ -56,6 +59,9 @@ struct hinic3_rx_info {
struct hinic3_rq_cqe *cqe;
dma_addr_t cqe_dma;
struct page *page;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
u32 page_offset;
u32 rsvd1;
struct hinic3_rq_wqe *rq_wqe;
@@ -96,7 +102,7 @@ struct hinic3_rxq {
u16 next_to_update;
struct device *dev; /* device for DMA mapping */
- unsigned long status;
+ u64 status;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
@@ -124,6 +130,9 @@ struct hinic3_dyna_rxq_res {
struct hinic3_rx_info *rx_info;
dma_addr_t cqe_start_paddr;
void *cqe_start_vaddr;
+#ifdef HAVE_PAGE_POOL_SUPPORT
+ struct page_pool *page_pool;
+#endif
};
int hinic3_alloc_rxqs(struct net_device *netdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
index bdd5a8e..051f05d 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_srv_nic.h
@@ -11,9 +11,10 @@
#ifndef HINIC3_SRV_NIC_H
#define HINIC3_SRV_NIC_H
-#include "hinic3_mgmt_interface.h"
+#include <linux/netdevice.h>
+#include "nic_mpu_cmd_defs.h"
#include "mag_mpu_cmd.h"
-#include "mag_cmd.h"
+#include "mag_mpu_cmd_defs.h"
#include "hinic3_lld.h"
enum hinic3_queue_type {
@@ -64,6 +65,7 @@ enum hinic3_nic_event_type {
EVENT_NIC_DCB_STATE_CHANGE,
EVENT_NIC_BOND_DOWN,
EVENT_NIC_BOND_UP,
+ EVENT_NIC_OUTBAND_CFG,
};
/* *
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
index e958782..d3f8696 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c
@@ -218,6 +218,77 @@ static void get_inner_l4_info(struct sk_buff *skb, union hinic3_l4 *l4,
}
}
+static void get_inner_l3_l4_type(struct sk_buff *skb, union hinic3_ip *ip,
+ union hinic3_l4 *l4,
+ enum sq_l3_type *l3_type, u8 *l4_proto)
+{
+ unsigned char *exthdr = NULL;
+
+ if (ip->v4->version == IP4_VERSION) {
+ *l3_type = IPV4_PKT_WITH_CHKSUM_OFFLOAD;
+ *l4_proto = ip->v4->protocol;
+
+#ifdef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
+ /* inner_transport_header is wrong in centos7.0 and suse12.1 */
+ l4->hdr = ip->hdr + ((u8)ip->v4->ihl << IP_HDR_IHL_UNIT_SHIFT);
+#endif
+ } else if (ip->v4->version == IP6_VERSION) {
+ *l3_type = IPV6_PKT;
+ exthdr = ip->hdr + sizeof(*ip->v6);
+ *l4_proto = ip->v6->nexthdr;
+ if (exthdr != l4->hdr) {
+ __be16 frag_off = 0;
+#ifndef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
+ ipv6_skip_exthdr(skb, (int)(exthdr - skb->data),
+ l4_proto, &frag_off);
+#else
+ int pld_off = 0;
+
+ pld_off = ipv6_skip_exthdr(skb,
+ (int)(exthdr - skb->data),
+ l4_proto, &frag_off);
+ l4->hdr = skb->data + pld_off;
+#endif
+ }
+ } else {
+ *l3_type = UNKNOWN_L3TYPE;
+ *l4_proto = 0;
+ }
+}
+
+static u8 hinic3_get_inner_l4_type(struct sk_buff *skb)
+{
+ enum sq_l3_type l3_type;
+ u8 l4_proto;
+ union hinic3_ip ip;
+ union hinic3_l4 l4;
+
+ ip.hdr = skb_inner_network_header(skb);
+ l4.hdr = skb_inner_transport_header(skb);
+
+ get_inner_l3_l4_type(skb, &ip, &l4, &l3_type, &l4_proto);
+ return l4_proto;
+}
+
+static void hinic3_set_unknown_tunnel_csum(struct sk_buff *skb)
+{
+ int csum_offset;
+ __sum16 skb_csum;
+ u8 l4_proto;
+
+ l4_proto = hinic3_get_inner_l4_type(skb);
+ /* Unsupport tunnel packet, disable csum offload */
+ skb_checksum_help(skb);
+ /* The value of csum is changed from 0xffff to 0 according to RFC1624 */
+ if (skb->ip_summed == CHECKSUM_NONE && l4_proto != IPPROTO_UDP) {
+ csum_offset = skb_checksum_start_offset(skb) + skb->csum_offset;
+ skb_csum = *(__sum16 *)(skb->data + csum_offset);
+ if (skb_csum == 0xffff) {
+ *(__sum16 *)(skb->data + csum_offset) = 0;
+ }
+ }
+}
+
static int hinic3_tx_csum(struct hinic3_txq *txq, struct hinic3_sq_task *task,
struct sk_buff *skb)
{
@@ -251,11 +322,9 @@ static int hinic3_tx_csum(struct hinic3_txq *txq, struct hinic3_sq_task *task,
l4_proto = IPPROTO_RAW;
}
- if (l4_proto != IPPROTO_UDP ||
- ((struct udphdr *)skb_transport_header(skb))->dest != VXLAN_OFFLOAD_PORT_LE) {
+ if (l4_proto != IPPROTO_UDP) {
TXQ_STATS_INC(txq, unknown_tunnel_pkt);
- /* Unsupport tunnel packet, disable csum offload */
- skb_checksum_help(skb);
+ hinic3_set_unknown_tunnel_csum(skb);
return 0;
}
}
@@ -265,44 +334,6 @@ static int hinic3_tx_csum(struct hinic3_txq *txq, struct hinic3_sq_task *task,
return 1;
}
-static void get_inner_l3_l4_type(struct sk_buff *skb, union hinic3_ip *ip,
- union hinic3_l4 *l4,
- enum sq_l3_type *l3_type, u8 *l4_proto)
-{
- unsigned char *exthdr = NULL;
-
- if (ip->v4->version == IP4_VERSION) {
- *l3_type = IPV4_PKT_WITH_CHKSUM_OFFLOAD;
- *l4_proto = ip->v4->protocol;
-
-#ifdef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
- /* inner_transport_header is wrong in centos7.0 and suse12.1 */
- l4->hdr = ip->hdr + ((u8)ip->v4->ihl << IP_HDR_IHL_UNIT_SHIFT);
-#endif
- } else if (ip->v4->version == IP6_VERSION) {
- *l3_type = IPV6_PKT;
- exthdr = ip->hdr + sizeof(*ip->v6);
- *l4_proto = ip->v6->nexthdr;
- if (exthdr != l4->hdr) {
- __be16 frag_off = 0;
-#ifndef HAVE_OUTER_IPV6_TUNNEL_OFFLOAD
- ipv6_skip_exthdr(skb, (int)(exthdr - skb->data),
- l4_proto, &frag_off);
-#else
- int pld_off = 0;
-
- pld_off = ipv6_skip_exthdr(skb,
- (int)(exthdr - skb->data),
- l4_proto, &frag_off);
- l4->hdr = skb->data + pld_off;
-#endif
- }
- } else {
- *l3_type = UNKNOWN_L3TYPE;
- *l4_proto = 0;
- }
-}
-
static void hinic3_set_tso_info(struct hinic3_sq_task *task, u32 *queue_info,
enum sq_l4offload_type l4_offload,
u32 offset, u32 mss)
@@ -463,7 +494,8 @@ static void get_pkt_stats(struct hinic3_tx_info *tx_info, struct sk_buff *skb)
#endif
} else {
#endif
- ihs = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ ihs = (u32)(skb_transport_offset(skb)) +
+ tcp_hdrlen(skb);
#if (defined(HAVE_SKB_INNER_TRANSPORT_HEADER) && \
defined(HAVE_SK_BUFF_ENCAPSULATION))
}
@@ -471,7 +503,8 @@ static void get_pkt_stats(struct hinic3_tx_info *tx_info, struct sk_buff *skb)
hdr_len = (skb_shinfo(skb)->gso_segs - 1) * ihs;
tx_info->num_bytes = skb->len + (u64)hdr_len;
} else {
- tx_info->num_bytes = skb->len > ETH_ZLEN ? skb->len : ETH_ZLEN;
+ tx_info->num_bytes = (skb->len > ETH_ZLEN) ?
+ skb->len : ETH_ZLEN;
}
tx_info->num_pkts = 1;
@@ -626,6 +659,14 @@ static netdev_tx_t hinic3_send_one_skb(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
+ /* l2nic outband vlan cfg enable */
+ if ((!skb_vlan_tag_present(skb)) &&
+ (nic_dev->nic_cap.outband_vlan_cfg_en == 1) &&
+ nic_dev->outband_cfg.outband_default_vid != 0) {
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+ (u16)nic_dev->outband_cfg.outband_default_vid);
+ }
+
offload = hinic3_tx_offload(skb, &task, &queue_info, txq);
if (unlikely(offload == TX_OFFLOAD_INVALID)) {
TXQ_STATS_INC(txq, offload_cow_skb_err);
@@ -834,6 +875,7 @@ int hinic3_alloc_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
tqres->bds = kzalloc(size, GFP_KERNEL);
if (!tqres->bds) {
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
nicif_err(nic_dev, drv, nic_dev->netdev,
"Failed to alloc txq%d bds info\n", idx);
goto err_out;
@@ -847,7 +889,9 @@ err_out:
tqres = &txqs_res[i];
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
return -ENOMEM;
@@ -864,7 +908,9 @@ void hinic3_free_txqs_res(struct hinic3_nic_dev *nic_dev, u16 num_sq,
free_all_tx_skbs(nic_dev, sq_depth, tqres->tx_info);
kfree(tqres->bds);
+ tqres->bds = NULL;
kfree(tqres->tx_info);
+ tqres->tx_info = NULL;
}
}
@@ -938,6 +984,7 @@ void hinic3_free_txqs(struct net_device *netdev)
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
kfree(nic_dev->txqs);
+ nic_dev->txqs = NULL;
}
static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
@@ -954,7 +1001,7 @@ static bool is_hw_complete_sq_process(struct hinic3_io_queue *sq)
static int hinic3_stop_sq(struct hinic3_txq *txq)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(txq->netdev);
- unsigned long timeout;
+ u64 timeout;
int err;
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -963,7 +1010,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
return 0;
usleep_range(900, 1000); /* sleep 900 us ~ 1000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* force hardware to drop packets */
timeout = msecs_to_jiffies(HINIC3_FLUSH_QUEUE_TIMEOUT) + jiffies;
@@ -976,7 +1023,7 @@ static int hinic3_stop_sq(struct hinic3_txq *txq)
break;
usleep_range(9900, 10000); /* sleep 9900 us ~ 10000 us */
- } while (time_before(jiffies, timeout));
+ } while (time_before(jiffies, (unsigned long)timeout));
/* Avoid msleep takes too long and get a fake result */
if (is_hw_complete_sq_process(txq->sq))
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
index 1b9e509..7ae029b 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_wq.h
@@ -29,7 +29,7 @@ struct hinic3_wq {
#define WQ_MASK_IDX(wq, idx) ((idx) & (wq)->idx_mask)
#define WQ_MASK_PAGE(wq, pg_idx) \
- ((pg_idx) < (wq)->num_wq_pages ? (pg_idx) : 0)
+ (((pg_idx) < ((wq)->num_wq_pages)) ? (pg_idx) : 0)
#define WQ_PAGE_IDX(wq, idx) ((idx) >> (wq)->wqebbs_per_page_shift)
#define WQ_OFFSET_IN_PAGE(wq, idx) ((idx) & (wq)->wqebbs_per_page_mask)
#define WQ_GET_WQEBB_ADDR(wq, pg_idx, idx_in_pg) \
@@ -75,7 +75,7 @@ static inline void *hinic3_wq_get_multi_wqebbs(struct hinic3_wq *wq,
pg_idx = WQ_PAGE_IDX(wq, *prod_idx);
off_in_page = WQ_OFFSET_IN_PAGE(wq, *prod_idx);
- if (off_in_page + num_wqebbs > wq->wqebbs_per_page) {
+ if ((off_in_page + num_wqebbs) > wq->wqebbs_per_page) {
/* wqe across wq page boundary */
*second_part_wqebbs_addr =
WQ_GET_WQEBB_ADDR(wq, WQ_MASK_PAGE(wq, pg_idx + 1), 0);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
index b742f8a..0419fc2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_api_cmd.c
@@ -400,12 +400,16 @@ static int wait_for_status_poll(struct hinic3_api_cmd_chain *chain)
API_CMD_STATUS_TIMEOUT, 100); /* wait 100 us once */
}
-static void copy_resp_data(struct hinic3_api_cmd_cell_ctxt *ctxt, void *ack,
- u16 ack_size)
+static void copy_resp_data(struct hinic3_api_cmd_chain *chain,
+ struct hinic3_api_cmd_cell_ctxt *ctxt,
+ void *ack, u16 ack_size)
{
struct hinic3_api_cmd_resp_fmt *resp = ctxt->resp;
+ int rsp_size_align = chain->rsp_size_align - 0x8;
+ int rsp_size = (ack_size > rsp_size_align) ? rsp_size_align : ack_size;
+
+ memcpy(ack, &resp->resp_data, rsp_size);
- memcpy(ack, &resp->resp_data, ack_size);
ctxt->status = 0;
}
@@ -464,7 +468,7 @@ static int wait_for_api_cmd_completion(struct hinic3_api_cmd_chain *chain,
case HINIC3_API_CMD_POLL_READ:
err = wait_for_resp_polling(ctxt);
if (err == 0)
- copy_resp_data(ctxt, ack, ack_size);
+ copy_resp_data(chain, ctxt, ack, ack_size);
else
sdk_err(dev, "API CMD poll response timeout\n");
break;
@@ -1055,13 +1059,11 @@ alloc_cells_buf_err:
alloc_wb_status_err:
kfree(chain->cell_ctxt);
-/*lint -save -e548*/
alloc_cell_ctxt_err:
if (chain->chain_type == HINIC3_API_CMD_WRITE_ASYNC_TO_MGMT_CPU)
spin_lock_deinit(&chain->async_lock);
else
sema_deinit(&chain->sem);
-/*lint -restore*/
return err;
}
@@ -1078,6 +1080,7 @@ static void api_chain_free(struct hinic3_api_cmd_chain *chain)
dma_free_coherent(dev, sizeof(*chain->wb_status),
chain->wb_status, chain->wb_status_paddr);
kfree(chain->cell_ctxt);
+ chain->cell_ctxt = NULL;
if (chain->chain_type == HINIC3_API_CMD_WRITE_ASYNC_TO_MGMT_CPU)
spin_lock_deinit(&chain->async_lock);
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
index 0878186..ceb7636 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.c
@@ -657,7 +657,7 @@ static int cmdq_sync_cmd_direct_resp(struct hinic3_cmdq *cmdq, u8 mod,
cmd_info->channel = channel;
cmdq_set_cmd_buf(cmd_info, cmdq->hwdev, buf_in, NULL);
- memcpy(&saved_cmd_info, cmd_info, sizeof(*cmd_info));
+ memcpy(&saved_cmd_info, cmd_info, sizeof(struct hinic3_cmdq_cmd_info));
cmdq_set_lcmd_wqe(&wqe, SYNC_CMD_DIRECT_RESP, buf_in, NULL,
wrapped, mod, cmd, curr_prod_idx);
@@ -745,7 +745,7 @@ static int cmdq_sync_cmd_detail_resp(struct hinic3_cmdq *cmdq, u8 mod, u8 cmd,
cmd_info->channel = channel;
cmdq_set_cmd_buf(cmd_info, cmdq->hwdev, buf_in, buf_out);
- memcpy(&saved_cmd_info, cmd_info, sizeof(*cmd_info));
+ memcpy(&saved_cmd_info, cmd_info, sizeof(struct hinic3_cmdq_cmd_info));
cmdq_set_lcmd_wqe(&wqe, SYNC_CMD_SGE_RESP, buf_in, buf_out,
wrapped, mod, cmd, curr_prod_idx);
@@ -994,9 +994,11 @@ int hinic3_cmdq_async(void *hwdev, u8 mod, u8 cmd, struct hinic3_cmd_buf *buf_in
return cmdq_async_cmd(&cmdqs->cmdq[HINIC3_CMDQ_SYNC], mod,
cmd, buf_in, channel);
}
+EXPORT_SYMBOL(hinic3_cmdq_async);
int hinic3_cmdq_async_cos(void *hwdev, u8 mod, u8 cmd,
- u8 cos_id, struct hinic3_cmd_buf *buf_in, u16 channel)
+ u8 cos_id, struct hinic3_cmd_buf *buf_in,
+ u16 channel)
{
struct hinic3_cmdqs *cmdqs = NULL;
int err;
@@ -1136,7 +1138,7 @@ void hinic3_cmdq_ceq_handler(void *handle, u32 ceqe_data)
break;
case HINIC3_CMD_TYPE_SET_ARM:
/* arm_bit was set until here */
- if (cmdq_arm_ceq_handler(cmdq, wqe, ci))
+ if (cmdq_arm_ceq_handler(cmdq, wqe, ci) != 0)
return;
break;
default:
@@ -1221,6 +1223,7 @@ cmd_infos_err:
static void free_cmdq(struct hinic3_cmdq *cmdq)
{
kfree(cmdq->cmd_infos);
+ cmdq->cmd_infos = NULL;
spin_lock_deinit(&cmdq->cmdq_lock);
}
@@ -1425,7 +1428,7 @@ static int create_cmdq_wq(struct hinic3_cmdqs *cmdqs)
type = HINIC3_CMDQ_SYNC;
for (; type < cmdqs->cmdq_num; type++)
memcpy((u8 *)cmdqs->wq_block_vaddr +
- CMDQ_WQ_CLA_SIZE * type,
+ ((u64)type * CMDQ_WQ_CLA_SIZE),
cmdqs->cmdq[type].wq.wq_block_vaddr,
cmdqs->cmdq[type].wq.num_wq_pages * sizeof(u64));
}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
index b0344ea..b174ad2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_cmdq.h
@@ -14,11 +14,6 @@
#include "hinic3_common.h"
#include "hinic3_hwdev.h"
-struct dma_pool {
- unsigned int size;
- void *dev_hdl;
-};
-
#define HINIC3_SCMD_DATA_LEN 16
#define HINIC3_CMDQ_DEPTH 4096
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
index 4c13a2e..af336f2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.c
@@ -22,11 +22,15 @@
#include "hinic3_sriov.h"
#include "hinic3_nictool.h"
#include "hinic3_pci_id_tbl.h"
+#include "hinic3_hwdev.h"
+#include "cfg_mgmt_mpu_cmd_defs.h"
+#include "mpu_cmd_base_defs.h"
#include "hinic3_dev_mgmt.h"
#define HINIC3_WAIT_TOOL_CNT_TIMEOUT 10000
#define HINIC3_WAIT_TOOL_MIN_USLEEP_TIME 9900
#define HINIC3_WAIT_TOOL_MAX_USLEEP_TIME 10000
+#define HIGHT_BDF 8
static unsigned long card_bit_map;
@@ -60,15 +64,23 @@ void lld_dev_cnt_init(struct hinic3_pcidev *pci_adapter)
void lld_dev_hold(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_inc(&pci_adapter->ref_cnt);
}
void lld_dev_put(struct hinic3_lld_dev *dev)
{
- struct hinic3_pcidev *pci_adapter = pci_get_drvdata(dev->pdev);
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!dev)
+ return;
+ pci_adapter = pci_get_drvdata(dev->pdev);
atomic_dec(&pci_adapter->ref_cnt);
}
@@ -236,6 +248,40 @@ void hinic3_get_all_chip_id(void *id_info)
card_id->num = (u32)i;
}
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+ u64 bar1_phy_addr = 0;
+ u64 bar3_phy_addr = 0;
+ u64 bar1_size = 0;
+ u64 bar3_size = 0;
+
+ lld_hold();
+
+ /* get PF bar1 or bar3 physical address to verify */
+ list_for_each_entry(chip_node, &g_hinic3_chip_list, node) {
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (hinic3_func_type(dev->hwdev) == TYPE_VF)
+ continue;
+
+ bar1_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+ bar1_size = pci_resource_len(dev->pcidev, HINIC3_PF_PCI_CFG_REG_BAR);
+
+ bar3_phy_addr = pci_resource_start(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ bar3_size = pci_resource_len(dev->pcidev, HINIC3_PCI_MGMT_REG_BAR);
+ if ((phy_addr == bar1_phy_addr && vmsize <= bar1_size) ||
+ (phy_addr == bar3_phy_addr && vmsize <= bar3_size)) {
+ lld_put();
+ return 0;
+ }
+ }
+ }
+
+ lld_put();
+ return -EINVAL;
+}
+
void hinic3_get_card_func_info_by_card_name(const char *chip_name,
struct hinic3_card_func_info *card_func)
{
@@ -328,7 +374,6 @@ out:
if (dev)
lld_dev_hold(dev);
lld_put();
-
return dev;
}
@@ -422,6 +467,28 @@ struct hinic3_lld_dev *hinic3_get_lld_dev_by_chip_and_port(const char *chip_name
return NULL;
}
+void *hinic3_get_ppf_dev(void)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct list_head *chip_list = NULL;
+
+ lld_hold();
+ chip_list = get_hinic3_chip_list();
+
+ list_for_each_entry(chip_node, chip_list, node)
+ list_for_each_entry(pci_adapter, &chip_node->func_list, node)
+ if (hinic3_func_type(pci_adapter->hwdev) == TYPE_PPF) {
+ pr_info("Get ppf_func_id:%u", hinic3_global_func_id(pci_adapter->hwdev));
+ lld_put();
+ return pci_adapter->lld_dev.hwdev;
+ }
+
+ lld_put();
+ return NULL;
+}
+EXPORT_SYMBOL(hinic3_get_ppf_dev);
+
struct hinic3_lld_dev *hinic3_get_lld_dev_by_dev_name(const char *dev_name,
enum hinic3_service_type type)
{
@@ -518,6 +585,7 @@ EXPORT_SYMBOL(hinic3_get_ppf_lld_dev_unsafe);
int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 max_len)
{
struct hinic3_pcidev *pci_adapter = NULL;
+ int ret = 0;
if (!lld_dev || !chip_name || !max_len)
return -EINVAL;
@@ -527,12 +595,18 @@ int hinic3_get_chip_name(struct hinic3_lld_dev *lld_dev, char *chip_name, u16 ma
return -EFAULT;
lld_hold();
- strncpy(chip_name, pci_adapter->chip_node->chip_name, max_len);
+ if (strscpy(chip_name, pci_adapter->chip_node->chip_name, max_len) < 0)
+ goto RELEASE;
chip_name[max_len - 1] = '\0';
lld_put();
return 0;
+
+RELEASE:
+ lld_put();
+
+ return ret;
}
EXPORT_SYMBOL(hinic3_get_chip_name);
@@ -541,6 +615,81 @@ struct hinic3_hwdev *hinic3_get_sdk_hwdev_by_lld(struct hinic3_lld_dev *lld_dev)
return lld_dev->hwdev;
}
+void hinic3_write_oshr_info(struct os_hot_replace_info *out_oshr_info,
+ struct hw_pf_info *info,
+ struct hinic3_board_info *board_info,
+ struct card_node *chip_node, u32 serivce_enable,
+ u32 func_info_idx)
+{
+ out_oshr_info->func_infos[func_info_idx].pf_idx = info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].backup_pf =
+ (((info->glb_func_idx) / (board_info->port_num)) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ ((info->glb_func_idx) + (board_info->port_num)) :
+ ((info->glb_func_idx) - (board_info->port_num));
+ out_oshr_info->func_infos[func_info_idx].partition =
+ ((info->glb_func_idx) / (board_info->port_num)) % HOT_REPLACE_PARTITION_NUM;
+ out_oshr_info->func_infos[func_info_idx].port_id = info->port_id;
+ out_oshr_info->func_infos[func_info_idx].bdf = (info->bus_num << HIGHT_BDF) + info->glb_func_idx;
+ out_oshr_info->func_infos[func_info_idx].bus_num = chip_node->bus_num;
+ out_oshr_info->func_infos[func_info_idx].valid = serivce_enable;
+ memcpy(out_oshr_info->func_infos[func_info_idx].card_name,
+ chip_node->chip_name, IFNAMSIZ);
+}
+
+void hinic3_get_os_hot_replace_info(void *oshr_info)
+{
+ struct os_hot_replace_info *out_oshr_info = (struct os_hot_replace_info *)oshr_info;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dst_dev = NULL;
+ struct hinic3_board_info *board_info = NULL;
+ struct hw_pf_info *infos = NULL;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ u32 func_info_idx = 0, func_id = 0, func_num, serivce_enable = 0;
+ struct list_head *hinic3_chip_list = get_hinic3_chip_list();
+ int err;
+
+ lld_hold();
+ pf_infos = kzalloc(sizeof(struct hinic3_hw_pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ pr_err("kzalloc pf_infos fail\n");
+ lld_put();
+ return;
+ }
+ list_for_each_entry(chip_node, hinic3_chip_list, node) {
+ list_for_each_entry(dst_dev, &chip_node->func_list, node) { // get all pf infos in one time by one pf_id
+ err = hinic3_get_hw_pf_infos(dst_dev->hwdev, pf_infos, HINIC3_CHANNEL_COMM);
+ if (err != 0) {
+ pr_err("get pf info failed\n");
+ break;
+ }
+
+ serivce_enable = 0;
+ infos = pf_infos->infos;
+ board_info = &((struct hinic3_hwdev *)(dst_dev->hwdev))->board_info;
+ if (((struct hinic3_hwdev *)(dst_dev->hwdev))->hot_replace_mode == HOT_REPLACE_ENABLE) {
+ serivce_enable = 1;
+ }
+ break;
+ }
+
+ func_num = pf_infos->num_pfs;
+ if (func_num <= 0) {
+ pr_err("get pf num failed\n");
+ break;
+ }
+
+ for (func_id = 0; func_id < func_num; func_id++) {
+ hinic3_write_oshr_info(out_oshr_info, &infos[func_id],
+ board_info, chip_node,
+ serivce_enable, func_info_idx);
+ func_info_idx++;
+ }
+ }
+ out_oshr_info->func_cnt = func_info_idx;
+ kfree(pf_infos);
+ lld_put();
+}
+
struct card_node *hinic3_get_chip_node_by_lld(struct hinic3_lld_dev *lld_dev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(lld_dev->pdev);
@@ -620,9 +769,13 @@ void hinic3_get_card_info(const void *hwdev, void *bufin)
}
if (hinic3_func_for_mgmt(fun_hwdev))
- strlcpy(info->pf[i].name, "FOR_MGMT", IFNAMSIZ);
+ strscpy(info->pf[i].name, "FOR_MGMT", IFNAMSIZ);
+
+ if (dev->lld_dev.pdev->subsystem_device == BIFUR_RESOURCE_PF_SSID) {
+ strscpy(info->pf[i].name, "bifur", IFNAMSIZ);
+ }
- strlcpy(info->pf[i].bus_info, pci_name(dev->pcidev),
+ strscpy(info->pf[i].bus_info, pci_name(dev->pcidev),
sizeof(info->pf[i].bus_info));
info->pf_num++;
i = info->pf_num;
@@ -719,6 +872,7 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
struct card_node *chip_node = NULL;
unsigned char i;
unsigned char bus_number = 0;
+ int err;
if (chip_node_is_exist(pci_adapter, &bus_number))
return 0;
@@ -750,6 +904,13 @@ int alloc_chip_node(struct hinic3_pcidev *pci_adapter)
return -EINVAL;
}
+ err = sscanf(chip_node->chip_name, HINIC3_CHIP_NAME "%d", &(chip_node->chip_id));
+ if (err <= 0) {
+ clear_bit(i, &card_bit_map);
+ kfree(chip_node);
+ return -EINVAL;
+ }
+
sdk_info(&pci_adapter->pcidev->dev,
"Add new chip %s to global list succeed\n",
chip_node->chip_name);
@@ -801,3 +962,36 @@ int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *
return 0;
}
+
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin)
+{
+ struct card_node *chip_node = NULL;
+ struct card_mbox_cnt_info *info = (struct card_mbox_cnt_info *)bufin;
+ struct hinic3_pcidev *dev = NULL;
+ struct hinic3_hwdev *func_hwdev = NULL;
+ u32 i = 0;
+
+ info->func_num = 0;
+ chip_node = hinic3_get_chip_node_by_hwdev(hwdev);
+ if (chip_node == NULL)
+ return;
+
+ lld_hold();
+
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ func_hwdev = (struct hinic3_hwdev *)dev->hwdev;
+ strscpy(info->func_info[i].bus_info, pci_name(dev->pcidev),
+ sizeof(info->func_info[i].bus_info));
+
+ info->func_info[i].send_cnt = func_hwdev->mbox_send_cnt;
+ info->func_info[i].ack_cnt = func_hwdev->mbox_ack_cnt;
+ info->func_num++;
+ i = info->func_num;
+ if (i >= ARRAY_SIZE(info->func_info)) {
+ sdk_err(&dev->pcidev->dev, "chip_node->func_list bigger than pf_max + vf_max\n");
+ break;
+ }
+ }
+
+ lld_put();
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
index a327c4a..bfa8f3e 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_dev_mgmt.h
@@ -19,8 +19,10 @@
#define PRINT_ULD_DETACH_TIMEOUT_INTERVAL 1000 /* 1 second */
#define ULD_LOCK_MIN_USLEEP_TIME 900
#define ULD_LOCK_MAX_USLEEP_TIME 1000
+#define BIFUR_RESOURCE_PF_SSID 0x05a1
-#define HINIC3_IS_VF_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_VF)
+#define HINIC3_IS_VF_DEV(pdev) ((pdev)->device == HINIC3_DEV_ID_VF || \
+ (pdev)->device == HINIC3_DEV_SDI_5_1_ID_VF)
#define HINIC3_IS_SPU_DEV(pdev) \
(((pdev)->device == HINIC3_DEV_ID_SPU) || ((pdev)->device == HINIC3_DEV_ID_SDI_5_0_PF) || \
(((pdev)->device == HINIC3_DEV_ID_DPU_PF)))
@@ -79,6 +81,13 @@ struct hinic3_pcidev {
u16 probe_fault_level;
u16 rsvd2;
u64 rsvd4;
+
+ struct workqueue_struct *multi_host_mgmt_workq;
+ struct work_struct slave_nic_work;
+ struct work_struct slave_vroce_work;
+
+ struct workqueue_struct *migration_probe_workq;
+ struct delayed_work migration_probe_dwork;
};
struct hinic_chip_info {
@@ -104,4 +113,6 @@ void wait_lld_dev_unused(struct hinic3_pcidev *pci_adapter);
void *hinic3_get_hwdev_by_pcidev(struct pci_dev *pdev);
+int hinic3_bar_mmap_param_valid(phys_addr_t phy_addr, unsigned long vmsize);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
index 1949ab8..8f9d00a 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_devlink.c
@@ -101,7 +101,8 @@ static bool check_image_device_type(struct hinic3_hwdev *hwdev, u32 device_type)
static void encapsulate_update_cmd(struct hinic3_cmd_update_firmware *msg,
struct firmware_section *section_info,
- int *remain_len, u32 *send_len, u32 *send_pos)
+ const int *remain_len, u32 *send_len,
+ u32 *send_pos)
{
memset(msg->data, 0, sizeof(msg->data));
msg->ctl_info.sf = (*remain_len == section_info->section_len) ? true : false;
@@ -380,6 +381,7 @@ int hinic3_init_devlink(struct hinic3_hwdev *hwdev)
struct pci_dev *pdev = NULL;
int err;
+ pdev = hwdev->hwif->pdev;
devlink = devlink_alloc(&hinic3_devlink_ops, sizeof(struct hinic3_devlink));
if (!devlink) {
sdk_err(hwdev->dev_hdl, "Failed to alloc devlink\n");
@@ -391,7 +393,6 @@ int hinic3_init_devlink(struct hinic3_hwdev *hwdev)
hwdev->devlink_dev->activate_fw = FW_CFG_DEFAULT_INDEX;
hwdev->devlink_dev->switch_cfg = FW_CFG_DEFAULT_INDEX;
- pdev = hwdev->hwif->pdev;
err = devlink_register(devlink, &pdev->dev);
if (err) {
sdk_err(hwdev->dev_hdl, "Failed to register devlink\n");
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
index 4b08aa0..caa99e3 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_eqs.c
@@ -26,6 +26,8 @@
#include "hinic3_prof_adap.h"
#include "hinic3_eqs.h"
+#include "vram_common.h"
+
#define HINIC3_EQS_WQ_NAME "hinic3_eqs"
#define AEQ_CTRL_0_INTR_IDX_SHIFT 0
@@ -66,7 +68,6 @@
#define HINIC3_TASK_PROCESS_EQE_LIMIT 1024
#define HINIC3_EQ_UPDATE_CI_STEP 64
-/*lint -e806*/
static uint g_aeq_len = HINIC3_DEFAULT_AEQ_LEN;
module_param(g_aeq_len, uint, 0444);
MODULE_PARM_DESC(g_aeq_len,
@@ -83,7 +84,6 @@ static uint g_num_ceqe_in_tasklet = HINIC3_TASK_PROCESS_EQE_LIMIT;
module_param(g_num_ceqe_in_tasklet, uint, 0444);
MODULE_PARM_DESC(g_num_ceqe_in_tasklet,
"The max number of ceqe can be processed in tasklet, default = 1024");
-/*lint +e806*/
#define CEQ_CTRL_0_INTR_IDX_SHIFT 0
#define CEQ_CTRL_0_DMA_ATTR_SHIFT 12
@@ -801,6 +801,7 @@ static int alloc_eq_pages(struct hinic3_eq *eq)
u32 reg, init_val;
u16 pg_idx, i;
int err;
+ gfp_t gfp_vram;
eq->eq_pages = kcalloc(eq->num_pages, sizeof(*eq->eq_pages),
GFP_KERNEL);
@@ -809,12 +810,15 @@ static int alloc_eq_pages(struct hinic3_eq *eq)
return -ENOMEM;
}
+ gfp_vram = hi_vram_get_gfp_vram();
+
for (pg_idx = 0; pg_idx < eq->num_pages; pg_idx++) {
eq_page = &eq->eq_pages[pg_idx];
err = hinic3_dma_zalloc_coherent_align(eq->hwdev->dev_hdl,
eq->page_size,
HINIC3_MIN_EQ_PAGE_SIZE,
- GFP_KERNEL, eq_page);
+ GFP_KERNEL | gfp_vram,
+ eq_page);
if (err) {
sdk_err(eq->hwdev->dev_hdl, "Failed to alloc eq page, page index: %hu\n",
pg_idx);
@@ -865,6 +869,7 @@ static void free_eq_pages(struct hinic3_eq *eq)
&eq->eq_pages[pg_idx]);
kfree(eq->eq_pages);
+ eq->eq_pages = NULL;
}
static inline u32 get_page_size(const struct hinic3_eq *eq)
@@ -1104,7 +1109,8 @@ int hinic3_aeqs_init(struct hinic3_hwdev *hwdev, u16 num_aeqs,
hwdev->aeqs = aeqs;
aeqs->hwdev = hwdev;
aeqs->num_aeqs = num_aeqs;
- aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME, WQ_MEM_RECLAIM,
+ aeqs->workq = alloc_workqueue(HINIC3_EQS_WQ_NAME,
+ WQ_MEM_RECLAIM | WQ_HIGHPRI,
HINIC3_MAX_AEQS);
if (!aeqs->workq) {
sdk_err(hwdev->dev_hdl, "Failed to initialize aeq workqueue\n");
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
index a4cbac8..6b96b87 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_api.c
@@ -83,6 +83,48 @@ int hinic3_sm_ctr_rd16(void *hwdev, u8 node, u8 instance, u32 ctr_id,
}
/**
+ * hinic3_sm_ctr_rd16_clear - small single 16 counter read and clear to zero
+ * @hwdev: the hardware device
+ * @node: the node id
+ * @ctr_id: counter id
+ * @value: read counter value ptr
+ * Return: 0 - success, negative - failure
+ **/
+int hinic3_sm_ctr_rd16_clear(void *hwdev, u8 node, u8 instance, u32 ctr_id,
+ u16 *value)
+{
+ struct chipif_sml_ctr_rd_req req;
+ union ctr_rd_rsp rsp;
+ int ret;
+
+ if (!hwdev || !value)
+ return -EFAULT;
+
+ if (!COMM_SUPPORT_API_CHAIN((struct hinic3_hwdev *)hwdev))
+ return -EPERM;
+
+ memset(&req, 0, sizeof(req));
+
+ hinic3_sml_ctr_read_build_req(&req, instance,
+ CHIPIF_SM_CTR_OP_READ_CLEAR,
+ CHIPIF_ACK, ctr_id, 0);
+
+ ret = hinic3_api_cmd_read_ack(hwdev, node, (u8 *)&req,
+ (unsigned short)sizeof(req),
+ (void *)&rsp,
+ (unsigned short)sizeof(rsp));
+ if (ret) {
+ sdk_err(((struct hinic3_hwdev *)hwdev)->dev_hdl,
+ "Sm 16bit counter clear fail, err(%d)\n", ret);
+ return ret;
+ }
+ sml_ctr_htonl_n((u32 *)&rsp, sizeof(rsp) / sizeof(u32));
+ *value = rsp.bs_ss16_rsp.value1;
+
+ return 0;
+}
+
+/**
* hinic3_sm_ctr_rd32 - small single 32 counter read
* @hwdev: the hardware device
* @node: the node id
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
index cea7581..2d4a9f6 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.c
@@ -34,13 +34,16 @@ static void parse_pub_res_cap_dfx(struct hinic3_hwdev *hwdev,
cap->max_vf);
sdk_info(hwdev->dev_hdl, "Host_pf_num: 0x%x, pf_id_start: 0x%x, host_vf_num: 0x%x, vf_id_start: 0x%x\n",
cap->pf_num, cap->pf_id_start, cap->vf_num, cap->vf_id_start);
- sdk_info(hwdev->dev_hdl, "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x\n",
- cap->host_valid_bitmap, cap->master_host_id, cap->srv_multi_host_mode);
sdk_info(hwdev->dev_hdl,
- "fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
- cap->fake_vf_start_id, cap->fake_vf_num, cap->fake_vf_max_pctx);
- sdk_info(hwdev->dev_hdl, "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x\n",
- cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len);
+ "host_valid_bitmap: 0x%x, master_host_id: 0x%x, srv_multi_host_mode: 0x%x, hot_plug_disable: 0x%x\n",
+ cap->host_valid_bitmap, cap->master_host_id, cap->srv_multi_host_mode,
+ cap->hot_plug_disable);
+ sdk_info(hwdev->dev_hdl,
+ "os_hot_replace: 0x%x, fake_vf_start_id: 0x%x, fake_vf_num: 0x%x, fake_vf_max_pctx: 0x%x\n",
+ cap->os_hot_replace, cap->fake_vf_start_id, cap->fake_vf_num, cap->fake_vf_max_pctx);
+ sdk_info(hwdev->dev_hdl,
+ "fake_vf_bfilter_start_addr: 0x%x, fake_vf_bfilter_len: 0x%x, bond_create_mode: 0x%x\n",
+ cap->fake_vf_bfilter_start_addr, cap->fake_vf_bfilter_len, cap->bond_create_mode);
}
static void parse_cqm_res_cap(struct hinic3_hwdev *hwdev, struct service_cap *cap,
@@ -109,6 +112,9 @@ static void parse_pub_res_cap(struct hinic3_hwdev *hwdev,
cap->host_valid_bitmap = dev_cap->host_valid_bitmap;
cap->master_host_id = dev_cap->master_host_id;
cap->srv_multi_host_mode = dev_cap->srv_multi_host_mode;
+ cap->hot_plug_disable = dev_cap->hot_plug_disable;
+ cap->bond_create_mode = dev_cap->bond_create_mode;
+ cap->os_hot_replace = dev_cap->os_hot_replace;
cap->fake_vf_en = dev_cap->fake_vf_en;
cap->fake_vf_start_bit = dev_cap->fake_vf_start_bit;
cap->fake_vf_end_bit = dev_cap->fake_vf_end_bit;
@@ -148,18 +154,27 @@ static void parse_l2nic_res_cap(struct hinic3_hwdev *hwdev,
nic_cap->max_sqs = dev_cap->nic_max_sq_id + 1;
nic_cap->max_rqs = dev_cap->nic_max_rq_id + 1;
nic_cap->default_num_queues = dev_cap->nic_default_num_queues;
+ nic_cap->outband_vlan_cfg_en = dev_cap->outband_vlan_cfg_en;
+ nic_cap->lro_enable = dev_cap->lro_enable;
sdk_info(hwdev->dev_hdl, "L2nic resource capbility, max_sqs: 0x%x, max_rqs: 0x%x\n",
nic_cap->max_sqs, nic_cap->max_rqs);
/* Check parameters from firmware */
- if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP ||
- nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
- sdk_info(hwdev->dev_hdl, "Number of qp exceed limit[1-%d]: sq: %u, rq: %u\n",
- HINIC3_CFG_MAX_QP, nic_cap->max_sqs, nic_cap->max_rqs);
+ if (nic_cap->max_sqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of sq exceed limit[1-%d]: sq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_sqs);
nic_cap->max_sqs = HINIC3_CFG_MAX_QP;
+ }
+
+ if (nic_cap->max_rqs > HINIC3_CFG_MAX_QP) {
+ sdk_info(hwdev->dev_hdl, "Number of rq exceed limit[1-%d]: rq: %u\n",
+ HINIC3_CFG_MAX_QP, nic_cap->max_rqs);
nic_cap->max_rqs = HINIC3_CFG_MAX_QP;
}
+
+ if (nic_cap->outband_vlan_cfg_en)
+ sdk_info(hwdev->dev_hdl, "L2nic outband vlan cfg enabled\n");
}
static void parse_fc_res_cap(struct hinic3_hwdev *hwdev,
@@ -333,6 +348,28 @@ static void parse_ipsec_res_cap(struct hinic3_hwdev *hwdev,
dev_cap->ipsec_max_sactx, dev_cap->ipsec_max_cq);
}
+static void parse_vbs_res_cap(struct hinic3_hwdev *hwdev,
+ struct service_cap *cap,
+ struct cfg_cmd_dev_cap *dev_cap,
+ enum func_type type)
+{
+ struct vbs_service_cap *vbs_cap = &cap->vbs_cap;
+
+ vbs_cap->vbs_max_volq = dev_cap->vbs_max_volq;
+ vbs_cap->vbs_main_pf_enable = dev_cap->vbs_main_pf_enable;
+ vbs_cap->vbs_vsock_pf_enable = dev_cap->vbs_vsock_pf_enable;
+ vbs_cap->vbs_fushion_queue_pf_enable = dev_cap->vbs_fushion_queue_pf_enable;
+
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS resource capbility, vbs_max_volq: 0x%x\n",
+ dev_cap->vbs_max_volq);
+ sdk_info(hwdev->dev_hdl,
+ "Get VBS pf info, vbs_main_pf_enable: 0x%x, vbs_vsock_pf_enable: 0x%x, vbs_fushion_queue_pf_enable: 0x%x\n",
+ dev_cap->vbs_main_pf_enable,
+ dev_cap->vbs_vsock_pf_enable,
+ dev_cap->vbs_fushion_queue_pf_enable);
+}
+
static void parse_dev_cap(struct hinic3_hwdev *dev,
struct cfg_cmd_dev_cap *dev_cap, enum func_type type)
{
@@ -375,6 +412,9 @@ static void parse_dev_cap(struct hinic3_hwdev *dev,
if (IS_PPA_TYPE(dev))
parse_ppa_res_cap(dev, cap, dev_cap, type);
+
+ if (IS_VBS_TYPE(dev))
+ parse_vbs_res_cap(dev, cap, dev_cap, type);
}
static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
@@ -404,6 +444,23 @@ static int get_cap_from_fw(struct hinic3_hwdev *dev, enum func_type type)
return 0;
}
+u8 hinic3_get_bond_create_mode(void *dev)
+{
+ struct hinic3_hwdev *hwdev = NULL;
+ struct service_cap *cap = NULL;
+
+ if (!dev) {
+ pr_err("pointer dev is NULL\n");
+ return -EINVAL;
+ }
+
+ hwdev = (struct hinic3_hwdev *)dev;
+ cap = &hwdev->cfg_mgmt->svc_cap;
+
+ return cap->bond_create_mode;
+}
+EXPORT_SYMBOL(hinic3_get_bond_create_mode);
+
int hinic3_get_dev_cap(void *dev)
{
enum func_type type;
@@ -1173,6 +1230,20 @@ bool hinic3_support_ppa(void *hwdev, struct ppa_service_cap *cap)
}
EXPORT_SYMBOL(hinic3_support_ppa);
+bool hinic3_support_bifur(void *hwdev, struct bifur_service_cap *cap)
+{
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)hwdev;
+
+ if (!hwdev)
+ return false;
+
+ if (!IS_BIFUR_TYPE(dev))
+ return false;
+
+ return true;
+}
+EXPORT_SYMBOL(hinic3_support_bifur);
+
bool hinic3_support_migr(void *hwdev, struct migr_service_cap *cap)
{
struct hinic3_hwdev *dev = hwdev;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
index db6e3ca..7157e97 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_cfg.h
@@ -166,6 +166,11 @@ struct service_cap {
u8 srv_multi_host_mode;
u16 virtio_vq_size;
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 os_hot_replace;
+ u8 rsvd1;
+
u8 timer_pf_num;
u8 timer_pf_id_start;
u16 timer_vf_num;
@@ -319,9 +324,11 @@ struct cfg_mgmt_info {
#define IS_RDMA_ENABLE(dev) \
((dev)->cfg_mgmt->svc_cap.sf_svc_attr.rdma_en)
#define IS_PPA_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_PPA)
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_PPA)
#define IS_MIGR_TYPE(dev) \
- (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_MIGRATE)
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_MIGRATE)
+#define IS_BIFUR_TYPE(dev) \
+ (((u32)(dev)->cfg_mgmt->svc_cap.chip_svc_type) & CFG_SERVICE_MASK_BIFUR)
int init_cfg_mgmt(struct hinic3_hwdev *dev);
@@ -333,5 +340,7 @@ void free_capability(struct hinic3_hwdev *dev);
int hinic3_init_vf_dev_cap(void *hwdev);
+u8 hinic3_get_bond_create_mode(void *dev);
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
index d8a1a28..47264f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_comm.c
@@ -21,7 +21,9 @@
#include "hinic3_hw_cfg.h"
#include "hinic3_cmdq.h"
#include "mpu_inband_cmd_defs.h"
+#include "mpu_board_defs.h"
#include "hinic3_hw_comm.h"
+#include "vram_common.h"
#define HINIC3_MSIX_CNT_LLI_TIMER_SHIFT 0
#define HINIC3_MSIX_CNT_LLI_CREDIT_SHIFT 8
@@ -242,12 +244,19 @@ int hinic3_func_reset(void *dev, u16 func_id, u64 reset_flag, u16 channel)
struct hinic3_hwdev *hwdev = dev;
u16 out_size = sizeof(func_reset);
int err = 0;
+ int is_in_kexec;
if (!dev) {
pr_err("Invalid para: dev is null.\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ sdk_info(hwdev->dev_hdl, "Skip function reset!\n");
+ return 0;
+ }
+
sdk_info(hwdev->dev_hdl, "Function is reset, flag: 0x%llx, channel:0x%x\n",
reset_flag, channel);
@@ -523,7 +532,7 @@ EXPORT_SYMBOL(hinic3_set_ppf_flr_type);
int hinic3_set_ppf_tbl_hotreplace_flag(void *hwdev, u8 flag)
{
- struct comm_cmd_ppf_tbl_htrp_config htr_info = {0};
+ struct comm_cmd_ppf_tbl_htrp_config htr_info = {};
u16 out_size = sizeof(struct comm_cmd_ppf_tbl_htrp_config);
struct hinic3_hwdev *dev = hwdev;
int ret;
@@ -868,11 +877,19 @@ static int set_ppf_tmr_status(struct hinic3_hwdev *hwdev,
int hinic3_ppf_tmr_start(void *hwdev)
{
+ int is_in_kexec;
+
if (!hwdev) {
pr_err("Hwdev pointer is NULL for starting ppf timer\n");
return -EINVAL;
}
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec != 0) {
+ pr_info("Skip starting ppt timer during kexec");
+ return 0;
+ }
+
return set_ppf_tmr_status(hwdev, HINIC_PPF_TMR_FLAG_START);
}
EXPORT_SYMBOL(hinic3_ppf_tmr_start);
@@ -888,18 +905,110 @@ int hinic3_ppf_tmr_stop(void *hwdev)
}
EXPORT_SYMBOL(hinic3_ppf_tmr_stop);
+static int hi_vram_kalloc_align(struct hinic3_hwdev *hwdev, char *name,
+ u32 page_size, u32 page_num,
+ struct hinic3_dma_addr_align *mem_align)
+{
+ void *vaddr = NULL, *align_vaddr = NULL;
+ dma_addr_t paddr, align_paddr;
+ u64 real_size = page_size;
+ u64 align = page_size;
+
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ /* align */
+ if (align_paddr == paddr) {
+ align_vaddr = vaddr;
+ goto out;
+ }
+
+ hi_vram_kfree((void *)vaddr, name, real_size);
+
+ /* realloc memory for align */
+ real_size = page_size + align;
+ vaddr = (void *)hi_vram_kalloc(name, real_size);
+ if (vaddr == NULL) {
+ sdk_err(hwdev->dev_hdl, "vram kalloc align failed, name:%s.\n", name);
+ return -ENOMEM;
+ }
+
+ paddr = (dma_addr_t)virt_to_phys(vaddr);
+ align_paddr = ALIGN(paddr, align);
+ align_vaddr = (void *)((u64)vaddr + (align_paddr - paddr));
+
+out:
+ mem_align->real_size = (u32)real_size;
+ mem_align->ori_vaddr = vaddr;
+ mem_align->ori_paddr = paddr;
+ mem_align->align_vaddr = align_vaddr;
+ mem_align->align_paddr = align_paddr;
+
+ return 0;
+}
+
+static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
+{
+ u32 i;
+ struct hinic3_dma_addr_align *page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = hwdev->mqm_eqm_vram_name;
+
+ page_addr = hwdev->mqm_att.brm_srch_page_addr;
+
+ for (i = 0; i < hwdev->mqm_att.page_num; i++) {
+ if (is_use_vram != 0) {
+ hi_vram_kfree(page_addr->ori_vaddr, mqm_eqm_vram_name[i].vram_name,
+ page_addr->real_size);
+ } else {
+ hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
+ }
+ page_addr->ori_vaddr = NULL;
+ page_addr++;
+ }
+
+ kfree(mqm_eqm_vram_name);
+ hwdev->mqm_eqm_vram_name = NULL;
+}
+
static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
u32 page_num)
{
struct hinic3_dma_addr_align *page_addr = hwdev->mqm_att.brm_srch_page_addr;
+ int is_use_vram = get_use_vram_flag();
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name = NULL;
u32 valid_num = 0;
u32 flag = 1;
u32 i = 0;
int err;
+ u16 func_id;
+
+ mqm_eqm_vram_name = kzalloc(sizeof(struct mqm_eqm_vram_name_s) * page_num, GFP_KERNEL);
+ if (mqm_eqm_vram_name == NULL) {
+ sdk_err(hwdev->dev_hdl, "mqm eqm alloc vram name failed.\n");
+ return -ENOMEM;
+ }
+
+ hwdev->mqm_eqm_vram_name = mqm_eqm_vram_name;
+ func_id = hinic3_global_func_id(hwdev);
for (i = 0; i < page_num; i++) {
- err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl, page_size,
- page_size, GFP_KERNEL, page_addr);
+ if (is_use_vram != 0) {
+ snprintf(mqm_eqm_vram_name[i].vram_name,
+ VRAM_NAME_MAX_LEN, "%s%u%s%u",
+ VRAM_CQM_GLB_FUNC_BASE, func_id, VRAM_NIC_MQM, i);
+ err = hi_vram_kalloc_align(
+ hwdev, mqm_eqm_vram_name[i].vram_name,
+ page_size, page_num, page_addr);
+ } else {
+ err = hinic3_dma_zalloc_coherent_align(hwdev->dev_hdl, page_size,
+ page_size, GFP_KERNEL, page_addr);
+ }
if (err) {
flag = 0;
break;
@@ -908,15 +1017,12 @@ static int mqm_eqm_try_alloc_mem(struct hinic3_hwdev *hwdev, u32 page_size,
page_addr++;
}
+ hwdev->mqm_att.page_num = valid_num;
+
if (flag == 1) {
hwdev->mqm_att.page_size = page_size;
- hwdev->mqm_att.page_num = page_num;
} else {
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
- for (i = 0; i < valid_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
+ mqm_eqm_free_page_mem(hwdev);
return -EFAULT;
}
@@ -955,19 +1061,6 @@ static int mqm_eqm_alloc_page_mem(struct hinic3_hwdev *hwdev)
return ret;
}
-static void mqm_eqm_free_page_mem(struct hinic3_hwdev *hwdev)
-{
- u32 i;
- struct hinic3_dma_addr_align *page_addr;
-
- page_addr = hwdev->mqm_att.brm_srch_page_addr;
-
- for (i = 0; i < hwdev->mqm_att.page_num; i++) {
- hinic3_dma_free_coherent_align(hwdev->dev_hdl, page_addr);
- page_addr++;
- }
-}
-
static int mqm_eqm_set_cfg_2_hw(struct hinic3_hwdev *hwdev, u8 valid)
{
struct comm_cmd_eqm_cfg info_eqm_cfg;
@@ -1098,6 +1191,7 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
{
struct comm_cmd_get_eqm_num info_eqm_fix;
int ret;
+ int is_in_kexec;
if (hwdev->hwif->attr.func_type != TYPE_PPF)
return 0;
@@ -1127,10 +1221,15 @@ static int mqm_eqm_init(struct hinic3_hwdev *hwdev)
goto err_page;
}
- ret = mqm_eqm_set_page_2_hw(hwdev);
- if (ret) {
- sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
- goto err_ecmd;
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ ret = mqm_eqm_set_page_2_hw(hwdev);
+ if (ret) {
+ sdk_err(hwdev->dev_hdl, "Set page to hw failed\r\n");
+ goto err_ecmd;
+ }
+ } else {
+ sdk_info(hwdev->dev_hdl, "Mqm db don't set to chip when os hot replace.\r\n");
}
ret = mqm_eqm_set_cfg_2_hw(hwdev, 1);
@@ -1568,3 +1667,15 @@ int hinic3_switch_config(void *hwdev, u8 cfg_index)
return 0;
}
+
+bool hinic3_is_optical_module_mode(void *hwdev)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (dev->board_info.board_type == BOARD_TYPE_STRG_4X25G_COMSTORAGE ||
+ dev->board_info.board_type == BOARD_TYPE_CAL_4X25G_COMSTORAGE ||
+ dev->board_info.board_type == BOARD_TYPE_CAL_2X100G_TCE_BACKPLANE)
+ return false;
+
+ return true;
+}
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
index baa1ce0..722fecd 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hw_mt.c
@@ -252,98 +252,6 @@ static u32 get_up_timeout_val(enum hinic3_mod_type mod, u16 cmd)
return 0; /* use default mbox/apichain timeout time */
}
-static int api_csr_read(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
-{
- struct up_log_msg_st *up_log_msg = (struct up_log_msg_st *)buf_in;
- u8 *buf_out_tmp = (u8 *)buf_out;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
-
- if (!buf_in || !buf_out || in_size != sizeof(*up_log_msg) ||
- *out_size != up_log_msg->rd_len || up_log_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = up_log_msg->rd_len;
- rd_addr = up_log_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_rd32(hwdev, node_id,
- rd_addr + offset,
- (u32 *)(buf_out_tmp + offset));
- if (ret) {
- pr_err("Csr rd fail, err: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, node_id, rd_addr + offset);
- return ret;
- }
- offset += DW_WIDTH;
- }
- *out_size = rd_len;
-
- return ret;
-}
-
-static int api_csr_write(void *hwdev, struct msg_module *nt_msg,
- void *buf_in, u32 in_size, void *buf_out,
- u32 *out_size)
-{
- struct csr_write_st *csr_write_msg = (struct csr_write_st *)buf_in;
- int ret = 0;
- u32 rd_len;
- u32 rd_addr;
- u32 rd_cnt = 0;
- u32 offset = 0;
- u8 node_id;
- u32 i;
- u8 *data = NULL;
-
- if (!buf_in || in_size != sizeof(*csr_write_msg) || csr_write_msg->rd_len == 0 ||
- csr_write_msg->rd_len > API_CSR_MAX_RD_LEN || csr_write_msg->rd_len % DW_WIDTH != 0)
- return -EINVAL;
-
- rd_len = csr_write_msg->rd_len;
- rd_addr = csr_write_msg->addr;
- node_id = (u8)nt_msg->mpu_cmd.mod;
-
- rd_cnt = rd_len / DW_WIDTH;
-
- data = kzalloc(rd_len, GFP_KERNEL);
- if (!data) {
- pr_err("No more memory\n");
- return -EFAULT;
- }
- if (copy_from_user(data, (void *)csr_write_msg->data, rd_len)) {
- pr_err("Copy information from user failed\n");
- kfree(data);
- return -EFAULT;
- }
-
- for (i = 0; i < rd_cnt; i++) {
- ret = hinic3_api_csr_wr32(hwdev, node_id,
- rd_addr + offset,
- *((u32 *)(data + offset)));
- if (ret) {
- pr_err("Csr wr fail, ret: %d, node_id: %u, csr addr: 0x%08x\n",
- ret, rd_addr + offset, node_id);
- kfree(data);
- return ret;
- }
- offset += DW_WIDTH;
- }
-
- *out_size = 0;
- kfree(data);
- return ret;
-}
-
int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
@@ -370,10 +278,8 @@ int send_to_mpu(void *hwdev, struct msg_module *nt_msg,
return ret;
}
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_BYPASS) {
- if (nt_msg->mpu_cmd.cmd == API_CSR_WRITE)
- return api_csr_write(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
-
- ret = api_csr_read(hwdev, nt_msg, buf_in, in_size, buf_out, out_size);
+ pr_err("Unsupported api_type %u\n", nt_msg->mpu_cmd.api_type);
+ return -EINVAL;
} else if (nt_msg->mpu_cmd.api_type == API_TYPE_API_CHAIN_TO_MPU) {
timeout = get_up_timeout_val(mod, cmd);
if (hinic3_pcie_itf_id(hwdev) != SPU_HOST_ID)
@@ -440,6 +346,23 @@ static int sm_rd16(void *hwdev, u32 id, u8 instance,
return ret;
}
+static int sm_rd16_clear(void *hwdev, u32 id, u8 instance,
+ u8 node, struct sm_out_st *buf_out)
+{
+ u16 val1;
+ int ret;
+
+ ret = hinic3_sm_ctr_rd16_clear(hwdev, node, instance, id, &val1);
+ if (ret != 0) {
+ pr_err("Get sm ctr clear information (16 bits)failed!\n");
+ val1 = 0xffff;
+ }
+
+ buf_out->val1 = val1;
+
+ return ret;
+}
+
static int sm_rd32(void *hwdev, u32 id, u8 instance,
u8 node, struct sm_out_st *buf_out)
{
@@ -559,6 +482,7 @@ const struct sm_module_handle sm_module_cmd_handle[] = {
{SM_CTR_RD32, sm_rd32},
{SM_CTR_RD64_PAIR, sm_rd64_pair},
{SM_CTR_RD64, sm_rd64},
+ {SM_CTR_RD16_CLEAR, sm_rd16_clear},
{SM_CTR_RD32_CLEAR, sm_rd32_clear},
{SM_CTR_RD64_PAIR_CLEAR, sm_rd64_pair_clear},
{SM_CTR_RD64_CLEAR, sm_rd64_clear}
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
index 620136a..ac80b63 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.c
@@ -101,6 +101,12 @@ enum hinic3_pcie_tph {
#define SLAVE_HOST_STATUS_SET(host_id, enable) (((u8)(enable) & 1U) << (host_id))
#define SLAVE_HOST_STATUS_GET(host_id, val) (!!((val) & (1U << (host_id))))
+#ifdef HAVE_HOT_REPLACE_FUNC
+ extern int get_partition_id(void);
+#else
+ static int get_partition_id(void) { return 0; }
+#endif
+
void set_slave_host_enable(void *hwdev, u8 host_id, bool enable)
{
u32 reg_val;
@@ -207,6 +213,28 @@ static void hinic3_init_host_mode_pre(struct hinic3_hwdev *hwdev)
}
}
+static void hinic3_init_hot_plug_status(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->hot_plug_disable) {
+ hwdev->hot_plug_mode = HOT_PLUG_DISABLE;
+ } else {
+ hwdev->hot_plug_mode = HOT_PLUG_ENABLE;
+ }
+}
+
+static void hinic3_init_os_hot_replace(struct hinic3_hwdev *hwdev)
+{
+ struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+
+ if (cap->os_hot_replace) {
+ hwdev->hot_replace_mode = HOT_REPLACE_ENABLE;
+ } else {
+ hwdev->hot_replace_mode = HOT_REPLACE_DISABLE;
+ }
+}
+
static u8 hinic3_nic_sw_aeqe_handler(void *hwdev, u8 event, u8 *data)
{
struct hinic3_hwdev *dev = hwdev;
@@ -270,14 +298,20 @@ static void chip_fault_show(struct hinic3_hwdev *hwdev,
"fatal", "reset", "host", "flr", "general", "suggestion"};
char level_str[FAULT_SHOW_STR_LEN + 1];
u8 level;
+ int ret;
memset(level_str, 0, FAULT_SHOW_STR_LEN + 1);
level = event->event.chip.err_level;
- if (level < FAULT_LEVEL_MAX)
- strncpy(level_str, fault_level[level],
- FAULT_SHOW_STR_LEN);
- else
- strncpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (level < FAULT_LEVEL_MAX) {
+ ret = strscpy(level_str, fault_level[level],
+ FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ } else {
+ ret = strscpy(level_str, "Unknown", FAULT_SHOW_STR_LEN);
+ if (ret < 0)
+ return;
+ }
if (level == FAULT_LEVEL_SERIOUS_FLR)
dev_err(hwdev->dev_hdl, "err_level: %u [%s], flr func_id: %u\n",
@@ -299,6 +333,7 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
"reg rd timeout", "reg wr timeout", "phy fault", "tsensor fault"};
char type_str[FAULT_SHOW_STR_LEN + 1] = {0};
struct fault_event_stats *fault = NULL;
+ int ret;
sdk_err(hwdev->dev_hdl, "Fault event report received, func_id: %u\n",
hinic3_global_func_id(hwdev));
@@ -306,10 +341,14 @@ static void fault_report_show(struct hinic3_hwdev *hwdev,
fault = &hwdev->hw_stats.fault_event_stats;
if (event->type < FAULT_TYPE_MAX) {
- strncpy(type_str, fault_type[event->type], sizeof(type_str));
+ ret = strscpy(type_str, fault_type[event->type], sizeof(type_str));
+ if (ret < 0)
+ return;
atomic_inc(&fault->fault_type_stat[event->type]);
} else {
- strncpy(type_str, "Unknown", sizeof(type_str));
+ ret = strscpy(type_str, "Unknown", sizeof(type_str));
+ if (ret < 0)
+ return;
}
sdk_err(hwdev->dev_hdl, "Fault type: %u [%s]\n", event->type, type_str);
@@ -1536,15 +1575,30 @@ int hinic3_init_hwdev(struct hinic3_init_para *para)
hinic3_init_host_mode_pre(hwdev);
+ hinic3_init_hot_plug_status(hwdev);
+
+ hinic3_init_os_hot_replace(hwdev);
+
err = hinic3_multi_host_mgmt_init(hwdev);
if (err != 0) {
sdk_err(hwdev->dev_hdl, "Failed to init function mode\n");
goto init_multi_host_fail;
}
- err = hinic3_init_ppf_work(hwdev);
- if (err != 0)
- goto init_ppf_work_fail;
+ // hot_replace_mode is enable, run ppf function only when partition_id is 0
+ // or run ppf function directly
+ if (hwdev->hot_replace_mode == HOT_REPLACE_ENABLE) {
+ if (get_partition_id() == 0) {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0) {
+ goto init_ppf_work_fail;
+ }
+ }
+ } else {
+ err = hinic3_init_ppf_work(hwdev);
+ if (err != 0)
+ goto init_ppf_work_fail;
+ }
err = hinic3_set_comm_features(hwdev, hwdev->features, COMM_MAX_FEATURE_QWORD);
if (err != 0) {
@@ -1948,6 +2002,19 @@ void hinic3_link_event_stats(void *dev, u8 link)
}
EXPORT_SYMBOL(hinic3_link_event_stats);
+int hinic3_get_link_event_stats(void *dev, int *link_state)
+{
+ struct hinic3_hwdev *hwdev = dev;
+
+ if (!hwdev || !link_state)
+ return -EINVAL;
+
+ *link_state = hwdev->hw_stats.link_event_stats.link_down_stats.counter;
+
+ return 0;
+}
+EXPORT_SYMBOL(hinic3_get_link_event_stats);
+
u8 hinic3_max_pf_num(void *hwdev)
{
if (!hwdev)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
index e739767..7c2cfc2 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwdev.h
@@ -10,6 +10,7 @@
#include "hinic3_hw.h"
#include "mpu_inband_cmd_defs.h"
#include "hinic3_profile.h"
+#include "vram_common.h"
struct cfg_mgmt_info;
@@ -82,6 +83,22 @@ enum hinic3_host_mode_e {
HINIC3_SDI_MODE_MAX,
};
+enum hinic3_hot_plug_mode {
+ HOT_PLUG_ENABLE,
+ HOT_PLUG_DISABLE,
+};
+
+enum hinic3_os_hot_replace_mode {
+ HOT_REPLACE_DISABLE,
+ HOT_REPLACE_ENABLE,
+};
+
+#define UNSUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_DISABLE)
+
+#define SUPPORT_HOT_PLUG(hwdev) \
+ ((hwdev)->hot_plug_mode == HOT_PLUG_ENABLE)
+
#define MULTI_HOST_CHIP_MODE_SHIFT 0
#define MULTI_HOST_MASTER_MBX_STS_SHIFT 17
#define MULTI_HOST_PRIV_DATA_SHIFT 0x8
@@ -100,6 +117,10 @@ enum hinic3_host_mode_e {
((val) & (~(MULTI_HOST_##member##_MASK \
<< MULTI_HOST_##member##_SHIFT)))
+struct mqm_eqm_vram_name_s {
+ char vram_name[VRAM_NAME_MAX_LEN];
+};
+
struct hinic3_hwdev {
void *adapter_hdl; /* pointer to hinic3_pcidev or NDIS_Adapter */
void *pcidev_hdl; /* pointer to pcidev or Handler */
@@ -138,6 +159,9 @@ struct hinic3_hwdev {
u32 rsvd2;
struct hinic3_multi_host_mgmt *mhost_mgmt;
+ char mhost_mgmt_name[VRAM_NAME_MAX_LEN];
+
+ struct mqm_eqm_vram_name_s *mqm_eqm_vram_name;
struct mutex stateful_mutex; /* protect cqm init and deinit */
@@ -170,7 +194,10 @@ struct hinic3_hwdev {
struct hinic3_devlink *devlink_dev;
enum hinic3_func_mode func_mode;
- u32 rsvd3;
+ enum hinic3_hot_plug_mode hot_plug_mode;
+
+ enum hinic3_os_hot_replace_mode hot_replace_mode;
+ u32 rsvd5;
DECLARE_BITMAP(func_probe_in_host, MAX_FUNCTION_NUM);
DECLARE_BITMAP(netdev_setup_state, MAX_FUNCTION_NUM);
@@ -179,7 +206,10 @@ struct hinic3_hwdev {
u64 last_recv_aeq_cnt;
u16 aeq_busy_cnt;
- u64 rsvd4[8];
+ u64 mbox_send_cnt;
+ u64 mbox_ack_cnt;
+
+ u64 rsvd4[5];
};
#define HINIC3_DRV_FEATURE_QW0 \
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
index 33f1210..8590f70 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_hwif.c
@@ -544,6 +544,7 @@ static void free_db_area(struct hinic3_free_db_area *free_db_area)
{
spin_lock_deinit(&free_db_area->idx_lock);
kfree(free_db_area->db_bitmap_array);
+ free_db_area->db_bitmap_array = NULL;
}
static int get_db_idx(struct hinic3_hwif *hwif, u32 *idx)
@@ -841,6 +842,7 @@ void hinic3_free_hwif(struct hinic3_hwdev *hwdev)
free_db_area(&hwdev->hwif->free_db_area);
enable_all_msix(hwdev);
kfree(hwdev->hwif);
+ hwdev->hwif = NULL;
}
u16 hinic3_global_func_id(void *hwdev)
@@ -856,6 +858,44 @@ u16 hinic3_global_func_id(void *hwdev)
}
EXPORT_SYMBOL(hinic3_global_func_id);
+/**
+ * get function id from register,used by sriov hot migration process
+ * @hwdev: the pointer to hw device
+ */
+u16 hinic3_global_func_id_hw(void *hwdev)
+{
+ u32 addr, attr0;
+ struct hinic3_hwdev *dev;
+
+ dev = (struct hinic3_hwdev *)hwdev;
+ addr = HINIC3_CSR_FUNC_ATTR0_ADDR;
+ attr0 = hinic3_hwif_read_reg(dev->hwif, addr);
+
+ return HINIC3_AF0_GET(attr0, FUNC_GLOBAL_IDX);
+}
+
+/**
+ * get function id, used by sriov hot migratition process.
+ * @hwdev: the pointer to hw device
+ * @func_id: function id
+ */
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id)
+{
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)hwdev;
+
+ if (!hwdev || !func_id)
+ return -EINVAL;
+
+ /* only vf get func_id from chip reg for sriov migrate */
+ if (!HINIC3_IS_VF(dev)) {
+ *func_id = hinic3_global_func_id(hwdev);
+ return 0;
+ }
+
+ *func_id = hinic3_global_func_id_hw(dev);
+ return 0;
+}
+
u16 hinic3_intr_num(void *hwdev)
{
struct hinic3_hwif *hwif = NULL;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
index 321a3b7..4e2e8b0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_lld.c
@@ -16,6 +16,7 @@
#include <linux/rtc.h>
#include <linux/aer.h>
#include <linux/debugfs.h>
+#include <linux/notifier.h>
#include "ossl_knl.h"
#include "hinic3_mt.h"
@@ -29,26 +30,41 @@
#include "hinic3_lld.h"
#include "hinic3_profile.h"
+#include "hinic3_hw_cfg.h"
+#include "hinic3_multi_host_mgmt.h"
#include "hinic3_hwdev.h"
#include "hinic3_prof_adap.h"
-#include "comm_msg_intf.h"
+#include "hinic3_devlink.h"
-static bool disable_vf_load;
+#include "vram_common.h"
+
+enum partition_dev_type {
+ PARTITION_DEV_NONE = 0,
+ PARTITION_DEV_SHARED,
+ PARTITION_DEV_EXCLUSIVE,
+ PARTITION_DEV_BACKUP,
+};
+
+#ifdef HAVE_HOT_REPLACE_FUNC
+extern int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type, unsigned int partition_id);
+extern int get_partition_id(void);
+#else
+static int vpci_set_partition_attrs(struct pci_dev *dev, unsigned int dev_type, unsigned int partition_id) { return 0; }
+static int get_partition_id(void) { return 0; }
+#endif
+
+static bool disable_vf_load = false;
module_param(disable_vf_load, bool, 0444);
MODULE_PARM_DESC(disable_vf_load,
"Disable virtual functions probe or not - default is false");
+static bool g_is_pf_migrated = false;
static bool disable_attach;
module_param(disable_attach, bool, 0444);
MODULE_PARM_DESC(disable_attach, "disable_attach or not - default is false");
#define HINIC3_WAIT_SRIOV_CFG_TIMEOUT 15000
-MODULE_AUTHOR("Huawei Technologies CO., Ltd");
-MODULE_DESCRIPTION(HINIC3_DRV_DESC);
-MODULE_VERSION(HINIC3_DRV_VERSION);
-MODULE_LICENSE("GPL");
-
#if !(defined(HAVE_SRIOV_CONFIGURE) || defined(HAVE_RHEL6_SRIOV_CONFIGURE))
static DEVICE_ATTR(sriov_numvfs, 0664,
hinic3_sriov_numvfs_show, hinic3_sriov_numvfs_store);
@@ -71,7 +87,18 @@ static const struct attribute_group hinic3_attr_group = {
struct hinic3_uld_info g_uld_info[SERVICE_T_MAX] = { {0} };
#define HINIC3_EVENT_PROCESS_TIMEOUT 10000
+#define HINIC3_WAIT_EVENT_PROCESS_TIMEOUT 100
struct mutex g_uld_mutex;
+#define BUS_MAX_DEV_NUM 256
+#define HINIC3_SLAVE_WORK_MAX_NUM 20
+
+typedef struct vf_offset_info {
+ u8 valid;
+ u16 vf_offset_from_pf[CMD_MAX_MAX_PF_NUM];
+} VF_OFFSET_INFO_S;
+
+static VF_OFFSET_INFO_S g_vf_offset;
+DEFINE_MUTEX(g_vf_offset_lock);
void hinic3_uld_lock_init(void)
{
@@ -80,13 +107,23 @@ void hinic3_uld_lock_init(void)
static const char *s_uld_name[SERVICE_T_MAX] = {
"nic", "ovs", "roce", "toe", "ioe",
- "fc", "vbs", "ipsec", "virtio", "migrate", "ppa", "custom"};
+ "fc", "vbs", "ipsec", "virtio", "migrate",
+ "ppa", "custom", "vroce", "crypt", "vsock", "bifur"};
const char **hinic3_get_uld_names(void)
{
return s_uld_name;
}
+#ifdef CONFIG_PCI_IOV
+static int hinic3_get_pf_device_id(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_dev = pci_physfn(pdev);
+
+ return pf_dev->device;
+}
+#endif
+
static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
const struct hinic3_uld_info *uld_info)
{
@@ -105,6 +142,10 @@ static int attach_uld(struct hinic3_pcidev *dev, enum hinic3_service_type type,
atomic_set(&dev->uld_ref_cnt[type], 0);
+ if (!uld_info->probe) {
+ err = 0;
+ goto out_unlock;
+ }
err = uld_info->probe(&dev->lld_dev, &uld_dev, dev->uld_dev_name[type]);
if (err) {
sdk_err(&dev->pcidev->dev,
@@ -173,6 +214,10 @@ static void detach_uld(struct hinic3_pcidev *dev,
wait_uld_unused(dev, type);
+ if (!uld_info->remove) {
+ mutex_unlock(&dev->pdev_mutex);
+ return;
+ }
uld_info->remove(&dev->lld_dev, dev->uld_dev[type]);
dev->uld_dev[type] = NULL;
@@ -190,10 +235,15 @@ static void attach_ulds(struct hinic3_pcidev *dev)
enum hinic3_service_type type;
struct pci_dev *pdev = dev->pcidev;
- lld_hold();
+ int is_in_kexec = vram_get_kexec_flag();
+ /* don't need hold when driver parallel load during spu hot replace */
+ if (is_in_kexec == 0) {
+ lld_hold();
+ }
+
mutex_lock(&g_uld_mutex);
- for (type = SERVICE_T_NIC; type < SERVICE_T_MAX; type++) {
+ for (type = SERVICE_T_OVS; type < SERVICE_T_MAX; type++) {
if (g_uld_info[type].probe) {
if (pdev->is_virtfn &&
(!hinic3_get_vf_service_load(pdev, (u16)type))) {
@@ -205,7 +255,10 @@ static void attach_ulds(struct hinic3_pcidev *dev)
}
}
mutex_unlock(&g_uld_mutex);
- lld_put();
+
+ if (is_in_kexec == 0) {
+ lld_put();
+ }
}
static void detach_ulds(struct hinic3_pcidev *dev)
@@ -255,10 +308,10 @@ int hinic3_register_uld(enum hinic3_service_type type,
}
chip_list = get_hinic3_chip_list();
- memcpy(&g_uld_info[type], uld_info, sizeof(*uld_info));
+ memcpy(&g_uld_info[type], uld_info, sizeof(struct hinic3_uld_info));
list_for_each_entry(chip_node, chip_list, node) {
list_for_each_entry(dev, &chip_node->func_list, node) {
- if (attach_uld(dev, type, uld_info)) {
+ if (attach_uld(dev, type, uld_info) != 0) {
sdk_err(&dev->pcidev->dev,
"Attach %s driver to pcie device failed\n",
s_uld_name[type]);
@@ -312,7 +365,7 @@ void hinic3_unregister_uld(enum hinic3_service_type type)
}
uld_info = &g_uld_info[type];
- memset(uld_info, 0, sizeof(*uld_info));
+ memset(uld_info, 0, sizeof(struct hinic3_uld_info));
mutex_unlock(&g_uld_mutex);
lld_put();
}
@@ -366,6 +419,26 @@ void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_ser
}
EXPORT_SYMBOL(hinic3_detach_service);
+void hinic3_module_get(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ __module_get(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_get);
+
+void hinic3_module_put(void *hwdev, enum hinic3_service_type type)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (!dev || type >= SERVICE_T_MAX)
+ return;
+ module_put(THIS_MODULE);
+}
+EXPORT_SYMBOL(hinic3_module_put);
+
static void hinic3_sync_time_to_fmw(struct hinic3_pcidev *pdev_pri)
{
struct timeval tv = {0};
@@ -382,7 +455,8 @@ static void hinic3_sync_time_to_fmw(struct hinic3_pcidev *pdev_pri)
err);
} else {
rtc_time_to_tm((unsigned long)(tv.tv_sec), &rt_time);
- sdk_info(&pdev_pri->pcidev->dev, "Synchronize UTC time to firmware succeed. UTC time %d-%02d-%02d %02d:%02d:%02d.\n",
+ sdk_info(&pdev_pri->pcidev->dev,
+ "Synchronize UTC time to firmware succeed. UTC time %d-%02d-%02d %02d:%02d:%02d.\n",
rt_time.tm_year + HINIC3_SYNC_YEAR_OFFSET,
rt_time.tm_mon + HINIC3_SYNC_MONTH_OFFSET,
rt_time.tm_mday, rt_time.tm_hour,
@@ -448,23 +522,434 @@ static void send_event_to_all_pf(struct hinic3_pcidev *dev,
lld_put();
}
+u32 hinic3_pdev_is_virtfn(struct pci_dev *pdev)
+{
+#ifdef CONFIG_PCI_IOV
+ return pdev->is_virtfn;
+#else
+ return 0;
+#endif
+}
+
+static int hinic3_get_function_enable(struct pci_dev *pdev, bool *en)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+ int err;
+
+ /* PF in host os or function in guest os, probe sdk in default */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev) {
+ *en = true;
+ return 0;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev) {
+ /* vf in host and pf sdk not probed */
+ return -EFAULT;
+ }
+ pf_hwdev = pci_adapter->hwdev;
+
+ err = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (err) {
+ sdk_err(&pci_adapter->pcidev->dev, "Func hinic3_get_vfid_by_vfpci fail %d \n", err);
+ return err;
+ }
+
+ err = hinic3_get_func_nic_enable(pf_hwdev, global_func_id, en);
+ if (!!err) {
+ sdk_info(&pdev->dev, "Failed to get function nic status, err %d.\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+int hinic3_set_func_probe_in_host(void *hwdev, u16 func_id, bool probe)
+{
+ struct hinic3_hwdev *dev = hwdev;
+
+ if (hinic3_func_type(hwdev) != TYPE_PPF)
+ return -EINVAL;
+
+ if (probe)
+ set_bit(func_id, dev->func_probe_in_host);
+ else
+ clear_bit(func_id, dev->func_probe_in_host);
+
+ return 0;
+}
+
+bool hinic3_get_func_probe_in_host(void *hwdev, u16 func_id)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+ bool probed = false;
+
+ if (!hwdev)
+ return false;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return false;
+ }
+
+ probed = !!test_bit(func_id, ppf_dev->func_probe_in_host);
+ up(&dev->ppf_sem);
+
+ return probed;
+}
+
+void *hinic3_get_ppf_hwdev_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct card_node *chip_node = NULL;
+ struct hinic3_pcidev *dev = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ chip_node = pci_adapter->chip_node;
+ lld_dev_hold(&pci_adapter->lld_dev);
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (dev->lld_state == HINIC3_IN_REMOVE)
+ continue;
+
+ if (dev->hwdev && hinic3_func_type(dev->hwdev) == TYPE_PPF) {
+ lld_dev_put(&pci_adapter->lld_dev);
+ return dev->hwdev;
+ }
+ }
+ lld_dev_put(&pci_adapter->lld_dev);
+
+ return NULL;
+}
+
+static int hinic3_set_vf_nic_used_state(void *hwdev, u16 func_id, bool opened)
+{
+ struct hinic3_hwdev *dev = hwdev;
+ struct hinic3_hwdev *ppf_dev = NULL;
+
+ if (!dev || func_id >= MAX_FUNCTION_NUM)
+ return -EINVAL;
+
+ down(&dev->ppf_sem);
+ ppf_dev = hinic3_get_ppf_hwdev_by_pdev(dev->pcidev_hdl);
+ if (!ppf_dev || hinic3_func_type(ppf_dev) != TYPE_PPF) {
+ up(&dev->ppf_sem);
+ return -EINVAL;
+ }
+
+ if (opened)
+ set_bit(func_id, ppf_dev->netdev_setup_state);
+ else
+ clear_bit(func_id, ppf_dev->netdev_setup_state);
+
+ up(&dev->ppf_sem);
+
+ return 0;
+}
+
+static void set_vf_func_in_use(struct pci_dev *pdev, bool in_use)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ u16 global_func_id;
+
+ /* only need to be set when VF is on the host */
+ if (!hinic3_pdev_is_virtfn(pdev) || !pf_pdev)
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter || !pci_adapter->hwdev)
+ return;
+
+ pf_hwdev = pci_adapter->hwdev;
+
+ global_func_id = (u16)pdev->devfn + hinic3_glb_pf_vf_offset(pf_hwdev);
+ (void)hinic3_set_vf_nic_used_state(pf_hwdev, global_func_id, in_use);
+}
+
+static int hinic3_pf_get_vf_offset_info(struct hinic3_pcidev *des_dev, u16 *vf_offset)
+{
+ int err, i;
+ struct hinic3_hw_pf_infos *pf_infos = NULL;
+ u16 pf_func_id;
+ struct hinic3_pcidev *pf_pci_adapter = NULL;
+
+ pf_pci_adapter = (hinic3_pdev_is_virtfn(des_dev->pcidev)) ? pci_get_drvdata(des_dev->pcidev->physfn) : des_dev;
+ pf_func_id = hinic3_global_func_id(pf_pci_adapter->hwdev);
+ if (pf_func_id >= CMD_MAX_MAX_PF_NUM || !vf_offset)
+ return -EINVAL;
+
+ mutex_lock(&g_vf_offset_lock);
+ if (g_vf_offset.valid == 0) {
+ pf_infos = kzalloc(sizeof(*pf_infos), GFP_KERNEL);
+ if (!pf_infos) {
+ sdk_err(&pf_pci_adapter->pcidev->dev, "Malloc pf_infos fail\n");
+ err = -ENOMEM;
+ goto err_malloc;
+ }
+
+ err = hinic3_get_hw_pf_infos(pf_pci_adapter->hwdev, pf_infos, HINIC3_CHANNEL_COMM);
+ if (err) {
+ sdk_warn(&pf_pci_adapter->pcidev->dev, "Hinic3_get_hw_pf_infos fail err %d\n", err);
+ err = -EFAULT;
+ goto err_out;
+ }
+
+ g_vf_offset.valid = 1;
+ for (i = 0; i < CMD_MAX_MAX_PF_NUM; i++) {
+ g_vf_offset.vf_offset_from_pf[i] = pf_infos->infos[i].vf_offset;
+ }
+
+ kfree(pf_infos);
+ }
+
+ *vf_offset = g_vf_offset.vf_offset_from_pf[pf_func_id];
+
+ mutex_unlock(&g_vf_offset_lock);
+
+ return 0;
+
+err_out:
+ kfree(pf_infos);
+err_malloc:
+ mutex_unlock(&g_vf_offset_lock);
+ return err;
+}
+
+static struct pci_dev *get_vf_pdev_by_pf(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ int err;
+ u16 bus_num;
+ u16 vf_start, vf_end;
+ u16 des_fn, pf_func_id, vf_offset;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ pf_func_id = hinic3_global_func_id(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end || pf_func_id >= CMD_MAX_MAX_PF_NUM)
+ return NULL;
+
+ err = hinic3_pf_get_vf_offset_info(des_dev, &vf_offset);
+ if (err) {
+ sdk_warn(&des_dev->pcidev->dev, "Hinic3_pf_get_vf_offset_info fail\n");
+ return NULL;
+ }
+
+ des_fn = ((func_id - vf_start) - 1) + pf_func_id + vf_offset;
+ bus_num = des_dev->pcidev->bus->number + des_fn / BUS_MAX_DEV_NUM;
+
+ return pci_get_domain_bus_and_slot(0, bus_num, (des_fn % BUS_MAX_DEV_NUM));
+}
+
+static struct hinic3_pcidev *get_des_pci_adapter(struct hinic3_pcidev *des_dev,
+ u16 func_id)
+{
+ struct pci_dev *des_pdev = NULL;
+ u16 vf_start, vf_end;
+ bool probe_in_host = false;
+
+ if (hinic3_global_func_id(des_dev->hwdev) == func_id)
+ return des_dev;
+
+ vf_start = hinic3_glb_pf_vf_offset(des_dev->hwdev);
+ vf_end = vf_start + hinic3_func_max_vf(des_dev->hwdev);
+ if (func_id <= vf_start || func_id > vf_end)
+ return NULL;
+
+ des_pdev = get_vf_pdev_by_pf(des_dev, func_id);
+ if (!des_pdev)
+ return NULL;
+
+ pci_dev_put(des_pdev);
+
+ probe_in_host = hinic3_get_func_probe_in_host(des_dev->hwdev, func_id);
+ if (!probe_in_host)
+ return NULL;
+
+ return pci_get_drvdata(des_pdev);
+}
+
+int __set_vroce_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ u8 enable_vroce = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_vroce_enable(pci_adapter->hwdev, func_id, &enable_vroce);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Failed to get vroce state.\n");
+ return err;
+ }
+
+ mutex_lock(&g_uld_mutex);
+
+ if (!!enable_vroce) {
+ if (!g_uld_info[SERVICE_T_ROCE].probe) {
+ sdk_info(&pdev->dev, "Uld(roce_info) has not been registered!\n");
+ mutex_unlock(&g_uld_mutex);
+ return 0;
+ }
+
+ err = attach_uld(pci_adapter, SERVICE_T_ROCE, &g_uld_info[SERVICE_T_ROCE]);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Failed to initialize VROCE.\n");
+ mutex_unlock(&g_uld_mutex);
+ return err;
+ }
+ } else {
+ sdk_info(&pdev->dev, "Func %hu vroce state: disable.\n", func_id);
+ if (g_uld_info[SERVICE_T_ROCE].remove)
+ detach_uld(pci_adapter, SERVICE_T_ROCE);
+ }
+
+ mutex_unlock(&g_uld_mutex);
+
+ return 0;
+}
+
+void slave_host_mgmt_vroce_work(struct work_struct *work)
+{
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_vroce_work);
+
+ __set_vroce_func_state(pci_adapter);
+}
+
+void *hinic3_get_roce_uld_by_pdev(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev)
+ return NULL;
+
+ pci_adapter = pci_get_drvdata(pdev);
+ if (!pci_adapter)
+ return NULL;
+
+ return pci_adapter->uld_dev[SERVICE_T_ROCE];
+}
+
+static int __func_service_state_process(struct hinic3_pcidev *event_dev,
+ struct hinic3_pcidev *des_dev,
+ struct hinic3_mhost_nic_func_state *state, u16 cmd)
+{
+ int err = 0;
+ struct hinic3_hwdev *dev = (struct hinic3_hwdev *)event_dev->hwdev;
+
+ switch (cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ state->enable = hinic3_get_roce_uld_by_pdev(des_dev->pcidev) ? 1 : 0;
+ break;
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive nic[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ if (event_dev->multi_host_mgmt_workq) {
+ queue_work(event_dev->multi_host_mgmt_workq, &des_dev->slave_nic_work);
+ } else {
+ sdk_err(&des_dev->pcidev->dev, "Can not schedule slave nic work\n");
+ err = -EFAULT;
+ }
+ break;
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ sdk_info(&des_dev->pcidev->dev, "Receive vroce[%u] state changed event, state: %u\n",
+ state->func_idx, state->enable);
+ queue_work_on(hisdk3_get_work_cpu_affinity(dev, WORK_TYPE_MBOX),
+ event_dev->multi_host_mgmt_workq,
+ &des_dev->slave_vroce_work);
+ break;
+ default:
+ sdk_warn(&des_dev->pcidev->dev, "Service state process with unknown cmd: %u\n", cmd);
+ err = -EFAULT;
+ break;
+ }
+
+ return err;
+}
+
+static void __multi_host_mgmt(struct hinic3_pcidev *dev,
+ struct hinic3_multi_host_mgmt_event *mhost_mgmt)
+{
+ struct hinic3_pcidev *cur_dev = NULL;
+ struct hinic3_pcidev *des_dev = NULL;
+ struct hinic3_mhost_nic_func_state *nic_state = NULL;
+ u16 sub_cmd = mhost_mgmt->sub_cmd;
+
+ switch (sub_cmd) {
+ case HINIC3_MHOST_GET_VROCE_STATE:
+ case HINIC3_MHOST_VROCE_STATE_CHANGE:
+ case HINIC3_MHOST_NIC_STATE_CHANGE:
+ nic_state = mhost_mgmt->data;
+ nic_state->status = 0;
+ if (!dev->hwdev)
+ return;
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)dev->hwdev))
+ return;
+
+ /* find func_idx pci_adapter and disable or enable nic */
+ lld_dev_hold(&dev->lld_dev);
+ list_for_each_entry(cur_dev, &dev->chip_node->func_list, node) {
+ if (cur_dev->lld_state == HINIC3_IN_REMOVE || hinic3_pdev_is_virtfn(cur_dev->pcidev))
+ continue;
+
+ des_dev = get_des_pci_adapter(cur_dev, nic_state->func_idx);
+ if (!des_dev)
+ continue;
+
+ if (__func_service_state_process(dev, des_dev, nic_state, sub_cmd))
+ nic_state->status = 1;
+ break;
+ }
+ lld_dev_put(&dev->lld_dev);
+ break;
+ default:
+ sdk_warn(&dev->pcidev->dev, "Received unknown multi-host mgmt event: %u\n",
+ mhost_mgmt->sub_cmd);
+ break;
+ }
+}
+
static void hinic3_event_process(void *adapter, struct hinic3_event_info *event)
{
struct hinic3_pcidev *dev = adapter;
struct hinic3_fault_event *fault = (void *)event->event_data;
+ struct hinic3_multi_host_mgmt_event *mhost_event = (void *)event->event_data;
u16 func_id;
- if ((event->service == EVENT_SRV_COMM && event->type == EVENT_COMM_FAULT) &&
- fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
- fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
- func_id = fault->event.chip.func_id;
- return send_event_to_dst_pf(adapter, func_id, event);
- }
-
- if (event->type == EVENT_COMM_MGMT_WATCHDOG)
+ switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MULTI_HOST_MGMT):
+ __multi_host_mgmt(dev, mhost_event);
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_FAULT):
+ if (fault->fault_level == FAULT_LEVEL_SERIOUS_FLR &&
+ fault->event.chip.func_id < hinic3_max_pf_num(dev->hwdev)) {
+ func_id = fault->event.chip.func_id;
+ return send_event_to_dst_pf(adapter, func_id, event);
+ }
+ break;
+ case HINIC3_SRV_EVENT_TYPE(EVENT_SRV_COMM, EVENT_COMM_MGMT_WATCHDOG):
send_event_to_all_pf(adapter, event);
- else
+ break;
+ default:
send_uld_dev_event(adapter, event);
+ break;
+ }
}
static void uld_def_init(struct hinic3_pcidev *pci_adapter)
@@ -631,36 +1116,75 @@ static void hinic3_pci_deinit(struct pci_dev *pdev)
kfree(pci_adapter);
}
-#ifdef CONFIG_X86
-/**
- * cfg_order_reg - when cpu model is haswell or broadwell, should configure dma
- * order register to zero
- * @pci_adapter: pci_adapter
- **/
-/*lint -save -e40 */
-static void cfg_order_reg(struct hinic3_pcidev *pci_adapter)
+static void set_vf_load_state(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
{
- u8 cpu_model[] = {0x3c, 0x3f, 0x45, 0x46, 0x3d, 0x47, 0x4f, 0x56};
- struct cpuinfo_x86 *cpuinfo = NULL;
- u32 i;
-
- if (hinic3_func_type(pci_adapter->hwdev) == TYPE_VF)
- return;
+ /* In bm mode, slave host will load vfs in default */
+ if (IS_BMGW_SLAVE_HOST(((struct hinic3_hwdev *)pci_adapter->hwdev)) &&
+ hinic3_func_type(pci_adapter->hwdev) != TYPE_VF)
+ hinic3_set_vf_load_state(pdev, false);
- cpuinfo = &cpu_data(0);
- for (i = 0; i < sizeof(cpu_model); i++) {
- if (cpu_model[i] == cpuinfo->x86_model)
- hinic3_set_pcie_order_cfg(pci_adapter->hwdev);
+ if (!disable_attach) {
+ if ((hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) &&
+ hinic3_is_bm_slave_host(pci_adapter->hwdev)) {
+ if (hinic3_func_max_vf(pci_adapter->hwdev) == 0) {
+ sdk_warn(&pdev->dev, "The sriov enabling process is skipped, vfs_num: 0.\n");
+ return;
+ }
+ hinic3_pci_sriov_enable(pdev, hinic3_func_max_vf(pci_adapter->hwdev));
+ }
}
}
-/*lint -restore*/
-#endif
-
-static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+static void hinic3_init_ppf_hwdev(struct hinic3_hwdev *hwdev)
{
- struct hinic3_init_para init_para = {0};
- bool cqm_init_en = false;
+ if (!hwdev) {
+ pr_err("[%s:%d] null hwdev pointer\n", __FILE__, __LINE__);
+ return;
+ }
+
+ hwdev->ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(hwdev->pcidev_hdl);
+ return;
+}
+
+static int set_nic_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ u16 func_id;
+ int err;
+ bool enable_nic = false;
+
+ func_id = hinic3_global_func_id(pci_adapter->hwdev);
+
+ err = hinic3_get_func_nic_enable(pci_adapter->hwdev, func_id, &enable_nic);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Failed to get nic state.\n");
+ return err;
+ }
+
+ if (!enable_nic) {
+ sdk_info(&pdev->dev, "Func %hu nic state: disable.\n", func_id);
+ detach_uld(pci_adapter, SERVICE_T_NIC);
+ return 0;
+ }
+
+ if (IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ (void)hinic3_init_vf_dev_cap(pci_adapter->hwdev);
+
+ if (g_uld_info[SERVICE_T_NIC].probe) {
+ err = attach_uld(pci_adapter, SERVICE_T_NIC, &g_uld_info[SERVICE_T_NIC]);
+ if (0 != err) {
+ sdk_err(&pdev->dev, "Initialize NIC failed\n");
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_init_para init_para = {0};
+ bool cqm_init_en = false;
int err;
init_para.adapter_hdl = pci_adapter;
@@ -715,7 +1239,16 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
list_add_tail(&pci_adapter->node, &pci_adapter->chip_node->func_list);
lld_unlock_chip_node();
+ hinic3_init_ppf_hwdev((struct hinic3_hwdev *)pci_adapter->hwdev);
+
+ set_vf_load_state(pdev, pci_adapter);
+
if (!disable_attach) {
+ /* NIC is base driver, probe firstly */
+ err = set_nic_func_state(pci_adapter);
+ if (err)
+ goto set_nic_func_state_err;
+
attach_ulds(pci_adapter);
if (hinic3_func_type(pci_adapter->hwdev) != TYPE_VF) {
@@ -726,10 +1259,6 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
goto create_sysfs_err;
}
}
-
-#ifdef CONFIG_X86
- cfg_order_reg(pci_adapter);
-#endif
}
return 0;
@@ -737,6 +1266,7 @@ static int hinic3_func_init(struct pci_dev *pdev, struct hinic3_pcidev *pci_adap
create_sysfs_err:
detach_ulds(pci_adapter);
+set_nic_func_state_err:
lld_lock_chip_node();
list_del(&pci_adapter->node);
lld_unlock_chip_node();
@@ -785,6 +1315,7 @@ static void hinic3_func_deinit(struct pci_dev *pdev)
hinic3_free_stateful(pci_adapter->hwdev);
hinic3_free_hwdev(pci_adapter->hwdev);
+ pci_adapter->hwdev = NULL;
}
static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
@@ -806,6 +1337,49 @@ static void wait_sriov_cfg_complete(struct hinic3_pcidev *pci_adapter)
} while (time_before(jiffies, end));
}
+static bool hinic3_get_vf_nic_en_status(struct pci_dev *pdev)
+{
+ bool nic_en = false;
+ u16 global_func_id;
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!pdev) {
+ pr_err("pdev is null.\n");
+ return false;
+ }
+
+ if (pdev->is_virtfn)
+ pf_pdev = pdev->physfn;
+ else
+ return false;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return false;
+ }
+
+ if (!IS_BMGW_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev))
+ return false;
+
+ if (hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id)) {
+ sdk_err(&pdev->dev, "Get vf id by vfpci failed\n");
+ return false;
+ }
+
+ if (hinic3_get_mhost_func_nic_enable(pci_adapter->hwdev,
+ global_func_id, &nic_en)) {
+ sdk_err(&pdev->dev, "Get function nic status failed\n");
+ return false;
+ }
+
+ sdk_info(&pdev->dev, "Func %hu %s default probe in host\n",
+ global_func_id, (nic_en) ? "enable" : "disable");
+
+ return nic_en;
+}
+
bool hinic3_get_vf_load_state(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = NULL;
@@ -860,6 +1434,8 @@ int hinic3_set_vf_load_state(struct pci_dev *pdev, bool vf_load_state)
}
EXPORT_SYMBOL(hinic3_set_vf_load_state);
+
+
bool hinic3_get_vf_service_load(struct pci_dev *pdev, u16 service)
{
struct hinic3_pcidev *pci_adapter = NULL;
@@ -923,6 +1499,33 @@ int hinic3_set_vf_service_load(struct pci_dev *pdev, u16 service,
}
EXPORT_SYMBOL(hinic3_set_vf_service_load);
+static bool hinic3_is_host_vmsec_enable(struct pci_dev *pdev)
+{
+ struct hinic3_pcidev *pci_adapter = NULL;
+ struct pci_dev *pf_pdev = NULL;
+
+ if (pdev->is_virtfn) {
+ pf_pdev = pdev->physfn;
+ } else {
+ pf_pdev = pdev;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ pr_err("Pci_adapter is null.\n");
+ return false;
+ }
+
+ /* pf/vf used in host */
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ (hinic3_func_type(pci_adapter->hwdev) == TYPE_PF) &&
+ IS_RDMA_TYPE((struct hinic3_hwdev *)pci_adapter->hwdev)) {
+ return true;
+ }
+
+ return false;
+}
+
static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
@@ -936,6 +1539,13 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
pci_adapter->lld_state = HINIC3_IN_REMOVE;
mutex_unlock(&pci_adapter->pdev_mutex);
+ if (!(pdev->is_virtfn) && (hinic3_is_host_vmsec_enable(pdev) == true) &&
+ (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF)) {
+ cancel_delayed_work_sync(&pci_adapter->migration_probe_dwork);
+ flush_workqueue(pci_adapter->migration_probe_workq);
+ destroy_workqueue(pci_adapter->migration_probe_workq);
+ }
+
hinic3_detect_hw_present(pci_adapter->hwdev);
hisdk3_remove_pre_process(pci_adapter->hwdev);
@@ -960,23 +1570,129 @@ static int hinic3_remove_func(struct hinic3_pcidev *pci_adapter)
sdk_info(&pdev->dev, "Pcie device removed function\n");
+ set_vf_func_in_use(pdev, false);
+
+ return 0;
+}
+
+int hinic3_get_vfid_by_vfpci(void *hwdev, struct pci_dev *pdev, u16 *global_func_id)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ u16 pf_bus, vf_bus, vf_offset;
+ int err;
+
+ if (!pdev || !global_func_id || !hinic3_pdev_is_virtfn(pdev))
+ return -EINVAL;
+ (void)hwdev;
+ pf_pdev = pdev->physfn;
+
+ vf_bus = pdev->bus->number;
+ pf_bus = pf_pdev->bus->number;
+
+ if (pdev->vendor == HINIC3_VIRTIO_VNEDER_ID) {
+ return -EPERM;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&pdev->dev, "pci_adapter is null.\n");
+ return -EINVAL;
+ }
+
+ err = hinic3_pf_get_vf_offset_info(pci_adapter, &vf_offset);
+ if (err) {
+ sdk_err(&pdev->dev, "Func hinic3_pf_get_vf_offset_info fail\n");
+ return -EFAULT;
+ }
+
+ *global_func_id = (u16)((vf_bus - pf_bus) * BUS_MAX_DEV_NUM) + (u16)pdev->devfn +
+ (u16)(CMD_MAX_MAX_PF_NUM - g_vf_offset.vf_offset_from_pf[0]);
+
return 0;
}
+EXPORT_SYMBOL(hinic3_get_vfid_by_vfpci);
+
+static void hinic3_set_vf_status_in_host(struct pci_dev *pdev, bool status)
+{
+ struct pci_dev *pf_pdev = pdev->physfn;
+ struct hinic3_pcidev *pci_adapter = NULL;
+ void *pf_hwdev = NULL;
+ void *ppf_hwdev = NULL;
+ u16 global_func_id;
+ int ret;
+
+ if (!pf_pdev)
+ return;
+
+ if (!hinic3_pdev_is_virtfn(pdev))
+ return;
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ pf_hwdev = pci_adapter->hwdev;
+ ppf_hwdev = hinic3_get_ppf_hwdev_by_pdev(pf_pdev);
+ if (!pf_hwdev || !ppf_hwdev)
+ return;
+
+ ret = hinic3_get_vfid_by_vfpci(NULL, pdev, &global_func_id);
+ if (ret) {
+ sdk_err(&pci_adapter->pcidev->dev, "Func hinic3_get_vfid_by_vfpci fail %d \n", ret);
+ return;
+ }
+
+ ret = hinic3_set_func_probe_in_host(ppf_hwdev, global_func_id, status);
+ if (ret)
+ sdk_err(&pci_adapter->pcidev->dev, "Set the function probe status in host failed\n");
+}
+#ifdef CONFIG_PCI_IOV
+static bool check_pdev_type_and_state(struct pci_dev *pdev)
+{
+ if (!(pdev->is_virtfn)) {
+ return false;
+ }
+
+ if ((hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_1_PF) &&
+ (hinic3_get_pf_device_id(pdev) != HINIC3_DEV_ID_SDI_5_0_PF)) {
+ return false;
+ }
+
+ if (!hinic3_get_vf_load_state(pdev)) {
+ return false;
+ }
+
+ return true;
+}
+#endif
static void hinic3_remove(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
+ sdk_info(&pdev->dev, "Pcie device remove begin\n");
+
if (!pci_adapter)
- return;
+ goto out;
+#ifdef CONFIG_PCI_IOV
+ if (check_pdev_type_and_state(pdev)) {
+ goto out;
+ }
+#endif
- sdk_info(&pdev->dev, "Pcie device remove begin\n");
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
hinic3_remove_func(pci_adapter);
+ if (!pci_adapter->pcidev->is_virtfn &&
+ pci_adapter->multi_host_mgmt_workq)
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
+
hinic3_pci_deinit(pdev);
hinic3_probe_pre_unprocess(pdev);
+out:
+ hinic3_set_vf_status_in_host(pdev, false);
+
sdk_info(&pdev->dev, "Pcie device removed\n");
}
@@ -995,7 +1711,7 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
if (pci_adapter->lld_state >= HINIC3_PROBE_START) {
sdk_warn(&pdev->dev, "Don not probe repeat\n");
mutex_unlock(&pci_adapter->pdev_mutex);
- return 0;
+ return -EEXIST;
}
pci_adapter->lld_state = HINIC3_PROBE_START;
mutex_unlock(&pci_adapter->pdev_mutex);
@@ -1003,15 +1719,28 @@ static int probe_func_param_init(struct hinic3_pcidev *pci_adapter)
return 0;
}
+static void hinic3_probe_success_process(struct hinic3_pcidev *pci_adapter)
+{
+ hinic3_probe_success(pci_adapter->hwdev);
+
+ mutex_lock(&pci_adapter->pdev_mutex);
+ pci_adapter->lld_state = HINIC3_PROBE_OK;
+ mutex_unlock(&pci_adapter->pdev_mutex);
+}
+
static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
{
struct pci_dev *pdev = pci_adapter->pcidev;
int err;
err = probe_func_param_init(pci_adapter);
- if (err)
+ if (err == -EEXIST)
+ return 0;
+ else if (err)
return err;
+ set_vf_func_in_use(pdev, true);
+
err = mapping_bar(pdev, pci_adapter);
if (err) {
sdk_err(&pdev->dev, "Failed to map bar\n");
@@ -1043,11 +1772,7 @@ static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter)
}
}
- hinic3_probe_success(pci_adapter->hwdev);
-
- mutex_lock(&pci_adapter->pdev_mutex);
- pci_adapter->lld_state = HINIC3_PROBE_OK;
- mutex_unlock(&pci_adapter->pdev_mutex);
+ hinic3_probe_success_process(pci_adapter);
return 0;
@@ -1063,18 +1788,299 @@ alloc_chip_node_fail:
unmapping_bar(pci_adapter);
map_bar_failed:
+ set_vf_func_in_use(pdev, false);
sdk_err(&pdev->dev, "Pcie device probe function failed\n");
return err;
}
+void hinic3_set_func_state(struct hinic3_pcidev *pci_adapter)
+{
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int err;
+ bool enable_func = false;
+
+ err = hinic3_get_function_enable(pdev, &enable_func);
+ if (err) {
+ sdk_info(&pdev->dev, "Get function enable failed\n");
+ return;
+ }
+
+ sdk_info(&pdev->dev, "%s function resource start\n",
+ enable_func ? "Initialize" : "Free");
+ if (enable_func) {
+ err = hinic3_probe_func(pci_adapter);
+ if (err)
+ sdk_info(&pdev->dev, "Function probe failed\n");
+ } else {
+ hinic3_remove_func(pci_adapter);
+ }
+ if (err == 0)
+ sdk_info(&pdev->dev, "%s function resource end\n",
+ enable_func ? "Initialize" : "Free");
+}
+
+void slave_host_mgmt_work(struct work_struct *work)
+{
+ struct hinic3_pcidev *pci_adapter =
+ container_of(work, struct hinic3_pcidev, slave_nic_work);
+
+ if (hinic3_pdev_is_virtfn(pci_adapter->pcidev))
+ hinic3_set_func_state(pci_adapter);
+ else
+ set_nic_func_state(pci_adapter);
+}
+
+static int pci_adapter_assign_val(struct hinic3_pcidev **ppci_adapter,
+ struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ *ppci_adapter = pci_get_drvdata(pdev);
+ (*ppci_adapter)->disable_vf_load = disable_vf_load;
+ (*ppci_adapter)->id = *id;
+ (*ppci_adapter)->lld_state = HINIC3_NOT_PROBE;
+ (*ppci_adapter)->probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ lld_dev_cnt_init(*ppci_adapter);
+
+ (*ppci_adapter)->multi_host_mgmt_workq =
+ alloc_workqueue("hinic_mhost_mgmt", WQ_UNBOUND,
+ HINIC3_SLAVE_WORK_MAX_NUM);
+ if (!(*ppci_adapter)->multi_host_mgmt_workq) {
+ hinic3_pci_deinit(pdev);
+ sdk_err(&pdev->dev, "Alloc multi host mgmt workqueue failed\n");
+ return -ENOMEM;
+ }
+
+ INIT_WORK(&(*ppci_adapter)->slave_nic_work, slave_host_mgmt_work);
+ INIT_WORK(&(*ppci_adapter)->slave_vroce_work,
+ slave_host_mgmt_vroce_work);
+
+ return 0;
+}
+
+static void slave_host_vfio_probe_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct hinic3_pcidev *pci_adapter = container_of(delay, struct hinic3_pcidev, migration_probe_dwork);
+ struct pci_dev *pdev = pci_adapter->pcidev;
+ int (*dev_migration_probe)(struct pci_dev *);
+ int rc;
+
+ if (hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) != TYPE_PF) {
+ return;
+ }
+
+ dev_migration_probe = __symbol_get("migration_dev_migration_probe");
+ if (!(dev_migration_probe)) {
+ sdk_err(&pdev->dev,
+ "Failed to find: migration_dev_migration_probe");
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork, WAIT_TIME * HZ);
+ } else {
+ rc = dev_migration_probe(pdev);
+ __symbol_put("migration_dev_migration_probe");
+ if (rc) {
+ sdk_err(&pdev->dev,
+ "Failed to __dev_migration_probe, rc:0x%x, pf migrated(%d).\n",
+ rc, g_is_pf_migrated);
+ } else {
+ g_is_pf_migrated = true;
+ sdk_info(&pdev->dev,
+ "Successed in __dev_migration_probe, pf migrated(%d).\n",
+ g_is_pf_migrated);
+ }
+ }
+
+ return;
+}
+
+struct vf_add_delaywork {
+ struct pci_dev *vf_pdev;
+ struct delayed_work migration_vf_add_dwork;
+};
+
+static void slave_host_migration_vf_add_delay_work(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct vf_add_delaywork *vf_add = container_of(delay, struct vf_add_delaywork, migration_vf_add_dwork);
+ struct pci_dev *vf_pdev = vf_add->vf_pdev;
+ struct pci_dev *pf_pdev = NULL;
+ int (*migration_dev_add_vf)(struct pci_dev *);
+ int ret;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!vf_pdev) {
+ pr_err("vf pdev is null.\n");
+ goto err1;
+ }
+ if (!vf_pdev->is_virtfn) {
+ sdk_err(&vf_pdev->dev, "Pdev is not virtfn.\n");
+ goto err1;
+ }
+
+ pf_pdev = vf_pdev->physfn;
+ if (!pf_pdev) {
+ sdk_err(&vf_pdev->dev, "pf_pdev is null.\n");
+ goto err1;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_err(&vf_pdev->dev, "Pci_adapter is null.\n");
+ goto err1;
+ }
+
+ if (!g_is_pf_migrated) {
+ sdk_info(&vf_pdev->dev, "pf is not migrated yet, so vf continues to try again.\n");
+ goto delay_work;
+ }
+
+ migration_dev_add_vf = __symbol_get("migration_dev_add_vf");
+ if (migration_dev_add_vf) {
+ ret = migration_dev_add_vf(vf_pdev);
+ __symbol_put("migration_dev_add_vf");
+ if (ret) {
+ sdk_err(&vf_pdev->dev,
+ "vf get migration symbol successed, but dev add vf failed, ret:%d.\n",
+ ret);
+ } else {
+ sdk_info(&vf_pdev->dev,
+ "vf get migration symbol successed, and dev add vf success.\n");
+ }
+ goto err1;
+ }
+ sdk_info(&vf_pdev->dev, "pf is migrated, but vf get migration symbol failed.\n");
+
+delay_work:
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork, WAIT_TIME * HZ);
+ return;
+
+err1:
+ kfree(vf_add);
+ return;
+}
+
+static void hinic3_probe_vf_add_dwork(struct pci_dev *pdev)
+{
+ struct pci_dev *pf_pdev = NULL;
+ struct hinic3_pcidev *pci_adapter = NULL;
+
+ if (!hinic3_is_host_vmsec_enable(pdev)) {
+ return;
+ }
+
+#if defined(CONFIG_SP_VID_DID)
+ if ((pdev->vendor == PCI_VENDOR_ID_SPNIC) && (pdev->device == HINIC3_DEV_SDI_5_1_ID_VF)) {
+#elif defined(CONFIG_NF_VID_DID)
+ if ((pdev->vendor == PCI_VENDOR_ID_NF) && (pdev->device == NFNIC_DEV_ID_VF)) {
+#else
+ if ((pdev->vendor == PCI_VENDOR_ID_HUAWEI) && (pdev->device == HINIC3_DEV_SDI_5_0_ID_VF)) {
+#endif
+ struct vf_add_delaywork *vf_add = kmalloc(sizeof(struct vf_add_delaywork), GFP_ATOMIC);
+ if (!vf_add) {
+ sdk_info(&pdev->dev, "vf_add is null.\n");
+ return;
+ }
+ vf_add->vf_pdev = pdev;
+
+ pf_pdev = pdev->physfn;
+
+ if (!pf_pdev) {
+ sdk_info(&pdev->dev, "Vf-pf_pdev is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ pci_adapter = pci_get_drvdata(pf_pdev);
+ if (!pci_adapter) {
+ sdk_info(&pdev->dev, "Pci_adapter is null.\n");
+ kfree(vf_add);
+ return;
+ }
+
+ INIT_DELAYED_WORK(&vf_add->migration_vf_add_dwork,
+ slave_host_migration_vf_add_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &vf_add->migration_vf_add_dwork,
+ WAIT_TIME * HZ);
+ }
+
+ return;
+}
+
+static int hinic3_probe_migration_dwork(struct pci_dev *pdev, struct hinic3_pcidev *pci_adapter)
+{
+ if (!hinic3_is_host_vmsec_enable(pdev)) {
+ sdk_info(&pdev->dev, "Probe_migration : hinic3_is_host_vmsec_enable is (0).\n");
+ return 0;
+ }
+
+ if (IS_VM_SLAVE_HOST((struct hinic3_hwdev *)pci_adapter->hwdev) &&
+ hinic3_func_type((struct hinic3_hwdev *)pci_adapter->hwdev) == TYPE_PF) {
+ pci_adapter->migration_probe_workq =
+ create_singlethread_workqueue("hinic3_migration_probe_delay");
+ if (!pci_adapter->migration_probe_workq) {
+ sdk_err(&pdev->dev, "Failed to create work queue:%s\n",
+ "hinic3_migration_probe_delay");
+ return -EINVAL;
+ }
+
+ INIT_DELAYED_WORK(&pci_adapter->migration_probe_dwork,
+ slave_host_vfio_probe_delay_work);
+
+ queue_delayed_work(pci_adapter->migration_probe_workq,
+ &pci_adapter->migration_probe_dwork, WAIT_TIME * HZ);
+ }
+
+ return 0;
+}
+
+static bool hinic3_os_hot_replace_allow(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_hwdev *hwdev = (struct hinic3_hwdev *)pci_adapter->hwdev;
+ // check service enable and dev is not VF
+ if (hinic3_func_type(hwdev) == TYPE_VF || hwdev->hot_replace_mode == HOT_REPLACE_DISABLE)
+ return false;
+
+ return true;
+}
+
+static bool hinic3_os_hot_replace_process(struct hinic3_pcidev *pci_adapter)
+{
+ struct hinic3_board_info *board_info;
+ u16 cur_pf_id = hinic3_global_func_id(pci_adapter->hwdev);
+ u8 cur_partion_id;
+ board_info = &((struct hinic3_hwdev *)(pci_adapter->hwdev))->board_info;
+ // probe to os
+ vpci_set_partition_attrs(pci_adapter->pcidev, PARTITION_DEV_EXCLUSIVE,
+ get_function_partition(cur_pf_id, board_info->port_num));
+
+ // check pf_id is in the right partition_id
+ cur_partion_id = get_partition_id();
+ if (get_function_partition(cur_pf_id, board_info->port_num) == cur_partion_id) {
+ return true;
+ }
+
+ pci_adapter->probe_fault_level = FAULT_LEVEL_SUGGESTION;
+ return false;
+}
+
static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct hinic3_pcidev *pci_adapter = NULL;
u16 probe_fault_level = FAULT_LEVEL_SERIOUS_FLR;
+ u32 device_id, function_id;
int err;
sdk_info(&pdev->dev, "Pcie device probe begin\n");
-
+#ifdef CONFIG_PCI_IOV
+ hinic3_set_vf_status_in_host(pdev, true);
+ if (check_pdev_type_and_state(pdev)) {
+ sdk_info(&pdev->dev, "VFs are not binded to hinic\n");
+ hinic3_probe_vf_add_dwork(pdev);
+ return -EINVAL;
+ }
+#endif
err = hinic3_probe_pre_process(pdev);
if (err != 0 && err != HINIC3_NOT_PROBE)
goto out;
@@ -1082,33 +2088,53 @@ static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (err == HINIC3_NOT_PROBE)
return 0;
- err = hinic3_pci_init(pdev);
- if (err)
+ if (hinic3_pci_init(pdev))
goto pci_init_err;
- pci_adapter = pci_get_drvdata(pdev);
- pci_adapter->disable_vf_load = disable_vf_load;
- pci_adapter->id = *id;
- pci_adapter->lld_state = HINIC3_NOT_PROBE;
- pci_adapter->probe_fault_level = probe_fault_level;
- lld_dev_cnt_init(pci_adapter);
+ if (pci_adapter_assign_val(&pci_adapter, pdev, id))
+ goto allco_queue_err;
- if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev))) {
+ if (pdev->is_virtfn && (!hinic3_get_vf_load_state(pdev)) &&
+ (!hinic3_get_vf_nic_en_status(pdev))) {
sdk_info(&pdev->dev, "VF device disable load in host\n");
return 0;
}
- err = hinic3_probe_func(pci_adapter);
- if (err)
+ if (hinic3_probe_func(pci_adapter))
+ goto hinic3_probe_func_fail;
+
+ if (hinic3_os_hot_replace_allow(pci_adapter)) {
+ if (!hinic3_os_hot_replace_process(pci_adapter)) {
+ device_id = PCI_SLOT(pdev->devfn);
+ function_id = PCI_FUNC(pdev->devfn);
+ sdk_info(&pdev->dev,
+ "os hot replace: skip function %d:%d for partition %d",
+ device_id, function_id, get_partition_id());
+ goto os_hot_repalce_not_allow;
+ }
+ }
+
+ if (hinic3_probe_migration_dwork(pdev, pci_adapter))
goto hinic3_probe_func_fail;
sdk_info(&pdev->dev, "Pcie device probed\n");
return 0;
+os_hot_repalce_not_allow:
+ hinic3_func_deinit(pdev);
+ lld_lock_chip_node();
+ free_chip_node(pci_adapter);
+ lld_unlock_chip_node();
+ unmapping_bar(pci_adapter);
+ set_vf_func_in_use(pdev, false);
+
hinic3_probe_func_fail:
+ destroy_workqueue(pci_adapter->multi_host_mgmt_workq);
+ cancel_work_sync(&pci_adapter->slave_nic_work);
+ cancel_work_sync(&pci_adapter->slave_vroce_work);
+allco_queue_err:
probe_fault_level = pci_adapter->probe_fault_level;
hinic3_pci_deinit(pdev);
-
pci_init_err:
hinic3_probe_pre_unprocess(pdev);
@@ -1131,6 +2157,10 @@ static int hinic3_get_pf_info(struct pci_dev *pdev, u16 service,
}
*pf_infos = kzalloc(sizeof(struct hinic3_hw_pf_infos), GFP_KERNEL);
+ if (*pf_infos == NULL) {
+ sdk_err(&pdev->dev, "pf_infos kzalloc failed\n");
+ return -EFAULT;
+ }
err = hinic3_get_hw_pf_infos(dev->hwdev, *pf_infos, HINIC3_CHANNEL_COMM);
if (err) {
kfree(*pf_infos);
@@ -1146,6 +2176,7 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
{
int err;
+ mutex_lock(&dst_dev->pdev_mutex);
/* unload invalid vf func id */
if (!en && vf_func_id != hinic3_global_func_id(dst_dev->hwdev) &&
!strcmp(des_pdev->driver->name, HINIC3_DRV_NAME)) {
@@ -1163,6 +2194,8 @@ static int hinic3_set_func_en(struct pci_dev *des_pdev, struct hinic3_pcidev *ds
err = hinic3_probe_func(dst_dev);
if (err)
return -EFAULT;
+ } else {
+ mutex_unlock(&dst_dev->pdev_mutex);
}
return 0;
@@ -1187,7 +2220,6 @@ static int get_vf_service_state_param(struct pci_dev *pdev, struct hinic3_pcidev
return 0;
}
-#define BUS_MAX_DEV_NUM 256
static int hinic3_dst_pdev_valid(struct hinic3_pcidev *dst_dev, struct pci_dev **des_pdev_ptr,
u16 vf_devfn, bool en)
{
@@ -1245,7 +2277,7 @@ int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id, u16 servic
lld_hold();
list_for_each_entry(dst_dev, &dev->chip_node->func_list, node) {
- if (paramerter_is_unexpected(dst_dev, &func_id, &vf_start, &vf_end, vf_func_id))
+ if (paramerter_is_unexpected(dst_dev, &func_id, &vf_start, &vf_end, vf_func_id) != 0)
continue;
vf_devfn = pf_infos->infos[func_id].vf_offset + (vf_func_id - vf_start) +
@@ -1269,7 +2301,6 @@ int hinic3_set_vf_service_state(struct pci_dev *pdev, u16 vf_func_id, u16 servic
if (en)
pci_dev_put(des_pdev);
- mutex_lock(&dst_dev->pdev_mutex);
find_dst_dev = true;
break;
}
@@ -1289,19 +2320,18 @@ free_pf_info:
}
EXPORT_SYMBOL(hinic3_set_vf_service_state);
-/*lint -save -e133 -e10*/
static const struct pci_device_id hinic3_pci_table[] = {
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SPU), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_STANDARD), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
- {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_1_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_SDI_5_0_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_DPU_PF), 0},
+ {PCI_VDEVICE(HUAWEI, HINIC3_DEV_SDI_5_1_ID_VF), 0},
{PCI_VDEVICE(HUAWEI, HINIC3_DEV_ID_VF), 0},
{0, 0}
};
-/*lint -restore*/
-
MODULE_DEVICE_TABLE(pci, hinic3_pci_table);
/**
@@ -1333,14 +2363,27 @@ static pci_ers_result_t hinic3_io_error_detected(struct pci_dev *pdev,
return PCI_ERS_RESULT_CAN_RECOVER;
}
+static void hinic3_timer_disable(void *hwdev)
+{
+ if (!hwdev)
+ return;
+
+ if (hinic3_get_stateful_enable(hwdev) && hinic3_get_timer_enable(hwdev))
+ (void)hinic3_func_tmr_bitmap_set(hwdev, hinic3_global_func_id(hwdev), false);
+
+ return;
+}
+
static void hinic3_shutdown(struct pci_dev *pdev)
{
struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev);
sdk_info(&pdev->dev, "Shutdown device\n");
- if (pci_adapter)
+ if (pci_adapter) {
+ hinic3_timer_disable(pci_adapter->hwdev);
hinic3_shutdown_hwdev(pci_adapter->hwdev);
+ }
pci_disable_device(pdev);
@@ -1367,6 +2410,9 @@ static struct pci_driver hinic3_driver = {
.probe = hinic3_probe,
.remove = hinic3_remove,
.shutdown = hinic3_shutdown,
+#ifdef CONFIG_PARTITION_DEVICE
+ .driver.probe_concurrency = true,
+#endif
#if defined(HAVE_SRIOV_CONFIGURE)
.sriov_configure = hinic3_pci_sriov_configure,
#elif defined(HAVE_RHEL6_SRIOV_CONFIGURE)
@@ -1388,16 +2434,21 @@ int hinic3_lld_init(void)
err = hinic3_module_pre_init();
if (err) {
pr_err("Init custom failed\n");
- return err;
+ goto module_pre_init_err;
}
err = pci_register_driver(&hinic3_driver);
if (err) {
- hinic3_module_post_exit();
- return err;
+ pr_err("sdk3 pci register driver failed\n");
+ goto register_pci_driver_err;
}
return 0;
+
+register_pci_driver_err:
+ hinic3_module_post_exit();
+module_pre_init_err:
+ return err;
}
void hinic3_lld_exit(void)
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
index d2a7dd7..5398a34 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mbox.c
@@ -584,6 +584,7 @@ static void free_recv_mbox(struct hinic3_recv_mbox *recv_msg)
kfree(recv_msg->resp_buff);
kfree(recv_msg->msg);
kfree(recv_msg);
+ recv_msg = NULL;
}
static void recv_func_mbox_work_handler(struct work_struct *work)
@@ -1233,6 +1234,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
set_mbox_to_func_event(func_to_func, EVENT_FAIL);
goto send_err;
}
+ func_to_func->hwdev->mbox_send_cnt++;
if (wait_mbox_msg_completion(func_to_func, timeout) != 0) {
sdk_err(func_to_func->hwdev->dev_hdl,
@@ -1241,6 +1243,7 @@ int hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, u8 mod, u16 cmd,
err = -ETIMEDOUT;
goto send_err;
}
+ func_to_func->hwdev->mbox_ack_cnt++;
if (mod != msg_desc->mod || cmd != msg_desc->cmd) {
sdk_err(func_to_func->hwdev->dev_hdl,
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
index 3ad9a77..0d75177 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_mgmt.c
@@ -348,7 +348,7 @@ int hinic3_pf_to_mgmt_sync(void *hwdev, u8 mod, u16 cmd, void *buf_in,
if (!COMM_SUPPORT_API_CHAIN((struct hinic3_hwdev *)hwdev))
return -EPERM;
- if (!buf_in || in_size == 0)
+ if ((buf_in == NULL) || (in_size == 0))
return -EINVAL;
ret = msg_to_mgmt_pre(mod, buf_in, in_size);
@@ -864,6 +864,7 @@ static int alloc_recv_msg(struct hinic3_recv_msg *recv_msg)
static void free_recv_msg(struct hinic3_recv_msg *recv_msg)
{
kfree(recv_msg->msg);
+ recv_msg->msg = NULL;
}
/**
@@ -935,6 +936,9 @@ static void free_msg_buf(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt)
free_recv_msg(&pf_to_mgmt->recv_resp_msg_from_mgmt);
free_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
+ pf_to_mgmt->mgmt_ack_buf = NULL;
+ pf_to_mgmt->sync_msg_buf = NULL;
+ pf_to_mgmt->async_msg_buf = NULL;
}
/**
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
index 3548410..b619800 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_multi_host_mgmt.c
@@ -676,6 +676,11 @@ static int hinic3_register_slave_ppf(struct hinic3_hwdev *hwdev, bool registered
if (!IS_SLAVE_HOST(hwdev))
return -EINVAL;
+ /* if unsupport hot plug, return true. */
+ if (UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev)) {
+ return 0;
+ }
+
host_info = kcalloc(1, sizeof(struct register_slave_host), GFP_KERNEL);
if (!host_info)
return -ENOMEM;
@@ -1074,8 +1079,9 @@ int hinic3_get_func_nic_enable(void *hwdev, u16 glb_func_idx, bool *en)
if (!hwdev || !en)
return -EINVAL;
- /* if single host, return true. */
- if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev)) {
+ /* if single host or unsupport hot plug, return true. */
+ if (!IS_MULTI_HOST((struct hinic3_hwdev *)hwdev) ||
+ UNSUPPORT_HOT_PLUG((struct hinic3_hwdev *)hwdev)) {
*en = true;
return 0;
}
@@ -1145,11 +1151,18 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
{
int err;
struct service_cap *cap = &hwdev->cfg_mgmt->svc_cap;
+ int is_use_vram, is_in_kexec;
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
- hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0) {
+ snprintf(hwdev->mhost_mgmt_name, VRAM_NAME_MAX_LEN, "%s", VRAM_NIC_MHOST_MGMT);
+ hwdev->mhost_mgmt = hi_vram_kalloc(hwdev->mhost_mgmt_name, sizeof(*hwdev->mhost_mgmt));
+ } else {
+ hwdev->mhost_mgmt = kcalloc(1, sizeof(*hwdev->mhost_mgmt), GFP_KERNEL);
+ }
if (!hwdev->mhost_mgmt)
return -ENOMEM;
@@ -1165,8 +1178,11 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK, hwdev, hilink_ppf_mbox_handler);
hinic3_register_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC, hwdev, sw_func_ppf_mbox_handler);
- bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
- bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ is_in_kexec = vram_get_kexec_flag();
+ if (is_in_kexec == 0) {
+ bitmap_zero(hwdev->mhost_mgmt->func_nic_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ bitmap_zero(hwdev->mhost_mgmt->func_vroce_en, HINIC3_MAX_MGMT_FUNCTIONS);
+ }
/* Slave host:
* register slave host ppf functions
@@ -1179,7 +1195,13 @@ int hinic3_multi_host_mgmt_init(struct hinic3_hwdev *hwdev)
return 0;
out_free_mhost_mgmt:
- kfree(hwdev->mhost_mgmt);
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)hwdev->mhost_mgmt,
+ hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ } else {
+ kfree(hwdev->mhost_mgmt);
+ }
hwdev->mhost_mgmt = NULL;
return err;
@@ -1187,6 +1209,7 @@ out_free_mhost_mgmt:
int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
{
+ int is_use_vram;
if (!IS_MULTI_HOST(hwdev) || !HINIC3_IS_PPF(hwdev))
return 0;
@@ -1203,7 +1226,14 @@ int hinic3_multi_host_mgmt_free(struct hinic3_hwdev *hwdev)
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_HILINK);
hinic3_unregister_ppf_mbox_cb(hwdev, HINIC3_MOD_SW_FUNC);
- kfree(hwdev->mhost_mgmt);
+ is_use_vram = get_use_vram_flag();
+ if (is_use_vram != 0) {
+ hi_vram_kfree((void *)hwdev->mhost_mgmt,
+ hwdev->mhost_mgmt_name,
+ sizeof(*hwdev->mhost_mgmt));
+ } else {
+ kfree(hwdev->mhost_mgmt);
+ }
hwdev->mhost_mgmt = NULL;
return 0;
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
index f7d350c..ee7afef 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.c
@@ -14,6 +14,7 @@
#include "hinic3_crm.h"
#include "hinic3_hw.h"
#include "hinic3_hw_cfg.h"
+#include "hinic3_dev_mgmt.h"
#include "hinic3_hwdev.h"
#include "hinic3_lld.h"
#include "hinic3_hw_mt.h"
@@ -22,9 +23,7 @@
static int g_nictool_ref_cnt;
static dev_t g_dev_id = {0};
-/*lint -save -e104 -e808*/
static struct class *g_nictool_class;
-/*lint -restore*/
static struct cdev g_nictool_cdev;
#define HINIC3_MAX_BUF_SIZE (2048 * 1024)
@@ -92,6 +91,21 @@ static int get_all_chip_id_cmd(struct hinic3_lld_dev *lld_dev, const void *buf_i
return 0;
}
+static int get_os_hot_replace_info(struct hinic3_lld_dev *lld_dev,
+ const void *buf_in, u32 in_size,
+ void *buf_out, u32 *out_size)
+{
+ if (*out_size != sizeof(struct os_hot_replace_info) || !buf_out) {
+ pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
+ *out_size, sizeof(struct os_hot_replace_info));
+ return -EFAULT;
+ }
+
+ hinic3_get_os_hot_replace_info(buf_out);
+
+ return 0;
+}
+
static int get_card_usr_api_chain_mem(int card_idx)
{
unsigned char *tmp = NULL;
@@ -100,8 +114,8 @@ static int get_card_usr_api_chain_mem(int card_idx)
card_id = card_idx;
if (!g_card_vir_addr[card_idx]) {
g_card_vir_addr[card_idx] =
- (void *)__get_free_pages(GFP_KERNEL,
- DBGTOOL_PAGE_ORDER);
+ (void *)ossl_get_free_pages(GFP_KERNEL,
+ DBGTOOL_PAGE_ORDER);
if (!g_card_vir_addr[card_idx]) {
pr_err("Alloc api chain memory fail for card %d!\n", card_idx);
return -EFAULT;
@@ -166,7 +180,7 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
if (!buf_out || *out_size != sizeof(struct pf_dev_info) * PF_DEV_INFO_NUM) {
pr_err("Invalid parameter: out_buf_size %u, expect %lu\n",
- *out_size, sizeof(dev_info) * PF_DEV_INFO_NUM);
+ *out_size, sizeof(*dev_info) * PF_DEV_INFO_NUM);
return -EFAULT;
}
@@ -193,13 +207,18 @@ static int get_pf_dev_info(struct hinic3_lld_dev *lld_dev, const void *buf_in, u
return 0;
}
-static long dbgtool_knl_free_mem(int id)
+static void dbgtool_knl_free_mem(int id)
{
unsigned char *tmp = NULL;
int i;
+ if (id < 0 || id >= MAX_CARD_NUM) {
+ pr_err("Invalid card id\n");
+ return;
+ }
+
if (!g_card_vir_addr[id])
- return 0;
+ return;
tmp = g_card_vir_addr[id];
for (i = 0; i < (1 << DBGTOOL_PAGE_ORDER); i++) {
@@ -210,8 +229,6 @@ static long dbgtool_knl_free_mem(int id)
free_pages((unsigned long)g_card_vir_addr[id], DBGTOOL_PAGE_ORDER);
g_card_vir_addr[id] = NULL;
g_card_phy_addr[id] = 0;
-
- return 0;
}
static int free_knl_mem(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_size,
@@ -236,7 +253,8 @@ static int free_knl_mem(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32
return 0;
}
-static int card_info_param_valid(char *dev_name, const void *buf_out, u32 buf_out_size, int *id)
+static int card_info_param_valid(const char *dev_name, const void *buf_out,
+ u32 buf_out_size, int *id)
{
int err;
@@ -351,7 +369,7 @@ static int get_hw_drv_version(struct hinic3_lld_dev *lld_dev, const void *buf_in
}
err = snprintf(ver_info->ver, sizeof(ver_info->ver), "%s %s", HINIC3_DRV_VERSION,
- "2023-05-17_19:56:38");
+ "2025-05-01_00:00:03");
if (err < 0)
return -EINVAL;
@@ -386,22 +404,38 @@ static int get_pf_id(struct hinic3_lld_dev *lld_dev, const void *buf_in, u32 in_
return 0;
}
+static int get_mbox_cnt(struct hinic3_lld_dev *lld_dev, const void *buf_in,
+ u32 in_size, void *buf_out, u32 *out_size)
+{
+ if (buf_out == NULL || *out_size != sizeof(struct card_mbox_cnt_info)) {
+ pr_err("buf_out is NULL, or out_size != %lu\n",
+ sizeof(struct card_info));
+ return -EINVAL;
+ }
+
+ hinic3_get_mbox_cnt(hinic3_get_sdk_hwdev_by_lld(lld_dev), buf_out);
+
+ return 0;
+}
+
struct hw_drv_module_handle hw_driv_module_cmd_handle[] = {
- {FUNC_TYPE, get_func_type},
- {GET_FUNC_IDX, get_func_id},
- {GET_HW_STATS, (hw_driv_module)get_hw_driver_stats},
- {CLEAR_HW_STATS, clear_hw_driver_stats},
- {GET_SELF_TEST_RES, get_self_test_result},
- {GET_CHIP_FAULT_STATS, (hw_driv_module)get_chip_faults_stats},
- {GET_SINGLE_CARD_INFO, (hw_driv_module)get_single_card_info},
- {IS_DRV_IN_VM, is_driver_in_vm},
- {GET_CHIP_ID, get_all_chip_id_cmd},
- {GET_PF_DEV_INFO, get_pf_dev_info},
- {CMD_FREE_MEM, free_knl_mem},
- {GET_CHIP_INFO, get_card_func_info},
- {GET_FUNC_CAP, get_pf_cap_info},
- {GET_DRV_VERSION, get_hw_drv_version},
- {GET_PF_ID, get_pf_id},
+ {FUNC_TYPE, get_func_type},
+ {GET_FUNC_IDX, get_func_id},
+ {GET_HW_STATS, (hw_driv_module)get_hw_driver_stats},
+ {CLEAR_HW_STATS, clear_hw_driver_stats},
+ {GET_SELF_TEST_RES, get_self_test_result},
+ {GET_CHIP_FAULT_STATS, (hw_driv_module)get_chip_faults_stats},
+ {GET_SINGLE_CARD_INFO, (hw_driv_module)get_single_card_info},
+ {IS_DRV_IN_VM, is_driver_in_vm},
+ {GET_CHIP_ID, get_all_chip_id_cmd},
+ {GET_PF_DEV_INFO, get_pf_dev_info},
+ {CMD_FREE_MEM, free_knl_mem},
+ {GET_CHIP_INFO, get_card_func_info},
+ {GET_FUNC_CAP, get_pf_cap_info},
+ {GET_DRV_VERSION, get_hw_drv_version},
+ {GET_PF_ID, get_pf_id},
+ {GET_OS_HOT_REPLACE_INFO, get_os_hot_replace_info},
+ {GET_MBOX_CNT, (hw_driv_module)get_mbox_cnt},
};
static int alloc_tmp_buf(void *hwdev, struct msg_module *nt_msg, u32 in_size,
@@ -439,8 +473,8 @@ static void free_tmp_buf(void *hwdev, struct msg_module *nt_msg,
static int send_to_hw_driver(struct hinic3_lld_dev *lld_dev, struct msg_module *nt_msg,
const void *buf_in, u32 in_size, void *buf_out, u32 *out_size)
{
- int index, num_cmds = sizeof(hw_driv_module_cmd_handle) /
- sizeof(hw_driv_module_cmd_handle[0]);
+ int index, num_cmds = (int)(sizeof(hw_driv_module_cmd_handle) /
+ sizeof(hw_driv_module_cmd_handle[0]));
enum driver_cmd_type cmd_type =
(enum driver_cmd_type)(nt_msg->msg_formate);
int err = 0;
@@ -482,8 +516,8 @@ static int send_to_service_driver(struct hinic3_lld_dev *lld_dev, struct msg_mod
if (nt_msg->msg_formate == GET_DRV_VERSION)
return 0;
- pr_err("Can not get the uld dev correctly: %s, %s driver may be not register\n",
- nt_msg->device_name, service_name[type]);
+ pr_err("Can not get the uld dev correctly: %s driver may be not register\n",
+ service_name[type]);
return -EINVAL;
}
@@ -550,26 +584,29 @@ static struct hinic3_lld_dev *get_lld_dev_by_nt_msg(struct msg_module *nt_msg)
{
struct hinic3_lld_dev *lld_dev = NULL;
- if (nt_msg->module >= SEND_TO_SRV_DRV_BASE && nt_msg->module < SEND_TO_DRIVER_MAX &&
- nt_msg->module != SEND_TO_HW_DRIVER && nt_msg->msg_formate != GET_DRV_VERSION) {
+ if (nt_msg->module == SEND_TO_NIC_DRIVER &&
+ (nt_msg->msg_formate == GET_XSFP_INFO ||
+ nt_msg->msg_formate == GET_XSFP_PRESENT ||
+ nt_msg->msg_formate == GET_XSFP_INFO_COMP_CMIS)) {
+ lld_dev = hinic3_get_lld_dev_by_chip_and_port(nt_msg->device_name, nt_msg->port_id);
+ } else if (nt_msg->module == SEND_TO_CUSTOM_DRIVER &&
+ nt_msg->msg_formate == CMD_CUSTOM_BOND_GET_CHIP_NAME) {
+ lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
+ SERVICE_T_MAX);
+ } else if (nt_msg->module == SEND_TO_VBS_DRIVER ||
+ nt_msg->module == SEND_TO_BIFUR_DRIVER) {
+ lld_dev = hinic3_get_lld_dev_by_chip_name(nt_msg->device_name);
+ } else if (nt_msg->module >= SEND_TO_SRV_DRV_BASE &&
+ nt_msg->module < SEND_TO_DRIVER_MAX &&
+ nt_msg->msg_formate != GET_DRV_VERSION) {
lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
nt_msg->module - SEND_TO_SRV_DRV_BASE);
} else {
lld_dev = hinic3_get_lld_dev_by_chip_name(nt_msg->device_name);
if (!lld_dev)
- lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name,
- SERVICE_T_MAX);
+ lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name, SERVICE_T_MAX);
}
- if (nt_msg->module == SEND_TO_NIC_DRIVER && (nt_msg->msg_formate == GET_XSFP_INFO ||
- nt_msg->msg_formate == GET_XSFP_PRESENT))
- lld_dev = hinic3_get_lld_dev_by_chip_and_port(nt_msg->device_name,
- nt_msg->port_id);
-
- if (nt_msg->module == SEND_TO_CUSTOM_DRIVER &&
- nt_msg->msg_formate == CMD_CUSTOM_BOND_GET_CHIP_NAME)
- lld_dev = hinic3_get_lld_dev_by_dev_name(nt_msg->device_name, SERVICE_T_MAX);
-
return lld_dev;
}
@@ -591,14 +628,16 @@ static long hinicadm_k_unlocked_ioctl(struct file *pfile, unsigned long arg)
lld_dev = get_lld_dev_by_nt_msg(&nt_msg);
if (!lld_dev) {
if (nt_msg.msg_formate != DEV_NAME_TEST)
- pr_err("Can not find device %s for module %d\n",
+ pr_err("Can not find device %s for module %u\n",
nt_msg.device_name, nt_msg.module);
return -ENODEV;
}
- if (nt_msg.msg_formate == DEV_NAME_TEST)
+ if (nt_msg.msg_formate == DEV_NAME_TEST) {
+ lld_dev_put(lld_dev);
return 0;
+ }
ret = alloc_tmp_buf(hinic3_get_sdk_hwdev_by_lld(lld_dev), &nt_msg,
in_size, &buf_in, out_size_expect, &buf_out);
@@ -642,6 +681,9 @@ out_free_lock:
static long dbgtool_knl_ffm_info_rd(struct dbgtool_param *para,
struct dbgtool_k_glb_info *dbgtool_info)
{
+ if (!para->param.ffm_rd || !dbgtool_info->ffm)
+ return -EINVAL;
+
/* Copy the ffm_info to user mode */
if (copy_to_user(para->param.ffm_rd, dbgtool_info->ffm,
(unsigned int)sizeof(struct ffm_record_info))) {
@@ -674,13 +716,14 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
card_info = (struct card_node *)g_card_node_array[i];
if (!card_info)
continue;
- if (!strncmp(param.chip_name, card_info->chip_name, IFNAMSIZ))
+ if (memcmp(param.chip_name, card_info->chip_name,
+ strlen(card_info->chip_name) + 1) == 0)
break;
}
if (i == MAX_CARD_NUM || !card_info) {
lld_put();
- pr_err("Can't find this card %s\n", param.chip_name);
+ pr_err("Can't find this card.\n");
return -EFAULT;
}
@@ -701,6 +744,7 @@ static long dbgtool_k_unlocked_ioctl(struct file *pfile,
default:
pr_err("Dbgtool cmd(0x%x) not support now\n", real_cmd);
ret = -EFAULT;
+ break;
}
up(&dbgtool_info->dbgtool_sem);
@@ -746,9 +790,11 @@ static long nictool_k_unlocked_ioctl(struct file *pfile,
static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
{
+ pgprot_t vm_page_prot;
unsigned long vmsize = vma->vm_end - vma->vm_start;
phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
phys_addr_t phy_addr;
+ int err = 0;
if (vmsize > (PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER))) {
pr_err("Map size = %lu is bigger than alloc\n", vmsize);
@@ -757,14 +803,18 @@ static int hinic3_mem_mmap(struct file *filp, struct vm_area_struct *vma)
/* old version of tool set vma->vm_pgoff to 0 */
phy_addr = offset ? offset : g_card_phy_addr[card_id];
-
- if (!phy_addr) {
- pr_err("Card_id = %d physical address is 0\n", card_id);
- return -EAGAIN;
+ /* check phy_addr valid */
+ if (phy_addr != g_card_phy_addr[card_id]) {
+ err = hinic3_bar_mmap_param_valid(phy_addr, vmsize);
+ if (err != 0) {
+ pr_err("mmap param invalid, err: %d\n", err);
+ return err;
+ }
}
/* Disable cache and write buffer in the mapping area */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_page_prot = vm_page_prot;
if (remap_pfn_range(vma, vma->vm_start, (phy_addr >> PAGE_SHIFT),
vmsize, vma->vm_page_prot)) {
pr_err("Remap pfn range failed.\n");
@@ -787,7 +837,6 @@ static const struct file_operations fifo_operations = {
static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
{
struct dbgtool_k_glb_info *dbgtool_info = NULL;
- int err, id;
if (hinic3_func_type(hwdev) != TYPE_VF)
chip_info->func_handle_array[hinic3_global_func_id(hwdev)] = NULL;
@@ -795,23 +844,23 @@ static void free_dbgtool_info(void *hwdev, struct card_node *chip_info)
if (--chip_info->func_num)
return;
- err = sscanf(chip_info->chip_name, HINIC3_CHIP_NAME "%d", &id);
- if (err < 0)
- pr_err("Failed to get card id\n");
-
- if (id < MAX_CARD_NUM)
- g_card_node_array[id] = NULL;
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ g_card_node_array[chip_info->chip_id] = NULL;
dbgtool_info = chip_info->dbgtool_info;
/* FFM deinit */
- kfree(dbgtool_info->ffm);
- dbgtool_info->ffm = NULL;
+ if (dbgtool_info && dbgtool_info->ffm) {
+ kfree(dbgtool_info->ffm);
+ dbgtool_info->ffm = NULL;
+ }
+
+ if (dbgtool_info)
+ kfree(dbgtool_info);
- kfree(dbgtool_info);
chip_info->dbgtool_info = NULL;
- if (id < MAX_CARD_NUM)
- (void)dbgtool_knl_free_mem(id);
+ if (chip_info->chip_id >= 0 && chip_info->chip_id < MAX_CARD_NUM)
+ dbgtool_knl_free_mem(chip_info->chip_id);
}
static int alloc_dbgtool_info(void *hwdev, struct card_node *chip_info)
@@ -872,7 +921,6 @@ dbgtool_info_fail:
* nictool_k_init - initialize the hw interface
**/
/* temp for dbgtool_info */
-/*lint -e438*/
int nictool_k_init(void *hwdev, void *chip_node)
{
struct card_node *chip_info = (struct card_node *)chip_node;
@@ -895,9 +943,7 @@ int nictool_k_init(void *hwdev, void *chip_node)
}
/* Create equipment */
- /*lint -save -e160*/
g_nictool_class = class_create(THIS_MODULE, HIADM3_DEV_CLASS);
- /*lint -restore*/
if (IS_ERR(g_nictool_class)) {
pr_err("Create nictool_class fail\n");
err = -EFAULT;
@@ -944,7 +990,7 @@ alloc_chdev_fail:
free_dbgtool_info(hwdev, chip_info);
return err;
-} /*lint +e438*/
+}
void nictool_k_uninit(void *hwdev, void *chip_node)
{
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
index f368133..c943dfc 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_nictool.h
@@ -18,6 +18,8 @@
int nictool_k_init(void *hwdev, void *chip_node);
void nictool_k_uninit(void *hwdev, void *chip_node);
+void hinic3_get_os_hot_replace_info(void *oshr_info);
+
void hinic3_get_all_chip_id(void *id_info);
void hinic3_get_card_func_info_by_card_name
@@ -29,6 +31,8 @@ bool hinic3_is_in_host(void);
int hinic3_get_pf_id(struct card_node *chip_node, u32 port_id, u32 *pf_id, u32 *isvalid);
+void hinic3_get_mbox_cnt(const void *hwdev, void *bufin);
+
extern struct hinic3_uld_info g_uld_info[SERVICE_T_MAX];
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
index 2d5423e..6f145a0 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_pci_id_tbl.h
@@ -19,6 +19,20 @@
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
+#elif defined(CONFIG_NF_VID_DID)
+#define PCI_VENDOR_ID_NF 0x2036
+#define NFNIC_DEV_ID_STANDARD 0x1618
+#define NFNIC_DEV_ID_SDI_5_1_PF 0x0226
+#define NFNIC_DEV_ID_SDI_5_0_PF 0x0225
+#define NFNIC_DEV_ID_DPU_PF 0x0224
+#define NFNIC_DEV_ID_VF 0x1619
+#define NFNIC_DEV_ID_VF_HV 0x379F
+#define NFNIC_DEV_SDI_5_1_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_0_ID_VF 0x375F
+#define NFNIC_DEV_SDI_5_1_ID_VF_HV 0x379F
+#define NFNIC_DEV_ID_SPU 0xAC00
+#define NFNIC_DEV_SDI_5_1_SSDID_VF 0x1000
+#define NFNIC_DEV_SDI_V100_SSDID_MASK (3 << 12)
#else
#define PCI_VENDOR_ID_HUAWEI 0x19e5
#define HINIC3_DEV_ID_STANDARD 0x0222
@@ -28,16 +42,33 @@
#define HINIC3_DEV_ID_VF 0x375F
#define HINIC3_DEV_ID_VF_HV 0x379F
#define HINIC3_DEV_SDI_5_1_ID_VF 0x375F
+#define HINIC3_DEV_SDI_5_0_ID_VF 0x375F
#define HINIC3_DEV_SDI_5_1_ID_VF_HV 0x379F
#define HINIC3_DEV_ID_SPU 0xAC00
#define HINIC3_DEV_SDI_5_1_SSDID_VF 0x1000
#define HINIC3_DEV_SDI_V100_SSDID_MASK (3 << 12)
#endif
+#define NFNIC_DEV_SSID_2X25G_NF 0x0860
+#define NFNIC_DEV_SSID_4X25G_NF 0x0861
+#define NFNIC_DEV_SSID_2x100G_NF 0x0862
+#define NFNIC_DEV_SSID_2x200G_NF 0x0863
+
+#define HINIC3_DEV_SSID_2X10G 0x0035
#define HINIC3_DEV_SSID_2X25G 0x0051
#define HINIC3_DEV_SSID_4X25G 0x0052
+#define HINIC3_DEV_SSID_4X25G_BD 0x0252
+#define HINIC3_DEV_SSID_4X25G_SMARTNIC 0x0152
+#define HINIC3_DEV_SSID_6X25G_VL 0x0356
#define HINIC3_DEV_SSID_2X100G 0x00A1
+#define HINIC3_DEV_SSID_2X100G_SMARTNIC 0x01A1
+#define HINIC3_DEV_SSID_2X200G 0x04B1
#define HINIC3_DEV_SSID_2X100G_VF 0x1000
+#define HINIC3_DEV_SSID_HPC_4_HOST_NIC 0x005A
+#define HINIC3_DEV_SSID_2X200G_VL 0x00B1
+#define HINIC3_DEV_SSID_1X100G 0x02A4
+
+#define BIFUR_RESOURCE_PF_SSID 0x05a1
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
index b23b69f..c8258ff 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_sriov.c
@@ -68,7 +68,6 @@ ssize_t hinic3_sriov_numvfs_show(struct device *dev,
return sprintf(buf, "%d\n", pci_num_vf(pdev));
}
-/*lint -save -e713*/
ssize_t hinic3_sriov_numvfs_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -116,7 +115,6 @@ ssize_t hinic3_sriov_numvfs_store(struct device *dev,
return count;
}
-/*lint -restore*/
#endif /* !(HAVE_SRIOV_CONFIGURE || HAVE_RHEL6_SRIOV_CONFIGURE) */
int hinic3_pci_sriov_disable(struct pci_dev *dev)
@@ -174,24 +172,15 @@ int hinic3_pci_sriov_disable(struct pci_dev *dev)
return 0;
}
-int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
-{
#ifdef CONFIG_PCI_IOV
- struct hinic3_sriov_info *sriov_info = NULL;
- struct hinic3_event_info event = {0};
- void *hwdev = NULL;
- int pre_existing_vfs = 0;
- int err = 0;
-
- sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
- hwdev = hinic3_get_hwdev_by_pcidev(dev);
- if (!hwdev) {
- sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
- return -EPERM;
- }
+int hinic3_pci_sriov_check(struct hinic3_sriov_info *sriov_info, struct pci_dev *dev, int num_vfs)
+{
+ int pre_existing_vfs;
+ int err;
if (test_and_set_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state)) {
- sdk_err(&dev->dev, "SR-IOV enable in process, please wait, num_vfs %d\n",
+ sdk_err(&dev->dev,
+ "SR-IOV enable in process, please wait, num_vfs %d\n",
num_vfs);
return -EPERM;
}
@@ -202,6 +191,7 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
clear_bit(HINIC3_SRIOV_ENABLE, &sriov_info->state);
return -ERANGE;
}
+
if (pre_existing_vfs && pre_existing_vfs != num_vfs) {
err = hinic3_pci_sriov_disable(dev);
if (err) {
@@ -213,6 +203,31 @@ int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
return num_vfs;
}
+ return 0;
+}
+#endif
+
+
+int hinic3_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
+{
+#ifdef CONFIG_PCI_IOV
+ struct hinic3_sriov_info *sriov_info = NULL;
+ struct hinic3_event_info event = {0};
+ void *hwdev = NULL;
+ int err = 0;
+
+ sriov_info = hinic3_get_sriov_info_by_pcidev(dev);
+ hwdev = hinic3_get_hwdev_by_pcidev(dev);
+ if (!hwdev) {
+ sdk_err(&dev->dev, "SR-IOV enable is not permitted, please wait...\n");
+ return -EPERM;
+ }
+
+ err = hinic3_pci_sriov_check(sriov_info, dev, num_vfs);
+ if (err != 0) {
+ return err;
+ }
+
err = hinic3_init_vf_hw(hwdev, 1, (u16)num_vfs);
if (err) {
sdk_err(&dev->dev, "Failed to init vf in hardware before enable sriov, error %d\n",
@@ -262,6 +277,3 @@ int hinic3_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
else
return hinic3_pci_sriov_enable(dev, num_vfs);
}
-
-/*lint -restore*/
-
diff --git a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c
index 2f5e098..4f8acd6 100644
--- a/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c
+++ b/drivers/net/ethernet/huawei/hinic3/hw/hinic3_wq.c
@@ -128,7 +128,7 @@ int hinic3_wq_create(void *hwdev, struct hinic3_wq *wq, u32 q_depth,
wq_page_size = ALIGN(dev->wq_page_size, PAGE_SIZE);
- memset(wq, 0, sizeof(*wq));
+ memset(wq, 0, sizeof(struct hinic3_wq));
wq->dev_hdl = dev->dev_hdl;
wq->q_depth = q_depth;
wq->idx_mask = (u16)(q_depth - 1);
diff --git a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
index 9e8fc75..bfb4499 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/bond/bond_common_defs.h
@@ -10,6 +10,10 @@
#define OVS_PORT_NUM_MAX BOND_PORT_MAX_NUM
#define DEFAULT_ROCE_BOND_FUNC 0xFFFFFFFF
+#define BOND_ID_IS_VALID(_id) \
+ (((_id) >= BOND_FIRST_ID) && ((_id) <= BOND_MAX_ID))
+#define BOND_ID_IS_INVALID(_id) (!(BOND_ID_IS_VALID(_id)))
+
enum bond_group_id {
BOND_FIRST_ID = 1,
BOND_MAX_ID = 4,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
index f56df08..f9737ea 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/cfg_mgmt/cfg_mgmt_mpu_cmd_defs.h
@@ -21,6 +21,7 @@ enum servic_bit_define {
SERVICE_BIT_PPA = 11,
SERVICE_BIT_MIGRATE = 12,
SERVICE_BIT_VROCE = 13,
+ SERVICE_BIT_BIFUR = 14,
SERVICE_BIT_MAX
};
@@ -38,6 +39,7 @@ enum servic_bit_define {
#define CFG_SERVICE_MASK_PPA (0x1 << SERVICE_BIT_PPA)
#define CFG_SERVICE_MASK_MIGRATE (0x1 << SERVICE_BIT_MIGRATE)
#define CFG_SERVICE_MASK_VROCE (0x1 << SERVICE_BIT_VROCE)
+#define CFG_SERVICE_MASK_BIFUR (0x1 << SERVICE_BIT_BIFUR)
/* Definition of the scenario ID in the cfg_data, which is used for SML memory allocation. */
enum scenes_id_define {
@@ -50,6 +52,8 @@ enum scenes_id_define {
SCENES_ID_STORAGE_ROCE = 6,
SCENES_ID_COMPUTE_ROCE = 7,
SCENES_ID_STORAGE_TOE = 8,
+ SCENES_ID_COMPUTE_DPU = 100,
+ SCENES_ID_COMPUTE_SMART_NIC = 101,
SCENES_ID_MAX
};
@@ -120,13 +124,18 @@ struct cfg_cmd_dev_cap {
u8 srv_multi_host_mode;
u8 virtio_vq_size;
- u32 rsvd_func3[5];
+ u8 hot_plug_disable;
+ u8 bond_create_mode;
+ u8 lro_enable;
+ u8 os_hot_replace;
+
+ u32 rsvd_func3[4];
/* l2nic */
u16 nic_max_sq_id;
u16 nic_max_rq_id;
u16 nic_default_num_queues;
- u16 rsvd1_nic;
+ u16 outband_vlan_cfg_en;
u32 rsvd2_nic[2];
/* RoCE */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
index d9f67e2..6c5b995 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_common.h
@@ -37,7 +37,7 @@ static inline void hinic3_cpu_to_be32(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -59,7 +59,7 @@ static inline void hinic3_be32_to_cpu(void *data, int len)
{
int i, chunk_sz = sizeof(u32);
int data_len = len;
- u32 *mem = data;
+ u32 *mem = (u32 *)data;
if (!data)
return;
@@ -86,52 +86,16 @@ static inline void hinic3_set_sge(struct hinic3_sge *sge, dma_addr_t addr,
sge->len = (u32)len;
}
-#ifdef HW_CONVERT_ENDIAN
#define hinic3_hw_be32(val) (val)
#define hinic3_hw_cpu32(val) (val)
#define hinic3_hw_cpu16(val) (val)
-#else
-#define hinic3_hw_be32(val) cpu_to_be32(val)
-#define hinic3_hw_cpu32(val) be32_to_cpu(val)
-#define hinic3_hw_cpu16(val) be16_to_cpu(val)
-#endif
static inline void hinic3_hw_be32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_be32(*mem);
- mem++;
- }
-#endif
}
static inline void hinic3_hw_cpu32_len(void *data, int len)
{
-#ifndef HW_CONVERT_ENDIAN
- int i, chunk_sz = sizeof(u32);
- int data_len = len;
- u32 *mem = data;
-
- if (!data)
- return;
-
- data_len = data_len / chunk_sz;
-
- for (i = 0; i < data_len; i++) {
- *mem = hinic3_hw_cpu32(*mem);
- mem++;
- }
-#endif
}
int hinic3_dma_zalloc_coherent_align(void *dev_hdl, u64 size, u64 align,
@@ -149,6 +113,8 @@ int hinic3_wait_for_timeout(void *priv_data, wait_cpl_handler handler,
/* func_attr.glb_func_idx, global function index */
u16 hinic3_global_func_id(void *hwdev);
+int hinic3_global_func_id_get(void *hwdev, u16 *func_id);
+
/* func_attr.p2p_idx, belongs to which pf */
u8 hinic3_pf_id_of_vf(void *hwdev);
diff --git a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
index 9a9bfe2..e36ba1d 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/hinic3_lld.h
@@ -219,5 +219,7 @@ void hinic3_detach_nic(const struct hinic3_lld_dev *lld_dev);
int hinic3_attach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
void hinic3_detach_service(const struct hinic3_lld_dev *lld_dev, enum hinic3_service_type type);
const char **hinic3_get_uld_names(void);
+int hinic3_lld_init(void);
+void hinic3_lld_exit(void);
#endif
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
index 97d34f0..199f17a 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mag_mpu_cmd.h
@@ -43,6 +43,10 @@ enum mag_cmd {
MAG_CMD_GET_XSFP_PRESENT = 62, /* get xsfp present status @see mag_cmd_get_xsfp_present */
MAG_CMD_SET_XSFP_RW = 63, /* sfp/qsfp single byte read/write, @see mag_cmd_set_xsfp_rw */
MAG_CMD_CFG_XSFP_TEMPERATURE = 64, /* get xsfp temp @see mag_cmd_sfp_temp_out_info */
+ /**< set xsfp tlv info @see struct mag_cmd_set_xsfp_tlv_req */
+ MAG_CMD_SET_XSFP_TLV_INFO = 65,
+ /**< get xsfp tlv info @see struct drv_mag_cmd_get_xsfp_tlv_rsp */
+ MAG_CMD_GET_XSFP_TLV_INFO = 66,
/* Event reported 100-149 */
MAG_CMD_WIRE_EVENT = 100,
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
index caaba5d..88a9c0d 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_board_defs.h
@@ -16,32 +16,43 @@
#define BOARD_TYPE_RSVD_RANGE_END 255
enum board_type_define_e {
- BOARD_TYPE_MPU_DEFAULT = 0, /* Default config */
- BOARD_TYPE_TEST_EVB_4X25G = 1, /* EVB Board */
- BOARD_TYPE_TEST_CEM_2X100G = 2, /* 2X100G CEM Card */
- BOARD_TYPE_STRG_SMARTIO_4X32G_FC = 30, /* 4X32G SmartIO FC Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_TIOE = 31, /* 4X25GE SmartIO TIOE Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE = 32, /* 4X25GE SmartIO ROCE Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE_AA = 33, /* 4X25GE SmartIO ROCE_AA Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV = 34, /* 4X25GE SmartIO container Card */
- BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV_SW = 35, /* 4X25GE SmartIO container switch Card */
- BOARD_TYPE_STRG_4X25G_COMSTORAGE = 36, /* 4X25GE compute storage Onboard Card */
- BOARD_TYPE_STRG_2X100G_TIOE = 40, /* 2X100G SmartIO TIOE Card */
- BOARD_TYPE_STRG_2X100G_ROCE = 41, /* 2X100G SmartIO ROCE Card */
- BOARD_TYPE_STRG_2X100G_ROCE_AA = 42, /* 2X100G SmartIO ROCE_AA Card */
- BOARD_TYPE_CAL_2X25G_NIC_75MPPS = 100, /* 2X25G ETH Standard card 75MPPS */
- BOARD_TYPE_CAL_2X25G_NIC_40MPPS = 101, /* 2X25G ETH Standard card 40MPPS */
- BOARD_TYPE_CAL_2X100G_DPU = 102, /* 2x100G DPU Card */
- BOARD_TYPE_CAL_4X25G_NIC_120MPPS = 105, /* 4X25G ETH Standard card 120MPPS */
- BOARD_TYPE_CAL_4X25G_COMSTORAGE = 106, /* 4X25GE compute storage Onboard Card */
- BOARD_TYPE_CAL_2X32G_FC_HBA = 110, /* 2X32G FC HBA card */
- BOARD_TYPE_CAL_2X16G_FC_HBA = 111, /* 2X16G FC HBA card */
- BOARD_TYPE_CAL_2X100G_NIC_120MPPS = 115, /* 2X100G ETH Standard card 120MPPS */
- BOARD_TYPE_CAL_2X25G_DPU = 116, /* 2x25G DPU Card */
- BOARD_TYPE_CAL_4X25G_DPU = 118, /* 4x25G DPU Card */
- BOARD_TYPE_CLD_2X100G_SDI5_1 = 170, /* 2X100G SDI 5.1 Card */
- BOARD_TYPE_CLD_2X25G_SDI5_0_LITE = 171, /* 2x25G SDI5.0 Lite Card */
- BOARD_TYPE_CLD_2X100G_SDI5_0 = 172, /* 2x100G SDI5.0 Card */
+ BOARD_TYPE_MPU_DEFAULT = 0,
+ BOARD_TYPE_TEST_EVB_4X25G = 1,
+ BOARD_TYPE_TEST_CEM_2X100G = 2,
+ BOARD_TYPE_STRG_SMARTIO_4X32G_FC = 30,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_TIOE = 31,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE = 32,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_ROCE_AA = 33,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV = 34,
+ BOARD_TYPE_STRG_SMARTIO_4X25G_SRIOV_SW = 35,
+ BOARD_TYPE_STRG_4X25G_COMSTORAGE = 36,
+ BOARD_TYPE_STRG_2X100G_TIOE = 40,
+ BOARD_TYPE_STRG_2X100G_ROCE = 41,
+ BOARD_TYPE_STRG_2X100G_ROCE_AA = 42,
+ BOARD_TYPE_CAL_2X25G_NIC_75MPPS = 100,
+ BOARD_TYPE_CAL_2X25G_NIC_40MPPS = 101,
+ BOARD_TYPE_CAL_2X100G_DPU_VL = 102,
+ BOARD_TYPE_CAL_4X25G_NIC_120MPPS = 105,
+ BOARD_TYPE_CAL_4X25G_COMSTORAGE = 106,
+ BOARD_TYPE_CAL_2X32G_FC_HBA = 110,
+ BOARD_TYPE_CAL_2X16G_FC_HBA = 111,
+ BOARD_TYPE_CAL_2X100G_NIC_120MPPS = 115,
+ BOARD_TYPE_CAL_2X25G_DPU_BD = 116,
+ BOARD_TYPE_CAL_2X100G_TCE_BACKPLANE = 117,
+ BOARD_TYPE_CAL_4X25G_DPU_VL = 118,
+ BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS = 119,
+ BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS = 120,
+ BOARD_TYPE_CAL_6X25G_DPU_VL = 121,
+ BOARD_TYPE_CAL_4X25G_DPU_BD = 122,
+ BOARD_TYPE_CAL_2X25G_NIC_4HOST = 123,
+ BOARD_TYPE_CAL_2X10G_LOW_POWER = 125,
+ BOARD_TYPE_CAL_2X200G_NIC_INTERNET = 127,
+ BOARD_TYPE_CAL_1X100GR2_OCP = 129,
+ BOARD_TYPE_CAL_2X200G_DPU_VL = 130,
+ BOARD_TYPE_CLD_2X100G_SDI5_1 = 170,
+ BOARD_TYPE_CLD_2X25G_SDI5_0_LITE = 171,
+ BOARD_TYPE_CLD_2X100G_SDI5_0 = 172,
+ BOARD_TYPE_CLD_4X25G_SDI5_0_C = 175,
BOARD_TYPE_MAX_INDEX = 0xFF
};
@@ -49,23 +60,76 @@ static inline u32 spu_board_type_valid(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
- ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
+}
+
+static inline int board_type_is_sdi_50(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
+ ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C);
}
static inline int board_type_is_sdi(u32 board_type)
{
return ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_1) ||
((board_type) == BOARD_TYPE_CLD_2X25G_SDI5_0_LITE) ||
- ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0);
+ ((board_type) == BOARD_TYPE_CLD_2X100G_SDI5_0) ||
+ ((board_type) == BOARD_TYPE_CLD_4X25G_SDI5_0_C);
+}
+
+static inline int board_type_is_dpu_spu(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
}
static inline int board_type_is_dpu(u32 board_type)
{
- return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_2X100G_DPU) ||
- ((board_type) == BOARD_TYPE_CAL_4X25G_DPU);
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_DPU_BD) ||
+ ((board_type) == BOARD_TYPE_CAL_6X25G_DPU_VL) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_DPU_VL);
+}
+
+static inline int board_type_is_smartnic(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS);
+}
+
+/* 此接口判断是否是分布式存储的标卡以及计算的标卡(含ROCE特性),
+ * 仅用于LLDP TX功能冲突命令字处理的判断
+ */
+static inline int board_type_is_compute(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_75MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_40MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_NIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_COMSTORAGE) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_NIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X10G_LOW_POWER) ||
+ ((board_type) == BOARD_TYPE_CAL_2X200G_NIC_INTERNET) ||
+ ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP) ||
+ ((board_type) == BOARD_TYPE_CAL_4X25G_SMARTNIC_120MPPS) ||
+ ((board_type) == BOARD_TYPE_CAL_2X25G_NIC_4HOST) ||
+ ((board_type) == BOARD_TYPE_CAL_2X100G_SMARTNIC_120MPPS);
+}
+
+/* 此接口判断服务器输入reboot网卡是否需要复位 */
+static inline int board_type_is_multi_socket(u32 board_type)
+{
+ return ((board_type) == BOARD_TYPE_CAL_1X100GR2_OCP);
}
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
index 89d5cc4..e65c206 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_cmd_base_defs.h
@@ -1,11 +1,11 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ * Description : common definitions
+ */
#ifndef COMM_DEFS_H
#define COMM_DEFS_H
-#include "mgmt_msg_base.h"
-
/** MPU CMD MODULE TYPE */
enum hinic3_mod_type {
HINIC3_MOD_COMM = 0, /* HW communication module */
@@ -33,16 +33,16 @@ enum hinic3_mod_type {
HINIC3_MOD_MAX,
};
-/* Func reset flag, Specifies the resource to be cleaned.*/
-enum func_reset_flag_e {
+/* func reset的flag ,用于指示清理哪种资源 */
+enum func_reset_flag_e{
RES_TYPE_FLUSH_BIT = 0,
RES_TYPE_MQM,
RES_TYPE_SMF,
RES_TYPE_PF_BW_CFG,
RES_TYPE_COMM = 10,
- RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
- RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_MGMT_CH, /* clear mbox and aeq, The RES_TYPE_COMM bit must be set */
+ RES_TYPE_COMM_CMD_CH, /* clear cmdq and ceq, The RES_TYPE_COMM bit must be set */
RES_TYPE_NIC,
RES_TYPE_OVS,
RES_TYPE_VBS,
@@ -53,33 +53,48 @@ enum func_reset_flag_e {
RES_TYPE_MAX,
};
-#define HINIC3_COMM_RES \
- ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
- (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
- (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
+#define HINIC3_COMM_RES \
+ ((1 << RES_TYPE_COMM) | (1 << RES_TYPE_COMM_CMD_CH) | \
+ (1 << RES_TYPE_FLUSH_BIT) | (1 << RES_TYPE_MQM) | \
+ (1 << RES_TYPE_SMF) | (1 << RES_TYPE_PF_BW_CFG))
-#define HINIC3_NIC_RES BIT(RES_TYPE_NIC)
-#define HINIC3_OVS_RES BIT(RES_TYPE_OVS)
-#define HINIC3_VBS_RES BIT(RES_TYPE_VBS)
-#define HINIC3_ROCE_RES BIT(RES_TYPE_ROCE)
-#define HINIC3_FC_RES BIT(RES_TYPE_FC)
-#define HINIC3_TOE_RES BIT(RES_TYPE_TOE)
-#define HINIC3_IPSEC_RES BIT(RES_TYPE_IPSEC)
+#define HINIC3_NIC_RES (1 << RES_TYPE_NIC)
+#define HINIC3_OVS_RES (1 << RES_TYPE_OVS)
+#define HINIC3_VBS_RES (1 << RES_TYPE_VBS)
+#define HINIC3_ROCE_RES (1 << RES_TYPE_ROCE)
+#define HINIC3_FC_RES (1 << RES_TYPE_FC)
+#define HINIC3_TOE_RES (1 << RES_TYPE_TOE)
+#define HINIC3_IPSEC_RES (1 << RES_TYPE_IPSEC)
/* MODE OVS、NIC、UNKNOWN */
#define HINIC3_WORK_MODE_OVS 0
#define HINIC3_WORK_MODE_UNKNOWN 1
#define HINIC3_WORK_MODE_NIC 2
-#define DEVICE_TYPE_L2NIC 0
-#define DEVICE_TYPE_NVME 1
-#define DEVICE_TYPE_VIRTIO_NET 2
-#define DEVICE_TYPE_VIRTIO_BLK 3
-#define DEVICE_TYPE_VIRTIO_VSOCK 4
-#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
-#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
-#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
-#define DEVICE_TYPE_VIRTIO_HPC 8
+#define DEVICE_TYPE_L2NIC 0
+#define DEVICE_TYPE_NVME 1
+#define DEVICE_TYPE_VIRTIO_NET 2
+#define DEVICE_TYPE_VIRTIO_BLK 3
+#define DEVICE_TYPE_VIRTIO_VSOCK 4
+#define DEVICE_TYPE_VIRTIO_NET_TRANSITION 5
+#define DEVICE_TYPE_VIRTIO_BLK_TRANSITION 6
+#define DEVICE_TYPE_VIRTIO_SCSI_TRANSITION 7
+#define DEVICE_TYPE_VIRTIO_HPC 8
+#define DEVICE_TYPE_VIRTIO_FS 9
+
+#define IS_STORAGE_DEVICE_TYPE(dev_type) \
+ ((dev_type) == DEVICE_TYPE_VIRTIO_BLK || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_BLK_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_SCSI_TRANSITION || \
+ (dev_type) == DEVICE_TYPE_VIRTIO_FS)
+
+#define MGMT_MSG_CMD_OP_SET 1
+#define MGMT_MSG_CMD_OP_GET 0
+
+#define MGMT_MSG_CMD_OP_START 1
+#define MGMT_MSG_CMD_OP_STOP 0
+
+#define HOT_REPLACE_PARTITION_NUM 2
enum hinic3_svc_type {
SVC_T_COMM = 0,
@@ -98,8 +113,17 @@ enum hinic3_svc_type {
};
/**
- * Common header control information of the COMM message interaction command word
- * between the driver and PF.
+ * Common header control information of the COMM message interaction command word between the driver and PF
+ * stuct mgmt_msg_head and struct comm_info_head are the same stucture
+ */
+struct mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+/**
+ * Common header control information of the COMM message interaction command word between the driver and PF
*/
struct comm_info_head {
/** response status code, 0: success, others: error code */
@@ -113,4 +137,29 @@ struct comm_info_head {
u8 rsvd[5];
};
+
+static inline u32 get_function_partition(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM;
+}
+
+static inline u32 is_primary_function(u32 function_id, u32 port_num)
+{
+ return (function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0;
+}
+
+static inline u32 mpu_nic_get_primary_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ function_id : (function_id - port_num);
+}
+
+// when func_id is in partition 0/1, it will get its another func_id in partition 1/0
+static inline u32 mpu_nic_get_backup_function(u32 function_id, u32 port_num)
+{
+ return ((function_id / port_num) % HOT_REPLACE_PARTITION_NUM == 0) ?
+ (function_id + port_num) : (function_id - port_num);
+}
+
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
index b24e729..fd0401f 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd.h
@@ -89,6 +89,10 @@ enum hinic3_mgmt_cmd {
* @see comm_read_ucode_sm_resp
*/
COMM_MGMT_CMD_CLEAR_LOG, /**< clear log @see comm_cmd_clear_log_s */
+ COMM_MGMT_CMD_UCODE_SM_COUNTER_PER,
+ /**< get ucode sm counter @see struct comm_read_ucode_sm_per_req
+ * @see struct comm_read_ucode_sm_per_resp
+ */
COMM_MGMT_CMD_CHECK_IF_SWITCH_WORKMODE = 140, /* check if switch workmode reserved
* @see comm_cmd_check_if_switch_workmode
@@ -101,6 +105,7 @@ enum hinic3_mgmt_cmd {
COMM_MGMT_CMD_CPI_TCAM_DBG, /* enable or disable the scheduled cpi tcam task,
* set task interval time @see comm_cmd_cpi_tcam_dbg_s
*/
+ COMM_MGMT_CMD_LLDP_TX_FUNC_SET,
COMM_MGMT_CMD_SECTION_RSVD_0 = 160, /**< rsvd0 section */
COMM_MGMT_CMD_SECTION_RSVD_1 = 170, /**< rsvd1 section */
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
index f535777..fd3a7dd 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_inband_cmd_defs.h
@@ -313,7 +313,8 @@ struct comm_cmd_get_fw_version {
struct mgmt_msg_head head;
u16 fw_type; /**< firmware type @see enum hinic3_fw_ver_type */
- u16 rsvd1;
+ u16 fw_dfx_vld : 1; /**< 0: release, 1: debug */
+ u16 rsvd1 : 15;
u8 ver[HINIC3_FW_VERSION_LEN]; /**< firmware version */
u8 time[HINIC3_FW_COMPILE_TIME_LEN]; /**< firmware compile time */
};
@@ -558,6 +559,7 @@ struct nic_log_info_request {
#define MPU_TEMP_OP_GET 0
#define MPU_TEMP_THRESHOLD_OP_CFG 1
+#define MPU_TEMP_MCTP_DFX_INFO_GET 2
struct comm_temp_in_info {
struct comm_info_head head;
u8 opt_type; /**< operation type 0:read operation 1:cfg operation */
@@ -660,6 +662,28 @@ struct comm_read_ucode_sm_resp {
u64 val2;
};
+#define PER_REQ_MAX_DATA_LEN 0x600
+
+struct comm_read_ucode_sm_per_req {
+ struct mgmt_msg_head msg_head;
+
+ u32 tbl_type;
+ u32 count_id;
+};
+
+struct comm_read_ucode_sm_per_resp {
+ struct mgmt_msg_head msg_head;
+
+ u8 data[PER_REQ_MAX_DATA_LEN];
+};
+
+struct ucode_sm_counter_get_info {
+ u32 width_type;
+ u32 tbl_type;
+ unsigned int base_count;
+ unsigned int count_num;
+};
+
enum log_type {
MPU_LOG_CLEAR = 0,
SMU_LOG_CLEAR = 1,
@@ -1057,7 +1081,9 @@ struct comm_cmd_ncsi_settings {
u8 lldp_over_ncsi_enable;
u8 lldp_over_mctp_enable;
u32 magicwd;
- u8 rsvd[8];
+ u8 lldp_tx_enable;
+ u8 rsvd[3];
+ u32 crc;
struct tag_ncsi_chan_info ncsi_chan_info;
};
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
index fde8617..767f886 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/mpu_outband_ncsi_cmd_defs.h
@@ -114,6 +114,14 @@ struct tag_ncsi_client_info {
#define AEN_CTRL_CONFIG_REQ_SHIFT 1
#define AEN_CTRL_DRV_CHANGE_SHIFT 2
+/* AEN Type */
+enum aen_type_e{
+ AEN_LINK_STATUS_CHANGE_TYPE = 0x0,
+ AEN_CONFIG_REQUIRED_TYPE = 0x1,
+ OEM_AEN_CONFIG_REQUEST_TYPE = 0x80,
+ AEN_TYPE_MAX = 0x100
+} ;
+
/* get link status 0x0A */
#define GET_LINK_STATUS_REQ_LEN 0
#define GET_LINK_STATUS_RSP_LEN 16
diff --git a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
index fe663e1..83b75f9 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/mpu/nic_cfg_comm.h
@@ -1,5 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+/*
+ * Copyright (C), 2001-2021, Huawei Tech. Co., Ltd.
+ * File Name : nic_cfg_comm.h
+ * Version : Initial Draft
+ * Description : nic config common header file
+ * Function List :
+ * History :
+ * Modification: Created file
+ */
#ifndef NIC_CFG_COMM_H
#define NIC_CFG_COMM_H
@@ -26,7 +34,7 @@ enum nic_rss_hash_type {
};
#define NIC_RSS_INDIR_SIZE 256
-#define NIC_RSS_KEY_SIZE 40
+#define NIC_RSS_KEY_SIZE 40
/* *
* Definition of the NIC receiving mode
@@ -36,6 +44,7 @@ enum nic_rss_hash_type {
#define NIC_RX_MODE_BC 0x04
#define NIC_RX_MODE_MC_ALL 0x08
#define NIC_RX_MODE_PROMISC 0x10
+#define NIC_RX_DB_COS_MAX 0x4
/* IEEE 802.1Qaz std */
#define NIC_DCB_COS_MAX 0x8
@@ -52,4 +61,7 @@ enum nic_rss_hash_type {
#define NIC_DCB_PRIO_STRICT 0x1
#define NIC_DCB_MAX_PFC_NUM 0x4
+
+#define NIC_ETS_PERCENT_WEIGHT 100
+
#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
index 801aeed..9f93f7e 100644
--- a/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
+++ b/drivers/net/ethernet/huawei/hinic3/include/vram_common.h
@@ -23,7 +23,11 @@
#define VRAM_CQM_BITMAP_BASE "B"
#define VRAM_NIC_DCB "DCB"
+#define VRAM_NIC_MHOST_MGMT "MHOST_MGMT"
#define VRAM_NIC_VRAM "NIC_VRAM"
+#define VRAM_NIC_IRQ_VRAM "NIC_IRQ"
+
+#define VRAM_NIC_MQM "NM"
#define VRAM_VBS_BASE_IOCB "BASE_IOCB"
#define VRAM_VBS_EX_IOCB "EX_IOCB"
@@ -55,11 +59,16 @@ enum KUP_HOOK_POINT {
PRE_FREEZE,
FREEZE_TO_KILL,
PRE_UPDATE_KERNEL,
- FLUSH_DURING_KUP,
POST_UPDATE_KERNEL,
UNFREEZE_TO_RUN,
POST_RUN,
KUP_HOOK_MAX,
};
+#define hi_vram_kalloc(name, size) 0
+#define hi_vram_kfree(vaddr, name, size)
+#define get_use_vram_flag(void) 0
+#define vram_get_kexec_flag(void) 0
+#define hi_vram_get_gfp_vram(void) 0
+
#endif /* VRAM_COMMON_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h b/drivers/net/ethernet/huawei/hinic3/mag_cmd.h
deleted file mode 100644
index 9649503..0000000
--- a/drivers/net/ethernet/huawei/hinic3/mag_cmd.h
+++ /dev/null
@@ -1,922 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
-
-#ifndef MAG_MPU_CMD_DEFS_H
-#define MAG_MPU_CMD_DEFS_H
-
-#include "mpu_cmd_base_defs.h"
-
-/* serdes cmd struct define */
-#define CMD_ARRAY_BUF_SIZE 64
-#define SERDES_CMD_DATA_BUF_SIZE 512
-struct serdes_in_info {
- u32 chip_id : 16;
- u32 macro_id : 16;
- u32 start_sds_id : 16;
- u32 sds_num : 16;
-
- u32 cmd_type : 8; /* reserved for iotype */
- u32 sub_cmd : 8;
- u32 rw : 1; /* 0: read, 1: write */
- u32 rsvd : 15;
-
- u32 val;
- union {
- char field[CMD_ARRAY_BUF_SIZE];
- u32 addr;
- u8 *ex_param;
- };
-};
-
-struct serdes_out_info {
- u32 str_len; /* out_str length */
- u32 result_offset;
- u32 type; /* 0:data; 1:string */
- char out_str[SERDES_CMD_DATA_BUF_SIZE];
-};
-
-struct serdes_cmd_in {
- struct mgmt_msg_head head;
-
- struct serdes_in_info serdes_in;
-};
-
-struct serdes_cmd_out {
- struct mgmt_msg_head head;
-
- struct serdes_out_info serdes_out;
-};
-
-enum mag_cmd_port_speed {
- PORT_SPEED_NOT_SET = 0,
- PORT_SPEED_10MB = 1,
- PORT_SPEED_100MB = 2,
- PORT_SPEED_1GB = 3,
- PORT_SPEED_10GB = 4,
- PORT_SPEED_25GB = 5,
- PORT_SPEED_40GB = 6,
- PORT_SPEED_50GB = 7,
- PORT_SPEED_100GB = 8,
- PORT_SPEED_200GB = 9,
- PORT_SPEED_UNKNOWN
-};
-
-enum mag_cmd_port_an {
- PORT_AN_NOT_SET = 0,
- PORT_CFG_AN_ON = 1,
- PORT_CFG_AN_OFF = 2
-};
-
-enum mag_cmd_port_adapt {
- PORT_ADAPT_NOT_SET = 0,
- PORT_CFG_ADAPT_ON = 1,
- PORT_CFG_ADAPT_OFF = 2
-};
-
-enum mag_cmd_port_sriov {
- PORT_SRIOV_NOT_SET = 0,
- PORT_CFG_SRIOV_ON = 1,
- PORT_CFG_SRIOV_OFF = 2
-};
-
-enum mag_cmd_port_fec {
- PORT_FEC_NOT_SET = 0,
- PORT_FEC_RSFEC = 1,
- PORT_FEC_BASEFEC = 2,
- PORT_FEC_NOFEC = 3,
- PORT_FEC_LLRSFEC = 4,
- PORT_FEC_AUTO = 5
-};
-
-enum mag_cmd_port_lanes {
- PORT_LANES_NOT_SET = 0,
- PORT_LANES_X1 = 1,
- PORT_LANES_X2 = 2,
- PORT_LANES_X4 = 4,
- PORT_LANES_X8 = 8 /* reserved for future use */
-};
-
-enum mag_cmd_port_duplex {
- PORT_DUPLEX_HALF = 0,
- PORT_DUPLEX_FULL = 1
-};
-
-enum mag_cmd_wire_node {
- WIRE_NODE_UNDEF = 0,
- CABLE_10G = 1,
- FIBER_10G = 2,
- CABLE_25G = 3,
- FIBER_25G = 4,
- CABLE_40G = 5,
- FIBER_40G = 6,
- CABLE_50G = 7,
- FIBER_50G = 8,
- CABLE_100G = 9,
- FIBER_100G = 10,
- CABLE_200G = 11,
- FIBER_200G = 12,
- WIRE_NODE_NUM
-};
-
-enum mag_cmd_cnt_type {
- MAG_RX_RSFEC_DEC_CW_CNT = 0,
- MAG_RX_RSFEC_CORR_CW_CNT = 1,
- MAG_RX_RSFEC_UNCORR_CW_CNT = 2,
- MAG_RX_PCS_BER_CNT = 3,
- MAG_RX_PCS_ERR_BLOCK_CNT = 4,
- MAG_RX_PCS_E_BLK_CNT = 5,
- MAG_RX_PCS_DEC_ERR_BLK_CNT = 6,
- MAG_RX_PCS_LANE_BIP_ERR_CNT = 7,
- MAG_CNT_NUM
-};
-
-/* mag_cmd_set_port_cfg config bitmap */
-#define MAG_CMD_SET_SPEED 0x1
-#define MAG_CMD_SET_AUTONEG 0x2
-#define MAG_CMD_SET_FEC 0x4
-#define MAG_CMD_SET_LANES 0x8
-struct mag_cmd_set_port_cfg {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 rsvd0[3];
-
- u32 config_bitmap;
- u8 speed;
- u8 autoneg;
- u8 fec;
- u8 lanes;
- u8 rsvd1[20];
-};
-
-/* mag supported/advertised link mode bitmap */
-enum mag_cmd_link_mode {
- LINK_MODE_GE = 0,
- LINK_MODE_10GE_BASE_R = 1,
- LINK_MODE_25GE_BASE_R = 2,
- LINK_MODE_40GE_BASE_R4 = 3,
- LINK_MODE_50GE_BASE_R = 4,
- LINK_MODE_50GE_BASE_R2 = 5,
- LINK_MODE_100GE_BASE_R = 6,
- LINK_MODE_100GE_BASE_R2 = 7,
- LINK_MODE_100GE_BASE_R4 = 8,
- LINK_MODE_200GE_BASE_R2 = 9,
- LINK_MODE_200GE_BASE_R4 = 10,
- LINK_MODE_MAX_NUMBERS,
-
- LINK_MODE_UNKNOWN = 0xFFFF
-};
-
-#define LINK_MODE_GE_BIT 0x1u
-#define LINK_MODE_10GE_BASE_R_BIT 0x2u
-#define LINK_MODE_25GE_BASE_R_BIT 0x4u
-#define LINK_MODE_40GE_BASE_R4_BIT 0x8u
-#define LINK_MODE_50GE_BASE_R_BIT 0x10u
-#define LINK_MODE_50GE_BASE_R2_BIT 0x20u
-#define LINK_MODE_100GE_BASE_R_BIT 0x40u
-#define LINK_MODE_100GE_BASE_R2_BIT 0x80u
-#define LINK_MODE_100GE_BASE_R4_BIT 0x100u
-#define LINK_MODE_200GE_BASE_R2_BIT 0x200u
-#define LINK_MODE_200GE_BASE_R4_BIT 0x400u
-
-#define CABLE_10GE_BASE_R_BIT LINK_MODE_10GE_BASE_R_BIT
-#define CABLE_25GE_BASE_R_BIT (LINK_MODE_25GE_BASE_R_BIT | LINK_MODE_10GE_BASE_R_BIT)
-#define CABLE_40GE_BASE_R4_BIT LINK_MODE_40GE_BASE_R4_BIT
-#define CABLE_50GE_BASE_R_BIT (LINK_MODE_50GE_BASE_R_BIT | LINK_MODE_25GE_BASE_R_BIT | \
- LINK_MODE_10GE_BASE_R_BIT)
-#define CABLE_50GE_BASE_R2_BIT LINK_MODE_50GE_BASE_R2_BIT
-#define CABLE_100GE_BASE_R2_BIT (LINK_MODE_100GE_BASE_R2_BIT | LINK_MODE_50GE_BASE_R2_BIT)
-#define CABLE_100GE_BASE_R4_BIT (LINK_MODE_100GE_BASE_R4_BIT | LINK_MODE_40GE_BASE_R4_BIT)
-#define CABLE_200GE_BASE_R4_BIT (LINK_MODE_200GE_BASE_R4_BIT | LINK_MODE_100GE_BASE_R4_BIT | \
- LINK_MODE_40GE_BASE_R4_BIT)
-
-struct mag_cmd_get_port_info {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 rsvd0[3];
-
- u8 wire_type;
- u8 an_support;
- u8 an_en;
- u8 duplex;
-
- u8 speed;
- u8 fec;
- u8 lanes;
- u8 rsvd1;
-
- u32 supported_mode;
- u32 advertised_mode;
- u8 rsvd2[8];
-};
-
-#define MAG_CMD_OPCODE_GET 0
-#define MAG_CMD_OPCODE_SET 1
-struct mag_cmd_set_port_adapt {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 opcode; /* 0:get adapt info 1:set adapt */
- u8 enable;
- u8 rsvd0;
- u32 speed_mode;
- u32 rsvd1[3];
-};
-
-#define MAG_CMD_LP_MODE_SDS_S_TX2RX 1
-#define MAG_CMD_LP_MODE_SDS_P_RX2TX 2
-#define MAG_CMD_LP_MODE_SDS_P_TX2RX 3
-#define MAG_CMD_LP_MODE_MAC_RX2TX 4
-#define MAG_CMD_LP_MODE_MAC_TX2RX 5
-#define MAG_CMD_LP_MODE_TXDP2RXDP 6
-struct mag_cmd_cfg_loopback_mode {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 opcode; /* 0:get loopback mode 1:set loopback mode */
- u8 lp_mode;
- u8 lp_en; /* 0:disable 1:enable */
-
- u32 rsvd0[2];
-};
-
-#define MAG_CMD_PORT_DISABLE 0x0
-#define MAG_CMD_TX_ENABLE 0x1
-#define MAG_CMD_RX_ENABLE 0x2
-/* the physical port is disable only when all pf of the port are set to down,
- * if any pf is enable, the port is enable
- */
-struct mag_cmd_set_port_enable {
- struct mgmt_msg_head head;
-
- u16 function_id; /* function_id should not more than the max support pf_id(32) */
- u16 rsvd0;
-
- u8 state; /* bitmap bit0:tx_en bit1:rx_en */
- u8 rsvd1[3];
-};
-
-struct mag_cmd_get_port_enable {
- struct mgmt_msg_head head;
-
- u8 port;
- u8 state; /* bitmap bit0:tx_en bit1:rx_en */
- u8 rsvd0[2];
-};
-
-#define PMA_FOLLOW_DEFAULT 0x0
-#define PMA_FOLLOW_ENABLE 0x1
-#define PMA_FOLLOW_DISABLE 0x2
-#define PMA_FOLLOW_GET 0x4
-/* the physical port disable link follow only when all pf of the port are set to follow disable */
-struct mag_cmd_set_link_follow {
- struct mgmt_msg_head head;
-
- u16 function_id; /* function_id should not more than the max support pf_id(32) */
- u16 rsvd0;
-
- u8 follow;
- u8 rsvd1[3];
-};
-
-/* firmware also use this cmd report link event to driver */
-struct mag_cmd_get_link_status {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 status; /* 0:link down 1:link up */
- u8 rsvd0[2];
-};
-
-/* firmware also use this cmd report bond event to driver */
-struct mag_cmd_get_bond_status {
- struct mgmt_msg_head head;
-
- u8 status; /* 0:bond down 1:bond up */
- u8 rsvd0[3];
-};
-
-struct mag_cmd_set_pma_enable {
- struct mgmt_msg_head head;
-
- u16 function_id; /* function_id should not more than the max support pf_id(32) */
- u16 enable;
-};
-
-struct mag_cmd_cfg_an_type {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 opcode; /* 0:get an type 1:set an type */
- u8 rsvd0[2];
-
- u32 an_type; /* 0:ieee 1:25G/50 eth consortium */
-};
-
-struct mag_cmd_get_link_time {
- struct mgmt_msg_head head;
- u8 port_id;
- u8 rsvd0[3];
-
- u32 link_up_begin;
- u32 link_up_end;
- u32 link_down_begin;
- u32 link_down_end;
-};
-
-struct mag_cmd_cfg_fec_mode {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 opcode; /* 0:get fec mode 1:set fec mode */
- u8 fec;
- u8 rsvd0;
-};
-
-/* speed */
-#define PANGEA_ADAPT_10G_BITMAP 0xd
-#define PANGEA_ADAPT_25G_BITMAP 0x72
-#define PANGEA_ADAPT_40G_BITMAP 0x680
-#define PANGEA_ADAPT_100G_BITMAP 0x1900
-
-/* speed and fec */
-#define PANGEA_10G_NO_BITMAP 0x8
-#define PANGEA_10G_BASE_BITMAP 0x4
-#define PANGEA_25G_NO_BITMAP 0x10
-#define PANGEA_25G_BASE_BITMAP 0x20
-#define PANGEA_25G_RS_BITMAP 0x40
-#define PANGEA_40G_NO_BITMAP 0x400
-#define PANGEA_40G_BASE_BITMAP 0x200
-#define PANGEA_100G_NO_BITMAP 0x800
-#define PANGEA_100G_RS_BITMAP 0x1000
-
-/* adapt or fec */
-#define PANGEA_ADAPT_ADAPT_BITMAP 0x183
-#define PANGEA_ADAPT_NO_BITMAP 0xc18
-#define PANGEA_ADAPT_BASE_BITMAP 0x224
-#define PANGEA_ADAPT_RS_BITMAP 0x1040
-
-/* default cfg */
-#define PANGEA_ADAPT_CFG_10G_CR 0x200d
-#define PANGEA_ADAPT_CFG_10G_SRLR 0xd
-#define PANGEA_ADAPT_CFG_25G_CR 0x207f
-#define PANGEA_ADAPT_CFG_25G_SRLR 0x72
-#define PANGEA_ADAPT_CFG_40G_CR4 0x2680
-#define PANGEA_ADAPT_CFG_40G_SRLR4 0x680
-#define PANGEA_ADAPT_CFG_100G_CR4 0x3f80
-#define PANGEA_ADAPT_CFG_100G_SRLR4 0x1900
-
-union pangea_adapt_bitmap_u {
- struct {
- u32 adapt_10g : 1; /* [0] adapt_10g */
- u32 adapt_25g : 1; /* [1] adapt_25g */
- u32 base_10g : 1; /* [2] base_10g */
- u32 no_10g : 1; /* [3] no_10g */
- u32 no_25g : 1; /* [4] no_25g */
- u32 base_25g : 1; /* [5] base_25g */
- u32 rs_25g : 1; /* [6] rs_25g */
- u32 adapt_40g : 1; /* [7] adapt_40g */
- u32 adapt_100g : 1; /* [8] adapt_100g */
- u32 base_40g : 1; /* [9] base_40g */
- u32 no_40g : 1; /* [10] no_40g */
- u32 no_100g : 1; /* [11] no_100g */
- u32 rs_100g : 1; /* [12] rs_100g */
- u32 auto_neg : 1; /* [13] auto_neg */
- u32 rsvd0 : 18; /* [31:14] reserved */
- } bits;
-
- u32 value;
-};
-
-#define PANGEA_ADAPT_GET 0x0
-#define PANGEA_ADAPT_SET 0x1
-struct mag_cmd_set_pangea_adapt {
- struct mgmt_msg_head head;
-
- u16 port_id;
- u8 opcode; /* 0:get adapt info 1:cfg adapt info */
- u8 wire_type;
-
- union pangea_adapt_bitmap_u cfg_bitmap;
- union pangea_adapt_bitmap_u cur_bitmap;
- u32 rsvd1[3];
-};
-
-struct mag_cmd_cfg_bios_link_cfg {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 opcode; /* 0:get bios link info 1:set bios link cfg */
- u8 clear;
- u8 rsvd0;
-
- u32 wire_type;
- u8 an_en;
- u8 speed;
- u8 fec;
- u8 rsvd1;
- u32 speed_mode;
- u32 rsvd2[3];
-};
-
-struct mag_cmd_restore_link_cfg {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 rsvd[7];
-};
-
-struct mag_cmd_activate_bios_link_cfg {
- struct mgmt_msg_head head;
-
- u32 rsvd[8];
-};
-
-/* led type */
-enum mag_led_type {
- MAG_CMD_LED_TYPE_ALARM = 0x0,
- MAG_CMD_LED_TYPE_LOW_SPEED = 0x1,
- MAG_CMD_LED_TYPE_HIGH_SPEED = 0x2
-};
-
-/* led mode */
-enum mag_led_mode {
- MAG_CMD_LED_MODE_DEFAULT = 0x0,
- MAG_CMD_LED_MODE_FORCE_ON = 0x1,
- MAG_CMD_LED_MODE_FORCE_OFF = 0x2,
- MAG_CMD_LED_MODE_FORCE_BLINK_1HZ = 0x3,
- MAG_CMD_LED_MODE_FORCE_BLINK_2HZ = 0x4,
- MAG_CMD_LED_MODE_FORCE_BLINK_4HZ = 0x5,
- MAG_CMD_LED_MODE_1HZ = 0x6,
- MAG_CMD_LED_MODE_2HZ = 0x7,
- MAG_CMD_LED_MODE_4HZ = 0x8
-};
-
-/* the led is report alarm when any pf of the port is alram */
-struct mag_cmd_set_led_cfg {
- struct mgmt_msg_head head;
-
- u16 function_id;
- u8 type;
- u8 mode;
-};
-
-#define XSFP_INFO_MAX_SIZE 640
-/* xsfp wire type, refer to cmis protocol definition */
-enum mag_wire_type {
- MAG_CMD_WIRE_TYPE_UNKNOWN = 0x0,
- MAG_CMD_WIRE_TYPE_MM = 0x1,
- MAG_CMD_WIRE_TYPE_SM = 0x2,
- MAG_CMD_WIRE_TYPE_COPPER = 0x3,
- MAG_CMD_WIRE_TYPE_ACC = 0x4,
- MAG_CMD_WIRE_TYPE_BASET = 0x5,
- MAG_CMD_WIRE_TYPE_AOC = 0x40,
- MAG_CMD_WIRE_TYPE_ELECTRIC = 0x41,
- MAG_CMD_WIRE_TYPE_BACKPLANE = 0x42
-};
-
-struct mag_cmd_get_xsfp_info {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 wire_type;
- u16 out_len;
- u32 rsvd;
- u8 sfp_info[XSFP_INFO_MAX_SIZE];
-};
-
-#define MAG_CMD_XSFP_DISABLE 0x0
-#define MAG_CMD_XSFP_ENABLE 0x1
-/* the sfp is disable only when all pf of the port are set sfp down,
- * if any pf is enable, the sfp is enable
- */
-struct mag_cmd_set_xsfp_enable {
- struct mgmt_msg_head head;
-
- u32 port_id;
- u32 status; /* 0:on 1:off */
-};
-
-#define MAG_CMD_XSFP_PRESENT 0x0
-#define MAG_CMD_XSFP_ABSENT 0x1
-struct mag_cmd_get_xsfp_present {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 abs_status; /* 0:present, 1:absent */
- u8 rsvd[2];
-};
-
-#define MAG_CMD_XSFP_READ 0x0
-#define MAG_CMD_XSFP_WRITE 0x1
-struct mag_cmd_set_xsfp_rw {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 operation; /* 0: read; 1: write */
- u8 value;
- u8 rsvd0;
- u32 devaddr;
- u32 offset;
- u32 rsvd1;
-};
-
-struct mag_cmd_cfg_xsfp_temperature {
- struct mgmt_msg_head head;
-
- u8 opcode; /* 0:read 1:write */
- u8 rsvd0[3];
- s32 max_temp;
- s32 min_temp;
-};
-
-struct mag_cmd_get_xsfp_temperature {
- struct mgmt_msg_head head;
-
- s16 sfp_temp[8];
- u8 rsvd[32];
- s32 max_temp;
- s32 min_temp;
-};
-
-/* xsfp plug event */
-struct mag_cmd_wire_event {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 status; /* 0:present, 1:absent */
- u8 rsvd[2];
-};
-
-/* link err type definition */
-#define MAG_CMD_ERR_XSFP_UNKNOWN 0x0
-struct mag_cmd_link_err_event {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 link_err_type;
- u8 rsvd[2];
-};
-
-#define MAG_PARAM_TYPE_DEFAULT_CFG 0x0
-#define MAG_PARAM_TYPE_BIOS_CFG 0x1
-#define MAG_PARAM_TYPE_TOOL_CFG 0x2
-#define MAG_PARAM_TYPE_FINAL_CFG 0x3
-#define MAG_PARAM_TYPE_WIRE_INFO 0x4
-#define MAG_PARAM_TYPE_ADAPT_INFO 0x5
-#define MAG_PARAM_TYPE_MAX_CNT 0x6
-struct param_head {
- u8 valid_len;
- u8 info_type;
- u8 rsvd[2];
-};
-
-struct mag_port_link_param {
- struct param_head head;
-
- u8 an;
- u8 fec;
- u8 speed;
- u8 rsvd0;
-
- u32 used;
- u32 an_fec_ability;
- u32 an_speed_ability;
- u32 an_pause_ability;
-};
-
-struct mag_port_wire_info {
- struct param_head head;
-
- u8 status;
- u8 rsvd0[3];
-
- u8 wire_type;
- u8 default_fec;
- u8 speed;
- u8 rsvd1;
- u32 speed_ability;
-};
-
-struct mag_port_adapt_info {
- struct param_head head;
-
- u32 adapt_en;
- u32 flash_adapt;
- u32 rsvd0[2];
-
- u32 wire_node;
- u32 an_en;
- u32 speed;
- u32 fec;
-};
-
-struct mag_port_param_info {
- u8 parameter_cnt;
- u8 lane_id;
- u8 lane_num;
- u8 rsvd0;
-
- struct mag_port_link_param default_cfg;
- struct mag_port_link_param bios_cfg;
- struct mag_port_link_param tool_cfg;
- struct mag_port_link_param final_cfg;
-
- struct mag_port_wire_info wire_info;
- struct mag_port_adapt_info adapt_info;
-};
-
-#define XSFP_VENDOR_NAME_LEN 16
-struct mag_cmd_event_port_info {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 event_type;
- u8 rsvd0[2];
-
- u8 vendor_name[XSFP_VENDOR_NAME_LEN];
- u32 port_type; /* fiber / copper */
- u32 port_sub_type; /* sr / lr */
- u32 cable_length; /* 1/3/5m */
- u8 cable_temp; /* temp */
- u8 max_speed; /* Maximum rate of an optical module */
- u8 sfp_type; /* sfp/qsfp */
- u8 rsvd1;
- u32 power[4]; /* Optical Power */
-
- u8 an_state;
- u8 fec;
- u16 speed;
-
- u8 gpio_insert; /* 0:present 1:absent */
- u8 alos;
- u8 rx_los;
- u8 pma_ctrl;
-
- u32 pma_fifo_reg;
- u32 pma_signal_ok_reg;
- u32 pcs_64_66b_reg;
- u32 rf_lf;
- u8 pcs_link;
- u8 pcs_mac_link;
- u8 tx_enable;
- u8 rx_enable;
- u32 pcs_err_cnt;
-
- u8 eq_data[38];
- u8 rsvd2[2];
-
- u32 his_link_machine_state;
- u32 cur_link_machine_state;
- u8 his_machine_state_data[128];
- u8 cur_machine_state_data[128];
- u8 his_machine_state_length;
- u8 cur_machine_state_length;
-
- struct mag_port_param_info param_info;
- u8 rsvd3[360];
-};
-
-struct mag_cmd_port_stats {
- u64 mac_tx_fragment_pkt_num;
- u64 mac_tx_undersize_pkt_num;
- u64 mac_tx_undermin_pkt_num;
- u64 mac_tx_64_oct_pkt_num;
- u64 mac_tx_65_127_oct_pkt_num;
- u64 mac_tx_128_255_oct_pkt_num;
- u64 mac_tx_256_511_oct_pkt_num;
- u64 mac_tx_512_1023_oct_pkt_num;
- u64 mac_tx_1024_1518_oct_pkt_num;
- u64 mac_tx_1519_2047_oct_pkt_num;
- u64 mac_tx_2048_4095_oct_pkt_num;
- u64 mac_tx_4096_8191_oct_pkt_num;
- u64 mac_tx_8192_9216_oct_pkt_num;
- u64 mac_tx_9217_12287_oct_pkt_num;
- u64 mac_tx_12288_16383_oct_pkt_num;
- u64 mac_tx_1519_max_bad_pkt_num;
- u64 mac_tx_1519_max_good_pkt_num;
- u64 mac_tx_oversize_pkt_num;
- u64 mac_tx_jabber_pkt_num;
- u64 mac_tx_bad_pkt_num;
- u64 mac_tx_bad_oct_num;
- u64 mac_tx_good_pkt_num;
- u64 mac_tx_good_oct_num;
- u64 mac_tx_total_pkt_num;
- u64 mac_tx_total_oct_num;
- u64 mac_tx_uni_pkt_num;
- u64 mac_tx_multi_pkt_num;
- u64 mac_tx_broad_pkt_num;
- u64 mac_tx_pause_num;
- u64 mac_tx_pfc_pkt_num;
- u64 mac_tx_pfc_pri0_pkt_num;
- u64 mac_tx_pfc_pri1_pkt_num;
- u64 mac_tx_pfc_pri2_pkt_num;
- u64 mac_tx_pfc_pri3_pkt_num;
- u64 mac_tx_pfc_pri4_pkt_num;
- u64 mac_tx_pfc_pri5_pkt_num;
- u64 mac_tx_pfc_pri6_pkt_num;
- u64 mac_tx_pfc_pri7_pkt_num;
- u64 mac_tx_control_pkt_num;
- u64 mac_tx_err_all_pkt_num;
- u64 mac_tx_from_app_good_pkt_num;
- u64 mac_tx_from_app_bad_pkt_num;
-
- u64 mac_rx_fragment_pkt_num;
- u64 mac_rx_undersize_pkt_num;
- u64 mac_rx_undermin_pkt_num;
- u64 mac_rx_64_oct_pkt_num;
- u64 mac_rx_65_127_oct_pkt_num;
- u64 mac_rx_128_255_oct_pkt_num;
- u64 mac_rx_256_511_oct_pkt_num;
- u64 mac_rx_512_1023_oct_pkt_num;
- u64 mac_rx_1024_1518_oct_pkt_num;
- u64 mac_rx_1519_2047_oct_pkt_num;
- u64 mac_rx_2048_4095_oct_pkt_num;
- u64 mac_rx_4096_8191_oct_pkt_num;
- u64 mac_rx_8192_9216_oct_pkt_num;
- u64 mac_rx_9217_12287_oct_pkt_num;
- u64 mac_rx_12288_16383_oct_pkt_num;
- u64 mac_rx_1519_max_bad_pkt_num;
- u64 mac_rx_1519_max_good_pkt_num;
- u64 mac_rx_oversize_pkt_num;
- u64 mac_rx_jabber_pkt_num;
- u64 mac_rx_bad_pkt_num;
- u64 mac_rx_bad_oct_num;
- u64 mac_rx_good_pkt_num;
- u64 mac_rx_good_oct_num;
- u64 mac_rx_total_pkt_num;
- u64 mac_rx_total_oct_num;
- u64 mac_rx_uni_pkt_num;
- u64 mac_rx_multi_pkt_num;
- u64 mac_rx_broad_pkt_num;
- u64 mac_rx_pause_num;
- u64 mac_rx_pfc_pkt_num;
- u64 mac_rx_pfc_pri0_pkt_num;
- u64 mac_rx_pfc_pri1_pkt_num;
- u64 mac_rx_pfc_pri2_pkt_num;
- u64 mac_rx_pfc_pri3_pkt_num;
- u64 mac_rx_pfc_pri4_pkt_num;
- u64 mac_rx_pfc_pri5_pkt_num;
- u64 mac_rx_pfc_pri6_pkt_num;
- u64 mac_rx_pfc_pri7_pkt_num;
- u64 mac_rx_control_pkt_num;
- u64 mac_rx_sym_err_pkt_num;
- u64 mac_rx_fcs_err_pkt_num;
- u64 mac_rx_send_app_good_pkt_num;
- u64 mac_rx_send_app_bad_pkt_num;
- u64 mac_rx_unfilter_pkt_num;
-};
-
-struct mag_port_stats {
- u64 tx_frag_pkts_port;
- u64 tx_under_frame_pkts_port;
- u64 tx_under_min_pkts_port;
- u64 tx_64_oct_pkts_port;
- u64 tx_127_oct_pkts_port;
- u64 tx_255_oct_pkts_port;
- u64 tx_511_oct_pkts_port;
- u64 tx_1023_oct_pkts_port;
- u64 tx_1518_oct_pkts_port;
- u64 tx_2047_oct_pkts_port;
- u64 tx_4095_oct_pkts_port;
- u64 tx_8191_oct_pkts_port;
- u64 tx_9216_oct_pkts_port;
- u64 tx_12287_oct_pkts_port;
- u64 tx_16383_oct_pkts_port;
- u64 tx_1519_to_max_bad_pkts_port;
- u64 tx_1519_to_max_good_pkts_port;
- u64 tx_oversize_pkts_port;
- u64 tx_jabber_pkts_port;
- u64 tx_bad_pkts_port;
- u64 tx_bad_octs_port;
- u64 tx_good_pkts_port;
- u64 tx_good_octs_port;
- u64 tx_total_pkts_port;
- u64 tx_total_octs_port;
- u64 tx_unicast_pkts_port;
- u64 tx_multicast_pkts_port;
- u64 tx_broadcast_pkts_port;
- u64 tx_pause_pkts_port;
- u64 tx_pfc_pkts_port;
- u64 tx_pri_0_pkts_port;
- u64 tx_pri_1_pkts_port;
- u64 tx_pri_2_pkts_port;
- u64 tx_pri_3_pkts_port;
- u64 tx_pri_4_pkts_port;
- u64 tx_pri_5_pkts_port;
- u64 tx_pri_6_pkts_port;
- u64 tx_pri_7_pkts_port;
- u64 tx_mac_control_pkts_port;
- u64 tx_y1731_pkts_port;
- u64 tx_1588_pkts_port;
- u64 tx_error_pkts_port;
- u64 tx_app_good_pkts_port;
- u64 tx_app_bad_pkts_port;
- u64 rx_frag_pkts_port;
- u64 rx_under_frame_pkts_port;
- u64 rx_under_min_pkts_port;
- u64 rx_64_oct_pkts_port;
- u64 rx_127_oct_pkts_port;
- u64 rx_255_oct_pkts_port;
- u64 rx_511_oct_pkts_port;
- u64 rx_1023_oct_pkts_port;
- u64 rx_1518_oct_pkts_port;
- u64 rx_2047_oct_pkts_port;
- u64 rx_4095_oct_pkts_port;
- u64 rx_8191_oct_pkts_port;
- u64 rx_9216_oct_pkts_port;
- u64 rx_12287_oct_pkts_port;
- u64 rx_16383_oct_pkts_port;
- u64 rx_1519_to_max_bad_pkts_port;
- u64 rx_1519_to_max_good_pkts_port;
- u64 rx_oversize_pkts_port;
- u64 rx_jabber_pkts_port;
- u64 rx_bad_pkts_port;
- u64 rx_bad_octs_port;
- u64 rx_good_pkts_port;
- u64 rx_good_octs_port;
- u64 rx_total_pkts_port;
- u64 rx_total_octs_port;
- u64 rx_unicast_pkts_port;
- u64 rx_multicast_pkts_port;
- u64 rx_broadcast_pkts_port;
- u64 rx_pause_pkts_port;
- u64 rx_pfc_pkts_port;
- u64 rx_pri_0_pkts_port;
- u64 rx_pri_1_pkts_port;
- u64 rx_pri_2_pkts_port;
- u64 rx_pri_3_pkts_port;
- u64 rx_pri_4_pkts_port;
- u64 rx_pri_5_pkts_port;
- u64 rx_pri_6_pkts_port;
- u64 rx_pri_7_pkts_port;
- u64 rx_mac_control_pkts_port;
- u64 rx_y1731_pkts_port;
- u64 rx_sym_err_pkts_port;
- u64 rx_fcs_err_pkts_port;
- u64 rx_app_good_pkts_port;
- u64 rx_app_bad_pkts_port;
- u64 rx_unfilter_pkts_port;
-};
-
-struct mag_cmd_port_stats_info {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 rsvd0[3];
-};
-
-struct mag_cmd_get_port_stat {
- struct mgmt_msg_head head;
-
- struct mag_cmd_port_stats counter;
- u64 rsvd1[15];
-};
-
-struct mag_cmd_get_pcs_err_cnt {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 rsvd0[3];
-
- u32 pcs_err_cnt;
-};
-
-struct mag_cmd_get_mag_cnt {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 len;
- u8 rsvd0[2];
-
- u32 mag_csr[128];
-};
-
-struct mag_cmd_dump_antrain_info {
- struct mgmt_msg_head head;
-
- u8 port_id;
- u8 len;
- u8 rsvd0[2];
-
- u32 antrain_csr[256];
-};
-
-#define MAG_SFP_PORT_NUM 24
-struct mag_cmd_sfp_temp_in_info {
- struct mgmt_msg_head head; /* 8B */
- u8 opt_type; /* 0:read operation 1:cfg operation */
- u8 rsv[3];
- s32 max_temp; /* Chip optical module threshold */
- s32 min_temp; /* Chip optical module threshold */
-};
-
-struct mag_cmd_sfp_temp_out_info {
- struct mgmt_msg_head head; /* 8B */
- s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
- s32 max_temp; /* Chip optical module threshold */
- s32 min_temp; /* Chip optical module threshold */
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
new file mode 100644
index 0000000..e77d7d5
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/mag_mpu_cmd_defs.h
@@ -0,0 +1,1143 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+
+#ifndef MAG_MPU_CMD_DEFS_H
+#define MAG_MPU_CMD_DEFS_H
+
+#include "mpu_cmd_base_defs.h"
+
+/* serdes cmd struct define */
+#define CMD_ARRAY_BUF_SIZE 64
+#define SERDES_CMD_DATA_BUF_SIZE 512
+#define RATE_MBPS_TO_GBPS 1000
+struct serdes_in_info {
+ u32 chip_id : 16;
+ u32 macro_id : 16;
+ u32 start_sds_id : 16;
+ u32 sds_num : 16;
+
+ u32 cmd_type : 8; /* reserved for iotype */
+ u32 sub_cmd : 8;
+ u32 rw : 1; /* 0: read, 1: write */
+ u32 rsvd : 15;
+
+ u32 val;
+ union {
+ char field[CMD_ARRAY_BUF_SIZE];
+ u32 addr;
+ u8 *ex_param;
+ };
+};
+
+struct serdes_out_info {
+ u32 str_len; /* out_str length */
+ u32 result_offset;
+ u32 type; /* 0:data; 1:string */
+ char out_str[SERDES_CMD_DATA_BUF_SIZE];
+};
+
+struct serdes_cmd_in {
+ struct mgmt_msg_head head;
+
+ struct serdes_in_info serdes_in;
+};
+
+struct serdes_cmd_out {
+ struct mgmt_msg_head head;
+
+ struct serdes_out_info serdes_out;
+};
+
+enum mag_cmd_port_speed {
+ PORT_SPEED_NOT_SET = 0,
+ PORT_SPEED_10MB = 1,
+ PORT_SPEED_100MB = 2,
+ PORT_SPEED_1GB = 3,
+ PORT_SPEED_10GB = 4,
+ PORT_SPEED_25GB = 5,
+ PORT_SPEED_40GB = 6,
+ PORT_SPEED_50GB = 7,
+ PORT_SPEED_100GB = 8,
+ PORT_SPEED_200GB = 9,
+ PORT_SPEED_UNKNOWN
+};
+
+enum mag_cmd_port_an {
+ PORT_AN_NOT_SET = 0,
+ PORT_CFG_AN_ON = 1,
+ PORT_CFG_AN_OFF = 2
+};
+
+enum mag_cmd_port_adapt {
+ PORT_ADAPT_NOT_SET = 0,
+ PORT_CFG_ADAPT_ON = 1,
+ PORT_CFG_ADAPT_OFF = 2
+};
+
+enum mag_cmd_port_sriov {
+ PORT_SRIOV_NOT_SET = 0,
+ PORT_CFG_SRIOV_ON = 1,
+ PORT_CFG_SRIOV_OFF = 2
+};
+
+enum mag_cmd_port_fec {
+ PORT_FEC_NOT_SET = 0,
+ PORT_FEC_RSFEC = 1,
+ PORT_FEC_BASEFEC = 2,
+ PORT_FEC_NOFEC = 3,
+ PORT_FEC_LLRSFEC = 4,
+ PORT_FEC_AUTO = 5
+};
+
+enum mag_cmd_port_lanes {
+ PORT_LANES_NOT_SET = 0,
+ PORT_LANES_X1 = 1,
+ PORT_LANES_X2 = 2,
+ PORT_LANES_X4 = 4,
+ PORT_LANES_X8 = 8 /* reserved for future use */
+};
+
+enum mag_cmd_port_duplex {
+ PORT_DUPLEX_HALF = 0,
+ PORT_DUPLEX_FULL = 1
+};
+
+enum mag_cmd_wire_node {
+ WIRE_NODE_UNDEF = 0,
+ CABLE_10G = 1,
+ FIBER_10G = 2,
+ CABLE_25G = 3,
+ FIBER_25G = 4,
+ CABLE_40G = 5,
+ FIBER_40G = 6,
+ CABLE_50G = 7,
+ FIBER_50G = 8,
+ CABLE_100G = 9,
+ FIBER_100G = 10,
+ CABLE_200G = 11,
+ FIBER_200G = 12,
+ WIRE_NODE_NUM
+};
+
+enum mag_cmd_cnt_type {
+ MAG_RX_RSFEC_DEC_CW_CNT = 0,
+ MAG_RX_RSFEC_CORR_CW_CNT = 1,
+ MAG_RX_RSFEC_UNCORR_CW_CNT = 2,
+ MAG_RX_PCS_BER_CNT = 3,
+ MAG_RX_PCS_ERR_BLOCK_CNT = 4,
+ MAG_RX_PCS_E_BLK_CNT = 5,
+ MAG_RX_PCS_DEC_ERR_BLK_CNT = 6,
+ MAG_RX_PCS_LANE_BIP_ERR_CNT = 7,
+ MAG_RX_RSFEC_ERR_CW_CNT = 8,
+ MAG_CNT_NUM
+};
+
+/* mag_cmd_set_port_cfg config bitmap */
+#define MAG_CMD_SET_SPEED 0x1
+#define MAG_CMD_SET_AUTONEG 0x2
+#define MAG_CMD_SET_FEC 0x4
+#define MAG_CMD_SET_LANES 0x8
+struct mag_cmd_set_port_cfg {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd0[3];
+
+ u32 config_bitmap;
+ u8 speed;
+ u8 autoneg;
+ u8 fec;
+ u8 lanes;
+ u8 rsvd1[20];
+};
+
+/* mag supported/advertised link mode bitmap */
+enum mag_cmd_link_mode {
+ LINK_MODE_GE = 0,
+ LINK_MODE_10GE_BASE_R = 1,
+ LINK_MODE_25GE_BASE_R = 2,
+ LINK_MODE_40GE_BASE_R4 = 3,
+ LINK_MODE_50GE_BASE_R = 4,
+ LINK_MODE_50GE_BASE_R2 = 5,
+ LINK_MODE_100GE_BASE_R = 6,
+ LINK_MODE_100GE_BASE_R2 = 7,
+ LINK_MODE_100GE_BASE_R4 = 8,
+ LINK_MODE_200GE_BASE_R2 = 9,
+ LINK_MODE_200GE_BASE_R4 = 10,
+ LINK_MODE_MAX_NUMBERS,
+
+ LINK_MODE_UNKNOWN = 0xFFFF
+};
+
+#define LINK_MODE_GE_BIT 0x1u
+#define LINK_MODE_10GE_BASE_R_BIT 0x2u
+#define LINK_MODE_25GE_BASE_R_BIT 0x4u
+#define LINK_MODE_40GE_BASE_R4_BIT 0x8u
+#define LINK_MODE_50GE_BASE_R_BIT 0x10u
+#define LINK_MODE_50GE_BASE_R2_BIT 0x20u
+#define LINK_MODE_100GE_BASE_R_BIT 0x40u
+#define LINK_MODE_100GE_BASE_R2_BIT 0x80u
+#define LINK_MODE_100GE_BASE_R4_BIT 0x100u
+#define LINK_MODE_200GE_BASE_R2_BIT 0x200u
+#define LINK_MODE_200GE_BASE_R4_BIT 0x400u
+
+#define CABLE_10GE_BASE_R_BIT LINK_MODE_10GE_BASE_R_BIT
+#define CABLE_25GE_BASE_R_BIT (LINK_MODE_25GE_BASE_R_BIT | LINK_MODE_10GE_BASE_R_BIT)
+#define CABLE_40GE_BASE_R4_BIT LINK_MODE_40GE_BASE_R4_BIT
+#define CABLE_50GE_BASE_R_BIT (LINK_MODE_50GE_BASE_R_BIT | LINK_MODE_25GE_BASE_R_BIT | \
+ LINK_MODE_10GE_BASE_R_BIT)
+#define CABLE_50GE_BASE_R2_BIT LINK_MODE_50GE_BASE_R2_BIT
+#define CABLE_100GE_BASE_R2_BIT (LINK_MODE_100GE_BASE_R2_BIT | LINK_MODE_50GE_BASE_R2_BIT)
+#define CABLE_100GE_BASE_R4_BIT (LINK_MODE_100GE_BASE_R4_BIT | LINK_MODE_40GE_BASE_R4_BIT)
+#define CABLE_200GE_BASE_R4_BIT (LINK_MODE_200GE_BASE_R4_BIT | LINK_MODE_100GE_BASE_R4_BIT | \
+ LINK_MODE_40GE_BASE_R4_BIT)
+
+struct mag_cmd_get_port_info {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd0[3];
+
+ u8 wire_type;
+ u8 an_support;
+ u8 an_en;
+ u8 duplex;
+
+ u8 speed;
+ u8 fec;
+ u8 lanes;
+ u8 rsvd1;
+
+ u32 supported_mode;
+ u32 advertised_mode;
+ u32 supported_fec_mode;
+ u16 bond_speed;
+ u8 rsvd2[2];
+};
+
+#define MAG_CMD_OPCODE_GET 0
+#define MAG_CMD_OPCODE_SET 1
+struct mag_cmd_set_port_adapt {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 opcode; /* 0:get adapt info 1:set adapt */
+ u8 enable;
+ u8 rsvd0;
+ u32 speed_mode;
+ u32 rsvd1[3];
+};
+
+#define MAG_CMD_LP_MODE_SDS_S_TX2RX 1
+#define MAG_CMD_LP_MODE_SDS_P_RX2TX 2
+#define MAG_CMD_LP_MODE_SDS_P_TX2RX 3
+#define MAG_CMD_LP_MODE_MAC_RX2TX 4
+#define MAG_CMD_LP_MODE_MAC_TX2RX 5
+#define MAG_CMD_LP_MODE_TXDP2RXDP 6
+struct mag_cmd_cfg_loopback_mode {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 opcode; /* 0:get loopback mode 1:set loopback mode */
+ u8 lp_mode;
+ u8 lp_en; /* 0:disable 1:enable */
+
+ u32 rsvd0[2];
+};
+
+#define MAG_CMD_PORT_DISABLE 0x0
+#define MAG_CMD_TX_ENABLE 0x1
+#define MAG_CMD_RX_ENABLE 0x2
+/* the physical port is disable only when all pf of the port are set to down,
+ * if any pf is enable, the port is enable
+ */
+struct mag_cmd_set_port_enable {
+ struct mgmt_msg_head head;
+
+ u16 function_id; /* function_id should not more than the max support pf_id(32) */
+ u16 rsvd0;
+
+ u8 state; /* bitmap bit0:tx_en bit1:rx_en */
+ u8 rsvd1[3];
+};
+
+struct mag_cmd_get_port_enable {
+ struct mgmt_msg_head head;
+
+ u8 port;
+ u8 state; /* bitmap bit0:tx_en bit1:rx_en */
+ u8 rsvd0[2];
+};
+
+#define PMA_FOLLOW_DEFAULT 0x0
+#define PMA_FOLLOW_ENABLE 0x1
+#define PMA_FOLLOW_DISABLE 0x2
+#define PMA_FOLLOW_GET 0x4
+/* the physical port disable link follow only when all pf of the port are set to follow disable */
+struct mag_cmd_set_link_follow {
+ struct mgmt_msg_head head;
+
+ u16 function_id; /* function_id should not more than the max support pf_id(32) */
+ u16 rsvd0;
+
+ u8 follow;
+ u8 rsvd1[3];
+};
+
+/* firmware also use this cmd report link event to driver */
+struct mag_cmd_get_link_status {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 status; /* 0:link down 1:link up */
+ u8 rsvd0[2];
+};
+
+/* firmware also use this cmd report bond event to driver */
+struct mag_cmd_get_bond_status {
+ struct mgmt_msg_head head;
+
+ u8 status; /* 0:bond down 1:bond up */
+ u8 rsvd0[3];
+};
+
+struct mag_cmd_set_pma_enable {
+ struct mgmt_msg_head head;
+
+ u16 function_id; /* function_id should not more than the max support pf_id(32) */
+ u16 enable;
+};
+
+struct mag_cmd_cfg_an_type {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 opcode; /* 0:get an type 1:set an type */
+ u8 rsvd0[2];
+
+ u32 an_type; /* 0:ieee 1:25G/50 eth consortium */
+};
+
+struct mag_cmd_get_link_time {
+ struct mgmt_msg_head head;
+ u8 port_id;
+ u8 rsvd0[3];
+
+ u32 link_up_begin;
+ u32 link_up_end;
+ u32 link_down_begin;
+ u32 link_down_end;
+};
+
+struct mag_cmd_cfg_fec_mode {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 opcode; /* 0:get fec mode 1:set fec mode */
+ u8 advertised_fec;
+ u8 supported_fec;
+};
+
+/* speed */
+#define PANGEA_ADAPT_10G_BITMAP 0xd
+#define PANGEA_ADAPT_25G_BITMAP 0x72
+#define PANGEA_ADAPT_40G_BITMAP 0x680
+#define PANGEA_ADAPT_100G_BITMAP 0x1900
+
+/* speed and fec */
+#define PANGEA_10G_NO_BITMAP 0x8
+#define PANGEA_10G_BASE_BITMAP 0x4
+#define PANGEA_25G_NO_BITMAP 0x10
+#define PANGEA_25G_BASE_BITMAP 0x20
+#define PANGEA_25G_RS_BITMAP 0x40
+#define PANGEA_40G_NO_BITMAP 0x400
+#define PANGEA_40G_BASE_BITMAP 0x200
+#define PANGEA_100G_NO_BITMAP 0x800
+#define PANGEA_100G_RS_BITMAP 0x1000
+
+/* adapt or fec */
+#define PANGEA_ADAPT_ADAPT_BITMAP 0x183
+#define PANGEA_ADAPT_NO_BITMAP 0xc18
+#define PANGEA_ADAPT_BASE_BITMAP 0x224
+#define PANGEA_ADAPT_RS_BITMAP 0x1040
+
+/* default cfg */
+#define PANGEA_ADAPT_CFG_10G_CR 0x200d
+#define PANGEA_ADAPT_CFG_10G_SRLR 0xd
+#define PANGEA_ADAPT_CFG_25G_CR 0x207f
+#define PANGEA_ADAPT_CFG_25G_SRLR 0x72
+#define PANGEA_ADAPT_CFG_40G_CR4 0x2680
+#define PANGEA_ADAPT_CFG_40G_SRLR4 0x680
+#define PANGEA_ADAPT_CFG_100G_CR4 0x3f80
+#define PANGEA_ADAPT_CFG_100G_SRLR4 0x1900
+
+union pangea_adapt_bitmap_u {
+ struct {
+ u32 adapt_10g : 1; /* [0] adapt_10g */
+ u32 adapt_25g : 1; /* [1] adapt_25g */
+ u32 base_10g : 1; /* [2] base_10g */
+ u32 no_10g : 1; /* [3] no_10g */
+ u32 no_25g : 1; /* [4] no_25g */
+ u32 base_25g : 1; /* [5] base_25g */
+ u32 rs_25g : 1; /* [6] rs_25g */
+ u32 adapt_40g : 1; /* [7] adapt_40g */
+ u32 adapt_100g : 1; /* [8] adapt_100g */
+ u32 base_40g : 1; /* [9] base_40g */
+ u32 no_40g : 1; /* [10] no_40g */
+ u32 no_100g : 1; /* [11] no_100g */
+ u32 rs_100g : 1; /* [12] rs_100g */
+ u32 auto_neg : 1; /* [13] auto_neg */
+ u32 rsvd0 : 18; /* [31:14] reserved */
+ } bits;
+
+ u32 value;
+};
+
+#define PANGEA_ADAPT_GET 0x0
+#define PANGEA_ADAPT_SET 0x1
+struct mag_cmd_set_pangea_adapt {
+ struct mgmt_msg_head head;
+
+ u16 port_id;
+ u8 opcode; /* 0:get adapt info 1:cfg adapt info */
+ u8 wire_type;
+
+ union pangea_adapt_bitmap_u cfg_bitmap;
+ union pangea_adapt_bitmap_u cur_bitmap;
+ u32 rsvd1[3];
+};
+
+struct mag_cmd_cfg_bios_link_cfg {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 opcode; /* 0:get bios link info 1:set bios link cfg */
+ u8 clear;
+ u8 rsvd0;
+
+ u32 wire_type;
+ u8 an_en;
+ u8 speed;
+ u8 fec;
+ u8 rsvd1;
+ u32 speed_mode;
+ u32 rsvd2[3];
+};
+
+struct mag_cmd_restore_link_cfg {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[7];
+};
+
+struct mag_cmd_activate_bios_link_cfg {
+ struct mgmt_msg_head head;
+
+ u32 rsvd[8];
+};
+
+/* led type */
+enum mag_led_type {
+ MAG_CMD_LED_TYPE_ALARM = 0x0,
+ MAG_CMD_LED_TYPE_LOW_SPEED = 0x1,
+ MAG_CMD_LED_TYPE_HIGH_SPEED = 0x2
+};
+
+/* led mode */
+enum mag_led_mode {
+ MAG_CMD_LED_MODE_DEFAULT = 0x0,
+ MAG_CMD_LED_MODE_FORCE_ON = 0x1,
+ MAG_CMD_LED_MODE_FORCE_OFF = 0x2,
+ MAG_CMD_LED_MODE_FORCE_BLINK_1HZ = 0x3,
+ MAG_CMD_LED_MODE_FORCE_BLINK_2HZ = 0x4,
+ MAG_CMD_LED_MODE_FORCE_BLINK_4HZ = 0x5,
+ MAG_CMD_LED_MODE_1HZ = 0x6,
+ MAG_CMD_LED_MODE_2HZ = 0x7,
+ MAG_CMD_LED_MODE_4HZ = 0x8
+};
+
+/* the led is report alarm when any pf of the port is alram */
+struct mag_cmd_set_led_cfg {
+ struct mgmt_msg_head head;
+
+ u16 function_id;
+ u8 type;
+ u8 mode;
+};
+
+#define XSFP_INFO_MAX_SIZE 640
+/* xsfp wire type, refer to cmis protocol definition */
+enum mag_wire_type {
+ MAG_CMD_WIRE_TYPE_UNKNOWN = 0x0,
+ MAG_CMD_WIRE_TYPE_MM = 0x1,
+ MAG_CMD_WIRE_TYPE_SM = 0x2,
+ MAG_CMD_WIRE_TYPE_COPPER = 0x3,
+ MAG_CMD_WIRE_TYPE_ACC = 0x4,
+ MAG_CMD_WIRE_TYPE_BASET = 0x5,
+ MAG_CMD_WIRE_TYPE_AOC = 0x40,
+ MAG_CMD_WIRE_TYPE_ELECTRIC = 0x41,
+ MAG_CMD_WIRE_TYPE_BACKPLANE = 0x42
+};
+
+struct mag_cmd_get_xsfp_info {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 wire_type;
+ u16 out_len;
+ u32 rsvd;
+ u8 sfp_info[XSFP_INFO_MAX_SIZE];
+};
+
+#define MAG_CMD_XSFP_DISABLE 0x0
+#define MAG_CMD_XSFP_ENABLE 0x1
+/* the sfp is disable only when all pf of the port are set sfp down,
+ * if any pf is enable, the sfp is enable
+ */
+struct mag_cmd_set_xsfp_enable {
+ struct mgmt_msg_head head;
+
+ u32 port_id;
+ u32 status; /* 0:on 1:off */
+};
+
+#define MAG_CMD_XSFP_PRESENT 0x0
+#define MAG_CMD_XSFP_ABSENT 0x1
+struct mag_cmd_get_xsfp_present {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 abs_status; /* 0:present, 1:absent */
+ u8 rsvd[2];
+};
+
+#define MAG_CMD_XSFP_READ 0x0
+#define MAG_CMD_XSFP_WRITE 0x1
+struct mag_cmd_set_xsfp_rw {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 operation; /* 0: read; 1: write */
+ u8 value;
+ u8 rsvd0;
+ u32 devaddr;
+ u32 offset;
+ u32 rsvd1;
+};
+
+struct mag_cmd_cfg_xsfp_temperature {
+ struct mgmt_msg_head head;
+
+ u8 opcode; /* 0:read 1:write */
+ u8 rsvd0[3];
+ s32 max_temp;
+ s32 min_temp;
+};
+
+struct mag_cmd_get_xsfp_temperature {
+ struct mgmt_msg_head head;
+
+ s16 sfp_temp[8];
+ u8 rsvd[32];
+ s32 max_temp;
+ s32 min_temp;
+};
+
+/* xsfp plug event */
+struct mag_cmd_wire_event {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 status; /* 0:present, 1:absent */
+ u8 rsvd[2];
+};
+
+/* link err type definition */
+#define MAG_CMD_ERR_XSFP_UNKNOWN 0x0
+struct mag_cmd_link_err_event {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 link_err_type;
+ u8 rsvd[2];
+};
+
+#define MAG_PARAM_TYPE_DEFAULT_CFG 0x0
+#define MAG_PARAM_TYPE_BIOS_CFG 0x1
+#define MAG_PARAM_TYPE_TOOL_CFG 0x2
+#define MAG_PARAM_TYPE_FINAL_CFG 0x3
+#define MAG_PARAM_TYPE_WIRE_INFO 0x4
+#define MAG_PARAM_TYPE_ADAPT_INFO 0x5
+#define MAG_PARAM_TYPE_MAX_CNT 0x6
+struct param_head {
+ u8 valid_len;
+ u8 info_type;
+ u8 rsvd[2];
+};
+
+struct mag_port_link_param {
+ struct param_head head;
+
+ u8 an;
+ u8 fec;
+ u8 speed;
+ u8 rsvd0;
+
+ u32 used;
+ u32 an_fec_ability;
+ u32 an_speed_ability;
+ u32 an_pause_ability;
+};
+
+struct mag_port_wire_info {
+ struct param_head head;
+
+ u8 status;
+ u8 rsvd0[3];
+
+ u8 wire_type;
+ u8 default_fec;
+ u8 speed;
+ u8 rsvd1;
+ u32 speed_ability;
+};
+
+struct mag_port_adapt_info {
+ struct param_head head;
+
+ u32 adapt_en;
+ u32 flash_adapt;
+ u32 rsvd0[2];
+
+ u32 wire_node;
+ u32 an_en;
+ u32 speed;
+ u32 fec;
+};
+
+struct mag_port_param_info {
+ u8 parameter_cnt;
+ u8 lane_id;
+ u8 lane_num;
+ u8 rsvd0;
+
+ struct mag_port_link_param default_cfg;
+ struct mag_port_link_param bios_cfg;
+ struct mag_port_link_param tool_cfg;
+ struct mag_port_link_param final_cfg;
+
+ struct mag_port_wire_info wire_info;
+ struct mag_port_adapt_info adapt_info;
+};
+
+#define XSFP_VENDOR_NAME_LEN 16
+struct mag_cmd_event_port_info {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 event_type;
+ u8 rsvd0[2];
+
+ u8 vendor_name[XSFP_VENDOR_NAME_LEN];
+ u32 port_type; /* fiber / copper */
+ u32 port_sub_type; /* sr / lr */
+ u32 cable_length; /* 1/3/5m */
+ u8 cable_temp; /* temp */
+ u8 max_speed; /* Maximum rate of an optical module */
+ u8 sfp_type; /* sfp/qsfp/dsfp */
+ u8 rsvd1;
+ u32 power[4]; /* Optical Power */
+
+ u8 an_state;
+ u8 fec;
+ u16 speed;
+
+ u8 gpio_insert; /* 0:present 1:absent */
+ u8 alos;
+ u8 rx_los;
+ u8 pma_ctrl;
+
+ u32 pma_fifo_reg;
+ u32 pma_signal_ok_reg;
+ u32 pcs_64_66b_reg;
+ u32 rf_lf;
+ u8 pcs_link;
+ u8 pcs_mac_link;
+ u8 tx_enable;
+ u8 rx_enable;
+ u32 pcs_err_cnt;
+
+ u8 eq_data[38];
+ u8 rsvd2[2];
+
+ u32 his_link_machine_state;
+ u32 cur_link_machine_state;
+ u8 his_machine_state_data[128];
+ u8 cur_machine_state_data[128];
+ u8 his_machine_state_length;
+ u8 cur_machine_state_length;
+
+ struct mag_port_param_info param_info;
+ u8 rsvd3[360];
+};
+
+struct mag_cmd_rsfec_stats {
+ u32 rx_err_lane_phy;
+};
+
+struct mag_cmd_port_stats {
+ u64 mac_tx_fragment_pkt_num;
+ u64 mac_tx_undersize_pkt_num;
+ u64 mac_tx_undermin_pkt_num;
+ u64 mac_tx_64_oct_pkt_num;
+ u64 mac_tx_65_127_oct_pkt_num;
+ u64 mac_tx_128_255_oct_pkt_num;
+ u64 mac_tx_256_511_oct_pkt_num;
+ u64 mac_tx_512_1023_oct_pkt_num;
+ u64 mac_tx_1024_1518_oct_pkt_num;
+ u64 mac_tx_1519_2047_oct_pkt_num;
+ u64 mac_tx_2048_4095_oct_pkt_num;
+ u64 mac_tx_4096_8191_oct_pkt_num;
+ u64 mac_tx_8192_9216_oct_pkt_num;
+ u64 mac_tx_9217_12287_oct_pkt_num;
+ u64 mac_tx_12288_16383_oct_pkt_num;
+ u64 mac_tx_1519_max_bad_pkt_num;
+ u64 mac_tx_1519_max_good_pkt_num;
+ u64 mac_tx_oversize_pkt_num;
+ u64 mac_tx_jabber_pkt_num;
+ u64 mac_tx_bad_pkt_num;
+ u64 mac_tx_bad_oct_num;
+ u64 mac_tx_good_pkt_num;
+ u64 mac_tx_good_oct_num;
+ u64 mac_tx_total_pkt_num;
+ u64 mac_tx_total_oct_num;
+ u64 mac_tx_uni_pkt_num;
+ u64 mac_tx_multi_pkt_num;
+ u64 mac_tx_broad_pkt_num;
+ u64 mac_tx_pause_num;
+ u64 mac_tx_pfc_pkt_num;
+ u64 mac_tx_pfc_pri0_pkt_num;
+ u64 mac_tx_pfc_pri1_pkt_num;
+ u64 mac_tx_pfc_pri2_pkt_num;
+ u64 mac_tx_pfc_pri3_pkt_num;
+ u64 mac_tx_pfc_pri4_pkt_num;
+ u64 mac_tx_pfc_pri5_pkt_num;
+ u64 mac_tx_pfc_pri6_pkt_num;
+ u64 mac_tx_pfc_pri7_pkt_num;
+ u64 mac_tx_control_pkt_num;
+ u64 mac_tx_err_all_pkt_num;
+ u64 mac_tx_from_app_good_pkt_num;
+ u64 mac_tx_from_app_bad_pkt_num;
+
+ u64 mac_rx_fragment_pkt_num;
+ u64 mac_rx_undersize_pkt_num;
+ u64 mac_rx_undermin_pkt_num;
+ u64 mac_rx_64_oct_pkt_num;
+ u64 mac_rx_65_127_oct_pkt_num;
+ u64 mac_rx_128_255_oct_pkt_num;
+ u64 mac_rx_256_511_oct_pkt_num;
+ u64 mac_rx_512_1023_oct_pkt_num;
+ u64 mac_rx_1024_1518_oct_pkt_num;
+ u64 mac_rx_1519_2047_oct_pkt_num;
+ u64 mac_rx_2048_4095_oct_pkt_num;
+ u64 mac_rx_4096_8191_oct_pkt_num;
+ u64 mac_rx_8192_9216_oct_pkt_num;
+ u64 mac_rx_9217_12287_oct_pkt_num;
+ u64 mac_rx_12288_16383_oct_pkt_num;
+ u64 mac_rx_1519_max_bad_pkt_num;
+ u64 mac_rx_1519_max_good_pkt_num;
+ u64 mac_rx_oversize_pkt_num;
+ u64 mac_rx_jabber_pkt_num;
+ u64 mac_rx_bad_pkt_num;
+ u64 mac_rx_bad_oct_num;
+ u64 mac_rx_good_pkt_num;
+ u64 mac_rx_good_oct_num;
+ u64 mac_rx_total_pkt_num;
+ u64 mac_rx_total_oct_num;
+ u64 mac_rx_uni_pkt_num;
+ u64 mac_rx_multi_pkt_num;
+ u64 mac_rx_broad_pkt_num;
+ u64 mac_rx_pause_num;
+ u64 mac_rx_pfc_pkt_num;
+ u64 mac_rx_pfc_pri0_pkt_num;
+ u64 mac_rx_pfc_pri1_pkt_num;
+ u64 mac_rx_pfc_pri2_pkt_num;
+ u64 mac_rx_pfc_pri3_pkt_num;
+ u64 mac_rx_pfc_pri4_pkt_num;
+ u64 mac_rx_pfc_pri5_pkt_num;
+ u64 mac_rx_pfc_pri6_pkt_num;
+ u64 mac_rx_pfc_pri7_pkt_num;
+ u64 mac_rx_control_pkt_num;
+ u64 mac_rx_sym_err_pkt_num;
+ u64 mac_rx_fcs_err_pkt_num;
+ u64 mac_rx_send_app_good_pkt_num;
+ u64 mac_rx_send_app_bad_pkt_num;
+ u64 mac_rx_unfilter_pkt_num;
+};
+
+struct mag_port_stats {
+ u64 tx_frag_pkts_port;
+ u64 tx_under_frame_pkts_port;
+ u64 tx_under_min_pkts_port;
+ u64 tx_64_oct_pkts_port;
+ u64 tx_127_oct_pkts_port;
+ u64 tx_255_oct_pkts_port;
+ u64 tx_511_oct_pkts_port;
+ u64 tx_1023_oct_pkts_port;
+ u64 tx_1518_oct_pkts_port;
+ u64 tx_2047_oct_pkts_port;
+ u64 tx_4095_oct_pkts_port;
+ u64 tx_8191_oct_pkts_port;
+ u64 tx_9216_oct_pkts_port;
+ u64 tx_12287_oct_pkts_port;
+ u64 tx_16383_oct_pkts_port;
+ u64 tx_1519_to_max_bad_pkts_port;
+ u64 tx_1519_to_max_good_pkts_port;
+ u64 tx_oversize_pkts_port;
+ u64 tx_jabber_pkts_port;
+ u64 tx_bad_pkts_port;
+ u64 tx_bad_octs_port;
+ u64 tx_good_pkts_port;
+ u64 tx_good_octs_port;
+ u64 tx_total_pkts_port;
+ u64 tx_total_octs_port;
+ u64 tx_unicast_pkts_port;
+ u64 tx_multicast_pkts_port;
+ u64 tx_broadcast_pkts_port;
+ u64 tx_pause_pkts_port;
+ u64 tx_pfc_pkts_port;
+ u64 tx_pri_0_pkts_port;
+ u64 tx_pri_1_pkts_port;
+ u64 tx_pri_2_pkts_port;
+ u64 tx_pri_3_pkts_port;
+ u64 tx_pri_4_pkts_port;
+ u64 tx_pri_5_pkts_port;
+ u64 tx_pri_6_pkts_port;
+ u64 tx_pri_7_pkts_port;
+ u64 tx_mac_control_pkts_port;
+ u64 tx_y1731_pkts_port;
+ u64 tx_1588_pkts_port;
+ u64 tx_error_pkts_port;
+ u64 tx_app_good_pkts_port;
+ u64 tx_app_bad_pkts_port;
+ u64 rx_frag_pkts_port;
+ u64 rx_under_frame_pkts_port;
+ u64 rx_under_min_pkts_port;
+ u64 rx_64_oct_pkts_port;
+ u64 rx_127_oct_pkts_port;
+ u64 rx_255_oct_pkts_port;
+ u64 rx_511_oct_pkts_port;
+ u64 rx_1023_oct_pkts_port;
+ u64 rx_1518_oct_pkts_port;
+ u64 rx_2047_oct_pkts_port;
+ u64 rx_4095_oct_pkts_port;
+ u64 rx_8191_oct_pkts_port;
+ u64 rx_9216_oct_pkts_port;
+ u64 rx_12287_oct_pkts_port;
+ u64 rx_16383_oct_pkts_port;
+ u64 rx_1519_to_max_bad_pkts_port;
+ u64 rx_1519_to_max_good_pkts_port;
+ u64 rx_oversize_pkts_port;
+ u64 rx_jabber_pkts_port;
+ u64 rx_bad_pkts_port;
+ u64 rx_bad_octs_port;
+ u64 rx_good_pkts_port;
+ u64 rx_good_octs_port;
+ u64 rx_total_pkts_port;
+ u64 rx_total_octs_port;
+ u64 rx_unicast_pkts_port;
+ u64 rx_multicast_pkts_port;
+ u64 rx_broadcast_pkts_port;
+ u64 rx_pause_pkts_port;
+ u64 rx_pfc_pkts_port;
+ u64 rx_pri_0_pkts_port;
+ u64 rx_pri_1_pkts_port;
+ u64 rx_pri_2_pkts_port;
+ u64 rx_pri_3_pkts_port;
+ u64 rx_pri_4_pkts_port;
+ u64 rx_pri_5_pkts_port;
+ u64 rx_pri_6_pkts_port;
+ u64 rx_pri_7_pkts_port;
+ u64 rx_mac_control_pkts_port;
+ u64 rx_y1731_pkts_port;
+ u64 rx_sym_err_pkts_port;
+ u64 rx_fcs_err_pkts_port;
+ u64 rx_app_good_pkts_port;
+ u64 rx_app_bad_pkts_port;
+ u64 rx_unfilter_pkts_port;
+};
+
+struct mag_cmd_port_stats_info {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd0[3];
+};
+
+struct mag_cmd_get_port_stat {
+ struct mgmt_msg_head head;
+
+ struct mag_cmd_port_stats counter;
+ u64 rsvd1[15];
+};
+
+struct mag_cmd_get_pcs_err_cnt {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd0[3];
+
+ u32 pcs_err_cnt;
+};
+
+struct mag_cmd_get_mag_cnt {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 len;
+ u8 rsvd0[2];
+
+ u32 mag_csr[128];
+};
+
+struct mag_cmd_dump_antrain_info {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 len;
+ u8 rsvd0[2];
+
+ u32 antrain_csr[256];
+};
+
+#define MAG_SFP_PORT_NUM 24
+struct mag_cmd_sfp_temp_in_info {
+ struct mgmt_msg_head head; /* 8B */
+ u8 opt_type; /* 0:read operation 1:cfg operation */
+ u8 rsv[3];
+ s32 max_temp; /* Chip optical module threshold */
+ s32 min_temp; /* Chip optical module threshold */
+};
+
+struct mag_cmd_sfp_temp_out_info {
+ struct mgmt_msg_head head; /* 8B */
+ s16 sfp_temp_data[MAG_SFP_PORT_NUM]; /* Temperature read */
+ s32 max_temp; /* Chip optical module threshold */
+ s32 min_temp; /* Chip optical module threshold */
+};
+
+#define XSFP_CMIS_PARSE_PAGE_NUM 6
+#define XSFP_CMIS_INFO_MAX_SIZE 1536
+#define QSFP_CMIS_PAGE_SIZE 128
+#define QSFP_CMIS_MAX_CHANNEL_NUM 0x8
+
+/* Lower: Control and Essentials, Upper: Administrative Information */
+#define QSFP_CMIS_PAGE_00H 0x00
+/* Advertising */
+#define QSFP_CMIS_PAGE_01H 0x01
+/* Module and lane Thresholds */
+#define QSFP_CMIS_PAGE_02H 0x02
+/* User EEPROM */
+#define QSFP_CMIS_PAGE_03H 0x03
+/* Laser Capabilities Advertising (Page 04h, Optional) */
+#define QSFP_CMIS_PAGE_04H 0x04
+#define QSFP_CMIS_PAGE_05H 0x05
+/* Lane and Data Path Control */
+#define QSFP_CMIS_PAGE_10H 0x10
+/* Lane Status */
+#define QSFP_CMIS_PAGE_11H 0x11
+#define QSFP_CMIS_PAGE_12H 0x12
+
+#define MGMT_TLV_U8_SIZE 1
+#define MGMT_TLV_U16_SIZE 2
+#define MGMT_TLV_U32_SIZE 4
+
+#define MGMT_TLV_GET_U8(addr) (*((u8 *)(void *)(addr)))
+#define MGMT_TLV_SET_U8(addr, value) \
+ ((*((u8 *)(void *)(addr))) = ((u8)(value)))
+
+#define MGMT_TLV_GET_U16(addr) (*((u16 *)(void *)(addr)))
+#define MGMT_TLV_SET_U16(addr, value) \
+ ((*((u16 *)(void *)(addr))) = ((u16)(value)))
+
+#define MGMT_TLV_GET_U32(addr) (*((u32 *)(void *)(addr)))
+#define MGMT_TLV_SET_U32(addr, value) \
+ ((*((u32 *)(void *)(addr))) = ((u32)(value)))
+
+#define MGMT_TLV_TYPE_END 0xFFFF
+
+enum mag_xsfp_type {
+ MAG_XSFP_TYPE_PAGE = 0x01,
+ MAG_XSFP_TYPE_WIRE_TYPE = 0x02,
+ MAG_XSFP_TYPE_END = MGMT_TLV_TYPE_END
+};
+
+struct qsfp_cmis_lower_page_00_s {
+ u8 resv0[14];
+ u8 temperature_msb;
+ u8 temperature_lsb;
+ u8 volt_supply[2];
+ u8 resv1[67];
+ u8 media_type;
+ u8 electrical_interface_id;
+ u8 media_interface_id;
+ u8 lane_count;
+ u8 resv2[39];
+};
+
+struct qsfp_cmis_upper_page_00_s {
+ u8 identifier;
+ u8 vendor_name[16];
+ u8 vendor_oui[3];
+ u8 vendor_pn[16];
+ u8 vendor_rev[2];
+ u8 vendor_sn[16];
+ u8 date_code[8];
+ u8 clei_code[10];
+ u8 power_character[2];
+ u8 cable_len;
+ u8 connector;
+ u8 copper_cable_attenuation[6];
+ u8 near_end_implementation;
+ u8 far_end_config;
+ u8 media_technology;
+ u8 resv0[43];
+};
+
+struct qsfp_cmis_upper_page_01_s {
+ u8 firmware_rev[2];
+ u8 hardware_rev[2];
+ u8 smf_len_km;
+ u8 om5_len;
+ u8 om4_len;
+ u8 om3_len;
+ u8 om2_len;
+ u8 resv0;
+ u8 wavelength[2];
+ u8 wavelength_tolerance[2];
+ u8 pages_implement;
+ u8 resv1[16];
+ u8 monitor_implement[2];
+ u8 resv2[95];
+};
+
+struct qsfp_cmis_upper_page_02_s {
+ u8 temperature_high_alarm[2];
+ u8 temperature_low_alarm[2];
+ u8 temperature_high_warn[2];
+ u8 temperature_low_warn[2];
+ u8 volt_high_alarm[2];
+ u8 volt_low_alarm[2];
+ u8 volt_high_warn[2];
+ u8 volt_low_warn[2];
+ u8 resv0[32];
+ u8 tx_power_high_alarm[2];
+ u8 tx_power_low_alarm[2];
+ u8 tx_power_high_warn[2];
+ u8 tx_power_low_warn[2];
+ u8 tx_bias_high_alarm[2];
+ u8 tx_bias_low_alarm[2];
+ u8 tx_bias_high_warn[2];
+ u8 tx_bias_low_warn[2];
+ u8 rx_power_high_alarm[2];
+ u8 rx_power_low_alarm[2];
+ u8 rx_power_high_warn[2];
+ u8 rx_power_low_warn[2];
+ u8 resv1[56];
+};
+
+struct qsfp_cmis_upper_page_03_s {
+ u8 resv0[QSFP_CMIS_PAGE_SIZE]; /* Reg 128-255: Upper Memory: Page 03H */
+};
+
+struct qsfp_cmis_upper_page_10_s {
+ u8 resv0[2]; /* Reg 128-129: Upper Memory: Page 10H */
+ u8 tx_disable; /* Reg 130: Tx disable, 0b=enabled, 1b=disabled */
+ u8 resv1[125]; /* Reg 131-255 */
+};
+
+struct qsfp_cmis_upper_page_11_s {
+ u8 resv0[7];
+ u8 tx_fault;
+ u8 tx_los;
+ u8 resv1[10];
+ u8 rx_los;
+ u8 resv2[6];
+ u8 tx_power[16];
+ u8 tx_bias[16];
+ u8 rx_power[16];
+ u8 resv3[54];
+};
+
+struct qsfp_cmis_info_s {
+ struct qsfp_cmis_lower_page_00_s lower_page_00;
+ struct qsfp_cmis_upper_page_00_s upper_page_00;
+ struct qsfp_cmis_upper_page_01_s upper_page_01;
+ struct qsfp_cmis_upper_page_02_s upper_page_02;
+ struct qsfp_cmis_upper_page_10_s upper_page_10;
+ struct qsfp_cmis_upper_page_11_s upper_page_11;
+};
+
+struct qsfp_cmis_comm_power_s {
+ u32 chl_power[QSFP_CMIS_MAX_CHANNEL_NUM];
+};
+
+struct qsfp_cmis_wire_info_s {
+ struct qsfp_cmis_comm_power_s rx_power;
+ u8 rx_los;
+ u8 resv0[3];
+};
+
+struct mgmt_tlv_info {
+ u16 type;
+ u16 length;
+ u8 value[];
+};
+
+struct mag_cmd_set_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 tlv_buf[];
+};
+
+struct mag_cmd_set_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+};
+
+struct mag_cmd_get_xsfp_tlv_req {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd;
+ u16 rsp_buf_len;
+};
+
+struct mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[];
+};
+
+
+struct parse_tlv_info {
+ u8 tlv_page_info[XSFP_CMIS_INFO_MAX_SIZE + 1];
+ u32 tlv_page_info_len;
+ u32 tlv_page_num[XSFP_CMIS_PARSE_PAGE_NUM];
+ u32 wire_type;
+ u8 id;
+};
+
+struct drv_mag_cmd_get_xsfp_tlv_rsp {
+ struct mgmt_msg_head head;
+
+ u8 port_id;
+ u8 rsvd[3];
+
+ u8 tlv_buf[XSFP_CMIS_INFO_MAX_SIZE];
+};
+
+#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h b/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
deleted file mode 100644
index 257bf67..0000000
--- a/drivers/net/ethernet/huawei/hinic3/mgmt_msg_base.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
- * File Name : mgmt_msg_base.h
- * Version : Initial Draft
- * Created : 2021/6/28
- * Last Modified :
- * Description : COMM Command interfaces between Driver and MPU
- * Function List :
- */
-
-#ifndef MGMT_MSG_BASE_H
-#define MGMT_MSG_BASE_H
-
-#define MGMT_MSG_CMD_OP_SET 1
-#define MGMT_MSG_CMD_OP_GET 0
-
-#define MGMT_MSG_CMD_OP_START 1
-#define MGMT_MSG_CMD_OP_STOP 0
-
-struct mgmt_msg_head {
- u8 status;
- u8 version;
- u8 rsvd0[6];
-};
-
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h b/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
deleted file mode 100644
index 9fb4232..0000000
--- a/drivers/net/ethernet/huawei/hinic3/nic_cfg_comm.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C), 2001-2021, Huawei Tech. Co., Ltd.
- * File Name : nic_cfg_comm.h
- * Version : Initial Draft
- * Description : nic config common header file
- * Function List :
- * History :
- * Modification: Created file
- */
-
-#ifndef NIC_CFG_COMM_H
-#define NIC_CFG_COMM_H
-
-/* rss */
-#define HINIC3_RSS_TYPE_VALID_SHIFT 23
-#define HINIC3_RSS_TYPE_TCP_IPV6_EXT_SHIFT 24
-#define HINIC3_RSS_TYPE_IPV6_EXT_SHIFT 25
-#define HINIC3_RSS_TYPE_TCP_IPV6_SHIFT 26
-#define HINIC3_RSS_TYPE_IPV6_SHIFT 27
-#define HINIC3_RSS_TYPE_TCP_IPV4_SHIFT 28
-#define HINIC3_RSS_TYPE_IPV4_SHIFT 29
-#define HINIC3_RSS_TYPE_UDP_IPV6_SHIFT 30
-#define HINIC3_RSS_TYPE_UDP_IPV4_SHIFT 31
-
-#define HINIC3_RSS_TYPE_SET(val, member) (((u32)(val) & 0x1) << HINIC3_RSS_TYPE_##member##_SHIFT)
-#define HINIC3_RSS_TYPE_GET(val, member) (((u32)(val) >> HINIC3_RSS_TYPE_##member##_SHIFT) & 0x1)
-
-enum nic_rss_hash_type {
- NIC_RSS_HASH_TYPE_XOR = 0,
- NIC_RSS_HASH_TYPE_TOEP,
-
- NIC_RSS_HASH_TYPE_MAX /* MUST BE THE LAST ONE */
-};
-
-#define NIC_RSS_INDIR_SIZE 256
-#define NIC_RSS_KEY_SIZE 40
-
-/* *
- * Definition of the NIC receiving mode
- */
-#define NIC_RX_MODE_UC 0x01
-#define NIC_RX_MODE_MC 0x02
-#define NIC_RX_MODE_BC 0x04
-#define NIC_RX_MODE_MC_ALL 0x08
-#define NIC_RX_MODE_PROMISC 0x10
-
-/* IEEE 802.1Qaz std */
-#define NIC_DCB_COS_MAX 0x8
-#define NIC_DCB_UP_MAX 0x8
-#define NIC_DCB_TC_MAX 0x8
-#define NIC_DCB_PG_MAX 0x8
-#define NIC_DCB_TSA_SP 0x0
-#define NIC_DCB_TSA_CBS 0x1 /* hi1822 do NOT support */
-#define NIC_DCB_TSA_ETS 0x2
-#define NIC_DCB_DSCP_NUM 0x8
-#define NIC_DCB_IP_PRI_MAX 0x40
-
-#define NIC_DCB_PRIO_DWRR 0x0
-#define NIC_DCB_PRIO_STRICT 0x1
-
-#define NIC_DCB_MAX_PFC_NUM 0x4
-#endif
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
new file mode 100644
index 0000000..8e0fa89
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd.h
@@ -0,0 +1,174 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
+ * File Name : nic_mpu_cmd.h
+ * Version : Initial Draft
+ * Created : 2019/4/25
+ * Last Modified :
+ * Description : NIC Commands between Driver and MPU
+ * Function List :
+ */
+
+#ifndef NIC_MPU_CMD_H
+#define NIC_MPU_CMD_H
+
+/* Commands between NIC to MPU
+ */
+enum hinic3_nic_cmd {
+ HINIC3_NIC_CMD_VF_REGISTER = 0, /* only for PFD and VFD */
+
+ /* FUNC CFG */
+ HINIC3_NIC_CMD_SET_FUNC_TBL = 5,
+ HINIC3_NIC_CMD_SET_VPORT_ENABLE,
+ HINIC3_NIC_CMD_SET_RX_MODE,
+ HINIC3_NIC_CMD_SQ_CI_ATTR_SET,
+ HINIC3_NIC_CMD_GET_VPORT_STAT,
+ HINIC3_NIC_CMD_CLEAN_VPORT_STAT,
+ HINIC3_NIC_CMD_CLEAR_QP_RESOURCE,
+ HINIC3_NIC_CMD_CFG_FLEX_QUEUE,
+ /* LRO CFG */
+ HINIC3_NIC_CMD_CFG_RX_LRO,
+ HINIC3_NIC_CMD_CFG_LRO_TIMER,
+ HINIC3_NIC_CMD_FEATURE_NEGO,
+ HINIC3_NIC_CMD_CFG_LOCAL_LRO_STATE,
+
+ HINIC3_NIC_CMD_CACHE_OUT_QP_RES,
+ HINIC3_NIC_CMD_SET_FUNC_ER_FWD_ID,
+
+ /** MAC & VLAN CFG & VXLAN CFG */
+ HINIC3_NIC_CMD_GET_MAC = 20,
+ HINIC3_NIC_CMD_SET_MAC,
+ HINIC3_NIC_CMD_DEL_MAC,
+ HINIC3_NIC_CMD_UPDATE_MAC,
+ HINIC3_NIC_CMD_GET_ALL_DEFAULT_MAC,
+
+ HINIC3_NIC_CMD_CFG_FUNC_VLAN,
+ HINIC3_NIC_CMD_SET_VLAN_FILTER_EN,
+ HINIC3_NIC_CMD_SET_RX_VLAN_OFFLOAD,
+ HINIC3_NIC_CMD_SMAC_CHECK_STATE,
+ HINIC3_NIC_CMD_OUTBAND_SET_FUNC_VLAN,
+
+ HINIC3_NIC_CMD_CFG_VXLAN_PORT,
+ HINIC3_NIC_CMD_RX_RATE_CFG,
+ HINIC3_NIC_CMD_WR_ORDERING_CFG,
+
+ /* SR-IOV */
+ HINIC3_NIC_CMD_CFG_VF_VLAN = 40,
+ HINIC3_NIC_CMD_SET_SPOOPCHK_STATE,
+ /* RATE LIMIT */
+ HINIC3_NIC_CMD_SET_MAX_MIN_RATE,
+
+ /* RSS CFG */
+ HINIC3_NIC_CMD_RSS_CFG = 60,
+ HINIC3_NIC_CMD_RSS_TEMP_MGR, /* TODO: delete after implement nego cmd */
+ HINIC3_NIC_CMD_GET_RSS_CTX_TBL, /* TODO: delete: move to ucode cmd */
+ HINIC3_NIC_CMD_CFG_RSS_HASH_KEY,
+ HINIC3_NIC_CMD_CFG_RSS_HASH_ENGINE,
+ HINIC3_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC,
+ /* IP checksum error packets, enable rss quadruple hash */
+ HINIC3_NIC_CMD_IPCS_ERR_RSS_ENABLE_OP = 66,
+ HINIC3_NIC_CMD_GTP_INNER_PARSE_STATUS,
+
+ /* PPA/FDIR */
+ HINIC3_NIC_CMD_ADD_TC_FLOW = 80,
+ HINIC3_NIC_CMD_DEL_TC_FLOW,
+ HINIC3_NIC_CMD_GET_TC_FLOW,
+ HINIC3_NIC_CMD_FLUSH_TCAM,
+ HINIC3_NIC_CMD_CFG_TCAM_BLOCK,
+ HINIC3_NIC_CMD_ENABLE_TCAM,
+ HINIC3_NIC_CMD_GET_TCAM_BLOCK,
+ HINIC3_NIC_CMD_CFG_PPA_TABLE_ID,
+ HINIC3_NIC_CMD_SET_PPA_EN = 88,
+ HINIC3_NIC_CMD_CFG_PPA_MODE,
+ HINIC3_NIC_CMD_CFG_PPA_FLUSH,
+ HINIC3_NIC_CMD_SET_FDIR_STATUS,
+ HINIC3_NIC_CMD_GET_PPA_COUNTER,
+ HINIC3_NIC_CMD_SET_FUNC_FLOW_BIFUR_ENABLE,
+ HINIC3_NIC_CMD_SET_BOND_MASK,
+ HINIC3_NIC_CMD_GET_BLOCK_TC_FLOWS,
+ HINIC3_NIC_CMD_GET_BOND_MASK,
+
+ /* PORT CFG */
+ HINIC3_NIC_CMD_SET_PORT_ENABLE = 100,
+ HINIC3_NIC_CMD_CFG_PAUSE_INFO,
+
+ HINIC3_NIC_CMD_SET_PORT_CAR,
+ HINIC3_NIC_CMD_SET_ER_DROP_PKT,
+
+ HINIC3_NIC_CMD_VF_COS,
+ HINIC3_NIC_CMD_SETUP_COS_MAPPING,
+ HINIC3_NIC_CMD_SET_ETS,
+ HINIC3_NIC_CMD_SET_PFC,
+ HINIC3_NIC_CMD_QOS_ETS,
+ HINIC3_NIC_CMD_QOS_PFC,
+ HINIC3_NIC_CMD_QOS_DCB_STATE,
+ HINIC3_NIC_CMD_QOS_PORT_CFG,
+ HINIC3_NIC_CMD_QOS_MAP_CFG,
+ HINIC3_NIC_CMD_FORCE_PKT_DROP,
+ HINIC3_NIC_CMD_CFG_TX_PROMISC_SKIP = 114,
+ HINIC3_NIC_CMD_SET_PORT_FLOW_BIFUR_ENABLE = 117,
+ HINIC3_NIC_CMD_TX_PAUSE_EXCP_NOTICE = 118,
+ HINIC3_NIC_CMD_INQUIRT_PAUSE_CFG = 119,
+
+ /* MISC */
+ HINIC3_NIC_CMD_BIOS_CFG = 120,
+ HINIC3_NIC_CMD_SET_FIRMWARE_CUSTOM_PACKETS_MSG,
+
+ /* BOND */
+ HINIC3_NIC_CMD_BOND_DEV_CREATE = 134,
+ HINIC3_NIC_CMD_BOND_DEV_DELETE,
+ HINIC3_NIC_CMD_BOND_DEV_OPEN_CLOSE,
+ HINIC3_NIC_CMD_BOND_INFO_GET,
+ HINIC3_NIC_CMD_BOND_ACTIVE_INFO_GET,
+ HINIC3_NIC_CMD_BOND_ACTIVE_NOTICE,
+
+ /* DFX */
+ HINIC3_NIC_CMD_GET_SM_TABLE = 140,
+ HINIC3_NIC_CMD_RD_LINE_TBL,
+
+ HINIC3_NIC_CMD_SET_UCAPTURE_OPT = 160, /* TODO: move to roce */
+ HINIC3_NIC_CMD_SET_VHD_CFG,
+
+ /* OUT OF BAND */
+ HINIC3_NIC_CMD_GET_OUTBAND_CFG = 170,
+ HINIC3_NIC_CMD_OUTBAND_CFG_NOTICE,
+
+ /* TODO: move to HILINK */
+ HINIC3_NIC_CMD_GET_PORT_STAT = 200,
+ HINIC3_NIC_CMD_CLEAN_PORT_STAT,
+ HINIC3_NIC_CMD_CFG_LOOPBACK_MODE,
+ HINIC3_NIC_CMD_GET_SFP_QSFP_INFO,
+ HINIC3_NIC_CMD_SET_SFP_STATUS,
+ HINIC3_NIC_CMD_GET_LIGHT_MODULE_ABS,
+ HINIC3_NIC_CMD_GET_LINK_INFO,
+ HINIC3_NIC_CMD_CFG_AN_TYPE,
+ HINIC3_NIC_CMD_GET_PORT_INFO,
+ HINIC3_NIC_CMD_SET_LINK_SETTINGS,
+ HINIC3_NIC_CMD_ACTIVATE_BIOS_LINK_CFG,
+ HINIC3_NIC_CMD_RESTORE_LINK_CFG,
+ HINIC3_NIC_CMD_SET_LINK_FOLLOW,
+ HINIC3_NIC_CMD_GET_LINK_STATE,
+ HINIC3_NIC_CMD_LINK_STATUS_REPORT,
+ HINIC3_NIC_CMD_CABLE_PLUG_EVENT,
+ HINIC3_NIC_CMD_LINK_ERR_EVENT,
+ HINIC3_NIC_CMD_SET_LED_STATUS,
+
+ /* mig */
+ HINIC3_NIC_CMD_MIG_SET_CEQ_CTRL = 230,
+ HINIC3_NIC_CMD_MIG_CFG_MSIX_INFO,
+ HINIC3_NIC_CMD_MIG_CFG_FUNC_VAT_TBL,
+ HINIC3_NIC_CMD_MIG_GET_VF_INFO,
+ HINIC3_NIC_CMD_MIG_CHK_MBX_EMPTY,
+ HINIC3_NIC_CMD_MIG_SET_VPORT_ENABLE,
+ HINIC3_NIC_CMD_MIG_CFG_SQ_CI,
+ HINIC3_NIC_CMD_MIG_CFG_RSS_TBL,
+ HINIC3_NIC_CMD_MIG_CFG_MAC_TBL,
+ HINIC3_NIC_CMD_MIG_TMP_SET_CMDQ_CTX,
+
+ HINIC3_OSHR_CMD_ACTIVE_FUNCTION = 240,
+ HINIC3_NIC_CMD_GET_RQ_INFO = 241,
+
+ HINIC3_NIC_CMD_MAX = 256,
+};
+
+#endif /* NIC_MPU_CMD_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
new file mode 100644
index 0000000..ee6bf20
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_mpu_cmd_defs.h
@@ -0,0 +1,1420 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2024 Huawei Technologies Co., Ltd */
+
+#ifndef NIC_MPU_CMD_DEFS_H
+#define NIC_MPU_CMD_DEFS_H
+
+#include "nic_cfg_comm.h"
+#include "mpu_cmd_base_defs.h"
+
+#ifndef ETH_ALEN
+#define ETH_ALEN 6
+#endif
+
+#define HINIC3_CMD_OP_SET 1
+#define HINIC3_CMD_OP_GET 0
+
+#define HINIC3_CMD_OP_ADD 1
+#define HINIC3_CMD_OP_DEL 0
+
+#define NIC_TCAM_BLOCK_LARGE_NUM 256
+#define NIC_TCAM_BLOCK_LARGE_SIZE 16
+
+#define TRAFFIC_BIFUR_MODEL_TYPE 2
+
+#define NIC_TCAM_FLOW_BIFUR_FLAG (1 << 0)
+
+#ifndef BIT
+#define BIT(n) (1UL << (n))
+#endif
+
+enum nic_feature_cap {
+ NIC_F_CSUM = BIT(0),
+ NIC_F_SCTP_CRC = BIT(1),
+ NIC_F_TSO = BIT(2),
+ NIC_F_LRO = BIT(3),
+ NIC_F_UFO = BIT(4),
+ NIC_F_RSS = BIT(5),
+ NIC_F_RX_VLAN_FILTER = BIT(6),
+ NIC_F_RX_VLAN_STRIP = BIT(7),
+ NIC_F_TX_VLAN_INSERT = BIT(8),
+ NIC_F_VXLAN_OFFLOAD = BIT(9),
+ NIC_F_IPSEC_OFFLOAD = BIT(10),
+ NIC_F_FDIR = BIT(11),
+ NIC_F_PROMISC = BIT(12),
+ NIC_F_ALLMULTI = BIT(13),
+ NIC_F_XSFP_REPORT = BIT(14),
+ NIC_F_VF_MAC = BIT(15),
+ NIC_F_RATE_LIMIT = BIT(16),
+ NIC_F_RXQ_RECOVERY = BIT(17),
+};
+
+#define NIC_F_ALL_MASK 0x3FFFF /* 使能所有属性 */
+
+struct hinic3_mgmt_msg_head {
+ u8 status;
+ u8 version;
+ u8 rsvd0[6];
+};
+
+#define NIC_MAX_FEATURE_QWORD 4
+struct hinic3_cmd_feature_nego {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 1: set, 0: get */
+ u8 rsvd;
+ u64 s_feature[NIC_MAX_FEATURE_QWORD];
+};
+
+struct hinic3_port_mac_set {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 rsvd1;
+ u8 mac[ETH_ALEN];
+};
+
+struct hinic3_port_mac_update {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 vlan_id;
+ u16 rsvd1;
+ u8 old_mac[ETH_ALEN];
+ u16 rsvd2;
+ u8 new_mac[ETH_ALEN];
+};
+
+struct hinic3_vport_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 state; /* 0--disable, 1--enable */
+ u8 rsvd2[3];
+};
+
+struct hinic3_port_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 state; /* 0--disable, 1--enable */
+ u8 rsvd2[3];
+};
+
+#define HINIC3_SET_PORT_CAR_PROFILE 0
+#define HINIC3_SET_PORT_CAR_STATE 1
+#define HINIC3_GET_PORT_CAR_LIMIT_SPEED 2
+
+struct hinic3_port_car_info {
+ u32 cir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
+ u32 xir; /* unit: kbps, range:[1,400*1000*1000], i.e. 1Kbps~400Gbps(400M*kbps) */
+ u32 cbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
+ u32 xbs; /* unit: Byte, range:[1,320*1000*1000], i.e. 1byte~2560Mbit */
+};
+
+struct hinic3_cmd_set_port_car {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode; /* 0--set car profile, 1--set car state */
+ u8 state; /* 0--disable, 1--enable */
+ u8 level;
+
+ struct hinic3_port_car_info car;
+};
+
+struct hinic3_cmd_clear_qp_resource {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_cmd_cache_out_qp_resource {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_port_stats_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_vport_stats {
+ u64 tx_unicast_pkts_vport;
+ u64 tx_unicast_bytes_vport;
+ u64 tx_multicast_pkts_vport;
+ u64 tx_multicast_bytes_vport;
+ u64 tx_broadcast_pkts_vport;
+ u64 tx_broadcast_bytes_vport;
+
+ u64 rx_unicast_pkts_vport;
+ u64 rx_unicast_bytes_vport;
+ u64 rx_multicast_pkts_vport;
+ u64 rx_multicast_bytes_vport;
+ u64 rx_broadcast_pkts_vport;
+ u64 rx_broadcast_bytes_vport;
+
+ u64 tx_discard_vport;
+ u64 rx_discard_vport;
+ u64 tx_err_vport;
+ u64 rx_err_vport;
+};
+
+struct hinic3_phy_fpga_port_stats {
+ u64 mac_rx_total_octs_port;
+ u64 mac_tx_total_octs_port;
+ u64 mac_rx_under_frame_pkts_port;
+ u64 mac_rx_frag_pkts_port;
+ u64 mac_rx_64_oct_pkts_port;
+ u64 mac_rx_127_oct_pkts_port;
+ u64 mac_rx_255_oct_pkts_port;
+ u64 mac_rx_511_oct_pkts_port;
+ u64 mac_rx_1023_oct_pkts_port;
+ u64 mac_rx_max_oct_pkts_port;
+ u64 mac_rx_over_oct_pkts_port;
+ u64 mac_tx_64_oct_pkts_port;
+ u64 mac_tx_127_oct_pkts_port;
+ u64 mac_tx_255_oct_pkts_port;
+ u64 mac_tx_511_oct_pkts_port;
+ u64 mac_tx_1023_oct_pkts_port;
+ u64 mac_tx_max_oct_pkts_port;
+ u64 mac_tx_over_oct_pkts_port;
+ u64 mac_rx_good_pkts_port;
+ u64 mac_rx_crc_error_pkts_port;
+ u64 mac_rx_broadcast_ok_port;
+ u64 mac_rx_multicast_ok_port;
+ u64 mac_rx_mac_frame_ok_port;
+ u64 mac_rx_length_err_pkts_port;
+ u64 mac_rx_vlan_pkts_port;
+ u64 mac_rx_pause_pkts_port;
+ u64 mac_rx_unknown_mac_frame_port;
+ u64 mac_tx_good_pkts_port;
+ u64 mac_tx_broadcast_ok_port;
+ u64 mac_tx_multicast_ok_port;
+ u64 mac_tx_underrun_pkts_port;
+ u64 mac_tx_mac_frame_ok_port;
+ u64 mac_tx_vlan_pkts_port;
+ u64 mac_tx_pause_pkts_port;
+};
+
+struct hinic3_port_stats {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ struct hinic3_phy_fpga_port_stats stats;
+};
+
+struct hinic3_cmd_vport_stats {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u32 stats_size;
+ u32 rsvd1;
+ struct hinic3_vport_stats stats;
+ u64 rsvd2[6];
+};
+
+struct hinic3_cmd_qpn {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 base_qpn;
+};
+
+enum hinic3_func_tbl_cfg_bitmap {
+ FUNC_CFG_INIT,
+ FUNC_CFG_RX_BUF_SIZE,
+ FUNC_CFG_MTU,
+};
+
+struct hinic3_func_tbl_cfg {
+ u16 rx_wqe_buf_size;
+ u16 mtu;
+ u32 rsvd[9];
+};
+
+struct hinic3_cmd_set_func_tbl {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd;
+
+ u32 cfg_bitmap;
+ struct hinic3_func_tbl_cfg tbl_cfg;
+};
+
+struct hinic3_cmd_cons_idx_attr {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_idx;
+ u8 dma_attr_off;
+ u8 pending_limit;
+ u8 coalescing_time;
+ u8 intr_en;
+ u16 intr_idx;
+ u32 l2nic_sqn;
+ u32 rsvd;
+ u64 ci_addr;
+};
+
+union sm_tbl_args {
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } mac_table_arg;
+ struct {
+ u32 er_id;
+ u32 vlan_id;
+ } vlan_elb_table_arg;
+ struct {
+ u32 func_id;
+ } vlan_filter_arg;
+ struct {
+ u32 mc_id;
+ } mc_elb_arg;
+ struct {
+ u32 func_id;
+ } func_tbl_arg;
+ struct {
+ u32 port_id;
+ } port_tbl_arg;
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } fdir_io_table_arg;
+ struct {
+ u32 tbl_index;
+ u32 cnt;
+ u32 total_cnt;
+ } flexq_table_arg;
+ u32 args[4];
+};
+
+#define DFX_SM_TBL_BUF_MAX (768)
+
+struct nic_cmd_dfx_sm_table {
+ struct hinic3_mgmt_msg_head msg_head;
+ u32 tbl_type;
+ union sm_tbl_args args;
+ u8 tbl_buf[DFX_SM_TBL_BUF_MAX];
+};
+
+struct hinic3_cmd_vlan_offload {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 vlan_offload;
+ u8 rsvd1[5];
+};
+
+/* ucode capture cfg info */
+struct nic_cmd_capture_info {
+ struct hinic3_mgmt_msg_head msg_head;
+ u32 op_type;
+ u32 func_port;
+ u32 is_en_trx;
+ u32 offset_cos;
+ u32 data_vlan;
+};
+
+struct hinic3_cmd_lro_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u8 lro_ipv4_en;
+ u8 lro_ipv6_en;
+ u8 lro_max_pkt_len; /* unit is 1K */
+ u8 resv2[13];
+};
+
+struct hinic3_cmd_lro_timer {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 opcode; /* 1: set timer value, 0: get timer value */
+ u8 rsvd1;
+ u16 rsvd2;
+ u32 timer;
+};
+
+struct hinic3_cmd_local_lro_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 state; /* 0: disable, 1: enable */
+};
+
+struct hinic3_cmd_gtp_inner_parse_status {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 0: get state, 1: set state */
+ u8 status; /* 0: disable, 1: enable */
+};
+
+struct hinic3_cmd_vf_vlan_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u16 vlan_id;
+ u8 qos;
+ u8 rsvd2[5];
+};
+
+struct hinic3_cmd_spoofchk_set {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 state;
+ u8 rsvd1;
+};
+
+struct hinic3_cmd_tx_rate_cfg {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 rsvd1;
+ u8 direct;
+ u32 min_rate;
+ u32 max_rate;
+ u8 rsvd2[8];
+};
+
+struct hinic3_cmd_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+ u8 port_type;
+ u8 autoneg_cap;
+ u8 autoneg_state;
+ u8 duplex;
+ u8 speed;
+ u8 fec;
+ u16 rsvd2;
+ u32 rsvd3[4];
+};
+
+struct hinic3_cmd_register_vf {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 op_register; /* 0 - unregister, 1 - register */
+ u8 rsvd1[3];
+ u32 support_extra_feature;
+ u8 rsvd2[32];
+};
+
+struct hinic3_cmd_link_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 state;
+ u16 rsvd1;
+};
+
+struct hinic3_cmd_vlan_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 outband_defvid_flag;
+ u16 vlan_id;
+ u8 blacklist_flag;
+ u8 rsvd2;
+};
+
+#define VLAN_BLACKLIST_ENABLE 1
+#define VLAN_BLACKLIST_DISABLE 0
+
+struct hinic3_cmd_vxlan_port_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 cfg_mode;
+ u16 vxlan_port;
+ u16 rsvd2;
+};
+
+/* set vlan filter */
+struct hinic3_cmd_set_vlan_filter {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 resvd[2];
+ u32 vlan_filter_ctrl; /* bit0:vlan filter en; bit1:broadcast_filter_en */
+};
+
+struct hinic3_cmd_link_ksettings_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+
+ u32 valid_bitmap;
+ u8 speed; /* enum nic_speed_level */
+ u8 autoneg; /* 0 - off, 1 - on */
+ u8 fec; /* 0 - RSFEC, 1 - BASEFEC, 2 - NOFEC */
+ u8 rsvd2[21]; /* reserved for duplex, port, etc. */
+};
+
+struct mpu_lt_info {
+ u8 node;
+ u8 inst;
+ u8 entry_size;
+ u8 rsvd;
+ u32 lt_index;
+ u32 offset;
+ u32 len;
+};
+
+struct nic_mpu_lt_opera {
+ struct hinic3_mgmt_msg_head msg_head;
+ struct mpu_lt_info net_lt_cmd;
+ u8 data[100];
+};
+
+struct hinic3_force_pkt_drop {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port;
+ u8 rsvd1[3];
+};
+
+struct hinic3_rx_mode_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u32 rx_mode;
+};
+
+/* rss */
+struct hinic3_rss_context_table {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u32 context;
+};
+
+struct hinic3_cmd_rss_engine_type {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 hash_engine;
+ u8 rsvd1[4];
+};
+
+struct hinic3_cmd_rss_hash_key {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode;
+ u8 rsvd1;
+ u8 key[NIC_RSS_KEY_SIZE];
+};
+
+struct hinic3_rss_indir_table {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 indir[NIC_RSS_INDIR_SIZE];
+};
+
+#define NIC_RSS_CMD_TEMP_ALLOC 0x01
+#define NIC_RSS_CMD_TEMP_FREE 0x02
+
+struct hinic3_rss_template_mgmt {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 cmd;
+ u8 template_id;
+ u8 rsvd1[4];
+};
+
+struct hinic3_cmd_rss_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 rss_en;
+ u8 rq_priority_number;
+ u8 prio_tc[NIC_DCB_COS_MAX];
+ u16 num_qps;
+ u16 rsvd1;
+};
+
+struct hinic3_dcb_state {
+ u8 dcb_on;
+ u8 default_cos;
+ u8 trust;
+ u8 rsvd1;
+ u8 pcp2cos[NIC_DCB_UP_MAX];
+ u8 dscp2cos[64];
+ u32 rsvd2[7];
+};
+
+struct hinic3_cmd_vf_dcb_state {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ struct hinic3_dcb_state state;
+};
+
+struct hinic3_up_ets_cfg { /* delet */
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 rsvd1[3];
+
+ u8 cos_tc[NIC_DCB_COS_MAX];
+ u8 tc_bw[NIC_DCB_TC_MAX];
+ u8 cos_prio[NIC_DCB_COS_MAX];
+ u8 cos_bw[NIC_DCB_COS_MAX];
+ u8 tc_prio[NIC_DCB_TC_MAX];
+};
+
+#define CMD_QOS_ETS_COS_TC BIT(0)
+#define CMD_QOS_ETS_TC_BW BIT(1)
+#define CMD_QOS_ETS_COS_PRIO BIT(2)
+#define CMD_QOS_ETS_COS_BW BIT(3)
+#define CMD_QOS_ETS_TC_PRIO BIT(4)
+#define CMD_QOS_ETS_TC_RATELIMIT BIT(5)
+
+struct hinic3_cmd_ets_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 1 - set, 0 - get */
+ /* bit0 - cos_tc, bit1 - tc_bw, bit2 - cos_prio, bit3 - cos_bw, bit4 - tc_prio */
+ u8 cfg_bitmap;
+ u8 rsvd;
+
+ u8 cos_tc[NIC_DCB_COS_MAX];
+ u8 tc_bw[NIC_DCB_TC_MAX];
+ u8 cos_prio[NIC_DCB_COS_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 cos_bw[NIC_DCB_COS_MAX];
+ u8 tc_prio[NIC_DCB_TC_MAX]; /* 0 - DWRR, 1 - STRICT */
+ u8 rate_limit[NIC_DCB_TC_MAX];
+};
+
+struct hinic3_cmd_set_dcb_state {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 op_code; /* 0 - get dcb state, 1 - set dcb state */
+ u8 state; /* 0 - disable, 1 - enable dcb */
+ u8 port_state; /* 0 - disable, 1 - enable dcb */
+ u8 rsvd[7];
+};
+
+#define PFC_BIT_MAP_NUM 8
+struct hinic3_cmd_set_pfc {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 0:get 1: set pfc_en 2: set pfc_bitmap 3: set all */
+ u8 pfc_en; /* pfc_en 和 pfc_bitmap 必须同时设置 */
+ u8 pfc_bitmap;
+ u8 rsvd[4];
+};
+
+#define CMD_QOS_PORT_TRUST BIT(0)
+#define CMD_QOS_PORT_DFT_COS BIT(1)
+struct hinic3_cmd_qos_port_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 port_id;
+ u8 op_code; /* 0 - get, 1 - set */
+ u8 cfg_bitmap; /* bit0 - trust, bit1 - dft_cos */
+ u8 rsvd0;
+
+ u8 trust;
+ u8 dft_cos;
+ u8 rsvd1[18];
+};
+
+#define MAP_COS_MAX_NUM 8
+#define CMD_QOS_MAP_PCP2COS BIT(0)
+#define CMD_QOS_MAP_DSCP2COS BIT(1)
+struct hinic3_cmd_qos_map_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 op_code;
+ u8 cfg_bitmap; /* bit0 - pcp2cos, bit1 - dscp2cos */
+ u16 rsvd0;
+
+ u8 pcp2cos[8]; /* 8 must be configured together */
+ /* If the dscp2cos parameter is set to 0xFF, the MPU ignores the DSCP priority,
+ * Multiple mappings between DSCP values and CoS values can be configured at a time.
+ */
+ u8 dscp2cos[64];
+ u32 rsvd1[4];
+};
+
+struct hinic3_cos_up_map {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 cos_valid_mask; /* every bit indicate index of map is valid 1 or not 0 */
+ u16 rsvd1;
+
+ /* user priority in cos(index:cos, value: up pri) */
+ u8 map[NIC_DCB_UP_MAX];
+};
+
+struct hinic3_cmd_pause_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode;
+ u16 rsvd1;
+ u8 auto_neg;
+ u8 rx_pause;
+ u8 tx_pause;
+ u8 rsvd2[5];
+};
+
+struct nic_cmd_pause_inquiry_cfg {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 valid;
+
+ u32 type; /* 1: set, 2: get */
+
+ u32 cos_id;
+
+ u32 rx_inquiry_pause_drop_pkts_en;
+ u32 rx_inquiry_pause_period_ms;
+ u32 rx_inquiry_pause_times;
+ /* rx pause Detection Threshold, Default PAUSE_FRAME_THD_10G/25G/40G/100 */
+ u32 rx_inquiry_pause_frame_thd;
+ u32 rx_inquiry_tx_total_pkts;
+
+ u32 tx_inquiry_pause_en; /* tx pause detect enable */
+ u32 tx_inquiry_pause_period_ms; /* tx pause Default Detection Period 200ms */
+ u32 tx_inquiry_pause_times; /* tx pause Default Times Period 5 */
+ u32 tx_inquiry_pause_frame_thd; /* tx pause Detection Threshold */
+ u32 tx_inquiry_rx_total_pkts;
+ u32 rsvd[3];
+};
+
+/* pfc/pause Storm TX exception reporting */
+struct nic_cmd_tx_pause_notice {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 tx_pause_except; /* 1: abnormality,0: normal */
+ u32 except_level;
+ u32 rsvd;
+};
+
+#define HINIC3_CMD_OP_FREE 0
+#define HINIC3_CMD_OP_ALLOC 1
+
+struct hinic3_cmd_cfg_qps {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 opcode; /* 1: alloc qp, 0: free qp */
+ u8 rsvd1;
+ u16 num_qps;
+ u16 rsvd2;
+};
+
+struct hinic3_cmd_led_config {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port;
+ u8 type;
+ u8 mode;
+ u8 rsvd1;
+};
+
+struct hinic3_cmd_port_loopback {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 opcode;
+ u8 mode;
+ u8 en;
+ u32 rsvd1[2];
+};
+
+struct hinic3_cmd_get_light_module_abs {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 abs_status; /* 0:present, 1:absent */
+ u8 rsv[2];
+};
+
+#define STD_SFP_INFO_MAX_SIZE 640
+struct hinic3_cmd_get_std_sfp_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u8 port_id;
+ u8 wire_type;
+ u16 eeprom_len;
+ u32 rsvd;
+ u8 sfp_info[STD_SFP_INFO_MAX_SIZE];
+};
+
+struct hinic3_cable_plug_event {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 plugged; /* 0: unplugged, 1: plugged */
+ u8 port_id;
+};
+
+struct nic_cmd_mac_info {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 valid_bitmap;
+ u16 rsvd;
+
+ u8 host_id[32];
+ u8 port_id[32];
+ u8 mac_addr[192];
+};
+
+struct nic_cmd_set_tcam_enable {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 tcam_enable;
+ u8 rsvd1;
+ u32 rsvd2;
+};
+
+struct nic_cmd_set_fdir_status {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u16 rsvd1;
+ u8 pkt_type_en;
+ u8 pkt_type;
+ u8 qid;
+ u8 rsvd2;
+};
+
+#define HINIC3_TCAM_BLOCK_ENABLE 1
+#define HINIC3_TCAM_BLOCK_DISABLE 0
+#define HINIC3_MAX_TCAM_RULES_NUM 4096
+
+/* tcam block type, according to tcam block size */
+enum {
+ NIC_TCAM_BLOCK_TYPE_LARGE = 0, /* block_size: 16 */
+ NIC_TCAM_BLOCK_TYPE_SMALL, /* block_size: 0 */
+ NIC_TCAM_BLOCK_TYPE_MAX
+};
+
+/* alloc tcam block input struct */
+struct nic_cmd_ctrl_tcam_block_in {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
+ /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
+ u8 tcam_type;
+ u16 tcam_block_index;
+ /* Size of the block that the driver wants to allocate
+ * Interface returned by the UP to the driver,
+ * indicating the size of the allocated TCAM block supported by the UP
+ */
+ u16 alloc_block_num;
+};
+
+/* alloc tcam block output struct */
+struct nic_cmd_ctrl_tcam_block_out {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u8 alloc_en; /* 0: Releases the allocated TCAM block. 1: Applies for a new TCAM block */
+ /* 0: 16 size tcam block, 1: 0 size tcam block, other reserved. */
+ u8 tcam_type;
+ u16 tcam_block_index;
+ /* Size of the block that the driver wants to allocate
+ * Interface returned by the UP to the driver,
+ * indicating the size of the allocated TCAM block supported by the UP
+ */
+ u16 mpu_alloc_block_size;
+};
+
+struct nic_cmd_flush_tcam_rules {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id; /* func_id */
+ u16 rsvd;
+};
+
+struct nic_cmd_dfx_fdir_tcam_block_table {
+ struct hinic3_mgmt_msg_head head;
+ u8 tcam_type;
+ u8 valid;
+ u16 tcam_block_index;
+ u16 use_function_id;
+ u16 rsvd;
+};
+
+struct tcam_result {
+ u32 qid;
+ u32 rsvd;
+};
+
+#define TCAM_FLOW_KEY_SIZE (44)
+
+struct tcam_key_x_y {
+ u8 x[TCAM_FLOW_KEY_SIZE];
+ u8 y[TCAM_FLOW_KEY_SIZE];
+};
+
+struct nic_tcam_cfg_rule {
+ u32 index;
+ struct tcam_result data;
+ struct tcam_key_x_y key;
+};
+
+#define TCAM_RULE_FDIR_TYPE 0
+#define TCAM_RULE_PPA_TYPE 1
+
+struct nic_cmd_fdir_add_rule {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 type;
+ u8 fdir_ext; /* 0x1: flow bifur en bit */
+ struct nic_tcam_cfg_rule rule;
+};
+
+struct nic_cmd_fdir_del_rules {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 type;
+ u8 rsvd;
+ u32 index_start;
+ u32 index_num;
+};
+
+struct nic_cmd_fdir_get_rule {
+ struct hinic3_mgmt_msg_head head;
+
+ u32 index;
+ u8 valid;
+ u8 type;
+ u16 rsvd;
+ struct tcam_key_x_y key;
+ struct tcam_result data;
+ u64 packet_count;
+ u64 byte_count;
+};
+
+struct nic_cmd_fdir_get_block_rules {
+ struct hinic3_mgmt_msg_head head;
+ u8 tcam_block_type; // only NIC_TCAM_BLOCK_TYPE_LARGE
+ u8 tcam_table_type; // TCAM_RULE_PPA_TYPE or TCAM_RULE_FDIR_TYPE
+ u16 tcam_block_index;
+ u8 valid[NIC_TCAM_BLOCK_LARGE_SIZE];
+ struct tcam_key_x_y key[NIC_TCAM_BLOCK_LARGE_SIZE];
+ struct tcam_result data[NIC_TCAM_BLOCK_LARGE_SIZE];
+};
+
+struct hinic3_tcam_key_ipv4_mem {
+ u32 rsvd1 : 1;
+ u32 bifur_flag : 2;
+ u32 model : 1;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+ u32 sipv4_h : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+ u32 dipv4_h : 16;
+ u32 sipv4_l : 16;
+ u32 vlan_id : 15;
+ u32 vlan_flag : 1;
+ u32 dipv4_l : 16;
+ u32 rsvd3;
+ u32 dport : 16;
+ u32 rsvd4 : 16;
+ u32 rsvd5 : 16;
+ u32 sport : 16;
+ u32 outer_sipv4_h : 16;
+ u32 rsvd6 : 16;
+ u32 outer_dipv4_h : 16;
+ u32 outer_sipv4_l : 16;
+ u32 vni_h : 16;
+ u32 outer_dipv4_l : 16;
+ u32 rsvd7 : 16;
+ u32 vni_l : 16;
+};
+
+union hinic3_tag_tcam_ext_info {
+ struct {
+ u32 id : 16; /* id */
+ u32 type : 4; /* type: 0-func, 1-vmdq, 2-port, 3-rsvd, 4-trunk, 5-dp, 6-mc */
+ u32 host_id : 3;
+ u32 rss_q_num : 8; /* rss queue num */
+ u32 ext : 1;
+ } bs;
+ u32 value;
+};
+
+struct hinic3_tcam_key_ipv6_mem {
+ u32 bifur_flag : 2;
+ u32 vlan_flag : 1;
+ u32 outer_ip_type : 1;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+ u32 sipv6_key0 : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+ u32 sipv6_key2 : 16;
+ u32 sipv6_key1 : 16;
+ u32 sipv6_key4 : 16;
+ u32 sipv6_key3 : 16;
+ u32 sipv6_key6 : 16;
+ u32 sipv6_key5 : 16;
+ u32 dport : 16;
+ u32 sipv6_key7 : 16;
+ u32 dipv6_key0 : 16;
+ u32 sport : 16;
+ u32 dipv6_key2 : 16;
+ u32 dipv6_key1 : 16;
+ u32 dipv6_key4 : 16;
+ u32 dipv6_key3 : 16;
+ u32 dipv6_key6 : 16;
+ u32 dipv6_key5 : 16;
+ u32 rsvd2 : 16;
+ u32 dipv6_key7 : 16;
+};
+
+struct hinic3_tcam_key_vxlan_ipv6_mem {
+ u32 rsvd1 : 4;
+ u32 tunnel_type : 4;
+ u32 ip_proto : 8;
+ u32 rsvd0 : 16;
+
+ u32 dipv6_key0 : 16;
+ u32 ip_type : 1;
+ u32 function_id : 15;
+
+ u32 dipv6_key2 : 16;
+ u32 dipv6_key1 : 16;
+
+ u32 dipv6_key4 : 16;
+ u32 dipv6_key3 : 16;
+
+ u32 dipv6_key6 : 16;
+ u32 dipv6_key5 : 16;
+
+ u32 dport : 16;
+ u32 dipv6_key7 : 16;
+
+ u32 rsvd2 : 16;
+ u32 sport : 16;
+
+ u32 outer_sipv4_h : 16;
+ u32 rsvd3 : 16;
+
+ u32 outer_dipv4_h : 16;
+ u32 outer_sipv4_l : 16;
+
+ u32 vni_h : 16;
+ u32 outer_dipv4_l : 16;
+
+ u32 rsvd4 : 16;
+ u32 vni_l : 16;
+};
+
+struct tag_tcam_key {
+ union {
+ struct hinic3_tcam_key_ipv4_mem key_info;
+ struct hinic3_tcam_key_ipv6_mem key_info_ipv6;
+ struct hinic3_tcam_key_vxlan_ipv6_mem key_info_vxlan_ipv6;
+ };
+
+ union {
+ struct hinic3_tcam_key_ipv4_mem key_mask;
+ struct hinic3_tcam_key_ipv6_mem key_mask_ipv6;
+ struct hinic3_tcam_key_vxlan_ipv6_mem key_mask_vxlan_ipv6;
+ };
+};
+
+enum {
+ PPA_TABLE_ID_CLEAN_CMD = 0,
+ PPA_TABLE_ID_ADD_CMD,
+ PPA_TABLE_ID_DEL_CMD,
+ FDIR_TABLE_ID_ADD_CMD,
+ FDIR_TABLE_ID_DEL_CMD,
+ PPA_TABEL_ID_MAX
+};
+
+struct hinic3_ppa_cfg_table_id_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u16 cmd;
+ u16 table_id;
+ u16 rsvd1;
+};
+
+struct hinic3_ppa_cfg_ppa_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 func_id;
+ u8 ppa_en;
+ u8 ppa_miss_drop_en;
+};
+
+struct hinic3_func_flow_bifur_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 func_id;
+ u8 flow_bifur_en;
+ u8 rsvd[5];
+};
+
+struct hinic3_port_flow_bifur_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 port_id;
+ u8 flow_bifur_en;
+ u8 flow_bifur_type; /* 0->vf bifur, 2->traffic bifur */
+ u8 rsvd[4];
+};
+
+struct hinic3_bond_mask_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 func_id;
+ u8 bond_mask;
+ u8 bond_en;
+ u8 func_valid;
+ u8 rsvd[3];
+};
+
+struct hinic3_func_er_value_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+ u16 vf_id;
+ u16 er_fwd_id;
+};
+
+#define HINIC3_TX_SET_PROMISC_SKIP 0
+#define HINIC3_TX_GET_PROMISC_SKIP 1
+
+#define HINIC3_GET_TRAFFIC_BIFUR_STATE 0
+#define HINIC3_SET_TRAFFIC_BIFUR_STATE 1
+
+struct hinic3_tx_promisc_cfg {
+ struct hinic3_mgmt_msg_head msg_head;
+ u8 port_id;
+ u8 promisc_skip_en; /* 0: disable tx promisc replication, 1: enable */
+ u8 opcode; /* 0: set, 1: get */
+ u8 rsvd1;
+};
+
+struct hinic3_ppa_cfg_mode_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u8 ppa_mode;
+ u8 qpc_func_nums;
+ u16 base_qpc_func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_ppa_flush_en_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 rsvd0;
+ u8 flush_en; /* 0 flush done, 1 in flush operation */
+ u8 rsvd1;
+};
+
+struct hinic3_ppa_fdir_query_cmd {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u32 index;
+ u32 rsvd;
+ u64 pkt_nums;
+ u64 pkt_bytes;
+};
+
+/* BIOS CONF */
+enum {
+ NIC_NVM_DATA_SET = BIT(0), /* 1-save, 0-read */
+ NIC_NVM_DATA_PXE = BIT(1),
+ NIC_NVM_DATA_VLAN = BIT(2),
+ NIC_NVM_DATA_VLAN_PRI = BIT(3),
+ NIC_NVM_DATA_VLAN_ID = BIT(4),
+ NIC_NVM_DATA_WORK_MODE = BIT(5),
+ NIC_NVM_DATA_PF_TX_SPEED_LIMIT = BIT(6),
+ NIC_NVM_DATA_GE_MODE = BIT(7),
+ NIC_NVM_DATA_AUTO_NEG = BIT(8),
+ NIC_NVM_DATA_LINK_FEC = BIT(9),
+ NIC_NVM_DATA_PF_ADAPTIVE_LINK = BIT(10),
+ NIC_NVM_DATA_SRIOV_CONTROL = BIT(11),
+ NIC_NVM_DATA_EXTEND_MODE = BIT(12),
+ NIC_NVM_DATA_LEGACY_VLAN = BIT(13),
+ NIC_NVM_DATA_LEGACY_VLAN_PRI = BIT(14),
+ NIC_NVM_DATA_LEGACY_VLAN_ID = BIT(15),
+ NIC_NVM_DATA_RESET = BIT(31),
+};
+
+#define BIOS_CFG_SIGNATURE 0x1923E518
+#define BIOS_OP_CFG_ALL(op_code_val) \
+ ((((op_code_val) >> 1) & (0xFFFFFFFF)) != 0)
+#define BIOS_OP_CFG_WRITE(op_code_val) \
+ ((((op_code_val) & NIC_NVM_DATA_SET)) != 0)
+#define BIOS_OP_CFG_PXE_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PXE) != 0)
+#define BIOS_OP_CFG_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN) != 0)
+#define BIOS_OP_CFG_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_VLAN_ID) != 0)
+#define BIOS_OP_CFG_WORK_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_WORK_MODE) != 0)
+#define BIOS_OP_CFG_PF_BW(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_TX_SPEED_LIMIT) != 0)
+#define BIOS_OP_CFG_GE_SPEED(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_GE_MODE) != 0)
+#define BIOS_OP_CFG_AUTO_NEG(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_AUTO_NEG) != 0)
+#define BIOS_OP_CFG_LINK_FEC(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LINK_FEC) != 0)
+#define BIOS_OP_CFG_AUTO_ADPAT(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_PF_ADAPTIVE_LINK) != 0)
+#define BIOS_OP_CFG_SRIOV_ENABLE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_SRIOV_CONTROL) != 0)
+#define BIOS_OP_CFG_EXTEND_MODE(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_EXTEND_MODE) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_EN(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_PRI(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_PRI) != 0)
+#define BIOS_OP_CFG_LEGACY_VLAN_ID(op_code_val) \
+ (((op_code_val) & NIC_NVM_DATA_LEGACY_VLAN_ID) != 0)
+#define BIOS_OP_CFG_RST_DEF_SET(op_code_val) \
+ (((op_code_val) & (u32)NIC_NVM_DATA_RESET) != 0)
+
+
+#define NIC_BIOS_CFG_MAX_PF_BW 100
+
+struct nic_legacy_vlan_cfg {
+ /* Legacy mode PXE VLAN enable: 0 - disable 1 - enable */
+ u8 pxe_vlan_en : 1;
+ /* Legacy mode PXE VLAN priority: 0-7 */
+ u8 pxe_vlan_pri : 3;
+ /* Legacy mode PXE VLAN ID 1-4094 */
+ u16 pxe_vlan_id : 12;
+};
+
+/* Note: This structure must be 4-byte aligned. */
+struct nic_bios_cfg {
+ u32 signature;
+ u8 pxe_en;
+ u8 extend_mode;
+ struct nic_legacy_vlan_cfg nlvc;
+ u8 pxe_vlan_en;
+ u8 pxe_vlan_pri;
+ u16 pxe_vlan_id;
+ u32 service_mode;
+ u32 pf_tx_bw;
+ u8 speed;
+ u8 auto_neg;
+ u8 lanes;
+ u8 fec;
+ u8 auto_adapt;
+ u8 func_valid;
+ u8 func_id;
+ u8 sriov_en;
+};
+
+struct nic_cmd_bios_cfg {
+ struct hinic3_mgmt_msg_head head;
+ u32 op_code; /* Operation Code: Bit0[0: read 1:write, BIT1-6: cfg_mask */
+ struct nic_bios_cfg bios_cfg;
+};
+
+struct nic_rx_rate_bios_cfg {
+ struct mgmt_msg_head msg_head;
+
+ u32 op_code; /* Operation Code:[0:read 1:write] */
+ u8 rx_rate_limit;
+ u8 func_id;
+};
+
+struct nic_cmd_vhd_config {
+ struct hinic3_mgmt_msg_head head;
+
+ u16 func_id;
+ u8 vhd_type;
+ u8 virtio_small_enable; /* 0: mergeable mode, 1: small mode */
+};
+
+/* BOND */
+struct hinic3_create_bond_info {
+ u32 bond_id;
+ u32 master_slave_port_id;
+ u32 slave_bitmap; /* bond port id bitmap */
+ u32 poll_timeout; /* Bond device link check time */
+ u32 up_delay; /* Temporarily reserved */
+ u32 down_delay; /* Temporarily reserved */
+ u32 bond_mode; /* Temporarily reserved */
+ u32 active_pf; /* bond use active pf id */
+ u32 active_port_max_num; /* Maximum number of active bond member interfaces */
+ u32 active_port_min_num; /* Minimum number of active bond member interfaces */
+ u32 xmit_hash_policy;
+ u32 default_param_flag;
+ u32 rsvd;
+};
+
+struct hinic3_cmd_create_bond {
+ struct hinic3_mgmt_msg_head head;
+ struct hinic3_create_bond_info create_bond_info;
+};
+
+struct hinic3_cmd_delete_bond {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 rsvd[2];
+};
+
+struct hinic3_open_close_bond_info {
+ u32 bond_id;
+ u32 open_close_flag; /* Bond flag. 1: open; 0: close. */
+ u32 rsvd[2];
+};
+
+struct hinic3_cmd_open_close_bond {
+ struct hinic3_mgmt_msg_head head;
+ struct hinic3_open_close_bond_info open_close_bond_info;
+};
+
+struct lacp_port_params {
+ u16 port_number;
+ u16 port_priority;
+ u16 key;
+ u16 system_priority;
+ u8 system[ETH_ALEN];
+ u8 port_state;
+ u8 rsvd;
+};
+
+struct lacp_port_info {
+ u32 selected;
+ u32 aggregator_port_id;
+
+ struct lacp_port_params actor;
+ struct lacp_port_params partner;
+
+ u64 tx_lacp_pkts;
+ u64 rx_lacp_pkts;
+ u64 rx_8023ad_drop;
+ u64 tx_8023ad_drop;
+ u64 unknown_pkt_drop;
+ u64 rx_marker_pkts;
+ u64 tx_marker_pkts;
+};
+
+struct hinic3_bond_status_info {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 bon_mmi_status;
+ u32 active_bitmap;
+ u32 port_count;
+
+ struct lacp_port_info port_info[4];
+
+ u64 success_report_cnt[4];
+ u64 fail_report_cnt[4];
+
+ u64 poll_timeout;
+ u64 fast_periodic_timeout;
+ u64 slow_periodic_timeout;
+ u64 short_timeout;
+ u64 long_timeout;
+ u64 aggregate_wait_timeout;
+ u64 tx_period_timeout;
+ u64 rx_marker_timer;
+};
+
+struct hinic3_bond_active_report_info {
+ struct hinic3_mgmt_msg_head head;
+ u32 bond_id;
+ u32 bon_mmi_status;
+ u32 active_bitmap;
+
+ u8 rsvd[16];
+};
+
+/* IP checksum error packets, enable rss quadruple hash. */
+struct hinic3_ipcs_err_rss_enable_operation_s {
+ struct hinic3_mgmt_msg_head head;
+
+ u8 en_tag;
+ u8 type; /* 1: set 0: get */
+ u8 rsvd[2];
+};
+
+struct hinic3_smac_check_state {
+ struct hinic3_mgmt_msg_head head;
+ u8 smac_check_en; /* 1: enable 0: disable */
+ u8 op_code; /* 1: set 0: get */
+ u8 flash_en; /* 1: enable 0: disable */
+ u8 rsvd;
+};
+
+struct hinic3_clear_log_state {
+ struct hinic3_mgmt_msg_head head;
+ u32 type;
+};
+
+struct hinic3_outband_cfg_info {
+ struct hinic3_mgmt_msg_head msg_head;
+
+ u16 outband_default_vid;
+ u16 func_id;
+};
+
+struct hinic3_wr_ordering {
+ struct hinic3_mgmt_msg_head head;
+ u8 op_code; /* 1: set 0: get */
+ u8 wr_pkt_so_ro;
+ u8 rd_pkt_so_ro;
+ u8 rsvd;
+};
+
+struct hinic3_function_active_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rsvd1;
+};
+
+struct hinic3_rq_info {
+ struct hinic3_mgmt_msg_head head;
+ u16 func_id;
+ u16 rq_depth;
+ u16 rq_num;
+ u16 pf_num;
+ u16 port_num;
+};
+
+#endif /* HINIC_MGMT_INTERFACE_H */
diff --git a/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
new file mode 100644
index 0000000..97eda43
--- /dev/null
+++ b/drivers/net/ethernet/huawei/hinic3/nic_npu_cmd.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
+ * File Name : nic_npu_cmd.h
+ * Version : Initial Draft
+ * Created : 2019/4/25
+ * Last Modified :
+ * Description : NIC Commands between Driver and NPU
+ * Function List :
+ */
+
+#ifndef NIC_NPU_CMD_H
+#define NIC_NPU_CMD_H
+
+/* NIC CMDQ MODE */
+enum hinic3_ucode_cmd {
+ HINIC3_UCODE_CMD_MODIFY_QUEUE_CTX = 0,
+ HINIC3_UCODE_CMD_CLEAN_QUEUE_CONTEXT,
+ HINIC3_UCODE_CMD_ARM_SQ, /**< Unused */
+ HINIC3_UCODE_CMD_ARM_RQ, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
+ HINIC3_UCODE_CMD_GET_RSS_CONTEXT_TABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_IQ_ENABLE, /**< Unused */
+ HINIC3_UCODE_CMD_SET_RQ_FLUSH = 10,
+ HINIC3_UCODE_CMD_MODIFY_VLAN_CTX,
+ HINIC3_UCODE_CMD_PPA_HASH_TABLE,
+ HINIC3_UCODE_CMD_RXQ_INFO_GET = 13,
+ HINIC3_UCODE_MIG_CFG_Q_CTX = 14,
+ HINIC3_UCODE_MIG_CHK_SQ_STOP,
+ HINIC3_UCODE_CHK_RQ_STOP,
+ HINIC3_UCODE_MIG_CFG_BAT_INFO,
+};
+
+#endif /* NIC_NPU_CMD_H */
\ No newline at end of file
diff --git a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
index ee005a8..5f0f790 100644
--- a/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
+++ b/drivers/net/ethernet/huawei/hinic3/ossl_knl_linux.h
@@ -4,8 +4,8 @@
#ifndef OSSL_KNL_LINUX_H_
#define OSSL_KNL_LINUX_H_
-#include <net/checksum.h>
#include <net/ipv6.h>
+#include <net/devlink.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/device.h>
@@ -19,6 +19,12 @@
#include <linux/list.h>
#include <linux/bitmap.h>
#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/filter.h>
+#include <linux/aer.h>
+#include <linux/socket.h>
#ifndef NETIF_F_SCTP_CSUM
#define NETIF_F_SCTP_CSUM 0
@@ -37,6 +43,17 @@
#define ossl_get_free_pages __get_free_pages
+#ifndef ETHTOOL_LINK_MODE_100000baseKR_Full_BIT
+#define ETHTOOL_LINK_MODE_100000baseKR_Full_BIT 75
+#define ETHTOOL_LINK_MODE_100000baseCR_Full_BIT 78
+#define ETHTOOL_LINK_MODE_100000baseSR_Full_BIT 76
+#endif
+#ifndef ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT
+#define ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT 80
+#define ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT 81
+#define ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT 84
+#endif
+
#ifndef high_16_bits
#define low_16_bits(x) ((x) & 0xFFFF)
#define high_16_bits(x) (((x) & 0xFFFF0000) >> 16)
@@ -54,13 +71,11 @@
#endif
#define HAVE_INET6_IFADDR_LIST
-
#define HAVE_NDO_GET_STATS64
#ifndef HAVE_MQPRIO
#define HAVE_MQPRIO
#endif
-
#ifndef HAVE_SETUP_TC
#define HAVE_SETUP_TC
#endif
@@ -68,25 +83,20 @@
#ifndef HAVE_NDO_SET_FEATURES
#define HAVE_NDO_SET_FEATURES
#endif
-
#define HAVE_IRQ_AFFINITY_NOTIFY
-
#define HAVE_ETHTOOL_SET_PHYS_ID
-
#define HAVE_NETDEV_WANTED_FEAUTES
#ifndef HAVE_PCI_DEV_FLAGS_ASSIGNED
#define HAVE_PCI_DEV_FLAGS_ASSIGNED
#define HAVE_VF_SPOOFCHK_CONFIGURE
#endif
-
#ifndef HAVE_SKB_L4_RXHASH
#define HAVE_SKB_L4_RXHASH
#endif
#define HAVE_ETHTOOL_GRXFHINDIR_SIZE
#define HAVE_INT_NDO_VLAN_RX_ADD_VID
-
#ifdef ETHTOOL_SRXNTUPLE
#undef ETHTOOL_SRXNTUPLE
#endif
@@ -95,9 +105,9 @@
#define _kc_kunmap_atomic(addr) kunmap_atomic(addr)
#include <linux/of_net.h>
-
#define HAVE_FDB_OPS
#define HAVE_ETHTOOL_GET_TS_INFO
+
#define HAVE_NAPI_GRO_FLUSH_OLD
#ifndef HAVE_SRIOV_CONFIGURE
@@ -107,6 +117,7 @@
#define HAVE_ENCAP_TSO_OFFLOAD
#define HAVE_SKB_INNER_NETWORK_HEADER
+
#define HAVE_NDO_SET_VF_LINK_STATE
#define HAVE_SKB_INNER_PROTOCOL
#define HAVE_MPLS_FEATURES
@@ -115,12 +126,12 @@
#define HAVE_NETIF_SET_XPS_QUEUE_CONST_MASK
#define HAVE_VXLAN_CHECKS
-#define HAVE_NDO_SELECT_QUEUE_ACCEL
#define HAVE_NET_GET_RANDOM_ONCE
#define HAVE_HWMON_DEVICE_REGISTER_WITH_GROUPS
#define HAVE_NDO_SELECT_QUEUE_ACCEL_FALLBACK
+
#define HAVE_NDO_SET_VF_MIN_MAX_TX_RATE
#define HAVE_VLAN_FIND_DEV_DEEP_RCU
@@ -128,8 +139,8 @@
#define HAVE_MULTI_VLAN_OFFLOAD_EN
#define HAVE_ETH_GET_HEADLEN_FUNC
-#define HAVE_RXFH_HASHFUNC
+#define HAVE_RXFH_HASHFUNC
#define HAVE_NDO_SET_VF_TRUST
#include <net/devlink.h>
@@ -138,6 +149,7 @@
#define HAVE_NETDEVICE_MIN_MAX_MTU
+
#define HAVE_VOID_NDO_GET_STATS64
#define HAVE_VM_OPS_FAULT_NO_VMA
@@ -146,9 +158,13 @@
#define HAVE_PCI_ERROR_HANDLER_RESET_PREPARE
#define HAVE_PTP_CLOCK_DO_AUX_WORK
+
#define HAVE_NDO_SETUP_TC_REMOVE_TC_TO_NETDEV
#define HAVE_XDP_SUPPORT
+#if (KERNEL_VERSION(5, 9, 0) > LINUX_VERSION_CODE)
+#define HAVE_XDP_QUERY_PROG
+#endif
#define HAVE_NDO_BPF_NETDEV_BPF
#define HAVE_TIMER_SETUP
@@ -158,6 +174,7 @@
#define HAVE_NDO_SELECT_QUEUE_SB_DEV
+
#define dev_open(x) dev_open(x, NULL)
#define HAVE_NEW_ETHTOOL_LINK_SETTINGS_ONLY
@@ -180,12 +197,14 @@ static inline void *_hinic3_dma_zalloc_coherent(struct device *dev,
}
#endif
+#if (KERNEL_VERSION(5, 6, 0) <= LINUX_VERSION_CODE)
#ifndef DT_KNL_EMU
struct timeval {
__kernel_old_time_t tv_sec; /* seconds */
__kernel_suseconds_t tv_usec; /* microseconds */
};
#endif
+#endif
#ifndef do_gettimeofday
#define do_gettimeofday(time) _kc_do_gettimeofday(time)
@@ -199,6 +218,8 @@ static inline void _kc_do_gettimeofday(struct timeval *tv)
}
#endif
+
+
#define HAVE_NDO_SELECT_QUEUE_SB_DEV_ONLY
#define ETH_GET_HEADLEN_NEED_DEV
#define HAVE_GENL_OPS_FIELD_VALIDATE
@@ -207,32 +228,75 @@ static inline void _kc_do_gettimeofday(struct timeval *tv)
#define FIELD_SIZEOF(t, f) (sizeof(((t *)0)->f))
#endif
+/*****************************************************************************/
+#if (KERNEL_VERSION(5, 5, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.5.0 */
#define HAVE_DEVLINK_FLASH_UPDATE_PARAMS
+#endif /* 5.5.0 */
+/*****************************************************************************/
+#if (KERNEL_VERSION(5, 6, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.6.0 */
#ifndef rtc_time_to_tm
#define rtc_time_to_tm rtc_time64_to_tm
#endif
#define HAVE_NDO_TX_TIMEOUT_TXQ
#define HAVE_PROC_OPS
+#endif /* 5.6.0 */
+/*****************************************************************************/
+#if (KERNEL_VERSION(5, 7, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.7.0 */
#define SUPPORTED_COALESCE_PARAMS
#ifndef pci_cleanup_aer_uncorrect_error_status
#define pci_cleanup_aer_uncorrect_error_status pci_aer_clear_nonfatal_status
#endif
+#endif /* 5.7.0 */
+
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 9, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.9.0 */
#define HAVE_XDP_FRAME_SZ
+#endif /* 5.9.0 */
+
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE)
+#define HAVE_DEVLINK_FW_FILE_NAME_PARAM
+#else /* >= 5.10.0 */
+#endif /* 5.10.0 */
#define HAVE_DEVLINK_FW_FILE_NAME_MEMBER
-#define HAVE_ENCAPSULATION_TSO
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE)
+#else /* >= 5.10.0 */
+#if !defined(HAVE_ETHTOOL_COALESCE_EXTACK) && \
+ !defined(NO_ETHTOOL_COALESCE_EXTACK)
+#define HAVE_ETHTOOL_COALESCE_EXTACK
+#endif
+#endif /* 5.10.0 */
+
+/* ************************************************************************ */
+#if (KERNEL_VERSION(5, 10, 0) > LINUX_VERSION_CODE)
+
+#else /* >= 5.10.0 */
+#if !defined(HAVE_ETHTOOL_RINGPARAM_EXTACK) && \
+ !defined(NO_ETHTOOL_RINGPARAM_EXTACK)
+#define HAVE_ETHTOOL_RINGPARAM_EXTACK
+#endif
+#endif /* 5.10.0 */
+/* ************************************************************************ */
+#define HAVE_NDO_UDP_TUNNEL_ADD
+#define HAVE_ENCAPSULATION_TSO
#define HAVE_ENCAPSULATION_CSUM
#ifndef eth_zero_addr
static inline void hinic3_eth_zero_addr(u8 *addr)
{
- memset(addr, 0x00, ETH_ALEN);
+ (void)memset(addr, 0x00, ETH_ALEN);
}
#define eth_zero_addr(_addr) hinic3_eth_zero_addr(_addr)
@@ -273,13 +337,10 @@ int creat_thread(struct sdk_thread_info *thread_info);
void stop_thread(struct sdk_thread_info *thread_info);
#define destroy_work(work)
-
void utctime_to_localtime(u64 utctime, u64 *localtime);
-
#ifndef HAVE_TIMER_SETUP
void initialize_timer(const void *adapter_hdl, struct timer_list *timer);
#endif
-
void add_to_timer(struct timer_list *timer, u64 period);
void stop_timer(struct timer_list *timer);
void delete_timer(struct timer_list *timer);
@@ -304,3 +365,4 @@ u64 ossl_get_real_time(void);
#define tasklet_state(tasklet) ((tasklet)->state)
#endif
+/* ************************************************************************ */
--
1.8.3.1
2
3

[openeuler:OLK-5.10] BUILD REGRESSION f5912cbd669a2722f81f0f054fb8aec1525da8ee
by kernel test robot 08 May '25
by kernel test robot 08 May '25
08 May '25
tree/branch: https://gitee.com/openeuler/kernel.git OLK-5.10
branch HEAD: f5912cbd669a2722f81f0f054fb8aec1525da8ee !16057 mailbox: pcc: Always clear the platform ack interrupt first
Error/Warning (recently discovered and may have been fixed):
https://lore.kernel.org/oe-kbuild-all/202504290538.Gt6tWC7N-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202504290828.J8Cynzh6-lkp@intel.com
https://lore.kernel.org/oe-kbuild-all/202505062356.u2rMcCQF-lkp@intel.com
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:24: warning: Excess function parameter 'author' description in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:24: warning: Excess function parameter 'date' description in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:24: warning: Excess function parameter 'file' description in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:24: warning: Function parameter or member 'buf_len' not described in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:24: warning: Function parameter or member 'buff' not described in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxe/base/trace/sxe_trace.c:21: warning: Excess function parameter 'author' description in 'SXE_FILE_NAME_LEN'
drivers/net/ethernet/linkdata/sxe/base/trace/sxe_trace.c:21: warning: Excess function parameter 'date' description in 'SXE_FILE_NAME_LEN'
drivers/net/ethernet/linkdata/sxe/base/trace/sxe_trace.c:21: warning: Excess function parameter 'file' description in 'SXE_FILE_NAME_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:23: warning: Excess function parameter 'author' description in 'sxe_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:23: warning: Excess function parameter 'date' description in 'sxe_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:23: warning: Excess function parameter 'file' description in 'sxe_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:23: warning: Function parameter or member 'protocol' not described in 'sxe_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:23: warning: Function parameter or member 'skb' not described in 'sxe_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb.c:16: warning: Excess function parameter 'author' description in 'SXE_TC_BWG_PERCENT_PER_CHAN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb.c:16: warning: Excess function parameter 'date' description in 'SXE_TC_BWG_PERCENT_PER_CHAN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb.c:16: warning: Excess function parameter 'file' description in 'SXE_TC_BWG_PERCENT_PER_CHAN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb_nl.c:20: warning: Excess function parameter 'author' description in 'BIT_PFC'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb_nl.c:20: warning: Excess function parameter 'date' description in 'BIT_PFC'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb_nl.c:20: warning: Excess function parameter 'file' description in 'BIT_PFC'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debug.c:18: warning: Excess function parameter 'author' description in 'SKB_DESCRIPTION_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debug.c:18: warning: Excess function parameter 'date' description in 'SKB_DESCRIPTION_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debug.c:18: warning: Excess function parameter 'file' description in 'SKB_DESCRIPTION_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:432:6: error: no previous prototype for 'sxe_debugfs_entries_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:459:6: error: no previous prototype for 'sxe_debugfs_entries_exit' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:465:6: error: no previous prototype for 'sxe_debugfs_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debugfs.c:470:6: error: no previous prototype for 'sxe_debugfs_exit' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c:2022:5: error: no previous prototype for 'sxe_reg_test' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c:2644:5: error: no previous prototype for 'sxe_phys_id_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ethtool.c:2736:47: error: suggest braces around empty body in an 'if' statement [-Werror=empty-body]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_filter.c:24: warning: cannot understand function prototype: 'struct workqueue_struct *sxe_fnav_workqueue; '
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_cli.c:18: warning: cannot understand function prototype: 'dev_t sxe_cdev_major; '
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_hdc.c:27: warning: cannot understand function prototype: 'atomic_t hdc_available = ATOMIC_INIT(1); '
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1014:6: error: no previous prototype for 'sxe_hw_link_speed_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1033:6: error: no previous prototype for 'sxe_hw_is_link_state_up' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1055:6: error: no previous prototype for 'sxe_hw_mac_pad_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1064:5: error: no previous prototype for 'sxe_hw_fc_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1135:6: error: no previous prototype for 'sxe_fc_autoneg_localcap_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1164:5: error: no previous prototype for 'sxe_hw_pfc_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1256:6: error: no previous prototype for 'sxe_hw_crc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1264:6: error: no previous prototype for 'sxe_hw_loopback_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1276:6: error: no previous prototype for 'sxe_hw_mac_txrx_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1285:6: error: no previous prototype for 'sxe_hw_mac_max_frame_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1298:5: error: no previous prototype for 'sxe_hw_mac_max_frame_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1330:6: error: no previous prototype for 'sxe_hw_fc_tc_high_water_mark_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1335:6: error: no previous prototype for 'sxe_hw_fc_tc_low_water_mark_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1340:6: error: no previous prototype for 'sxe_hw_is_fc_autoneg_disabled' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1345:6: error: no previous prototype for 'sxe_hw_fc_autoneg_disable_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1360:6: error: no previous prototype for 'sxe_hw_fc_requested_mode_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1388:5: error: no previous prototype for 'sxe_hw_rx_mode_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1393:5: error: no previous prototype for 'sxe_hw_pool_rx_mode_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1398:6: error: no previous prototype for 'sxe_hw_rx_mode_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1403:6: error: no previous prototype for 'sxe_hw_pool_rx_mode_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1408:6: error: no previous prototype for 'sxe_hw_rx_lro_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1420:6: error: no previous prototype for 'sxe_hw_rx_nfs_filter_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1428:6: error: no previous prototype for 'sxe_hw_rx_udp_frag_checksum_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1437:6: error: no previous prototype for 'sxe_hw_fc_mac_addr_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1449:5: error: no previous prototype for 'sxe_hw_uc_addr_add' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1484:5: error: no previous prototype for 'sxe_hw_uc_addr_del' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1510:6: error: no previous prototype for 'sxe_hw_mta_hash_table_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1515:6: error: no previous prototype for 'sxe_hw_mta_hash_table_update' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1525:5: error: no previous prototype for 'sxe_hw_mc_filter_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1530:6: error: no previous prototype for 'sxe_hw_mc_filter_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1554:6: error: no previous prototype for 'sxe_hw_uc_addr_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1587:6: error: no previous prototype for 'sxe_hw_vt_ctrl_cfg' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1601:6: error: no previous prototype for 'sxe_hw_vt_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1675:5: error: no previous prototype for 'sxe_hw_vlan_pool_filter_read' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1697:6: error: no previous prototype for 'sxe_hw_vlan_filter_array_write' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1702:5: error: no previous prototype for 'sxe_hw_vlan_filter_array_read' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1707:6: error: no previous prototype for 'sxe_hw_vlan_filter_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1735:5: error: no previous prototype for 'sxe_hw_vlvf_slot_find' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1769:5: error: no previous prototype for 'sxe_hw_vlan_filter_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1836:6: error: no previous prototype for 'sxe_hw_vlan_filter_array_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1910:5: error: no previous prototype for 'sxe_hw_rx_pkt_buf_size_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1915:6: error: no previous prototype for 'sxe_hw_rx_multi_ring_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:1996:6: error: no previous prototype for 'sxe_hw_rss_key_set_all' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2004:6: error: no previous prototype for 'sxe_hw_rss_redir_tbl_reg_write' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2009:6: error: no previous prototype for 'sxe_hw_rss_redir_tbl_set_all' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2024:6: error: no previous prototype for 'sxe_hw_rx_cap_switch_on' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2041:6: error: no previous prototype for 'sxe_hw_rx_cap_switch_off' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2070:6: error: no previous prototype for 'sxe_hw_tx_pkt_buf_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2086:6: error: no previous prototype for 'sxe_hw_tx_pkt_buf_size_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2101:6: error: no previous prototype for 'sxe_hw_rx_lro_ack_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2147:6: error: no previous prototype for 'sxe_hw_fnav_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2204:5: error: no previous prototype for 'sxe_hw_fnav_port_mask_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:230:6: error: no previous prototype for 'sxe_hw_no_snoop_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2310:5: error: no previous prototype for 'sxe_hw_fnav_specific_rule_mask_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2445:5: error: no previous prototype for 'sxe_hw_fnav_specific_rule_add' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2469:5: error: no previous prototype for 'sxe_hw_fnav_specific_rule_del' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2500:6: error: no previous prototype for 'sxe_hw_fnav_sample_rule_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2587:5: error: no previous prototype for 'sxe_hw_fnav_sample_rules_table_reinit' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:262:6: error: no previous prototype for 'sxe_hw_uc_addr_pool_del' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2651:5: error: no previous prototype for 'sxe_hw_ptp_systime_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2667:6: error: no previous prototype for 'sxe_hw_ptp_systime_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2676:6: error: no previous prototype for 'sxe_hw_ptp_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2692:6: error: no previous prototype for 'sxe_hw_ptp_rx_timestamp_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2697:6: error: no previous prototype for 'sxe_hw_ptp_tx_timestamp_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2729:5: error: no previous prototype for 'sxe_hw_ptp_rx_timestamp_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2746:6: error: no previous prototype for 'sxe_hw_ptp_is_rx_timestamp_valid' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2758:6: error: no previous prototype for 'sxe_hw_ptp_timestamp_mode_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2782:6: error: no previous prototype for 'sxe_hw_ptp_timestamp_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:283:5: error: no previous prototype for 'sxe_hw_uc_addr_pool_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2922:6: error: no previous prototype for 'sxe_hw_rx_dma_ctrl_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2930:6: error: no previous prototype for 'sxe_hw_rx_dma_lro_ctrl_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2938:6: error: no previous prototype for 'sxe_hw_rx_desc_thresh_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2949:6: error: no previous prototype for 'sxe_hw_rx_ring_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2983:6: error: no previous prototype for 'sxe_hw_rx_ring_switch_not_polling' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:2999:6: error: no previous prototype for 'sxe_hw_rx_queue_desc_reg_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3016:6: error: no previous prototype for 'sxe_hw_rx_ring_desc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3030:6: error: no previous prototype for 'sxe_hw_rx_rcv_ctl_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3043:6: error: no previous prototype for 'sxe_hw_rx_lro_ctl_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3111:6: error: no previous prototype for 'sxe_hw_tx_ring_head_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3116:6: error: no previous prototype for 'sxe_hw_tx_ring_tail_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3121:6: error: no previous prototype for 'sxe_hw_tx_ring_desc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3136:6: error: no previous prototype for 'sxe_hw_tx_desc_thresh_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3147:6: error: no previous prototype for 'sxe_hw_all_ring_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3165:6: error: no previous prototype for 'sxe_hw_tx_ring_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3195:6: error: no previous prototype for 'sxe_hw_tx_ring_switch_not_polling' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3209:6: error: no previous prototype for 'sxe_hw_tx_pkt_buf_thresh_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3230:6: error: no previous prototype for 'sxe_hw_tx_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3257:6: error: no previous prototype for 'sxe_hw_vlan_tag_strip_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3279:6: error: no previous prototype for 'sxe_hw_tx_vlan_tag_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3284:5: error: no previous prototype for 'sxe_hw_tx_vlan_insert_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3289:6: error: no previous prototype for 'sxe_hw_tx_ring_info_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3295:6: error: no previous prototype for 'sxe_hw_dcb_rx_bw_alloc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3330:6: error: no previous prototype for 'sxe_hw_dcb_tx_desc_bw_alloc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3360:6: error: no previous prototype for 'sxe_hw_dcb_tx_data_bw_alloc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:337:5: error: no previous prototype for 'sxe_hw_nic_reset' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3397:6: error: no previous prototype for 'sxe_hw_dcb_pfc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3515:6: error: no previous prototype for 'sxe_hw_vt_pool_loopback_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3523:6: error: no previous prototype for 'sxe_hw_pool_rx_ring_drop_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3545:5: error: no previous prototype for 'sxe_hw_rx_pool_bitmap_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3550:6: error: no previous prototype for 'sxe_hw_rx_pool_bitmap_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3555:5: error: no previous prototype for 'sxe_hw_tx_pool_bitmap_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3560:6: error: no previous prototype for 'sxe_hw_tx_pool_bitmap_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3565:6: error: no previous prototype for 'sxe_hw_dcb_max_mem_window_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3570:6: error: no previous prototype for 'sxe_hw_dcb_tx_ring_rate_factor_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3577:6: error: no previous prototype for 'sxe_hw_spoof_count_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3586:6: error: no previous prototype for 'sxe_hw_pool_mac_anti_spoof_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3613:6: error: no previous prototype for 'sxe_hw_rx_drop_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3674:6: error: no previous prototype for 'sxe_hw_dcb_rate_limiter_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:367:6: error: no previous prototype for 'sxe_hw_pf_rst_done_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:3990:6: error: no previous prototype for 'sxe_hw_stats_regs_clean' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4099:6: error: no previous prototype for 'sxe_hw_stats_seq_clean' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4115:50: error: suggest braces around empty body in an 'if' statement [-Werror=empty-body]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4125:6: error: no previous prototype for 'sxe_hw_stats_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4301:6: error: no previous prototype for 'sxe_hw_mbx_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4326:6: error: no previous prototype for 'sxe_hw_vf_rst_check' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4342:6: error: no previous prototype for 'sxe_hw_vf_req_check' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4355:6: error: no previous prototype for 'sxe_hw_vf_ack_check' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4389:5: error: no previous prototype for 'sxe_hw_rcv_msg_from_vf' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4419:5: error: no previous prototype for 'sxe_hw_send_msg_to_vf' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4462:6: error: no previous prototype for 'sxe_hw_mbx_mem_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4488:6: error: no previous prototype for 'sxe_hw_pcie_vt_mode_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4497:5: error: no previous prototype for 'sxe_hw_hdc_lock_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4536:6: error: no previous prototype for 'sxe_hw_hdc_lock_release' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4552:6: error: no previous prototype for 'sxe_hw_hdc_fw_ov_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4557:6: error: no previous prototype for 'sxe_hw_hdc_is_fw_over_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4567:6: error: no previous prototype for 'sxe_hw_hdc_packet_send_done' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4573:6: error: no previous prototype for 'sxe_hw_hdc_packet_header_send' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4578:6: error: no previous prototype for 'sxe_hw_hdc_packet_data_dword_send' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4584:5: error: no previous prototype for 'sxe_hw_hdc_fw_ack_header_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4589:5: error: no previous prototype for 'sxe_hw_hdc_packet_data_dword_rcv' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4594:5: error: no previous prototype for 'sxe_hw_hdc_fw_status_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4604:6: error: no previous prototype for 'sxe_hw_hdc_drv_status_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:4609:5: error: no previous prototype for 'sxe_hw_hdc_channel_state_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:735:5: error: no previous prototype for 'sxe_hw_pending_irq_read_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:740:6: error: no previous prototype for 'sxe_hw_pending_irq_write_clear' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:745:5: error: no previous prototype for 'sxe_hw_irq_cause_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:765:6: error: no previous prototype for 'sxe_hw_ring_irq_auto_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:775:6: error: no previous prototype for 'sxe_hw_irq_general_reg_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:780:5: error: no previous prototype for 'sxe_hw_irq_general_reg_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:790:6: error: no previous prototype for 'sxe_hw_event_irq_map' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:806:6: error: no previous prototype for 'sxe_hw_ring_irq_map' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:823:6: error: no previous prototype for 'sxe_hw_ring_irq_interval_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:838:6: error: no previous prototype for 'sxe_hw_event_irq_auto_clear_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:843:6: error: no previous prototype for 'sxe_hw_specific_irq_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:848:6: error: no previous prototype for 'sxe_hw_specific_irq_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:876:6: error: no previous prototype for 'sxe_hw_all_irq_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:994:5: error: no previous prototype for 'sxe_hw_link_speed_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ipsec.c:23: warning: cannot understand function prototype: 'const char ipsec_aes_name[] = "rfc4106(gcm(aes))"; '
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:136:5: error: no previous prototype for 'sxe_msi_irq_init' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:182:6: error: no previous prototype for 'sxe_disable_dcb' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:212:6: error: no previous prototype for 'sxe_disable_rss' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:729:6: error: no previous prototype for 'sxe_lsc_irq_handler' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_irq.c:745:6: error: no previous prototype for 'sxe_mailbox_irq_handler' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c:70:6: error: no previous prototype for 'sxe_allow_inval_mac' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_monitor.c:24: warning: cannot understand function prototype: 'struct workqueue_struct *sxe_fnav_workqueue; '
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c:40: warning: Excess function parameter 'author' description in 'SXE_HW_REINIT_SRIOV_DELAY'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c:40: warning: Excess function parameter 'date' description in 'SXE_HW_REINIT_SRIOV_DELAY'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c:40: warning: Excess function parameter 'file' description in 'SXE_HW_REINIT_SRIOV_DELAY'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:16: warning: Excess function parameter 'author' description in 'sxe_check_cfg_fault'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:16: warning: Excess function parameter 'date' description in 'sxe_check_cfg_fault'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:16: warning: Excess function parameter 'file' description in 'sxe_check_cfg_fault'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:16: warning: Function parameter or member 'dev' not described in 'sxe_check_cfg_fault'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:16: warning: Function parameter or member 'hw' not described in 'sxe_check_cfg_fault'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_phy.c:733:5: error: no previous prototype for 'sxe_multispeed_sfp_link_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ptp.c:18: warning: Excess function parameter 'author' description in 'sxe_ptp_read'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ptp.c:18: warning: Excess function parameter 'date' description in 'sxe_ptp_read'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ptp.c:18: warning: Excess function parameter 'file' description in 'sxe_ptp_read'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ptp.c:18: warning: Function parameter or member 'cc' not described in 'sxe_ptp_read'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ring.c:18: warning: Excess function parameter 'author' description in 'sxe_rss_num_get'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ring.c:18: warning: Excess function parameter 'date' description in 'sxe_rss_num_get'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ring.c:18: warning: Excess function parameter 'file' description in 'sxe_rss_num_get'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_ring.c:18: warning: Function parameter or member 'adapter' not described in 'sxe_rss_num_get'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c:1431:6: error: no previous prototype for 'sxe_headers_cleanup' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_rx_proc.c:1569:6: error: no previous prototype for 'sxe_rx_buffer_page_offset_update' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c:1552:6: error: no previous prototype for 'sxe_set_vf_link_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c:766:13: error: variable 'ret' set but not used [-Werror=unused-but-set-variable]
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:41: warning: Excess function parameter 'author' description in 'SXE_SKB_MIN_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:41: warning: Excess function parameter 'date' description in 'SXE_SKB_MIN_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:41: warning: Excess function parameter 'file' description in 'SXE_SKB_MIN_LEN'
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_xdp.c:403:6: error: no previous prototype for 'sxe_txrx_ring_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:24: warning: Excess function parameter 'author' description in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:24: warning: Excess function parameter 'date' description in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:24: warning: Excess function parameter 'file' description in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:24: warning: Function parameter or member 'buf_len' not described in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxevf/base/log/sxe_log.c:24: warning: Function parameter or member 'buff' not described in 'time_for_file_name'
drivers/net/ethernet/linkdata/sxevf/base/trace/sxe_trace.c:21: warning: Excess function parameter 'author' description in 'SXE_FILE_NAME_LEN'
drivers/net/ethernet/linkdata/sxevf/base/trace/sxe_trace.c:21: warning: Excess function parameter 'date' description in 'SXE_FILE_NAME_LEN'
drivers/net/ethernet/linkdata/sxevf/base/trace/sxe_trace.c:21: warning: Excess function parameter 'file' description in 'SXE_FILE_NAME_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:23: warning: Excess function parameter 'author' description in 'sxevf_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:23: warning: Excess function parameter 'date' description in 'sxevf_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:23: warning: Excess function parameter 'file' description in 'sxevf_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:23: warning: Function parameter or member 'protocol' not described in 'sxevf_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c:23: warning: Function parameter or member 'skb' not described in 'sxevf_is_sctp_ipv4'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_debug.c:18: warning: Excess function parameter 'author' description in 'SKB_DESCRIPTION_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_debug.c:18: warning: Excess function parameter 'date' description in 'SKB_DESCRIPTION_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_debug.c:18: warning: Excess function parameter 'file' description in 'SKB_DESCRIPTION_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ethtool.c:22: warning: Excess function parameter 'author' description in 'SXEVF_DIAG_REGS_TEST'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ethtool.c:22: warning: Excess function parameter 'date' description in 'SXEVF_DIAG_REGS_TEST'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ethtool.c:22: warning: Excess function parameter 'file' description in 'SXEVF_DIAG_REGS_TEST'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:160:6: error: no previous prototype for 'sxevf_hw_stop' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:187:6: error: no previous prototype for 'sxevf_msg_write' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:196:5: error: no previous prototype for 'sxevf_msg_read' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:206:5: error: no previous prototype for 'sxevf_mailbox_read' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:211:6: error: no previous prototype for 'sxevf_mailbox_write' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:216:6: error: no previous prototype for 'sxevf_pf_req_irq_trigger' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:221:6: error: no previous prototype for 'sxevf_pf_ack_irq_trigger' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:226:6: error: no previous prototype for 'sxevf_event_irq_map' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:240:6: error: no previous prototype for 'sxevf_specific_irq_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:245:6: error: no previous prototype for 'sxevf_irq_enable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:251:6: error: no previous prototype for 'sxevf_irq_disable' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:259:6: error: no previous prototype for 'sxevf_hw_ring_irq_map' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:276:6: error: no previous prototype for 'sxevf_ring_irq_interval_set' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:313:6: error: no previous prototype for 'sxevf_hw_reset' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:324:5: error: no previous prototype for 'sxevf_link_state_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:539:6: error: no previous prototype for 'sxevf_tx_ring_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:594:6: error: no previous prototype for 'sxevf_rx_ring_switch' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:626:6: error: no previous prototype for 'sxevf_rx_ring_desc_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:640:6: error: no previous prototype for 'sxevf_rx_rcv_ctl_configure' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:697:6: error: no previous prototype for 'sxevf_32bit_counter_update' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:710:6: error: no previous prototype for 'sxevf_36bit_counter_update' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:726:6: error: no previous prototype for 'sxevf_packet_stats_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c:740:6: error: no previous prototype for 'sxevf_stats_init_value_get' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ipsec.c:21: warning: cannot understand function prototype: 'const char ipsec_aes_name[] = "rfc4106(gcm(aes))"; '
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Excess function parameter 'author' description in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Excess function parameter 'date' description in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Excess function parameter 'file' description in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Function parameter or member 'dev' not described in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Function parameter or member 'napi' not described in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Function parameter or member 'poll' not described in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_irq.c:35: warning: Function parameter or member 'weight' not described in 'netif_napi_add_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:28: warning: Excess function parameter 'author' description in 'SXEVF_MSG_LEVEL_DEFAULT'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:28: warning: Excess function parameter 'date' description in 'SXEVF_MSG_LEVEL_DEFAULT'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:28: warning: Excess function parameter 'file' description in 'SXEVF_MSG_LEVEL_DEFAULT'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_monitor.c:19: warning: Excess function parameter 'author' description in 'SXEVF_CHECK_LINK_TIMER_PERIOD'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_monitor.c:19: warning: Excess function parameter 'date' description in 'SXEVF_CHECK_LINK_TIMER_PERIOD'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_monitor.c:19: warning: Excess function parameter 'file' description in 'SXEVF_CHECK_LINK_TIMER_PERIOD'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_msg.c:20: warning: Excess function parameter 'author' description in 'SXEVF_PFMSG_MASK'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_msg.c:20: warning: Excess function parameter 'date' description in 'SXEVF_PFMSG_MASK'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_msg.c:20: warning: Excess function parameter 'file' description in 'SXEVF_PFMSG_MASK'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c:32: warning: Excess function parameter 'author' description in 'SXEVF_MAX_MAC_HDR_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c:32: warning: Excess function parameter 'date' description in 'SXEVF_MAX_MAC_HDR_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c:32: warning: Excess function parameter 'file' description in 'SXEVF_MAX_MAC_HDR_LEN'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ring.c:19: warning: Excess function parameter 'author' description in 'sxevf_ring_feature_init'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ring.c:19: warning: Excess function parameter 'date' description in 'sxevf_ring_feature_init'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ring.c:19: warning: Excess function parameter 'file' description in 'sxevf_ring_feature_init'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_ring.c:19: warning: Function parameter or member 'adapter' not described in 'sxevf_ring_feature_init'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_rx_proc.c:362:6: error: no previous prototype for 'sxevf_rx_ring_buffers_alloc' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:127:5: error: no previous prototype for 'sxevf_tx_ring_alloc' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:703:66: error: suggest braces around empty body in an 'if' statement [-Werror=empty-body]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:838:71: error: suggest braces around empty body in an 'else' statement [-Werror=empty-body]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.c:88:6: error: no previous prototype for 'sxevf_tx_ring_free' [-Werror=missing-prototypes]
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:23: warning: Excess function parameter 'author' description in 'bpf_warn_invalid_xdp_action_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:23: warning: Excess function parameter 'date' description in 'bpf_warn_invalid_xdp_action_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:23: warning: Excess function parameter 'file' description in 'bpf_warn_invalid_xdp_action_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:23: warning: Function parameter or member 'act' not described in 'bpf_warn_invalid_xdp_action_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:23: warning: Function parameter or member 'dev' not described in 'bpf_warn_invalid_xdp_action_compat'
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_xdp.c:23: warning: Function parameter or member 'prog' not described in 'bpf_warn_invalid_xdp_action_compat'
include/linux/backing-dev.h:430:49: warning: 'struct cgroup_subsys' declared inside parameter list will not be visible outside of this definition or declaration
include/linux/backing-dev.h:430:49: warning: declaration of 'struct cgroup_subsys' will not be visible outside of this function [-Wvisibility]
include/linux/minmax.h:20:35: warning: comparison of distinct pointer types lacks a cast
Error/Warning ids grouped by kconfigs:
recent_errors
|-- arm64-allnoconfig
| `-- include-linux-backing-dev.h:warning:struct-cgroup_subsys-declared-inside-parameter-list-will-not-be-visible-outside-of-this-definition-or-declaration
|-- x86_64-allnoconfig
| `-- include-linux-backing-dev.h:warning:declaration-of-struct-cgroup_subsys-will-not-be-visible-outside-of-this-function
|-- x86_64-allyesconfig
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-author-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-date-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-file-description-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxe_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-author-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-date-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-file-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-author-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-date-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-file-description-in-BIT_PFC
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:cannot-understand-function-prototype:dev_t-sxe_cdev_major
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:cannot-understand-function-prototype:atomic_t-hdc_available-ATOMIC_INIT()
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-author-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-date-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-file-description-in-SXE_HW_REINIT_SRIOV_DELAY
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-author-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-date-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-file-description-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-dev-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-hw-not-described-in-sxe_check_cfg_fault
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-author-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-date-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-file-description-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Function-parameter-or-member-cc-not-described-in-sxe_ptp_read
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-author-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-date-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-file-description-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxe_rss_num_get
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-author-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-date-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-file-description-in-SXE_SKB_MIN_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-author-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-date-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-file-description-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxevf_is_sctp_ipv4
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-author-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-date-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-file-description-in-SXEVF_DIAG_REGS_TEST
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-author-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-date-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-file-description-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-dev-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-napi-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-poll-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-weight-not-described-in-netif_napi_add_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-author-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-date-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-file-description-in-SXEVF_MSG_LEVEL_DEFAULT
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-author-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-date-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-file-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-author-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-date-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-file-description-in-SXEVF_PFMSG_MASK
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-author-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-date-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-file-description-in-SXEVF_MAX_MAC_HDR_LEN
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-author-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-date-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-file-description-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxevf_ring_feature_init
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-author-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-date-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-file-description-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-act-not-described-in-bpf_warn_invalid_xdp_action_compat
| |-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-dev-not-described-in-bpf_warn_invalid_xdp_action_compat
| `-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-prog-not-described-in-bpf_warn_invalid_xdp_action_compat
|-- x86_64-buildonly-randconfig-006-20250506
| `-- include-linux-minmax.h:warning:comparison-of-distinct-pointer-types-lacks-a-cast
`-- x86_64-defconfig
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxe-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
|-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
|-- drivers-net-ethernet-linkdata-sxe-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-author-description-in-sxe_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-date-description-in-sxe_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Excess-function-parameter-file-description-in-sxe_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxe_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxe_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-author-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-date-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb.c:warning:Excess-function-parameter-file-description-in-SXE_TC_BWG_PERCENT_PER_CHAN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-author-description-in-BIT_PFC
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-date-description-in-BIT_PFC
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_dcb_nl.c:warning:Excess-function-parameter-file-description-in-BIT_PFC
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_entries_exit
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_entries_init
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_exit
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_debugfs.c:error:no-previous-prototype-for-sxe_debugfs_init
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-sxe_phys_id_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:no-previous-prototype-for-sxe_reg_test
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ethtool.c:error:suggest-braces-around-empty-body-in-an-if-statement
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_filter.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_cli.c:warning:cannot-understand-function-prototype:dev_t-sxe_cdev_major
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_host_hdc.c:warning:cannot-understand-function-prototype:atomic_t-hdc_available-ATOMIC_INIT()
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_fc_autoneg_localcap_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_all_irq_disable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_all_ring_disable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_crc_configure
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_max_mem_window_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_pfc_configure
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_rate_limiter_clear
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_rx_bw_alloc_configure
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_data_bw_alloc_configure
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_desc_bw_alloc_configure
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_dcb_tx_ring_rate_factor_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_event_irq_auto_clear_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_event_irq_map
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_autoneg_disable_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_enable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_mac_addr_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_requested_mode_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_tc_high_water_mark_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fc_tc_low_water_mark_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_enable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_port_mask_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_sample_rule_configure
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_sample_rules_table_reinit
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_add
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_del
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_fnav_specific_rule_mask_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_channel_state_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_drv_status_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_ack_header_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_ov_clear
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_fw_status_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_is_fw_over_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_lock_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_lock_release
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_data_dword_rcv
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_data_dword_send
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_header_send
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_hdc_packet_send_done
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_cause_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_general_reg_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_irq_general_reg_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_is_fc_autoneg_disabled
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_is_link_state_up
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_link_speed_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_link_speed_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_loopback_switch
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_max_frame_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_max_frame_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_pad_enable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mac_txrx_enable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mbx_init
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mbx_mem_clear
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mc_filter_enable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mc_filter_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mta_hash_table_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_mta_hash_table_update
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_nic_reset
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_no_snoop_disable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pcie_vt_mode_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pending_irq_read_clear
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pending_irq_write_clear
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pf_rst_done_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pfc_enable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_mac_anti_spoof_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_mode_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_mode_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_pool_rx_ring_drop_enable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_init
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_is_rx_timestamp_valid
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_rx_timestamp_clear
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_rx_timestamp_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_systime_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_systime_init
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_timestamp_enable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_timestamp_mode_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ptp_tx_timestamp_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rcv_msg_from_vf
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_auto_disable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_interval_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_ring_irq_map
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_key_set_all
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_redir_tbl_reg_write
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rss_redir_tbl_set_all
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_cap_switch_off
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_cap_switch_on
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_desc_thresh_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_dma_ctrl_init
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_dma_lro_ctrl_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_drop_switch
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_ack_switch
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_ctl_configure
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_lro_enable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_mode_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_mode_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_multi_ring_configure
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_nfs_filter_disable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pkt_buf_size_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pool_bitmap_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_pool_bitmap_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_queue_desc_reg_configure
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_rcv_ctl_configure
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_desc_configure
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_switch
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_ring_switch_not_polling
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_rx_udp_frag_checksum_disable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_send_msg_to_vf
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_specific_irq_disable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_specific_irq_enable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_spoof_count_enable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_regs_clean
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_stats_seq_clean
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_desc_thresh_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_enable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_size_configure
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_switch
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pkt_buf_thresh_configure
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pool_bitmap_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_pool_bitmap_set
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_desc_configure
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_head_init
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_info_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_switch
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_switch_not_polling
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_ring_tail_init
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_vlan_insert_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_tx_vlan_tag_clear
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_add
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_clear
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_del
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_pool_del
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_uc_addr_pool_enable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_ack_check
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_req_check
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vf_rst_check
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_clear
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_read
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_array_write
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_configure
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_filter_switch
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_pool_filter_read
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlan_tag_strip_switch
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vlvf_slot_find
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_ctrl_cfg
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_disable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:no-previous-prototype-for-sxe_hw_vt_pool_loopback_switch
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_hw.c:error:suggest-braces-around-empty-body-in-an-if-statement
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_disable_dcb
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_disable_rss
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_lsc_irq_handler
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_mailbox_irq_handler
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_irq.c:error:no-previous-prototype-for-sxe_msi_irq_init
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_main.c:error:no-previous-prototype-for-sxe_allow_inval_mac
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_monitor.c:warning:cannot-understand-function-prototype:struct-workqueue_struct-sxe_fnav_workqueue
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-author-description-in-SXE_HW_REINIT_SRIOV_DELAY
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-date-description-in-SXE_HW_REINIT_SRIOV_DELAY
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_netdev.c:warning:Excess-function-parameter-file-description-in-SXE_HW_REINIT_SRIOV_DELAY
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-author-description-in-sxe_check_cfg_fault
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-date-description-in-sxe_check_cfg_fault
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Excess-function-parameter-file-description-in-sxe_check_cfg_fault
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-dev-not-described-in-sxe_check_cfg_fault
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_pci.c:warning:Function-parameter-or-member-hw-not-described-in-sxe_check_cfg_fault
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_phy.c:error:no-previous-prototype-for-sxe_multispeed_sfp_link_configure
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-author-description-in-sxe_ptp_read
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-date-description-in-sxe_ptp_read
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Excess-function-parameter-file-description-in-sxe_ptp_read
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ptp.c:warning:Function-parameter-or-member-cc-not-described-in-sxe_ptp_read
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-author-description-in-sxe_rss_num_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-date-description-in-sxe_rss_num_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Excess-function-parameter-file-description-in-sxe_rss_num_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxe_rss_num_get
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-sxe_headers_cleanup
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_rx_proc.c:error:no-previous-prototype-for-sxe_rx_buffer_page_offset_update
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:no-previous-prototype-for-sxe_set_vf_link_enable
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_sriov.c:error:variable-ret-set-but-not-used
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-author-description-in-SXE_SKB_MIN_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-date-description-in-SXE_SKB_MIN_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_tx_proc.c:warning:Excess-function-parameter-file-description-in-SXE_SKB_MIN_LEN
|-- drivers-net-ethernet-linkdata-sxe-sxepf-sxe_xdp.c:error:no-previous-prototype-for-sxe_txrx_ring_enable
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-author-description-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-date-description-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Excess-function-parameter-file-description-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buf_len-not-described-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxevf-base-log-sxe_log.c:warning:Function-parameter-or-member-buff-not-described-in-time_for_file_name
|-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-author-description-in-SXE_FILE_NAME_LEN
|-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-date-description-in-SXE_FILE_NAME_LEN
|-- drivers-net-ethernet-linkdata-sxevf-base-trace-sxe_trace.c:warning:Excess-function-parameter-file-description-in-SXE_FILE_NAME_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-author-description-in-sxevf_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-date-description-in-sxevf_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Excess-function-parameter-file-description-in-sxevf_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-protocol-not-described-in-sxevf_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_csum.c:warning:Function-parameter-or-member-skb-not-described-in-sxevf_is_sctp_ipv4
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-author-description-in-SKB_DESCRIPTION_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-date-description-in-SKB_DESCRIPTION_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_debug.c:warning:Excess-function-parameter-file-description-in-SKB_DESCRIPTION_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-author-description-in-SXEVF_DIAG_REGS_TEST
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-date-description-in-SXEVF_DIAG_REGS_TEST
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ethtool.c:warning:Excess-function-parameter-file-description-in-SXEVF_DIAG_REGS_TEST
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_32bit_counter_update
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_36bit_counter_update
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_event_irq_map
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_reset
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_ring_irq_map
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_hw_stop
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_irq_disable
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_irq_enable
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_link_state_get
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_mailbox_read
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_mailbox_write
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_msg_read
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_msg_write
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_packet_stats_get
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_pf_ack_irq_trigger
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_pf_req_irq_trigger
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_ring_irq_interval_set
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_rcv_ctl_configure
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_ring_desc_configure
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_rx_ring_switch
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_specific_irq_enable
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_stats_init_value_get
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_hw.c:error:no-previous-prototype-for-sxevf_tx_ring_switch
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ipsec.c:warning:cannot-understand-function-prototype:const-char-ipsec_aes_name-rfc4106(gcm(aes))
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-author-description-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-date-description-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Excess-function-parameter-file-description-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-dev-not-described-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-napi-not-described-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-poll-not-described-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_irq.c:warning:Function-parameter-or-member-weight-not-described-in-netif_napi_add_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-author-description-in-SXEVF_MSG_LEVEL_DEFAULT
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-date-description-in-SXEVF_MSG_LEVEL_DEFAULT
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_main.c:warning:Excess-function-parameter-file-description-in-SXEVF_MSG_LEVEL_DEFAULT
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-author-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-date-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_monitor.c:warning:Excess-function-parameter-file-description-in-SXEVF_CHECK_LINK_TIMER_PERIOD
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-author-description-in-SXEVF_PFMSG_MASK
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-date-description-in-SXEVF_PFMSG_MASK
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_msg.c:warning:Excess-function-parameter-file-description-in-SXEVF_PFMSG_MASK
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-author-description-in-SXEVF_MAX_MAC_HDR_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-date-description-in-SXEVF_MAX_MAC_HDR_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_netdev.c:warning:Excess-function-parameter-file-description-in-SXEVF_MAX_MAC_HDR_LEN
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-author-description-in-sxevf_ring_feature_init
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-date-description-in-sxevf_ring_feature_init
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Excess-function-parameter-file-description-in-sxevf_ring_feature_init
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_ring.c:warning:Function-parameter-or-member-adapter-not-described-in-sxevf_ring_feature_init
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_rx_proc.c:error:no-previous-prototype-for-sxevf_rx_ring_buffers_alloc
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-sxevf_tx_ring_alloc
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:no-previous-prototype-for-sxevf_tx_ring_free
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:suggest-braces-around-empty-body-in-an-else-statement
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_tx_proc.c:error:suggest-braces-around-empty-body-in-an-if-statement
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-author-description-in-bpf_warn_invalid_xdp_action_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-date-description-in-bpf_warn_invalid_xdp_action_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Excess-function-parameter-file-description-in-bpf_warn_invalid_xdp_action_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-act-not-described-in-bpf_warn_invalid_xdp_action_compat
|-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-dev-not-described-in-bpf_warn_invalid_xdp_action_compat
`-- drivers-net-ethernet-linkdata-sxevf-sxevf-sxevf_xdp.c:warning:Function-parameter-or-member-prog-not-described-in-bpf_warn_invalid_xdp_action_compat
elapsed time: 2422m
configs tested: 5
configs skipped: 50
tested configs:
arm64 allmodconfig clang-19
arm64 allnoconfig gcc-14.2.0
x86_64 allnoconfig clang-20
x86_64 allyesconfig clang-20
x86_64 defconfig gcc-11
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-6.6 2208/2208] include/trace/stages/init.h:2:23: warning: 'str__bonding__trace_system_name' defined but not used
by kernel test robot 08 May '25
by kernel test robot 08 May '25
08 May '25
Hi Wei,
FYI, the error/warning still remains.
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: 66448995cc552d846c7442188f69e833f4a86676
commit: 69ddcb21328bd29cfd2f64710bdac158f4c90bf6 [2208/2208] drivers: hooks: add bonding driver vendor hooks
config: loongarch-allmodconfig (https://download.01.org/0day-ci/archive/20250508/202505080910.94UlZrA0-lkp@…)
compiler: loongarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250508/202505080910.94UlZrA0-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505080910.94UlZrA0-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from include/trace/trace_events.h:27,
from include/trace/define_trace.h:102,
from include/trace/hooks/bonding.h:27,
from drivers/hooks/vendor_hooks.c:11:
>> include/trace/stages/init.h:2:23: warning: 'str__bonding__trace_system_name' defined but not used [-Wunused-const-variable=]
2 | #define __app__(x, y) str__##x##y
| ^~~~~
include/trace/stages/init.h:3:21: note: in expansion of macro '__app__'
3 | #define __app(x, y) __app__(x, y)
| ^~~~~~~
include/trace/stages/init.h:5:29: note: in expansion of macro '__app'
5 | #define TRACE_SYSTEM_STRING __app(TRACE_SYSTEM_VAR,__trace_system_name)
| ^~~~~
include/trace/stages/init.h:8:27: note: in expansion of macro 'TRACE_SYSTEM_STRING'
8 | static const char TRACE_SYSTEM_STRING[] = \
| ^~~~~~~~~~~~~~~~~~~
include/trace/stages/init.h:11:1: note: in expansion of macro 'TRACE_MAKE_SYSTEM_STR'
11 | TRACE_MAKE_SYSTEM_STR();
| ^~~~~~~~~~~~~~~~~~~~~
vim +/str__bonding__trace_system_name +2 include/trace/stages/init.h
af6b9668e85ffd Steven Rostedt (Google 2022-03-03 @2) #define __app__(x, y) str__##x##y
af6b9668e85ffd Steven Rostedt (Google 2022-03-03 3) #define __app(x, y) __app__(x, y)
af6b9668e85ffd Steven Rostedt (Google 2022-03-03 4)
:::::: The code at line 2 was first introduced by commit
:::::: af6b9668e85ffd1502aada8036ccbf4dbd481708 tracing: Move the defines to create TRACE_EVENTS into their own files
:::::: TO: Steven Rostedt (Google) <rostedt(a)goodmis.org>
:::::: CC: Steven Rostedt (Google) <rostedt(a)goodmis.org>
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-6.6 2208/2208] drivers/net/ethernet/yunsilicon/xsc/pci/xsc_lag.c:1128:21: warning: variable 'bond_dev' set but not used
by kernel test robot 08 May '25
by kernel test robot 08 May '25
08 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: 66448995cc552d846c7442188f69e833f4a86676
commit: d0888acfac5d4aca4538e40f027e80d9230c5002 [2208/2208] drivers: update Yunsilicon drivers to version rel_2412_std_card
config: x86_64-allyesconfig (https://download.01.org/0day-ci/archive/20250508/202505080526.qCQgtY7V-lkp@…)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250508/202505080526.qCQgtY7V-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505080526.qCQgtY7V-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/net/ethernet/yunsilicon/xsc/pci/xsc_lag.c:1128:21: warning: variable 'bond_dev' set but not used [-Wunused-but-set-variable]
1128 | struct net_device *bond_dev;
| ^
1 warning generated.
--
>> drivers/net/ethernet/yunsilicon/xsc/pci/sriov_sysfs.c:911:31: warning: unused variable 'vf_type_ib' [-Wunused-const-variable]
911 | static const struct kobj_type vf_type_ib = {
| ^~~~~~~~~~
1 warning generated.
vim +/bond_dev +1128 drivers/net/ethernet/yunsilicon/xsc/pci/xsc_lag.c
601fb01dc16f74 tianx 2024-04-11 1122
bcfb3e65a5707c Tian Xin 2024-10-30 1123 static void xsc_handle_changelowerstate_event(struct xsc_board_lag *board_lag,
bcfb3e65a5707c Tian Xin 2024-10-30 1124 struct net_device *ndev,
bcfb3e65a5707c Tian Xin 2024-10-30 1125 struct netdev_notifier_changelowerstate_info *info)
601fb01dc16f74 tianx 2024-04-11 1126 {
bcfb3e65a5707c Tian Xin 2024-10-30 1127 struct netdev_lag_lower_state_info *lag_lower_info;
bcfb3e65a5707c Tian Xin 2024-10-30 @1128 struct net_device *bond_dev;
bcfb3e65a5707c Tian Xin 2024-10-30 1129 struct slave *slave;
bcfb3e65a5707c Tian Xin 2024-10-30 1130 struct xsc_lag *lag;
bcfb3e65a5707c Tian Xin 2024-10-30 1131 u8 bond_id;
bcfb3e65a5707c Tian Xin 2024-10-30 1132 enum lag_slave_status slave_status = XSC_LAG_SLAVE_INACTIVE;
d0888acfac5d4a Xin Tian 2025-04-29 1133 struct xsc_adapter *adapter;
d0888acfac5d4a Xin Tian 2025-04-29 1134 struct xsc_core_device *xdev;
601fb01dc16f74 tianx 2024-04-11 1135
bcfb3e65a5707c Tian Xin 2024-10-30 1136 if (!netif_is_lag_port(ndev) || !info->lower_state_info)
bcfb3e65a5707c Tian Xin 2024-10-30 1137 return;
601fb01dc16f74 tianx 2024-04-11 1138
bcfb3e65a5707c Tian Xin 2024-10-30 1139 rcu_read_lock();
bcfb3e65a5707c Tian Xin 2024-10-30 1140 slave = bond_slave_get_rtnl(ndev);
bcfb3e65a5707c Tian Xin 2024-10-30 1141 rcu_read_unlock();
bcfb3e65a5707c Tian Xin 2024-10-30 1142 if (!slave || !slave->bond || !slave->bond->dev)
bcfb3e65a5707c Tian Xin 2024-10-30 1143 return;
601fb01dc16f74 tianx 2024-04-11 1144
bcfb3e65a5707c Tian Xin 2024-10-30 1145 bond_dev = slave->bond->dev;
bcfb3e65a5707c Tian Xin 2024-10-30 1146
bcfb3e65a5707c Tian Xin 2024-10-30 1147 lag_lower_info = info->lower_state_info;
bcfb3e65a5707c Tian Xin 2024-10-30 1148 if (lag_lower_info->link_up && lag_lower_info->tx_enabled)
bcfb3e65a5707c Tian Xin 2024-10-30 1149 slave_status = XSC_LAG_SLAVE_ACTIVE;
bcfb3e65a5707c Tian Xin 2024-10-30 1150
bcfb3e65a5707c Tian Xin 2024-10-30 1151 mutex_lock(&board_lag->lock);
bcfb3e65a5707c Tian Xin 2024-10-30 1152 if (!xsc_board_lag_filter(board_lag, ndev)) {
bcfb3e65a5707c Tian Xin 2024-10-30 1153 mutex_unlock(&board_lag->lock);
bcfb3e65a5707c Tian Xin 2024-10-30 1154 return;
601fb01dc16f74 tianx 2024-04-11 1155 }
601fb01dc16f74 tianx 2024-04-11 1156
d0888acfac5d4a Xin Tian 2025-04-29 1157 adapter = netdev_priv(ndev);
d0888acfac5d4a Xin Tian 2025-04-29 1158 xdev = adapter->xdev;
d0888acfac5d4a Xin Tian 2025-04-29 1159 bond_id = xdev->bond_id;
bcfb3e65a5707c Tian Xin 2024-10-30 1160 if (bond_id == BOND_ID_INVALID) {
bcfb3e65a5707c Tian Xin 2024-10-30 1161 mutex_unlock(&board_lag->lock);
bcfb3e65a5707c Tian Xin 2024-10-30 1162 return;
601fb01dc16f74 tianx 2024-04-11 1163 }
601fb01dc16f74 tianx 2024-04-11 1164
bcfb3e65a5707c Tian Xin 2024-10-30 1165 lag = &board_lag->xsc_lag[bond_id];
bcfb3e65a5707c Tian Xin 2024-10-30 1166 pack_lag_update_member_status(lag, ndev, slave_status);
bcfb3e65a5707c Tian Xin 2024-10-30 1167 mutex_unlock(&board_lag->lock);
bcfb3e65a5707c Tian Xin 2024-10-30 1168
bcfb3e65a5707c Tian Xin 2024-10-30 1169 return;
601fb01dc16f74 tianx 2024-04-11 1170 }
601fb01dc16f74 tianx 2024-04-11 1171
:::::: The code at line 1128 was first introduced by commit
:::::: bcfb3e65a5707ca4caf593a33276f26b993ad71e drivers: update Yunsilicon driver to version 2406_rc16
:::::: TO: Tian Xin <tianx(a)yunsilicon.com>
:::::: CC: Tian Xin <tianx(a)yunsilicon.com>
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0
您好!
Kernel 邀请您参加 2025-05-09 14:00 召开的WeLink会议(自动录制)
会议主题:openEuler Kernel SIG双周例会
会议内容:
1. 进展update
2. 议题征集中(新增议题可回复此邮件申请,也可直接填报至会议纪要看板。)
会议链接:https://meeting.huaweicloud.com:36443/#/j/964960259
会议纪要:https://etherpad.openeuler.org/p/Kernel-meetings
更多资讯尽在:https://www.openeuler.org/zh/
Hello!
Kernel invites you to attend the WeLink conference(auto recording) will be held at 2025-05-09 14:00,
The subject of the conference is openEuler Kernel SIG双周例会
Summary:
1. 进展update
2. 议题征集中(新增议题可回复此邮件申请,也可直接填报至会议纪要看板。)
You can join the meeting at https://meeting.huaweicloud.com:36443/#/j/964960259
Add topics at https://etherpad.openeuler.org/p/Kernel-meetings
More information: https://www.openeuler.org/en/
1
0

07 May '25
From: Sean Heelan <seanheelan(a)gmail.com>
stable inclusion
from stable-v6.6.88
commit 1db2451de23e98bc864c6a6e52aa0d82c91cb325
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC5BMV
CVE: CVE-2025-37778
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 1e440d5b25b7efccb3defe542a73c51005799a5f upstream.
krb_authenticate frees sess->user and does not set the pointer
to NULL. It calls ksmbd_krb5_authenticate to reinitialise
sess->user but that function may return without doing so. If
that happens then smb2_sess_setup, which calls krb_authenticate,
will be accessing free'd memory when it later uses sess->user.
Cc: stable(a)vger.kernel.org
Signed-off-by: Sean Heelan <seanheelan(a)gmail.com>
Acked-by: Namjae Jeon <linkinjeon(a)kernel.org>
Signed-off-by: Steve French <stfrench(a)microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Wang Zhaolong <wangzhaolong1(a)huawei.com>
---
fs/smb/server/smb2pdu.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 2074d977d5c9..80ef2f4b9210 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -1591,12 +1591,14 @@ static int krb5_authenticate(struct ksmbd_work *work,
/* Check previous session */
prev_sess_id = le64_to_cpu(req->PreviousSessionId);
if (prev_sess_id && prev_sess_id != sess->id)
destroy_previous_session(conn, sess->user, prev_sess_id);
- if (sess->state == SMB2_SESSION_VALID)
+ if (sess->state == SMB2_SESSION_VALID) {
ksmbd_free_user(sess->user);
+ sess->user = NULL;
+ }
retval = ksmbd_krb5_authenticate(sess, in_blob, in_len,
out_blob, &out_len);
if (retval) {
ksmbd_debug(SMB, "krb5 authentication failed\n");
--
2.34.3
2
1

07 May '25
From: Daniel Borkmann <daniel(a)iogearbox.net>
stable inclusion
from stable-6.6.89
commit c4312c4d244aa58e811ff0297e013124d115e793
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC5I61
CVE: CVE-2025-37799
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 4c2227656d9003f4d77afc76f34dd81b95e4c2c4 upstream.
vmxnet3 driver's XDP handling is buggy for packet sizes using ring0 (that
is, packet sizes between 128 - 3k bytes).
We noticed MTU-related connectivity issues with Cilium's service load-
balancing in case of vmxnet3 as NIC underneath. A simple curl to a HTTP
backend service where the XDP LB was doing IPIP encap led to overly large
packet sizes but only for *some* of the packets (e.g. HTTP GET request)
while others (e.g. the prior TCP 3WHS) looked completely fine on the wire.
In fact, the pcap recording on the backend node actually revealed that the
node with the XDP LB was leaking uninitialized kernel data onto the wire
for the affected packets, for example, while the packets should have been
152 bytes their actual size was 1482 bytes, so the remainder after 152 bytes
was padded with whatever other data was in that page at the time (e.g. we
saw user/payload data from prior processed packets).
We only noticed this through an MTU issue, e.g. when the XDP LB node and
the backend node both had the same MTU (e.g. 1500) then the curl request
got dropped on the backend node's NIC given the packet was too large even
though the IPIP-encapped packet normally would never even come close to
the MTU limit. Lowering the MTU on the XDP LB (e.g. 1480) allowed to let
the curl request succeed (which also indicates that the kernel ignored the
padding, and thus the issue wasn't very user-visible).
Commit e127ce7699c1 ("vmxnet3: Fix missing reserved tailroom") was too eager
to also switch xdp_prepare_buff() from rcd->len to rbi->len. It really needs
to stick to rcd->len which is the actual packet length from the descriptor.
The latter we also feed into vmxnet3_process_xdp_small(), by the way, and
it indicates the correct length needed to initialize the xdp->{data,data_end}
parts. For e127ce7699c1 ("vmxnet3: Fix missing reserved tailroom") the
relevant part was adapting xdp_init_buff() to address the warning given the
xdp_data_hard_end() depends on xdp->frame_sz. With that fixed, traffic on
the wire looks good again.
Fixes: e127ce7699c1 ("vmxnet3: Fix missing reserved tailroom")
Signed-off-by: Daniel Borkmann <daniel(a)iogearbox.net>
Tested-by: Andrew Sauber <andrew.sauber(a)isovalent.com>
Cc: Anton Protopopov <aspsk(a)isovalent.com>
Cc: William Tu <witu(a)nvidia.com>
Cc: Martin Zaharinov <micron10(a)gmail.com>
Cc: Ronak Doshi <ronak.doshi(a)broadcom.com>
Reviewed-by: Simon Horman <horms(a)kernel.org>
Link: https://patch.msgid.link/20250423133600.176689-1-daniel@iogearbox.net
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Tengda Wu <wutengda2(a)huawei.com>
---
drivers/net/vmxnet3/vmxnet3_xdp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/vmxnet3/vmxnet3_xdp.c b/drivers/net/vmxnet3/vmxnet3_xdp.c
index 616ecc38d172..5f470499e600 100644
--- a/drivers/net/vmxnet3/vmxnet3_xdp.c
+++ b/drivers/net/vmxnet3/vmxnet3_xdp.c
@@ -397,7 +397,7 @@ vmxnet3_process_xdp(struct vmxnet3_adapter *adapter,
xdp_init_buff(&xdp, PAGE_SIZE, &rq->xdp_rxq);
xdp_prepare_buff(&xdp, page_address(page), rq->page_pool->p.offset,
- rbi->len, false);
+ rcd->len, false);
xdp_buff_clear_frags_flag(&xdp);
xdp_prog = rcu_dereference(rq->adapter->xdp_bpf_prog);
--
2.34.1
2
1
fix CVE-2023-53093.
Steven Rostedt (Google) (2):
tracing: Do not let histogram values have some modifiers
tracing/histograms: Allow variables to have some modifiers
kernel/trace/trace_events_hist.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
--
2.34.1
2
3

[PATCH OLK-5.10] vhost-scsi: Fix handling of multiple calls to vhost_scsi_set_endpoint
by Yin Tirui 07 May '25
by Yin Tirui 07 May '25
07 May '25
From: Mike Christie <michael.christie(a)oracle.com>
mainline inclusion
from mainline-v6.15-rc1
commit 5dd639a1646ef5fe8f4bf270fad47c5c3755b9b6
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBP35K
CVE: CVE-2025-22083
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
If vhost_scsi_set_endpoint is called multiple times without a
vhost_scsi_clear_endpoint between them, we can hit multiple bugs
found by Haoran Zhang:
1. Use-after-free when no tpgs are found:
This fixes a use after free that occurs when vhost_scsi_set_endpoint is
called more than once and calls after the first call do not find any
tpgs to add to the vs_tpg. When vhost_scsi_set_endpoint first finds
tpgs to add to the vs_tpg array match=true, so we will do:
vhost_vq_set_backend(vq, vs_tpg);
...
kfree(vs->vs_tpg);
vs->vs_tpg = vs_tpg;
If vhost_scsi_set_endpoint is called again and no tpgs are found
match=false so we skip the vhost_vq_set_backend call leaving the
pointer to the vs_tpg we then free via:
kfree(vs->vs_tpg);
vs->vs_tpg = vs_tpg;
If a scsi request is then sent we do:
vhost_scsi_handle_vq -> vhost_scsi_get_req -> vhost_vq_get_backend
which sees the vs_tpg we just did a kfree on.
2. Tpg dir removal hang:
This patch fixes an issue where we cannot remove a LIO/target layer
tpg (and structs above it like the target) dir due to the refcount
dropping to -1.
The problem is that if vhost_scsi_set_endpoint detects a tpg is already
in the vs->vs_tpg array or if the tpg has been removed so
target_depend_item fails, the undepend goto handler will do
target_undepend_item on all tpgs in the vs_tpg array dropping their
refcount to 0. At this time vs_tpg contains both the tpgs we have added
in the current vhost_scsi_set_endpoint call as well as tpgs we added in
previous calls which are also in vs->vs_tpg.
Later, when vhost_scsi_clear_endpoint runs it will do
target_undepend_item on all the tpgs in the vs->vs_tpg which will drop
their refcount to -1. Userspace will then not be able to remove the tpg
and will hang when it tries to do rmdir on the tpg dir.
3. Tpg leak:
This fixes a bug where we can leak tpgs and cause them to be
un-removable because the target name is overwritten when
vhost_scsi_set_endpoint is called multiple times but with different
target names.
The bug occurs if a user has called VHOST_SCSI_SET_ENDPOINT and setup
a vhost-scsi device to target/tpg mapping, then calls
VHOST_SCSI_SET_ENDPOINT again with a new target name that has tpgs we
haven't seen before (target1 has tpg1 but target2 has tpg2). When this
happens we don't teardown the old target tpg mapping and just overwrite
the target name and the vs->vs_tpg array. Later when we do
vhost_scsi_clear_endpoint, we are passed in either target1 or target2's
name and we will only match that target's tpgs when we loop over the
vs->vs_tpg. We will then return from the function without doing
target_undepend_item on the tpgs.
Because of all these bugs, it looks like being able to call
vhost_scsi_set_endpoint multiple times was never supported. The major
user, QEMU, already has checks to prevent this use case. So to fix the
issues, this patch prevents vhost_scsi_set_endpoint from being called
if it's already successfully added tpgs. To add, remove or change the
tpg config or target name, you must do a vhost_scsi_clear_endpoint
first.
Fixes: 25b98b64e284 ("vhost scsi: alloc cmds per vq instead of session")
Fixes: 4f7f46d32c98 ("tcm_vhost: Use vq->private_data to indicate if the endpoint is setup")
Reported-by: Haoran Zhang <wh1sper(a)zju.edu.cn>
Closes: https://lore.kernel.org/virtualization/e418a5ee-45ca-4d18-9b5d-6f8b6b1add8e…
Signed-off-by: Mike Christie <michael.christie(a)oracle.com>
Reviewed-by: Stefan Hajnoczi <stefanha(a)redhat.com>
Message-Id: <20250129210922.121533-1-michael.christie(a)oracle.com>
Signed-off-by: Michael S. Tsirkin <mst(a)redhat.com>
Acked-by: Stefano Garzarella <sgarzare(a)redhat.com>
Conflicts:
drivers/vhost/scsi.c
[Fixing context conflicts]
Signed-off-by: Yin Tirui <yintirui(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
---
drivers/vhost/scsi.c | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index a23a65e7d828..f896c8a83f1a 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1589,14 +1589,19 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
}
}
+ if (vs->vs_tpg) {
+ pr_err("vhost-scsi endpoint already set for %s.\n",
+ vs->vs_vhost_wwpn);
+ ret = -EEXIST;
+ goto out;
+ }
+
len = sizeof(vs_tpg[0]) * VHOST_SCSI_MAX_TARGET;
vs_tpg = kzalloc(len, GFP_KERNEL);
if (!vs_tpg) {
ret = -ENOMEM;
goto out;
}
- if (vs->vs_tpg)
- memcpy(vs_tpg, vs->vs_tpg, len);
list_for_each_entry(tpg, &vhost_scsi_list, tv_tpg_list) {
mutex_lock(&tpg->tv_tpg_mutex);
@@ -1611,11 +1616,6 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
tv_tport = tpg->tport;
if (!strcmp(tv_tport->tport_name, t->vhost_wwpn)) {
- if (vs->vs_tpg && vs->vs_tpg[tpg->tport_tpgt]) {
- mutex_unlock(&tpg->tv_tpg_mutex);
- ret = -EEXIST;
- goto undepend;
- }
/*
* In order to ensure individual vhost-scsi configfs
* groups cannot be removed while in use by vhost ioctl,
@@ -1660,15 +1660,15 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
}
ret = 0;
} else {
- ret = -EEXIST;
+ ret = -ENODEV;
+ goto free_tpg;
}
/*
- * Act as synchronize_rcu to make sure access to
- * old vs->vs_tpg is finished.
+ * Act as synchronize_rcu to make sure requests after this point
+ * see a fully setup device.
*/
vhost_scsi_flush(vs);
- kfree(vs->vs_tpg);
vs->vs_tpg = vs_tpg;
goto out;
@@ -1685,6 +1685,7 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
target_undepend_item(&tpg->se_tpg.tpg_group.cg_item);
}
}
+free_tpg:
kfree(vs_tpg);
out:
mutex_unlock(&vs->dev.mutex);
@@ -1773,6 +1774,7 @@ vhost_scsi_clear_endpoint(struct vhost_scsi *vs,
vhost_scsi_flush(vs);
kfree(vs->vs_tpg);
vs->vs_tpg = NULL;
+ memset(vs->vs_vhost_wwpn, 0, sizeof(vs->vs_vhost_wwpn));
WARN_ON(vs->vs_events_nr);
mutex_unlock(&vs->dev.mutex);
mutex_unlock(&vhost_scsi_mutex);
--
2.22.0
2
1
From: Grzegorz Nitka <grzegorz.nitka(a)intel.com>
mainline inclusion
from mainline-v6.14-rc7
commit 23d97f18901ef5e4e264e3b1777fe65c760186b5
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBY42R
CVE: CVE-2025-21981
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
Fix aRFS (accelerated Receive Flow Steering) structures memory leak by
adding a checker to verify if aRFS memory is already allocated while
configuring VSI. aRFS objects are allocated in two cases:
- as part of VSI initialization (at probe), and
- as part of reset handling
However, VSI reconfiguration executed during reset involves memory
allocation one more time, without prior releasing already allocated
resources. This led to the memory leak with the following signature:
[root@os-delivery ~]# cat /sys/kernel/debug/kmemleak
unreferenced object 0xff3c1ca7252e6000 (size 8192):
comm "kworker/0:0", pid 8, jiffies 4296833052
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace (crc 0):
[<ffffffff991ec485>] __kmalloc_cache_noprof+0x275/0x340
[<ffffffffc0a6e06a>] ice_init_arfs+0x3a/0xe0 [ice]
[<ffffffffc09f1027>] ice_vsi_cfg_def+0x607/0x850 [ice]
[<ffffffffc09f244b>] ice_vsi_setup+0x5b/0x130 [ice]
[<ffffffffc09c2131>] ice_init+0x1c1/0x460 [ice]
[<ffffffffc09c64af>] ice_probe+0x2af/0x520 [ice]
[<ffffffff994fbcd3>] local_pci_probe+0x43/0xa0
[<ffffffff98f07103>] work_for_cpu_fn+0x13/0x20
[<ffffffff98f0b6d9>] process_one_work+0x179/0x390
[<ffffffff98f0c1e9>] worker_thread+0x239/0x340
[<ffffffff98f14abc>] kthread+0xcc/0x100
[<ffffffff98e45a6d>] ret_from_fork+0x2d/0x50
[<ffffffff98e083ba>] ret_from_fork_asm+0x1a/0x30
...
Fixes: 28bf26724fdb ("ice: Implement aRFS")
Reviewed-by: Michal Swiatkowski <michal.swiatkowski(a)linux.intel.com>
Signed-off-by: Grzegorz Nitka <grzegorz.nitka(a)intel.com>
Reviewed-by: Simon Horman <horms(a)kernel.org>
Tested-by: Rinitha S <sx.rinitha(a)intel.com> (A Contingent worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen(a)intel.com>
Conflicts:
drivers/net/ethernet/intel/ice/ice_arfs.c
[context conflict]
Signed-off-by: Tirui Yin <yintirui(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
---
drivers/net/ethernet/intel/ice/ice_arfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_arfs.c b/drivers/net/ethernet/intel/ice/ice_arfs.c
index eca2ba2eea8c..085b1a0d67c5 100644
--- a/drivers/net/ethernet/intel/ice/ice_arfs.c
+++ b/drivers/net/ethernet/intel/ice/ice_arfs.c
@@ -510,7 +510,7 @@ void ice_init_arfs(struct ice_vsi *vsi)
struct hlist_head *arfs_fltr_list;
unsigned int i;
- if (!vsi || vsi->type != ICE_VSI_PF)
+ if (!vsi || vsi->type != ICE_VSI_PF || ice_is_arfs_active(vsi))
return;
arfs_fltr_list = kzalloc(sizeof(*arfs_fltr_list) * ICE_MAX_ARFS_LIST,
--
2.22.0
2
1

[PATCH OLK-6.6] vhost-scsi: Fix handling of multiple calls to vhost_scsi_set_endpoint
by Yin Tirui 07 May '25
by Yin Tirui 07 May '25
07 May '25
From: Mike Christie <michael.christie(a)oracle.com>
stable inclusion
from stable-v6.6.87
commit 2b34bdc42df047794542f3e220fe989124e4499a
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBP35K
CVE: CVE-2025-22083
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 5dd639a1646ef5fe8f4bf270fad47c5c3755b9b6 ]
If vhost_scsi_set_endpoint is called multiple times without a
vhost_scsi_clear_endpoint between them, we can hit multiple bugs
found by Haoran Zhang:
1. Use-after-free when no tpgs are found:
This fixes a use after free that occurs when vhost_scsi_set_endpoint is
called more than once and calls after the first call do not find any
tpgs to add to the vs_tpg. When vhost_scsi_set_endpoint first finds
tpgs to add to the vs_tpg array match=true, so we will do:
vhost_vq_set_backend(vq, vs_tpg);
...
kfree(vs->vs_tpg);
vs->vs_tpg = vs_tpg;
If vhost_scsi_set_endpoint is called again and no tpgs are found
match=false so we skip the vhost_vq_set_backend call leaving the
pointer to the vs_tpg we then free via:
kfree(vs->vs_tpg);
vs->vs_tpg = vs_tpg;
If a scsi request is then sent we do:
vhost_scsi_handle_vq -> vhost_scsi_get_req -> vhost_vq_get_backend
which sees the vs_tpg we just did a kfree on.
2. Tpg dir removal hang:
This patch fixes an issue where we cannot remove a LIO/target layer
tpg (and structs above it like the target) dir due to the refcount
dropping to -1.
The problem is that if vhost_scsi_set_endpoint detects a tpg is already
in the vs->vs_tpg array or if the tpg has been removed so
target_depend_item fails, the undepend goto handler will do
target_undepend_item on all tpgs in the vs_tpg array dropping their
refcount to 0. At this time vs_tpg contains both the tpgs we have added
in the current vhost_scsi_set_endpoint call as well as tpgs we added in
previous calls which are also in vs->vs_tpg.
Later, when vhost_scsi_clear_endpoint runs it will do
target_undepend_item on all the tpgs in the vs->vs_tpg which will drop
their refcount to -1. Userspace will then not be able to remove the tpg
and will hang when it tries to do rmdir on the tpg dir.
3. Tpg leak:
This fixes a bug where we can leak tpgs and cause them to be
un-removable because the target name is overwritten when
vhost_scsi_set_endpoint is called multiple times but with different
target names.
The bug occurs if a user has called VHOST_SCSI_SET_ENDPOINT and setup
a vhost-scsi device to target/tpg mapping, then calls
VHOST_SCSI_SET_ENDPOINT again with a new target name that has tpgs we
haven't seen before (target1 has tpg1 but target2 has tpg2). When this
happens we don't teardown the old target tpg mapping and just overwrite
the target name and the vs->vs_tpg array. Later when we do
vhost_scsi_clear_endpoint, we are passed in either target1 or target2's
name and we will only match that target's tpgs when we loop over the
vs->vs_tpg. We will then return from the function without doing
target_undepend_item on the tpgs.
Because of all these bugs, it looks like being able to call
vhost_scsi_set_endpoint multiple times was never supported. The major
user, QEMU, already has checks to prevent this use case. So to fix the
issues, this patch prevents vhost_scsi_set_endpoint from being called
if it's already successfully added tpgs. To add, remove or change the
tpg config or target name, you must do a vhost_scsi_clear_endpoint
first.
Fixes: 25b98b64e284 ("vhost scsi: alloc cmds per vq instead of session")
Fixes: 4f7f46d32c98 ("tcm_vhost: Use vq->private_data to indicate if the endpoint is setup")
Reported-by: Haoran Zhang <wh1sper(a)zju.edu.cn>
Closes: https://lore.kernel.org/virtualization/e418a5ee-45ca-4d18-9b5d-6f8b6b1add8e…
Signed-off-by: Mike Christie <michael.christie(a)oracle.com>
Reviewed-by: Stefan Hajnoczi <stefanha(a)redhat.com>
Message-Id: <20250129210922.121533-1-michael.christie(a)oracle.com>
Signed-off-by: Michael S. Tsirkin <mst(a)redhat.com>
Acked-by: Stefano Garzarella <sgarzare(a)redhat.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Yin Tirui <yintirui(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
---
drivers/vhost/scsi.c | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 99813232c25e..8d8a22504d71 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1688,14 +1688,19 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
}
}
+ if (vs->vs_tpg) {
+ pr_err("vhost-scsi endpoint already set for %s.\n",
+ vs->vs_vhost_wwpn);
+ ret = -EEXIST;
+ goto out;
+ }
+
len = sizeof(vs_tpg[0]) * VHOST_SCSI_MAX_TARGET;
vs_tpg = kzalloc(len, GFP_KERNEL);
if (!vs_tpg) {
ret = -ENOMEM;
goto out;
}
- if (vs->vs_tpg)
- memcpy(vs_tpg, vs->vs_tpg, len);
mutex_lock(&vhost_scsi_mutex);
list_for_each_entry(tpg, &vhost_scsi_list, tv_tpg_list) {
@@ -1711,12 +1716,6 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
tv_tport = tpg->tport;
if (!strcmp(tv_tport->tport_name, t->vhost_wwpn)) {
- if (vs->vs_tpg && vs->vs_tpg[tpg->tport_tpgt]) {
- mutex_unlock(&tpg->tv_tpg_mutex);
- mutex_unlock(&vhost_scsi_mutex);
- ret = -EEXIST;
- goto undepend;
- }
/*
* In order to ensure individual vhost-scsi configfs
* groups cannot be removed while in use by vhost ioctl,
@@ -1763,15 +1762,15 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
}
ret = 0;
} else {
- ret = -EEXIST;
+ ret = -ENODEV;
+ goto free_tpg;
}
/*
- * Act as synchronize_rcu to make sure access to
- * old vs->vs_tpg is finished.
+ * Act as synchronize_rcu to make sure requests after this point
+ * see a fully setup device.
*/
vhost_scsi_flush(vs);
- kfree(vs->vs_tpg);
vs->vs_tpg = vs_tpg;
goto out;
@@ -1791,6 +1790,7 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
target_undepend_item(&tpg->se_tpg.tpg_group.cg_item);
}
}
+free_tpg:
kfree(vs_tpg);
out:
mutex_unlock(&vs->dev.mutex);
@@ -1893,6 +1893,7 @@ vhost_scsi_clear_endpoint(struct vhost_scsi *vs,
vhost_scsi_flush(vs);
kfree(vs->vs_tpg);
vs->vs_tpg = NULL;
+ memset(vs->vs_vhost_wwpn, 0, sizeof(vs->vs_vhost_wwpn));
WARN_ON(vs->vs_events_nr);
mutex_unlock(&vs->dev.mutex);
return 0;
--
2.22.0
2
1
From: Grzegorz Nitka <grzegorz.nitka(a)intel.com>
stable inclusion
from stable-v6.6.84
commit 5d30d256661fc11b6e73fac6c3783a702e1006a3
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBY42R
CVE: CVE-2025-21981
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 23d97f18901ef5e4e264e3b1777fe65c760186b5 ]
Fix aRFS (accelerated Receive Flow Steering) structures memory leak by
adding a checker to verify if aRFS memory is already allocated while
configuring VSI. aRFS objects are allocated in two cases:
- as part of VSI initialization (at probe), and
- as part of reset handling
However, VSI reconfiguration executed during reset involves memory
allocation one more time, without prior releasing already allocated
resources. This led to the memory leak with the following signature:
[root@os-delivery ~]# cat /sys/kernel/debug/kmemleak
unreferenced object 0xff3c1ca7252e6000 (size 8192):
comm "kworker/0:0", pid 8, jiffies 4296833052
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace (crc 0):
[<ffffffff991ec485>] __kmalloc_cache_noprof+0x275/0x340
[<ffffffffc0a6e06a>] ice_init_arfs+0x3a/0xe0 [ice]
[<ffffffffc09f1027>] ice_vsi_cfg_def+0x607/0x850 [ice]
[<ffffffffc09f244b>] ice_vsi_setup+0x5b/0x130 [ice]
[<ffffffffc09c2131>] ice_init+0x1c1/0x460 [ice]
[<ffffffffc09c64af>] ice_probe+0x2af/0x520 [ice]
[<ffffffff994fbcd3>] local_pci_probe+0x43/0xa0
[<ffffffff98f07103>] work_for_cpu_fn+0x13/0x20
[<ffffffff98f0b6d9>] process_one_work+0x179/0x390
[<ffffffff98f0c1e9>] worker_thread+0x239/0x340
[<ffffffff98f14abc>] kthread+0xcc/0x100
[<ffffffff98e45a6d>] ret_from_fork+0x2d/0x50
[<ffffffff98e083ba>] ret_from_fork_asm+0x1a/0x30
...
Fixes: 28bf26724fdb ("ice: Implement aRFS")
Reviewed-by: Michal Swiatkowski <michal.swiatkowski(a)linux.intel.com>
Signed-off-by: Grzegorz Nitka <grzegorz.nitka(a)intel.com>
Reviewed-by: Simon Horman <horms(a)kernel.org>
Tested-by: Rinitha S <sx.rinitha(a)intel.com> (A Contingent worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen(a)intel.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Yin Tirui <yintirui(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
---
drivers/net/ethernet/intel/ice/ice_arfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_arfs.c b/drivers/net/ethernet/intel/ice/ice_arfs.c
index cca0e753f38f..d7e0116f6773 100644
--- a/drivers/net/ethernet/intel/ice/ice_arfs.c
+++ b/drivers/net/ethernet/intel/ice/ice_arfs.c
@@ -510,7 +510,7 @@ void ice_init_arfs(struct ice_vsi *vsi)
struct hlist_head *arfs_fltr_list;
unsigned int i;
- if (!vsi || vsi->type != ICE_VSI_PF)
+ if (!vsi || vsi->type != ICE_VSI_PF || ice_is_arfs_active(vsi))
return;
arfs_fltr_list = kcalloc(ICE_MAX_ARFS_LIST, sizeof(*arfs_fltr_list),
--
2.22.0
2
1
From: Eric Sandeen <sandeen(a)redhat.com>
stable inclusion
from stable-v6.6.87
commit 6dafa27764183738dc5368b669b71e3d0d154f12
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC1QS8
CVE: CVE-2025-23138
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit f13abc1e8e1a3b7455511c4e122750127f6bc9b0 ]
Currently, watch_queue_set_size() modifies the pipe buffers charged to
user->pipe_bufs without updating the pipe->nr_accounted on the pipe
itself, due to the if (!pipe_has_watch_queue()) test in
pipe_resize_ring(). This means that when the pipe is ultimately freed,
we decrement user->pipe_bufs by something other than what than we had
charged to it, potentially leading to an underflow. This in turn can
cause subsequent too_many_pipe_buffers_soft() tests to fail with -EPERM.
To remedy this, explicitly account for the pipe usage in
watch_queue_set_size() to match the number set via account_pipe_buffers()
(It's unclear why watch_queue_set_size() does not update nr_accounted;
it may be due to intentional overprovisioning in watch_queue_set_size()?)
Fixes: e95aada4cb93d ("pipe: wakeup wr_wait after setting max_usage")
Signed-off-by: Eric Sandeen <sandeen(a)redhat.com>
Link: https://lore.kernel.org/r/206682a8-0604-49e5-8224-fdbe0c12b460@redhat.com
Signed-off-by: Christian Brauner <brauner(a)kernel.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Yin Tirui <yintirui(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
---
kernel/watch_queue.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c
index 778b4056700f..17254597accd 100644
--- a/kernel/watch_queue.c
+++ b/kernel/watch_queue.c
@@ -269,6 +269,15 @@ long watch_queue_set_size(struct pipe_inode_info *pipe, unsigned int nr_notes)
if (ret < 0)
goto error;
+ /*
+ * pipe_resize_ring() does not update nr_accounted for watch_queue
+ * pipes, because the above vastly overprovisions. Set nr_accounted on
+ * and max_usage this pipe to the number that was actually charged to
+ * the user above via account_pipe_buffers.
+ */
+ pipe->max_usage = nr_pages;
+ pipe->nr_accounted = nr_pages;
+
ret = -ENOMEM;
pages = kcalloc(sizeof(struct page *), nr_pages, GFP_KERNEL);
if (!pages)
--
2.22.0
2
1
From: Eric Sandeen <sandeen(a)redhat.com>
stable inclusion
from stable-v5.10.236
commit 8658c75343ed00e5e154ebbe24335f51ba8db547
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC1QS8
CVE: CVE-2025-23138
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit f13abc1e8e1a3b7455511c4e122750127f6bc9b0 ]
Currently, watch_queue_set_size() modifies the pipe buffers charged to
user->pipe_bufs without updating the pipe->nr_accounted on the pipe
itself, due to the if (!pipe_has_watch_queue()) test in
pipe_resize_ring(). This means that when the pipe is ultimately freed,
we decrement user->pipe_bufs by something other than what than we had
charged to it, potentially leading to an underflow. This in turn can
cause subsequent too_many_pipe_buffers_soft() tests to fail with -EPERM.
To remedy this, explicitly account for the pipe usage in
watch_queue_set_size() to match the number set via account_pipe_buffers()
(It's unclear why watch_queue_set_size() does not update nr_accounted;
it may be due to intentional overprovisioning in watch_queue_set_size()?)
Fixes: e95aada4cb93d ("pipe: wakeup wr_wait after setting max_usage")
Signed-off-by: Eric Sandeen <sandeen(a)redhat.com>
Link: https://lore.kernel.org/r/206682a8-0604-49e5-8224-fdbe0c12b460@redhat.com
Signed-off-by: Christian Brauner <brauner(a)kernel.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Yin Tirui <yintirui(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
---
kernel/watch_queue.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c
index 73717917d816..37da8647b4ec 100644
--- a/kernel/watch_queue.c
+++ b/kernel/watch_queue.c
@@ -274,6 +274,15 @@ long watch_queue_set_size(struct pipe_inode_info *pipe, unsigned int nr_notes)
if (ret < 0)
goto error;
+ /*
+ * pipe_resize_ring() does not update nr_accounted for watch_queue
+ * pipes, because the above vastly overprovisions. Set nr_accounted on
+ * and max_usage this pipe to the number that was actually charged to
+ * the user above via account_pipe_buffers.
+ */
+ pipe->max_usage = nr_pages;
+ pipe->nr_accounted = nr_pages;
+
ret = -ENOMEM;
pages = kcalloc(sizeof(struct page *), nr_pages, GFP_KERNEL);
if (!pages)
--
2.22.0
2
1
V2: Set CONFIG_FUSE_PASSTHROUGH=y in openeuler_defconfig.
Amir Goldstein (57):
fs: rename __mnt_{want,drop}_write*() helpers
fs: export mnt_{get,put}_write_access() to modules
fuse: factor out helper fuse_truncate_update_attr()
fuse: allocate ff->release_args only if release is needed
fuse: break up fuse_open_common()
fuse: prepare for failing open response
fuse: introduce inode io modes
fuse: allow parallel dio writes with FUSE_DIRECT_IO_ALLOW_MMAP
ovl: use simpler function to convert iocb to rw flags
ovl: propagate IOCB_APPEND flag on writes to realfile
ovl: punt write aio completion to workqueue
ovl: protect copying of realinode attributes to ovl inode
fs: get mnt_writers count for an open backing file's real path
fs: create helper file_user_path() for user displayed mapped file path
fs: store real path instead of fake path in backing file f_path
ovl: add helper ovl_file_modified()
ovl: split ovl_want_write() into two helpers
ovl: reorder ovl_want_write() after ovl_inode_lock()
ovl: do not open/llseek lower file with upper sb_writers held
ovl: do not encode lower fh with upper sb_writers held
ovl: add permission hooks outside of do_splice_direct()
splice: remove permission hook from do_splice_direct()
splice: move permission hook out of splice_direct_to_actor()
splice: move permission hook out of splice_file_to_pipe()
splice: remove permission hook from iter_file_splice_write()
remap_range: move permission hooks out of do_clone_file_range()
remap_range: move file_start_write() to after permission hook
btrfs: move file_start_write() to after permission hook
coda: change locking order in coda_file_write_iter()
fs: move file_start_write() into vfs_iter_write()
fs: move permission hook out of do_iter_write()
fs: move permission hook out of do_iter_read()
fs: move kiocb_start_write() into vfs_iocb_iter_write()
fs: create __sb_write_started() helper
fs: create file_write_started() helper
fs: create {sb,file}_write_not_started() helpers
fs: prepare for stackable filesystems backing file helpers
fs: factor out backing_file_{read,write}_iter() helpers
fs: factor out backing_file_splice_{read,write}() helpers
fs: factor out backing_file_mmap() helper
fuse: factor out helper for FUSE_DEV_IOC_CLONE
fuse: introduce FUSE_PASSTHROUGH capability
fuse: implement ioctls to manage backing files
fuse: prepare for opening file in passthrough mode
fuse: implement open in passthrough mode
fuse: implement read/write passthrough
fuse: implement splice read/write passthrough
fuse: implement passthrough for mmap
fuse: fix wrong ff->iomode state changes from parallel dio write
fuse: fix parallel dio write on file open in passthrough mode
fuse: verify zero padding in fuse_backing_map
fuse: respect FOPEN_KEEP_CACHE on opendir
ovl: fix dentry reference leak after changes to underlying layers
ovl: relax WARN_ON in ovl_verify_area()
remap_range: merge do_clone_file_range() into vfs_clone_file_range()
fs: pass offset and result to backing_file end_write() callback
fuse: update inode size after extending passthrough write
Bernd Schubert (3):
fuse: create helper function if DIO write needs exclusive lock
fuse: add fuse_dio_lock/unlock helper functions
fuse: disable the combination of passthrough and writeback cache
Ed Tsai (1):
backing-file: convert to using fops->splice_write
Vegard Nossum (1):
fs: fix __sb_write_started() kerneldoc formatting
yangyun (1):
fuse: use exclusive lock when FUSE_I_CACHE_IO_MODE is set
fs/fuse/fuse_i.h | 151 +++++++++++--
fs/internal.h | 21 +-
fs/overlayfs/overlayfs.h | 38 +++-
include/linux/backing-file.h | 42 ++++
include/linux/fs.h | 89 ++++++--
include/linux/fsnotify.h | 3 +-
include/linux/mount.h | 4 +-
include/uapi/linux/fuse.h | 23 +-
arch/arc/kernel/troubleshoot.c | 6 +-
drivers/block/loop.c | 2 -
drivers/target/target_core_file.c | 10 +-
fs/backing-file.c | 339 ++++++++++++++++++++++++++++
fs/btrfs/ioctl.c | 12 +-
fs/cachefiles/io.c | 5 +-
fs/coda/file.c | 2 -
fs/file_table.c | 12 +-
fs/fuse/dev.c | 98 +++++---
fs/fuse/dir.c | 49 +++-
fs/fuse/file.c | 362 ++++++++++++++++++++----------
fs/fuse/inode.c | 37 +++
fs/fuse/iomode.c | 276 +++++++++++++++++++++++
fs/fuse/passthrough.c | 355 +++++++++++++++++++++++++++++
fs/inode.c | 8 +-
fs/namespace.c | 36 +--
fs/nfsd/vfs.c | 7 +-
fs/open.c | 70 +++---
fs/overlayfs/copy_up.c | 168 +++++++++-----
fs/overlayfs/dir.c | 60 +++--
fs/overlayfs/export.c | 7 +-
fs/overlayfs/file.c | 230 ++++---------------
fs/overlayfs/inode.c | 57 +++--
fs/overlayfs/namei.c | 37 ++-
fs/overlayfs/super.c | 47 ++--
fs/overlayfs/util.c | 75 ++++++-
fs/proc/base.c | 2 +-
fs/proc/nommu.c | 2 +-
fs/proc/task_mmu.c | 4 +-
fs/proc/task_nommu.c | 2 +-
fs/read_write.c | 156 ++++++++-----
fs/remap_range.c | 44 ++--
fs/splice.c | 82 ++++---
fs/super.c | 1 +
kernel/acct.c | 4 +-
kernel/trace/trace_output.c | 2 +-
MAINTAINERS | 9 +
fs/Kconfig | 4 +
fs/Makefile | 1 +
fs/fuse/Kconfig | 11 +
fs/fuse/Makefile | 2 +
fs/overlayfs/Kconfig | 1 +
50 files changed, 2290 insertions(+), 775 deletions(-)
create mode 100644 include/linux/backing-file.h
create mode 100644 fs/backing-file.c
create mode 100644 fs/fuse/iomode.c
create mode 100644 fs/fuse/passthrough.c
--
2.39.2
2
64

[openeuler:openEuler-1.0-LTS 1614/1614] include/trace/trace_events.h:26:23: warning: 'str__fs__trace_system_name' defined but not used
by kernel test robot 07 May '25
by kernel test robot 07 May '25
07 May '25
tree: https://gitee.com/openeuler/kernel.git openEuler-1.0-LTS
head: ac2dbcb2630a54db6d68c792a6cfff34c6bd5232
commit: a4f256bae217c9679528b4957b6dc68e52cd4782 [1614/1614] vfs: add bare tracepoints for vfs read and release
config: arm64-randconfig-001-20250506 (https://download.01.org/0day-ci/archive/20250507/202505070314.0zdCBK7T-lkp@…)
compiler: aarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250507/202505070314.0zdCBK7T-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505070314.0zdCBK7T-lkp@intel.com/
All warnings (new ones prefixed by >>):
fs/read_write.c:483:9: warning: no previous prototype for '__vfs_write' [-Wmissing-prototypes]
483 | ssize_t __vfs_write(struct file *file, const char __user *p, size_t count,
| ^~~~~~~~~~~
In file included from include/trace/define_trace.h:96,
from include/trace/events/fs.h:33,
from fs/read_write.c:28:
>> include/trace/trace_events.h:26:23: warning: 'str__fs__trace_system_name' defined but not used [-Wunused-const-variable=]
26 | #define __app__(x, y) str__##x##y
| ^~~~~
include/trace/trace_events.h:27:21: note: in expansion of macro '__app__'
27 | #define __app(x, y) __app__(x, y)
| ^~~~~~~
include/trace/trace_events.h:29:29: note: in expansion of macro '__app'
29 | #define TRACE_SYSTEM_STRING __app(TRACE_SYSTEM_VAR,__trace_system_name)
| ^~~~~
include/trace/trace_events.h:32:27: note: in expansion of macro 'TRACE_SYSTEM_STRING'
32 | static const char TRACE_SYSTEM_STRING[] = \
| ^~~~~~~~~~~~~~~~~~~
include/trace/trace_events.h:35:1: note: in expansion of macro 'TRACE_MAKE_SYSTEM_STR'
35 | TRACE_MAKE_SYSTEM_STR();
| ^~~~~~~~~~~~~~~~~~~~~
fs/read_write.c:90: warning: Function parameter or member 'maxsize' not described in 'generic_file_llseek_size'
fs/read_write.c:90: warning: Excess function parameter 'size' description in 'generic_file_llseek_size'
vim +/str__fs__trace_system_name +26 include/trace/trace_events.h
acd388fd3af350 include/trace/ftrace.h Steven Rostedt (Red Hat 2015-03-31 25)
acd388fd3af350 include/trace/ftrace.h Steven Rostedt (Red Hat 2015-03-31 @26) #define __app__(x, y) str__##x##y
acd388fd3af350 include/trace/ftrace.h Steven Rostedt (Red Hat 2015-03-31 27) #define __app(x, y) __app__(x, y)
acd388fd3af350 include/trace/ftrace.h Steven Rostedt (Red Hat 2015-03-31 28)
:::::: The code at line 26 was first introduced by commit
:::::: acd388fd3af350ab24c6ab6f19b83fc4a4f3aa60 tracing: Give system name a pointer
:::::: TO: Steven Rostedt (Red Hat) <rostedt(a)goodmis.org>
:::::: CC: Steven Rostedt <rostedt(a)goodmis.org>
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-6.6 2200/2200] drivers/vhost/vdpa.c:589:23: error: implicit declaration of function 'iommufd_ctx_from_fd'; did you mean 'iommufd_ctx_from_file'?
by kernel test robot 07 May '25
by kernel test robot 07 May '25
07 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: 9af1041f05d76435457d805d2d60c2aea1dc71f2
commit: 6a58b8be556fb7de52ae0272a994a1c73fffc903 [2200/2200] vhost/vdpa: Add support to bind and attach iommufd
config: x86_64-buildonly-randconfig-006-20250506 (https://download.01.org/0day-ci/archive/20250507/202505070025.y1C68ZCV-lkp@…)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250507/202505070025.y1C68ZCV-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505070025.y1C68ZCV-lkp@intel.com/
All error/warnings (new ones prefixed by >>):
drivers/vhost/vdpa.c: In function 'vhost_vdpa_bind_iommufd':
>> drivers/vhost/vdpa.c:589:23: error: implicit declaration of function 'iommufd_ctx_from_fd'; did you mean 'iommufd_ctx_from_file'? [-Werror=implicit-function-declaration]
589 | iommufd_ctx = iommufd_ctx_from_fd(bind.iommufd);
| ^~~~~~~~~~~~~~~~~~~
| iommufd_ctx_from_file
>> drivers/vhost/vdpa.c:589:21: warning: assignment to 'struct iommufd_ctx *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
589 | iommufd_ctx = iommufd_ctx_from_fd(bind.iommufd);
| ^
cc1: some warnings being treated as errors
Kconfig warnings: (for reference only)
WARNING: unmet direct dependencies detected for PTP_1588_CLOCK
Depends on [n]: NET [=y] && POSIX_TIMERS [=n]
Selected by [y]:
- SXE [=y] && NETDEVICES [=y] && ETHERNET [=y] && NET_VENDOR_LINKDATA [=y] && (X86 [=y] || ARM64) && PCI [=y]
- SXE_VF [=y] && NETDEVICES [=y] && ETHERNET [=y] && NET_VENDOR_LINKDATA [=y] && (X86 [=y] || ARM64) && PCI [=y]
vim +589 drivers/vhost/vdpa.c
576
577 static long vhost_vdpa_bind_iommufd(struct vhost_vdpa *v, int __user *argp)
578 {
579 struct vhost_vdpa_bind_iommufd bind;
580 struct iommufd_ctx *iommufd_ctx;
581 struct iommufd_device *idev;
582 struct device *dma_dev = vdpa_get_dma_dev(v->vdpa);
583 struct iommu_group *iommu_group = iommu_group_get(dma_dev);
584 int ret = 0;
585
586 if (copy_from_user(&bind, argp, sizeof(bind)))
587 return -EFAULT;
588
> 589 iommufd_ctx = iommufd_ctx_from_fd(bind.iommufd);
590 if (IS_ERR(iommufd_ctx))
591 return PTR_ERR(iommufd_ctx);
592
593 if (v->domain) {
594 iommu_detach_device(v->domain, dma_dev);
595 iommu_domain_free(v->domain);
596 v->domain = NULL;
597 }
598
599 /**
600 * Default iommu domain is created when vdpa device driver probes.
601 * Unuse default domain first to avoid failure when claiming dma owner.
602 */
603 if (dma_dev->bus && dma_dev->bus->dma_cleanup)
604 dma_dev->bus->dma_cleanup(dma_dev);
605 ret = iommu_group_claim_dma_owner(iommu_group, iommufd_ctx);
606 if (ret)
607 goto dma_configure;
608
609 idev = iommufd_device_bind(iommufd_ctx, dma_dev, &bind.out_devid);
610 if (IS_ERR(idev)) {
611 ret = PTR_ERR(idev);
612 goto release_owner;
613 }
614 v->iommufd_dev = idev;
615
616 if (copy_to_user(argp, &bind, sizeof(bind))) {
617 ret = -EFAULT;
618 goto unbind;
619 }
620
621 goto out;
622
623 unbind:
624 iommufd_device_unbind(v->iommufd_dev);
625 v->iommufd_dev = NULL;
626 release_owner:
627 iommu_group_release_dma_owner(iommu_group);
628 dma_configure:
629 if (dma_dev->bus && dma_dev->bus->dma_configure)
630 dma_dev->bus->dma_configure(dma_dev);
631 out:
632 iommufd_ctx_put(iommufd_ctx);
633 return ret;
634 }
635
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-5.10 2888/2888] include/linux/minmax.h:20:35: warning: comparison of distinct pointer types lacks a cast
by kernel test robot 06 May '25
by kernel test robot 06 May '25
06 May '25
Hi SeongJae,
FYI, the error/warning still remains.
tree: https://gitee.com/openeuler/kernel.git OLK-5.10
head: f5912cbd669a2722f81f0f054fb8aec1525da8ee
commit: 83b931be40b2829e20f38356509d8706ea6b6238 [2888/2888] mm/damon/core-test: test damon_set_regions
config: x86_64-buildonly-randconfig-006-20250506 (https://download.01.org/0day-ci/archive/20250506/202505062356.u2rMcCQF-lkp@…)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250506/202505062356.u2rMcCQF-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505062356.u2rMcCQF-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from include/linux/kernel.h:14,
from arch/x86/include/asm/percpu.h:27,
from arch/x86/include/asm/current.h:6,
from include/linux/mutex.h:14,
from include/linux/damon.h:11,
from mm/damon/core.c:10:
mm/damon/core-test.h: In function 'damon_test_set_regions':
>> include/linux/minmax.h:20:35: warning: comparison of distinct pointer types lacks a cast
20 | (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))
| ^~
include/kunit/test.h:748:16: note: in expansion of macro '__typecheck'
748 | ((void)__typecheck(__left, __right)); \
| ^~~~~~~~~~~
include/kunit/test.h:772:9: note: in expansion of macro 'KUNIT_BASE_BINARY_ASSERTION'
772 | KUNIT_BASE_BINARY_ASSERTION(test, \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/kunit/test.h:861:9: note: in expansion of macro 'KUNIT_BASE_EQ_MSG_ASSERTION'
861 | KUNIT_BASE_EQ_MSG_ASSERTION(test, \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/kunit/test.h:871:9: note: in expansion of macro 'KUNIT_BINARY_EQ_MSG_ASSERTION'
871 | KUNIT_BINARY_EQ_MSG_ASSERTION(test, \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/kunit/test.h:1234:9: note: in expansion of macro 'KUNIT_BINARY_EQ_ASSERTION'
1234 | KUNIT_BINARY_EQ_ASSERTION(test, KUNIT_EXPECTATION, left, right)
| ^~~~~~~~~~~~~~~~~~~~~~~~~
mm/damon/core-test.h:284:9: note: in expansion of macro 'KUNIT_EXPECT_EQ'
284 | KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 3);
| ^~~~~~~~~~~~~~~
vim +20 include/linux/minmax.h
cffb222bc2e032 Rikard Falkeborn 2021-06-07 6
b296a6d53339a7 Andy Shevchenko 2020-10-15 7 /*
b296a6d53339a7 Andy Shevchenko 2020-10-15 8 * min()/max()/clamp() macros must accomplish three things:
b296a6d53339a7 Andy Shevchenko 2020-10-15 9 *
b296a6d53339a7 Andy Shevchenko 2020-10-15 10 * - avoid multiple evaluations of the arguments (so side-effects like
b296a6d53339a7 Andy Shevchenko 2020-10-15 11 * "x++" happen only once) when non-constant.
b296a6d53339a7 Andy Shevchenko 2020-10-15 12 * - perform strict type-checking (to generate warnings instead of
b296a6d53339a7 Andy Shevchenko 2020-10-15 13 * nasty runtime surprises). See the "unnecessary" pointer comparison
b296a6d53339a7 Andy Shevchenko 2020-10-15 14 * in __typecheck().
b296a6d53339a7 Andy Shevchenko 2020-10-15 15 * - retain result as a constant expressions when called with only
b296a6d53339a7 Andy Shevchenko 2020-10-15 16 * constant expressions (to avoid tripping VLA warnings in stack
b296a6d53339a7 Andy Shevchenko 2020-10-15 17 * allocation usage).
b296a6d53339a7 Andy Shevchenko 2020-10-15 18 */
b296a6d53339a7 Andy Shevchenko 2020-10-15 19 #define __typecheck(x, y) \
b296a6d53339a7 Andy Shevchenko 2020-10-15 @20 (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))
b296a6d53339a7 Andy Shevchenko 2020-10-15 21
:::::: The code at line 20 was first introduced by commit
:::::: b296a6d53339a79082c1d2c1761e948e8b3def69 kernel.h: split out min()/max() et al. helpers
:::::: TO: Andy Shevchenko <andriy.shevchenko(a)linux.intel.com>
:::::: CC: Linus Torvalds <torvalds(a)linux-foundation.org>
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

06 May '25
From: Schspa Shi <schspa(a)gmail.com>
mainline inclusion
from mainline-v5.19-rc1
commit 310862e574001a97ad02272bac0fd13f75f42a27
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBP35K
CVE: CVE-2022-49385
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
When driver_attach(drv); failed, the driver_private will be freed.
But it has been added to the bus, which caused a UAF.
To fix it, we need to delete it from the bus when failed.
Fixes: 190888ac01d0 ("driver core: fix possible missing of device probe")
Signed-off-by: Schspa Shi <schspa(a)gmail.com>
Link: https://lore.kernel.org/r/20220513112444.45112-1-schspa@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Conflicts:
drivers/base/bus.c
[Fixing conflicts]
Signed-off-by: Tirui Yin <yintirui(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
---
drivers/base/bus.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 5f1966081c42..f45506c56c33 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -661,7 +661,7 @@ int bus_add_driver(struct device_driver *drv)
} else {
error = driver_attach(drv);
if (error)
- goto out_unregister;
+ goto out_del_list;
}
}
module_add_driver(drv->owner, drv);
@@ -689,6 +689,8 @@ int bus_add_driver(struct device_driver *drv)
return 0;
+out_del_list:
+ klist_del(&priv->knode_bus);
out_unregister:
kobject_put(&priv->kobj);
/* drv->p is freed in driver_release() */
--
2.22.0
2
1

[PATCH openEuler-1.0-LTS] [Backport] scsi: pm8001: Fix abort all task initialization
by Lin Ruifeng 06 May '25
by Lin Ruifeng 06 May '25
06 May '25
From: Damien Le Moal <damien.lemoal(a)opensource.wdc.com>
stable inclusion
from stable-v4.19.238
commit 1824a21b2cedc5774a5adfa74f5f7b90472d8677
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBP73H
CVE: CVE-2022-49217
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 7f12845c8389855dbcc67baa068b6832dc4a396e ]
In pm80xx_send_abort_all(), the n_elem field of the ccb used is not
initialized to 0. This missing initialization sometimes lead to the task
completion path seeing the ccb with a non-zero n_elem resulting in the
execution of invalid dma_unmap_sg() calls in pm8001_ccb_task_free(),
causing a crash such as:
[ 197.676341] RIP: 0010:iommu_dma_unmap_sg+0x6d/0x280
[ 197.700204] RSP: 0018:ffff889bbcf89c88 EFLAGS: 00010012
[ 197.705485] RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffff83d0bda0
[ 197.712687] RDX: 0000000000000002 RSI: 0000000000000000 RDI: ffff88810dffc0d0
[ 197.719887] RBP: 0000000000000000 R08: 0000000000000000 R09: ffff8881c790098b
[ 197.727089] R10: ffffed1038f20131 R11: 0000000000000001 R12: 0000000000000000
[ 197.734296] R13: ffff88810dffc0d0 R14: 0000000000000010 R15: 0000000000000000
[ 197.741493] FS: 0000000000000000(0000) GS:ffff889bbcf80000(0000) knlGS:0000000000000000
[ 197.749659] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 197.755459] CR2: 00007f16c1b42734 CR3: 0000000004814000 CR4: 0000000000350ee0
[ 197.762656] Call Trace:
[ 197.765127] <IRQ>
[ 197.767162] pm8001_ccb_task_free+0x5f1/0x820 [pm80xx]
[ 197.772364] ? do_raw_spin_unlock+0x54/0x220
[ 197.776680] pm8001_mpi_task_abort_resp+0x2ce/0x4f0 [pm80xx]
[ 197.782406] process_oq+0xe85/0x7890 [pm80xx]
[ 197.786817] ? lock_acquire+0x194/0x490
[ 197.790697] ? handle_irq_event+0x10e/0x1b0
[ 197.794920] ? mpi_sata_completion+0x2d70/0x2d70 [pm80xx]
[ 197.800378] ? __wake_up_bit+0x100/0x100
[ 197.804340] ? lock_is_held_type+0x98/0x110
[ 197.808565] pm80xx_chip_isr+0x94/0x130 [pm80xx]
[ 197.813243] tasklet_action_common.constprop.0+0x24b/0x2f0
[ 197.818785] __do_softirq+0x1b5/0x82d
[ 197.822485] ? do_raw_spin_unlock+0x54/0x220
[ 197.826799] __irq_exit_rcu+0x17e/0x1e0
[ 197.830678] irq_exit_rcu+0xa/0x20
[ 197.834114] common_interrupt+0x78/0x90
[ 197.840051] </IRQ>
[ 197.844236] <TASK>
[ 197.848397] asm_common_interrupt+0x1e/0x40
Avoid this issue by always initializing the ccb n_elem field to 0 in
pm8001_send_abort_all(), pm8001_send_read_log() and
pm80xx_send_abort_all().
Link: https://lore.kernel.org/r/20220220031810.738362-17-damien.lemoal@opensource…
Fixes: c6b9ef5779c3 ("[SCSI] pm80xx: NCQ error handling changes")
Reviewed-by: Jack Wang <jinpu.wang(a)ionos.com>
Signed-off-by: Damien Le Moal <damien.lemoal(a)opensource.wdc.com>
Signed-off-by: Martin K. Petersen <martin.petersen(a)oracle.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Lin Ruifeng <linruifeng4(a)huawei.com>
---
drivers/scsi/pm8001/pm8001_hwi.c | 2 ++
drivers/scsi/pm8001/pm80xx_hwi.c | 1 +
2 files changed, 3 insertions(+)
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 3e814c0469fb..0c943189b3ba 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -1748,6 +1748,7 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
ccb->device = pm8001_ha_dev;
ccb->ccb_tag = ccb_tag;
ccb->task = task;
+ ccb->n_elem = 0;
circularQ = &pm8001_ha->inbnd_q_tbl[0];
@@ -1810,6 +1811,7 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
ccb->device = pm8001_ha_dev;
ccb->ccb_tag = ccb_tag;
ccb->task = task;
+ ccb->n_elem = 0;
pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG;
pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG;
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 327992fbb553..1bc13452276d 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -1435,6 +1435,7 @@ static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha,
ccb->device = pm8001_ha_dev;
ccb->ccb_tag = ccb_tag;
ccb->task = task;
+ ccb->n_elem = 0;
circularQ = &pm8001_ha->inbnd_q_tbl[0];
--
2.22.0
2
1

[PATCH openEuler-1.0-LTS] [Backport] video: fbdev: cirrusfb: check pixclock to avoid divide by zero
by Lin Ruifeng 06 May '25
by Lin Ruifeng 06 May '25
06 May '25
From: George Kennedy <george.kennedy(a)oracle.com>
stable inclusion
from stable-v4.19.238
commit 40b13e3d85744210db13457785646634e2d056bd
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBP6SB
CVE: CVE-2021-47641
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 5c6f402bdcf9e7239c6bc7087eda71ac99b31379 ]
Do a sanity check on pixclock value to avoid divide by zero.
If the pixclock value is zero, the cirrusfb driver will round up
pixclock to get the derived frequency as close to maxclock as
possible.
Syzkaller reported a divide error in cirrusfb_check_pixclock.
divide error: 0000 [#1] SMP KASAN PTI
CPU: 0 PID: 14938 Comm: cirrusfb_test Not tainted 5.15.0-rc6 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.0-2
RIP: 0010:cirrusfb_check_var+0x6f1/0x1260
Call Trace:
fb_set_var+0x398/0xf90
do_fb_ioctl+0x4b8/0x6f0
fb_ioctl+0xeb/0x130
__x64_sys_ioctl+0x19d/0x220
do_syscall_64+0x3a/0x80
entry_SYSCALL_64_after_hwframe+0x44/0xae
Signed-off-by: George Kennedy <george.kennedy(a)oracle.com>
Reviewed-by: Geert Uytterhoeven <geert(a)linux-m68k.org>
Signed-off-by: Helge Deller <deller(a)gmx.de>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Lin Ruifeng <linruifeng4(a)huawei.com>
---
drivers/video/fbdev/cirrusfb.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/video/fbdev/cirrusfb.c b/drivers/video/fbdev/cirrusfb.c
index b3be06dd2908..72358d187023 100644
--- a/drivers/video/fbdev/cirrusfb.c
+++ b/drivers/video/fbdev/cirrusfb.c
@@ -470,7 +470,7 @@ static int cirrusfb_check_mclk(struct fb_info *info, long freq)
return 0;
}
-static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var,
+static int cirrusfb_check_pixclock(struct fb_var_screeninfo *var,
struct fb_info *info)
{
long freq;
@@ -479,9 +479,7 @@ static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var,
unsigned maxclockidx = var->bits_per_pixel >> 3;
/* convert from ps to kHz */
- freq = PICOS2KHZ(var->pixclock);
-
- dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq);
+ freq = PICOS2KHZ(var->pixclock ? : 1);
maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
cinfo->multiplexing = 0;
@@ -489,11 +487,13 @@ static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var,
/* If the frequency is greater than we can support, we might be able
* to use multiplexing for the video mode */
if (freq > maxclock) {
- dev_err(info->device,
- "Frequency greater than maxclock (%ld kHz)\n",
- maxclock);
- return -EINVAL;
+ var->pixclock = KHZ2PICOS(maxclock);
+
+ while ((freq = PICOS2KHZ(var->pixclock)) > maxclock)
+ var->pixclock++;
}
+ dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq);
+
/*
* Additional constraint: 8bpp uses DAC clock doubling to allow maximum
* pixel clock
--
2.22.0
2
1

06 May '25
From: Vincent Mailhol <mailhol.vincent(a)wanadoo.fr>
stable inclusion
from stable-v4.19.171
commit 5408824636fa0dfedb9ecb0d94abd573131bfbbe
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC21UY
CVE: CVE-2021-47670
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 50aca891d7a554db0901b245167cd653d73aaa71 ]
After calling peak_usb_netif_rx_ni(skb), dereferencing skb is unsafe.
Especially, the can_frame cf which aliases skb memory is accessed
after the peak_usb_netif_rx_ni().
Reordering the lines solves the issue.
Fixes: 0a25e1f4f185 ("can: peak_usb: add support for PEAK new CANFD USB adapters")
Link: https://lore.kernel.org/r/20210120114137.200019-4-mailhol.vincent@wanadoo.fr
Signed-off-by: Vincent Mailhol <mailhol.vincent(a)wanadoo.fr>
Signed-off-by: Marc Kleine-Budde <mkl(a)pengutronix.de>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Zhang Changzhong <zhangchangzhong(a)huawei.com>
---
drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 4198835..87574ce 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -514,11 +514,11 @@ static int pcan_usb_fd_decode_canmsg(struct pcan_usb_fd_if *usb_if,
else
memcpy(cfd->data, rm->d, cfd->len);
- peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(rm->ts_low));
-
netdev->stats.rx_packets++;
netdev->stats.rx_bytes += cfd->len;
+ peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(rm->ts_low));
+
return 0;
}
@@ -574,11 +574,11 @@ static int pcan_usb_fd_decode_status(struct pcan_usb_fd_if *usb_if,
if (!skb)
return -ENOMEM;
- peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(sm->ts_low));
-
netdev->stats.rx_packets++;
netdev->stats.rx_bytes += cf->can_dlc;
+ peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(sm->ts_low));
+
return 0;
}
--
2.9.5
2
1
From: Schspa Shi <schspa(a)gmail.com>
mainline inclusion
from mainline-v5.19-rc1
commit 310862e574001a97ad02272bac0fd13f75f42a27
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBP35K
CVE: CVE-2022-49385
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
When driver_attach(drv); failed, the driver_private will be freed.
But it has been added to the bus, which caused a UAF.
To fix it, we need to delete it from the bus when failed.
Fixes: 190888ac01d0 ("driver core: fix possible missing of device probe")
Signed-off-by: Schspa Shi <schspa(a)gmail.com>
Link: https://lore.kernel.org/r/20220513112444.45112-1-schspa@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Yin Tirui <yintirui(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
---
drivers/base/bus.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 5f1966081c42..f45506c56c33 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -661,7 +661,7 @@ int bus_add_driver(struct device_driver *drv)
} else {
error = driver_attach(drv);
if (error)
- goto out_unregister;
+ goto out_del_list;
}
}
module_add_driver(drv->owner, drv);
@@ -689,6 +689,8 @@ int bus_add_driver(struct device_driver *drv)
return 0;
+out_del_list:
+ klist_del(&priv->knode_bus);
out_unregister:
kobject_put(&priv->kobj);
/* drv->p is freed in driver_release() */
--
2.22.0
1
0

06 May '25
From: Eric Dumazet <edumazet(a)google.com>
mainline inclusion
from mainline-v6.14-rc3
commit 087c1faa594fa07a66933d750c0b2610aa1a2946
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBPC5R
CVE: CVE-2025-21759
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
igmp6_send() can be called without RTNL or RCU being held.
Extend RCU protection so that we can safely fetch the net pointer
and avoid a potential UAF.
Note that we no longer can use sock_alloc_send_skb() because
ipv6.igmp_sk uses GFP_KERNEL allocations which can sleep.
Instead use alloc_skb() and charge the net->ipv6.igmp_sk
socket under RCU protection.
Fixes: b8ad0cbc58f7 ("[NETNS][IPV6] mcast - handle several network namespace")
Signed-off-by: Eric Dumazet <edumazet(a)google.com>
Reviewed-by: David Ahern <dsahern(a)kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu(a)amazon.com>
Link: https://patch.msgid.link/20250207135841.1948589-9-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Conflicts:
net/ipv6/mcast.c
[commit b4a11b2033b7 separates OUTREQUESTS stastic from MIB_OUT,
which not merged lead to context conflicts. commit 2e7ef287f07c
convert from timer to delayed work. Because this patch was not
merged, we use GFP_ATOMIC flag]
Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com>
---
net/ipv6/mcast.c | 33 +++++++++++++++------------------
1 file changed, 15 insertions(+), 18 deletions(-)
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 9fb5077f8e9a..e0d5125de202 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1974,21 +1974,21 @@ static void mld_send_cr(struct inet6_dev *idev)
static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
{
- struct net *net = dev_net(dev);
- struct sock *sk = net->ipv6.igmp_sk;
+ const struct in6_addr *snd_addr, *saddr;
+ int err, len, payload_len, full_len;
+ struct in6_addr addr_buf;
struct inet6_dev *idev;
struct sk_buff *skb;
struct mld_msg *hdr;
- const struct in6_addr *snd_addr, *saddr;
- struct in6_addr addr_buf;
int hlen = LL_RESERVED_SPACE(dev);
int tlen = dev->needed_tailroom;
- int err, len, payload_len, full_len;
u8 ra[8] = { IPPROTO_ICMPV6, 0,
IPV6_TLV_ROUTERALERT, 2, 0, 0,
IPV6_TLV_PADN, 0 };
- struct flowi6 fl6;
struct dst_entry *dst;
+ struct flowi6 fl6;
+ struct net *net;
+ struct sock *sk;
if (type == ICMPV6_MGM_REDUCTION)
snd_addr = &in6addr_linklocal_allrouters;
@@ -1999,20 +1999,20 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
payload_len = len + sizeof(ra);
full_len = sizeof(struct ipv6hdr) + payload_len;
- rcu_read_lock();
- IP6_UPD_PO_STATS(net, __in6_dev_get(dev),
- IPSTATS_MIB_OUT, full_len);
- rcu_read_unlock();
-
- skb = sock_alloc_send_skb(sk, hlen + tlen + full_len, 1, &err);
+ skb = alloc_skb(hlen + tlen + full_len, GFP_ATOMIC);
+ rcu_read_lock();
+ net = dev_net_rcu(dev);
+ idev = __in6_dev_get(dev);
+ IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, full_len);
if (!skb) {
- rcu_read_lock();
- IP6_INC_STATS(net, __in6_dev_get(dev),
- IPSTATS_MIB_OUTDISCARDS);
+ IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
rcu_read_unlock();
return;
}
+ sk = net->ipv6.igmp_sk;
+ skb_set_owner_w(skb, sk);
+
skb->priority = TC_PRIO_CONTROL;
skb_reserve(skb, hlen);
@@ -2037,9 +2037,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
IPPROTO_ICMPV6,
csum_partial(hdr, len, 0));
- rcu_read_lock();
- idev = __in6_dev_get(skb->dev);
-
icmpv6_flow_init(sk, &fl6, type,
&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
skb->dev->ifindex);
--
2.25.1
2
1

[PATCH openEuler-1.0-LTS v2] ipv6: mcast: extend RCU protection in igmp6_send()
by Dong Chenchen 06 May '25
by Dong Chenchen 06 May '25
06 May '25
From: Eric Dumazet <edumazet(a)google.com>
mainline inclusion
from mainline-v6.14-rc3
commit 087c1faa594fa07a66933d750c0b2610aa1a2946
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBPC5R
CVE: CVE-2025-21759
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
igmp6_send() can be called without RTNL or RCU being held.
Extend RCU protection so that we can safely fetch the net pointer
and avoid a potential UAF.
Note that we no longer can use sock_alloc_send_skb() because
ipv6.igmp_sk uses GFP_KERNEL allocations which can sleep.
Instead use alloc_skb() and charge the net->ipv6.igmp_sk
socket under RCU protection.
Fixes: b8ad0cbc58f7 ("[NETNS][IPV6] mcast - handle several network namespace")
Signed-off-by: Eric Dumazet <edumazet(a)google.com>
Reviewed-by: David Ahern <dsahern(a)kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu(a)amazon.com>
Link: https://patch.msgid.link/20250207135841.1948589-9-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Conflicts:
net/ipv6/mcast.c
[commit b4a11b2033b7 separates OUTREQUESTS stastic from MIB_OUT,
which not merged lead to context conflicts. commit 2e7ef287f07c
convert from timer to delayed work. Because this patch was not
merged, we use GFP_ATOMIC flag]
Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com>
---
net/ipv6/mcast.c | 33 +++++++++++++++------------------
1 file changed, 15 insertions(+), 18 deletions(-)
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 3d048401141f..bb484fe27e13 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1979,21 +1979,21 @@ static void mld_send_cr(struct inet6_dev *idev)
static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
{
- struct net *net = dev_net(dev);
- struct sock *sk = net->ipv6.igmp_sk;
+ const struct in6_addr *snd_addr, *saddr;
+ int err, len, payload_len, full_len;
+ struct in6_addr addr_buf;
struct inet6_dev *idev;
struct sk_buff *skb;
struct mld_msg *hdr;
- const struct in6_addr *snd_addr, *saddr;
- struct in6_addr addr_buf;
int hlen = LL_RESERVED_SPACE(dev);
int tlen = dev->needed_tailroom;
- int err, len, payload_len, full_len;
u8 ra[8] = { IPPROTO_ICMPV6, 0,
IPV6_TLV_ROUTERALERT, 2, 0, 0,
IPV6_TLV_PADN, 0 };
- struct flowi6 fl6;
struct dst_entry *dst;
+ struct flowi6 fl6;
+ struct net *net;
+ struct sock *sk;
if (type == ICMPV6_MGM_REDUCTION)
snd_addr = &in6addr_linklocal_allrouters;
@@ -2004,20 +2004,20 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
payload_len = len + sizeof(ra);
full_len = sizeof(struct ipv6hdr) + payload_len;
- rcu_read_lock();
- IP6_UPD_PO_STATS(net, __in6_dev_get(dev),
- IPSTATS_MIB_OUT, full_len);
- rcu_read_unlock();
-
- skb = sock_alloc_send_skb(sk, hlen + tlen + full_len, 1, &err);
+ skb = alloc_skb(hlen + tlen + full_len, GFP_ATOMIC);
+ rcu_read_lock();
+ net = dev_net_rcu(dev);
+ idev = __in6_dev_get(dev);
+ IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, full_len);
if (!skb) {
- rcu_read_lock();
- IP6_INC_STATS(net, __in6_dev_get(dev),
- IPSTATS_MIB_OUTDISCARDS);
+ IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
rcu_read_unlock();
return;
}
+ sk = net->ipv6.igmp_sk;
+ skb_set_owner_w(skb, sk);
+
skb->priority = TC_PRIO_CONTROL;
skb_reserve(skb, hlen);
@@ -2042,9 +2042,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
IPPROTO_ICMPV6,
csum_partial(hdr, len, 0));
- rcu_read_lock();
- idev = __in6_dev_get(skb->dev);
-
icmpv6_flow_init(sk, &fl6, type,
&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
skb->dev->ifindex);
--
2.25.1
2
1

[PATCH openEuler-1.0-LTS 0/7] driver: base: fix UAF when driver_attach failed
by Yin Tirui 06 May '25
by Yin Tirui 06 May '25
06 May '25
The following series contains seven patches that fix UAF when driver_attach failed:
Alexander Duyck (3):
driver core: Probe devices asynchronously instead of the driver
async: Add support for queueing on specific NUMA node
driver core: Attach devices on CPU local to device node
Jason Gunthorpe (1):
driver core: Pull required checks into driver_probe_device()
Mark-PK Tsai (1):
driver core: Prevent overriding async driver of a device before it
probe
Schspa Shi (1):
driver: base: fix UAF when driver_attach failed
Zhang Wensheng (1):
driver core: fix potential deadlock in __driver_attach
drivers/base/base.h | 2 ++
drivers/base/bus.c | 27 ++++----------
drivers/base/dd.c | 59 ++++++++++++++++++++++++-------
include/linux/async.h | 82 +++++++++++++++++++++++++++++++++++++++++--
kernel/async.c | 53 +++++++++++++++-------------
5 files changed, 163 insertions(+), 60 deletions(-)
--
2.22.0
2
8
CVE-2022-49755
Udipto Goswami (2):
usb: gadget: f_fs: Prevent race during ffs_ep0_queue_wait
usb: gadget: f_fs: Fix unbalanced spinlock in __ffs_ep0_queue_wait
Uttkarsh Aggarwal (1):
usb: gadget: f_fs: Add unbind event before functionfs_unbind
drivers/usb/gadget/function/f_fs.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
--
2.22.0
2
4

[PATCH OLK-6.6] Revert "tmpfs: fault in smaller chunks if large folio allocation not allowed"
by Tong Tiangen 06 May '25
by Tong Tiangen 06 May '25
06 May '25
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IC5K6D
--------------------------------
This reverts commit 7944c724e4b6bbc86dc7b8ce1f370584fc01fc1e.
Use the upstream community solution to fix the problem:
ede039b6e20f ("tmpfs: don't enable large folios if not supported")
Fixes: ede039b6e20f ("tmpfs: don't enable large folios if not supported")
Fixes: 7944c724e4b6 ("tmpfs: fault in smaller chunks if large folio allocation not allowed")
Signed-off-by: Tong Tiangen <tongtiangen(a)huawei.com>
---
include/linux/fs.h | 2 --
mm/filemap.c | 7 +------
mm/shmem.c | 5 -----
3 files changed, 1 insertion(+), 13 deletions(-)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 493c13cf7cd6..5e7aeb5ff463 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -373,8 +373,6 @@ enum rw_hint {
#define IOCB_DIO_CALLER_COMP (1 << 22)
/* kiocb is a read or write operation submitted by fs/aio.c. */
#define IOCB_AIO_RW (1 << 23)
-/* fault int small chunks(PAGE_SIZE) from userspace */
-#define IOCB_NO_LARGE_CHUNK (1 << 24)
/* for use in trace events */
#define TRACE_IOCB_STRINGS \
diff --git a/mm/filemap.c b/mm/filemap.c
index 63b8ef7f31b1..905ebca8670e 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -4050,14 +4050,9 @@ ssize_t generic_perform_write(struct kiocb *iocb, struct iov_iter *i)
loff_t pos = iocb->ki_pos;
struct address_space *mapping = file->f_mapping;
const struct address_space_operations *a_ops = mapping->a_ops;
+ size_t chunk = mapping_max_folio_size(mapping);
long status = 0;
ssize_t written = 0;
- size_t chunk;
-
- if (iocb->ki_flags & IOCB_NO_LARGE_CHUNK)
- chunk = PAGE_SIZE;
- else
- chunk = mapping_max_folio_size(mapping);
do {
struct page *page;
diff --git a/mm/shmem.c b/mm/shmem.c
index 6fdc7144ca91..aa50cd285ee9 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -3269,7 +3269,6 @@ static ssize_t shmem_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
- pgoff_t index = iocb->ki_pos >> PAGE_SHIFT;
ssize_t ret;
inode_lock(inode);
@@ -3282,10 +3281,6 @@ static ssize_t shmem_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
ret = file_update_time(file);
if (ret)
goto unlock;
-
- if (!shmem_allowable_huge_orders(inode, NULL, index, 0, false))
- iocb->ki_flags |= IOCB_NO_LARGE_CHUNK;
-
ret = generic_perform_write(iocb, from);
unlock:
inode_unlock(inode);
--
2.25.1
2
1
Jisoo Jang (1):
net: nfc: Fix use-after-free in local_cleanup()
net/nfc/llcp_core.c | 1 +
1 file changed, 1 insertion(+)
--
2.34.1
2
2
hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IC30P1
--------------------------------
Add cpu prefetch option under the resctrl fs.
Signed-off-by: Zeng Heng <zengheng4(a)huawei.com>
---
arch/arm64/include/asm/mpam.h | 15 +++++
arch/arm64/include/asm/thread_info.h | 4 ++
fs/resctrl/internal.h | 1 +
fs/resctrl/rdtgroup.c | 84 ++++++++++++++++++++++++++++
4 files changed, 104 insertions(+)
diff --git a/arch/arm64/include/asm/mpam.h b/arch/arm64/include/asm/mpam.h
index 9abe1fe58c34..ac7b6250250c 100644
--- a/arch/arm64/include/asm/mpam.h
+++ b/arch/arm64/include/asm/mpam.h
@@ -143,16 +143,31 @@ static inline void resctrl_arch_set_rmid(struct task_struct *tsk, u32 rmid)
#endif
}
+#define setbit(x, y) (x |= (1<<y))
+#define clrbit(x, y) (x &= ~(1<<y))
+
static inline void mpam_thread_switch(struct task_struct *tsk)
{
u64 oldregval;
int cpu = smp_processor_id();
u64 regval = mpam_get_regval(tsk);
+ u64 val, val1;
if (!IS_ENABLED(CONFIG_ARM64_MPAM) ||
!static_branch_likely(&mpam_enabled))
return;
+ asm volatile("mrs %0, S3_1_c15_c6_4" : "=r" (val));
+ val1 = val;
+
+ if (task_thread_info(tsk)->prefetch_dis)
+ setbit(val1, 0);
+ else
+ clrbit(val1, 0);
+
+ if (val1 != val)
+ asm volatile("msr S3_1_c15_c6_4, %0" : : "r"(val1));
+
if (regval == READ_ONCE(mpam_resctrl_default_group))
regval = READ_ONCE(per_cpu(arm64_mpam_default, cpu));
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 379d24059f5b..a996caebb08e 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -48,7 +48,11 @@ struct thread_info {
#endif
u32 cpu;
+#ifdef CONFIG_ARM64_MPAM
+ KABI_USE(1, u32 prefetch_dis)
+#else
KABI_RESERVE(1)
+#endif
KABI_RESERVE(2)
};
diff --git a/fs/resctrl/internal.h b/fs/resctrl/internal.h
index 839fbcf51ed2..b81edf76263d 100644
--- a/fs/resctrl/internal.h
+++ b/fs/resctrl/internal.h
@@ -173,6 +173,7 @@ struct rdtgroup {
struct mongroup mon;
enum rdtgrp_mode mode;
struct pseudo_lock_region *plr;
+ u32 prefetch_dis;
};
/* List of all resource groups */
diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index b1f127432b42..79334b36798f 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -975,6 +975,80 @@ static int rdtgroup_tasks_show(struct kernfs_open_file *of,
return ret;
}
+#ifdef CONFIG_ARM64_MPAM
+static void update_prefetch_tasks(struct rdtgroup *r, u32 prefetch_dis)
+{
+ struct task_struct *p, *t;
+
+ rcu_read_lock();
+
+ for_each_process_thread(p, t) {
+ if (is_closid_match(t, r) || is_rmid_match(t, r)) {
+ WRITE_ONCE(task_thread_info(t)->prefetch_dis, prefetch_dis);
+ /* Update task_struct and will send IPI to target cpu */
+ smp_mb();
+ update_task_closid_rmid(t);
+ }
+ }
+
+ rcu_read_unlock();
+}
+
+static ssize_t rdtgroup_prefetch_write(struct kernfs_open_file *of,
+ char *buf, size_t nbytes, loff_t off)
+{
+ struct rdtgroup *rdtgrp;
+ int ret = 0;
+ u32 prefetch_dis;
+
+ rdtgrp = rdtgroup_kn_lock_live(of->kn);
+ if (!rdtgrp) {
+ rdtgroup_kn_unlock(of->kn);
+ return -ENOENT;
+ }
+ rdt_last_cmd_clear();
+
+ if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED ||
+ rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) {
+ ret = -EINVAL;
+ rdt_last_cmd_puts("Pseudo-locking in progress\n");
+ goto unlock;
+ }
+
+ if (kstrtou32(buf, 0, &prefetch_dis)) {
+ rdt_last_cmd_printf("Task list parsing error prefetch %s\n", buf);
+ ret = -EINVAL;
+ goto unlock;
+ }
+
+ if (rdtgrp->prefetch_dis != prefetch_dis) {
+ rdtgrp->prefetch_dis = prefetch_dis;
+ update_prefetch_tasks(rdtgrp, prefetch_dis);
+ }
+
+unlock:
+ rdtgroup_kn_unlock(of->kn);
+
+ return ret ?: nbytes;
+}
+
+static int rdtgroup_prefetch_show(struct kernfs_open_file *of,
+ struct seq_file *s, void *v)
+{
+ struct rdtgroup *rdtgrp;
+ int ret = 0;
+
+ rdtgrp = rdtgroup_kn_lock_live(of->kn);
+ if (rdtgrp)
+ seq_printf(s, "%u\n", rdtgrp->prefetch_dis);
+ else
+ ret = -ENOENT;
+ rdtgroup_kn_unlock(of->kn);
+
+ return ret;
+}
+#endif
+
static int rdtgroup_closid_show(struct kernfs_open_file *of,
struct seq_file *s, void *v)
{
@@ -2044,6 +2118,16 @@ static struct rftype res_common_files[] = {
.seq_show = rdtgroup_tasks_show,
.fflags = RFTYPE_BASE,
},
+#ifdef CONFIG_ARM64_MPAM
+ {
+ .name = "prefetch_dis",
+ .mode = 0644,
+ .kf_ops = &rdtgroup_kf_single_ops,
+ .write = rdtgroup_prefetch_write,
+ .seq_show = rdtgroup_prefetch_show,
+ .fflags = RFTYPE_BASE,
+ },
+#endif
{
.name = "mon_hw_id",
.mode = 0444,
--
2.25.1
2
1

06 May '25
From: Lin Ma <linma(a)zju.edu.cn>
stable inclusion
from stable-v4.19.247
commit 6abfaca8711803d0d7cc8c0fac1070a88509d463
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBP3YN
CVE: CVE-2022-49505
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 1b0e81416a24d6e9b8c2341e22e8bf48f8b8bfc9 ]
Commit 3e3b5dfcd16a ("NFC: reorder the logic in nfc_{un,}register_device")
assumes the device_is_registered() in function nfc_dev_up() will help
to check when the rfkill is unregistered. However, this check only
take effect when device_del(&dev->dev) is done in nfc_unregister_device().
Hence, the rfkill object is still possible be dereferenced.
The crash trace in latest kernel (5.18-rc2):
[ 68.760105] ==================================================================
[ 68.760330] BUG: KASAN: use-after-free in __lock_acquire+0x3ec1/0x6750
[ 68.760756] Read of size 8 at addr ffff888009c93018 by task fuzz/313
[ 68.760756]
[ 68.760756] CPU: 0 PID: 313 Comm: fuzz Not tainted 5.18.0-rc2 #4
[ 68.760756] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
[ 68.760756] Call Trace:
[ 68.760756] <TASK>
[ 68.760756] dump_stack_lvl+0x57/0x7d
[ 68.760756] print_report.cold+0x5e/0x5db
[ 68.760756] ? __lock_acquire+0x3ec1/0x6750
[ 68.760756] kasan_report+0xbe/0x1c0
[ 68.760756] ? __lock_acquire+0x3ec1/0x6750
[ 68.760756] __lock_acquire+0x3ec1/0x6750
[ 68.760756] ? lockdep_hardirqs_on_prepare+0x410/0x410
[ 68.760756] ? register_lock_class+0x18d0/0x18d0
[ 68.760756] lock_acquire+0x1ac/0x4f0
[ 68.760756] ? rfkill_blocked+0xe/0x60
[ 68.760756] ? lockdep_hardirqs_on_prepare+0x410/0x410
[ 68.760756] ? mutex_lock_io_nested+0x12c0/0x12c0
[ 68.760756] ? nla_get_range_signed+0x540/0x540
[ 68.760756] ? _raw_spin_lock_irqsave+0x4e/0x50
[ 68.760756] _raw_spin_lock_irqsave+0x39/0x50
[ 68.760756] ? rfkill_blocked+0xe/0x60
[ 68.760756] rfkill_blocked+0xe/0x60
[ 68.760756] nfc_dev_up+0x84/0x260
[ 68.760756] nfc_genl_dev_up+0x90/0xe0
[ 68.760756] genl_family_rcv_msg_doit+0x1f4/0x2f0
[ 68.760756] ? genl_family_rcv_msg_attrs_parse.constprop.0+0x230/0x230
[ 68.760756] ? security_capable+0x51/0x90
[ 68.760756] genl_rcv_msg+0x280/0x500
[ 68.760756] ? genl_get_cmd+0x3c0/0x3c0
[ 68.760756] ? lock_acquire+0x1ac/0x4f0
[ 68.760756] ? nfc_genl_dev_down+0xe0/0xe0
[ 68.760756] ? lockdep_hardirqs_on_prepare+0x410/0x410
[ 68.760756] netlink_rcv_skb+0x11b/0x340
[ 68.760756] ? genl_get_cmd+0x3c0/0x3c0
[ 68.760756] ? netlink_ack+0x9c0/0x9c0
[ 68.760756] ? netlink_deliver_tap+0x136/0xb00
[ 68.760756] genl_rcv+0x1f/0x30
[ 68.760756] netlink_unicast+0x430/0x710
[ 68.760756] ? memset+0x20/0x40
[ 68.760756] ? netlink_attachskb+0x740/0x740
[ 68.760756] ? __build_skb_around+0x1f4/0x2a0
[ 68.760756] netlink_sendmsg+0x75d/0xc00
[ 68.760756] ? netlink_unicast+0x710/0x710
[ 68.760756] ? netlink_unicast+0x710/0x710
[ 68.760756] sock_sendmsg+0xdf/0x110
[ 68.760756] __sys_sendto+0x19e/0x270
[ 68.760756] ? __ia32_sys_getpeername+0xa0/0xa0
[ 68.760756] ? fd_install+0x178/0x4c0
[ 68.760756] ? fd_install+0x195/0x4c0
[ 68.760756] ? kernel_fpu_begin_mask+0x1c0/0x1c0
[ 68.760756] __x64_sys_sendto+0xd8/0x1b0
[ 68.760756] ? lockdep_hardirqs_on+0xbf/0x130
[ 68.760756] ? syscall_enter_from_user_mode+0x1d/0x50
[ 68.760756] do_syscall_64+0x3b/0x90
[ 68.760756] entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 68.760756] RIP: 0033:0x7f67fb50e6b3
...
[ 68.760756] RSP: 002b:00007f67fa91fe90 EFLAGS: 00000293 ORIG_RAX: 000000000000002c
[ 68.760756] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f67fb50e6b3
[ 68.760756] RDX: 000000000000001c RSI: 0000559354603090 RDI: 0000000000000003
[ 68.760756] RBP: 00007f67fa91ff00 R08: 00007f67fa91fedc R09: 000000000000000c
[ 68.760756] R10: 0000000000000000 R11: 0000000000000293 R12: 00007ffe824d496e
[ 68.760756] R13: 00007ffe824d496f R14: 00007f67fa120000 R15: 0000000000000003
[ 68.760756] </TASK>
[ 68.760756]
[ 68.760756] Allocated by task 279:
[ 68.760756] kasan_save_stack+0x1e/0x40
[ 68.760756] __kasan_kmalloc+0x81/0xa0
[ 68.760756] rfkill_alloc+0x7f/0x280
[ 68.760756] nfc_register_device+0xa3/0x1a0
[ 68.760756] nci_register_device+0x77a/0xad0
[ 68.760756] nfcmrvl_nci_register_dev+0x20b/0x2c0
[ 68.760756] nfcmrvl_nci_uart_open+0xf2/0x1dd
[ 68.760756] nci_uart_tty_ioctl+0x2c3/0x4a0
[ 68.760756] tty_ioctl+0x764/0x1310
[ 68.760756] __x64_sys_ioctl+0x122/0x190
[ 68.760756] do_syscall_64+0x3b/0x90
[ 68.760756] entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 68.760756]
[ 68.760756] Freed by task 314:
[ 68.760756] kasan_save_stack+0x1e/0x40
[ 68.760756] kasan_set_track+0x21/0x30
[ 68.760756] kasan_set_free_info+0x20/0x30
[ 68.760756] __kasan_slab_free+0x108/0x170
[ 68.760756] kfree+0xb0/0x330
[ 68.760756] device_release+0x96/0x200
[ 68.760756] kobject_put+0xf9/0x1d0
[ 68.760756] nfc_unregister_device+0x77/0x190
[ 68.760756] nfcmrvl_nci_unregister_dev+0x88/0xd0
[ 68.760756] nci_uart_tty_close+0xdf/0x180
[ 68.760756] tty_ldisc_kill+0x73/0x110
[ 68.760756] tty_ldisc_hangup+0x281/0x5b0
[ 68.760756] __tty_hangup.part.0+0x431/0x890
[ 68.760756] tty_release+0x3a8/0xc80
[ 68.760756] __fput+0x1f0/0x8c0
[ 68.760756] task_work_run+0xc9/0x170
[ 68.760756] exit_to_user_mode_prepare+0x194/0x1a0
[ 68.760756] syscall_exit_to_user_mode+0x19/0x50
[ 68.760756] do_syscall_64+0x48/0x90
[ 68.760756] entry_SYSCALL_64_after_hwframe+0x44/0xae
This patch just add the null out of dev->rfkill to make sure such
dereference cannot happen. This is safe since the device_lock() already
protect the check/write from data race.
Fixes: 3e3b5dfcd16a ("NFC: reorder the logic in nfc_{un,}register_device")
Signed-off-by: Lin Ma <linma(a)zju.edu.cn>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski(a)linaro.org>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Guo Mengqi <guomengqi3(a)huawei.com>
---
net/nfc/core.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/nfc/core.c b/net/nfc/core.c
index a91c6b94e153..dd12ee46ac73 100644
--- a/net/nfc/core.c
+++ b/net/nfc/core.c
@@ -1171,6 +1171,7 @@ void nfc_unregister_device(struct nfc_dev *dev)
if (dev->rfkill) {
rfkill_unregister(dev->rfkill);
rfkill_destroy(dev->rfkill);
+ dev->rfkill = NULL;
}
dev->shutting_down = true;
device_unlock(&dev->dev);
--
2.22.0
2
1

06 May '25
From: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>
stable inclusion
from stable-v4.19.238
commit 684e505406abaeabe0058e9776f9210bf2747953
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBW9W8
CVE: CVE-2022-49111
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit f63d24baff787e13b723d86fe036f84bdbc35045 ]
This fixes the following trace caused by receiving
HCI_EV_DISCONN_PHY_LINK_COMPLETE which does call hci_conn_del without
first checking if conn->type is in fact AMP_LINK and in case it is
do properly cleanup upper layers with hci_disconn_cfm:
==================================================================
BUG: KASAN: use-after-free in hci_send_acl+0xaba/0xc50
Read of size 8 at addr ffff88800e404818 by task bluetoothd/142
CPU: 0 PID: 142 Comm: bluetoothd Not tainted
5.17.0-rc5-00006-gda4022eeac1a #7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0x45/0x59
print_address_description.constprop.0+0x1f/0x150
kasan_report.cold+0x7f/0x11b
hci_send_acl+0xaba/0xc50
l2cap_do_send+0x23f/0x3d0
l2cap_chan_send+0xc06/0x2cc0
l2cap_sock_sendmsg+0x201/0x2b0
sock_sendmsg+0xdc/0x110
sock_write_iter+0x20f/0x370
do_iter_readv_writev+0x343/0x690
do_iter_write+0x132/0x640
vfs_writev+0x198/0x570
do_writev+0x202/0x280
do_syscall_64+0x38/0x90
entry_SYSCALL_64_after_hwframe+0x44/0xae
RSP: 002b:00007ffce8a099b8 EFLAGS: 00000246 ORIG_RAX: 0000000000000014
Code: 0f 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b8 0f 1f 00 f3
0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 14 00 00 00 0f 05
<48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 89 54 24 1c 48 89 74 24 10
RDX: 0000000000000001 RSI: 00007ffce8a099e0 RDI: 0000000000000015
RAX: ffffffffffffffda RBX: 00007ffce8a099e0 RCX: 00007f788fc3cf77
R10: 00007ffce8af7080 R11: 0000000000000246 R12: 000055e4ccf75580
RBP: 0000000000000015 R08: 0000000000000002 R09: 0000000000000001
</TASK>
R13: 000055e4ccf754a0 R14: 000055e4ccf75cd0 R15: 000055e4ccf4a6b0
Allocated by task 45:
kasan_save_stack+0x1e/0x40
__kasan_kmalloc+0x81/0xa0
hci_chan_create+0x9a/0x2f0
l2cap_conn_add.part.0+0x1a/0xdc0
l2cap_connect_cfm+0x236/0x1000
le_conn_complete_evt+0x15a7/0x1db0
hci_le_conn_complete_evt+0x226/0x2c0
hci_le_meta_evt+0x247/0x450
hci_event_packet+0x61b/0xe90
hci_rx_work+0x4d5/0xc50
process_one_work+0x8fb/0x15a0
worker_thread+0x576/0x1240
kthread+0x29d/0x340
ret_from_fork+0x1f/0x30
Freed by task 45:
kasan_save_stack+0x1e/0x40
kasan_set_track+0x21/0x30
kasan_set_free_info+0x20/0x30
__kasan_slab_free+0xfb/0x130
kfree+0xac/0x350
hci_conn_cleanup+0x101/0x6a0
hci_conn_del+0x27e/0x6c0
hci_disconn_phylink_complete_evt+0xe0/0x120
hci_event_packet+0x812/0xe90
hci_rx_work+0x4d5/0xc50
process_one_work+0x8fb/0x15a0
worker_thread+0x576/0x1240
kthread+0x29d/0x340
ret_from_fork+0x1f/0x30
The buggy address belongs to the object at ffff88800c0f0500
The buggy address is located 24 bytes inside of
which belongs to the cache kmalloc-128 of size 128
The buggy address belongs to the page:
128-byte region [ffff88800c0f0500, ffff88800c0f0580)
flags: 0x100000000000200(slab|node=0|zone=1)
page:00000000fe45cd86 refcount:1 mapcount:0
mapping:0000000000000000 index:0x0 pfn:0xc0f0
raw: 0000000000000000 0000000080100010 00000001ffffffff
0000000000000000
raw: 0100000000000200 ffffea00003a2c80 dead000000000004
ffff8880078418c0
page dumped because: kasan: bad access detected
ffff88800c0f0400: 00 00 00 00 00 00 00 00 00 00 00 00 00 fc fc fc
Memory state around the buggy address:
>ffff88800c0f0500: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88800c0f0480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff88800c0f0580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
^
==================================================================
ffff88800c0f0600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
Reported-by: Sönke Huster <soenke.huster(a)eknoes.de>
Tested-by: Sönke Huster <soenke.huster(a)eknoes.de>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>
Signed-off-by: Marcel Holtmann <marcel(a)holtmann.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Guo Mengqi <guomengqi3(a)huawei.com>
---
net/bluetooth/hci_event.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 0067197535dd..3ed83b06c726 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -4775,8 +4775,9 @@ static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
hci_dev_lock(hdev);
hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
- if (hcon) {
+ if (hcon && hcon->type == AMP_LINK) {
hcon->state = BT_CLOSED;
+ hci_disconn_cfm(hcon, ev->reason);
hci_conn_del(hcon);
}
--
2.22.0
2
1
Amir Goldstein (57):
fs: rename __mnt_{want,drop}_write*() helpers
fs: export mnt_{get,put}_write_access() to modules
fuse: factor out helper fuse_truncate_update_attr()
fuse: allocate ff->release_args only if release is needed
fuse: break up fuse_open_common()
fuse: prepare for failing open response
fuse: introduce inode io modes
fuse: allow parallel dio writes with FUSE_DIRECT_IO_ALLOW_MMAP
ovl: use simpler function to convert iocb to rw flags
ovl: propagate IOCB_APPEND flag on writes to realfile
ovl: punt write aio completion to workqueue
ovl: protect copying of realinode attributes to ovl inode
fs: get mnt_writers count for an open backing file's real path
fs: create helper file_user_path() for user displayed mapped file path
fs: store real path instead of fake path in backing file f_path
ovl: add helper ovl_file_modified()
ovl: split ovl_want_write() into two helpers
ovl: reorder ovl_want_write() after ovl_inode_lock()
ovl: do not open/llseek lower file with upper sb_writers held
ovl: do not encode lower fh with upper sb_writers held
ovl: add permission hooks outside of do_splice_direct()
splice: remove permission hook from do_splice_direct()
splice: move permission hook out of splice_direct_to_actor()
splice: move permission hook out of splice_file_to_pipe()
splice: remove permission hook from iter_file_splice_write()
remap_range: move permission hooks out of do_clone_file_range()
remap_range: move file_start_write() to after permission hook
btrfs: move file_start_write() to after permission hook
coda: change locking order in coda_file_write_iter()
fs: move file_start_write() into vfs_iter_write()
fs: move permission hook out of do_iter_write()
fs: move permission hook out of do_iter_read()
fs: move kiocb_start_write() into vfs_iocb_iter_write()
fs: create __sb_write_started() helper
fs: create file_write_started() helper
fs: create {sb,file}_write_not_started() helpers
fs: prepare for stackable filesystems backing file helpers
fs: factor out backing_file_{read,write}_iter() helpers
fs: factor out backing_file_splice_{read,write}() helpers
fs: factor out backing_file_mmap() helper
fuse: factor out helper for FUSE_DEV_IOC_CLONE
fuse: introduce FUSE_PASSTHROUGH capability
fuse: implement ioctls to manage backing files
fuse: prepare for opening file in passthrough mode
fuse: implement open in passthrough mode
fuse: implement read/write passthrough
fuse: implement splice read/write passthrough
fuse: implement passthrough for mmap
fuse: fix wrong ff->iomode state changes from parallel dio write
fuse: fix parallel dio write on file open in passthrough mode
fuse: verify zero padding in fuse_backing_map
fuse: respect FOPEN_KEEP_CACHE on opendir
ovl: fix dentry reference leak after changes to underlying layers
ovl: relax WARN_ON in ovl_verify_area()
remap_range: merge do_clone_file_range() into vfs_clone_file_range()
fs: pass offset and result to backing_file end_write() callback
fuse: update inode size after extending passthrough write
Bernd Schubert (3):
fuse: create helper function if DIO write needs exclusive lock
fuse: add fuse_dio_lock/unlock helper functions
fuse: disable the combination of passthrough and writeback cache
Ed Tsai (1):
backing-file: convert to using fops->splice_write
Vegard Nossum (1):
fs: fix __sb_write_started() kerneldoc formatting
yangyun (1):
fuse: use exclusive lock when FUSE_I_CACHE_IO_MODE is set
fs/fuse/fuse_i.h | 151 +++++++++++--
fs/internal.h | 21 +-
fs/overlayfs/overlayfs.h | 38 +++-
include/linux/backing-file.h | 42 ++++
include/linux/fs.h | 89 ++++++--
include/linux/fsnotify.h | 3 +-
include/linux/mount.h | 4 +-
include/uapi/linux/fuse.h | 23 +-
arch/arc/kernel/troubleshoot.c | 6 +-
drivers/block/loop.c | 2 -
drivers/target/target_core_file.c | 10 +-
fs/backing-file.c | 339 ++++++++++++++++++++++++++++
fs/btrfs/ioctl.c | 12 +-
fs/cachefiles/io.c | 5 +-
fs/coda/file.c | 2 -
fs/file_table.c | 12 +-
fs/fuse/dev.c | 98 +++++---
fs/fuse/dir.c | 49 +++-
fs/fuse/file.c | 362 ++++++++++++++++++++----------
fs/fuse/inode.c | 37 +++
fs/fuse/iomode.c | 276 +++++++++++++++++++++++
fs/fuse/passthrough.c | 355 +++++++++++++++++++++++++++++
fs/inode.c | 8 +-
fs/namespace.c | 36 +--
fs/nfsd/vfs.c | 7 +-
fs/open.c | 70 +++---
fs/overlayfs/copy_up.c | 168 +++++++++-----
fs/overlayfs/dir.c | 60 +++--
fs/overlayfs/export.c | 7 +-
fs/overlayfs/file.c | 230 ++++---------------
fs/overlayfs/inode.c | 57 +++--
fs/overlayfs/namei.c | 37 ++-
fs/overlayfs/super.c | 47 ++--
fs/overlayfs/util.c | 75 ++++++-
fs/proc/base.c | 2 +-
fs/proc/nommu.c | 2 +-
fs/proc/task_mmu.c | 4 +-
fs/proc/task_nommu.c | 2 +-
fs/read_write.c | 156 ++++++++-----
fs/remap_range.c | 44 ++--
fs/splice.c | 82 ++++---
fs/super.c | 1 +
kernel/acct.c | 4 +-
kernel/trace/trace_output.c | 2 +-
MAINTAINERS | 9 +
fs/Kconfig | 4 +
fs/Makefile | 1 +
fs/fuse/Kconfig | 11 +
fs/fuse/Makefile | 2 +
fs/overlayfs/Kconfig | 1 +
50 files changed, 2290 insertions(+), 775 deletions(-)
create mode 100644 include/linux/backing-file.h
create mode 100644 fs/backing-file.c
create mode 100644 fs/fuse/iomode.c
create mode 100644 fs/fuse/passthrough.c
--
2.39.2
2
64
Amir Goldstein (57):
fs: rename __mnt_{want,drop}_write*() helpers
fs: export mnt_{get,put}_write_access() to modules
fuse: factor out helper fuse_truncate_update_attr()
fuse: allocate ff->release_args only if release is needed
fuse: break up fuse_open_common()
fuse: prepare for failing open response
fuse: introduce inode io modes
fuse: allow parallel dio writes with FUSE_DIRECT_IO_ALLOW_MMAP
ovl: use simpler function to convert iocb to rw flags
ovl: propagate IOCB_APPEND flag on writes to realfile
ovl: punt write aio completion to workqueue
ovl: protect copying of realinode attributes to ovl inode
fs: get mnt_writers count for an open backing file's real path
fs: create helper file_user_path() for user displayed mapped file path
fs: store real path instead of fake path in backing file f_path
ovl: add helper ovl_file_modified()
ovl: split ovl_want_write() into two helpers
ovl: reorder ovl_want_write() after ovl_inode_lock()
ovl: do not open/llseek lower file with upper sb_writers held
ovl: do not encode lower fh with upper sb_writers held
ovl: add permission hooks outside of do_splice_direct()
splice: remove permission hook from do_splice_direct()
splice: move permission hook out of splice_direct_to_actor()
splice: move permission hook out of splice_file_to_pipe()
splice: remove permission hook from iter_file_splice_write()
remap_range: move permission hooks out of do_clone_file_range()
remap_range: move file_start_write() to after permission hook
btrfs: move file_start_write() to after permission hook
coda: change locking order in coda_file_write_iter()
fs: move file_start_write() into vfs_iter_write()
fs: move permission hook out of do_iter_write()
fs: move permission hook out of do_iter_read()
fs: move kiocb_start_write() into vfs_iocb_iter_write()
fs: create __sb_write_started() helper
fs: create file_write_started() helper
fs: create {sb,file}_write_not_started() helpers
fs: prepare for stackable filesystems backing file helpers
fs: factor out backing_file_{read,write}_iter() helpers
fs: factor out backing_file_splice_{read,write}() helpers
fs: factor out backing_file_mmap() helper
fuse: factor out helper for FUSE_DEV_IOC_CLONE
fuse: introduce FUSE_PASSTHROUGH capability
fuse: implement ioctls to manage backing files
fuse: prepare for opening file in passthrough mode
fuse: implement open in passthrough mode
fuse: implement read/write passthrough
fuse: implement splice read/write passthrough
fuse: implement passthrough for mmap
fuse: fix wrong ff->iomode state changes from parallel dio write
fuse: fix parallel dio write on file open in passthrough mode
fuse: verify zero padding in fuse_backing_map
fuse: respect FOPEN_KEEP_CACHE on opendir
ovl: fix dentry reference leak after changes to underlying layers
ovl: relax WARN_ON in ovl_verify_area()
remap_range: merge do_clone_file_range() into vfs_clone_file_range()
fs: pass offset and result to backing_file end_write() callback
fuse: update inode size after extending passthrough write
Bernd Schubert (3):
fuse: create helper function if DIO write needs exclusive lock
fuse: add fuse_dio_lock/unlock helper functions
fuse: disable the combination of passthrough and writeback cache
Ed Tsai (1):
backing-file: convert to using fops->splice_write
Vegard Nossum (1):
fs: fix __sb_write_started() kerneldoc formatting
yangyun (1):
fuse: use exclusive lock when FUSE_I_CACHE_IO_MODE is set
fs/fuse/fuse_i.h | 151 +++++++++++--
fs/internal.h | 21 +-
fs/overlayfs/overlayfs.h | 38 +++-
include/linux/backing-file.h | 42 ++++
include/linux/fs.h | 89 ++++++--
include/linux/fsnotify.h | 3 +-
include/linux/mount.h | 4 +-
include/uapi/linux/fuse.h | 23 +-
arch/arc/kernel/troubleshoot.c | 6 +-
drivers/block/loop.c | 2 -
drivers/target/target_core_file.c | 10 +-
fs/backing-file.c | 339 ++++++++++++++++++++++++++++
fs/btrfs/ioctl.c | 12 +-
fs/cachefiles/io.c | 5 +-
fs/coda/file.c | 2 -
fs/file_table.c | 12 +-
fs/fuse/dev.c | 98 +++++---
fs/fuse/dir.c | 49 +++-
fs/fuse/file.c | 362 ++++++++++++++++++++----------
fs/fuse/inode.c | 37 +++
fs/fuse/iomode.c | 276 +++++++++++++++++++++++
fs/fuse/passthrough.c | 355 +++++++++++++++++++++++++++++
fs/inode.c | 8 +-
fs/namespace.c | 36 +--
fs/nfsd/vfs.c | 7 +-
fs/open.c | 70 +++---
fs/overlayfs/copy_up.c | 168 +++++++++-----
fs/overlayfs/dir.c | 60 +++--
fs/overlayfs/export.c | 7 +-
fs/overlayfs/file.c | 230 ++++---------------
fs/overlayfs/inode.c | 57 +++--
fs/overlayfs/namei.c | 37 ++-
fs/overlayfs/super.c | 47 ++--
fs/overlayfs/util.c | 75 ++++++-
fs/proc/base.c | 2 +-
fs/proc/nommu.c | 2 +-
fs/proc/task_mmu.c | 4 +-
fs/proc/task_nommu.c | 2 +-
fs/read_write.c | 156 ++++++++-----
fs/remap_range.c | 44 ++--
fs/splice.c | 82 ++++---
fs/super.c | 1 +
kernel/acct.c | 4 +-
kernel/trace/trace_output.c | 2 +-
MAINTAINERS | 9 +
fs/Kconfig | 4 +
fs/Makefile | 1 +
fs/fuse/Kconfig | 11 +
fs/fuse/Makefile | 2 +
fs/overlayfs/Kconfig | 1 +
50 files changed, 2290 insertions(+), 775 deletions(-)
create mode 100644 include/linux/backing-file.h
create mode 100644 fs/backing-file.c
create mode 100644 fs/fuse/iomode.c
create mode 100644 fs/fuse/passthrough.c
--
2.39.2
2
64

[openeuler:openEuler-1.0-LTS 1365/1365] drivers/acpi/cppc_acpi.c:614:3-8: WARNING: NULL check before some freeing functions is not needed.
by kernel test robot 05 May '25
by kernel test robot 05 May '25
05 May '25
tree: https://gitee.com/openeuler/kernel.git openEuler-1.0-LTS
head: a48a35466505c8a52da57596944bd0b4485e825f
commit: b8815fbbe89b0d15fa3296c3e57d2197a92f5bc0 [1365/1365] ACPI: CPPC: Fix cppc_cpufreq_init failed in CPU Hotplug situation
config: x86_64-randconfig-102-20250103 (https://download.01.org/0day-ci/archive/20250505/202505052008.Vj0WP8gn-lkp@…)
compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505052008.Vj0WP8gn-lkp@intel.com/
cocci warnings: (new ones prefixed by >>)
>> drivers/acpi/cppc_acpi.c:614:3-8: WARNING: NULL check before some freeing functions is not needed.
vim +614 drivers/acpi/cppc_acpi.c
576
577 int acpi_get_psd_map(struct cppc_cpudata **all_cpu_data)
578 {
579 struct cpc_desc **cpc_pptr, *cpc_ptr;
580 int parsed_core_num = 0;
581 int i, ret;
582
583 cpc_pptr = kcalloc(num_possible_cpus(), sizeof(void *), GFP_KERNEL);
584 if (!cpc_pptr)
585 return -ENOMEM;
586 for_each_possible_cpu(i) {
587 cpc_pptr[i] = kzalloc(sizeof(struct cpc_desc), GFP_KERNEL);
588 if (!cpc_pptr[i]) {
589 ret = -ENOMEM;
590 goto out;
591 }
592 }
593
594 /*
595 * We can not use acpi_get_devices() to walk the processor devices
596 * because some processor device is not present.
597 */
598 ret = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
599 ACPI_UINT32_MAX, acpi_parse_cpc, NULL,
600 cpc_pptr, (void **)&parsed_core_num);
601 if (ret)
602 goto out;
603 if (parsed_core_num != num_possible_cpus()) {
604 ret = -EINVAL;
605 goto out;
606 }
607
608 ret = __acpi_get_psd_map(all_cpu_data, cpc_pptr);
609
610 out:
611 for_each_possible_cpu(i) {
612 cpc_ptr = cpc_pptr[i];
613 if (cpc_ptr)
> 614 kfree(cpc_ptr);
615 }
616 kfree(cpc_pptr);
617
618 return ret;
619 }
620 EXPORT_SYMBOL_GPL(acpi_get_psd_map);
621
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

04 May '25
From: Vincent Mailhol <mailhol.vincent(a)wanadoo.fr>
stable inclusion
from stable-v5.11-rc5
commit 50aca891d7a554db0901b245167cd653d73aaa71
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC21UY
CVE: CVE-2021-47670
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
After calling peak_usb_netif_rx_ni(skb), dereferencing skb is unsafe.
Especially, the can_frame cf which aliases skb memory is accessed
after the peak_usb_netif_rx_ni().
Reordering the lines solves the issue.
Fixes: 0a25e1f4f185 ("can: peak_usb: add support for PEAK new CANFD USB adapters")
Link: https://lore.kernel.org/r/20210120114137.200019-4-mailhol.vincent@wanadoo.fr
Signed-off-by: Vincent Mailhol <mailhol.vincent(a)wanadoo.fr>
Signed-off-by: Marc Kleine-Budde <mkl(a)pengutronix.de>
Signed-off-by: Zhang Changzhong <zhangchangzhong(a)huawei.com>
---
drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 4198835..87574ce 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -514,11 +514,11 @@ static int pcan_usb_fd_decode_canmsg(struct pcan_usb_fd_if *usb_if,
else
memcpy(cfd->data, rm->d, cfd->len);
- peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(rm->ts_low));
-
netdev->stats.rx_packets++;
netdev->stats.rx_bytes += cfd->len;
+ peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(rm->ts_low));
+
return 0;
}
@@ -574,11 +574,11 @@ static int pcan_usb_fd_decode_status(struct pcan_usb_fd_if *usb_if,
if (!skb)
return -ENOMEM;
- peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(sm->ts_low));
-
netdev->stats.rx_packets++;
netdev->stats.rx_bytes += cf->can_dlc;
+ peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(sm->ts_low));
+
return 0;
}
--
2.9.5
2
1

[PATCH openEuler-1.0-LTS] net: mdio: validate parameter addr in mdiobus_get_phy()
by Zhang Changzhong 04 May '25
by Zhang Changzhong 04 May '25
04 May '25
From: Heiner Kallweit <hkallweit1(a)gmail.com>
stable inclusion
from stable-v4.19.272
commit c431a3d642593bbdb99e8a9e3eed608b730db6f8
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBWVY6
CVE: CVE-2023-53019
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 867dbe784c5010a466f00a7d1467c1c5ea569c75 ]
The caller may pass any value as addr, what may result in an out-of-bounds
access to array mdio_map. One existing case is stmmac_init_phy() that
may pass -1 as addr. Therefore validate addr before using it.
Fixes: 7f854420fbfe ("phy: Add API for {un}registering an mdio device to a bus.")
Signed-off-by: Heiner Kallweit <hkallweit1(a)gmail.com>
Reviewed-by: Andrew Lunn <andrew(a)lunn.ch>
Link: https://lore.kernel.org/r/cdf664ea-3312-e915-73f8-021678d08887@gmail.com
Signed-off-by: Paolo Abeni <pabeni(a)redhat.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Zhang Changzhong <zhangchangzhong(a)huawei.com>
---
drivers/net/phy/mdio_bus.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 3593717..60c732d 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -102,7 +102,12 @@ EXPORT_SYMBOL(mdiobus_unregister_device);
struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr)
{
- struct mdio_device *mdiodev = bus->mdio_map[addr];
+ struct mdio_device *mdiodev;
+
+ if (addr < 0 || addr >= ARRAY_SIZE(bus->mdio_map))
+ return NULL;
+
+ mdiodev = bus->mdio_map[addr];
if (!mdiodev)
return NULL;
--
2.9.5
2
1

[openeuler:OLK-5.10 2882/2882] ld.lld: error: undefined symbol: sk_msg_alloc
by kernel test robot 02 May '25
by kernel test robot 02 May '25
02 May '25
Hi Wei,
FYI, the error/warning still remains.
tree: https://gitee.com/openeuler/kernel.git OLK-5.10
head: 46abe407b020831448331eea487e07c883e95836
commit: e9ce37bbceb2779c0015fcac54cc8df7a2ec8b76 [2882/2882] tcp_comp: implement sendmsg for tcp compression
config: x86_64-randconfig-102-20250502 (https://download.01.org/0day-ci/archive/20250502/202505021845.WkxnVSOV-lkp@…)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250502/202505021845.WkxnVSOV-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505021845.WkxnVSOV-lkp@intel.com/
All errors (new ones prefixed by >>):
>> ld.lld: error: undefined symbol: sk_msg_alloc
>>> referenced by tcp_comp.c:148 (net/ipv4/tcp_comp.c:148)
>>> ipv4/tcp_comp.o:(tcp_comp_sendmsg) in archive net/built-in.a
--
>> ld.lld: error: undefined symbol: sk_msg_trim
>>> referenced by tcp_comp.c:236 (net/ipv4/tcp_comp.c:236)
>>> ipv4/tcp_comp.o:(tcp_comp_sendmsg) in archive net/built-in.a
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-5.10 2882/2882] drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_monitor.o: warning: objtool: sxevf_work_cb()+0x108b: can't find switch jump table
by kernel test robot 02 May '25
by kernel test robot 02 May '25
02 May '25
Hi liujie_answer,
First bad commit (maybe != root cause):
tree: https://gitee.com/openeuler/kernel.git OLK-5.10
head: 46abe407b020831448331eea487e07c883e95836
commit: 8cee206b5558245197158bd20895f95cc28d8468 [2882/2882] Ethernet: Linkdata: Supports Linkdata ethernet Controllers
config: x86_64-randconfig-101-20250502 (https://download.01.org/0day-ci/archive/20250502/202505021622.Vo53IuHc-lkp@…)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250502/202505021622.Vo53IuHc-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505021622.Vo53IuHc-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_monitor.o: warning: objtool: sxevf_work_cb()+0x108b: can't find switch jump table
Kconfig warnings: (for reference only)
WARNING: unmet direct dependencies detected for PGP_KEY_PARSER
Depends on [m]: CRYPTO [=y] && ASYMMETRIC_KEY_TYPE [=y] && ASYMMETRIC_PUBLIC_KEY_SUBTYPE [=m]
Selected by [y]:
- PGP_PRELOAD [=y] && CRYPTO [=y] && ASYMMETRIC_KEY_TYPE [=y]
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-6.6 2195/2195] include/linux/pgplib.h:36:23: error: field has incomplete type 'enum pgp_key_version'
by kernel test robot 02 May '25
by kernel test robot 02 May '25
02 May '25
Hi David,
FYI, the error/warning still remains.
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: 241523b7d82e629fd115303840c385702bf2ea5e
commit: 43d4042e06d2bf96adf67d25e8d91653507a4cf9 [2195/2195] KEYS: Provide a function to load keys from a PGP keyring blob
config: x86_64-randconfig-101-20250502 (https://download.01.org/0day-ci/archive/20250502/202505021617.FheAIoZW-lkp@…)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250502/202505021617.FheAIoZW-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505021617.FheAIoZW-lkp@intel.com/
All error/warnings (new ones prefixed by >>):
In file included from crypto/asymmetric_keys/pgp_preload.c:19:
>> include/linux/pgplib.h:26:15: warning: declaration of 'enum pgp_packet_tag' will not be visible outside of this function [-Wvisibility]
26 | enum pgp_packet_tag type,
| ^
>> include/linux/pgplib.h:36:23: error: field has incomplete type 'enum pgp_key_version'
36 | enum pgp_key_version version : 8;
| ^
include/linux/pgplib.h:36:7: note: forward declaration of 'enum pgp_key_version'
36 | enum pgp_key_version version : 8;
| ^
>> include/linux/pgplib.h:37:23: error: field has incomplete type 'enum pgp_pubkey_algo'
37 | enum pgp_pubkey_algo pubkey_algo : 8;
| ^
include/linux/pgplib.h:37:7: note: forward declaration of 'enum pgp_pubkey_algo'
37 | enum pgp_pubkey_algo pubkey_algo : 8;
| ^
>> crypto/asymmetric_keys/pgp_preload.c:63:10: warning: declaration of 'enum pgp_packet_tag' will not be visible outside of this function [-Wvisibility]
63 | enum pgp_packet_tag type, u8 headerlen,
| ^
>> crypto/asymmetric_keys/pgp_preload.c:63:25: error: variable has incomplete type 'enum pgp_packet_tag'
63 | enum pgp_packet_tag type, u8 headerlen,
| ^
crypto/asymmetric_keys/pgp_preload.c:63:10: note: forward declaration of 'enum pgp_packet_tag'
63 | enum pgp_packet_tag type, u8 headerlen,
| ^
>> crypto/asymmetric_keys/pgp_preload.c:107:36: error: use of undeclared identifier 'PGP_PKT_PUBLIC_KEY'
107 | ctx.pgp.types_of_interest = (1 << PGP_PKT_PUBLIC_KEY);
| ^
>> crypto/asymmetric_keys/pgp_preload.c:108:25: error: incompatible function pointer types assigning to 'int (*)(struct pgp_parse_context *, enum pgp_packet_tag, u8, const u8 *, size_t)' (aka 'int (*)(struct pgp_parse_context *, enum pgp_packet_tag, unsigned char, const unsigned char *, unsigned long)') from 'int (struct pgp_parse_context *, enum pgp_packet_tag, u8, const u8 *, size_t)' (aka 'int (struct pgp_parse_context *, enum pgp_packet_tag, unsigned char, const unsigned char *, unsigned long)') [-Wincompatible-function-pointer-types]
108 | ctx.pgp.process_packet = found_pgp_key;
| ^ ~~~~~~~~~~~~~
>> crypto/asymmetric_keys/pgp_preload.c:101:12: warning: no previous prototype for function 'preload_pgp_keys' [-Wmissing-prototypes]
101 | int __init preload_pgp_keys(const u8 *pgpdata, size_t pgpdatalen,
| ^
crypto/asymmetric_keys/pgp_preload.c:101:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
101 | int __init preload_pgp_keys(const u8 *pgpdata, size_t pgpdatalen,
| ^
| static
3 warnings and 5 errors generated.
--
In file included from crypto/asymmetric_keys/pgp_public_key.c:19:
In file included from include/linux/mpi.h:21:
In file included from include/linux/scatterlist.h:8:
In file included from include/linux/mm.h:2193:
include/linux/vmstat.h:522:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
522 | return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
| ~~~~~~~~~~~ ^ ~~~
In file included from crypto/asymmetric_keys/pgp_public_key.c:20:
>> include/linux/pgplib.h:26:15: warning: declaration of 'enum pgp_packet_tag' will not be visible outside of this function [-Wvisibility]
26 | enum pgp_packet_tag type,
| ^
>> include/linux/pgplib.h:36:23: error: field has incomplete type 'enum pgp_key_version'
36 | enum pgp_key_version version : 8;
| ^
include/linux/pgplib.h:36:7: note: forward declaration of 'enum pgp_key_version'
36 | enum pgp_key_version version : 8;
| ^
>> include/linux/pgplib.h:37:23: error: field has incomplete type 'enum pgp_pubkey_algo'
37 | enum pgp_pubkey_algo pubkey_algo : 8;
| ^
include/linux/pgplib.h:37:7: note: forward declaration of 'enum pgp_pubkey_algo'
37 | enum pgp_pubkey_algo pubkey_algo : 8;
| ^
>> crypto/asymmetric_keys/pgp_public_key.c:63:2: error: call to undeclared function 'kenter'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
63 | kenter("");
| ^
>> crypto/asymmetric_keys/pgp_public_key.c:65:22: error: use of undeclared identifier 'PGP_KEY_VERSION_4'
65 | n = (pgp->version < PGP_KEY_VERSION_4) ? 8 : 6;
| ^
>> crypto/asymmetric_keys/pgp_public_key.c:67:9: error: call to undeclared function 'mpi_key_length'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
67 | ret = mpi_key_length(key_ptr, keylen, nb + i, nn + i);
| ^
crypto/asymmetric_keys/pgp_public_key.c:95:21: error: use of undeclared identifier 'PGP_KEY_VERSION_4'
95 | if (pgp->version < PGP_KEY_VERSION_4) {
| ^
>> crypto/asymmetric_keys/pgp_public_key.c:115:2: error: call to undeclared function 'kleave'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
115 | kleave(" = %d", ret);
| ^
crypto/asymmetric_keys/pgp_public_key.c:134:42: error: use of undeclared identifier 'PGP_KEY_VERSION_4'
134 | tfm = crypto_alloc_shash(pgp->version < PGP_KEY_VERSION_4 ?
| ^
crypto/asymmetric_keys/pgp_public_key.c:191:2: error: call to undeclared function 'kleave'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
191 | kleave(" = %d", ret);
| ^
>> crypto/asymmetric_keys/pgp_public_key.c:199:12: warning: declaration of 'enum pgp_packet_tag' will not be visible outside of this function [-Wvisibility]
199 | enum pgp_packet_tag type,
| ^
>> crypto/asymmetric_keys/pgp_public_key.c:199:27: error: variable has incomplete type 'enum pgp_packet_tag'
199 | enum pgp_packet_tag type,
| ^
crypto/asymmetric_keys/pgp_public_key.c:199:12: note: forward declaration of 'enum pgp_packet_tag'
199 | enum pgp_packet_tag type,
| ^
crypto/asymmetric_keys/pgp_public_key.c:211:2: error: call to undeclared function 'kenter'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
211 | kenter(",%u,%u,,%zu", type, headerlen, datalen);
| ^
>> crypto/asymmetric_keys/pgp_public_key.c:213:14: error: use of undeclared identifier 'PGP_PKT_USER_ID'
213 | if (type == PGP_PKT_USER_ID) {
| ^
crypto/asymmetric_keys/pgp_public_key.c:216:3: error: call to undeclared function 'kleave'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
216 | kleave(" = 0 [user ID]");
| ^
crypto/asymmetric_keys/pgp_public_key.c:221:3: error: call to undeclared function 'kleave'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
221 | kleave(" = -ENOKEY [already]");
| ^
>> crypto/asymmetric_keys/pgp_public_key.c:234:25: error: use of undeclared identifier 'PGP_PUBKEY__LAST'
234 | if (pgp.pubkey_algo >= PGP_PUBKEY__LAST)
| ^
>> crypto/asymmetric_keys/pgp_public_key.c:236:9: error: use of undeclared identifier 'pgp_to_public_key_algo'
236 | algo = pgp_to_public_key_algo[pgp.pubkey_algo];
| ^
crypto/asymmetric_keys/pgp_public_key.c:252:2: error: call to undeclared function 'kleave'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
252 | kleave(" = 0 [use]");
| ^
crypto/asymmetric_keys/pgp_public_key.c:310:2: error: call to undeclared function 'kenter'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
310 | kenter("");
| ^
>> crypto/asymmetric_keys/pgp_public_key.c:313:36: error: use of undeclared identifier 'PGP_PKT_PUBLIC_KEY'
313 | ctx.pgp.types_of_interest = (1 << PGP_PKT_PUBLIC_KEY) |
| ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
3 warnings and 20 errors generated.
Kconfig warnings: (for reference only)
WARNING: unmet direct dependencies detected for PGP_KEY_PARSER
Depends on [m]: CRYPTO [=y] && ASYMMETRIC_KEY_TYPE [=y] && ASYMMETRIC_PUBLIC_KEY_SUBTYPE [=m]
Selected by [y]:
- PGP_PRELOAD [=y] && CRYPTO [=y] && ASYMMETRIC_KEY_TYPE [=y]
vim +36 include/linux/pgplib.h
b78af6579e15dc David Howells 2023-09-12 19
b78af6579e15dc David Howells 2023-09-12 20 /*
b78af6579e15dc David Howells 2023-09-12 21 * PGP library packet parser
b78af6579e15dc David Howells 2023-09-12 22 */
b78af6579e15dc David Howells 2023-09-12 23 struct pgp_parse_context {
b78af6579e15dc David Howells 2023-09-12 24 u64 types_of_interest;
b78af6579e15dc David Howells 2023-09-12 25 int (*process_packet)(struct pgp_parse_context *context,
b78af6579e15dc David Howells 2023-09-12 @26 enum pgp_packet_tag type,
b78af6579e15dc David Howells 2023-09-12 27 u8 headerlen,
b78af6579e15dc David Howells 2023-09-12 28 const u8 *data,
b78af6579e15dc David Howells 2023-09-12 29 size_t datalen);
b78af6579e15dc David Howells 2023-09-12 30 };
b78af6579e15dc David Howells 2023-09-12 31
b78af6579e15dc David Howells 2023-09-12 32 extern int pgp_parse_packets(const u8 *data, size_t datalen,
b78af6579e15dc David Howells 2023-09-12 33 struct pgp_parse_context *ctx);
b78af6579e15dc David Howells 2023-09-12 34
b78af6579e15dc David Howells 2023-09-12 35 struct pgp_parse_pubkey {
b78af6579e15dc David Howells 2023-09-12 @36 enum pgp_key_version version : 8;
b78af6579e15dc David Howells 2023-09-12 @37 enum pgp_pubkey_algo pubkey_algo : 8;
b78af6579e15dc David Howells 2023-09-12 38 __kernel_old_time_t creation_time;
b78af6579e15dc David Howells 2023-09-12 39 __kernel_old_time_t expires_at;
b78af6579e15dc David Howells 2023-09-12 40 };
b78af6579e15dc David Howells 2023-09-12 41
:::::: The code at line 36 was first introduced by commit
:::::: b78af6579e15dcdff86504da90af77f3e890270e PGPLIB: Basic packet parser
:::::: TO: David Howells <dhowells(a)redhat.com>
:::::: CC: zgzxx <zhangguangzhi3(a)huawei.com>
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-5.10 2882/2882] drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:134:36: sparse: sparse: invalid assignment: |=
by kernel test robot 02 May '25
by kernel test robot 02 May '25
02 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-5.10
head: 46abe407b020831448331eea487e07c883e95836
commit: 8cee206b5558245197158bd20895f95cc28d8468 [2882/2882] Ethernet: Linkdata: Supports Linkdata ethernet Controllers
config: x86_64-randconfig-122-20250502 (https://download.01.org/0day-ci/archive/20250502/202505021153.ilI6N3GY-lkp@…)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250502/202505021153.ilI6N3GY-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505021153.ilI6N3GY-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c: note: in included file:
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:134:36: sparse: sparse: invalid assignment: |=
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:134:36: sparse: left side has type restricted __le32
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:134:36: sparse: right side has type unsigned int
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:115:36: sparse: sparse: invalid assignment: |=
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:115:36: sparse: left side has type restricted __le32
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:115:36: sparse: right side has type unsigned int
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:121:36: sparse: sparse: invalid assignment: &=
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:121:36: sparse: left side has type restricted __le32
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:121:36: sparse: right side has type int
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:122:36: sparse: sparse: invalid assignment: |=
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:122:36: sparse: left side has type restricted __le32
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:122:36: sparse: right side has type unsigned int
--
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_cli.c:174:30: sparse: sparse: symbol 'sxe_cdev_fops' was not declared. Should it be static?
--
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_hdc.c:42:1: sparse: sparse: symbol 'g_hdc_sema' was not declared. Should it be static?
--
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:505:36: sparse: sparse: invalid assignment: |=
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:505:36: sparse: left side has type restricted __le32
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:505:36: sparse: right side has type int
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:507:41: sparse: sparse: cast from restricted __le32
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:508:32: sparse: sparse: cast from restricted __le32
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:509:41: sparse: sparse: cast from restricted __le32
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c:510:39: sparse: sparse: cast from restricted __le32
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.c: note: in included file:
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:115:36: sparse: sparse: invalid assignment: |=
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:115:36: sparse: left side has type restricted __le32
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:115:36: sparse: right side has type unsigned int
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:121:36: sparse: sparse: invalid assignment: &=
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:121:36: sparse: left side has type restricted __le32
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:121:36: sparse: right side has type int
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:122:36: sparse: sparse: invalid assignment: |=
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:122:36: sparse: left side has type restricted __le32
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:122:36: sparse: right side has type unsigned int
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:134:36: sparse: sparse: invalid assignment: |=
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:134:36: sparse: left side has type restricted __le32
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:134:36: sparse: right side has type unsigned int
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:147:34: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le32 [usertype] mss_l4len_idx @@ got unsigned int [usertype] mss_l4len @@
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:147:34: sparse: expected restricted __le32 [usertype] mss_l4len_idx
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:147:34: sparse: got unsigned int [usertype] mss_l4len
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:128:36: sparse: sparse: invalid assignment: |=
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:128:36: sparse: left side has type restricted __le32
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:128:36: sparse: right side has type unsigned int
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:121:36: sparse: sparse: invalid assignment: &=
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:121:36: sparse: left side has type restricted __le32
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:121:36: sparse: right side has type int
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:122:36: sparse: sparse: invalid assignment: |=
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:122:36: sparse: left side has type restricted __le32
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h:122:36: sparse: right side has type unsigned int
--
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_csum.c: note: in included file:
>> drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.h:103:36: sparse: sparse: invalid assignment: |=
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.h:103:36: sparse: left side has type restricted __le32
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.h:103:36: sparse: right side has type unsigned int
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.h:77:36: sparse: sparse: invalid assignment: |=
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.h:77:36: sparse: left side has type restricted __le32
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.h:77:36: sparse: right side has type unsigned int
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.h:83:36: sparse: sparse: invalid assignment: &=
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.h:83:36: sparse: left side has type restricted __le32
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.h:83:36: sparse: right side has type int
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.h:84:36: sparse: sparse: invalid assignment: |=
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.h:84:36: sparse: left side has type restricted __le32
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_tx_proc.h:84:36: sparse: right side has type unsigned int
vim +134 drivers/net/ethernet/linkdata/sxe/sxepf/sxe_tx_proc.h
130
131 static inline void
132 sxe_ctxt_desc_tucmd_set(struct sxe_tx_context_desc *ctxt_desc, u32 tucmd)
133 {
> 134 ctxt_desc->type_tucmd_mlhl |= tucmd;
135 }
136
137 static inline void
138 sxe_ctxt_desc_sa_idx_set(struct sxe_tx_context_desc *ctxt_desc, u32 sa_idx)
139 {
140 ctxt_desc->sa_idx = sa_idx;
141 }
142
143 static inline void
144 sxe_ctxt_desc_mss_l4len_set(struct sxe_tx_context_desc *ctxt_desc,
145 u32 mss_l4len)
146 {
> 147 ctxt_desc->mss_l4len_idx = mss_l4len;
148 }
149
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-5.10 2882/2882] drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:32:19: sparse: sparse: symbol 'g_netdev' was not declared. Should it be static?
by kernel test robot 02 May '25
by kernel test robot 02 May '25
02 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-5.10
head: 46abe407b020831448331eea487e07c883e95836
commit: 8cee206b5558245197158bd20895f95cc28d8468 [2882/2882] Ethernet: Linkdata: Supports Linkdata ethernet Controllers
config: x86_64-randconfig-123-20250502 (https://download.01.org/0day-ci/archive/20250502/202505021040.redoLH7C-lkp@…)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250502/202505021040.redoLH7C-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505021040.redoLH7C-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
>> drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:32:19: sparse: sparse: symbol 'g_netdev' was not declared. Should it be static?
>> drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:262:22: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void const volatile [noderef] __iomem *addr @@ got void const *reg @@
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:262:22: sparse: expected void const volatile [noderef] __iomem *addr
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:262:22: sparse: got void const *reg
>> drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:267:23: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void volatile [noderef] __iomem *addr @@ got void *reg @@
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:267:23: sparse: expected void volatile [noderef] __iomem *addr
drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:267:23: sparse: got void *reg
vim +/g_netdev +32 drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c
30
31 static struct workqueue_struct *sxevf_wq;
> 32 struct net_device *g_netdev;
33
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-5.10 2882/2882] drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c:1071:12: error: 'sxe_resume' defined but not used
by kernel test robot 02 May '25
by kernel test robot 02 May '25
02 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-5.10
head: 46abe407b020831448331eea487e07c883e95836
commit: 8cee206b5558245197158bd20895f95cc28d8468 [2882/2882] Ethernet: Linkdata: Supports Linkdata ethernet Controllers
config: x86_64-randconfig-122-20250502 (https://download.01.org/0day-ci/archive/20250502/202505020850.kZitpRTl-lkp@…)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250502/202505020850.kZitpRTl-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505020850.kZitpRTl-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c:70:6: error: no previous prototype for 'sxe_allow_inval_mac' [-Werror=missing-prototypes]
70 | bool sxe_allow_inval_mac(void)
| ^~~~~~~~~~~~~~~~~~~
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c:1071:12: error: 'sxe_resume' defined but not used [-Werror=unused-function]
1071 | static int sxe_resume(struct device *dev)
| ^~~~~~~~~~
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c:1038:12: error: 'sxe_suspend' defined but not used [-Werror=unused-function]
1038 | static int sxe_suspend(struct device *dev)
| ^~~~~~~~~~~
cc1: all warnings being treated as errors
--
>> drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_main.c:543:12: error: 'sxevf_resume' defined but not used [-Werror=unused-function]
543 | static s32 sxevf_resume(struct device *dev)
| ^~~~~~~~~~~~
cc1: all warnings being treated as errors
vim +/sxe_resume +1071 drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c
1036
1037 #ifdef CONFIG_PM
> 1038 static int sxe_suspend(struct device *dev)
1039 {
1040 struct pci_dev *pdev = to_pci_dev(dev);
1041 int ret;
1042 bool wol_enable;
1043 struct sxe_adapter *adapter = pci_get_drvdata(pdev);
1044 struct sxe_hw *hw = &adapter->hw;
1045
1046 ret = __sxe_shutdown(pdev, &wol_enable);
1047
1048 cancel_work_sync(&adapter->monitor_ctxt.work);
1049 cancel_work_sync(&adapter->hdc_ctxt.time_sync_work);
1050
1051 sxe_hdc_channel_destroy(hw);
1052 if (ret) {
1053 LOG_ERROR_BDF("driver shutdown err:%d\n", ret);
1054 goto l_ret;
1055 }
1056
1057 LOG_DEBUG_BDF("pci dev[%p], wol_enable:%s\n", pdev,
1058 wol_enable ? "yes" : "no");
1059
1060 if (wol_enable) {
1061 pci_prepare_to_sleep(pdev);
1062 } else {
1063 pci_wake_from_d3(pdev, false);
1064 pci_set_power_state(pdev, PCI_D3hot);
1065 }
1066
1067 l_ret:
1068 return ret;
1069 }
1070
> 1071 static int sxe_resume(struct device *dev)
1072 {
1073 struct pci_dev *pdev = to_pci_dev(dev);
1074 struct sxe_adapter *adapter = pci_get_drvdata(pdev);
1075 struct net_device *netdev = adapter->netdev;
1076 s32 ret;
1077 #ifdef SXE_WOL_CONFIGURE
1078 struct sxe_hw *hw = &adapter->hw;
1079 #endif
1080
1081 pci_set_power_state(pdev, PCI_D0);
1082 pci_restore_state(pdev);
1083
1084 pci_save_state(pdev);
1085
1086 ret = pci_enable_device_mem(pdev);
1087 if (ret) {
1088 LOG_DEV_ERR("cannot enable pci device from suspend\n");
1089 goto l_ret;
1090 }
1091
1092 /* in order to force CPU ordering */
1093 smp_mb__before_atomic();
1094 clear_bit(SXE_DISABLED, &adapter->state);
1095 pci_set_master(pdev);
1096
1097 pci_wake_from_d3(pdev, false);
1098
1099 sxe_hdc_available_set(1);
1100
1101 sxe_reset(adapter);
1102
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-5.10 2882/2882] drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c:2327:6: sparse: sparse: symbol 'mcp251xfd_tx_obj_write_sync' was not declared. Should it be static?
by kernel test robot 02 May '25
by kernel test robot 02 May '25
02 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-5.10
head: 46abe407b020831448331eea487e07c883e95836
commit: b4eaf3e808dc2abcab55bc72df3b0d15961f33f0 [2882/2882] can: mcp251xfd: fix infinite loop when xmit fails
config: x86_64-randconfig-123-20250502 (https://download.01.org/0day-ci/archive/20250502/202505020705.McaLXQv7-lkp@…)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250502/202505020705.McaLXQv7-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505020705.McaLXQv7-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
>> drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c:2327:6: sparse: sparse: symbol 'mcp251xfd_tx_obj_write_sync' was not declared. Should it be static?
vim +/mcp251xfd_tx_obj_write_sync +2327 drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
2326
> 2327 void mcp251xfd_tx_obj_write_sync(struct work_struct *work)
2328 {
2329 struct mcp251xfd_priv *priv = container_of(work, struct mcp251xfd_priv,
2330 tx_work);
2331 struct mcp251xfd_tx_obj *tx_obj = priv->tx_work_obj;
2332 struct mcp251xfd_tx_ring *tx_ring = priv->tx;
2333 int err;
2334
2335 err = spi_sync(priv->spi, &tx_obj->msg);
2336 if (err)
2337 mcp251xfd_tx_failure_drop(priv, tx_ring, err);
2338 }
2339
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:openEuler-1.0-LTS 1365/1365] drivers/acpi/cppc_acpi.c:614:3-8: WARNING: NULL check before some freeing functions is not needed.
by kernel test robot 01 May '25
by kernel test robot 01 May '25
01 May '25
tree: https://gitee.com/openeuler/kernel.git openEuler-1.0-LTS
head: a48a35466505c8a52da57596944bd0b4485e825f
commit: b8815fbbe89b0d15fa3296c3e57d2197a92f5bc0 [1365/1365] ACPI: CPPC: Fix cppc_cpufreq_init failed in CPU Hotplug situation
config: x86_64-randconfig-102-20250103 (https://download.01.org/0day-ci/archive/20250501/202505010210.KOXBibOl-lkp@…)
compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505010210.KOXBibOl-lkp@intel.com/
cocci warnings: (new ones prefixed by >>)
>> drivers/acpi/cppc_acpi.c:614:3-8: WARNING: NULL check before some freeing functions is not needed.
vim +614 drivers/acpi/cppc_acpi.c
576
577 int acpi_get_psd_map(struct cppc_cpudata **all_cpu_data)
578 {
579 struct cpc_desc **cpc_pptr, *cpc_ptr;
580 int parsed_core_num = 0;
581 int i, ret;
582
583 cpc_pptr = kcalloc(num_possible_cpus(), sizeof(void *), GFP_KERNEL);
584 if (!cpc_pptr)
585 return -ENOMEM;
586 for_each_possible_cpu(i) {
587 cpc_pptr[i] = kzalloc(sizeof(struct cpc_desc), GFP_KERNEL);
588 if (!cpc_pptr[i]) {
589 ret = -ENOMEM;
590 goto out;
591 }
592 }
593
594 /*
595 * We can not use acpi_get_devices() to walk the processor devices
596 * because some processor device is not present.
597 */
598 ret = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
599 ACPI_UINT32_MAX, acpi_parse_cpc, NULL,
600 cpc_pptr, (void **)&parsed_core_num);
601 if (ret)
602 goto out;
603 if (parsed_core_num != num_possible_cpus()) {
604 ret = -EINVAL;
605 goto out;
606 }
607
608 ret = __acpi_get_psd_map(all_cpu_data, cpc_pptr);
609
610 out:
611 for_each_possible_cpu(i) {
612 cpc_ptr = cpc_pptr[i];
613 if (cpc_ptr)
> 614 kfree(cpc_ptr);
615 }
616 kfree(cpc_pptr);
617
618 return ret;
619 }
620 EXPORT_SYMBOL_GPL(acpi_get_psd_map);
621
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-6.6 2195/2195] drivers/net/ethernet/mucse/rnp/rnp_mbx_fw.c:66: warning: Cannot understand * @force_free:
by kernel test robot 01 May '25
by kernel test robot 01 May '25
01 May '25
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: 241523b7d82e629fd115303840c385702bf2ea5e
commit: 2e6ffd454acd9b4432dfee6868f3c00be7df0b6c [2195/2195] RNP: NET: Fix rnp errors dmesg show in hygon
config: loongarch-allmodconfig (https://download.01.org/0day-ci/archive/20250501/202505010014.X9c71jEV-lkp@…)
compiler: loongarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250501/202505010014.X9c71jEV-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505010014.X9c71jEV-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/net/ethernet/mucse/rnp/rnp_mbx_fw.c:66: warning: Cannot understand * @force_free:
on line 66 - I thought it was a doc line
vim +66 drivers/net/ethernet/mucse/rnp/rnp_mbx_fw.c
64
65 /**
> 66 * @force_free:
67 * true: no other reference to this cookie, it is save to mark cookie reusable
68 * false: cookie may used by other(firmware), only available after 2min
69 **/
70 static void mbx_free_cookie(struct mbx_req_cookie *cookie, bool force_free)
71 {
72 if (!cookie)
73 return;
74
75 if (force_free) {
76 cookie->stat = COOKIE_FREE;
77 } else {
78 cookie->stat = COOKIE_FREE_WAIT_TIMEOUT;
79 }
80 }
81
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:openEuler-1.0-LTS 1605/1605] block/blk-core.c:158:18: sparse: sparse: incorrect type in initializer (different address spaces)
by kernel test robot 30 Apr '25
by kernel test robot 30 Apr '25
30 Apr '25
tree: https://gitee.com/openeuler/kernel.git openEuler-1.0-LTS
head: a48a35466505c8a52da57596944bd0b4485e825f
commit: f39ebff66fab7eee91421258aa7254ee0bbac778 [1605/1605] block: support to dispatch bio asynchronously
config: x86_64-randconfig-r112-20250430 (https://download.01.org/0day-ci/archive/20250430/202504302251.rkbjGYqc-lkp@…)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250430/202504302251.rkbjGYqc-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202504302251.rkbjGYqc-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
>> block/blk-core.c:158:18: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected void const [noderef] __percpu *__vpp_verify @@ got struct bio_dispatch_async_ctl [noderef] __percpu ** @@
block/blk-core.c:158:18: sparse: expected void const [noderef] __percpu *__vpp_verify
block/blk-core.c:158:18: sparse: got struct bio_dispatch_async_ctl [noderef] __percpu **
>> block/blk-core.c:158:17: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct bio_dispatch_async_ctl *ctl @@ got struct bio_dispatch_async_ctl [noderef] __percpu * @@
block/blk-core.c:158:17: sparse: expected struct bio_dispatch_async_ctl *ctl
block/blk-core.c:158:17: sparse: got struct bio_dispatch_async_ctl [noderef] __percpu *
block/blk-core.c:222:18: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected void const [noderef] __percpu *__vpp_verify @@ got struct bio_dispatch_async_ctl [noderef] __percpu ** @@
block/blk-core.c:222:18: sparse: expected void const [noderef] __percpu *__vpp_verify
block/blk-core.c:222:18: sparse: got struct bio_dispatch_async_ctl [noderef] __percpu **
block/blk-core.c:222:17: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct bio_dispatch_async_ctl *ctl @@ got struct bio_dispatch_async_ctl [noderef] __percpu * @@
block/blk-core.c:222:17: sparse: expected struct bio_dispatch_async_ctl *ctl
block/blk-core.c:222:17: sparse: got struct bio_dispatch_async_ctl [noderef] __percpu *
>> block/blk-core.c:259:32: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct bio_dispatch_async_ctl [noderef] __percpu **static [toplevel] bio_dispatch_async_ctl @@ got struct bio_dispatch_async_ctl *[noderef] __percpu * @@
block/blk-core.c:259:32: sparse: expected struct bio_dispatch_async_ctl [noderef] __percpu **static [toplevel] bio_dispatch_async_ctl
block/blk-core.c:259:32: sparse: got struct bio_dispatch_async_ctl *[noderef] __percpu *
block/blk-core.c:269:18: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected void const [noderef] __percpu *__vpp_verify @@ got struct bio_dispatch_async_ctl [noderef] __percpu ** @@
block/blk-core.c:269:18: sparse: expected void const [noderef] __percpu *__vpp_verify
block/blk-core.c:269:18: sparse: got struct bio_dispatch_async_ctl [noderef] __percpu **
>> block/blk-core.c:269:59: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct bio_dispatch_async_ctl [noderef] __percpu * @@ got struct bio_dispatch_async_ctl *ctl @@
block/blk-core.c:269:59: sparse: expected struct bio_dispatch_async_ctl [noderef] __percpu *
block/blk-core.c:269:59: sparse: got struct bio_dispatch_async_ctl *ctl
block/blk-core.c: note: in included file:
include/linux/backing-dev.h:511:19: sparse: sparse: incompatible types in comparison expression (different address spaces):
include/linux/backing-dev.h:511:19: sparse: struct rcu_device [noderef] __rcu *
include/linux/backing-dev.h:511:19: sparse: struct rcu_device *
block/blk-core.c: In function 'blk_account_io_completion':
block/blk-core.c:2999:21: warning: variable 'cpu' set but not used [-Wunused-but-set-variable]
2999 | int cpu;
| ^~~
vim +158 block/blk-core.c
152
153 static int bio_dispatch_work(void *data)
154 {
155 int loop_count = 0;
156 int cpu = smp_processor_id();
157 struct bio_dispatch_async_ctl *ctl =
> 158 *per_cpu_ptr(bio_dispatch_async_ctl, cpu);
159
160 for (;; loop_count++) {
161 struct bio_list bio_list_on_stack;
162 struct blk_plug plug;
163 struct bio *bio;
164 int count;
165
166 bio_list_init(&bio_list_on_stack);
167 count = collect_bio(ctl, &bio_list_on_stack);
168
169 if (!count) {
170 DEFINE_WAIT(wait);
171
172 for (;;) {
173 prepare_to_wait(&ctl->wait, &wait,
174 TASK_INTERRUPTIBLE);
175 count = collect_bio(ctl, &bio_list_on_stack);
176 if (count)
177 break;
178 schedule();
179 loop_count = 0;
180 }
181 finish_wait(&ctl->wait, &wait);
182
183 }
184
185 blk_start_plug(&plug);
186 while ((bio = bio_list_pop(&bio_list_on_stack))) {
187 struct request_queue *q = bio->bi_disk->queue;
188
189 q->make_request_fn(q, bio);
190 }
191 blk_finish_plug(&plug);
192
193 /* prevent soft lockup */
194 if (loop_count >= BIO_DISPATCH_MAX_LOOP) {
195 loop_count = 0;
196 cond_resched();
197 }
198 }
199
200 return 0;
201 }
202
203 static int get_dispatch_cpu(struct request_queue *q, int cpu)
204 {
205 int *last_dispatch_cpu = per_cpu_ptr(q->last_dispatch_cpu, cpu);
206
207 cpu = cpumask_next(*last_dispatch_cpu, &q->dispatch_async_cpus);
208 if (cpu >= nr_cpu_ids)
209 cpu = cpumask_first(&q->dispatch_async_cpus);
210
211 *last_dispatch_cpu = cpu;
212
213 return cpu;
214 }
215
216 static void blk_queue_make_request_async(struct bio *bio)
217 {
218 struct request_queue *q = bio->bi_disk->queue;
219 int cpu = smp_processor_id();
220 int dispatch_cpu = get_dispatch_cpu(q, cpu);
221 struct bio_dispatch_async_ctl *ctl =
222 *per_cpu_ptr(bio_dispatch_async_ctl, dispatch_cpu);
223
224 spin_lock_irq(bio_async_lock(ctl, cpu));
225 bio_list_add(bio_async_list(ctl, cpu), bio);
226 spin_unlock_irq(bio_async_lock(ctl, cpu));
227
228 if (wq_has_sleeper(&ctl->wait))
229 wake_up(&ctl->wait);
230 }
231
232 static blk_qc_t blk_queue_do_make_request(struct bio *bio)
233 {
234 struct request_queue *q = bio->bi_disk->queue;
235 int cpu = smp_processor_id();
236
237 /*
238 * Don't dispatch bio asynchronously in following cases:
239 *
240 * 1) QUEUE_FLAG_DISPATCH_ASYNC is not set;
241 * 2) current cpu is the target cpu;
242 * 3) bio is flagged no wait;
243 * 4) TODO: return value of submit_bio() will be used in io polling.
244 */
245 if (!test_bit(QUEUE_FLAG_DISPATCH_ASYNC, &q->queue_flags) ||
246 cpumask_test_cpu(cpu, &q->dispatch_async_cpus) ||
247 bio->bi_opf & REQ_NOWAIT)
248 return q->make_request_fn(q, bio);
249
250 /* return value is not concerned */
251 blk_queue_make_request_async(bio);
252 return BLK_QC_T_NONE;
253 }
254
255 static void init_blk_queue_async_dispatch(void)
256 {
257 int cpu;
258
> 259 bio_dispatch_async_ctl = alloc_percpu(struct bio_dispatch_async_ctl *);
260 if (!bio_dispatch_async_ctl)
261 panic("Failed to alloc bio_dispatch_async_ctl\n");
262
263 for_each_possible_cpu(cpu) {
264 int i;
265 struct bio_dispatch_async_ctl *ctl =
266 kmalloc(sizeof(struct bio_dispatch_async_ctl),
267 GFP_KERNEL | __GFP_NOFAIL);
268
> 269 *per_cpu_ptr(bio_dispatch_async_ctl, cpu) = ctl;
270
271 ctl->thread =
272 kthread_create_on_cpu(bio_dispatch_work, NULL, cpu,
273 "bio_dispatch_work_%u");
274 if (IS_ERR_OR_NULL(ctl->thread))
275 panic("Failed to create bio dispatch thread\n");
276
277 ctl->list = kmalloc_array(nr_cpu_ids,
278 sizeof(struct bio_list) << BIO_ASYNC_LIST_SHIFT,
279 GFP_KERNEL | __GFP_NOFAIL);
280 ctl->lock = kmalloc_array(nr_cpu_ids,
281 sizeof(spinlock_t) << BIO_ASYNC_LOCK_SHIFT,
282 GFP_KERNEL | __GFP_NOFAIL);
283 for (i = 0; i < nr_cpu_ids; ++i) {
284 bio_list_init(bio_async_list(ctl, i));
285 spin_lock_init(bio_async_lock(ctl, i));
286 }
287
288 wake_up_process(ctl->thread);
289 init_waitqueue_head(&ctl->wait);
290 }
291 }
292
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-5.10 2880/2880] drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf.h: sxe_errno.h is included more than once.
by kernel test robot 30 Apr '25
by kernel test robot 30 Apr '25
30 Apr '25
tree: https://gitee.com/openeuler/kernel.git OLK-5.10
head: 46abe407b020831448331eea487e07c883e95836
commit: 8cee206b5558245197158bd20895f95cc28d8468 [2880/2880] Ethernet: Linkdata: Supports Linkdata ethernet Controllers
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202504302232.oeU1VyOU-lkp@intel.com/
includecheck warnings: (new ones prefixed by >>)
>> drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf.h: sxe_errno.h is included more than once.
--
>> drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c: sxevf_hw.h is included more than once.
>> drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_hw.c: sxevf.h is included more than once.
--
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_netdev.c: sxe_netdev.h is included more than once.
--
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_sriov.c: sxe_ipsec.h is included more than once.
--
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_main.c: linux/moduleparam.h is included more than once.
--
>> drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf_netdev.c: sxevf_hw.h is included more than once.
vim +25 drivers/net/ethernet/linkdata/sxevf/sxevf/sxevf.h
18
19 #include "sxe_log.h"
20 #include "sxevf_hw.h"
21 #include "sxevf_ring.h"
22 #include "sxevf_irq.h"
23 #include "sxevf_monitor.h"
24 #include "sxevf_ipsec.h"
> 25 #include "sxe_errno.h"
26 #include "sxe_compat.h"
> 27 #include "sxe_errno.h"
28
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0
From: Eric Dumazet <edumazet(a)google.com>
mainline inclusion
from mainline-v6.14-rc3
commit a42b69f692165ec39db42d595f4f65a4c8f42e44
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBPC8P
CVE: CVE-2025-21762
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
arp_xmit() can be called without RTNL or RCU protection.
Use RCU protection to avoid potential UAF.
Fixes: 29a26a568038 ("netfilter: Pass struct net into the netfilter hooks")
Signed-off-by: Eric Dumazet <edumazet(a)google.com>
Reviewed-by: David Ahern <dsahern(a)kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu(a)amazon.com>
Link: https://patch.msgid.link/20250207135841.1948589-5-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com>
---
net/ipv4/arp.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 6185e50c1972..74e27a60ace9 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -637,10 +637,12 @@ static int arp_xmit_finish(struct net *net, struct sock *sk, struct sk_buff *skb
*/
void arp_xmit(struct sk_buff *skb)
{
+ rcu_read_lock();
/* Send it off, maybe filter it using firewalling first. */
NF_HOOK(NFPROTO_ARP, NF_ARP_OUT,
- dev_net(skb->dev), NULL, skb, NULL, skb->dev,
+ dev_net_rcu(skb->dev), NULL, skb, NULL, skb->dev,
arp_xmit_finish);
+ rcu_read_unlock();
}
EXPORT_SYMBOL(arp_xmit);
--
2.25.1
2
1

[PATCH OLK-5.10] openvswitch: use RCU protection in ovs_vport_cmd_fill_info()
by Dong Chenchen 30 Apr '25
by Dong Chenchen 30 Apr '25
30 Apr '25
From: Eric Dumazet <edumazet(a)google.com>
mainline inclusion
from mainline-v6.14-rc3
commit 90b2f49a502fa71090d9f4fe29a2f51fe5dff76d
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBPC5W
CVE: CVE-2025-21761
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
ovs_vport_cmd_fill_info() can be called without RTNL or RCU.
Use RCU protection and dev_net_rcu() to avoid potential UAF.
Fixes: 9354d4520342 ("openvswitch: reliable interface indentification in port dumps")
Signed-off-by: Eric Dumazet <edumazet(a)google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu(a)amazon.com>
Link: https://patch.msgid.link/20250207135841.1948589-6-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com>
---
net/openvswitch/datapath.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index b625ab5e9a43..b493931433e9 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -1980,6 +1980,7 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
{
struct ovs_header *ovs_header;
struct ovs_vport_stats vport_stats;
+ struct net *net_vport;
int err;
ovs_header = genlmsg_put(skb, portid, seq, &dp_vport_genl_family,
@@ -1996,12 +1997,15 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
nla_put_u32(skb, OVS_VPORT_ATTR_IFINDEX, vport->dev->ifindex))
goto nla_put_failure;
- if (!net_eq(net, dev_net(vport->dev))) {
- int id = peernet2id_alloc(net, dev_net(vport->dev), gfp);
+ rcu_read_lock();
+ net_vport = dev_net_rcu(vport->dev);
+ if (!net_eq(net, net_vport)) {
+ int id = peernet2id_alloc(net, net_vport, GFP_ATOMIC);
if (nla_put_s32(skb, OVS_VPORT_ATTR_NETNSID, id))
- goto nla_put_failure;
+ goto nla_put_failure_unlock;
}
+ rcu_read_unlock();
ovs_vport_get_stats(vport, &vport_stats);
if (nla_put_64bit(skb, OVS_VPORT_ATTR_STATS,
@@ -2019,6 +2023,8 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
genlmsg_end(skb, ovs_header);
return 0;
+nla_put_failure_unlock:
+ rcu_read_unlock();
nla_put_failure:
err = -EMSGSIZE;
error:
--
2.25.1
2
1
Fix CVE-2025-21763
Eric Dumazet (1):
neighbour: use RCU protection in __neigh_notify()
Li Zetao (1):
neighbour: delete redundant judgment statements
net/core/neighbour.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
--
2.25.1
2
3

30 Apr '25
From: Ilya Maximets <i.maximets(a)ovn.org>
stable inclusion
from stable-4.19.249
commit 7438dc55c0709819b813f4778aec2c48b782990b
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBP3FB
CVE: CVE-2022-49086
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 1f30fb9166d4f15a1aa19449b9da871fe0ed4796 upstream.
While parsing user-provided actions, openvswitch module may dynamically
allocate memory and store pointers in the internal copy of the actions.
So this memory has to be freed while destroying the actions.
Currently there are only two such actions: ct() and set(). However,
there are many actions that can hold nested lists of actions and
ovs_nla_free_flow_actions() just jumps over them leaking the memory.
For example, removal of the flow with the following actions will lead
to a leak of the memory allocated by nf_ct_tmpl_alloc():
actions:clone(ct(commit),0)
Non-freed set() action may also leak the 'dst' structure for the
tunnel info including device references.
Under certain conditions with a high rate of flow rotation that may
cause significant memory leak problem (2MB per second in reporter's
case). The problem is also hard to mitigate, because the user doesn't
have direct control over the datapath flows generated by OVS.
Fix that by iterating over all the nested actions and freeing
everything that needs to be freed recursively.
New build time assertion should protect us from this problem if new
actions will be added in the future.
Unfortunately, openvswitch module doesn't use NLA_F_NESTED, so all
attributes has to be explicitly checked. sample() and clone() actions
are mixing extra attributes into the user-provided action list. That
prevents some code generalization too.
Fixes: 34ae932a4036 ("openvswitch: Make tunnel set action attach a metadata dst")
Link: https://mail.openvswitch.org/pipermail/ovs-dev/2022-March/392922.html
Reported-by: Stéphane Graber <stgraber(a)ubuntu.com>
Signed-off-by: Ilya Maximets <i.maximets(a)ovn.org>
Acked-by: Aaron Conole <aconole(a)redhat.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
[Backport for 4.19: Removed handling of OVS_ACTION_ATTR_DEC_TTL
and OVS_ACTION_ATTR_CHECK_PKT_LEN as these actions do not exist
in this version. BUILD_BUG_ON condition adjusted accordingly.]
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com>
---
net/openvswitch/flow_netlink.c | 61 +++++++++++++++++++++++++++++++---
1 file changed, 56 insertions(+), 5 deletions(-)
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index 45acc612c73b..37bbe70893eb 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -2254,6 +2254,36 @@ static struct sw_flow_actions *nla_alloc_flow_actions(int size)
return sfa;
}
+static void ovs_nla_free_nested_actions(const struct nlattr *actions, int len);
+
+static void ovs_nla_free_clone_action(const struct nlattr *action)
+{
+ const struct nlattr *a = nla_data(action);
+ int rem = nla_len(action);
+
+ switch (nla_type(a)) {
+ case OVS_CLONE_ATTR_EXEC:
+ /* The real list of actions follows this attribute. */
+ a = nla_next(a, &rem);
+ ovs_nla_free_nested_actions(a, rem);
+ break;
+ }
+}
+
+static void ovs_nla_free_sample_action(const struct nlattr *action)
+{
+ const struct nlattr *a = nla_data(action);
+ int rem = nla_len(action);
+
+ switch (nla_type(a)) {
+ case OVS_SAMPLE_ATTR_ARG:
+ /* The real list of actions follows this attribute. */
+ a = nla_next(a, &rem);
+ ovs_nla_free_nested_actions(a, rem);
+ break;
+ }
+}
+
static void ovs_nla_free_set_action(const struct nlattr *a)
{
const struct nlattr *ovs_key = nla_data(a);
@@ -2267,25 +2297,46 @@ static void ovs_nla_free_set_action(const struct nlattr *a)
}
}
-void ovs_nla_free_flow_actions(struct sw_flow_actions *sf_acts)
+static void ovs_nla_free_nested_actions(const struct nlattr *actions, int len)
{
const struct nlattr *a;
int rem;
- if (!sf_acts)
+ /* Whenever new actions are added, the need to update this
+ * function should be considered.
+ */
+ BUILD_BUG_ON(OVS_ACTION_ATTR_MAX != 20);
+
+ if (!actions)
return;
- nla_for_each_attr(a, sf_acts->actions, sf_acts->actions_len, rem) {
+ nla_for_each_attr(a, actions, len, rem) {
switch (nla_type(a)) {
- case OVS_ACTION_ATTR_SET:
- ovs_nla_free_set_action(a);
+ case OVS_ACTION_ATTR_CLONE:
+ ovs_nla_free_clone_action(a);
break;
+
case OVS_ACTION_ATTR_CT:
ovs_ct_free_action(a);
break;
+
+ case OVS_ACTION_ATTR_SAMPLE:
+ ovs_nla_free_sample_action(a);
+ break;
+
+ case OVS_ACTION_ATTR_SET:
+ ovs_nla_free_set_action(a);
+ break;
}
}
+}
+
+void ovs_nla_free_flow_actions(struct sw_flow_actions *sf_acts)
+{
+ if (!sf_acts)
+ return;
+ ovs_nla_free_nested_actions(sf_acts->actions, sf_acts->actions_len);
kfree(sf_acts);
}
--
2.25.1
2
1

30 Apr '25
From: Eric Dumazet <edumazet(a)google.com>
mainline inclusion
from mainline-v6.14-rc3
commit ed6ae1f325d3c43966ec1b62ac1459e2b8e45640
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBPC4V
CVE: CVE-2025-21760
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
ndisc_send_skb() can be called without RTNL or RCU held.
Acquire rcu_read_lock() earlier, so that we can use dev_net_rcu()
and avoid a potential UAF.
Fixes: 1762f7e88eb3 ("[NETNS][IPV6] ndisc - make socket control per namespace")
Signed-off-by: Eric Dumazet <edumazet(a)google.com>
Reviewed-by: David Ahern <dsahern(a)kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu(a)amazon.com>
Link: https://patch.msgid.link/20250207135841.1948589-8-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Conflicts:
net/ipv6/ndisc.c
[commit 696c65444120 modify param format of ndisc_send_skb(), which
not merged lead to context confict]
Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com>
---
net/ipv6/ndisc.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 5134fa7f2888..8155fdb7b0f4 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -469,16 +469,20 @@ static void ndisc_send_skb(struct sk_buff *skb,
const struct in6_addr *daddr,
const struct in6_addr *saddr)
{
+ struct icmp6hdr *icmp6h = icmp6_hdr(skb);
struct dst_entry *dst = skb_dst(skb);
- struct net *net = dev_net(skb->dev);
- struct sock *sk = net->ipv6.ndisc_sk;
struct inet6_dev *idev;
+ struct net *net;
+ struct sock *sk;
int err;
- struct icmp6hdr *icmp6h = icmp6_hdr(skb);
u8 type;
type = icmp6h->icmp6_type;
+ rcu_read_lock();
+
+ net = dev_net_rcu(skb->dev);
+ sk = net->ipv6.ndisc_sk;
if (!dst) {
struct flowi6 fl6;
int oif = skb->dev->ifindex;
@@ -486,6 +490,7 @@ static void ndisc_send_skb(struct sk_buff *skb,
icmpv6_flow_init(sk, &fl6, type, saddr, daddr, oif);
dst = icmp6_dst_alloc(skb->dev, &fl6);
if (IS_ERR(dst)) {
+ rcu_read_unlock();
kfree_skb(skb);
return;
}
@@ -500,7 +505,6 @@ static void ndisc_send_skb(struct sk_buff *skb,
ip6_nd_hdr(skb, saddr, daddr, inet6_sk(sk)->hop_limit, skb->len);
- rcu_read_lock();
idev = __in6_dev_get(dst->dev);
IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
--
2.25.1
2
1

30 Apr '25
From: Eric Dumazet <edumazet(a)google.com>
mainline inclusion
from mainline-v6.14-rc3
commit 087c1faa594fa07a66933d750c0b2610aa1a2946
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBPC5R
CVE: CVE-2025-21759
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
igmp6_send() can be called without RTNL or RCU being held.
Extend RCU protection so that we can safely fetch the net pointer
and avoid a potential UAF.
Note that we no longer can use sock_alloc_send_skb() because
ipv6.igmp_sk uses GFP_KERNEL allocations which can sleep.
Instead use alloc_skb() and charge the net->ipv6.igmp_sk
socket under RCU protection.
Fixes: b8ad0cbc58f7 ("[NETNS][IPV6] mcast - handle several network namespace")
Signed-off-by: Eric Dumazet <edumazet(a)google.com>
Reviewed-by: David Ahern <dsahern(a)kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu(a)amazon.com>
Link: https://patch.msgid.link/20250207135841.1948589-9-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Conflicts:
net/ipv6/mcast.c
[commit b4a11b2033b7 separates OUTREQUESTS stastic from MIB_OUT,
which not merged lead to context conflicts]
Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com>
---
net/ipv6/mcast.c | 33 +++++++++++++++------------------
1 file changed, 15 insertions(+), 18 deletions(-)
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 9fb5077f8e9a..95b7f3216491 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1974,21 +1974,21 @@ static void mld_send_cr(struct inet6_dev *idev)
static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
{
- struct net *net = dev_net(dev);
- struct sock *sk = net->ipv6.igmp_sk;
+ const struct in6_addr *snd_addr, *saddr;
+ int err, len, payload_len, full_len;
+ struct in6_addr addr_buf;
struct inet6_dev *idev;
struct sk_buff *skb;
struct mld_msg *hdr;
- const struct in6_addr *snd_addr, *saddr;
- struct in6_addr addr_buf;
int hlen = LL_RESERVED_SPACE(dev);
int tlen = dev->needed_tailroom;
- int err, len, payload_len, full_len;
u8 ra[8] = { IPPROTO_ICMPV6, 0,
IPV6_TLV_ROUTERALERT, 2, 0, 0,
IPV6_TLV_PADN, 0 };
- struct flowi6 fl6;
struct dst_entry *dst;
+ struct flowi6 fl6;
+ struct net *net;
+ struct sock *sk;
if (type == ICMPV6_MGM_REDUCTION)
snd_addr = &in6addr_linklocal_allrouters;
@@ -1999,20 +1999,20 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
payload_len = len + sizeof(ra);
full_len = sizeof(struct ipv6hdr) + payload_len;
- rcu_read_lock();
- IP6_UPD_PO_STATS(net, __in6_dev_get(dev),
- IPSTATS_MIB_OUT, full_len);
- rcu_read_unlock();
-
- skb = sock_alloc_send_skb(sk, hlen + tlen + full_len, 1, &err);
+ skb = alloc_skb(hlen + tlen + full_len, GFP_KERNEL);
+ rcu_read_lock();
+ net = dev_net_rcu(dev);
+ idev = __in6_dev_get(dev);
+ IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, full_len);
if (!skb) {
- rcu_read_lock();
- IP6_INC_STATS(net, __in6_dev_get(dev),
- IPSTATS_MIB_OUTDISCARDS);
+ IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
rcu_read_unlock();
return;
}
+ sk = net->ipv6.igmp_sk;
+ skb_set_owner_w(skb, sk);
+
skb->priority = TC_PRIO_CONTROL;
skb_reserve(skb, hlen);
@@ -2037,9 +2037,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
IPPROTO_ICMPV6,
csum_partial(hdr, len, 0));
- rcu_read_lock();
- idev = __in6_dev_get(skb->dev);
-
icmpv6_flow_init(sk, &fl6, type,
&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
skb->dev->ifindex);
--
2.25.1
2
1

[PATCH openEuler-1.0-LTS] netfilter: ipset: Fix overflow before widen in the bitmap_ip_create() function.
by Dong Chenchen 30 Apr '25
by Dong Chenchen 30 Apr '25
30 Apr '25
From: Gavrilov Ilia <Ilia.Gavrilov(a)infotecs.ru>
stable inclusion
from stable-v4.19.270
commit dfd834ccc1b88bbbab81b9046a3a539dd0c2d14f
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBWVWD
CVE: CVE-2023-53032
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
commit 9ea4b476cea1b7d461d16dda25ca3c7e616e2d15 upstream.
When first_ip is 0, last_ip is 0xFFFFFFFF, and netmask is 31, the value of
an arithmetic expression 2 << (netmask - mask_bits - 1) is subject
to overflow due to a failure casting operands to a larger data type
before performing the arithmetic.
Note that it's harmless since the value will be checked at the next step.
Found by InfoTeCS on behalf of Linux Verification Center
(linuxtesting.org) with SVACE.
Fixes: b9fed748185a ("netfilter: ipset: Check and reject crazy /0 input parameters")
Signed-off-by: Ilia.Gavrilov <Ilia.Gavrilov(a)infotecs.ru>
Reviewed-by: Simon Horman <simon.horman(a)corigine.com>
Signed-off-by: Pablo Neira Ayuso <pablo(a)netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com>
---
net/netfilter/ipset/ip_set_bitmap_ip.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/ipset/ip_set_bitmap_ip.c b/net/netfilter/ipset/ip_set_bitmap_ip.c
index 49a6eec6f12f..b3ca8e87f629 100644
--- a/net/netfilter/ipset/ip_set_bitmap_ip.c
+++ b/net/netfilter/ipset/ip_set_bitmap_ip.c
@@ -296,8 +296,8 @@ bitmap_ip_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
return -IPSET_ERR_BITMAP_RANGE;
pr_debug("mask_bits %u, netmask %u\n", mask_bits, netmask);
- hosts = 2 << (32 - netmask - 1);
- elements = 2 << (netmask - mask_bits - 1);
+ hosts = 2U << (32 - netmask - 1);
+ elements = 2UL << (netmask - mask_bits - 1);
}
if (elements > IPSET_BITMAP_MAX_RANGE + 1)
return -IPSET_ERR_BITMAP_RANGE_SIZE;
--
2.25.1
2
1

[PATCH openEuler-1.0-LTS] ndisc: extend RCU protection in ndisc_send_skb()
by Dong Chenchen 30 Apr '25
by Dong Chenchen 30 Apr '25
30 Apr '25
From: Eric Dumazet <edumazet(a)google.com>
mainline inclusion
from mainline-v6.14-rc3
commit ed6ae1f325d3c43966ec1b62ac1459e2b8e45640
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBPC4V
CVE: CVE-2025-21760
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
ndisc_send_skb() can be called without RTNL or RCU held.
Acquire rcu_read_lock() earlier, so that we can use dev_net_rcu()
and avoid a potential UAF.
Fixes: 1762f7e88eb3 ("[NETNS][IPV6] ndisc - make socket control per namespace")
Signed-off-by: Eric Dumazet <edumazet(a)google.com>
Reviewed-by: David Ahern <dsahern(a)kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu(a)amazon.com>
Link: https://patch.msgid.link/20250207135841.1948589-8-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Conflicts:
net/ipv6/ndisc.c
[commit 696c65444120 modify param format of ndisc_send_skb(), which
not merged lead to context confict]
Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com>
---
net/ipv6/ndisc.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 5c1d092711aa..bd3153f5a63a 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -451,16 +451,20 @@ static void ndisc_send_skb(struct sk_buff *skb,
const struct in6_addr *daddr,
const struct in6_addr *saddr)
{
+ struct icmp6hdr *icmp6h = icmp6_hdr(skb);
struct dst_entry *dst = skb_dst(skb);
- struct net *net = dev_net(skb->dev);
- struct sock *sk = net->ipv6.ndisc_sk;
struct inet6_dev *idev;
+ struct net *net;
+ struct sock *sk;
int err;
- struct icmp6hdr *icmp6h = icmp6_hdr(skb);
u8 type;
type = icmp6h->icmp6_type;
+ rcu_read_lock();
+
+ net = dev_net_rcu(skb->dev);
+ sk = net->ipv6.ndisc_sk;
if (!dst) {
struct flowi6 fl6;
int oif = skb->dev->ifindex;
@@ -468,6 +472,7 @@ static void ndisc_send_skb(struct sk_buff *skb,
icmpv6_flow_init(sk, &fl6, type, saddr, daddr, oif);
dst = icmp6_dst_alloc(skb->dev, &fl6);
if (IS_ERR(dst)) {
+ rcu_read_unlock();
kfree_skb(skb);
return;
}
@@ -482,7 +487,6 @@ static void ndisc_send_skb(struct sk_buff *skb,
ip6_nd_hdr(skb, saddr, daddr, inet6_sk(sk)->hop_limit, skb->len);
- rcu_read_lock();
idev = __in6_dev_get(dst->dev);
IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
--
2.25.1
2
1

[PATCH openEuler-1.0-LTS] ipv6: mcast: extend RCU protection in igmp6_send()
by Dong Chenchen 30 Apr '25
by Dong Chenchen 30 Apr '25
30 Apr '25
From: Eric Dumazet <edumazet(a)google.com>
mainline inclusion
from mainline-v6.14-rc3
commit 087c1faa594fa07a66933d750c0b2610aa1a2946
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBPC5R
CVE: CVE-2025-21759
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
igmp6_send() can be called without RTNL or RCU being held.
Extend RCU protection so that we can safely fetch the net pointer
and avoid a potential UAF.
Note that we no longer can use sock_alloc_send_skb() because
ipv6.igmp_sk uses GFP_KERNEL allocations which can sleep.
Instead use alloc_skb() and charge the net->ipv6.igmp_sk
socket under RCU protection.
Fixes: b8ad0cbc58f7 ("[NETNS][IPV6] mcast - handle several network namespace")
Signed-off-by: Eric Dumazet <edumazet(a)google.com>
Reviewed-by: David Ahern <dsahern(a)kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu(a)amazon.com>
Link: https://patch.msgid.link/20250207135841.1948589-9-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Conflicts:
net/ipv6/mcast.c
[commit b4a11b2033b7 separates OUTREQUESTS stastic from MIB_OUT,
which not merged lead to context conflicts]
Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com>
---
net/ipv6/mcast.c | 33 +++++++++++++++------------------
1 file changed, 15 insertions(+), 18 deletions(-)
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 3d048401141f..d2b39d9af0a3 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1979,21 +1979,21 @@ static void mld_send_cr(struct inet6_dev *idev)
static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
{
- struct net *net = dev_net(dev);
- struct sock *sk = net->ipv6.igmp_sk;
+ const struct in6_addr *snd_addr, *saddr;
+ int err, len, payload_len, full_len;
+ struct in6_addr addr_buf;
struct inet6_dev *idev;
struct sk_buff *skb;
struct mld_msg *hdr;
- const struct in6_addr *snd_addr, *saddr;
- struct in6_addr addr_buf;
int hlen = LL_RESERVED_SPACE(dev);
int tlen = dev->needed_tailroom;
- int err, len, payload_len, full_len;
u8 ra[8] = { IPPROTO_ICMPV6, 0,
IPV6_TLV_ROUTERALERT, 2, 0, 0,
IPV6_TLV_PADN, 0 };
- struct flowi6 fl6;
struct dst_entry *dst;
+ struct flowi6 fl6;
+ struct net *net;
+ struct sock *sk;
if (type == ICMPV6_MGM_REDUCTION)
snd_addr = &in6addr_linklocal_allrouters;
@@ -2004,20 +2004,20 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
payload_len = len + sizeof(ra);
full_len = sizeof(struct ipv6hdr) + payload_len;
- rcu_read_lock();
- IP6_UPD_PO_STATS(net, __in6_dev_get(dev),
- IPSTATS_MIB_OUT, full_len);
- rcu_read_unlock();
-
- skb = sock_alloc_send_skb(sk, hlen + tlen + full_len, 1, &err);
+ skb = alloc_skb(hlen + tlen + full_len, GFP_KERNEL);
+ rcu_read_lock();
+ net = dev_net_rcu(dev);
+ idev = __in6_dev_get(dev);
+ IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, full_len);
if (!skb) {
- rcu_read_lock();
- IP6_INC_STATS(net, __in6_dev_get(dev),
- IPSTATS_MIB_OUTDISCARDS);
+ IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
rcu_read_unlock();
return;
}
+ sk = net->ipv6.igmp_sk;
+ skb_set_owner_w(skb, sk);
+
skb->priority = TC_PRIO_CONTROL;
skb_reserve(skb, hlen);
@@ -2042,9 +2042,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
IPPROTO_ICMPV6,
csum_partial(hdr, len, 0));
- rcu_read_lock();
- idev = __in6_dev_get(skb->dev);
-
icmpv6_flow_init(sk, &fl6, type,
&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
skb->dev->ifindex);
--
2.25.1
2
1
Support fuse fastpath by using the newly added kernel_ipc module.
chenrenhui (2):
ipc: add kernel_ipc module to enable fast process switching
fuse: support fastpath via kernel_ipc
Kconfig | 2 +
arch/arm64/configs/openeuler_defconfig | 2 +
arch/x86/configs/openeuler_defconfig | 2 +
fs/fuse/Kconfig | 9 +
fs/fuse/dev.c | 744 +++++++++++++++++++++++++
fs/fuse/dir.c | 87 ++-
fs/fuse/file.c | 235 +++++++-
fs/fuse/fuse_i.h | 55 ++
fs/fuse/inode.c | 112 ++++
fs/fuse/readdir.c | 8 +
include/linux/kernel_ipc.h | 48 ++
include/uapi/linux/fuse.h | 15 +-
ipc/Kconfig | 5 +
ipc/Makefile | 2 +-
ipc/kernel_ipc.c | 301 ++++++++++
15 files changed, 1599 insertions(+), 28 deletions(-)
create mode 100644 include/linux/kernel_ipc.h
create mode 100644 ipc/Kconfig
create mode 100644 ipc/kernel_ipc.c
--
2.33.0
2
3

[PATCH openEuler-1.0-LTS 0/6] driver: base: fix UAF when driver_attach failed
by Yin Tirui 30 Apr '25
by Yin Tirui 30 Apr '25
30 Apr '25
The following series contains six patches that fix UAF when driver_attach failed:
Alexander Duyck (2):
driver core: Probe devices asynchronously instead of the driver
driver core: Attach devices on CPU local to device node
Jason Gunthorpe (1):
driver core: Pull required checks into driver_probe_device()
Mark-PK Tsai (1):
driver core: Prevent overriding async driver of a device before it
probe
Schspa Shi (1):
driver: base: fix UAF when driver_attach failed
Zhang Wensheng (1):
driver core: fix potential deadlock in __driver_attach
drivers/base/base.h | 2 ++
drivers/base/bus.c | 27 +++++----------------
drivers/base/dd.c | 59 ++++++++++++++++++++++++++++++++++++---------
3 files changed, 55 insertions(+), 33 deletions(-)
--
2.22.0
2
7

[PATCH OLK-6.6] PCI: brcmstb: Fix error path after a call to regulator_bulk_get()
by Zeng Heng 30 Apr '25
by Zeng Heng 30 Apr '25
30 Apr '25
From: Jim Quinlan <james.quinlan(a)broadcom.com>
stable inclusion
from stable-6.6.87
commit eedd054834930b8d678f0776cd4b091b8fffbb4a
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC1QR8
CVE: CVE-2025-22095
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 3651ad5249c51cf7eee078e12612557040a6bdb4 ]
If the regulator_bulk_get() returns an error and no regulators
are created, we need to set their number to zero.
If we don't do this and the PCIe link up fails, a call to the
regulator_bulk_free() will result in a kernel panic.
While at it, print the error value, as we cannot return an error
upwards as the kernel will WARN() on an error from add_bus().
Fixes: 9e6be018b263 ("PCI: brcmstb: Enable child bus device regulators from DT")
Signed-off-by: Jim Quinlan <james.quinlan(a)broadcom.com>
Reviewed-by: Florian Fainelli <florian.fainelli(a)broadcom.com>
Link: https://lore.kernel.org/r/20250214173944.47506-5-james.quinlan@broadcom.com
[kwilczynski: commit log, use comma in the message to match style with
other similar messages]
Signed-off-by: Krzysztof Wilczyński <kwilczynski(a)kernel.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Zeng Heng <zengheng4(a)huawei.com>
---
drivers/pci/controller/pcie-brcmstb.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index e47a77f943b1..e07fda97c7eb 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -1132,7 +1132,8 @@ static int brcm_pcie_add_bus(struct pci_bus *bus)
ret = regulator_bulk_get(dev, sr->num_supplies, sr->supplies);
if (ret) {
- dev_info(dev, "No regulators for downstream device\n");
+ dev_info(dev, "Did not get regulators, err=%d\n", ret);
+ pcie->sr = NULL;
goto no_regulators;
}
--
2.25.1
2
1
From: Al Viro <viro(a)zeniv.linux.org.uk>
stable inclusion
from stable-6.6.87
commit 324f280806aab28ef757aecc18df419676c10ef8
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC1QOU
CVE: CVE-2025-22072
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit c134deabf4784e155d360744d4a6a835b9de4dd4 ]
prior to "[POWERPC] spufs: Fix gang destroy leaks" we used to have
a problem with gang lifetimes - creation of a gang returns opened
gang directory, which normally gets removed when that gets closed,
but if somebody has created a context belonging to that gang and
kept it alive until the gang got closed, removal failed and we
ended up with a leak.
Unfortunately, it had been fixed the wrong way. Dentry of gang
directory was no longer pinned, and rmdir on close was gone.
One problem was that failure of open kept calling simple_rmdir()
as cleanup, which meant an unbalanced dput(). Another bug was
in the success case - gang creation incremented link count on
root directory, but that was no longer undone when gang got
destroyed.
Fix consists of
* reverting the commit in question
* adding a counter to gang, protected by ->i_rwsem
of gang directory inode.
* having it set to 1 at creation time, dropped
in both spufs_dir_close() and spufs_gang_close() and bumped
in spufs_create_context(), provided that it's not 0.
* using simple_recursive_removal() to take the gang
directory out when counter reaches zero.
Fixes: 877907d37da9 "[POWERPC] spufs: Fix gang destroy leaks"
Signed-off-by: Al Viro <viro(a)zeniv.linux.org.uk>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Zeng Heng <zengheng4(a)huawei.com>
---
arch/powerpc/platforms/cell/spufs/gang.c | 1 +
arch/powerpc/platforms/cell/spufs/inode.c | 54 +++++++++++++++++++----
arch/powerpc/platforms/cell/spufs/spufs.h | 2 +
3 files changed, 49 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/platforms/cell/spufs/gang.c b/arch/powerpc/platforms/cell/spufs/gang.c
index 827d338deaf4..2c2999de6bfa 100644
--- a/arch/powerpc/platforms/cell/spufs/gang.c
+++ b/arch/powerpc/platforms/cell/spufs/gang.c
@@ -25,6 +25,7 @@ struct spu_gang *alloc_spu_gang(void)
mutex_init(&gang->aff_mutex);
INIT_LIST_HEAD(&gang->list);
INIT_LIST_HEAD(&gang->aff_list_head);
+ gang->alive = 1;
out:
return gang;
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 38c5be34c895..d0c273b10a1d 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -198,6 +198,23 @@ static int spufs_fill_dir(struct dentry *dir,
return 0;
}
+static void unuse_gang(struct dentry *dir)
+{
+ struct inode *inode = dir->d_inode;
+ struct spu_gang *gang = SPUFS_I(inode)->i_gang;
+
+ if (gang) {
+ bool dead;
+
+ inode_lock(inode); // exclusion with spufs_create_context()
+ dead = !--gang->alive;
+ inode_unlock(inode);
+
+ if (dead)
+ simple_recursive_removal(dir, NULL);
+ }
+}
+
static int spufs_dir_close(struct inode *inode, struct file *file)
{
struct inode *parent;
@@ -212,6 +229,7 @@ static int spufs_dir_close(struct inode *inode, struct file *file)
inode_unlock(parent);
WARN_ON(ret);
+ unuse_gang(dir->d_parent);
return dcache_dir_close(inode, file);
}
@@ -404,7 +422,7 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
{
int ret;
int affinity;
- struct spu_gang *gang;
+ struct spu_gang *gang = SPUFS_I(inode)->i_gang;
struct spu_context *neighbor;
struct path path = {.mnt = mnt, .dentry = dentry};
@@ -419,11 +437,15 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
if ((flags & SPU_CREATE_ISOLATE) && !isolated_loader)
return -ENODEV;
- gang = NULL;
+ if (gang) {
+ if (!gang->alive)
+ return -ENOENT;
+ gang->alive++;
+ }
+
neighbor = NULL;
affinity = flags & (SPU_CREATE_AFFINITY_MEM | SPU_CREATE_AFFINITY_SPU);
if (affinity) {
- gang = SPUFS_I(inode)->i_gang;
if (!gang)
return -EINVAL;
mutex_lock(&gang->aff_mutex);
@@ -452,6 +474,8 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
out_aff_unlock:
if (affinity)
mutex_unlock(&gang->aff_mutex);
+ if (ret && gang)
+ gang->alive--; // can't reach 0
return ret;
}
@@ -481,6 +505,7 @@ spufs_mkgang(struct inode *dir, struct dentry *dentry, umode_t mode)
inode->i_fop = &simple_dir_operations;
d_instantiate(dentry, inode);
+ dget(dentry);
inc_nlink(dir);
inc_nlink(d_inode(dentry));
return ret;
@@ -491,6 +516,21 @@ spufs_mkgang(struct inode *dir, struct dentry *dentry, umode_t mode)
return ret;
}
+static int spufs_gang_close(struct inode *inode, struct file *file)
+{
+ unuse_gang(file->f_path.dentry);
+ return dcache_dir_close(inode, file);
+}
+
+static const struct file_operations spufs_gang_fops = {
+ .open = dcache_dir_open,
+ .release = spufs_gang_close,
+ .llseek = dcache_dir_lseek,
+ .read = generic_read_dir,
+ .iterate_shared = dcache_readdir,
+ .fsync = noop_fsync,
+};
+
static int spufs_gang_open(const struct path *path)
{
int ret;
@@ -510,7 +550,7 @@ static int spufs_gang_open(const struct path *path)
return PTR_ERR(filp);
}
- filp->f_op = &simple_dir_operations;
+ filp->f_op = &spufs_gang_fops;
fd_install(ret, filp);
return ret;
}
@@ -525,10 +565,8 @@ static int spufs_create_gang(struct inode *inode,
ret = spufs_mkgang(inode, dentry, mode & 0777);
if (!ret) {
ret = spufs_gang_open(&path);
- if (ret < 0) {
- int err = simple_rmdir(inode, dentry);
- WARN_ON(err);
- }
+ if (ret < 0)
+ unuse_gang(dentry);
}
return ret;
}
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 84958487f696..d33787c57c39 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -151,6 +151,8 @@ struct spu_gang {
int aff_flags;
struct spu *aff_ref_spu;
atomic_t aff_sched_count;
+
+ int alive;
};
/* Flag bits for spu_gang aff_flags */
--
2.25.1
2
1

[PATCH openEuler-1.0-LTS 0/2] driver: base: fix UAF when driver_attach failed
by Yin Tirui 30 Apr '25
by Yin Tirui 30 Apr '25
30 Apr '25
The following series contains two patches that a fix UAF when driver_attach failed:
Alexander Duyck (1):
driver core: Probe devices asynchronously instead of the driver
Schspa Shi (1):
driver: base: fix UAF when driver_attach failed
drivers/base/base.h | 2 ++
drivers/base/bus.c | 25 +++++--------------------
drivers/base/dd.c | 43 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 50 insertions(+), 20 deletions(-)
--
2.22.0
2
3
From: Grzegorz Nitka <grzegorz.nitka(a)intel.com>
stable inclusion
from stable-v6.6.84
commit 5d30d256661fc11b6e73fac6c3783a702e1006a3
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBPLKM
CVE: CVE-2025-21981
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 23d97f18901ef5e4e264e3b1777fe65c760186b5 ]
Fix aRFS (accelerated Receive Flow Steering) structures memory leak by
adding a checker to verify if aRFS memory is already allocated while
configuring VSI. aRFS objects are allocated in two cases:
- as part of VSI initialization (at probe), and
- as part of reset handling
However, VSI reconfiguration executed during reset involves memory
allocation one more time, without prior releasing already allocated
resources. This led to the memory leak with the following signature:
[root@os-delivery ~]# cat /sys/kernel/debug/kmemleak
unreferenced object 0xff3c1ca7252e6000 (size 8192):
comm "kworker/0:0", pid 8, jiffies 4296833052
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace (crc 0):
[<ffffffff991ec485>] __kmalloc_cache_noprof+0x275/0x340
[<ffffffffc0a6e06a>] ice_init_arfs+0x3a/0xe0 [ice]
[<ffffffffc09f1027>] ice_vsi_cfg_def+0x607/0x850 [ice]
[<ffffffffc09f244b>] ice_vsi_setup+0x5b/0x130 [ice]
[<ffffffffc09c2131>] ice_init+0x1c1/0x460 [ice]
[<ffffffffc09c64af>] ice_probe+0x2af/0x520 [ice]
[<ffffffff994fbcd3>] local_pci_probe+0x43/0xa0
[<ffffffff98f07103>] work_for_cpu_fn+0x13/0x20
[<ffffffff98f0b6d9>] process_one_work+0x179/0x390
[<ffffffff98f0c1e9>] worker_thread+0x239/0x340
[<ffffffff98f14abc>] kthread+0xcc/0x100
[<ffffffff98e45a6d>] ret_from_fork+0x2d/0x50
[<ffffffff98e083ba>] ret_from_fork_asm+0x1a/0x30
...
Fixes: 28bf26724fdb ("ice: Implement aRFS")
Reviewed-by: Michal Swiatkowski <michal.swiatkowski(a)linux.intel.com>
Signed-off-by: Grzegorz Nitka <grzegorz.nitka(a)intel.com>
Reviewed-by: Simon Horman <horms(a)kernel.org>
Tested-by: Rinitha S <sx.rinitha(a)intel.com> (A Contingent worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen(a)intel.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Tirui Yin <yintirui(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
---
drivers/net/ethernet/intel/ice/ice_arfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_arfs.c b/drivers/net/ethernet/intel/ice/ice_arfs.c
index cca0e753f38f..d7e0116f6773 100644
--- a/drivers/net/ethernet/intel/ice/ice_arfs.c
+++ b/drivers/net/ethernet/intel/ice/ice_arfs.c
@@ -510,7 +510,7 @@ void ice_init_arfs(struct ice_vsi *vsi)
struct hlist_head *arfs_fltr_list;
unsigned int i;
- if (!vsi || vsi->type != ICE_VSI_PF)
+ if (!vsi || vsi->type != ICE_VSI_PF || ice_is_arfs_active(vsi))
return;
arfs_fltr_list = kcalloc(ICE_MAX_ARFS_LIST, sizeof(*arfs_fltr_list),
--
2.22.0
2
1
From: Grzegorz Nitka <grzegorz.nitka(a)intel.com>
mainline inclusion
from mainline-v6.14-rc7
commit 23d97f18901ef5e4e264e3b1777fe65c760186b5
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBPLKM
CVE: CVE-2025-21981
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
Fix aRFS (accelerated Receive Flow Steering) structures memory leak by
adding a checker to verify if aRFS memory is already allocated while
configuring VSI. aRFS objects are allocated in two cases:
- as part of VSI initialization (at probe), and
- as part of reset handling
However, VSI reconfiguration executed during reset involves memory
allocation one more time, without prior releasing already allocated
resources. This led to the memory leak with the following signature:
[root@os-delivery ~]# cat /sys/kernel/debug/kmemleak
unreferenced object 0xff3c1ca7252e6000 (size 8192):
comm "kworker/0:0", pid 8, jiffies 4296833052
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace (crc 0):
[<ffffffff991ec485>] __kmalloc_cache_noprof+0x275/0x340
[<ffffffffc0a6e06a>] ice_init_arfs+0x3a/0xe0 [ice]
[<ffffffffc09f1027>] ice_vsi_cfg_def+0x607/0x850 [ice]
[<ffffffffc09f244b>] ice_vsi_setup+0x5b/0x130 [ice]
[<ffffffffc09c2131>] ice_init+0x1c1/0x460 [ice]
[<ffffffffc09c64af>] ice_probe+0x2af/0x520 [ice]
[<ffffffff994fbcd3>] local_pci_probe+0x43/0xa0
[<ffffffff98f07103>] work_for_cpu_fn+0x13/0x20
[<ffffffff98f0b6d9>] process_one_work+0x179/0x390
[<ffffffff98f0c1e9>] worker_thread+0x239/0x340
[<ffffffff98f14abc>] kthread+0xcc/0x100
[<ffffffff98e45a6d>] ret_from_fork+0x2d/0x50
[<ffffffff98e083ba>] ret_from_fork_asm+0x1a/0x30
...
Fixes: 28bf26724fdb ("ice: Implement aRFS")
Reviewed-by: Michal Swiatkowski <michal.swiatkowski(a)linux.intel.com>
Signed-off-by: Grzegorz Nitka <grzegorz.nitka(a)intel.com>
Reviewed-by: Simon Horman <horms(a)kernel.org>
Tested-by: Rinitha S <sx.rinitha(a)intel.com> (A Contingent worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen(a)intel.com>
Signed-off-by: Tirui Yin <yintirui(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
---
drivers/net/ethernet/intel/ice/ice_arfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_arfs.c b/drivers/net/ethernet/intel/ice/ice_arfs.c
index 6560acd76c94..632f16ffee40 100644
--- a/drivers/net/ethernet/intel/ice/ice_arfs.c
+++ b/drivers/net/ethernet/intel/ice/ice_arfs.c
@@ -510,7 +510,7 @@ void ice_init_arfs(struct ice_vsi *vsi)
struct hlist_head *arfs_fltr_list;
unsigned int i;
- if (!vsi || vsi->type != ICE_VSI_PF)
+ if (!vsi || vsi->type != ICE_VSI_PF || ice_is_arfs_active(vsi))
return;
arfs_fltr_list = kzalloc(sizeof(*arfs_fltr_list) * ICE_MAX_ARFS_LIST,
--
2.22.0
2
1

[PATCH OLK-6.6] HID: hid-thrustmaster: Fix warning in thrustmaster_probe by adding endpoint check
by Yin Tirui 30 Apr '25
by Yin Tirui 30 Apr '25
30 Apr '25
From: Karol Przybylski <karprzy7(a)gmail.com>
stable inclusion
from stable-v6.6.76
commit ae730deded66150204c494282969bfa98dc3ae67
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBPBL8
CVE: CVE-2024-57993
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 50420d7c79c37a3efe4010ff9b1bb14bc61ebccf ]
syzbot has found a type mismatch between a USB pipe and the transfer
endpoint, which is triggered by the hid-thrustmaster driver[1].
There is a number of similar, already fixed issues [2].
In this case as in others, implementing check for endpoint type fixes the issue.
[1] https://syzkaller.appspot.com/bug?extid=040e8b3db6a96908d470
[2] https://syzkaller.appspot.com/bug?extid=348331f63b034f89b622
Fixes: c49c33637802 ("HID: support for initialization of some Thrustmaster wheels")
Reported-by: syzbot+040e8b3db6a96908d470(a)syzkaller.appspotmail.com
Tested-by: syzbot+040e8b3db6a96908d470(a)syzkaller.appspotmail.com
Signed-off-by: Karol Przybylski <karprzy7(a)gmail.com>
Signed-off-by: Jiri Kosina <jkosina(a)suse.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Tirui Yin <yintirui(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
---
drivers/hid/hid-thrustmaster.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/hid/hid-thrustmaster.c b/drivers/hid/hid-thrustmaster.c
index cf1679b0d4fb..6c3e758bbb09 100644
--- a/drivers/hid/hid-thrustmaster.c
+++ b/drivers/hid/hid-thrustmaster.c
@@ -170,6 +170,14 @@ static void thrustmaster_interrupts(struct hid_device *hdev)
ep = &usbif->cur_altsetting->endpoint[1];
b_ep = ep->desc.bEndpointAddress;
+ /* Are the expected endpoints present? */
+ u8 ep_addr[1] = {b_ep};
+
+ if (!usb_check_int_endpoints(usbif, ep_addr)) {
+ hid_err(hdev, "Unexpected non-int endpoint\n");
+ return;
+ }
+
for (i = 0; i < ARRAY_SIZE(setup_arr); ++i) {
memcpy(send_buf, setup_arr[i], setup_arr_sizes[i]);
--
2.22.0
2
1

[PATCH openEuler-1.0-LTS 1/2] driver core: Probe devices asynchronously instead of the driver
by Yin Tirui 30 Apr '25
by Yin Tirui 30 Apr '25
30 Apr '25
From: Alexander Duyck <alexander.h.duyck(a)linux.intel.com>
mainline inclusion
from mainline-v5.19-rc1
commit ef0ff68351be4fd83bec2d797f0efdc0174a55a4
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBP35K
CVE: CVE-2022-49385
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
Probe devices asynchronously instead of the driver. This results in us
seeing the same behavior if the device is registered before the driver or
after. This way we can avoid serializing the initialization should the
driver not be loaded until after the devices have already been added.
The motivation behind this is that if we have a set of devices that
take a significant amount of time to load we can greatly reduce the time to
load by processing them in parallel instead of one at a time. In addition,
each device can exist on a different node so placing a single thread on one
CPU to initialize all of the devices for a given driver can result in poor
performance on a system with multiple nodes.
This approach can reduce the time needed to scan SCSI LUNs significantly.
The only way to realize that speedup is by enabling more concurrency which
is what is achieved with this patch.
To achieve this it was necessary to add a new member "async_driver" to the
device_private structure to store the driver pointer while we wait on the
deferred probe call.
Reviewed-by: Bart Van Assche <bvanassche(a)acm.org>
Reviewed-by: Dan Williams <dan.j.williams(a)intel.com>
Signed-off-by: Alexander Duyck <alexander.h.duyck(a)linux.intel.com>
Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki(a)intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Signed-off-by: Yin Tirui <yintirui(a)huawei.com>
Reviewed-by: Weilong Chen <chenweilong(a)huawei.com>
---
drivers/base/base.h | 2 ++
drivers/base/bus.c | 23 +++--------------------
drivers/base/dd.c | 43 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 48 insertions(+), 20 deletions(-)
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 2d270b8c731a..92803ce31257 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -64,6 +64,7 @@ struct driver_private {
* binding of drivers which were unable to get all the resources needed by
* the device; typically because it depends on another driver getting
* probed first.
+ * @async_driver - pointer to device driver awaiting probe via async_probe
* @device - pointer back to the struct device that this structure is
* associated with.
* @dead - This device is currently either in the process of or has been
@@ -78,6 +79,7 @@ struct device_private {
struct klist_node knode_driver;
struct klist_node knode_bus;
struct list_head deferred_probe;
+ struct device_driver *async_driver;
struct device *device;
u8 dead:1;
};
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 5f1966081c42..07876b6aac57 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -611,17 +611,6 @@ static ssize_t uevent_store(struct device_driver *drv, const char *buf,
}
static DRIVER_ATTR_WO(uevent);
-static void driver_attach_async(void *_drv, async_cookie_t cookie)
-{
- struct device_driver *drv = _drv;
- int ret;
-
- ret = driver_attach(drv);
-
- pr_debug("bus: '%s': driver %s async attach completed: %d\n",
- drv->bus->name, drv->name, ret);
-}
-
/**
* bus_add_driver - Add a driver to the bus.
* @drv: driver.
@@ -654,15 +643,9 @@ int bus_add_driver(struct device_driver *drv)
klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
if (drv->bus->p->drivers_autoprobe) {
- if (driver_allows_async_probing(drv)) {
- pr_debug("bus: '%s': probing driver %s asynchronously\n",
- drv->bus->name, drv->name);
- async_schedule(driver_attach_async, drv);
- } else {
- error = driver_attach(drv);
- if (error)
- goto out_unregister;
- }
+ error = driver_attach(drv);
+ if (error)
+ goto out_unregister;
}
module_add_driver(drv->owner, drv);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 432a5645bac3..b69691f5d217 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -928,6 +928,30 @@ int device_driver_attach(struct device_driver *drv, struct device *dev)
return ret;
}
+static void __driver_attach_async_helper(void *_dev, async_cookie_t cookie)
+{
+ struct device *dev = _dev;
+ struct device_driver *drv;
+ int ret = 0;
+
+ __device_driver_lock(dev, dev->parent);
+
+ drv = dev->p->async_driver;
+
+ /*
+ * If device has been removed or someone has already successfully
+ * bound a driver before us just skip the driver probe call.
+ */
+ if (!dev->p->dead && !dev->driver)
+ ret = driver_probe_device(drv, dev);
+
+ __device_driver_unlock(dev, dev->parent);
+
+ dev_dbg(dev, "driver %s async attach completed: %d\n", drv->name, ret);
+
+ put_device(dev);
+}
+
static int __driver_attach(struct device *dev, void *data)
{
struct device_driver *drv = data;
@@ -964,6 +988,25 @@ static int __driver_attach(struct device *dev, void *data)
return 0;
} /* ret > 0 means positive match */
+ if (driver_allows_async_probing(drv)) {
+ /*
+ * Instead of probing the device synchronously we will
+ * probe it asynchronously to allow for more parallelism.
+ *
+ * We only take the device lock here in order to guarantee
+ * that the dev->driver and async_driver fields are protected
+ */
+ dev_dbg(dev, "probing driver %s asynchronously\n", drv->name);
+ device_lock(dev);
+ if (!dev->driver) {
+ get_device(dev);
+ dev->p->async_driver = drv;
+ async_schedule(__driver_attach_async_helper, dev);
+ }
+ device_unlock(dev);
+ return 0;
+ }
+
device_driver_attach(drv, dev);
return 0;
--
2.22.0
2
2

30 Apr '25
Offering: HULK
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IBYXQD
CVE: NA
---------------------------
When using null_blk with a large readahead window, calling madvise to
trigger readahead can lead to system softlocks. This occurs because
the CPU can remain in the mpage_readpages loop for extended periods
without rescheduling, preventing other processes from running.
Add a cond_resched() call at the beginning of each loop iteration to
allow the CPU to schedule other tasks when necessary, avoiding potential
softlocks during heavy readahead operations.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Zheng Qixing <zhengqixing(a)huawei.com>
---
fs/mpage.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/mpage.c b/fs/mpage.c
index fb2ff971c66b..d67a2bae0b87 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -394,6 +394,7 @@ mpage_readpages(struct address_space *mapping, struct list_head *pages,
for (page_idx = 0; page_idx < nr_pages; page_idx++) {
struct page *page = lru_to_page(pages);
+ cond_resched();
prefetchw(&page->flags);
list_del(&page->lru);
if (!add_to_page_cache_lru(page, mapping,
--
2.39.2
2
1

30 Apr '25
From: Eric Dumazet <edumazet(a)google.com>
mainline inclusion
from mainline-v6.14-rc3
commit a42b69f692165ec39db42d595f4f65a4c8f42e44
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBPC8P
CVE: CVE-2025-21762
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
arp_xmit() can be called without RTNL or RCU protection.
Use RCU protection to avoid potential UAF.
Fixes: 29a26a568038 ("netfilter: Pass struct net into the netfilter hooks")
Signed-off-by: Eric Dumazet <edumazet(a)google.com>
Reviewed-by: David Ahern <dsahern(a)kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu(a)amazon.com>
Link: https://patch.msgid.link/20250207135841.1948589-5-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com>
---
net/ipv4/arp.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index fccf246e4263..638e6e91441b 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -639,10 +639,12 @@ static int arp_xmit_finish(struct net *net, struct sock *sk, struct sk_buff *skb
*/
void arp_xmit(struct sk_buff *skb)
{
+ rcu_read_lock();
/* Send it off, maybe filter it using firewalling first. */
NF_HOOK(NFPROTO_ARP, NF_ARP_OUT,
- dev_net(skb->dev), NULL, skb, NULL, skb->dev,
+ dev_net_rcu(skb->dev), NULL, skb, NULL, skb->dev,
arp_xmit_finish);
+ rcu_read_unlock();
}
EXPORT_SYMBOL(arp_xmit);
--
2.25.1
2
1

[PATCH openEuler-1.0-LTS] openvswitch: use RCU protection in ovs_vport_cmd_fill_info()
by Dong Chenchen 30 Apr '25
by Dong Chenchen 30 Apr '25
30 Apr '25
From: Eric Dumazet <edumazet(a)google.com>
mainline inclusion
from mainline-v6.14-rc3
commit 90b2f49a502fa71090d9f4fe29a2f51fe5dff76d
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBPC5W
CVE: CVE-2025-21761
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
ovs_vport_cmd_fill_info() can be called without RTNL or RCU.
Use RCU protection and dev_net_rcu() to avoid potential UAF.
Fixes: 9354d4520342 ("openvswitch: reliable interface indentification in port dumps")
Signed-off-by: Eric Dumazet <edumazet(a)google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu(a)amazon.com>
Link: https://patch.msgid.link/20250207135841.1948589-6-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba(a)kernel.org>
Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com>
---
net/openvswitch/datapath.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 9143d4ee1c33..2dac3aaa8520 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -1873,6 +1873,7 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
{
struct ovs_header *ovs_header;
struct ovs_vport_stats vport_stats;
+ struct net *net_vport;
int err;
ovs_header = genlmsg_put(skb, portid, seq, &dp_vport_genl_family,
@@ -1889,12 +1890,15 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
nla_put_u32(skb, OVS_VPORT_ATTR_IFINDEX, vport->dev->ifindex))
goto nla_put_failure;
- if (!net_eq(net, dev_net(vport->dev))) {
- int id = peernet2id_alloc(net, dev_net(vport->dev), gfp);
+ rcu_read_lock();
+ net_vport = dev_net_rcu(vport->dev);
+ if (!net_eq(net, net_vport)) {
+ int id = peernet2id_alloc(net, net_vport, GFP_ATOMIC);
if (nla_put_s32(skb, OVS_VPORT_ATTR_NETNSID, id))
- goto nla_put_failure;
+ goto nla_put_failure_unlock;
}
+ rcu_read_unlock();
ovs_vport_get_stats(vport, &vport_stats);
if (nla_put_64bit(skb, OVS_VPORT_ATTR_STATS,
@@ -1912,6 +1916,8 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
genlmsg_end(skb, ovs_header);
return 0;
+nla_put_failure_unlock:
+ rcu_read_unlock();
nla_put_failure:
err = -EMSGSIZE;
error:
--
2.25.1
2
1
Fix CVE-2025-21763
Eric Dumazet (1):
neighbour: use RCU protection in __neigh_notify()
Li Zetao (1):
neighbour: delete redundant judgment statements
net/core/neighbour.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
--
2.25.1
2
3

[PATCH OLK-6.6] mm: zswap: handle incorrect attempts to load large folios
by Tong Tiangen 30 Apr '25
by Tong Tiangen 30 Apr '25
30 Apr '25
From: Yosry Ahmed <yosryahmed(a)google.com>
mainline inclusion
from mainline-v6.11-rc1
commit c63f210d4891f5b1b1057a0d7c91d2b0d15431d1
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IC3A3N
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
--------------------------------
Zswap does not support storing or loading large folios. Until proper
support is added, attempts to load large folios from zswap are a bug.
For example, if a swapin fault observes that contiguous PTEs are pointing
to contiguous swap entries and tries to swap them in as a large folio,
swap_read_folio() will pass in a large folio to zswap_load(), but
zswap_load() will only effectively load the first page in the folio. If
the first page is not in zswap, the folio will be read from disk, even
though other pages may be in zswap.
In both cases, this will lead to silent data corruption. Proper support
needs to be added before large folio swapins and zswap can work together.
Looking at callers of swap_read_folio(), it seems like they are either
allocated from __read_swap_cache_async() or do_swap_page() in the
SWP_SYNCHRONOUS_IO path. Both of which allocate order-0 folios, so
everything is fine for now.
However, there is ongoing work to add to support large folio swapins [1].
To make sure new development does not break zswap (or get broken by
zswap), add minimal handling of incorrect loads of large folios to zswap.
First, move the call folio_mark_uptodate() inside zswap_load().
If a large folio load is attempted, and zswap was ever enabled on the
system, return 'true' without calling folio_mark_uptodate(). This will
prevent the folio from being read from disk, and will emit an IO error
because the folio is not uptodate (e.g. do_swap_fault() will return
VM_FAULT_SIGBUS). It may not be reliable recovery in all cases, but it is
better than nothing.
This was tested by hacking the allocation in __read_swap_cache_async() to
use order 2 and __GFP_COMP.
In the future, to handle this correctly, the swapin code should:
(a) Fall back to order-0 swapins if zswap was ever used on the
machine, because compressed pages remain in zswap after it is
disabled.
(b) Add proper support to swapin large folios from zswap (fully or
partially).
Probably start with (a) then followup with (b).
[1]https://lore.kernel.org/linux-mm/20240304081348.197341-6-21cnbao@gmail.co…
Link: https://lkml.kernel.org/r/20240611024516.1375191-3-yosryahmed@google.com
Signed-off-by: Yosry Ahmed <yosryahmed(a)google.com>
Acked-by: Barry Song <baohua(a)kernel.org>
Cc: Barry Song <baohua(a)kernel.org>
Cc: Chengming Zhou <chengming.zhou(a)linux.dev>
Cc: Chris Li <chrisl(a)kernel.org>
Cc: David Hildenbrand <david(a)redhat.com>
Cc: Johannes Weiner <hannes(a)cmpxchg.org>
Cc: Matthew Wilcox (Oracle) <willy(a)infradead.org>
Cc: Nhat Pham <nphamcs(a)gmail.com>
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
Conflicts:
mm/zswap.c
mm/page_io.c
[context conflict because of a large number of zswap patchs are not
merged, mainly include: 1. 5b297f70bb2 "mm: zswap: inline and remove
zswap_entry_find_get()", 2. 796c2c23e14e "zswap: replace RB tree with
xarray", 3. 66447fd036a5 "mm/zswap: cleanup zswap_load()"]
Signed-off-by: Tong Tiangen <tongtiangen(a)huawei.com>
---
mm/page_io.c | 1 -
mm/zswap.c | 14 ++++++++++++++
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/mm/page_io.c b/mm/page_io.c
index 839a3b0a90f0..63817e97b472 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -521,7 +521,6 @@ void swap_read_folio(struct folio *folio, bool synchronous,
delayacct_swapin_start();
if (zswap_load(folio)) {
- folio_mark_uptodate(folio);
folio_unlock(folio);
} else if (data_race(sis->flags & SWP_FS_OPS)) {
swap_read_folio_fs(folio, plug);
diff --git a/mm/zswap.c b/mm/zswap.c
index 491487925192..dcf44712f0bf 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c
@@ -1419,6 +1419,17 @@ bool zswap_load(struct folio *folio)
if (zswap_never_enabled())
return false;
+ /*
+ * Large folios should not be swapped in while zswap is being used, as
+ * they are not properly handled. Zswap does not properly load large
+ * folios, and a large folio may only be partially in zswap.
+ *
+ * Return true without marking the folio uptodate so that an IO error is
+ * emitted (e.g. do_swap_page() will sigbus).
+ */
+ if (WARN_ON_ONCE(folio_test_large(folio)))
+ return true;
+
/* find */
spin_lock(&tree->lock);
entry = zswap_entry_find_get(&tree->rbroot, offset);
@@ -1488,6 +1499,9 @@ bool zswap_load(struct folio *folio)
zswap_entry_put(tree, entry);
spin_unlock(&tree->lock);
+ if (ret == true)
+ folio_mark_uptodate(folio);
+
return ret;
}
--
2.25.1
2
2

30 Apr '25
From: Jamie Bainbridge <jamie.bainbridge(a)gmail.com>
stable inclusion
from stable-v4.19.238
commit 9648adb1b3ece55c657d3a4f52bfee663b710dfe
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBP4XO
CVE: CVE-2022-49084
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
----------------------------------------------------------------
[ Upstream commit 4e910dbe36508654a896d5735b318c0b88172570 ]
qede_build_skb() assumes build_skb() always works and goes straight
to skb_reserve(). However, build_skb() can fail under memory pressure.
This results in a kernel panic because the skb to reserve is NULL.
Add a check in case build_skb() failed to allocate and return NULL.
The NULL return is handled correctly in callers to qede_build_skb().
Fixes: 8a8633978b842 ("qede: Add build_skb() support.")
Signed-off-by: Jamie Bainbridge <jamie.bainbridge(a)gmail.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Zhang Zekun <zhangzekun11(a)huawei.com>
---
drivers/net/ethernet/qlogic/qede/qede_fp.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/qlogic/qede/qede_fp.c b/drivers/net/ethernet/qlogic/qede/qede_fp.c
index a96da16f3404..09ca436e7d49 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_fp.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c
@@ -731,6 +731,9 @@ qede_build_skb(struct qede_rx_queue *rxq,
buf = page_address(bd->data) + bd->page_offset;
skb = build_skb(buf, rxq->rx_buf_seg_size);
+ if (unlikely(!skb))
+ return NULL;
+
skb_reserve(skb, pad);
skb_put(skb, len);
--
2.22.0
2
1

30 Apr '25
Offering: HULK
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IBYXQD
---------------------------
When using null_blk with a large readahead window, calling madvise to
trigger readahead can lead to system softlocks. This occurs because
the CPU can remain in the mpage_readpages loop for extended periods
without rescheduling, preventing other processes from running.
Add a cond_resched() call at the beginning of each loop iteration to
allow the CPU to schedule other tasks when necessary, avoiding potential
softlocks during heavy readahead operations.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Zheng Qixing <zhengqixing(a)huawei.com>
---
fs/mpage.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/mpage.c b/fs/mpage.c
index fb2ff971c66b..d67a2bae0b87 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -394,6 +394,7 @@ mpage_readpages(struct address_space *mapping, struct list_head *pages,
for (page_idx = 0; page_idx < nr_pages; page_idx++) {
struct page *page = lru_to_page(pages);
+ cond_resched();
prefetchw(&page->flags);
list_del(&page->lru);
if (!add_to_page_cache_lru(page, mapping,
--
2.39.2
2
1

30 Apr '25
From: Yu Kuai <yukuai3(a)huawei.com>
mainline inclusion
from mainline-v6.15-rc1
commit e879a0d9cb086c8e52ce6c04e5bfa63825a6213c
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC1QST
CVE: CVE-2025-22125
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
------------------
If blk-wbt is enabled by default, it's found that raid write performance
is quite bad because all IO are throttled by wbt of underlying disks,
due to flag REQ_IDLE is ignored. And turns out this behaviour exist since
blk-wbt is introduced.
Other than REQ_IDLE, other flags should not be ignored as well, for
example REQ_META can be set for filesystems, clearing it can cause priority
reverse problems; And REQ_NOWAIT should not be cleared as well, because
io will wait instead of failing directly in underlying disks.
Fix those problems by keep IO flags from master bio.
Fises: f51d46d0e7cb ("md: add support for REQ_NOWAIT")
Fixes: e34cbd307477 ("blk-wbt: add general throttling mechanism")
Fixes: 5404bc7a87b9 ("[PATCH] Allow file systems to differentiate between data and meta reads")
Link: https://lore.kernel.org/linux-raid/20250227121657.832356-1-yukuai1@huaweicl…
Signed-off-by: Yu Kuai <yukuai3(a)huawei.com>
Conflicts:
drivers/md/raid1.c
drivers/md/raid10.c
[Due to not merging commit 3c5e514db58f ("md/raid1: Use the new blk_opf_t
type"), commit cb1802ff82e1 ("md/raid10: Use the new blk_opf_t type"),
commit c34b7ac65087 ("block: remove bio_set_op_attrs") and commit
f2a38abf5f1c ("md/raid1: Atomic write support").]
Signed-off-by: Zheng Qixing <zhengqixing(a)huawei.com>
---
drivers/md/raid1.c | 4 ----
drivers/md/raid10.c | 7 -------
2 files changed, 11 deletions(-)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 6ad47783e974..0275dcb18692 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1199,8 +1199,6 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
struct raid1_info *mirror;
struct bio *read_bio;
struct bitmap *bitmap = mddev->bitmap;
- const int op = bio_op(bio);
- const unsigned long do_sync = (bio->bi_opf & REQ_SYNC);
int max_sectors;
int rdisk;
bool print_msg = !!r1_bio;
@@ -1293,7 +1291,6 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
mirror->rdev->data_offset;
bio_set_dev(read_bio, mirror->rdev->bdev);
read_bio->bi_end_io = raid1_end_read_request;
- bio_set_op_attrs(read_bio, op, do_sync);
if (test_bit(FailFast, &mirror->rdev->flags) &&
test_bit(R1BIO_FailFast, &r1_bio->state))
read_bio->bi_opf |= MD_FAILFAST;
@@ -1519,7 +1516,6 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
conf->mirrors[i].rdev->data_offset);
bio_set_dev(mbio, conf->mirrors[i].rdev->bdev);
mbio->bi_end_io = raid1_end_write_request;
- mbio->bi_opf = bio_op(bio) | (bio->bi_opf & (REQ_SYNC | REQ_FUA));
if (test_bit(FailFast, &conf->mirrors[i].rdev->flags) &&
!test_bit(WriteMostly, &conf->mirrors[i].rdev->flags) &&
conf->raid_disks - mddev->degraded > 1)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index f8fea9593955..07d58e88eb7b 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1166,8 +1166,6 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
{
struct r10conf *conf = mddev->private;
struct bio *read_bio;
- const int op = bio_op(bio);
- const unsigned long do_sync = (bio->bi_opf & REQ_SYNC);
int max_sectors;
sector_t sectors;
struct md_rdev *rdev;
@@ -1264,7 +1262,6 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
choose_data_offset(r10_bio, rdev);
bio_set_dev(read_bio, rdev->bdev);
read_bio->bi_end_io = raid10_end_read_request;
- bio_set_op_attrs(read_bio, op, do_sync);
if (test_bit(FailFast, &rdev->flags) &&
test_bit(R10BIO_FailFast, &r10_bio->state))
read_bio->bi_opf |= MD_FAILFAST;
@@ -1282,9 +1279,6 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
struct bio *bio, bool replacement,
int n_copy)
{
- const int op = bio_op(bio);
- const unsigned long do_sync = (bio->bi_opf & REQ_SYNC);
- const unsigned long do_fua = (bio->bi_opf & REQ_FUA);
unsigned long flags;
struct blk_plug_cb *cb;
struct raid10_plug_cb *plug = NULL;
@@ -1313,7 +1307,6 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
choose_data_offset(r10_bio, rdev));
bio_set_dev(mbio, rdev->bdev);
mbio->bi_end_io = raid10_end_write_request;
- bio_set_op_attrs(mbio, op, do_sync | do_fua);
if (!replacement && test_bit(FailFast,
&conf->mirrors[devnum].rdev->flags)
&& enough(conf, devnum))
--
2.39.2
2
1

30 Apr '25
From: Yu Kuai <yukuai3(a)huawei.com>
mainline inclusion
from mainline-v6.15-rc1
commit e879a0d9cb086c8e52ce6c04e5bfa63825a6213c
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC1QST
CVE: CVE-2025-22125
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
------------------
If blk-wbt is enabled by default, it's found that raid write performance
is quite bad because all IO are throttled by wbt of underlying disks,
due to flag REQ_IDLE is ignored. And turns out this behaviour exist since
blk-wbt is introduced.
Other than REQ_IDLE, other flags should not be ignored as well, for
example REQ_META can be set for filesystems, clearing it can cause priority
reverse problems; And REQ_NOWAIT should not be cleared as well, because
io will wait instead of failing directly in underlying disks.
Fix those problems by keep IO flags from master bio.
Fises: f51d46d0e7cb ("md: add support for REQ_NOWAIT")
Fixes: e34cbd307477 ("blk-wbt: add general throttling mechanism")
Fixes: 5404bc7a87b9 ("[PATCH] Allow file systems to differentiate between data and meta reads")
Link: https://lore.kernel.org/linux-raid/20250227121657.832356-1-yukuai1@huaweicl…
Signed-off-by: Yu Kuai <yukuai3(a)huawei.com>
Conflicts:
drivers/md/raid1.c
drivers/md/raid10.c
[Due to not merging commit 3c5e514db58f ("md/raid1: Use the new blk_opf_t
type"), commit cb1802ff82e1 ("md/raid10: Use the new blk_opf_t type"),
commit c34b7ac65087 ("block: remove bio_set_op_attrs") and commit
f2a38abf5f1c ("md/raid1: Atomic write support").]
Signed-off-by: Zheng Qixing <zhengqixing(a)huawei.com>
---
drivers/md/raid1.c | 4 ----
drivers/md/raid10.c | 7 -------
2 files changed, 11 deletions(-)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 6ad47783e974..0275dcb18692 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1199,8 +1199,6 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
struct raid1_info *mirror;
struct bio *read_bio;
struct bitmap *bitmap = mddev->bitmap;
- const int op = bio_op(bio);
- const unsigned long do_sync = (bio->bi_opf & REQ_SYNC);
int max_sectors;
int rdisk;
bool print_msg = !!r1_bio;
@@ -1293,7 +1291,6 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
mirror->rdev->data_offset;
bio_set_dev(read_bio, mirror->rdev->bdev);
read_bio->bi_end_io = raid1_end_read_request;
- bio_set_op_attrs(read_bio, op, do_sync);
if (test_bit(FailFast, &mirror->rdev->flags) &&
test_bit(R1BIO_FailFast, &r1_bio->state))
read_bio->bi_opf |= MD_FAILFAST;
@@ -1519,7 +1516,6 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
conf->mirrors[i].rdev->data_offset);
bio_set_dev(mbio, conf->mirrors[i].rdev->bdev);
mbio->bi_end_io = raid1_end_write_request;
- mbio->bi_opf = bio_op(bio) | (bio->bi_opf & (REQ_SYNC | REQ_FUA));
if (test_bit(FailFast, &conf->mirrors[i].rdev->flags) &&
!test_bit(WriteMostly, &conf->mirrors[i].rdev->flags) &&
conf->raid_disks - mddev->degraded > 1)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index f8fea9593955..07d58e88eb7b 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1166,8 +1166,6 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
{
struct r10conf *conf = mddev->private;
struct bio *read_bio;
- const int op = bio_op(bio);
- const unsigned long do_sync = (bio->bi_opf & REQ_SYNC);
int max_sectors;
sector_t sectors;
struct md_rdev *rdev;
@@ -1264,7 +1262,6 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
choose_data_offset(r10_bio, rdev);
bio_set_dev(read_bio, rdev->bdev);
read_bio->bi_end_io = raid10_end_read_request;
- bio_set_op_attrs(read_bio, op, do_sync);
if (test_bit(FailFast, &rdev->flags) &&
test_bit(R10BIO_FailFast, &r10_bio->state))
read_bio->bi_opf |= MD_FAILFAST;
@@ -1282,9 +1279,6 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
struct bio *bio, bool replacement,
int n_copy)
{
- const int op = bio_op(bio);
- const unsigned long do_sync = (bio->bi_opf & REQ_SYNC);
- const unsigned long do_fua = (bio->bi_opf & REQ_FUA);
unsigned long flags;
struct blk_plug_cb *cb;
struct raid10_plug_cb *plug = NULL;
@@ -1313,7 +1307,6 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
choose_data_offset(r10_bio, rdev));
bio_set_dev(mbio, rdev->bdev);
mbio->bi_end_io = raid10_end_write_request;
- bio_set_op_attrs(mbio, op, do_sync | do_fua);
if (!replacement && test_bit(FailFast,
&conf->mirrors[devnum].rdev->flags)
&& enough(conf, devnum))
--
2.39.2
2
1
From: Yu Kuai <yukuai3(a)huawei.com>
mainline inclusion
from mainline-v6.15-rc1
commit e879a0d9cb086c8e52ce6c04e5bfa63825a6213c
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IC1QST
CVE: CVE-2025-22125
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
------------------
If blk-wbt is enabled by default, it's found that raid write performance
is quite bad because all IO are throttled by wbt of underlying disks,
due to flag REQ_IDLE is ignored. And turns out this behaviour exist since
blk-wbt is introduced.
Other than REQ_IDLE, other flags should not be ignored as well, for
example REQ_META can be set for filesystems, clearing it can cause priority
reverse problems; And REQ_NOWAIT should not be cleared as well, because
io will wait instead of failing directly in underlying disks.
Fix those problems by keep IO flags from master bio.
Fises: f51d46d0e7cb ("md: add support for REQ_NOWAIT")
Fixes: e34cbd307477 ("blk-wbt: add general throttling mechanism")
Fixes: 5404bc7a87b9 ("[PATCH] Allow file systems to differentiate between data and meta reads")
Link: https://lore.kernel.org/linux-raid/20250227121657.832356-1-yukuai1@huaweicl…
Signed-off-by: Yu Kuai <yukuai3(a)huawei.com>
Conflicts:
drivers/md/raid1.c
[Due to not merging f2a38abf5f1c ("md/raid1: Atomic write support").]
drivers/md/raid10.c
[Due to not merging a1d9b4fd42d9 ("md/raid10: Atomic write support").]
Signed-off-by: Zheng Qixing <zhengqixing(a)huawei.com>
---
drivers/md/raid1.c | 4 ----
drivers/md/raid10.c | 7 -------
2 files changed, 11 deletions(-)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 1be011a700f8..4b7e68276d6c 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1212,8 +1212,6 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
struct raid1_info *mirror;
struct bio *read_bio;
struct bitmap *bitmap = mddev->bitmap;
- const enum req_op op = bio_op(bio);
- const blk_opf_t do_sync = bio->bi_opf & REQ_SYNC;
int max_sectors;
int rdisk;
bool r1bio_existed = !!r1_bio;
@@ -1311,7 +1309,6 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
read_bio->bi_iter.bi_sector = r1_bio->sector +
mirror->rdev->data_offset;
read_bio->bi_end_io = raid1_end_read_request;
- read_bio->bi_opf = op | do_sync;
if (test_bit(FailFast, &mirror->rdev->flags) &&
test_bit(R1BIO_FailFast, &r1_bio->state))
read_bio->bi_opf |= MD_FAILFAST;
@@ -1532,7 +1529,6 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
mbio->bi_iter.bi_sector = (r1_bio->sector + rdev->data_offset);
mbio->bi_end_io = raid1_end_write_request;
- mbio->bi_opf = bio_op(bio) | (bio->bi_opf & (REQ_SYNC | REQ_FUA));
if (test_bit(FailFast, &rdev->flags) &&
!test_bit(WriteMostly, &rdev->flags) &&
conf->raid_disks - mddev->degraded > 1)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 5d197d747697..1f7fa6f8f84e 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1161,8 +1161,6 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
{
struct r10conf *conf = mddev->private;
struct bio *read_bio;
- const enum req_op op = bio_op(bio);
- const blk_opf_t do_sync = bio->bi_opf & REQ_SYNC;
int max_sectors;
struct md_rdev *rdev;
char b[BDEVNAME_SIZE];
@@ -1238,7 +1236,6 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
read_bio->bi_iter.bi_sector = r10_bio->devs[slot].addr +
choose_data_offset(r10_bio, rdev);
read_bio->bi_end_io = raid10_end_read_request;
- read_bio->bi_opf = op | do_sync;
if (test_bit(FailFast, &rdev->flags) &&
test_bit(R10BIO_FailFast, &r10_bio->state))
read_bio->bi_opf |= MD_FAILFAST;
@@ -1255,9 +1252,6 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
struct bio *bio, bool replacement,
int n_copy)
{
- const enum req_op op = bio_op(bio);
- const blk_opf_t do_sync = bio->bi_opf & REQ_SYNC;
- const blk_opf_t do_fua = bio->bi_opf & REQ_FUA;
unsigned long flags;
struct r10conf *conf = mddev->private;
struct md_rdev *rdev;
@@ -1276,7 +1270,6 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
mbio->bi_iter.bi_sector = (r10_bio->devs[n_copy].addr +
choose_data_offset(r10_bio, rdev));
mbio->bi_end_io = raid10_end_write_request;
- mbio->bi_opf = op | do_sync | do_fua;
if (!replacement && test_bit(FailFast,
&conf->mirrors[devnum].rdev->flags)
&& enough(conf, devnum))
--
2.39.2
2
1

30 Apr '25
From: Magnus Lindholm <linmag7(a)gmail.com>
stable inclusion
from stable-v6.6.84
commit ea371d1cdefb0951c7127a33bcd7eb931cf44571
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBY434
CVE: CVE-2025-21957
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 5233e3235dec3065ccc632729675575dbe3c6b8a ]
A null dereference or oops exception will eventually occur when qla1280.c
driver is compiled with DEBUG_QLA1280 enabled and ql_debug_level > 2. I
think its clear from the code that the intention here is sg_dma_len(s) not
length of sg_next(s) when printing the debug info.
Signed-off-by: Magnus Lindholm <linmag7(a)gmail.com>
Link: https://lore.kernel.org/r/20250125095033.26188-1-linmag7@gmail.com
Signed-off-by: Martin K. Petersen <martin.petersen(a)oracle.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Zheng Qixing <zhengqixing(a)huawei.com>
---
drivers/scsi/qla1280.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 6e5e89aaa283..74b23c43af3e 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -2866,7 +2866,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
dprintk(3, "S/G Segment phys_addr=%x %x, len=0x%x\n",
cpu_to_le32(upper_32_bits(dma_handle)),
cpu_to_le32(lower_32_bits(dma_handle)),
- cpu_to_le32(sg_dma_len(sg_next(s))));
+ cpu_to_le32(sg_dma_len(s)));
remseg--;
}
dprintk(5, "qla1280_64bit_start_scsi: Scatter/gather "
--
2.39.2
2
1

[openeuler:OLK-6.6 2175/2175] include/linux/sched/signal.h: linux/kabi.h is included more than once.
by kernel test robot 30 Apr '25
by kernel test robot 30 Apr '25
30 Apr '25
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: dfd1abba9b4387cb2e9e79e3d6097c2ba507ce32
commit: b53643e68c841ccb6f05f90601ea30b1afeb0a2b [2175/2175] !3695 x86: Add x86 related kabi reservations
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202504300733.mAi3Indd-lkp@intel.com/
includecheck warnings: (new ones prefixed by >>)
>> include/linux/sched/signal.h: linux/kabi.h is included more than once.
vim +15 include/linux/sched/signal.h
4
5 #include <linux/rculist.h>
6 #include <linux/signal.h>
7 #include <linux/sched.h>
8 #include <linux/sched/jobctl.h>
9 #include <linux/sched/task.h>
10 #include <linux/cred.h>
11 #include <linux/refcount.h>
12 #include <linux/posix-timers.h>
13 #include <linux/mm_types.h>
14 #include <asm/ptrace.h>
> 15 #include <linux/kabi.h>
16
> 17 #include <linux/kabi.h>
18
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-6.6 2175/2175] drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debug.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
by kernel test robot 30 Apr '25
by kernel test robot 30 Apr '25
30 Apr '25
tree: https://gitee.com/openeuler/kernel.git OLK-6.6
head: dfd1abba9b4387cb2e9e79e3d6097c2ba507ce32
commit: 0ba0ebb029b99864fa5963024535f48299373354 [2175/2175] !15589 [OLK-6.6] Ethernet: Supports Linkdata ethernet Controllers
config: arm64-allmodconfig (https://download.01.org/0day-ci/archive/20250430/202504300433.T31occlR-lkp@…)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250430/202504300433.T31occlR-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202504300433.T31occlR-lkp@intel.com/
All error/warnings (new ones prefixed by >>):
| ^
| static
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:262:6: error: no previous prototype for function 'sxe_hw_uc_addr_pool_del' [-Werror,-Wmissing-prototypes]
262 | void sxe_hw_uc_addr_pool_del(struct sxe_hw *hw, u32 rar_idx, u32 pool_idx)
| ^
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:262:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
262 | void sxe_hw_uc_addr_pool_del(struct sxe_hw *hw, u32 rar_idx, u32 pool_idx)
| ^
| static
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:283:5: error: no previous prototype for function 'sxe_hw_uc_addr_pool_enable' [-Werror,-Wmissing-prototypes]
283 | s32 sxe_hw_uc_addr_pool_enable(struct sxe_hw *hw, u8 rar_idx, u8 pool_idx)
| ^
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:283:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
283 | s32 sxe_hw_uc_addr_pool_enable(struct sxe_hw *hw, u8 rar_idx, u8 pool_idx)
| ^
| static
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:337:5: error: no previous prototype for function 'sxe_hw_nic_reset' [-Werror,-Wmissing-prototypes]
337 | s32 sxe_hw_nic_reset(struct sxe_hw *hw)
| ^
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:337:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
337 | s32 sxe_hw_nic_reset(struct sxe_hw *hw)
| ^
| static
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:367:6: error: no previous prototype for function 'sxe_hw_pf_rst_done_set' [-Werror,-Wmissing-prototypes]
367 | void sxe_hw_pf_rst_done_set(struct sxe_hw *hw)
| ^
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:367:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
367 | void sxe_hw_pf_rst_done_set(struct sxe_hw *hw)
| ^
| static
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:735:5: error: no previous prototype for function 'sxe_hw_pending_irq_read_clear' [-Werror,-Wmissing-prototypes]
735 | u32 sxe_hw_pending_irq_read_clear(struct sxe_hw *hw)
| ^
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:735:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
735 | u32 sxe_hw_pending_irq_read_clear(struct sxe_hw *hw)
| ^
| static
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:740:6: error: no previous prototype for function 'sxe_hw_pending_irq_write_clear' [-Werror,-Wmissing-prototypes]
740 | void sxe_hw_pending_irq_write_clear(struct sxe_hw *hw, u32 value)
| ^
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:740:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
740 | void sxe_hw_pending_irq_write_clear(struct sxe_hw *hw, u32 value)
| ^
| static
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:745:5: error: no previous prototype for function 'sxe_hw_irq_cause_get' [-Werror,-Wmissing-prototypes]
745 | u32 sxe_hw_irq_cause_get(struct sxe_hw *hw)
| ^
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:745:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
745 | u32 sxe_hw_irq_cause_get(struct sxe_hw *hw)
| ^
| static
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:765:6: error: no previous prototype for function 'sxe_hw_ring_irq_auto_disable' [-Werror,-Wmissing-prototypes]
765 | void sxe_hw_ring_irq_auto_disable(struct sxe_hw *hw, bool is_msix)
| ^
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:765:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
765 | void sxe_hw_ring_irq_auto_disable(struct sxe_hw *hw, bool is_msix)
| ^
| static
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:775:6: error: no previous prototype for function 'sxe_hw_irq_general_reg_set' [-Werror,-Wmissing-prototypes]
775 | void sxe_hw_irq_general_reg_set(struct sxe_hw *hw, u32 value)
| ^
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:775:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
775 | void sxe_hw_irq_general_reg_set(struct sxe_hw *hw, u32 value)
| ^
| static
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:780:5: error: no previous prototype for function 'sxe_hw_irq_general_reg_get' [-Werror,-Wmissing-prototypes]
780 | u32 sxe_hw_irq_general_reg_get(struct sxe_hw *hw)
| ^
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:780:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
780 | u32 sxe_hw_irq_general_reg_get(struct sxe_hw *hw)
| ^
| static
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:790:6: error: no previous prototype for function 'sxe_hw_event_irq_map' [-Werror,-Wmissing-prototypes]
790 | void sxe_hw_event_irq_map(struct sxe_hw *hw, u8 offset, u16 irq_idx)
| ^
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:790:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
790 | void sxe_hw_event_irq_map(struct sxe_hw *hw, u8 offset, u16 irq_idx)
| ^
| static
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:806:6: error: no previous prototype for function 'sxe_hw_ring_irq_map' [-Werror,-Wmissing-prototypes]
806 | void sxe_hw_ring_irq_map(struct sxe_hw *hw, bool is_tx, u16 reg_idx,
| ^
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:806:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
806 | void sxe_hw_ring_irq_map(struct sxe_hw *hw, bool is_tx, u16 reg_idx,
| ^
| static
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:823:6: error: no previous prototype for function 'sxe_hw_ring_irq_interval_set' [-Werror,-Wmissing-prototypes]
823 | void sxe_hw_ring_irq_interval_set(struct sxe_hw *hw, u16 irq_idx, u32 interval)
| ^
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:823:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
823 | void sxe_hw_ring_irq_interval_set(struct sxe_hw *hw, u16 irq_idx, u32 interval)
| ^
| static
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:838:6: error: no previous prototype for function 'sxe_hw_event_irq_auto_clear_set' [-Werror,-Wmissing-prototypes]
838 | void sxe_hw_event_irq_auto_clear_set(struct sxe_hw *hw, u32 value)
| ^
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:838:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
838 | void sxe_hw_event_irq_auto_clear_set(struct sxe_hw *hw, u32 value)
| ^
| static
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:843:6: error: no previous prototype for function 'sxe_hw_specific_irq_disable' [-Werror,-Wmissing-prototypes]
843 | void sxe_hw_specific_irq_disable(struct sxe_hw *hw, u32 value)
| ^
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:843:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
843 | void sxe_hw_specific_irq_disable(struct sxe_hw *hw, u32 value)
| ^
| static
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:848:6: error: no previous prototype for function 'sxe_hw_specific_irq_enable' [-Werror,-Wmissing-prototypes]
848 | void sxe_hw_specific_irq_enable(struct sxe_hw *hw, u32 value)
| ^
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:848:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
848 | void sxe_hw_specific_irq_enable(struct sxe_hw *hw, u32 value)
| ^
| static
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:876:6: error: no previous prototype for function 'sxe_hw_all_irq_disable' [-Werror,-Wmissing-prototypes]
876 | void sxe_hw_all_irq_disable(struct sxe_hw *hw)
| ^
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:876:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
876 | void sxe_hw_all_irq_disable(struct sxe_hw *hw)
| ^
| static
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:994:5: error: no previous prototype for function 'sxe_hw_link_speed_get' [-Werror,-Wmissing-prototypes]
994 | u32 sxe_hw_link_speed_get(struct sxe_hw *hw)
| ^
drivers/net/ethernet/linkdata/sxe/sxepf/sxe_hw.c:994:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
994 | u32 sxe_hw_link_speed_get(struct sxe_hw *hw)
| ^
| static
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
--
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debug.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
* Copyright (C), 2020, Linkdata Technologies Co., Ltd.
--
>> drivers/net/ethernet/linkdata/sxe/base/log/sxe_log.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
* Copyright (C), 2020, Linkdata Technologies Co., Ltd.
--
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_cli.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
* Copyright (C), 2020, Linkdata Technologies Co., Ltd.
--
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_pci.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
* Copyright (C), 2020, Linkdata Technologies Co., Ltd.
--
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
* Copyright (C), 2020, Linkdata Technologies Co., Ltd.
--
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_csum.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
* Copyright (C), 2020, Linkdata Technologies Co., Ltd.
--
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_host_hdc.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
* Copyright (C), 2020, Linkdata Technologies Co., Ltd.
--
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_dcb_nl.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
* Copyright (C), 2020, Linkdata Technologies Co., Ltd.
--
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_monitor.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
* Copyright (C), 2020, Linkdata Technologies Co., Ltd.
--
>> drivers/net/ethernet/linkdata/sxe/sxepf/sxe_filter.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
* Copyright (C), 2020, Linkdata Technologies Co., Ltd.
..
vim +3 drivers/net/ethernet/linkdata/sxe/sxepf/sxe_debug.c
dd013ad487534c liujie_answer 2025-04-15 @3 * Copyright (C), 2020, Linkdata Technologies Co., Ltd.
dd013ad487534c liujie_answer 2025-04-15 4 *
dd013ad487534c liujie_answer 2025-04-15 5 * @file: sxe_debug.c
dd013ad487534c liujie_answer 2025-04-15 6 * @author: Linkdata
dd013ad487534c liujie_answer 2025-04-15 7 * @date: 2025.02.16
dd013ad487534c liujie_answer 2025-04-15 8 * @brief:
dd013ad487534c liujie_answer 2025-04-15 9 * @note:
dd013ad487534c liujie_answer 2025-04-15 10 */
dd013ad487534c liujie_answer 2025-04-15 11
:::::: The code at line 3 was first introduced by commit
:::::: dd013ad487534c1838afc2f55efdb5daec15aace Ethernet: Linkdata: Supports Linkdata ethernet Controllers
:::::: TO: liujie_answer <liujie5(a)linkdatatechnology.com>
:::::: CC: liujie_answer <liujie5(a)linkdatatechnology.com>
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:openEuler-1.0-LTS 1597/1597] include/linux/thread_info.h:59:17: warning: 'b' may be used uninitialized
by kernel test robot 30 Apr '25
by kernel test robot 30 Apr '25
30 Apr '25
Hi Yu,
FYI, the error/warning still remains.
tree: https://gitee.com/openeuler/kernel.git openEuler-1.0-LTS
head: a48a35466505c8a52da57596944bd0b4485e825f
commit: b9f356e64a7eda411ba8b63df9d4c5e204f16025 [1597/1597] block-io-hierarchy: core hierarchy iodump implementation
config: arm64-allmodconfig (https://download.01.org/0day-ci/archive/20250430/202504300437.9dd9ulNF-lkp@…)
compiler: aarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250430/202504300437.9dd9ulNF-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202504300437.9dd9ulNF-lkp@intel.com/
Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
All warnings (new ones prefixed by >>):
In file included from include/asm-generic/preempt.h:5,
from ./arch/arm64/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:81,
from include/linux/spinlock.h:51,
from include/linux/wait.h:9,
from include/linux/wait_bit.h:8,
from include/linux/fs.h:7,
from include/linux/seq_file.h:11,
from block/blk-io-hierarchy/iodump.c:14:
In function 'check_object_size',
inlined from 'check_copy_size' at include/linux/thread_info.h:90:2,
inlined from 'copy_from_user' at include/linux/uaccess.h:143:6,
inlined from 'threshold_store' at block/blk-io-hierarchy/iodump.c:240:6:
>> include/linux/thread_info.h:59:17: warning: 'b' may be used uninitialized [-Wmaybe-uninitialized]
59 | __check_object_size(ptr, n, to_user);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/thread_info.h: In function 'threshold_store':
include/linux/thread_info.h:52:13: note: by argument 1 of type 'const void *' to '__check_object_size' declared here
52 | extern void __check_object_size(const void *ptr, unsigned long n,
| ^~~~~~~~~~~~~~~~~~~
block/blk-io-hierarchy/iodump.c:234:14: note: 'b' declared here
234 | char b[MAX_BUF_LEN + 1];
| ^
vim +/b +59 include/linux/thread_info.h
0f60a8efe4005a Kees Cook 2016-07-12 50
f5509cc18daa7f Kees Cook 2016-06-07 51 #ifdef CONFIG_HARDENED_USERCOPY
f5509cc18daa7f Kees Cook 2016-06-07 52 extern void __check_object_size(const void *ptr, unsigned long n,
f5509cc18daa7f Kees Cook 2016-06-07 53 bool to_user);
f5509cc18daa7f Kees Cook 2016-06-07 54
a85d6b8242dc78 Kees Cook 2016-09-07 55 static __always_inline void check_object_size(const void *ptr, unsigned long n,
f5509cc18daa7f Kees Cook 2016-06-07 56 bool to_user)
f5509cc18daa7f Kees Cook 2016-06-07 57 {
81409e9e280588 Kees Cook 2016-08-31 58 if (!__builtin_constant_p(n))
f5509cc18daa7f Kees Cook 2016-06-07 @59 __check_object_size(ptr, n, to_user);
f5509cc18daa7f Kees Cook 2016-06-07 60 }
f5509cc18daa7f Kees Cook 2016-06-07 61 #else
f5509cc18daa7f Kees Cook 2016-06-07 62 static inline void check_object_size(const void *ptr, unsigned long n,
f5509cc18daa7f Kees Cook 2016-06-07 63 bool to_user)
f5509cc18daa7f Kees Cook 2016-06-07 64 { }
f5509cc18daa7f Kees Cook 2016-06-07 65 #endif /* CONFIG_HARDENED_USERCOPY */
f5509cc18daa7f Kees Cook 2016-06-07 66
:::::: The code at line 59 was first introduced by commit
:::::: f5509cc18daa7f82bcc553be70df2117c8eedc16 mm: Hardened usercopy
:::::: TO: Kees Cook <keescook(a)chromium.org>
:::::: CC: Kees Cook <keescook(a)chromium.org>
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:openEuler-1.0-LTS 1597/1597] include/asm-generic/bitops/non-atomic.h:106:27: warning: array subscript 'long unsigned int[0]' is partly outside array bounds of 'u32[1]' {aka 'unsigned int[1]'}
by kernel test robot 30 Apr '25
by kernel test robot 30 Apr '25
30 Apr '25
Hi Steven,
FYI, the error/warning still remains.
tree: https://gitee.com/openeuler/kernel.git openEuler-1.0-LTS
head: a48a35466505c8a52da57596944bd0b4485e825f
commit: a6a7981cbf66d4951425d33cdce6ef39206eba83 [1597/1597] Net: ethernet: Support 3snic 3s9xx network card
config: arm64-allmodconfig (https://download.01.org/0day-ci/archive/20250430/202504300130.TAvuRGbz-lkp@…)
compiler: aarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250430/202504300130.TAvuRGbz-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202504300130.TAvuRGbz-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/net/ethernet/3snic/sssnic/nic/sss_nic_ethtool_stats_api.c:492:5: warning: no previous prototype for 'sss_nic_get_io_stats_size' [-Wmissing-prototypes]
492 | u32 sss_nic_get_io_stats_size(const struct sss_nic_dev *nic_dev)
| ^~~~~~~~~~~~~~~~~~~~~~~~~
In file included from arch/arm64/include/asm/bitops.h:39,
from include/linux/bitops.h:20,
from include/linux/kernel.h:11,
from drivers/net/ethernet/3snic/sssnic/nic/sss_nic_ethtool_stats_api.c:6:
In function 'test_bit',
inlined from 'sss_nic_add_ethtool_link_mode' at drivers/net/ethernet/3snic/sssnic/nic/sss_nic_ethtool_stats_api.c:764:7:
>> include/asm-generic/bitops/non-atomic.h:106:27: warning: array subscript 'long unsigned int[0]' is partly outside array bounds of 'u32[1]' {aka 'unsigned int[1]'} [-Warray-bounds=]
106 | return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
| ~~~~^~~~~~~~~~~~~~
drivers/net/ethernet/3snic/sssnic/nic/sss_nic_ethtool_stats_api.c: In function 'sss_nic_add_ethtool_link_mode':
drivers/net/ethernet/3snic/sssnic/nic/sss_nic_ethtool_stats_api.c:759:40: note: object 'hw_mode' of size 4
759 | u32 hw_mode, u32 op)
| ~~~~^~~~~~~
vim +106 include/asm-generic/bitops/non-atomic.h
4117b02132d1cf Akinobu Mita 2006-03-26 98
4117b02132d1cf Akinobu Mita 2006-03-26 99 /**
4117b02132d1cf Akinobu Mita 2006-03-26 100 * test_bit - Determine whether a bit is set
4117b02132d1cf Akinobu Mita 2006-03-26 101 * @nr: bit number to test
4117b02132d1cf Akinobu Mita 2006-03-26 102 * @addr: Address to start counting from
4117b02132d1cf Akinobu Mita 2006-03-26 103 */
4117b02132d1cf Akinobu Mita 2006-03-26 104 static inline int test_bit(int nr, const volatile unsigned long *addr)
4117b02132d1cf Akinobu Mita 2006-03-26 105 {
d05be13bcc6ec6 Jiri Slaby 2007-10-18 @106 return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
4117b02132d1cf Akinobu Mita 2006-03-26 107 }
4117b02132d1cf Akinobu Mita 2006-03-26 108
:::::: The code at line 106 was first introduced by commit
:::::: d05be13bcc6ec615fb2e9556a9b85d52800669b6 define first set of BIT* macros
:::::: TO: Jiri Slaby <jirislaby(a)gmail.com>
:::::: CC: Linus Torvalds <torvalds(a)woody.linux-foundation.org>
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-5.10 2880/2880] include/linux/blk_types.h: linux/kabi.h is included more than once.
by kernel test robot 30 Apr '25
by kernel test robot 30 Apr '25
30 Apr '25
tree: https://gitee.com/openeuler/kernel.git OLK-5.10
head: b7710e01aad5e90a681267c840f4815b024b98c6
commit: dde4fe567523327d09054824030fb2d22e5009c7 [2880/2880] kabi: Add kabi reservation for storage module
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202504300111.nH5Pw0yV-lkp@intel.com/
includecheck warnings: (new ones prefixed by >>)
>> include/linux/blk_types.h: linux/kabi.h is included more than once.
--
>> include/linux/mm.h: linux/kabi.h is included more than once.
--
>> include/linux/ioport.h: linux/kabi.h is included more than once.
--
>> include/linux/device.h: linux/kabi.h is included more than once.
--
>> include/linux/device/class.h: linux/kabi.h is included more than once.
--
>> include/linux/cred.h: linux/kabi.h is included more than once.
--
>> include/linux/swap.h: linux/kabi.h is included more than once.
vim +9 include/linux/blk_types.h
8
> 9 #include <linux/kabi.h>
10 #include <linux/types.h>
11 #include <linux/bvec.h>
12 #include <linux/ktime.h>
> 13 #include <linux/kabi.h>
14
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-5.10 2881/2881] kismet: WARNING: unmet direct dependencies detected for PTP_1588_CLOCK when selected by SXE_VF
by kernel test robot 30 Apr '25
by kernel test robot 30 Apr '25
30 Apr '25
tree: https://gitee.com/openeuler/kernel.git OLK-5.10
head: b7710e01aad5e90a681267c840f4815b024b98c6
commit: 8cee206b5558245197158bd20895f95cc28d8468 [2881/2881] Ethernet: Linkdata: Supports Linkdata ethernet Controllers
config: x86_64-kismet-CONFIG_PTP_1588_CLOCK-CONFIG_SXE_VF-0-0 (https://download.01.org/0day-ci/archive/20250430/202504300151.RfBZyPgj-lkp@…)
reproduce: (https://download.01.org/0day-ci/archive/20250430/202504300151.RfBZyPgj-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202504300151.RfBZyPgj-lkp@intel.com/
kismet warnings: (new ones prefixed by >>)
>> kismet: WARNING: unmet direct dependencies detected for PTP_1588_CLOCK when selected by SXE_VF
WARNING: unmet direct dependencies detected for PTP_1588_CLOCK
Depends on [n]: NET [=y] && POSIX_TIMERS [=n]
Selected by [y]:
- SXE [=y] && NETDEVICES [=y] && ETHERNET [=y] && NET_VENDOR_LINKDATA [=y] && (X86 [=y] || ARM64) && PCI [=y]
- SXE_VF [=y] && NETDEVICES [=y] && ETHERNET [=y] && NET_VENDOR_LINKDATA [=y] && (X86 [=y] || ARM64) && PCI [=y]
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0

[openeuler:OLK-5.10 2881/2881] kismet: WARNING: unmet direct dependencies detected for PTP_1588_CLOCK when selected by SXE
by kernel test robot 30 Apr '25
by kernel test robot 30 Apr '25
30 Apr '25
tree: https://gitee.com/openeuler/kernel.git OLK-5.10
head: b7710e01aad5e90a681267c840f4815b024b98c6
commit: 8cee206b5558245197158bd20895f95cc28d8468 [2881/2881] Ethernet: Linkdata: Supports Linkdata ethernet Controllers
config: x86_64-kismet-CONFIG_PTP_1588_CLOCK-CONFIG_SXE-0-0 (https://download.01.org/0day-ci/archive/20250430/202504300001.MoxWgMgI-lkp@…)
reproduce: (https://download.01.org/0day-ci/archive/20250430/202504300001.MoxWgMgI-lkp@…)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp(a)intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202504300001.MoxWgMgI-lkp@intel.com/
kismet warnings: (new ones prefixed by >>)
>> kismet: WARNING: unmet direct dependencies detected for PTP_1588_CLOCK when selected by SXE
WARNING: unmet direct dependencies detected for PTP_1588_CLOCK
Depends on [n]: NET [=y] && POSIX_TIMERS [=n]
Selected by [y]:
- SXE [=y] && NETDEVICES [=y] && ETHERNET [=y] && NET_VENDOR_LINKDATA [=y] && (X86 [=y] || ARM64) && PCI [=y]
Selected by [m]:
- SXE_VF [=m] && NETDEVICES [=y] && ETHERNET [=y] && NET_VENDOR_LINKDATA [=y] && (X86 [=y] || ARM64) && PCI [=y]
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
1
0